Rozhodl jsem se zveřejnit návod na výrobu praktického data loggeru, který zaznamenává GPS polohu, kterou následně ukládá ve 2 vteřinových intervalech na micro SD kartu i společně s teplotou, vlhkostí vzduchu a atmosférickým tlakem. Tyto hodnoty jsou dále i posílány po sériové lince do USB počítače, kde data můžeme načíst v programu Arduino-sériový monitor.
Na výrobu jsem zvolil desku Mega 2560, která se mi válela v šuplíku, GPS modul neo 6M, čidlo teploty BMP280 a čtečku micro SD karet. Vše jsem zakoupil zde na https://dratek.cz/
Zapojení:
CIDLO PIN20SDA (DESKA) MODRA PIN21SCL (DESKA) ZLUTA 3,3 AZ 5V CERVENA GND CERNA GPS TX ZLUTA PIN13 (DESKA) RX MODRA PIN12 (DESKA) 5V CERVENA GND CERNA SD KARTA CS (MODRA) PIN53 (DESKA) SCK (ORANZOVA) PIN52 (DESKA) MOSI (ZELENA) PIN51 (DESKA) MOSO (BILA) PIN50 (DESKA) 3,3 AZ 5V CERVENA GND CERNA
Program vznikl spojením a lehkou úpravou tří programů ze zdejších stránek s návody a tak by se dal zařadit ke článkům s teplotním snímačem BMP280, GPS a SD kartou. Zachoval jsem i doprovodné komentáře na vysvětlení. Vím, že by se asi našel někdo, kdo by tento program dokázal i třeba zkrátit a napsat úsporněji. Já jsem zatím lehce mírně pokročilý začátečník a tak se do toho raději nebudu pouštět. Na začátku jsou klasicky vloženy knihovny (viz dále v textu) a nastaveny patřičné vstupy. Ve smyčce setup nastavíme sériovou komunikaci a zkontrolujeme funkčnost pamětové karty. Na začátku smyčky loop vytvoříme dočasné proměnné, zkontrolujeme komunikaci s GPS modulem i teploměrem a jestli modul GPS komunikuje, začne po sériové lince posílat data. Dojde-li k odpojení jednoho z modulů, je opět po sériové lince poslána chybová hláška/y. Dále je vytvořena zpráva s meteo daty a polohou, která je zapsána na SD kartu. Proběhne-li uložení v pořádku, je opět po lince poslána hláška o úspěšném uložení.
//GPS data logger s teplomerem, tlakomerem a vlhkomerem //Knihovny //SD #include <SD.h> // nastavení pinu CS pro SD kartu - pevně dané shieldem const int sd_CS = 53; //GPS NEO-6M #include <SoftwareSerial.h> #include <TinyGPS.h> // nastavení propojovacích pinů #define TX 12 #define RX 13 // inicializace GPS a komunikace po softwarové sériové lince TinyGPS gps; SoftwareSerial swSerial(RX, TX); //BME280 #include <Adafruit_BME280.h> #include <Adafruit_Sensor.h> #include <SPI.h> #include <Wire.h> // nastavení adresy senzoru #define BME280_ADRESA (0x76) // inicializace senzoru BME z knihovny Adafruit_BME280 bme; void setup() { // zahájení komunikace po sériové lince Serial.begin(9600); // zahájení komunikace s GPS modulem po softwarové sériové lince swSerial.begin(9600); // kontrola připojené SD karty if (!SD.begin(sd_CS)) { Serial.println("SD karta neni pripojena nebo je vadna!"); } } void loop() { // vytvoření dočasných proměnných pro načtení dat z GPS modulu float zSirka, zDelka; unsigned long stariDat; int rok; byte mesic, den, hodina, minuta, sekunda, setinaSekundy; // vytvoření proměnné pro vytištění data a času char datumCas[32]; // vytvoření dočasných proměnných pro načtení informací o komunikaci s GPS modulem bool novaData = false; unsigned long znaky; unsigned short slova, chyby; // po dobu jedné vteřiny budeme kontrolovat příjem dat z GPS for (unsigned long start = millis(); millis() - start < 1000;) { // kontrola aktivity softwarové komunikace while (swSerial.available()) { // vytvoření proměnné pro uložení načtených dat z GPS char c = swSerial.read(); //Serial.write(c); // pro výpis přijatých dat odkomentujte tento řádek // dekódování přijaté zprávy s kontrolou platných dat if (gps.encode(c)) { // pokud jsou přijatá data platná, nastavíme proměnnou pro tištění dat novaData = true; } } } // pokud proběhl příjem nových dat, vytiskneme všechny dostupné informace if (novaData) { // načtení GPS pozice do proměnných gps.f_get_position(&zSirka, &zDelka, &stariDat); // vytištění informací po sériové lince Serial.println(" ::Dostupne GPS udaje:: "); // vytištění informací po sériové lince Serial.print(" Zemepisna sirka: "); // nejprve zkontrolujeme, jestli máme platné údaje // (zSirka == TinyGPS::GPS_INVALID_F_ANGLE), // pokud nejsou validní (platné), vytiskneme nulu, // v opačném případě vytiskneme obsah proměnné s přesností 6 desetinných míst, // podobným způsobem se pracuje i s ostatními údaji Serial.println(zSirka == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : zSirka, 6); Serial.print(" Zemepisna delka: "); Serial.println(zDelka == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : zDelka, 6); Serial.print(" Pocet satelitu: "); Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites()); Serial.print(" Presnost: "); Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop()); Serial.print(" Stari dat: "); Serial.println(stariDat == TinyGPS::GPS_INVALID_AGE ? 0 : stariDat); Serial.print(" Nadmorska vyska m.n.m: "); Serial.println(gps.f_altitude() == TinyGPS::GPS_INVALID_F_ALTITUDE ? 0 : gps.f_altitude()); Serial.print(" Rychlost v km/h: "); Serial.println(gps.f_speed_kmph() == TinyGPS::GPS_INVALID_F_SPEED ? 0 : gps.f_speed_kmph()); // načtení data a času z GPS modulu do proměnných gps.crack_datetime(&rok, &mesic, &den, &hodina, &minuta, &sekunda, &setinaSekundy, &stariDat); // kontrola platnosti dat if (stariDat == TinyGPS::GPS_INVALID_AGE) { Serial.println("Nelze nacist datum a cas."); Serial.println(); } else { Serial.print("Datum a cas: "); // poskládání celé zprávy do proměnné datumCas a poté její vytištění, // %02d znamená desetinné číslo uvedené za uvozovkami s přesností na 2 číslice sprintf(datumCas, "%02d/%02d/%02d %02d:%02d:%02d", mesic, den, rok, hodina, minuta, sekunda); Serial.println(datumCas); Serial.println(); } } // načtení a vytištění informací o komunikaci s GPS modulem gps.stats(&znaky, &slova, &chyby); Serial.print("Detekovane znaky: "); Serial.print(znaky); Serial.print(", slova: "); Serial.print(slova); Serial.print(", chyby pri kontrole dat: "); Serial.print(chyby); Serial.println(); // kontrola chyb při komunikaci skrze detekci přijatých znaků if (znaky == 0) { Serial.println(); // vytištění prázdného řádku Serial.println("Chyba pri prijmu dat z GPS, zkontrolujte zapojeni!"); Serial.println(); } // oddeli mezi sebou text z GPS modulu a teplomeru BMP Serial.println(); // v případě chyby senzoru je vypsána hláška po sériové lince if (!bme.begin(BME280_ADRESA)) { Serial.println("BME280 senzor nenalezen, zkontrolujte zapojeni!"); Serial.println(); // vytištění prázdného řádku } // výpis všech dostupných informací ze senzoru BMP // výpis teploty Serial.println("::Dostupne meteorologicke udaje::"); // výpis teploty Serial.print("Teplota °C: "); Serial.println(bme.readTemperature()); // výpis relativní vlhkosti Serial.print("Relativni vlhkost %: "); Serial.println(bme.readHumidity()); // výpis tlaku s přepočtem na hektoPascaly Serial.print("Tlak hPa.: "); Serial.println(bme.readPressure() / 100.0F); // vytištění prázdného řádku Serial.println(); // otevření souboru na SD kartě s názvem mereni.txt File zapisDat = SD.open("mereni.txt", FILE_WRITE); // vytvoreni zpravy String dataString("::Dostupne GPS udaje:: "); dataString += (" Zemepisna sirka: "); dataString += String(zSirka == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : zSirka, 6); dataString += (" Zemepisna delka: "); dataString += String(zDelka == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : zDelka, 6); dataString += (" Pocet satelitu: "); dataString += String(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites()); dataString += (" Nadmorska vyska m.n.n: "); dataString += String(gps.f_altitude() == TinyGPS::GPS_INVALID_F_ALTITUDE ? 0 : gps.f_altitude()); dataString += (" Rychlost v km/h: "); dataString += String(gps.f_speed_kmph() == TinyGPS::GPS_INVALID_F_SPEED ? 0 : gps.f_speed_kmph()); dataString += (" Datum a cas: "); dataString += String(datumCas); dataString += String(" ::Dostupne meteorologicke udaje:: "); dataString += (" Teplota ve stupnich C: "); dataString += String(bme.readTemperature()); dataString += (" Relativni vlhkost %: "); dataString += String(bme.readHumidity()); dataString += (" Tlak v hPa.: "); dataString += String(bme.readPressure() / 100.0F); // v případě, že je soubor bez problémů vytvořen (pokud neexistuje), // nebo otevřen (pokud existuje), zapiš do něj dataString a ukonči zápis if (zapisDat) { zapisDat.println(dataString); zapisDat.close(); Serial.println(" Zapis na kartu uspesny. "); Serial.println(); } // v případě chyby při otevírání souboru vypiš chybu else { Serial.println(" Chyba pri otevreni souboru mereni.txt ! "); Serial.println(); } delay(2000); }
Z těchto dat uložených na kartě v dokumentu mereni.txt lze pak v Excelu sestavit třeba pěkný graf o teplotě, tlaku, nadmořské výšce apod. Prostě co se komu hodí. Program vypisuje tyto hodnoty: Zeměpisná délka, šířka na šest desetiných míst, Počet satelitů, Nadmořská výška, Rychlost v Km/h, Datum a čas, Teplotu, Vlhkost vzduch a Tlak v Hektopascalech. Pouze na začátku meření je vypsáno několik řádků nul, než dojde k inicializaci GPS modulu, ale teploměr již data ukládá.
V budoucnu se pokusím tento logger připojit k GSM modulu, aby mi i naměřená data posílal třeba v SMS zprávě.
Ukázka ukládaných dat do souboru mereni.txt (u GPS souřadnic je záměrně jedna číslice nahrazena hvězdičkou):
::Dostupne GPS udaje::Zemepisna sirka: 0.000000 delka: 0.000000 Pocet satelitu: 0 Nadmorska vyska m.n.n: 0.00 Rychlost v km/h: 0.00Datum a cas: żńUÖ|ŻŇcô_[×vOýÚ׸ř/źÍ{˛Óű¬©×Úä ::Dostupne meteorologicke udaje::Teplota °C: 23.55Relativni vlhkost %: 62.55Tlak hPa.: 956.46 ::Dostupne GPS udaje::Zemepisna sirka: 0.000000 delka: 0.000000 Pocet satelitu: 0 Nadmorska vyska m.n.n: 0.00 Rychlost v km/h: 0.00Datum a cas: żńUÖ|ŻŇcô_[×vOýÚ׸ř/źÍ{˛Óű¬©×Úä ::Dostupne meteorologicke udaje::Teplota °C: 23.88Relativni vlhkost %: 62.05Tlak hPa.: 956.46 ::Dostupne GPS udaje::Zemepisna sirka: 0.000000 delka: 0.000000 Pocet satelitu: 0 Nadmorska vyska m.n.n: 0.00 Rychlost v km/h: 0.00Datum a cas: żńUÖ|ŻŇcô_[×vOýÚ׸ř/źÍ{˛Óű¬©×Úä ::Dostupne meteorologicke udaje::Teplota °C: 23.91Relativni vlhkost %: 61.64Tlak hPa.: 956.42 ::Dostupne GPS udaje::Zemepisna sirka: 0.000000 delka: 0.000000 Pocet satelitu: 0 Nadmorska vyska m.n.n: 0.00 Rychlost v km/h: 0.00Datum a cas: żńUÖ|ŻŇcô_[×vOýÚ׸ř/źÍ{˛Óű¬©×Úä ::Dostupne meteorologicke udaje::Teplota °C: 23.94Relativni vlhkost %: 61.29Tlak hPa.: 956.48 ::Dostupne GPS udaje:: Zemepisna sirka: 0.000000 delka: 0.000000 Pocet satelitu: 0 Nadmorska vyska m.n.n: 0.00 Rychlost v km/h: 0.00 Datum a cas: ::Dostupne meteorologicke udaje:: Teplota stupne C: 24.01 Relativni vlhkost %: 60.44 Tlak hPa.: 956.47 ::Dostupne GPS udaje:: Zemepisna sirka: 0.000000 delka: 0.000000 Pocet satelitu: 0 Nadmorska vyska m.n.n: 0.00 Rychlost v km/h: 0.00 Datum a cas: ::Dostupne meteorologicke udaje:: Teplota stupne C: 24.03 Relativni vlhkost %: 60.32 Tlak hPa.: 956.44 ::Dostupne GPS udaje:: Zemepisna sirka: 0.000000 delka: 0.000000 Pocet satelitu: 0 Nadmorska vyska m.n.n: 0.00 Rychlost v km/h: 0.00 Datum a cas: ::Dostupne meteorologicke udaje:: Teplota stupne C: 24.04 Relativni vlhkost %: 60.21 Tlak hPa.: 956.46 ::Dostupne GPS udaje:: Zemepisna sirka: 0.000000 delka: 0.000000 Pocet satelitu: 0 Nadmorska vyska m.n.n: 0.00 Rychlost v km/h: 0.00 Datum a cas: żđUÖüŻŇkô[×VOýZǸ¸/źÍ{˛Óű®©×Ú1 ’ ::Dostupne meteorologicke udaje:: Teplota stupne C: 13.70 Relativni vlhkost %: 32.39 Tlak hPa.: 956.42 ::Dostupne GPS udaje:: Zemepisna sirka: 0.000000 delka: 0.000000 Pocet satelitu: 0 Nadmorska vyska m.n.n: 0.00 Rychlost v km/h: 0.00 Datum a cas: żđUÖüŻŇkô[×VOýZǸ¸/źÍ{˛Óű®©×Ú1 ’ ::Dostupne meteorologicke udaje:: Teplota stupne C: 13.34 Relativni vlhkost %: 32.44 Tlak hPa.: 956.44 ::Dostupne GPS udaje:: Zemepisna sirka: 49.1*2778 delka: 14.997972 Pocet satelitu: 5 Nadmorska vyska m.n.n: 505.90 Rychlost v km/h: 0.11 Datum a cas: 02/20/2018 17:06:46 ::Dostupne meteorologicke udaje:: Teplota stupne C: 12.92 Relativni vlhkost %: 33.99 Tlak hPa.: 956.48 ::Dostupne GPS udaje:: Zemepisna sirka: 49.1*2793 delka: 14.998005 Pocet satelitu: 5 Nadmorska vyska m.n.n: 505.30 Rychlost v km/h: 3.15 Datum a cas: 02/20/2018 17:06:49 ::Dostupne meteorologicke udaje:: Teplota stupne C: 12.39 Relativni vlhkost %: 34.32 Tlak hPa.: 956.47 ::Dostupne GPS udaje:: Zemepisna sirka: 49.1*2801 delka: 14.998020 Pocet satelitu: 5 Nadmorska vyska m.n.n: 504.50 Rychlost v km/h: 0.31 Datum a cas: 02/20/2018 17:06:53 ::Dostupne meteorologicke udaje:: Teplota stupne C: 12.00 Relativni vlhkost %: 34.44 Tlak hPa.: 956.47 ::Dostupne GPS udaje:: Zemepisna sirka: 49.1*2801 delka: 14.998027 Pocet satelitu: 5 Nadmorska vyska m.n.n: 503.80 Rychlost v km/h: 0.30 Datum a cas: 02/20/2018 17:06:56 ::Dostupne meteorologicke udaje:: Teplota stupne C: 11.70 Relativni vlhkost %: 34.71 Tlak hPa.: 956.51 ::Dostupne GPS udaje:: Zemepisna sirka: 49.1*2801 delka: 14.998038 Pocet satelitu: 5 Nadmorska vyska m.n.n: 503.60 Rychlost v km/h: 0.06 Datum a cas: 02/20/2018 17:06:59 ::Dostupne meteorologicke udaje:: Teplota stupne C: 11.35 Relativni vlhkost %: 35.58 Tlak hPa.: 956.48