Scrolling Graph Serial

I am trying to plot the values coming in from the serial port into a scrolling graph. Right now it it displaying some value but not what I want. It should plot every time ReadStringUntill gets to a new line etc. Any ideas are welcome thanks:

import processing.serial.*;

Serial port;  // Create object from Serial class
int val;      // Data received from the serial port
int[] values;
float zoom;
int inByte;
void setup() 
{
  size(1280, 480);
  // Open the port that the board is connected to and use the same speed (9600 bps)
  port = new Serial(this, Serial.list()[0], 9600);
  port.bufferUntil('\n');                     // Sets a specific byte to buffer until before calling serialEvent()

  values = new int[width];
  zoom = 1.0f;
  smooth();
}

int getY(int val) {
  return (int)(height - val / 1023.0f * (height - 1));
}

int getValue() {      // This is my myPort.bufferuntil?
  int value = -1;
  String inString = port.readStringUntil('\n');
  inString = trim(inString);
  value = int(inString);
  //value = port.read();
  //println(value);
  //if (inString != null) {
  //  inString = trim(inString);                // trim off whitespaces.
  //  value = int(inString); 
  //}
  //while (port.available() >= 1) {
    
  //  if (port.read() == 0xff) {
  //    value = (port.read());
  //  }
  //}
  return value;
}

void pushValue(int value) {
  for (int i=0; i<width-1; i++)
    values[i] = values[i+1];
  values[width-1] = value;
}

void drawLines() {
  stroke(255);
  int displayWidth = (int) (width / zoom);
  int k = values.length - displayWidth;
  int x0 = 0;
  int y0 = getY(values[k]);
  for (int i=1; i<displayWidth; i++) {
    k++;
    int x1 = (int) (i * (width-1) / (displayWidth-1));
    int y1 = getY(values[k]);
    line(x0, y0, x1, y1);
    x0 = x1;
    y0 = y1;
  }
}

void draw()
{
  background(0);
  //drawGrid();
  val = getValue();
  if (val != -1) {
    pushValue(val);
  }
  drawLines();
}```

Try something like this:

import processing.serial.*;

char lf = '\n';    // new line in ASCII
String myString = null;
Serial myPort;  // The serial port
int[] values;
int valueCount = 0;
final float zoom=1.0;

void pushValue(int value) {
  println("Received: ", value);
  if (valueCount < width) valueCount++;
  println("valueCount: ", valueCount);
  for (int i=valueCount-1; i>=1; --i) values[i] = values[i-1];
  values[0] = value;
}

void drawLines() {
  stroke(255);
  background(0);
  for (int i=1; i<valueCount; i++) line(i-1, height-values[i-1], i, height-values[i]);
}

void setup() {
  size(1280, 480);
  printArray(Serial.list()); // to see which port number to use in the line below
  myPort = new Serial(this, Serial.list()[0], 9600); // use first entry in the Serial list
  myPort.clear();
  myString = myPort.readStringUntil(lf);
  myString = null;
  values = new int[width];
}

void draw() {
  while (myPort.available() > 0) {
    myString = myPort.readStringUntil(lf);
    if (myString != null) {
      pushValue(int(myString.trim()));
      drawLines();
    }
  }
}

it’s probably not rock solid because reading the Serial port this way is probably fragile and using a circular buffer would be much better than shifting the data every time you get a new entry, but that can do for the moment :innocent:

I changed the way the graph was displayed, here it’s scrolling from left to right

I tested the code with the following Arduino program:

int value;
void sendValue()
{
  Serial.print(value);
  Serial.write('\n');
}

void getNewValue()
{
  value += random(-5, 6);
  value = constrain(value, 0, 480);
}

void setup() {
  Serial.begin(9600);
  value = random(0, 481);
}

void loop() {
  getNewValue();
  sendValue();
  delay(10);
}

which is basically sending a random evolving value every 10ms on the Serial line.

and I see a nicely scrolling graph

Hi Jay,
This is brilliant! Thank you very much! I was expermineting with your code ans I was trying to make it work with my following Arduino code:

#include <SoftwareSerial.h> 
int x;                                  //Initialsing x
int analog_output;                         //Serial Read output
int r_pin = A0;                              //Initialising output pin

void setup() {              
  Serial.begin(9600);               // Starting serial communication at 9600 Baud Rate
}

void loop() {
  analog_output = analogRead (r_pin);    // Reading from the resistor
  Serial.println (analog_output);        // Sending the output to Processing IDE
}

What do you think, would it be possible to combine this with your Processing code? Many thanks :innocent:

You have lots of unnecessary stuff in your code…

const byte sensorPin = A0;

void setup() {              
  Serial.begin(9600); // Starting serial communication at 9600 Baud Rate
}

void loop() {
  Serial.println(analogRead(sensorPin));  // Sending the sensor value out (to Processing program listening)
  delay(50); // don’t overflow the communication channel
}

Also remember that

  • you can’t open both the arduino serial monitor and your processing program as only one program on the PC can grab the Serial communication. `
  • opening the serial communication reboots the arduino, so take it into account if you make this more complicated.