michalmonday / CSV-Parser-for-Arduino

It turns CSV string into an associative array (like dict in python)
MIT License
57 stars 12 forks source link

Conflict between this library and RTClib #18

Closed enzoferrari1 closed 1 year ago

enzoferrari1 commented 1 year ago

Hi. I am currently using this library for a proyect. I have an SD card where a file called config.csv is present. Each file's row represents a change in the configuration of the program. I had no problems with the file, but when i added the RTClib and used the rtc.begin() function, the csv parser started to have incorrect lectures of the file. Does this mean that i can't use both libraries together? Why does this happen? Here is the code, ignore the first part where i define variables.

` // Código complementario para incorporar la lectura del archivo de configuracion programado // Our idea is having a file present in the SD card called config.csv where each row is a programmed change of variables // Any row's first field is either a 0 if the row was already loaded or a 1 if wasn't loaded, the second is the moment where that configuration should take place, the rest of the fields are all the variables to be changed. // Those variables are in the same order as showed in the MainProyect file, in the section "Variables Parametrizables" ("lastWatered" is not present in the config)

// Each field occupies a fixed amount of characters, so we know exactly how long each row is.

define ROW_LENGTH 57 // Fixed length of each row, counting the EOL characters

include "Time.h"

include

include "SD.h"

include

include

include

include

include "RTClib.h"

include

Sd2Card card; SdVolume volume; SdFile root; File myFile; DateTime now; RTC_DS3231 rtc;

const int chipSelect = 4;

unsigned long wateringTime; // Cantidad de tiempo(en milisegundos) el cual dura el riego const int8_t wateringTimeAdr = 0; // Dirección en la memoria EEPROM donde se guardará la variable unsigned long logInterval; // cada cuanto tiempo se realizan los senseos y guardado de ellos const int8_t logIntervalAdr = 4; unsigned long wateringInterval; // Período de tiempo para el riego, osea, cada cuanto está disponible el riego, si todavía no paso este tiempo desde el último regado, no se riega const int8_t wateringIntervalAdr = 8; uint16_t soilHumLim; // Umbral de humedad del suelo para saber si regar o no const int8_t soilHumLimAdr = 12; byte ambHumLim; // Umbral de humedad del ambiente para saber si prender el extractor o no const int8_t ambHumLimAdr = 16; byte startWateringAt; // Se desea regar en un rango horario del día determinado const int8_t startWateringAtAdr = 20; byte endWateringAt; // start y end representan las horas en donde arranca y termina el período const int8_t endWateringAtAdr = 21; byte lightsON; // Cuando prendemos las luces const int8_t lightsONAdr = 22; byte lightsOFF; // Cuando apagamos las luces const int8_t lightsOFFAdr = 23; time_t lastWatered; // Variable que guarda la fecha y hora del último regado, tipo de dato uint32_t para guardar tiempo, ver más adelante cuando se guarde en el regado const int8_t lastWateredAdr = 24;

CSV_Parser cp(/format/ "ucuLuLuLuducucucucuc", /has_header/ true, /delimiter/ ',');

void setup() {

Serial.begin(9600);

Wire.begin(); if(! rtc.begin()) { delay(5000); Serial.println("Error rtc"); } // Establece la fecha y hora del rtc a la fecha en el cual se compiló el sketch, si el rtc no está corriendo if (rtc.lostPower()) { // If we have a rtc model other than 3231, we could use the "isrunning" method rtc.adjust(DateTime(F(DATE), F(TIME))); } now = rtc.now();

pinMode(chipSelect, OUTPUT);

delay(5000);

if (!SD.begin(chipSelect)){ Serial.println("error sd"); }

myFile = SD.open("/config.CSV", O_RDWR); checkConfig(); for (int16_t n = 0 ; n < 200 ; n++) { myFile.seek(n); Serial.print(n); Serial.print(", "); Serial.write(myFile.read()); Serial.println("."); delay(5); } myFile.flush(); cp.print();

}

void loop() { // put your main code here, to run repeatedly:

}

// Function that marks a row as already used by changing the first character from 1 to 0

void deleteLine(uint32_t lineNumber) { // lineNumber is the number of the line selected to mark as already loaded (starting at 1) SD.open("config.CSV", O_RDWR); uint32_t pointer = (lineNumber + 1)*ROW_LENGTH; myFile.seek(pointer); // sets the pointer of the file at the start of the desired row

// We only want to overwrite the first character. myFile.print("0"); }

void checkConfig(){ if (cp.readSDfile("/config.CSV")) { uint8_t notLoaded = (uint8_t)cp["loaded"]; uint32_t configTime = (uint32_t)cp["cTime"]; uint32_t SDwateringTime = (uint32_t)cp["wTime"]; uint32_t SDwateringInterval = (uint32_t)cp["watInt"]; uint16_t SDsoilHumLim = (uint16_t)cp["soilLim"]; uint8_t SDambHumLim = (uint8_t)cp["ambLim"]; uint8_t SDstartWateringAt = (uint8_t)cp["sW"]; uint8_t SDendWateringAt = (uint8_t)cp["eW"]; uint8_t SDlightsON = (uint8_t)cp["lON"]; uint8_t SDlightsOFF = (uint8_t)cp["lOFF"]; for (int row = 0; row <= cp.getRowsCount(); row++) { //if(notLoaded[row] == 1) { Serial.print(row); Serial.print(" , "); Serial.println(SDstartWateringAt[row]); delay(500);

  if (notLoaded[row] == 1) { // (rtc.now().unixtime() > configTime[row])
    deleteLine(row);
  }
}

} else { Serial.println("Error"); } } ` And this is the csv file config.csv

When i call the method cp.print(), this is what appears in the serial: Header: loaded | cTime | wTime | watInt | soilLim | ambLim | sW | eW | lON | lOFF Types: uint8_t | uint32_t | uint32_t | uint32_t | uint16_t | uint8_t | uint8_t | uint8_t | uint8_t | uint8_t Values: 0 | 1357971456 | 1111111111 | 1357971456 | 1111 | 111 | 11 | 11 | 11 | 11 0 | 117637459 | 1111111111 | 117637459 | 1111 | 111 | 11 | 11 | 11 | 11 0 | 524292 | 1111111111 | 524292 | 1111 | 111 | 11 | 11 | 11 | 11 0 | 327880 | 1111111111 | 327880 | 1111 | 111 | 11 | 11 | 11 | 11 0 | 4 | 1111111111 | 4 | 1111 | 111 | 11 | 11 | 11 | 11

The "cTime", and "watInt" columns should be all 1's, but instead those values appears. This is a problem that doesn't appear when instead i run the same program without the rtc.begin() and rtc.lostPower() methods.

enzoferrari1 commented 1 year ago

Hey, it's me again. I think the problem is caused by dynamic memory shortage. I guess the library builds a bidimensional array. I already adressed the problem. Thanks