Hi, running into an issue here that seems related to the for loop section of my processing sketch.
My aim is to re-draw the loaded image as a grid of ellipses, using .get. The Distance sensor reading from arduino, (myDis) will change the ellipses scale and the iteration within the for loop, depending on the viewers distance from the sensor.
A problem in the logic and order of the processing sketch? I have tried a few iterations of this sketch, it seems to be the for loop where I am running into an issue - Any tips or observations would be appreciated, thanks
FIX: It’s fixed just about - Trim gets rid of unnecessary characters in the data such as white space/symbols, I believe this was part of the issue. I’ve also moved my for loop outside of the while loop, and there is an added function for error handling.
If anyone wants to expand on this code feel free.
*My next step is to try and make it run smoother/with less lag, any pointers let me know
// FIXED PROCESSING SKETCH
import processing.serial.*;
Serial mySerial;
String myString = null;
int nl = 10;
float myDis; // myDistance
PImage img;
void setup() {
size(918, 960, P2D); //same size as img
String myPort = Serial.list()[1];
mySerial = new Serial(this, myPort, 9600);
pixelDensity(displayDensity());
imageMode(CORNER);
img = loadImage("artwork_2.jpg");
}
void draw() {
while (mySerial.available() > 0) {
myString = mySerial.readStringUntil(nl); //STRIP
if (myString != null) {
myString = myString.trim(); // error with white space and additional characters interfering, trim gets rid of these
if (isValid(myString)) {
myDis = float(myString);
println(myDis);
} else {
println("Invalid value: " + myString);
}
}
}
background(0);
//display myDis sensor reading
textSize(128);
fill(255);
noStroke();
text(myDis, 40, 120);
for (int x = 0; x < img.width; x += myDis) {
for (int y = 0; y < img.height; y += myDis) {
pushMatrix();
color pix = img.get(x, y);
fill(pix);
noStroke();
ellipse(x, y, myDis, myDis);
popMatrix();
}
}
}
boolean isValid(String value) {
try {
Float.parseFloat(value);
return true;
} catch (NumberFormatException e) {
return false;
}
}
Also, because myDis is an int you will only send one byte of it when using Serial.write() in the way you use it. The better way would be
Serial.write((byte *)&myDis, sizeof(myDis));
This takes the address of myDis, casts it to a pointer to a byte and writes the two bytes (8-bit processors) or four bytes (32-bit processors). You’ll have to be careful with the endianness when sending binary data.
You are suggesting a delay(5) which means you are sending more than one string of data (ending in ‘/n’) per frame.
while (mySerial.available() > 0) will receive multiple strings of data per frame and keep up with the data that is being sent from Arduino.
if (mySerial.available() > 0) will only receive one string of data per frame; the data will be stuck in the buffer until it is received the next frame and the delay between data sent from Arduino and received by Processing will keep accumulate.
You can monitor the buffer and watch it grow with a simple statement: