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 ===== | ||