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

edited October 2015 in Arduino

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

Video of situation:

I made a simple sketch which does this no problem. It is only when I try to have the Arduino send data to Procesing 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);
      }

    }

Answers

  • edited July 2015

    delay(200);

    ?

  • Replace <= with < pls

    Because = twice is ambigous

    Also when have this kind of code try

    if .... .... else if .....

    You don't use else if

  • Thanks Chrisir.

    The delay is to show that by alternating the Serial.write slowly it will successfully send the message.

    I will try the comparison symbol and play with the if/else if combination.

    A friend was saying that it might be because the Arduino is simply sending the message too fast for Processing to pick up. (i.e. 120 fps vs 30 fps)

  • Try adding Serial.flush() immediately after Serial.write()

    Any reason you are not using Serial.print()?

  • Hi Joepekoe, I will try that. I am actually reinvestigating this now since the summer is over and I have some free time. I think the biggest thing we ran into was that the data is coming over too fast.

    I will advise after more testing. Thank you for your suggestion.

  • I guess you are on the right track. Always put a delay() inside of your arduino-sketch or control the amount of data sent by any other kind of timing. The arduino has no fixed framrate like processing and the number of loop()-cycles beeing executed per second depends on the code that is executed.

    Without delays, it can happen that thousands of values/messages are sent every second. So when you read one value per frame at a framrate of 60 in processing, it can take minutes to process all the serial-data that has been sent in the first second of your arduino sketch.

  • Good call. That's essentially the battle.

    As noted above i'm using this with an electronic drum pad. So timing is key.

    Given that a fair amount of people will want to send data from an Arduino to their computer I'm surprised that this doesn't comes up more often/the existence of an established way to deal with this - especially with such trivially simple data (on or off when a switch is flipped).

    Should have time tomorrow or the next day!

  • It is a common topic. In a case like yours, where you don't need continous data, i would only send messages as soon as the state (on/off) of your pad changes. Example:

    int ledPin = 13;
    int padPin = A0;
    boolean padOn = false;
    
    int THRESHOLD = 20;
    
    void setup() {
      pinMode(padPin, INPUT_PULLUP);
      pinMode(ledPin, OUTPUT);
      Serial.begin(9600);
    }
    
    void loop() {
    
      int val = analogRead(padPin);
    
      // only do something, when value is below threshold AND it was above before 
      if (val <= THRESHOLD && padOn) {
        digitalWrite(ledPin, LOW);
        Serial.write('0');
        padOn = false;
      }
      // only do something, when value is above threshold AND it was below before 
      else if (val > THRESHOLD && !padOn) {
        digitalWrite(ledPin, HIGH);
        Serial.write('1');
        padOn = true;
      }
      // a small delay is a good idea in most situations
      delay(5);
    }
    

    And in processing i prefer the serialEvent()-function to handle incoming serial-data.

  • Me too on serialEvent(). Lotsa forum threads using it: :D
    http://forum.Processing.org/two/discussions/tagged?Tag=serialEvent()

  • Excellent points, I look forward to round 2 tonight!

  • That worked like a charm!

    I ended up using a button so I could keep the setup simple while experimenting. This works great. I think it was the "padOn" boolean trick that made it happen.

  • Here is the Arduino Code:

    //  http://www.arduino.cc/en/Tutorial/Button
    // Slightly modified to send over Serial
    // http://forum.processing.org/two/discussion/11649/send-data-from-arduino-to-processing-over-serial-help-please#latest
    
    // constants won't change. They're used here to
    // set pin numbers:
    const int buttonPin = 2;     // the number of the pushbutton pin
    const int ledPin =  12;      // the number of the LED pin
    boolean padOn = false;
    
    // variables will change:
    int buttonState = 0;         // variable for reading the pushbutton status
    
    void setup() {
      // initialize the LED pin as an output:
      pinMode(ledPin, OUTPUT);
      // initialize the pushbutton pin as an input:
      pinMode(buttonPin, INPUT);
      // Starts Serial
      Serial.begin(9600);
    }
    
    void loop() {
      // read the state of the pushbutton value:
      buttonState = digitalRead(buttonPin);
    
      // check if the pushbutton is pressed.
      // if it is, the buttonState is HIGH:
      if (buttonState == HIGH && padOn) {
        // turn LED on:
        digitalWrite(ledPin, HIGH);
        Serial.write('0');
        padOn = false;
      } else if (buttonState == LOW && !padOn) {
      // turn LED off:
      digitalWrite(ledPin, LOW);
        Serial.write('2');
        padOn = true;
      }
    
      // a small delay is a good idea in most situations
      delay(5);
    }
    
  • And the Processing Code:

    // 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);
    
     // Use with "Simple_Button_Send"
     // http://forum.processing.org/two/discussion/11649/send-data-from-arduino-to-processing-over-serial-help-please#latest
    
     //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 == 48)  {
        rect(width/2, height/2, 60, 30);
      }
    }
    
Sign In or Register to comment.