We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hey everyone! I'm using this code that I saw from another post somewhere in this forum and adapted it to generate a heat map using data from an arduino. However, for some reason whenever I try streaming data in order to create the heat map, I always get back an error of some kind because of the data streaming. I'm specifically asking about lines 25 and 26 which is where the error happens. I think it might be because of some index out of bounds exception but I do not understand the library enough.
import cc.arduino.*;
import org.firmata.*;
import apsync.*;
import processing.serial.*;
float[][] interp_array;
Serial myPort; // Create object from Serial class
String val; // Data received from the serial port
int lf = 10;
void setup() {
//String portName = Serial.list()[2];
myPort = new Serial(this, "COM3", 9600);
size(400, 400);
interp_array = new float[400][400];
makeArray();
applyColor();
}
// Fill array with Perlin noise (smooth random) values
void makeArray() {
for (int r = 0; r < height; r++) {
for (int c = 0; c < width; c++) {
if ((r == 50 || r == 150 || r == 250 || r == 350) && (c == 50 || c == 150 || c == 250 || c == 350)) {
String data = myPort.readStringUntil(lf);
interp_array[c][r] = Float.parseFloat(data);
}
//else {
//// Range is 24.8 - 30.8
//interp_array[c][r] = 24.8 + 6.0 * noise(r * 0.02, c * 0.02);
//}
}
}
for (int r = 0; r < height; r++) {
for (int c = 0; c < width; c++) {
int[] closest_r_array = {abs(50 - r), abs(150 - r), abs(250 - r), abs(350 - r)};
int[] closest_c_array = {abs(50 - c), abs(150 - c), abs(250 - c), abs(350 - c)};
int closest_r = min(closest_r_array);
int closest_c = min(closest_c_array);
if (!(r == 50 || r == 150 || r == 250 || r == 350) && !(c == 50 || c == 150 || c == 250 || c == 350)) {
interp_array[c][r] = lerp(closest_r, closest_c, 0.5);
}
}
}
}
void applyColor() { // Generate the heat map
pushStyle(); // Save current drawing style
// Set drawing mode to HSB instead of RGB
colorMode(HSB, 1, 1, 1);
loadPixels();
int p = 0;
for (int r = 0; r < height; r++) {
for (int c = 0; c < width; c++) {
// Get the heat map value
float value = interp_array[c][r];
// Constrain value to acceptable range.
value = constrain(value, 25, 30);
// Map the value to the hue
// 0.2 blue
// 1.0 red
value = map(value, 25, 30, 0.2, 1.0);
pixels[p++] = color(value, 0.9, 1);
}
}
updatePixels();
popStyle(); // Restore original drawing style
}
Answers
Check the following link:
https://forum.processing.org/two/search?Page=p2&Search=arduino
For example:
https://forum.processing.org/two/discussion/comment/101680/#Comment_101680
In your case, line 25 should be handle in
serialEvent()
function. You also need to make sure that the value returned by this function is not null. You can check previous examples where this is demonstrated.Kf
If the code in line 25 is taken out of the for loop, how will I be able to stream continuous data from the arduino?
Setup is not a good place to do this operations as this function runs only once.
The serialEvent() is a callBack function that gets executed every time data arrives via serial. It is there where you handle the data. However, it is advised not to work in your sketch in that function. Any draw operation needs to be done in the drawing thread which you own and you can access via draw(): https://processing.org/reference/draw_.html
Here is my attempt on your code. Since I don't have an arduino, I have disabled about 5 lines in your code. For your code to work with your arduino, you need to adjust the min/max range to 25/30 and enable those 5 lines related to arduino and serial event. Or you can run the code as it is. I use key events to simulate your arduino's input data. For the code to work, you need to set your min/max to 0/9 and type 16 times to fill the array. as soon as the array is full, it populates the second and bigger table array using a modify version of your makeArray. I believe there is some work still to be done in your heat map code. You might need to create a separate post to address this issue.
Kf