Sending state of 64 buttons to arduino from processing via serial

Hello all, still fairly new to programming in general, but I am getting frustrated so I'm asking for help. I wrote a program in processing to display and keep track of the state of a grid of 64 buttons. The buttons "turn on and off" with a mouse click and the state of all 64 buttons is sent over serial when a keyboard button is pressed. I'm hoping to set the state of an LED matrix connected to the arduino when the serial message is received by the arduino. Right now I'm testing that the serial message is sent and received correctly. The arduino sketch has a for loop that populates an array with the values received by serial when there is at least 63 bytes available in the serial buffer on the arduino. As of right now, all of the buttons populate the array correctly except the 64th button. Am I missing something stupid here or am I not understanding how the serial transmission is happening?

Here is the code for the arduino:

int buttonState[64];


void setup() {
 pinMode(12, OUTPUT); // Set pin as OUTPUT
 pinMode(11, OUTPUT); // Set pin as OUTPUT
 pinMode(10, OUTPUT); // Set pin as OUTPUT
 pinMode(9, OUTPUT); // Set pin as OUTPUT
 Serial.begin(19200); // Start serial communication at 19200 bps
 
}
 
 void loop() {

  if(Serial.available() >= 63) {
    for(int b=0;b<64;b++){
      buttonState[b] = Serial.read();
    }
  }

  if (buttonState[0] == 1) { // If 1 was received
    digitalWrite(12, HIGH); // turn the LED on
  }
  
  if (buttonState[63] == 1) { // If 1 was received
    digitalWrite(11, HIGH); // turn the LED on
  }
  
  delay(10);
}

Here is the processing sketch:

import processing.serial.*;

PrintWriter output;
Serial myPort;  // Create object from Serial class
int rectSize = 50;
color[][] rectColor;
boolean[][] rectOver;
int[][] buttonState;
int[][] rectX;
int[][] rectY;
//int[][] send;
int side = 8;
int count = 0;

void setup() 
{
  rectColor = new color[side][side];
  rectOver = new boolean[side][side];
  rectX = new int[side][side];
  rectY = new int[side][side];
  //send = new int[side][side];
  buttonState = new int[side][side];
  size((side*(rectSize+10)), (side*(rectSize+10)));
  
  for(int j=0;j<side;j++){
    for(int k=0;k<side;k++){
      rectColor[j][k] = color(0);
      rectX[j][k] = (j*(rectSize+10))+5;
      rectY[j][k] = (k*(rectSize+10))+5;
      rectOver[j][k] = false;
      buttonState[j][k] = 0;
      //send[k][j] = count;
      count++;
    }  
  }  
  //println(Serial.list());
  String portName = Serial.list()[0];
  myPort = new Serial(this, portName, 19200);
  output = createWriter("positions.txt");
}

void draw() {
  update(mouseX, mouseY);
  background(127);
  
  for(int n=0;n<side;n++){
    for(int o=0;o<side;o++){
      fill(rectColor[o][n]);
      rect(rectX[o][n], rectY[o][n], rectSize, rectSize);
    }  
  }  
}

void update(int x, int y) {
  
  for(int s=0;s<side;s++){
    for(int t=0;t<side;t++){
      rectOver[t][s] = false;
      if ( overRect(rectX[t][s], rectY[t][s], rectSize, rectSize) ) {
        rectOver[t][s] = true;
      }
    }  
  }
}

void mousePressed() {
  for(int q=0;q<side;q++){
    for(int r=0;r<side;r++){
      if (rectOver[q][r] && buttonState[q][r] == 0) {
      rectColor[q][r] = color(255);
      buttonState[q][r] = 1;
      //myPort.write(send[q][r]);
    }
    else if (rectOver[q][r] && buttonState[q][r] == 1) {
      rectColor[q][r] = color(0);
      buttonState[q][r] = 0;
      //myPort.write(send[q][r] + 64);
    }
    }
  }
}

void keyPressed() {
  myPort.clear();
  for(int a=0;a<8;a++){
    for(int b=0;b<8;b++){
      myPort.write(buttonState[b][a]);
      output.print(buttonState[b][a]);
    }
  }
  output.flush(); // Writes the remaining data to the file
  output.close(); // Finishes the file
  exit(); // Stops the program
}


boolean overRect(int x, int y, int width, int height)  {
  if (mouseX >= x && mouseX <= x+width && 
      mouseY >= y && mouseY <= y+height) {
    return true;
  } else {
    return false;
  }
}

Hello,

You use 64 ints, that is 128 bytes, you could reduce this down to 8 bytes as each button is either on or off, 1 or 0, and each byte can hold 8 of those 1 or 0 :wink:

This isn't your problem, just a huge improvement for memory usage.

About your problem: maybe the last character that you receive is a line ending character?

The serial buffer on the Arduino only holds 64 characters. While you wait for 63 characters, the buffer is likely overflowing.

If you change the Processing app to send just 8 bytes, that's 64 bits, which is all you need to represent the state of 64 pins.

You'll be able to send data faster, not worry about overflow (as much), and not waste as much space on the Arduino.

PaulS:
The serial buffer on the Arduino only holds 64 characters. While you wait for 63 characters, the buffer is likely overflowing.

If you change the Processing app to send just 8 bytes, that's 64 bits, which is all you need to represent the state of 64 pins.

You'll be able to send data faster, not worry about overflow (as much), and not waste as much space on the Arduino.

Thank you!

I knew it probably had something to do with the serial buffer...
I added an 8 element byte array called "led" and changed the keyPressed function in the processing sketch to look like this:

void keyPressed() {
  
  for(int a=0;a<side;a++){
    for(int b=0;b<side;b++){
      if((buttonState[b][a]) == 1){
      led[a] += (128>>b);
      }
    }
  }
  
  myPort.write(led);
  }
}