Go Down

Topic: <Solved> Arduino Nano writes wrong on SD (Read 334 times) previous topic - next topic

ardumaker_ch

Sep 11, 2020, 11:15 am Last Edit: Sep 12, 2020, 12:05 am by ardumaker_ch
Good day together

I am new to the forum and am happy to be here.
I have already realized some projects on the arduino, but now I have a problem with my SD, which is edited by an Arduino Nano (old Bootloader).

My program does the following: first I call the function set(). This reads a text file into a char array (needs to be a char aaray since I also want to replace numbers with letters) with 8 rows and 5 columns. Of course the SD has exactly these 8 lines and 5 columns.

Then I call the function delet_row(), which "deletes" the desired row by skipping the row while writing. To get the right number of rows at the end, I insert a new row at the end, which is filled with zeros and separated by ";", just like the rest.

My problem now. When I run the program the first time, everything works fine. The second time, however, it inserts an additional zero at the third last line and takes away a zero at the second last line. On the third try it only gets worse...  :smiley-sad:

I try to find the error for a long time, but fail every time.
I would be glad if you would help me and I am grateful for every message. Thanks a lot!

My program:

Code: [Select]

#include <SPI.h>
#include <SD.h>

String toRead= "REWR.TXT";
char delim = ';';
const int x = 5;
const int y = 8;
String param[y][x];



void setup()
{
  
  Serial.begin(9600);

  set();
  delete_row(0);
}

void loop()
{
  delay(1000);
}


void set(){
  delay(100);
  SD.begin(4);
  File dataFile;
  dataFile = SD.open(toRead);
  int i=0;
  int j=0;
  String stringOne = "";
  while (dataFile.available()) {
    char letter = dataFile.read();
    if (letter != '\r' || letter != delim ){
      stringOne.concat(String(letter));
    }
    if (letter == delim || letter == '\r'){
      if (i == x){
        i = 0;
        j++;
      }
      stringOne.replace(String(delim),"");
      stringOne.replace("\n","");
      param[j][i] = stringOne;
      i++;
      stringOne="";
    }
  }
  param[j][i]=stringOne;
  dataFile.close();
  stringOne = "";
}


void delete_row(int del_row){

  delay(100);
  SD.begin(4);
  File dataFile;
  SD.remove(toRead);
  
  delay(100);

  SD.begin(4);
  dataFile = SD.open(toRead, FILE_WRITE);
  if(dataFile){
    int i=0;
    int j=0;
    for (i = 0; i < (y+1); i++) {
      delay(1000);
      if (i == del_row){
        Serial.println(i);
        continue;
      }
      for (j = 0; j < x; j++) {
        if (i == y){
          if (j == (x-1)){
            dataFile.print("0");
            Serial.print("0");
          }
          else{
            dataFile.print("0");
            dataFile.print(String(delim));
            Serial.print("0");
            Serial.print(String(delim));
          }
        }
        else{
          if (j == (x-1)){
            dataFile.print(String(param[i][j]));
            dataFile.print("\n");
            Serial.print(String(param[i][j]));
            Serial.print("\n");
          }
          else{
            dataFile.print(String(param[i][j]));
            dataFile.print(String(delim));
            Serial.print(String(param[i][j]));
            Serial.print(String(delim));
          }
        }
      }
     }
   }
  dataFile.close();
  delay(100);
}




My file "REWR.TXT that I want to edit:
Code: [Select]

1;2;3;4;5
11;21;31;41;51
12;22;32;42;52
13;23;33;43;53
14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;57



Result after an execution: (everything works fine)
Code: [Select]

11;21;31;41;51
12;22;32;42;52
13;23;33;43;53
14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;57
0;0;0;0;0



Result after two executions: (adds a zero)
Code: [Select]

12;22;32;42;52
13;23;33;43;53
14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;570
0;0;0;0;
0;0;0;0;0



Result after three executions:  (a new zero)
Code: [Select]

13;23;33;43;53
14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;5700
0;0;0;0;0
0;0;0;;
0;0;0;0;0



Result after four executions:  (something   :o )
Code: [Select]

14;24;34;44;54
15;25;35;45;55
16;26;36;46;56
17;27;37;47;57000
0;0;0;00;0
0;;0;0;0
0;0;;;
0;0;0;0;0

countrypaul

#1
Sep 11, 2020, 08:11 pm Last Edit: Sep 11, 2020, 08:31 pm by countrypaul
What is this statement meant to do?
Code: [Select]
   
if (letter != '\r' || letter != delim ){
      stringOne.concat(String(letter));
    }

Looks to me as though it will always be true, if it is a delim then its not /r  I think you wanted AND rather then OR in there - but I don't think it is the cause of your problem.

Can you le us know exactly what the print output on serial is?

ardumaker_ch

Hello countrypaul

Thanks for your message.
it should just check wether it's a delim / line break or not.

But that's not the problem. The problem is during deleting. The other parts works fine :)

countrypaul

My concern is that the logic on that line will always result in the if statement being entered unless  \r is the delimiter.

The result could be that the array contains not just 57, but 57\r,  the \r not being visible especially if there is a /n with it.

It might be worth putting some Serial.println in after your  dataFile.print("0"); and printing out the values of i,j,x,y just to be sure they are what we expect.
 

jremington

Use of Strings will eventually cause your Arduino to misbehave, and crash. 

It is much better to use the C-string (zero-terminated character array) functions.

ardumaker_ch

Hey everyone. I solved the problem.

The problem was, that i forgot an if condition which adds a "\r" in every second last row. An "\n" wasn't enough.


I will update the title as solved.
Thanks for all your comments  :D

Go Up