weird Serial.print() problem

Hello all,

I plugged 12 switches in my Arduino controller and I need to know which are on and which are off. I am sending this info using Serial.print() Now, I don't want to hog the serial port and send data continuously because that will make the program receiving this data freak out. So I created variables for each switch, and I check whether or not the value changes at every loop() iteration and if it does, I send the new value. Here is the code:

int rPin = 0;
int aPin = 2;
int bPin = 3;
int cPin = 4;
int dPin = 5;

int hPin = 6;
int ePin = 7;
int sPin = 8;
int oPin = 9;
int gPin = 10;

int nAPin = 11;
int nBPin = 12;
int nCPin = 13;

// variables
int aLock = 0; 
int bLock = 0;
int cLock = 0; 
int dLock = 0;

int hToggle = 0;
int eToggle = 0;
int sToggle = 0;
int oToggle = 0;
int gToggle = 0;

int nSelect = 0;

int val = 0;


void setup() {
  pinMode(rPin, INPUT);
  
  pinMode(aPin, INPUT);
  pinMode(bPin, INPUT);
  pinMode(cPin, INPUT);
  pinMode(dPin, INPUT);
  
  pinMode(hPin, INPUT);
  pinMode(ePin, INPUT);
  pinMode(sPin, INPUT);
  pinMode(oPin, INPUT);
  pinMode(gPin, INPUT);
  
  pinMode(nAPin, INPUT);
  pinMode(nBPin, INPUT);
  pinMode(nCPin, INPUT);
  
  // open the serial port
  Serial.begin(19200);
}


void loop() {
  //if (digitalRead(rPin) == LOW) {
  //  Serial.print('R');
  //}
  
  // report changes for handle locks
  val = digitalRead(aPin);
  if (aLock != val) {
    aLock = val; 
    Serial.print('A');
    Serial.print(aLock);  
  }
  
  val = digitalRead(bPin);
  if (bLock != val) {
    bLock = val; 
    Serial.print('B');
    Serial.print(bLock);  
  }
  
  val = digitalRead(cPin);
  if (cLock != val) {
    cLock = val; 
    Serial.print('C');
    Serial.print(cLock);  
  }
  
  val = digitalRead(dPin);
  if (dLock != val) {
    dLock = val; 
    Serial.print('D');
    Serial.print(dLock);  
  }
  
  // report changes for option toggles
  /*val = digitalRead(hPin);
  if (hToggle != val) {
    hToggle = val; 
    Serial.print('H');
    Serial.print(hToggle);
  }
  
  val = digitalRead(ePin);
  if (eToggle != val) {
    eToggle = val; 
    Serial.print('E');
    Serial.print(eToggle);
  }
 
  val = digitalRead(sPin);
  if (sToggle != val) {
    sToggle = val; 
    Serial.print('S');
    Serial.print(sToggle);
  }
  
  val = digitalRead(oPin);
  if (oToggle != val) {
    oToggle = val; 
    Serial.print('O');
    Serial.print(oToggle);
  }*/
  
  val = digitalRead(gPin);
  if (gToggle != val) {
    gToggle = val; 
    Serial.print('G');
    Serial.print(gToggle);
  }
  
  // report changes for handle selection
  if (digitalRead(nAPin) == LOW) {
    val = 1;
  } else if (digitalRead(nBPin) == LOW) {
    val = 2;
  } else if (digitalRead(nCPin) == LOW) {
    val = 3;
  } else {
    val = 4;
  }
  if (nSelect != val) {
    nSelect = val;
    Serial.print('N');
    Serial.print(nSelect);
  }
  
  delay(200);
}

I have a major problem. As soon as I do the whole if (changed) { print() } thing more than 8 times, it stops working. Nothing goes through the serial port. That's why some lines are commented in the code above. Now I know it's not a variable name or hardware problem, because if I comment any other 4 if-statements it still works. As soon as I take out the comments or only comment out 3 statements, nothing gets printed to the serial port.

On top of that, the following code, which prints out all the values without checking if they're changed or not, works perfectly:

int rPin = 0;
int aPin = 2;
int bPin = 3;
int cPin = 4;
int dPin = 5;

int hPin = 6;
int ePin = 7;
int sPin = 8;
int oPin = 9;
int gPin = 10;

int nAPin = 11;
int nBPin = 12;
int nCPin = 13;

int val = 0;

void setup() {
  pinMode(rPin, INPUT);
  
  pinMode(aPin, INPUT);
  pinMode(bPin, INPUT);
  pinMode(cPin, INPUT);
  pinMode(dPin, INPUT);
  
  pinMode(hPin, INPUT);
  pinMode(ePin, INPUT);
  pinMode(sPin, INPUT);
  pinMode(oPin, INPUT);
  pinMode(gPin, INPUT);
  
  pinMode(nAPin, INPUT);
  pinMode(nBPin, INPUT);
  pinMode(nCPin, INPUT);
  pinMode(nDPin, INPUT);
  
  // open the serial port
  Serial.begin(19200);
}


void loop() {
  Serial.print('R');
  Serial.print(digitalRead(rPin));
  
  Serial.print('A');
  Serial.print(digitalRead(aPin));
  Serial.print('B');
  Serial.print(digitalRead(bPin));
  Serial.print('C');
  Serial.print(digitalRead(cPin));
  Serial.print('D');
  Serial.print(digitalRead(dPin));
  
  Serial.print('H');
  Serial.print(digitalRead(hPin));
  Serial.print('E');
  Serial.print(digitalRead(ePin));
  Serial.print('S');
  Serial.print(digitalRead(sPin));
  Serial.print('O');
  Serial.print(digitalRead(oPin));
  Serial.print('G');
  Serial.print(digitalRead(gPin));
  
  Serial.print('N');
  if (digitalRead(nAPin) == LOW) {
    Serial.print(1);
  } else if (digitalRead(nBPin) == LOW) {
    Serial.print(2);
  } else if (digitalRead(nCPin) == LOW) {
    Serial.print(3);
  } else {
    Serial.print(4);
  }
  
  Serial.println();
  
  delay(100);
}

Has anyone encountered this problem? I have no idea what to do! Does it have something to do with delay()? Is there some buffer that I am exceeding?

Thanks in advance for the help

It may be that your code is too big for the Arduino chip, even if you don't get an error when you try to upload it. What size is reported when you try to upload? If it's between 6 and 7 KB, you may have a board with a 2 KB bootloader. The IDE expects a 1 KB bootloader when it checks if your code is too big.

If this is indeed the problem, there are a few things you can do. (The 2 KB bootloader were unfortunately burned on some boards as the result of a miscommunication in the development team.) Either change the maximum size for your sketches to 6144 in the Arduino preferences file (Arduino - Home) or burn a new bootloader onto the board (which requires extra hardware: http://www.arduino.cc/en/Main/Bootloader). Arduino 0005, due out as soon as we finish working out the bugs reported at Ars Electronica will reduce the size of the Arduino libraries, leaving more space for your sketches.

You could make your code smaller by making the code that checks the pins a,b,c,d,e,g,h,o,s and r and sends the value if its changed into a function that you call repeatedly from your main loop so that you do not write what is basically the same block of code 10 times in the chips memory.

HTH

Nick

Hmm, I think that might be the problem because the uploader reports a program size a little over 6100 bytes. I will try to optimize the code and see how it goes.

Is program size related to the number of characters in the code? So, if I follow Nick's advice and use functions and arrays, will it reduce the program size?

Thanks for the help, I'll let you guys know how it works out.

One more question, when you say I need extra hardware to burn the bootloader, does that mean I can't just directly use the "Burn Bootloader" command from Arduino 0004?

Will this hardware also be necessary when the new libraries come out with Arduino 0005, or are these uploaded with the program?

In general, the shorter your code, the less room it takes up on the chip, but it's not necessarily character for character. Nick's advice should definitely help, though.

The burn bootloader command in the Arduino IDE requires extra hardware to work. That's why we use a bootloader: it allows you to upload code to the board without an external programmer.