This shows you the differences between two versions of the page.
|
pm:prj2023:adarmaz:sistem-cartografiere-sol [2023/05/29 20:01] ioana.profeanu [Parsare date GPS] |
pm:prj2023:adarmaz:sistem-cartografiere-sol [2023/05/30 09:13] (current) ioana.profeanu [Download cod] |
||
|---|---|---|---|
| Line 61: | Line 61: | ||
| În lipsa vreunui input de la utilizator, se verifică dacă au trecut 60 de minute de la ultima citire a datelor, iar daca da, se face recitirea. | În lipsa vreunui input de la utilizator, se verifică dacă au trecut 60 de minute de la ultima citire a datelor, iar daca da, se face recitirea. | ||
| + | Programul face diverse verificări și afișări de mesaje pe ecran în cazurile speciale/de eroare, precum căutarea unei plante după resetarea metricilor, imposibilitatea de a citi cardul SD (de exemplu, dacă acesta nu este introdus) și dacă nu există nicio plantă care să poată fi plantată în mediul curent. | ||
| ==== Configurare timer ==== | ==== Configurare timer ==== | ||
| Line 68: | Line 69: | ||
| <code cpp> | <code cpp> | ||
| // timer contorizare durata de afisaj a statisticilor în stand-by | // timer contorizare durata de afisaj a statisticilor în stand-by | ||
| - | unsigned long int timerDisplayInfo = 0; | + | volatile unsigned long int timerDisplayInfo = 0; |
| // timer contorizare timp de la ultimul input al user-ului | // timer contorizare timp de la ultimul input al user-ului | ||
| - | int timerUser = 0; | + | volatile int timerUser = 0; |
| // contorizare timpul unui frame | // contorizare timpul unui frame | ||
| - | int frameTime = 0; | + | volatile int frameTime = 0; |
| ISR(TIMER1_COMPA_vect) { | ISR(TIMER1_COMPA_vect) { | ||
| Line 93: | Line 94: | ||
| // set prescaler to 1024 | // set prescaler to 1024 | ||
| TCCR1B |= (1 << CS12) | (1 << CS10); | TCCR1B |= (1 << CS12) | (1 << CS10); | ||
| - | // enable timer compare interrupts | + | // enable timer compare interrupts |
| - | TIMSK1 |= (1 << OCIE1A); | + | TIMSK1 |= (1 << OCIE1A); |
| } | } | ||
| </code> | </code> | ||
| Line 149: | Line 150: | ||
| Pentru lucrul cu cardul SD, am utilizat biblioteca SD.h, ce pune la dispoziție funcții de bază pentru scrierea și citirea datelor de pe cardul SD. | Pentru lucrul cu cardul SD, am utilizat biblioteca SD.h, ce pune la dispoziție funcții de bază pentru scrierea și citirea datelor de pe cardul SD. | ||
| + | |||
| + | === Scrierea metricilor medii === | ||
| + | |||
| + | La fiecare recalculare a metricilor, mediile datelor citite sunt stocate și pe cardul SD într-un fișier de log numit metrics.txt, inserându-se media temperaturii, a umitității aerului și solului, a luminozității și numărul de citiri. | ||
| <spoiler Cod scriere metrici pe cardul SD> | <spoiler Cod scriere metrici pe cardul SD> | ||
| <code cpp> | <code cpp> | ||
| - | void writeMetricsToSD(){ | + | // function which writes the average metrics to sd card |
| + | void writeMetricsToSD() | ||
| + | { | ||
| if (SD.begin(7)) { | if (SD.begin(7)) { | ||
| File myFile; | File myFile; | ||
| Line 186: | Line 193: | ||
| </code> | </code> | ||
| </spoiler> | </spoiler> | ||
| - | |||
| - | === Scrierea metricilor medii === | ||
| - | |||
| - | La fiecare recalculare a metricilor, mediile datelor citite sunt stocate și pe cardul SD într-un fișier de log numit metrics.txt, inserându-se media temperaturii, a umitității aerului și solului, a luminozității și numărul de citiri. | ||
| === Citirea plantelor === | === Citirea plantelor === | ||
| Line 219: | Line 222: | ||
| <code cpp> | <code cpp> | ||
| - | void displayPlantsList(bool showAll) { | + | // functions which displays the valid plants |
| - | display.clear(); // Clear the display | + | // on the display |
| - | display.setCursor(0, 0); // Set the cursor position | + | void displayPlantsList(bool showAll) |
| - | if (SD.begin(7)){ | + | { |
| + | display.clear(); | ||
| + | display.setCursor(0, 0); | ||
| + | // try to read from SD card | ||
| + | if (SD.begin(7)) { | ||
| File myFile; | File myFile; | ||
| - | if(SD.exists("plants.txt")) { | + | if (SD.exists("plants.txt")) { |
| myFile = SD.open("plants.txt"); | myFile = SD.open("plants.txt"); | ||
| - | + | // if the file exists, read from it | |
| - | if(myFile) { | + | if (myFile) { |
| int noPlantsOk = 0; | int noPlantsOk = 0; | ||
| - | + | // parse the data of the plant by extracting it; | |
| - | while(myFile.available()) { | + | // each data is delimited by a comma |
| + | while (myFile.available()) { | ||
| bool okPlant = false; | bool okPlant = false; | ||
| String line = myFile.readStringUntil('\n'); | String line = myFile.readStringUntil('\n'); | ||
| Line 236: | Line 244: | ||
| int values[9]; | int values[9]; | ||
| int index = 0; | int index = 0; | ||
| + | // read line | ||
| while (line.length() > 0) { | while (line.length() > 0) { | ||
| int commaIndex = line.indexOf(','); | int commaIndex = line.indexOf(','); | ||
| - | | ||
| if (commaIndex != -1) { | if (commaIndex != -1) { | ||
| String element = line.substring(0, commaIndex); | String element = line.substring(0, commaIndex); | ||
| - | line = line.substring(commaIndex + 2); // Skip comma and space after each value | + | line = line.substring(commaIndex + 2); |
| | | ||
| if (index == 0) { | if (index == 0) { | ||
| Line 248: | Line 255: | ||
| } else { | } else { | ||
| values[index - 1] = element.toInt(); | values[index - 1] = element.toInt(); | ||
| + | // check if the plant is between parameters | ||
| if (showAll == false) { | if (showAll == false) { | ||
| if (index == 1) { | if (index == 1) { | ||
| Line 260: | Line 267: | ||
| if (index == 3) { | if (index == 3) { | ||
| int mediumTemp = sumTemps / timesRead; | int mediumTemp = sumTemps / timesRead; | ||
| - | if ((mediumTemp >= values[1] && mediumTemp <= values[2]) == false) { | + | if ((mediumTemp >= values[1] && mediumTemp <= values[2]) |
| + | == false) { | ||
| break; | break; | ||
| } | } | ||
| Line 267: | Line 275: | ||
| if (index == 5) { | if (index == 5) { | ||
| int mediumAirMoist = sumAirMoist / timesRead; | int mediumAirMoist = sumAirMoist / timesRead; | ||
| - | if ((mediumAirMoist >= values[3] && mediumAirMoist <= values[4]) == false) { | + | if ((mediumAirMoist >= values[3] && mediumAirMoist |
| + | <= values[4]) == false) { | ||
| break; | break; | ||
| } | } | ||
| Line 274: | Line 283: | ||
| if (index == 7) { | if (index == 7) { | ||
| int mediumSoilMoist = sumSoilMoist / timesRead; | int mediumSoilMoist = sumSoilMoist / timesRead; | ||
| - | if ((mediumSoilMoist >= values[5] && mediumSoilMoist <= values[6]) == false) { | + | if ((mediumSoilMoist >= values[5] && mediumSoilMoist |
| + | <= values[6]) == false) { | ||
| break; | break; | ||
| } | } | ||
| Line 283: | Line 293: | ||
| index++; | index++; | ||
| } else { | } else { | ||
| - | // Last value in the line (no comma at the end) | + | // read last value from line |
| String element = line; | String element = line; | ||
| values[index - 1] = element.toInt(); | values[index - 1] = element.toInt(); | ||
| int mediumLight = sumLight / timesRead; | int mediumLight = sumLight / timesRead; | ||
| - | if (showAll == false && (mediumLight >= values[7] && mediumLight <= values[8]) == false) { | + | if (showAll == false && (mediumLight >= values[7] |
| + | && mediumLight <= values[8]) == false) { | ||
| break; | break; | ||
| } | } | ||
| + | |||
| okPlant = true; | okPlant = true; | ||
| noPlantsOk++; | noPlantsOk++; | ||
| Line 295: | Line 307: | ||
| } | } | ||
| } | } | ||
| + | // if a plant was found, display it | ||
| if (okPlant) { | if (okPlant) { | ||
| - | checkAndDisplayPlant(name, values); | + | displayPlantDetails(name, values); |
| } | } | ||
| } | } | ||
| + | // if no plants were found | ||
| if (noPlantsOk == 0) { | if (noPlantsOk == 0) { | ||
| display.println("No plants matched!"); | display.println("No plants matched!"); | ||
| - | display.displayRows(); // Update the display | + | display.displayRows(); |
| delay(8000); | delay(8000); | ||
| } | } | ||
| Line 307: | Line 321: | ||
| | | ||
| } else { | } else { | ||
| + | // if the file is not found | ||
| display.println("Add plants.txt file first!"); | display.println("Add plants.txt file first!"); | ||
| - | display.displayRows(); // Update the display | + | display.displayRows(); |
| delay(8000); | delay(8000); | ||
| } | } | ||
| } | } | ||
| } else { | } else { | ||
| + | // if unable to read file | ||
| display.println("Failed to display plants!"); | display.println("Failed to display plants!"); | ||
| - | display.displayRows(); // Update the display | + | display.displayRows(); |
| delay(8000); | delay(8000); | ||
| } | } | ||
| } | } | ||
| - | | ||
| </code> | </code> | ||
| </spoiler> | </spoiler> | ||
| Line 332: | Line 347: | ||
| <code cpp> | <code cpp> | ||
| - | // function for extracting the latitude | + | // function which, from an input NMEA sentence, |
| - | String extractLatitude(const String& sentence) { | + | // extracts a string with the latitude |
| + | String extractCoordinates(const String& sentence) | ||
| + | { | ||
| int commas; | int commas; | ||
| if (sentence.indexOf("GPRMC") != -1) { | if (sentence.indexOf("GPRMC") != -1) { | ||
| Line 347: | Line 364: | ||
| int endIndex = -1; | int endIndex = -1; | ||
| + | // count commas and extract the value of the latitude | ||
| for (size_t i = 0; i < sentence.length(); i++) { | for (size_t i = 0; i < sentence.length(); i++) { | ||
| if (sentence[i] == ',') { | if (sentence[i] == ',') { | ||
| Line 366: | Line 384: | ||
| } | } | ||
| - | // function for receiving NMEA sentences | + | // function which reads NMEA sentences from |
| + | // software serial for 20 seconds and returns the | ||
| + | // latitude in case the sentence is valid | ||
| String getGPGGAsentence() | String getGPGGAsentence() | ||
| { | { | ||
| Line 375: | Line 395: | ||
| gpsSerial.begin(9600); | gpsSerial.begin(9600); | ||
| - | // repeat the reading for 20 seconds | ||
| while (timerDisplayInfo - currentTime < MINUTE / 4) { | while (timerDisplayInfo - currentTime < MINUTE / 4) { | ||
| if (gpsSerial.available()) { | if (gpsSerial.available()) { | ||
| Line 399: | Line 418: | ||
| return sentence; | return sentence; | ||
| } | } | ||
| - | |||
| </code> | </code> | ||
| </spoiler> | </spoiler> | ||
| Line 449: | Line 467: | ||
| ===== Download cod ===== | ===== Download cod ===== | ||
| - | Codul poate fi vizualizat [[https://github.com/ioanaprofeanu/Sistem-cartografiere-sol.git|aici]]. | + | Codul poate fi vizualizat [[https://github.com/ioanaprofeanu/Sistem-cartografiere-sol.git|aici]] sau descărcat {{:pm:prj2023:adarmaz:sistem_cartografiere_sol.zip|aici}}. |
| ===== Jurnal ===== | ===== Jurnal ===== | ||