Pages: [1] 2   Go Down
Author Topic: problem with commnunicating arduino with processing (both sending and receiving)  (Read 1225 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello everyone,

I'm now working on how to communicate arduino with processing in both way. means the processing can read value from arduino to trigger certain animation, and the arduino can trigger some events ( like led on) when the animation runs in a certain point.

I wrote two quick sketches in arduino and processing. it is a snake goes from left to the right side of the screen. when it hits the right side, it will stop, and the led of arduino will be on for a certain period (3 seconds). after that, the snake goes from left to right again, and the led should be off for the next round.

the problem of my sketch is, the led will light up once, but never turns off again. i tried everything I could yet it still wont work.

does anyone have the similar problem or can anyone help me out ?


i'm really appreciated!

here is the code in arduino
int signal2 = '1';
int signal3 = '0';
void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
  Serial.write(signal3);
}

void loop() {
  byte check;
  if (Serial.available()>0) {
    check = Serial.read();
    if(check == '0'){
      digitalWrite(13, HIGH);
      delay(3000);              // wait for a second
      Serial.write(signal2);
    }
    else {
      digitalWrite(13, LOW);
      Serial.write(signal3);
    }
  }
}


======================

here is the code in processing:

import processing.opengl.*;
import processing.serial.*;
Serial port;

Mover[] mover;
int nummover = 1;

void setup() {
  frameRate(30);
  size(1000,1000,OPENGL);
  smooth();
  background(0);
  port = new Serial(this, "COM3", 9600);
  mover = new Mover[nummover];
  for(int i=0; i<nummover; i++) {
    mover=new Mover();
  }
}

void draw() {
  noStroke();
  background(255);
  int signal = port.read();
  if(signal == '1') {
    for (int i=0; i<nummover; i++) {
      mover.putAhold = false;
    }
  }
  for (int i=0; i<nummover; i++) {
    mover.update();
    mover.checkedge();
    mover.display();
  }

  int sta;
  if(mover[0].putAhold == true) {
    sta = '0';
  }
  else {
    sta = '3';
  } 
  port.write(sta);
  println(sta);
}

class Mover {
  PVector[] location;
  PVector velocity;
  PVector acc;
  float theta=random(360);
  float ra=6;
  float co=20;
  int tail = 250;
  boolean putAhold = false;

  Mover () {
    location = new PVector[tail];
    for (int i=0; i<tail; i++) {
      location = new PVector(0,height/2);
    }
    velocity = new PVector(0,0);
  }

  void update() {

    acc = new PVector(ra,cos(radians(theta))*ra);
    acc.normalize();
    velocity.add(acc);
    if(putAhold == true) {
      velocity.limit(0);
    }
    if(putAhold == false) {
      velocity.limit(6);
    }

    for(int i=tail-2; i>=0; i--) {
      location[i+1].x = location.x;
      location[i+1].y = location.y;
      location.add(velocity);
    }
    theta += 5;
  }

  void checkedge() {
    for(int i=tail-2; i>=0; i--) {
      if (location.x>width) {
        location.x=0;
        putAhold = true;
      }
    }
  }

  void display() {
    for(int i=tail-2; i>=0; i--) {
      strokeWeight(5);
      stroke(0,(100-i*1));
      if(location[i+1].x - location.x < 2) {
        line(location.x, location.y, location[i+1].x, location[i+1].y);
      }
    }
  }
}





Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 642
Posts: 50423
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
int signal2 = '1';
int signal3 = '0';
Names like zero and one would make more sense.

  for(int i=0; i<nummover; i++) {
    mover=new Mover();
  }
This is why the code buttons exists. Either the forum software or you screwed up this code. I'll assume that it was you posting the code incorrectly rather than you screwing up the code.

But, why do you have a one element array?

Serial data transfer is asynchronous. That means that you can never tell when it will happen. Yet, in the processing sketch, you assume that there will be data to read on every pass through draw().

You need to implement the serialEvent method, to handle serial data coming in. You'll need to figure out a way (global variables, typically) to make draw() and serialEvent() share data.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

thank you paul!
the mover = new Mover was a mistake when i paste to the forum. i have .

i just set one becoz it's more clean for the first test. i actually will have more of this object.

I just tried with serialEvent as you suggested. but the problem is still there. here is my modified code in processing. I'll skip the mover class

import processing.opengl.*;
import processing.serial.*;
Serial myPort;


String signal;
Mover[]
mover;
int nummover = 7;
int flag;

void setup() {
  frameRate(30);
  size(1000,1000,OPENGL);
  smooth();
  background(0);
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600);
  mover = new Mover[nummover];
  myPort.bufferUntil('\n');
  for(int i=0; i<nummover; i++) {
    mover=new Mover();
  }
}

void draw() {
  noStroke();
  background(255);
  if(flag == '1') {
    for (int i=0; i<nummover; i++) {
      mover.putAhold = false;
    }
  }
  for (int i=0; i<nummover; i++) {
    mover.update();
    mover.checkedge();
    mover.display();
  }

  int sta;
  if(mover[0].putAhold == true) {
    sta = '0';
  }
  else {
    sta = '3';
  } 
  myPort.write(sta);
  println(sta);
}

void serialEvent(Serial myPort) {
 signal = myPort.readStringUntil('\n');
 flag = int(signal);
}

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 642
Posts: 50423
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
the mover = new Mover was a mistake when i paste to the forum
So you repeated it?

Modify your posts. Select the code, and press the button with the # icon on it.

If you didn't change your Arduino code, your serialEvent() method is never called. It won't be called until the Arduino sends a carriage return, which it currently does not.
« Last Edit: November 07, 2011, 01:21:27 pm by PaulS » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi paul. I looked through the communication example in arduino. i did modified the code in arduino, yet it still stuck in the middle. It would be really helpful if u could tell me what kind of problem it is. i assume it might be the logic in processing code.

arduino
Code:
int signal1 = '1';
int signal0 = '0';
void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {
  byte check;
  if (Serial.available()>0) {
    check = Serial.read();
    if(check == '0') {
      digitalWrite(13, HIGH);
      delay(3000);
      Serial.print(signal1);
    } else {
    digitalWrite(13, LOW);
    Serial.print(signal0);
    }
  }
}

processing
Code:
import processing.opengl.*;
import processing.serial.*;
Serial myPort;

int signal;
Mover[] mover;
int nummover = 7;

void setup() {
  frameRate(30);
  size(1000,1000,OPENGL);
  smooth();
  background(0);
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600);
  mover = new Mover[nummover];
  myPort.bufferUntil('\n');
  for(int i=0; i<nummover; i++) {
    mover[i]=new Mover();
  }
}

void draw() {
  noStroke();
  background(255);
 
  for (int i=0; i<nummover; i++) {
    mover[i].update();
    mover[i].checkedge();
    mover[i].display();
  }

  int sta;
  if(mover[0].putAhold == true) {
    sta = '0';
  }
  else {
    sta = '3';
  } 
  myPort.write(sta);
  println(sta);
}

void serialEvent(Serial myPort) {
 signal = myPort.read();
   if(signal == '1') {
    //myPort.clear();
    for (int i=0; i<nummover; i++) {
      mover[i].putAhold = false;
    }
  }
}


thank you!
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 642
Posts: 50423
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
i did modified the code in arduino, yet it still stuck in the middle.
I have no idea what "it still stuck in the middle" means. I have no idea what "it" is.

However, the Processing code is going to buffer serial data until it receives a carriage return, because you told it to:
Code:
  myPort.bufferUntil('\n');

So, it might be useful in the Arduino code to actually send a carriage return, now and then. These are all of your serial statements:
Code:
  Serial.begin(9600);
  if (Serial.available()>0) {
    check = Serial.read();
      Serial.print(signal1);
    Serial.print(signal0);
None of these sends a carriage return.

Change the Serial.print() calls to Serial.println() calls to send the data followed by a carriage return/line feed.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello paul, thanks for your replying again. however it is still not working. I change the Serial.println to Serial. write in arduino, becaus it keeps sending weird numbers.

I think the problem here is the arduino always read '1' from processing. I test them separately they  work fine. the processing sending the correct number, and if i type in serial monitor in arduino, it response well too.

here is the code that I just modified

Code:
void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {
  int check;
  if (Serial.available()>0) {
    check = Serial.read();
    if(check == '0') {
      digitalWrite(13, HIGH);
      delay(3000);
      Serial.write('1');
    } else {
    digitalWrite(13, LOW);
    Serial.write('0');
    }
  }
}


Code:
import processing.opengl.*;
import processing.serial.*;
Serial myPort;

int signal;
Mover[] mover;
int nummover = 7;

void setup() {
  frameRate(30);
  size(1000,1000,OPENGL);
  smooth();
  background(0);
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600);
  mover = new Mover[nummover];
  for(int i=0; i<nummover; i++) {
    mover[i]=new Mover();
  }
}

void draw() {
  noStroke();
  background(255);
 
  for (int i=0; i<nummover; i++) {
    mover[i].update();
    mover[i].checkedge();
    mover[i].display();
  }

  int sta;
  if(mover[0].putAhold == true) {
    sta = '0';
  }
  else {
    sta = '3';
  } 
  myPort.write(sta);
  //println(sta);
}

void serialEvent(Serial myPort) {
 signal = myPort.read(); 
 println(signal);
 if(signal == '1') {
    for (int i=0; i<nummover; i++) {
      mover[i].putAhold = false;
    }
  } 
}

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 642
Posts: 50423
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
I change the Serial.println to Serial. write in arduino, becaus it keeps sending weird numbers.
What does this mean?

With the changes you've made now, the serialEvent method never gets called. So, you will never read anything from the Arduino.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

if u run the code, u will see the println(signal) is printing the values that received from arduino
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 642
Posts: 50423
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That would require that I do a lot of work that I shouldn't need to do. You have the hardware setup with the sketches uploaded.

Just show me the latest code on the Arduino, the latest Processing sketch, and the output from the println() commands in Processing.

What is possibly causing an issue is that the Arduino is sending '1' as an int as a string, which means that it is sending the string "49<cr><lf>". The string "49" is then being converted to an int, as 49, which, of course doesn't look like 1.

On the Arduino, change
Code:
int signal1 = '1';
int signal0 = '0';
to
Code:
int signal1 = 1;
int signal0 = 0;
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hello Paul,

I dont think the problem is '1' or 1. I changed the value like u said, however it is still not working.

the processing is printing 0 when it hits the boundary and 3 when it is not. the problem is the arduino just cannot receive the 3 sent from processing....
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 642
Posts: 50423
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
the problem is the arduino just cannot receive the 3 sent from processing....
Yes, it can. Post your latest code.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
int signal1 = 1;
int signal0 = 0;

void setup()
{
  Serial.begin(9600);
  pinMode(13, OUTPUT);
}

void loop() {
  byte check;
  if (Serial.available()>0) {
    check = Serial.read();
    if(check == 1) {
      digitalWrite(13, HIGH);
      delay(3000);
      Serial.write(signal1);
    } else {
    digitalWrite(13, LOW);
    Serial.write(signal0);
    }
  }
}


Code:
import processing.opengl.*;
import processing.serial.*;
Serial myPort;

int signal;
Mover[] mover;
int nummover = 7;
  int sta;
 
void setup() {
  frameRate(30);
  size(1000,1000,OPENGL);
  smooth();
  background(0);
  println(Serial.list());
  myPort = new Serial(this, Serial.list()[0], 9600);
  mover = new Mover[nummover];
  for(int i=0; i<nummover; i++) {
    mover[i]=new Mover();
  }
}

void draw() {
  noStroke();
  background(255); 
  for (int i=0; i<nummover; i++) {
    mover[i].update();
    mover[i].checkedge();
    mover[i].display();
  }

  if(mover[0].putAhold == true) {
    sta = 1;
  }
  else {
    sta = 3;
  } 
  myPort.write(sta);
  println(sta);
}

void serialEvent(Serial myPort) {
 signal = myPort.read(); 
// println(signal);
 if(signal == 1) {
    for (int i=0; i<nummover; i++) {
      mover[i].putAhold = false;
    }
  } 
}

class Mover {
  PVector[] location;
  PVector velocity;
  PVector acc;
  float theta=random(360);
  float ra=6;
  float co=20;
  int tail = 250;
  boolean putAhold = false;

  Mover () {
    location = new PVector[tail];
    for (int i=0; i<tail; i++) {
      location[i] = new PVector(0,height/2);
    }
    velocity = new PVector(0,0);
  }

  void update() {

    acc = new PVector(ra,cos(radians(theta))*ra);
    acc.normalize();
    velocity.add(acc);
    if(putAhold == true) {
      velocity.limit(0);
    }
    if(putAhold == false) {
      velocity.limit(6);
    }

    for(int i=tail-2; i>=0; i--) {
      location[i+1].x = location[i].x;
      location[i+1].y = location[i].y;
      location[i].add(velocity);
    }
    theta += 5;
  }

  void checkedge() {
    for(int i=tail-2; i>=0; i--) {
      if (location[i].x>width) {
        location[i].x=0;
        putAhold = true;
      }
    }
  }

  void display() {
    for(int i=tail-2; i>=0; i--) {
      strokeWeight(5);
      stroke(0,(100-i*1));
      if(location[i+1].x - location[i].x < 2) {
        line(location[i].x, location[i].y, location[i+1].x, location[i+1].y);
      }
    }
  }
}

Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 642
Posts: 50423
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You aren't, by any chance, using a Mega, are you?
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 20
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I only have an arduino duemilanove

do u think that is the cause?
Logged

Pages: [1] 2   Go Up
Jump to: