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
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;
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");
}
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.
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
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);
} 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.