Pages: [1] 2   Go Down
Author Topic: Having trouble dislaying images correctly on Processing.  (Read 1986 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 14
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I've set up a simple program using an arduino, a photocell and Processing. Basically it detects if when there's no light and shows the information on a simple display. Processing uses the info from the serial monitor. If there is no light it shows one image (PLAN1). When it detects a certain level of light it shows another image (PLAN2). This is all it is going to do. I'm pretty new to this so had to look through the basics of processing for a while but I got it to work, just not properly. At the moment it shows PLAN2 ok. But when I cove the photocell it shows PLAN1 but it overlays it.  This is because I had to use the tint() function to get it to work. I just want it to switch between images without having to use tint. I said I'd ask in a forum seeing as I couldn't find any info online. Any help at all would be greatly appreciated.

Here's the code for Processing:


import processing.serial.*;
Serial myPort;
String sensorReading="";

PImage img;
PImage img2;
//PImage bg;


void setup() {
  size(1300, 1000);
       
  String portName = Serial.list()[0];

  img = loadImage("PLAN1.png");
  img2 = loadImage("PLAN2.png");

 // bg = loadImage("PLAN2.png");
 
  myPort = new Serial(this, portName, 9600);
  //myPort.bufferUntil('1');
 

}

void draw() {
 
  //image(img, 0, 0);
  //The serialEvent controls the display


void serialEvent (Serial myPort) {
  sensorReading = myPort.readStringUntil('1');
 
  if (sensorReading != null) {
    noTint(); image(img, 0, 0);
  }
   
   
   
    else { tint(255,100);  image(img2, 0, 0) ;
   
}
 
 
 
 
 
  }
 
 
 


 
 
 








 
 
Logged

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

The image display should occur in the draw() function. The decision as to which image to display (in draw) should be based on a value that is set in the serialEvent callback.
Logged

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

I tried putting it in the draw() function but it wouldn't change back when I pulled my hand away from the photocell. It starts off by showing PLAN2, when I cover it it shows PLAN1 perfectly, but then when I uncover it it doesn't change back to PLAN2. Any idea what the problem could be? What value should I put in the serialEvent callback? Sorry if these questions are obvious but I'm just getting the hang of it.
Logged

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

Quote
What value should I put in the serialEvent callback?
I don't know what your code looks like now, so I can't tell you that. (Use the # icon when posting code.)

Quote
It starts off by showing PLAN2, when I cover it it shows PLAN1 perfectly, but then when I uncover it it doesn't change back to PLAN2.
Could be an Arduino problem, too. Can't say for sure without seeing the Arduino code.
Logged

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

Ok so here's the arduino code. I took it from a basic night light example:


Code:
/*
This example shows the output of an analogRead() of a Photocell.
 By M.Gonzalez
 www.codingcolor.com
 The example code is in the public domain
 */

int photocellPin = 0;// Photocell connected to analog pin 0
int photocellVal = 0; // define photocell variable
int ledPin = 9;// LED connected to digital pin 9
int ledState = 0;//state of the led
int fadeDown = 30;//delay per fade
int fadeUp = 20;//delay per fade
int minLight = 200;//min light threshold
int maxLight = 300;//max light threshold


void setup() {
  //Serial.begin(9600);
  pinMode(photocellPin, INPUT);
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}
void loop() {
  photocellVal = analogRead(photocellPin);

  if (photocellVal < minLight and ledState == 0){
    fadeLed(1);
    //Serial.println("fade up");
  }                     
  else if (photocellVal > maxLight and ledState == 1){
    fadeLed(0);
    // Serial.println("fade down");
  }



}

void fadeLed(int num){
  if (num == 1){
    for(int fadeValue = 0 ; fadeValue <= 255; fadeValue +=5) {
      analogWrite(ledPin, fadeValue);             
      delay(fadeUp);                           
    }
    ledState = 1;
   
    Serial.println("1");



  }
  else{ 
    for(int fadeValue = 255 ; fadeValue >= 0; fadeValue -=5) {
      analogWrite(ledPin, fadeValue);             
      delay(fadeDown);                           
    }
    ledState = 0;
   
    Serial.println("2");
   

}


}

The Processing code looks like this now.

Code:
import processing.serial.*;
Serial myPort;
String sensorReading="";

PImage img;
PImage img2;
//PImage bg;


void setup() {
  size(1300, 1000);
       
  String portName = Serial.list()[0];

  img = loadImage("PLAN1.png");
  img2 = loadImage("PLAN2.png");

 // bg = loadImage("PLAN2.png");
 
  myPort = new Serial(this, portName, 9600);
  //myPort.bufferUntil('1');
 

}

void draw() {
 
  if (sensorReading != null) {
     image(img, 0, 0);
  }
   
   
   
    else {   image(img2, 0, 0) ;
   
}


void serialEvent (Serial myPort) {
  sensorReading = myPort.readStringUntil('1');
 
 
  }
 
 
As I said, it works to some extent now.  It starts off by showing PLAN2, when I cover it it shows PLAN1 perfectly, but then when I uncover it it doesn't change back to PLAN2. The Processing code I posted in the first post probably looks better, even if it is tinted. I'd love to just get it working. I got to the stage I'm at now by tinkering with the code on each side. There's more than likely code I don't need but I don't mind as long as it's working. Any ideas? Thanks again for replying.
Logged

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

Code:
  sensorReading = myPort.readStringUntil('1');
Read the serial data until a 1 arrives. Store the data in a string variable. I don't know what you are thinking, here.

The Arduino sends a character, '1' or '2', followed by a carriage return and line feed. The Processing application should read the string until the carriage return arrives.
Logged

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

Thanks again, I'm new to coding but figuring it out. Ok so after a bit of work and thanks to your help I got a bit further. In Processing, I changed the this section of code
Code:
myPort = new Serial(this, portName, 9600);
  myPort.bufferUntil('\r');

and this

Code:
void serialEvent (Serial myPort) {
  sensorReading = myPort.readStringUntil('\n');
 
 
  }

and now it is one step closer to working.

It didn't work at all with myPort.readStringUntil('\r') so I changed it to myPort.readStringUntil('\n')

What happens now is it starts with PLAN2, then I cover the light and the image quickly fades to PLAN1. No tint, it looks clean. I uncover the light and it changes back to PLAN2. Perfect, all seems good. I then cover the light again and it wont change back to PLAN1. It stops to work. I also the led connected so I know the arduino is still reading the light. To get it to keep working again I have to quit the Processing app and restart.

I'm thinking there should be some type of loop or refresh command to restart the sensorReading.
Logged

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

Quote
I'm thinking there should be some type of loop or refresh command to restart the sensorReading.
You can use the print() function, to print to the bottom of the IDE window. Use that to print information when the serialEvent() callback gets called, to print what was read from the serial port, etc.

sensorReading should contain "1" or "2". Unless you changed the code in draw(), as soon as sensorRead is value in the callback, the image changes. There is no way to unvalue sensorReading, as your code is written.

I think that the draw() function should display an image based on the actual value in sensorReading, not the presence or absence of a value.
Logged

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

I think I understand what you mean. The sensorReading can't be null again. So I should change that line. So it should look something like this:

Code:
void draw() {
 
  if (sensorReading = "1") {
     image(img, 0, 0);
  }
   
   
   
     if (sensorReading = "2") {
     image(img, 0, 0);
  }
   
}

Would that be correct?
Logged

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

Quote
Would that be correct?
Yes.
Logged

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

Ok, sorry about all these questions now but I'm so close. changed them from if

Code:
(sensorReading != null) {
     image(img, 0, 0);
  }

to

Code:
if (sensorReading == "1") {
     image(img, 0, 0);
  }

like I said above and now it's not showing any images at all! I thought that would work. This is a bit of a disaster! It must have omething to do with how it's readin the serail monitor. The serial monitor just prints
Code:
1
2
1
2
1
2


so maybe that's what the problem is. I'm really stumped on this one.

What did you mean by
Quote
You can use the print() function, to print to the bottom of the IDE window. Use that to print information when the serialEvent() callback gets called, to print what was read from the serial port, etc.
Is this with the arduino code or the Processing code.
Logged

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

Quote
It must have omething to do with how it's readin the serail monitor.
Processing doesn't read the serial monitor. If you have the serial monitor open, Processing can not connect to the serial port that the Arduino is writing to, so, of course it won't get any serial data.

Quote
Is this with the arduino code or the Processing code.
Where is the serialEvent callback?
Logged

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

The serialEvent callback is in the Processing code.

Code:
import processing.serial.*;
Serial myPort;
String sensorReading="";

PImage img;
PImage img2;


void setup() {
  size(1300, 1000);
   
       
  String portName = Serial.list()[0];

  img = loadImage("PLAN1.png");
  img2 = loadImage("PLAN2.png");
 
  myPort = new Serial(this, portName, 9600);
  myPort.bufferUntil('\r');
 
}

void draw() {
 
 
 
  if (sensorReading != null) {
     image(img, 0, 0);
     
  }
   
   
    if (sensorReading == null) { image(img2, 0, 0);
   
}


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

  }
 
 

So how do I use the print() function to print the information when serialEvent() gets called? I tried various ways but can't seem to get it to work. It's showing PLAN1, PLAN2, PLAN1 and then just stopping. I tried changing != null to == "1" but that just showed no images at all. Is there any way to unvalue the sensorReading? What am I missing in the serialEvent callback in the code above? I've tried putting in various print() functions and loops but nothing is working. I've been at this for nearly 10 hours today! Sorry if I'm bothering you with all these questions.
Logged

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

Quote
What am I missing in the serialEvent callback in the code above?
Some debug statements.

Quote
I tried changing != null to == "1" but that just showed no images at all.
This would imply that no serial data is arriving. But, you don't know that, because there are no debug statements.

Quote
Is there any way to unvalue the sensorReading?
No. sensorReading always has a value. Sometimes that value is a NULL string, but it always has a value.

Quote
I've tried putting in various print() functions and loops but nothing is working.
What do you mean by "nothing is working"? If you put a println() statement in setup(), do you see the output at the bottom of the IDE window?

If so, then something is working. If not, then there is a real problem.

If you put println("Some serial data arrived"); in serialEvent, you can tell whether serial data is arriving. If you put
print("Serial string: [");
print(sensorReading);
println("]");
in serialEvent, you can see WHAT serial data arrived.

If you never see any of the messages from the serialEvent callback, but you do see the message from setup(), then we know something else.
Logged

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

Yes, it is printing at the bottom of the IDE, both from setup() and serialEvent.

print(sensorReading); also displays 1 or 2 depending on if there's light or not. So they both work. What isn't working is the images.

What do you mean by debug statements in the serialEvent?

This is what it's like now.

 
Code:
void serialEvent (Serial myPort) {
 
  sensorReading = myPort.readStringUntil('\n');
 
    print(sensorReading);
 
  }
Logged

Pages: [1] 2   Go Up
Jump to: