Pages: [1]   Go Down
Author Topic: Unexpected infinite restart loop in setup()  (Read 474 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I am using an Arduino Mega 2560

So, I am completely lost as to what is happening right now. Basically, the code is supposed to read a bunch of text files and output their delimited contents to the serial monitor. The content of the files looks something like this:
Code:
:name: // Move
:character:         // Character
// This is a comment
:damage:                 // Damage
:meter:                 // Meter
:advantage:                                                   // Advantage
:101010101010,        // Combo
101010101010,
101010101010,
101010101010,
101010101010
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,
101010101010,:

So far, I can succesfully tell the difference between important areas of the file and comment sections, and can read the important data. But for some reason, once the code is finished analyzing the content of the name field, it then proceeds to overwrite the variable containing the name field data (it will make sense when you see the code):
Code:
#include <SD.h>
int chipSelect = 10;
int charArrayCounter = 0; // I use this to concatenate
int currPosition = 0;
boolean ignoreFlag = true; // true if you are supposed to ignore

// Arrays (already present in buttonForwarding)
String comboNames[8];
String comboAdvantage[8];
String comboDamage[8];
String comboMeter[8];
String comboCharacter[8];
int comboLength[8];

// Values
char name[] = {""};
char character[]= {""};
char damage[] = {""};
char meter[] = {""};
char advantage[] = {""};
byte body[200][12];

// Vars for array ops
int bufferPosition = 0; // The position in the buffer
int bufferId = 0; // The number of the buffer

File comboFile;

void setup()
{
  Serial.begin(9600);
 
  pinMode(10, OUTPUT);
  Serial.print("Initializing SD card...");
  if (!SD.begin(chipSelect)) {
    Serial.print("failed!"); // If there is an issue, tell us and quit 
    return;
  }
  Serial.print("card initialized"); // You will only be here on success
  Serial.println();
 
  // Load the info for all the files
  for (int comboNumber = 0; comboNumber < 8; comboNumber++) {
    Serial.print("Opening File ");
    Serial.println(comboNumber);
    loadInfo(comboNumber);
  }
}

// This uses String comboNames[], int comboAdvantage[], int comboDamage[], int comboMeter, int comboLength[], String comboCharacter[] and comboIndex as an ID
void loadInfo(int comboIndex)
{
  switch (comboIndex) { // Open the combo file (c0, c1, c2, etc) and parse the values
    case 0:
      comboFile = SD.open("c0.txt"); // Open the combo file
      break;
    case 1:
      comboFile = SD.open("c1.txt");
      break;
    case 2:
      comboFile = SD.open("c2.txt");
      break;
    case 3:
      comboFile = SD.open("c3.txt");
      break;
    case 4:
      comboFile = SD.open("c4.txt");
      break;
    case 5:
      comboFile = SD.open("c5.txt");
      break;
    case 6:
      comboFile = SD.open("c6.txt");
      break;
    case 7:
      comboFile = SD.open("c7.txt");
      break;
  }

  // Dump the file
  if (comboFile) {                       // If the file is availble
     while (comboFile.available()) {
      char in = comboFile.read();        //read in the character
      if (in == ':') {                   // If entering a zone
        ignoreFlag = !ignoreFlag;
        if (ignoreFlag) {
          currPosition++;                // When it switches to high
          charArrayCounter = 0;
        }
      }
      else if (!ignoreFlag)  {           // If in an important zone
        switch (currPosition) {
          case 0:
            name[charArrayCounter] = in;
            break;
          case 1:
            character[charArrayCounter] = in;
            break;
          case 2:
            damage[charArrayCounter] = in;
            break;
          case 3:
            meter[charArrayCounter] = in;
            break;
          case 4:
            advantage[charArrayCounter] = in;
            break;
          case 5:
            if (in == '\n' || in == '\r') { // Ignore line breaks
              break;
            }
            else if (in == ',') { // When you reach a new buffer reset and increment
              bufferId++;
              bufferPosition = 0; // Reset the position in the buffer
              break;
            }
            else if (bufferId < 200) { // If recording info, add it to its appropriate position in the array
              body[bufferId][bufferPosition] = in - '0';
              bufferPosition++;
            }
            break;
        }
        charArrayCounter++; // Move the charArrayCounter forward one
      }
    }
  Serial.println("Done reading file ");
  comboFile.close(); // Close the file
  }
 
  // If the file isnt open produce an error
  else Serial.println("There was an error opening the file");
 
  // Store all the newly created values in the arrays
  comboNames[comboIndex] = name;
  comboAdvantage[comboIndex] = advantage;
  comboDamage[comboIndex] = damage;
  comboMeter[comboIndex] = meter;
  comboCharacter[comboIndex] = character;
  comboLength[comboIndex] = bufferId+1;
}

void loop()
{
}

So if I were to add a "Serial.println(name);" line in "case 0:" after "name[charArrayCounter] = in;", it will say
Code:
Initializing SD card...card initialized
Opening File 0
n
na
nam
name
Done reading file
Opening File 1
Done reading file
Opening File 2
Done reading file
Opening File 3
Done reading file
Opening File 4
Done reading file
Opening File 5
Done reading file
Opening File 6
Done reading file
Opening File 7
Done reading file

But if I add the "Serial.println(name);" line in "case 1: " after "character[charArrayCounter] = in;", it will produce
Code:
Initializing SD card...card initialized
Opening File 0
n
na
nam
name
ncme
nche
ncha
nchar
nchara
nchar
nchar
nchar
nchar
Done reading file
Opening File 1
Done reading file
Opening File 2
Done reading file
Opening File 3
Done reading file
Opening File 4
Done reading file
Opening File 5
Done reading file
Opening File 6
Done reading file
Opening File 7
Done reading file

I understand that I don't reset the value for currPosition, so after the first file, currPosition = 6, and thus wont access any of the switches. So when I try to fix this by resetting the value of currPosition at the beginning of loadInfo(), I get this output in the serial monitor:
Code:
Initializing SD card...card initialized
Opening File 0
Done reading file
Opening File 1
Initializing SD card...card initialized
Opening File 0
Done reading file
Opening File 1

This repeats forever, no matter where I put the line "currPosition = 0;". I have even tried "currPosition = currPosition - 5;" to no avail. I dont know if the early bit of info I provided about "name" is any help, but I figured the two might be related. Also, the ON LED on the board does not flash, however the one labeled L does. I have a feeling this may be related to a memory issue, but I am not sure.

I honestly don't know what is wrong, and would greatly appreciate any advice, even if it is only to state that this is a disgusting piece of code.
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 988
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
char name[] = {""};
It appears you are allocating zero bytes to this buffer (well, maybe one for the terminating null) and later putting bytes in the buffer as though there was plenty of room or perhaps it would magically be allocated. 

I believe it will be much happier if you allocate some space for each of the char[] variables, something like this:

Code:
#define NAMELEN 20
char name[NAMELEN];

-br
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Well, you solved what I spent a day slamming my head against in less than 5 minutes. Thanks, I guess I got tunnel vision =)
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 988
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Happens to everyone.  Glad you're rolling again.

Best,

-br
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 38
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Alright, so while ur fix solved my issue, the char[] variables temporarily storing the values while in the loadInfo loop were not resetting, so  I moved their declarations inside the function so they would be reset upon every load. Now, I am getting the same issue I had in my original post: after scanning one file (not really scanning but saying it was), the arduino would restart the setup() function. Really confused here.
Logged

0
Offline Offline
God Member
*****
Karma: 39
Posts: 988
Get Bitlash: http://bitlash.net
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The way this is usually done is to make them global again and initialize them to safe values at the top of each loop.  For C strings, you can just set the first byte to '\0' or just 0 to initialize an empty string.


br
Logged

Pages: [1]   Go Up
Jump to: