Arduino Serialread makes my processing animation stop

edited September 2015 in Arduino

Hey guys, I want to control a ball's acceleration in a proccesing animation, accordingly to a analogue input on my Arduino. The balls acceleration and behaviour is written with PVectors (see code below) but when I activate my arduino sketch, the ball just disappears from the window. I have made several simple tests were I for an example changed the size of an ellipse by mapping the serialRead with success, so the communication between Arduino and Processing is not the problem.

//the code:

import processing.serial.*;
Serial myPort; 

Mover mover;

float inByte;

void setup(){
  size(800,600);
  background(240);
  smooth();
  mover = new Mover();

  myPort = new Serial(this,Serial.list()[2], 9600);
  myPort.bufferUntil('\n');
}


void draw(){
  background(240);
  mover.update();
  mover.checkEdges();
  mover.display();

  fill(10);

}

void serialEvent (Serial myPort){
  String inString = myPort.readStringUntil('\n');

  if(inString != null){
    inString = trim(inString);
    inByte = float(inString);
    inByte = map(inByte,0,1023,0,5);
  }
}


//newtab 
class Mover{
  PVector location;
  PVector velocity;
  PVector acceleration;
  float topspeed;

  Mover(){
    location = new PVector(width/2,height/2);
    velocity = new PVector(0,0);
    topspeed = 10;
  }

  void update(){
    acceleration = PVector.random2D();
    acceleration.mult(inByte);

    velocity.add(acceleration);
    velocity.limit(topspeed);
    location.add(velocity);
  }

  void display(){
    noStroke();
    fill(10);
    ellipse(location.x, location.y, 50, 50);

  }


void checkEdges(){
  if(location.x > width){
    location.x = 0;
  }
  else if (location.x < 0 ){
    location.x = width;
  }

  if(location.y > height){
    location.y = 0;
  }
  else if(location.x < 0){
    location.y = height;
  }
}
}

Answers

  • You'll get a better response if you format your code. Here's how:

    http://forum.processing.org/two/discussion/8045/how-to-format-code-and-text

  • ahh, thx for the tip bilmor

  • edited September 2015

    Dunno whether it helps or not, but I've got some tips anyways:
    Since you had already activated bufferUntil(), just a simple readString() within serialEvent() is enough:

    https://Processing.org/reference/libraries/serial/Serial_bufferUntil_.html
    https://Processing.org/reference/libraries/serial/Serial_readString_.html

    Also it seems like inByte is used internally inside Mover class mostly.
    So you should consider declaring it a member of it.

    In short, something like this: O:-)

    import processing.serial.Serial;
    
    Mover mover;
    
    void setup() {
      size(800, 600, JAVA2D);
      smooth(4);
    
      mover = new Mover();
    
      new Serial(this, Serial.list()[2], 9600).bufferUntil(ENTER);
    } 
    
    void serialEvent(Serial s) {
      mover.inByte = map( float(s.readString().trim()), 0, 1023, 0, 5 );
    }
    
    class Mover {
      static final int TOP_SPEED = 10;
      final PVector loc = new PVector(), vel = new PVector(), acc = new PVector();
    
      float inByte;
    
      Mover() {
        loc.set(width>>1, height>>1);
      }
    
      void update() {
        PVector.random2D(acc).mult(inByte);
        vel.add(acc);
        vel.limit(TOP_SPEED);
        loc.add(vel);
      }
    }
    
  • Thx for the advice GoToLoop. As a test I managed to control the size of the mover with inByte but when i add more movers to the animation they all disappear. And when I try to multiple inByte with the acc, the mover disappears again.

  • Hey i think that the problem is that processing Serial lags when arduino sends too much data. since the values dont change over a certain period of time, all the data gets buffered every time that the the arduino prints data over the serial port. and if the values are the same every time, that wll be buffered and readed afterward by processing. Add a delay of 25 millisec to your arduino sketch. and check if it works. It worked for me. The lag was so bad that i could unplug my arduino, and processing was still "receiving data from the comport".

  • I tried to add delay to my Arduino sketch but i didn't work :( i also tried with delay(100), but my mover still disappears. My Arduino sketch looks like this:

    #include "pitches.h"
    
    //photocell variables
    int photoRPin = 0;
    int ledPin = 12;
    int tonePin = 8; 
    int buttonPin = 2; 
    
    int buttonPushCounter = 1;
    int buttonState = 0; 
    int lastButtonState = 0; 
    
    
    int minLight = 1023;
    int maxLight = 0;
    int lightLevel = 0;
    int newLightLevel = 0; 
    
    
    
    int melody[] = {
    
      NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4,
      NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
      NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5,
      NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
      NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6,
      NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
      NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7,
      NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
    };
    
    void setup() {
      Serial.begin(9600);
      pinMode(tonePin,OUTPUT);
      pinMode(ledPin,OUTPUT);
      pinMode(buttonPin,INPUT);
      delay(2);
    
    
      while (millis() < 5000) {
      lightLevel = analogRead(photoRPin);
      if (lightLevel > maxLight){
        maxLight = lightLevel;
      }
      if (lightLevel < minLight){
        minLight = lightLevel;
        }
      }
       tone(tonePin, melody[22],100);
       delay(100);
       tone(tonePin, melody[22],100);
       noTone(tonePin);     
    
    }
    
    void loop() {
    
      buttonState = digitalRead(buttonPin);
    
      if(buttonState != lastButtonState){
        if (buttonState == HIGH){
          buttonPushCounter++;
          Serial.println("on");
          Serial.print("number of button pushes:  ");
          Serial.println(buttonPushCounter);
         }
       else {
         Serial.println("off");
       }
      }
      lastButtonState = buttonState;
    
    
      if(buttonPushCounter % 2 == 0){
    
        lightLevel = analogRead(photoRPin);
          if (lightLevel > maxLight){
          maxLight = lightLevel;
        }
        if (lightLevel < minLight){
          minLight = lightLevel;
          }
    
           Serial.println(lightLevel);
           delay(100);
         lightLevel = map(lightLevel,minLight,maxLight, 0 , 47);
         lightLevel = constrain(lightLevel, 0 , 47);
    
         if(lightLevel == 0){
           noTone(tonePin);
         } else {
             delay(100);
             tone(tonePin, melody[lightLevel],10);
          }
    
         newLightLevel = map(lightLevel,0,47,0,150);
         analogWrite(ledPin,newLightLevel);
    
      } else {
        digitalWrite(ledPin, LOW);
        digitalWrite(tonePin, LOW);
        noTone(tonePin);
      }
    }
    
Sign In or Register to comment.