Differences

This shows you the differences between two versions of the page.

Link to this comparison view

pm:prj2023:adarmaz:sistem-cartografiere-sol [2023/05/29 19:59]
ioana.profeanu [Utilizarea cardului SD]
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 211: Line 214:
 | 4    | Polar | | 4    | Polar |
  
-Pentru modul de afișare a plantelor ce pot trăi în mediul curent, se compară valorile medii pentru fiecare dintre categoriile de metrici, afișându-se doar plantele care se încadrează în datele stocate pe cardul SD.+Pentru modul de afișare a plantelor ce pot trăi în mediul curent, se compară valorile medii pentru fiecare dintre categoriile de metrici, primul criteriu de comparare fiind clima, afișându-se doar plantele care se încadrează în parametrii dați.
  
 Pentru modul de afișare a tututor plantelor, se afișează pe ecran toate plantele, fără a face vreo filtrare. Pentru modul de afișare a tututor plantelor, se afișează pe ecran toate plantele, fără a face vreo filtrare.
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 324: Line 339:
 ==== Parsare date GPS ==== ==== Parsare date GPS ====
  
-Pentru a utiliza modulul GPS NEO-6M, am folosit biblioteca SoftwareSerial.h. Deși în mod normal modulul utilizează USART, nu am folosit ​cei doi pini dedicațai Arduino-ului,​ deoarece acest lucru m-ar fi împiedicat din a face debugging utilizând afișarea ​la serială.+Pentru a utiliza modulul GPS NEO-6M, am folosit biblioteca SoftwareSerial.h. Deși în mod normal modulul utilizează USART, nu am folosit ​pinii RX șTX Arduino-ului,​ deoarece acest lucru m-ar fi împiedicat din a face debugging utilizând afișarea serială.
 Am decis, de asemenea, să îmi implementez propria funcție de parsare a input-ului primit de la GPS, din considerente de memorie (introducerea unei biblioteci adiționale ar fi costat memorie), dar și pentru că doream să extrag doar latitudinea din input-ul primit (doar de aceasta este nevoie pentru a determina clima). Am decis, de asemenea, să îmi implementez propria funcție de parsare a input-ului primit de la GPS, din considerente de memorie (introducerea unei biblioteci adiționale ar fi costat memorie), dar și pentru că doream să extrag doar latitudinea din input-ul primit (doar de aceasta este nevoie pentru a determina clima).
  
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 =====
  
pm/prj2023/adarmaz/sistem-cartografiere-sol.1685379585.txt.gz · Last modified: 2023/05/29 19:59 by ioana.profeanu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0