תוכן עניינים:
2025 מְחַבֵּר: John Day | [email protected]. שונה לאחרונה: 2025-01-13 06:57
מטרות:
- צור לוגר נתונים עבור ≤ 500 $. הוא מאחסן נתונים לגבי טמפרטורה, pH ו- DO עם חותמת זמן ושימוש בתקשורת I2C.
- מדוע I2C (מעגל אינטגרטיבי)? אפשר לערום כמה שיותר חיישנים באותו קו בהתחשב בכך שלכל אחד מהם יש כתובת ייחודית.
שלב 1:
שלב 2: קנה את החלקים למטה:
- Arduino MEGA 2560, $ 35,
- מתאם מתח ללוח Arduino, $ 5.98,
- מודול LCD I2C (תצוגה), $ 8.99,
- שעון בזמן אמת (RTC), 7.5 $,
- לוח פריצה של כרטיס MicroSD, 7.5 $,
- כרטיס SD בנפח 4GB, $ 6.98,
- חיישן דיגיטלי DS18B20 עמיד למים, $ 9.95,
- בדיקת pH + ערכות + מאגרים סטנדרטיים, $ 149.15,
- DO בדיקה + ערכות + מאגרים סטנדרטיים, $ 247.45,
- לוח לחם, כבל מגשר, $ 7.98,
- (אופציונלי) מבודד מתח, $ 24,
סה כ: 510.48 דולר
* ניתן לקנות חלקים מסוימים (כמו הלוח הגנרי) מספקים אחרים (eBay, מוכר סיני) במחיר נמוך יותר. מומלץ לבצע בדיקות pH ו- DO כדי לקבל אותן מאטלס סיינטיפיק.
* מומלץ מולטימטר לבדיקת מוליכות ומתח. זה עולה בערך $ 10-15 (https://goo.gl/iAMDJo)
שלב 3: חיווט
- השתמש בכבלי מגשר/DuPont לחיבור החלקים כפי שמוצג בסקיצה למטה.
- השתמש במולטימטר כדי לבדוק את ההולכה.
- בדוק את אספקת המתח החיובי (VCC) ואת הקרקע (GND) (קל לבלבל אם אינך מכיר מעגל)
- חבר את מתאם החשמל ובדוק את מחוון ההפעלה בכל חלק. כאשר יש ספקות, השתמש במד המרובה כדי לבדוק את המתח בין VCC ל- GND להיות (5V)
שלב 4: הכינו את מעגלי ה- PH, DO, כרטיס ה- SD
- עבור ל- I2C למעגלי pH ו- DO
- התפרצויות ה- pH ו- DO נשלחות עם תקשורת טורית כמצב ברירת המחדל שידור/קבלה (TX/RX). כדי להשתמש בקו השעון במצב I2C (SCL) ובקו הנתונים (SDA), החלף מצב על ידי (1): נתק כבלי VCC, TX, RX, (2): קפץ TX לקרקע עבור בדיקה, PGND (לא GND), (3) חבר VCC למעגל, (4): המתן עד שה LED ישתנה מירוק לכחול. פרטים נוספים בדוק בעמוד 39 (גליון נתונים למעגל pH,
- בצע את אותו שלב עם מעגל DO
- (אם אתה יודע כיצד להעלות את הקוד לדוגמא ללוח, תוכל לעשות זאת באמצעות צג סידורי)
- עיצוב כרטיס SD לפורמט FAT
שלב 5: הכנת תוכנה
- הורד את סביבת הפיתוח המשולבת של Arduino (IDE),
- התקן את הספרייה ל- Arduino IDE:
- רובם מגיעים עם תוכנת Arduino. LiquidCrystal_I2C.h זמין באמצעות GitHub
- התקן את מנהל ההתקן עבור USB. עבור Arduino אמיתי, ייתכן שלא תצטרך להתקין אחד. עבור אחד כללי, עליך להתקין מנהל התקן CH340 (GitHub:
- בדוק אם אתה מחבר את הלוח כראוי על ידי הפעלת בדיקת LED מהבהבת
- כיצד למצוא את כתובת ה- MAC של הטמפרטורה הדיגיטלית 18B20. שימוש בתבנית סורק I2C ב- Arduino IDE עם החללית מחוברת. לכל מכשיר יש כתובת MAC ייחודית, כך שתוכל להשתמש בכמה שיותר בדיקות טמפרטורה עם קו משותף אחד (#9). 18B20 משתמשת בחוט I2C אחד, כך שמדובר במקרה מיוחד של שיטת תקשורת I2C. להלן שיטה אחת לאיתור MAC - בקרת גישה רפואית ("ROM" בעת הפעלת ההליך שלהלן).
שלב 6: התחל קידוד
- העתק הדבק את הקוד למטה ל- Arduino IDE:
- או הורד את הקוד (.ino) וחלון חדש יופיע ב- Arduino IDE.
/*
הדרכות הפניה:
1. טמפרטורה, ORP, כורת pH:
2. מגן דיגיטלי מאובטח (SD):
קוד זה יפיק נתונים לצג הטורי Arduino. הקלד פקודות לתוך הצג הסדרתי של Arduino כדי לשלוט במעגל ה- pH של EZO במצב I2C.
שונה מהדרכות שהוזכרו למעלה, בעיקר מקוד I2C של Atlas-Scientific
עודכן לאחרונה: 26 ביולי 2017 על ידי Binh Nguyen
*/
#include // אפשר I2C.
#define pH_address 99 // מספר ברירת מחדל I2C מזהה עבור מעגל pH EZO.
#define DO_address 97 // מספר ברירת המחדל של מזהה I2C עבור מעגל EZO DO.
#כלול "RTClib.h" // פונקציות תאריך ושעה באמצעות RTC DS1307 המחובר באמצעות I2C ו- Wire lib
RTC_DS1307 rtc;
#include // עבור libarary SD
#include // כרטיס SD לאחסון נתונים
const int chipSelect = 53; // צריך להבין את ההתפרצות של Adafruit SD //
// DO = MISO, DI = MOSI, על סיכת ATmega#: 50 (MISO), 51 (MOSI), 52 (SCK), 53 (SS)
char logFileName = "dataLT.txt"; // שנה logFileName כדי לזהות את הניסוי שלך, למשל PBR_01_02, datalog1
מזהה ארוך = 1; // מספר הזיהוי להזנת סדר היומן
#לִכלוֹל
LiquidCrystal_I2C lcd (0x27, 20, 4);
#לִכלוֹל
#לִכלוֹל
# הגדר ONE_WIRE_BUS 9 // הגדר את הסיכה # לבדיקת טמפרטורה
OneWire oneWire (ONE_WIRE_BUS);
חיישני טמפרטורה של Dallas (& oneWire);
DeviceAddress ProbeP = {0x28, 0xC2, 0xE8, 0x37, 0x07, 0x00, 0x00, 0xBF}; // כתובת MAC, ייחודית לכל בדיקה
Data מחרוזת; // הגרסה העיקרית לאחסון כל הנתונים
Data מחרוזת 2; // גרסה זמנית לאחסון טמפרטורה/pH/DO להדפסה
נתוני char computerd [20]; // הוראה מאת Atlas Scientific: אנו יוצרים מערך תווים של 20 בתים בכדי לאחסן נתונים נכנסים ממחשב מחשב/מק/אחר.
בייט קיבל_מחשב_מחשב = 0; // עלינו לדעת כמה דמויות התקבלו.
בייט serial_event = 0; // דגל לאותת כאשר התקבלו נתונים מהמחשב האישי/מק/אחר.
קוד בתים = 0; // משמש להחזיק את קוד התגובה I2C.
char pH_data [20]; // אנו יוצרים מערך תווים של 20 בתים בכדי לאחסן נתונים נכנסים ממעגל ה- pH.
בייט in_char = 0; // משמש כמאגר 1 בתים לאחסון בתים כבולים ממעגל ה- pH.
בת i = 0; // מונה המשמש עבור מערך ph_data.
int time_ = 1800; // משמש לשינוי העיכוב הדרוש בהתאם לפקודה שנשלחה למעגל ה- pH של EZO Class.
צף pH_float; // float var משמש כדי להחזיק את ערך הציפה של ה- pH.
char DO_data [20];
// צף temp_C;
הגדרת חלל () // אתחול חומרה.
{
Serial.begin (9600); // אפשר יציאה טורית.
Wire.begin (pH_address); // אפשר יציאת I2C עבור בדיקת pH
Wire.begin (DO_address);
lcd.init ();
lcd.begin (20, 4);
lcd.backlight ();
lcd.home ();
lcd.print ("שלום PBR!");
lcd.setCursor (0, 1);
lcd.print ("אתחול …");
Serial.print ("RTC הוא …");
אם (! rtc.begin ())
{
Serial.println ("RTC: שעון בזמן אמת … לא נמצא");
while (1); // (Serial.println ("RTC: שעון בזמן אמת … FOUND"));
}
Serial.println ("ריצה");
Serial.print ("שעון בזמן אמת …");
אם (! rtc.isrunning ())
{rtc.adjust (DateTime (F (_ DATE_), F (_ TIME_)));
}
Serial.println ("עובד");
lcd.setCursor (0, 0);
lcd.println ("RTC: אישור");
Serial.print ("כרטיס SD …"); // בדוק אם הכרטיס קיים וניתן לאתחל אותו:
אם (! SD.begin (chipSelect))
{Serial.println ("נכשל"); // אל תעשה יותר כלום:
לַחֲזוֹר;
}
Serial.println ("אישור");
lcd.setCursor (0, 1);
lcd.println ("כרטיס SD: אישור");
Serial.print ("קובץ יומן:");
Serial.print (logFileName);
Serial.print ("…");
קובץ logFile = SD.open (logFileName, FILE_WRITE); // פתח את הקובץ. "datalog" והדפס את הכותרת
אם (logFile)
{
logFile.println (",,,"); // ציינו שהיו נתונים בריצה הקודמת
כותרת מחרוזת = "תאריך -שעה, טמפ '(C), pH, DO";
logFile.println (כותרת);
logFile.close ();
Serial.println ("READY");
//Serial.println(dataString); // הדפס גם ליציאה הטורקית:
}
else {Serial.println ("שגיאה בפתיחת יומן הנתונים"); } // אם הקובץ אינו פתוח, צץ שגיאה:
lcd.setCursor (0, 2);
lcd.print ("קובץ יומן:");
lcd.println (logFileName);
עיכוב (1000);
חיישנים.התחל ();
sensors.setResolution (ProbeP, 10); // 10 היא הרזולוציה (10bit)
lcd.clear ();
id = 0;
}
לולאת חלל ()
{// הלולאה הראשית.
dataString = String (id);
dataString = מחרוזת (',');
DateTime עכשיו = rtc.now ();
dataString = String (now.year (), DEC);
dataString += String ('/');
dataString += String (now.month (), DEC);
dataString += String ('/');
dataString += String (now.day (), DEC);
dataString += String ('');
dataString += מחרוזת (now.hour (), DEC);
dataString += String (':');
dataString += String (now.minute (), DEC);
dataString += String (':');
dataString += String (now.second (), DEC);
lcd.home ();
lcd.print (dataString);
sensors.requestTemperatures ();
displayTemperature (ProbeP);
Wire.beginTransmission (pH_address); // התקשר למעגל לפי מספר הזהות שלו
Wire.write ('r'); // קוד קשה r לקרוא תמיד
Wire.endTransmission (); // לסיים את העברת הנתונים I2C.
עיכוב (time_); // המתן את פרק הזמן הנכון עד שהמעגל יסיים את הוראתו.
Wire.requestFrom (pH_address, 20, 1); // התקשר למעגל ובקש 20 בתים (זה עשוי להיות יותר ממה שאנחנו צריכים)
בעוד (Wire.available ()) // יש בתים לקבל
{
in_char = Wire.read (); // לקבל בתים.
if ((in_char> 31) && (in_char <127)) // לבדוק אם ניתן להשתמש בחריטה (להדפסה)
{
pH_data = in_char; // טען את הבייט הזה במערך שלנו.
i+= 1;
}
if (in_char == 0) // אם אנו רואים שנשלחה אלינו פקודה null.
{
i = 0; // אפס את המונה i ל 0.
Wire.endTransmission (); // לסיים את העברת הנתונים I2C.
לשבור; // צא מלולאת ה- while.
}
}
אירוע סדרתי = 0; // אפס את דגל האירוע הטורי.
dataString2 += ",";
dataString2 += מחרוזת (pH_data);
שידור Wire.beginTransmission (DO_address); // התקשר למעגל לפי מספר הזהות שלו
Wire.write ('r');
Wire.endTransmission (); // לסיים את העברת הנתונים I2C
עיכוב (time_); // המתן את פרק הזמן הנכון עד שהמעגל יסיים את הוראתו
Wire.requestFrom (DO_address, 20, 1); // התקשר למעגל ובקש 20 בתים
בעוד (Wire.available ()) // יש בתים לקבל.
{
in_char = Wire.read (); // לקבל בתים.
if ((in_char> 31) && (in_char <127)) // בדוק אם ניתן להשתמש ב- char (להדפסה), אחרת ה- in_char מכיל סמל בתחילת הקובץ.txt
{DO_data = in_char; // טען את הבייט הזה במערך שלנו
i+= 1; // לקבל את המונה של רכיב המערך
}
אם (in_char == 0)
{// אם אנו רואים שנשלחה אלינו פקודה null
i = 0; // אפס את המונה i ל 0.
Wire.endTransmission (); // לסיים את העברת הנתונים I2C.
לשבור; // צא מלולאת ה- while.
}
}
אירוע סדרתי = 0; // אפס את דגל האירוע הטורי
pH_float = atof (pH_data);
dataString2 += ",";
dataString2 += מחרוזת (DO_data);
lcd.setCursor (0, 1);
lcd.print ("טמפרטורה/ pH/ DO");
lcd.setCursor (0, 2);
lcd.print (dataString2);
dataString += ',';
dataString += dataString2;
קובץ dataFile = SD.open (logFileName, FILE_WRITE); // פתח את הקובץ. שים לב שרק קובץ אחד יכול להיות פתוח בכל פעם, לכן עליך לסגור קובץ זה לפני פתיחת קובץ אחר.
אם (dataFile) // אם הקובץ זמין, כתוב אליו:
{
dataFile.println (dataString);
dataFile.close ();
Serial.println (dataString); // הדפס גם ליציאה הטורקית:
}
אחרת {Serial.println ("שגיאה בפתיחת קובץ יומן נתונים"); } // אם הקובץ אינו פתוח, צץ שגיאה:
lcd.setCursor (0, 3);
lcd.print ("ריצה (x5m):");
lcd.setCursor (15, 3);
lcd.print (id);
id ++; // להגדיל מזהה אחד איטרציה הבאה
dataString = "";
עיכוב (300000); // עיכוב 5 דקות = 5*60*1000 אלפיות השנייה
lcd.clear ();
} // סוף הלולאה הראשית
display display טמפרטורה (DeviceAddress deviceAddress)
{
float tempC = sensors.getTempC (deviceAddress);
if (tempC == -127.00) lcd.print ("שגיאת טמפרטורה");
else dataString2 = מחרוזת (tempC);
} // סוף הקוד כאן
- בחר את יציאת ה- COM הנכונה באמצעות Arduino IDE תחת כלים/יציאה
- בחר את הלוח הנכון של Arduino. השתמשתי במגה 2560 מכיוון שיש לו יותר זיכרון פנימי. Arduino Nano או Uno עובד מצוין עם ההתקנה הזו.
- בדוק וקוד והעלה קוד
שלב 7: תוצאות על חיווט (ניתן לשפר) ותצוגת LCD
- שים לב: נתקלתי ברעש של בדיקת DO לבדיקת pH לאחר 2-3 חודשים של פעולה רציפה. על פי Atlas Scientific, מומלץ לבודד מתח בתוך הקו כאשר בדיקות pH, מוליכות פועלות יחד. פרטים נוספים נמצאים בעמוד 9 (https://goo.gl/d62Rqv)
- הנתונים שנרשמו (הראשון כולל תווים לא מודפסים לפני נתוני pH ו- DO). סיננתי לקוד על ידי מתן תווים להדפסה בלבד.
שלב 8: ייבא נתונים ועשה גרף
- ייבא נתונים מהטקסט בכרטיסייה DATA (Excel 2013)
- הפרד את הנתונים באמצעות פסיק (לכן מועיל פסיקים לאחר כל קלט נתונים)
- משרטטים את הנתונים. לכל נתונים למטה יש כ- 1700 נקודות. מרווח המדידה הוא 5 דקות (מתכוונן). המינימום למעגלי DO ו- pH לקריאת הנתונים הוא 1.8 שניות.
שלב 9: כיול
- ניתן לכייל את חיישן הטמפרטורה הדיגיטלית (18B20) על ידי התאמת ההפרש ישירות ל. אחרת, אם הפיצוי והמדרון דורשים כיול, תוכל לעשות זאת על ידי שינוי ערכים בקו 453, DallasTemperature.cpp בתיקייה / libraries / DallasTemperature.
- עבור בדיקות pH ו- DO, ניתן לכייל את הגששים בעזרת פתרונות נלווים. עליך להשתמש בקוד לדוגמה של Atlas Scientific ופעל לפי ההנחיות בקובץ זה.
- אנא עקוב אחר עמודים 26 ו -50 עבור בדיקת pH (https://goo.gl/d62Rqv) לכיול ופיצוי טמפרטורה, וכן עמודים 7-8 ו- 50 עבור בדיקת DO (https://goo.gl/mA32mp). ראשית, אנא העלה מחדש את הקוד הגנרי שסופק על ידי אטלס, פתח את הצג הסידורי והזן פקודה מתאימה.
שלב 10: יותר מדי חיווט?
- אתה יכול לחסל את כרטיס ה- SD ואת מודול השעון בזמן אמת באמצעות מגן Dragino Yun ללוחות Arduino (https://goo.gl/J9PBTH). היה צורך לשנות את הקוד לעבודה עם Yun Shield. הנה מקום טוב להתחיל בו (https://goo.gl/c1x8Dm)
- עדיין יותר מדי חיווט: Atlas Scientific הכין מדריך למעגלי EZO שלהם (https://goo.gl/dGyb12) ולוח ללא הלחמה (https://goo.gl/uWF51n). שילוב הטמפרטורה הדיגיטלית 18B20 נמצאת כאן (https://goo.gl/ATcnGd). עליך להכיר פקודות ב- Raspbian (גרסה של Debian Linux) הפועלות ב- Raspberry Pi (https://goo.gl/549xvk)
שלב 11: הכרה:
זהו פרויקט הצד שלי במהלך המחקר הפוסט -דוקטורט שלי שעבדתי על פוטוביוגרקט מקדים לטיפוח מיקרו -אצות. אז חשבתי שצריך לזכות שהצדדים נתנו תנאים כדי שזה יקרה. ראשית, המענק, DE-EE0007093: "העשרת אספקה CO2 באטמוספירה (ACED)" ממשרד האנרגיה האמריקאי, משרד יעילות האנרגיה והאנרגיה המתחדשת ממוקד דלקים ביולוגיים ומוצרי ביולוגיה. אני מודה לד"ר ברוס א. ריטמן במרכז Biodesign Swette לביוטכנולוגיה סביבתית, אוניברסיטת מדינת אריזונה על שנתן לי את ההזדמנות להתעסק עם אלקטרוניקה וארדואינו. הוכשרתי בהנדסת סביבה, בעיקר כימיה, קצת מיקרוביולוגיה.