We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Dear Forum,
I'm building a drawbot that draws bitmaps. I'm almost there -thanks to the good people here-, but I can't get my head around this issue here.
I have a Processing sketch that can parse coordinates from a string from my arduino, display the corresponding pixel on screen and send the brightness of that pixel back to the arduino. Then I have an arduino code that can move to the next pixel and send its location coordinates as a string.
This seems to work, but only for one pixel. Then processing sends me and ArrayIndexOutOfBoundsException. I guess I need to flush a string somewhere. But I don't know which one. The debuggerer somehow gets stuck on my sketch too. So some advice would be really helpful.
Here's the Processing sketch:
import processing.serial.*; //import the Serial library
Serial myPort; //the Serial port object
String strIn = ""; //Declare a string with name strIn, this will store the coordinates received from the arduino
String strOut = ""; //Declare a string with name strOut, this will store the coordinates and corrseponding geryvalue of a pixel in the bitmap.
String portName = ""; //apparently this is necessary
String coordinates;
int locX= 0;
int locY= 0;
PImage img;
void setup()
{
size(182, 262); //This is the size of the canvas and the range of the printer //<>//
// Make a new instance of a PImage by loading an image file
img = loadImage("parel.bmp");
tint(255, 100);
image (img, 0, 0);
String portName = Serial.list()[0];
myPort = new Serial(this, portName, 9600);
}
void draw()
{
if (myPort.available() > 0) // If data is available,
{
strIn = myPort.readStringUntil('\n'); // read it and store it in a string called strIn
String[] coordinates = split(strIn, ",");
//Cut the strIn string at the comma into two strings called coordinates.
//We expect a message coming in something like "XXX,YYY"
int locX = int(trim(coordinates[0])); //This says that the first string is an integer called LocX
int locY = int(trim(coordinates[1])); //This says that the next string is an integer called LocX
color pix = img.get(locX, locY); //look up the colour of the requested pixel
stroke(pix); //show the pixel on the canvas on screen
point(locX, locY);
int Bright = round(brightness(pix)); //sending pix will send a large negative string, so we will just send the brightness
strOut = locX + "," + locY + "," + Bright + "L" + "\n"; //put all the needed values into a string called strOut
myPort.write(strOut); //send it over serial port to the arduino to parse
}
}
And here's the arduino sketch:
// Jerry Wirerammer lives!
unsigned int xPos ; //this integer sets the X position of the robot
unsigned int yPos ; //this integer sets the Y position of the robot
unsigned int xGoal ; //this integer sets the X location of the pixel where the mothership thinks the robot is. If the Robot is in position, it can put a dot.
unsigned int yGoal ; //this integer sets the X location of the pixel where the mothership thinks the robot is. If the Robot is in position, it can put a dot.
unsigned int GreyValue ;
char val;
int CanvasWidth = 182;
int CanvasHeight = 263;
String received ;
void setup() {
Serial.begin(9600); //Serial communication, we are using it
goHome(); //move to the 0,0 position.
}
void loop() {
Serial.print(xPos);
Serial.print(",");
Serial.println(yPos);
if ( Serial.available() ) // if data is available to read
{
val = Serial.read(); // read it and store it in 'val'
if ( val != 'L' ) { // if not an 'L'
received += val; // add it to the received string
}
else {
// if 'L' was received (our designated termination char)
//Look for the location of the first comma
int commaIndex = received.indexOf(',');
// Search for the next comma just after the first
int secondCommaIndex = received.indexOf(',', commaIndex + 1);
String firstValue = received.substring(0, commaIndex); //the first series of characters before the first comma
String secondValue = received.substring(commaIndex + 1, secondCommaIndex); //the next series of characters between the first and second comma
String thirdValue = received.substring(secondCommaIndex); //the final series of characters before the L that we didn't add to the "received" string
xGoal = firstValue.toInt();
yGoal = secondValue.toInt();
GreyValue = thirdValue.toInt();
/* debugging purposes only:
Serial.print("received:");
Serial.println(received);
Serial.print("xGoal =");
Serial.println(xGoal);
Serial.print("yGoal =");
Serial.println(yGoal);
Serial.print("xPos =");
Serial.println(xPos);
Serial.print("yPos =");
Serial.println(yPos);
*/
received = ""; // Flush the string so we can receive new data
}
}
else {
delay (1000); // wait a bit and try again
}
if (xGoal == xPos) {
if (yGoal == yPos) {
MoveOn();
}
}
}
void MoveOn() //this subroutine tells the robot how to move to the next position.
{
if (xPos != CanvasWidth) { //if we are not at the end of the x axis
xPos = xPos + 1; //and adjust x position by increasing by one
}
else if (yPos != CanvasHeight) { //if we are not at the end of the y axis
xPos = 0; //and adjust x position to its starting value
yPos = yPos + 1; //and adjust y position by increasing by one
}
else {
delay(1); //Do nothing. This will make the robot print the last pixel over and over again.
}
}
void goHome() //this subroutine tells the robot how to move to position 0,0
{
while (xPos != 0) { //if we are not x position 0
xPos = xPos - 1; //and adjust x position by increasing by one
//this will repeat until we are at position x=0
}
while (yPos != 0) { //if we are not x position 0
yPos = yPos - 1; //and adjust x position by increasing by one
}
}
Answers
Which code line does the ArrayIndexOutOfBoundsException happen?
Your code would be easier to manage if you relied on readBufferUntil(), serialEvent() & readString():
It happens on line 35.
Do you have an example of such a code?
https://forum.Processing.org/two/discussions/tagged?Tag=readstring()
I tweaked the sketch a bit by flushing all strings at the end of each reading. The AIOOBE error is gone and I can run the debugger now. Don't really understand why.
Now Arduino is no longer responding after two or three pixels.
New code: