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