Send Data from Arduino to Processing over serial // help please

I am trying to send data from an Arduino Uno to Processing.

Video of situation: https://youtu.be/s68aYfD71WY

I made a simple sketch which does this no problem. It is only when I try to have the Arduino send data to Processing in an “if conditional” from an analog sensor reading that I run into trouble.

For instance, the simple send from Arduino looks like this:

   int ledPin = 13;

void setup()
{
  Serial.begin(9600);
   pinMode(ledPin, OUTPUT);
}
void loop()
{
  Serial.write(1);
   digitalWrite(ledPin, HIGH);
  delay(200);
  Serial.write(0);
   digitalWrite(ledPin, LOW);
  delay(200);
}

And the corresponding Processing code looks like this:

    import processing.serial.*;
    
    Serial myPort;  // Create object from Serial class
    int val;
    
    void setup() {
      //change the 0 to a 1 or 2 etc. to match your port
      String portName = Serial.list()[2]; 
      myPort = new Serial(this, portName, 9600);
    
      rectMode(CENTER);
    }
    
    void draw()
    {
      background(0);
      fill(255);
    
      if (myPort.available()>0)
      {
        val = myPort.read();
      }
      println(val);
      
      if (val == 1)  {
        rect(width/2, height/2, 30, 30);
      }
    }

It makes a white square appears when the number “1” is sent to Processing. It works so simple. It works every time. I was so pleased.

However, when I try it with the next Arduino sketch, nothing ever happens. It always stays on “0” even though I can see on the Arduino the LED turns on showing that yes, this piece of code has run. The Processing portion can stay exactly the same.

Why am I not seeing it work right? I have tried so many things. This tells me it’s either painfully obvious or I’ve done something horribly karmically wrong and this is my punishment.

Thank you for nay tips.

        // Used to interface with electronic drum pads
        // Using a piezo sensor
        // Casey Scalf 2015
        
        
        int ledPin = 13;
        int padPin = 0; // Red
        // Black is Ground
        
        byte val;
        byte a = 0;
        
        int THRESHOLD = 20;
        
        void setup() {
        
          Serial.begin(9600);
        
          pinMode(ledPin, OUTPUT);
        }
        
        void loop() {
        
          val = analogRead(padPin);
          
          if (val <= THRESHOLD) {
            digitalWrite(ledPin, LOW);
            a = 0;
            Serial.write(a);
          }
          
            if (val >= THRESHOLD) {
            digitalWrite(ledPin, HIGH);
            a = 1;
            Serial.write(a);
          }
        
        }

Try getting the program to work with the Serial Monitor and use Serial.println(val); so you can see what values are being used in the IF tests

It is a good idea to have a mechanism in your PC program so it can print debug messages without screwing up the rest of the PC program. Perhaps prefix debug messages with "DBG" or some similar scheme.

...R

Hi Sensebellum

A difference between your Arduino programs is the use of delay() in the first one. Bytes are sent every 200ms.

The second program will send bytes as fast as the 9600 bps bit rate allows. This may be causing problems on the Processing side.

ADDED ...

Seems like the draw() function in Processing runs at a set rate of frames per second. So reading the incoming serial data inside draw() leads to problems.

There is a discussion here on using serialEvent() in Processing and only sending changes in state here: http://arduino.stackexchange.com/questions/1830/reducing-lag-between-the-arduino-and-a-processing-sketch-on-my-computer

Regards

Ray

Thanks Ray,

I will look that up. I was talking with a friend and we were pretty sure it was a timing thing (i.e. one is faster than the other).

I will clean up the code and use a button for the sketch so more people can work on it.

@Robin2 I will use it to print to the monitor and make a snapshot of that and see what is going on. I've done this early in the program and it will spit out the values correctly (0-255). However, what it prints when I ask it to send a message may be different. I will look into it.

I think this is getting close!

I am still really confused as to why this is happening. Don’t lots of people send data from an Arduino to a program like Processing? Successfully?

Here is a new video showcasing the button. This should be the simplest way to possibly make this happen… But it still does not…

Here is the updated Youtube Video: https://youtu.be/JDcbM-sBX8c

Any ideas?

///////// Arduino

// Used to interface with electronic drum pads
// Using a piezo sensor
// Casey Scalf 2015


int ledPin = 13;
int padPin = 0; // Red

byte val;
int THRESHOLD = 20;

void setup() {

  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

}

void loop() {
  
  val = analogRead(padPin);

  if (val > THRESHOLD) {
    Serial.write(1);
    digitalWrite(ledPin, HIGH);
  }

  else if (val < THRESHOLD) {
    Serial.write(0);
    digitalWrite(ledPin, LOW);
  }
  
}

///////// Processing

// Used to recive signals from an Arduino over Serial
// Casey Scalf 2015

import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;

void setup() {
  size(300, 200);
  frameRate(60);
  
  //change the 0 to a 1 or 2 etc. to match your port
  String portName = Serial.list()[2]; 
  myPort = new Serial(this, portName, 9600);

  rectMode(CENTER);
}

void draw()
{
  background(0);
  fill(255);

  if (myPort.available()>0)
  {
    val = myPort.read();
    println(val);
  }
  
  if (val == 1)  {
    rect(width/2, height/2, 60, 30);
  }
}

I am still really confused as to why this is happening. Don't lots of people send data from an Arduino to a program like Processing? Successfully?

Well, get your arduino code working with the serial monitor, then work on the processing part of your project.

While it may be technically less efficient it will be much easier to debug your code if you transmit data as Ascii characters rather than byte values for unprintable characters.

Use Serial.println('1') rather than Serial.write(1)

Then the same code should work with the Serial Monitor and with Processing. And, as said in Replies #1 and #5 get it working with the Serial Monitor first.

...R

Okay, so the problem is obvious, because, it was already stated and you already agreed to it, but failed to fix the problem in your updated sketch. So, instead of just giving you the answer, I'm going to show it to you.

Try this for Processing and look at the bottom console, tell me what you see...

// Used to recive signals from an Arduino over Serial
// Casey Scalf 2015

import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;

void setup() {
  size(300, 200);
  frameRate(60);
  
  //change the 0 to a 1 or 2 etc. to match your port
  String portName = Serial.list()[2]; 
  myPort = new Serial(this, portName, 9600);

  rectMode(CENTER);
}

void draw()
{
  background(0);
  fill(255);

  if (myPort.available()>0)
  {
    println(myPort.available());
    val = myPort.read();
  }
  
  if (val == 1)  {
    rect(width/2, height/2, 60, 30);
  }
}

Side Note: What happens when val is equal to THRESHOLD?

Thanks for the encouragement.

I tried the newest Processing code posted using the Arduino code from my previous post.

I tired write/print/println. They all successfully printed to the serial monitor for the Arduino - except for write, in which the serial is blank, because that does not print to the Arduino I understand.

Each iteration yielded ever increasing numbers in the Processing console using the code posted most recently.

The serial has always worked with the Arduino on this project. That is what is so confusing at the moment. It is only when I try to print/println/write to Processing that the message becomes troubled.

What can we try next? Sorry if I keep missing the obvious I just am not seeing the path and would love to successfully solve this puzzle.

Thank you,

466
480
495
510
529
539
554
573
583
602
617
632
650
661
680
690
709
720
734
749
764
783
797
812
827
841
856
871
889
900
915
930
948
959
974
988
1007
1022
1037
1051
1066
1081
1095
1110
1129
1140
1158
1169
1184
1198
1213
1228
1246
1257
1276
1291
1305
1320
1335
1353

except for write, in which the serial is blank, because that does not print to the Arduino I understand.

print(), println(), and write() send data FROM the Arduino. read() gets data that was sent TO the Arduino.

print() and println() convert binary data to strings to send. write() does not convert the binary data to a string.

Post YOUR Processing code AND you Arduino code. Summarize the problem(s) you are having.

I'm just going to say it....

That increasing number is the amount of bytes piled up in the buffer on your computer, you are not reading it fast enough...

Imagine you pouring water into a funnel at a gallon per minute, but the funnel can only drain 1/2 a gallon per minute...what will happen, well, the water will keep piling up until you stop pouring water and it will take some time to drain out.

You Are Sending Data TOO FAST.

Notice that the number printed is the value returned from Serial.available(), the amount of bytes available in the serial buffer...

  if (myPort.available()>0)
  {
    println(myPort.available());
    val = myPort.read();
  }

This could be done with a while statement, rather than an if statement.

You could also pay attention to the fact that, unlike loop() on the Arduino, draw() is not called over and over AS FAST AS POSSIBLE. Therefore, serial data input should NOT be done in draw(). There is a serialEvent() method that can be overwritten, to handle serial communications correctly (much faster).

Once again, thanks for the help.

I know some of you are pros but this is not exactly obvious to me. I get the concept, just not the way to write this in the code.

→ To summarize, it sounds like the data is piling up too fast. Yes?
→ How can I send it in a way that allows it to be ready sufficiently in Processing?
→ The drum pad needs to be hit very fast, how can we assure there is no delay yet it is read sufficiently?
→ What would you do? How would you implement it?

Here is the most recent version of both the Arduino AND the Processing code.

Processing:

// Used to receive signals from an Arduino over Serial
// Casey Scalf 2015

import processing.serial.*;

Serial myPort;  // Create object from Serial class
int val;

void setup() {
  size(300, 200);
  frameRate(60);
  
  //change the 0 to a 1 or 2 etc. to match your port
  String portName = Serial.list()[2]; 
  myPort = new Serial(this, portName, 9600);

  rectMode(CENTER);
}

void draw()
{
  background(0);
  fill(255);

  if (myPort.available()>0)
  {
    val = myPort.read();
    println(val);
  }
  
  if (val == 1)  {
    rect(width/2, height/2, 60, 30);
  }
}

Arduino:

// Used to interface with electronic drum pads
// Using a piezo sensor
// Casey Scalf 2015


int ledPin = 13;
int padPin = 0; // Red

byte val;
int THRESHOLD = 20;

void setup() {

  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);

}

void loop() {
  
  val = analogRead(padPin);

  if (val > THRESHOLD) {
    Serial.write(1);
    digitalWrite(ledPin, HIGH);
  }

  else if (val < THRESHOLD) {
    Serial.write(0);
    digitalWrite(ledPin, LOW);
  }
  
}

Sensebellum:
-> How can I send it in a way that allows it to be ready sufficiently in Processing?

A simple, if crude, way is to put delay(500); as the last thing in loop() in your Arduino code. Then it will only send values every 500 millisecs. Obviously you can change the delay if you want.

A better way would be for Processing to send a message to the Arduino whenever it wishes to receive more data. The message could be as simple as the letter 'M' for more.

...R

Well, what you are doing currently is reading 1 byte per draw() in Processing, instead you should read as many bytes are available in the buffer.

void draw(){
  while(myPort.available() > 0){
    value = myPort.read();
    //do stuff with the value
  }
}

Well, what you are doing currently is reading 1 byte per draw() in Processing, instead you should read as many bytes are available in the buffer.

I'm sorry. That is wrong. Serial input should not be done in draw() AT ALL.

The reason is that draw() is called at some (user-settable) frame rate. Serial input should happen WHEN THERE IS DATA, not when the next frame is to be drawn.

Were OP to do this properly, he/she would see that that is what is happening.

I see, I thought it was similar to arduino's serialEvent where it is checked at the end of loop() (or main, really), but I looked it up and you are right

@Robin2, The funny thing is I tried that and I did not see a difference. I put them in many different places. I will try again soon. Unfortunately the read when ready method is not applicable to the application. I want it to be able to be hit (the drum pad) at any point in time.

Also, a ways back I changed it to a button instead a drum pad - still as an analog read. When the button is pressed it reads a full 255. I found that even if I held it down for a second all of the same problems and behaviors were exhibited.

@Ps991, I will try that. I could image the 1 byte per draw() would read it too... superficially or too quickly.

In any case, I feel there is a good way to do this. I am thinking of some creative hacks to get around this but I would love, love, love to nail down how to do this over serial the proper way.

Thanks gain for all of the help.

No, dont do what I said, do what PaulS said

There is a serialEvent() method that can be overwritten, to handle serial communications correctly (much faster).

just put this in your processing code

void serialEvent(){
 //read serial and do stuff
}

serialEvent for Processing Example Link

just put this in your processing code

Not exactly.

Put this, instead:

void serialEvent(Serial thePortThatDataArrivedOn)
{
    // Serial data arrived on a port, defined in thePortThatDataArrivedOn
    // Use thePortThatDataArrivedOn.readString(),
    //       thePortThatDataArrivedOn.readStringUntil(), etc. to read the data
}