Problem when reading file line by line to feed it in to char

Hi all!
I making a program that uses a circular buffer and saves it to a file.
The thing is i wan to load the file and feed it to the circular buffer.
I need to parse each line to load the buffer. So i use strtok.
The log file is a csv file with this form:

LUN 00:00,20.00,50.00
LUN 00:01,21.00,51.00

I think two lines is enough for testing purposes.
But i have a problem.
The code is this:

#include <CircularBuffer.h>
#include <string.h>
#include <LittleFS.h>

unsigned long log_prevTime = 0;
unsigned int log_time = 10000;
unsigned long tPrevioSensor = 0;
unsigned long sensor_delay = 1000;
double tempD1;
double rHum;

namespace data {
  typedef struct {
    String time;
    double t;
    double h;
  } record;
  void print(record r) {
   File file = LittleFS.open("log.csv", "a");
      file.print(r.time);
      file.print(",");
      file.print(r.t);
      file.print(",");
      file.println(r.h);
      file.close();
    }

  }


CircularBuffer<data::record, 128> structs;

void getSensorData(){
  tempD1 = random(20,30);
  rHum = random(50, 60);
}
void wrBuff(){
  LittleFS.remove("log.csv");
 
  
  String ft = "MAR 00:00";
  structs.push(data::record{ft, tempD1, rHum});
  for (int j=0; j < structs.size(); j++){
    data::print(structs[j]);
  }
}
void load_chart(){
  File chart = LittleFS.open("log.csv","r");
  
  String ln;
  byte index = 0;
  char *str[4];
  char *ptr = NULL;
  String H;
  float t;
  float h;
  char *linea;
  while (chart.available()){
    
    chart.readStringUntil('\n').toCharArray(linea, 25);
    //linea[23] = '\n';
    Serial.println(linea);
    ptr = strtok(linea,",");
    while(ptr != NULL){
      str[index] = ptr;
      index++;
      ptr = strtok(NULL,",");
    }
    H = str[0];
    t = atof(str[1]);
    h = atof(str[2]);
    structs.push(data::record{H,t,h});
    
    Serial.println(H);
    Serial.println(t);
    Serial.println(h);
  }
  chart.close();
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
    // Initialize LittleFS
    if (!LittleFS.begin()) {
      Serial.println("Ha ocurrido un error al montar los archivos del LFS.");
      return;
    }
    else{
      Serial.println("Sistema de Archivos Inciado correctamente.");
    }
    load_chart();
}

void loop() {
  // put your main code here, to run repeatedly:
  if(millis() >= tPrevioSensor + sensor_delay){
      getSensorData();
      tPrevioSensor = millis();
    }
    if (millis() >= log_prevTime + log_time){
    /*log_file(String(tempD1)+ "," + String(rHum));*/
    wrBuff();
    log_prevTime = millis();
  }
}

The part that's not working is the linea variable. it doesnt get printed nor filled by the chart.readStringUntil("\n").toCharArray(linea, 25);

What am i doing wrong?

e

You posted and incomplete code.

I thought that was enough. the full code is very large. Ill try to make a snippet with all parts involved in this problem.

How big is the buffer?

char *linea;

No, not a snippet! Make an MRE. This is the smallest possible complete code that compiles and demonstrates the problem at hand.

1 Like
namespace data {
  typedef struct {
    String time;
    double t;
    double h;
  } record;
  void print(record r) {
   File file = LittleFS.open("log.csv", "a");
      file.print(r.time);
      file.print(",");
      file.print(r.t);
      file.print(",");
      file.println(r.h);
      file.close();
    }

  }


CircularBuffer<data::record, 128> structs;

void load_chart(){
  File chart = LittleFS.open("log.csv","r");
  
  String ln;
  byte index = 0;
  char *str[4];
  char *ptr = NULL;
  String H;
  float t;
  float h;
  char *linea;
  while (chart.available()){
    
    chart.readStringUntil('\n').toCharArray(linea, 25);
    //linea[23] = '\n';
    
    ptr = strtok(linea,",");
    while(ptr != NULL){
      str[index] = ptr;
      index++;
      ptr = strtok(NULL,",");
    }
    H = str[0];
    t = atof(str[1]);
    h = atof(str[2]);
    structs.push(data::record{H,t,h});
    
    Serial.println(H);
    Serial.println(t);
    Serial.println(h);
  }
  chart.close();
}

im on it

24 characters. Or at least that should be. but i cant initialize it with size.

I made an MRE and edited the first post

char linea[25];

chart.readStringUntil('\n').toCharArray(linea, 25);

doing that gives this and esp resets

15:02:25.706 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
15:02:25.753 ->
15:02:25.753 -> Exception (3):
15:02:25.800 -> epc1=0x4020dbc7 epc2=0x00000000 epc3=0x00000000 excvaddr=0x40207330 depc=0x00000000
15:02:25.847 ->
15:02:25.847 -> >>>stack>>>
15:02:25.893 ->
15:02:25.893 -> ctx: cont
15:02:25.893 -> sp: 3ffffd00 end: 3fffffd0 offset: 0150
15:02:25.939 -> 3ffffe50: 0000000b 00000010 00000001 401009a0
15:02:25.988 -> 3ffffe60: 0000000b 00000010 3fffff40 00000000
15:02:26.035 -> 3ffffe70: 40207330 00000001 3fff0800 4020242c
15:02:26.082 -> 3ffffe80: 3ffe8368 00000000 40207330 00000000
15:02:26.128 -> 3ffffe90: 00000001 3fffff67 3fffff40 40207853
15:02:26.175 -> 3ffffea0: 00000000 00000001 3fffff40 3ffef818
15:02:26.269 -> 3ffffeb0: 0000000a 3fffff10 00000000 40206214
15:02:26.315 -> 3ffffec0: 00000868 0000010d 3ffe85e4 00000000
15:02:26.361 -> 3ffffed0: 3fffff60 00000004 3ffe8859 40207895
15:02:26.409 -> 3ffffee0: 3fffdad0 3ffe87d6 00000000 00000000
15:02:26.456 -> 3ffffef0: 3fffff61 00000000 3fffff40 3ffef818
15:02:26.503 -> 3fffff00: 3fffdad0 3ffe87d6 00000002 40205971
15:02:26.550 -> 3fffff10: 4020b320 00000000 000003e8 0000005e
15:02:26.598 -> 3fffff20: 00000000 3fff08b4 3fff08a4 402064f0
15:02:26.646 -> 3fffff30: 00000000 00000000 3ffef780 00000020
15:02:26.739 -> 3fffff40: 00000000 000b000f 00000000 3ffe885b
15:02:26.787 -> 3fffff50: 00000008 40209508 ffffffff 00000001
15:02:26.833 -> 3fffff60: 302e302c 2e300030 000d3030 40208f78
15:02:26.881 -> 3fffff70: 3ffe8a2a fffffffc 3fffff61 3fffff66
15:02:26.928 -> 3fffff80: 40207330 3ffe8a28 30302e30 3ffef800
15:02:26.974 -> 3fffff90: 04000000 00000000 3ffef7ac 00000000
15:02:27.021 -> 3fffffa0: 3fffdad0 00000000 00000000 00000000
15:02:27.068 -> 3fffffb0: feefeffe 00000000 3ffef804 40207d84
15:02:27.114 -> 3fffffc0: feefeffe feefeffe 3fffdab0 40100c45
15:02:27.207 -> <<<stack<<<
15:02:27.207 ->

I don't know why Serial.println(linea); doesn't get printed.

the serial.println(linea); was making esp restart

linea is just an uninitialized pointer. It's not pointing to any memory you're allowed to use. Try:

    char linea[30];

Thanks i think im closer to solving it.
Now at least H,t,m gets a value.
But starts to reset after a while.
Must be running out of ram?

15:15:08.848 -> ⸮X%⸮h⸮=⸮⸮⸮B⸮Sistema de Archivos Inciado correctamente.
15:15:08.988 -> MAR 00:00
15:15:08.988 -> 26.05
15:15:08.988 -> 50.00
15:15:09.036 -> MIE 00:00
15:15:09.036 -> 27.00
15:15:09.036 -> 51.00
15:15:09.036 -> MAR 00:00
15:15:09.036 -> 29.00
15:15:09.083 -> 53.00
15:15:09.083 -> MAR 00:00
15:15:09.083 -> 25.00
15:15:09.083 -> 51.00
15:15:09.083 -> MAR 00:00
15:15:09.129 -> 27.00
15:15:09.129 -> 51.00
15:15:09.129 -> MAR 00:00
15:15:09.129 -> 23.00
15:15:09.129 -> 52.00
15:15:09.129 ->
15:15:09.129 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
15:15:09.226 ->
15:15:09.226 -> Exception (2):
15:15:09.226 -> epc1=0x3fffff70 epc2=0x00000000 epc3=0x00000000 excvaddr=0x3fffff70 depc=0x00000000
15:15:09.319 ->
15:15:09.319 -> >>>stack>>>
15:15:09.319 ->
15:15:09.319 -> ctx: cont
15:15:09.366 -> sp: 3ffffe70 end: 3fffffd0 offset: 0150
15:15:09.412 -> 3fffffc0: feefeffe feefeffe 3fffdab0 40100c45
15:15:09.459 -> <<<stack<<<
15:15:09.459 ->

Yeahp is a memory problem.
when it loads more than 4 indexes of circular buffer/file, it starts resetting

Post the complete code that's producing that result.

#include <CircularBuffer.h>
#include <string.h>
#include <LittleFS.h>

unsigned long log_prevTime = 0;
unsigned int log_time = 10000;
unsigned long tPrevioSensor = 0;
unsigned long sensor_delay = 1000;
double tempD1;
double rHum;

namespace data {
  typedef struct {
    String time;
    double t;
    double h;
  } record;
  void print(record r) {
   File file = LittleFS.open("log.csv", "a");
      file.print(r.time);
      file.print(",");
      file.print(r.t);
      file.print(",");
      file.println(r.h);
      file.close();
    }

  }


CircularBuffer<data::record, 128> structs;

void getSensorData(){
  tempD1 = random(20,30);
  rHum = random(50, 60);
}
void wrBuff(){
  LittleFS.remove("log.csv");
  
  String ft = "JUE 00:05";
  
  structs.push(data::record{ft, tempD1, rHum});
  
  
  for (int j=0; j < structs.size(); j++){
    data::print(structs[j]);
  }
  
  
}
void load_chart(){
  File chart = LittleFS.open("log.csv","r");
  
  byte index = 0;
  char *str[4];
  char *ptr = NULL;
  String H;
  float t;
  float h;
 
  while (chart.available()){
    char linea[23];
    chart.readStringUntil('\n').toCharArray(linea, 23);
    
    ptr = strtok(linea,",");
    while(ptr != NULL){
      str[index] = ptr;
      index++;
      ptr = strtok(NULL,",");
    }
    H = str[0];
    t = atof(str[1]);
    h = atof(str[2]);
    structs.push(data::record{H,t,h});
    
  }
  chart.close();
}
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
    // Initialize LittleFS
    if (!LittleFS.begin()) {
      Serial.println("Ha ocurrido un error al montar los archivos del LFS.");
      return;
    }
    else{
      Serial.println("Sistema de Archivos Inciado correctamente.");
    }
    load_chart();
}

void loop() {
  // put your main code here, to run repeatedly:
  if(millis() >= tPrevioSensor + sensor_delay){
      getSensorData();
      tPrevioSensor = millis();
    }
    if (millis() >= log_prevTime + log_time){
    
    wrBuff();
    log_prevTime = millis();
  }
}

ESP32? ESP8266? Which board?

is esp8266.
I noticed the problem starts when load_chart() has to load 6 lines.
Before that it runs ok.
Im thinking esp8266 isnt big enough to load more than those six lines.
or i have a memmory leak somewhere