Go Down

#### FS355

Hi there,

I am in desperate need of help. I am doing a school project using processing, Arduino with 2 ultrasonic sensors and what I am trying to do is change between 7 images by using the sensors (left or right) unfortunately I haven't been able to achieve this as I am really new to Arduino and processing and I don't understand where I am going wrong.

The two sensors will be set apart so that when the user approaches the left or right sensor the image changes either going back to the previous image or go to the next image. I want to trigger the change when the distance is between 50 and 60 cm so that the images don't get triggered when you are too close or too far.

The codes that I am using are bellow. Please take a look and help solve this. I only have 4 days to do it plus evaluate it.

Thank you so so much I am very grateful to you all.

Arduino code:
 #include int generalDist = 50;int TRIGGER_PIN1 = 2 ; // Arduino pin tied to trigger pin on the ultrasonic sensor.int ECHO_PIN1    = 4 ; // Arduino pin tied to echo pin on the ultrasonic sensor.int TRIGGER_PIN2 = 7 ; // Arduino pin tied to trigger pin on the ultrasonic sensor.int ECHO_PIN2    = 8 ; // Arduino pin tied to echo pin on the ultrasonic sensor.//#define TRIGGER_PIN  12  // Arduino pin tied to trigger pin on the ultrasonic sensor.//#define ECHO_PIN     11  // Arduino pin tied to echo pin on the ultrasonic sensor.int MAX_DISTANCE1 = 200 ;// Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.int MAX_DISTANCE2 = 200 ;// Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.//#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.int dist1=0;int dist2=0;unsigned int uS;int val= 0;//int Delay_Ms = 300;  //delay value for setting tempo// int range = 0;NewPing sonar1(TRIGGER_PIN1, ECHO_PIN1, MAX_DISTANCE1); // NewPing setup of pins and maximum distance.NewPing sonar2(TRIGGER_PIN2, ECHO_PIN2, MAX_DISTANCE2); // NewPing setup of pins and maximum distance.void setup() {  Serial.begin(9600); // Open serial monitor at 115200 baud to see ping results.  delay(500);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.  uS = sonar1.ping(); // Send ping, get ping time in microseconds (uS).  MAX_DISTANCE1 = ((uS / US_ROUNDTRIP_CM)); // Convert ping time to distance in cm and print result (0 = outside set distance range)  delay(100);     uS = sonar2.ping(); // Send ping, get ping time in microseconds (uS).  MAX_DISTANCE2 = ((uS / US_ROUNDTRIP_CM)); // Convert ping time to distance in cm and print result (0 = outside set distance range)  delay(500);   }void loop() {  delay(100);     int uS = sonar1.ping(); // Send ping, get ping time in microseconds (uS).  dist1 = (uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)  delay (200);  uS = sonar2.ping(); // Send ping, get ping time in microseconds (uS).  dist2 = (uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range)  //range = map(dist, 0, 50, 15, 0);  // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.  //int uS = sonar1.ping(); // Send ping, get ping time in microseconds (uS).  // Serial.print(" ");  delay (500);  Serial.write(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside set distance range) //Serial.print("L"); Serial.write(dist1); if (dist1

Processing Code:

PS only the sensor on TRIGGER_PIN2 = 7 ; ECHO_PIN2    = 8; is working properly and the other one doesnt work.

Thank you again and i am sorry for the long essay

#### PaulS

Code: [Select]
`void setup() {  Serial.begin(9600); // Open serial monitor at 115200 baud to see ping results.  delay(500);                      // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.  uS = sonar1.ping(); // Send ping, get ping time in microseconds (uS).  MAX_DISTANCE1 = ((uS / US_ROUNDTRIP_CM)); // Convert ping time to distance in cm and print result (0 = outside set distance range)  delay(100);     uS = sonar2.ping(); // Send ping, get ping time in microseconds (uS).  MAX_DISTANCE2 = ((uS / US_ROUNDTRIP_CM)); // Convert ping time to distance in cm and print result (0 = outside set distance range)  delay(500);   }`
It's rather useless to ping anything in setup(). Why are you?

Code: [Select]
`  Serial.write(uS / US_ROUNDTRIP_CM); // Convert ping time to distance in cm and print result (0 = outside `
Serial.write() is for sending binary data.

You need to make up your mind what you are sending to Processing. Some delimiters between the values makes it easier to parse the data. Right now, you are sending "xx1<cr><lf>xx2<cr><lf>nnn<cr><lf>" where x is a binary value and nnn is the distance, as a string, that the second ping got, and <cr><lf> are carriage return and line feed.

In Processing, you are reading all the data available on the serial port, which may or may not be a full packet, and storing that data in a 2 element array. The first two bytes are binary data that you then convert to a String. You do nothing with this String except print it, with no indication what the String is.

You are doing all this in draw(), which is wrong.

Make your Arduino program send something like "1, dist1, 2, dist2<cr><lf>",

Make your Processing sketch bufferUntil() the \n arrives. Add a serialEvent() method that gets called when the complete packet has arrived. Read ALL the data, as a String. Then, split the String at the commas, to create an array. If there are 4 values in the array, set global variables, that draw() uses, to useful parts of the array.

#### PaulS

Quote
I do want to send the distance as 1 or 2 for dist1 and dist2 and want it to be sent as bytes to processing and then trigger the changes.

If you measure the distance, why not send that value? Just sending 1 seems useless.

Why do you want the data sent as bytes, when you read as strings?

If you do this:
Code: [Select]
`Serial.print(1);Serial.print(",");Serial.print(dist1);Serial.print(2);Serial.print(",");Serial.println(dist2);`
Processing could receive something like "1,45,2,34<cr><lf>".

Testing leftSensorTriggered or rightSensorTriggered is pointless, as you are getting (incorrectly now, but the above code will fix that) data from both sensors.

What you need to test is which value is smaller. That indicates which side the object being sensed (presumably a person) is closer to.

The values that you get do not distinguish between the values this time and the values last time. You need to store the current readings as the previous readings before updating the current readings. Then, the Processing side needs to compare the current reading with the previous reading to determine whether the object has moved closer, farther away, or stayed still. You need to do that for each side.

Lets work on getting the Arduino side getting, and sending, good data, correctly, only when it needs to. Then, we can work on getting Processing to collect and read that data. Then, we can work on getting Processing to use the data.

#### PaulS

Quote
So what do I do with data now that both sensors printing out the distances?

Well, the first thing you need is another Serial.print() between dist1 and 2, to add a comma.

Then, in Processing, you need a serialEvent() function and some changes in setup():
Quote
String portName = Serial.list()[0];

println(portName);
myPort = new Serial(this, portName, 9600);
myPort.bufferUntil('\n');

Code: [Select]
`void serialEvent(Serial myPort){  boolean validString = true;  // whether the string you got is valid  // read the serial buffer:  String myString = myPort.readStringUntil('\n');  // make sure you have a valid string:  if (myString != null)  {     print("Serialized data: ");     println(myString);     // Use the function to convert the string to an array of ints     int[] nums = int(split(myString, '''));     // Then, make sure that there are 4 values in nums     // You get to figure this out     // Then, copy nums[1] and nums[3] somewhere     // else (global variables) so draw() can use them  }}`

#### PaulS

Quote
unfortunately I am still having troubles with processing. The thing is when I added the "void serialEvent(Serial myPort)" bit it stopped working and I keep getting "Unexpected token: void" highlighting the serialEvent bit and I dont know what is going on really.

I'd guess that you are trying to put serialEvent() inside draw(), rather than after it. Of course, sans your code, it's only a guess.

#### PaulS

You have so many problems in that code that it is hard to know where to start. NO SERIAL DATA should be handled in draw(). GET RID OF ANYTHING THAT DEALS WITH SERIAL DATA in draw().

Code: [Select]
`String myString = myPort.readStringUntil('\n');if (myString != null){print("Serialized data: ");println(myString);// Use the function to convert the string to an array of intsString numbers = "10 50 15 60";int char [] nums = int(split(myString, ''));}`
Let's get some data from the serial port, and print it out. Then, lets create another String instance that we don't use. Then, lets ignore any advice about the TYPE of variable to be created. Finally, let's ignore any advice about the character to use to split the String. Where does that leave us. Thoroughly frustrated, I'm guessing.

Oh, wait. I see the problem. My last post isn't there. Ignore that.

Your serialEvent method needs to be:
Code: [Select]
`void serialEvent(Serial myPort){  // read the serial buffer:  String myString = myPort.readStringUntil('\n');  if (myString != null)  {    print("Serialized data: ");    println(myString);    // Use the function to convert the string to an array of ints    int [] nums = int(split(myString, ','));  }   d1 = nums[1];   d2 = nums[3];}`
where d1 and d2 are global variables that then get used in draw() as the distances from the Arduino sensors.

#### PaulS

Quote
Thanks for that, So this is how processing is printing the data from the arduino

It shouldn't be. But it is because your are reading data all over the place.

Uncomment this:
Code: [Select]
`  //myPort.bufferUntil('\n');`
That is essential code.

Get rid of this, from draw():
Code: [Select]
`  byte[] inBuffer = new byte[2];  while (myPort.available ()> 0) {   inBuffer = myPort.readBytes();    myPort.readBytes(inBuffer);    if (inBuffer != null) {      String myString = new String(inBuffer);      println(myString);    }  }`

And this:
Code: [Select]
` if ( myPort.available() > 0)     {  // If data is available,   //myPort = myPort.read();         // read it and store it in myPort  }`

Remove the whole sensorTriggered() method, for now. Until you get good data into Processing, there is no need to have any code that tries to use that data.

#### PaulS

In serialEvent(), nums is a local array. It goes out of scope before d1 and d2 are assigned values. Move those two assignments up before the closing } after the int nums[] statement.

#### PaulS

Quote
So now I am getting this, what's next?

Verify that the values in d1 and d2 are correct.

Then, use them in draw(). It don't understand what you are trying to do with them, but, now you have them, so you can do whatever it is you are trying to do with them.

#### PaulS

Quote
So does this code seem right to you?

Not entirely. There is too much white space. There is a delay() call. The code is not properly formatted.

There are no sensors that are triggered. There are distances that are known. I think that you need to get rid of rightSensorTriggered and leftSensorTriggered. Create two new variables that hold the previous values of d1 and d2.

Compare d1 to prevD1 to decide if one action is needed. Compare d2 to prevD2 to see if another action is needed.

#### PaulS

Quote
How would do this by removing the booleans and replacing with something like int left, right

Yes.

Quote
When I remove the delays flicker through quickly as soon as the distance is 20 and above

Then, you need to change the frame rate. Unlike loop() on the Arduino, draw() is not called as fast as possible. You can set the frame rate, which defines how often the draw() function is called. The artificial delay is not the solution.

#### PaulS

Code: [Select]
`int left = d1;int right = d2;`
So, what values do left and right have?

Do they ever change?

#### PaulS

Quote
I think that the value of left and right should be 10 and if d1 or d2 are greater than or equal to the left or right the image should change.

No. d1 and d2 are global variables. Therefore, they are initialized to 0. Then, left and right are also initialized to 0. You never assign new values to left and right, and you never use d1 and d2 (that you do assign values to).

#### AWOL

Quote
I have tried different methods of doing it
the experience works better if you show us your attempts.
"Pete, it's a fool (who) looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

#### AWOL

Code: [Select]
`if (right(d2>= dist)){`
"right" is a non-void function taking a boolean parameter?
"Pete, it's a fool (who) looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

Go Up