The HC-SR04 ultrasonic sensor gives me "null"

edited March 2018 in Arduino

Hi, programmers. I have asked many questions about an art project that I'm making, but in different threads. This could be the fifth(?) but here I go...again. The thing is that I'm having troubles with my sensor and the response in Processing. I found the way to stablish communication between the two programs (Arduino and Processing) but when I wanted to execute an "if" statement the sensor doesn't work and gives me the "null" answer. It's a problem with the code in both programs or just the sensor?

Thanks in advance!

Here are the both codes:

Arduino

/* How to use the HC-SR04 Ultrasonic Sensor with Arduino 
   Dev: Michalis Vasilakis // Date: 23/7/2015 // www.ardumotive.com */

//Libraries
#include "Ultrasonic.h"

//Define pins ultrasonic(trig,echo)
Ultrasonic ultrasonic(A0,A1);

//Variables
int distance;
int ledPin = 13;

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

void loop(){
  distance = ultrasonic.distanceRead(CM); //Use 'CM' for centimeters or 'INC' for inches
  //Print distance...
  if (distance <= 150) {
    Serial.print("SI");
    digitalWrite(ledPin, HIGH);
  } else {
    Serial.print(distance);
    digitalWrite(ledPin, LOW);
  }
}

Processing

import processing.serial.Serial;
import processing.video.*;

Serial myPort;
String val;   
Movie video1, video2, video3;



void setup() {
  fullScreen(SPAN);
  background(0);
  video1 = new Movie(this, "estas ahi.mp4");
  video2 = new Movie(this, "estas lejos.mp4");
  video3 = new Movie(this, "me gustaria estar aqui.mp4");
  video1.loop();
  video2.stop();
  video3.stop();
  String portName = Serial.list()[0];
  myPort = new  Serial(this, portName, 9600);
  myPort.bufferUntil('\n');
}

void serialEvent(final Serial s) {
  val = s.readString().trim();
  if (val.equals("SI")) {
    video1.stop();
    video2.loop();
    video3.loop();
  } else {
    video1.loop();
    video2.stop();
    video3.stop();
  }
}


void draw() {
  println(val);
  image(video1,320,120,640,480);
  image(video2,1600,200,640,480);
  image(video3,2880,235,640,480);

} 

void movieEvent(Movie video) {
  video.read();
}

Answers

  • What line gives you null?

    Anyhow, the problem is sort of both. If you make your life easier, you change both codes. On the arduino side, you send a new line character after sending data. On the Processing side, you read the input data from your serial and you split your data based on the new line char. Then you process each of your tokens in the case you get multiple tokens which you can always check by inquiring for the length of the array in the split function (split/splitTokens ===> Reference)

    By the way, notice in your setup: myPort.bufferUntil('\n'); but you are not sending this character in your arduino code. Furthermore, in serialEvent() you should be working with https://processing.org/reference/libraries/serial/Serial_readStringUntil_.html For the time being:

    void serialEvent(final Serial s) {
      val = s.readStringUntil('\n');
    
      if (val==null)
        return;
    
      String in=split(val, '\n');
    
      if (in.length!=0) {
        if (in[0].equals("SI")) {  //Processing only first token in case of multiples
          video1.stop();
          video2.loop();
          video3.loop();
        } else {
          video1.loop();
          video2.stop();
          video3.stop();
        }
      }
    }
    

    Check the following post for reference:

    https://processing.org/reference/split_.html
    https://forum.processing.org/two/discussion/16618/processing-with-arduino-void-serialevent#Item_1
    https://forum.processing.org/two/discussion/22640/can-anyone-help-me-find-what-s-wrong-with-my-code-for-a-video-player-based-off-sensor-reading#latest

    Kf

  • Thanks @kfrajer for the answer.

    When I start the sketch, the videos are running, the sensor is connected (the board LEDs show me that at least) but the null answer its printed in the processing console. :-??

    The thig is that I stablished communication with another code, and it ran perfectly giving me the distances of an object. Then I changed the text that it will be printed and the "if" statement:

    if (distance <= 150) {
        Serial.print("SI");
        digitalWrite(ledPin, HIGH);
    }
    

    I came back to the original code in arduino but keeps printing null.

    So, I don't know what It changed... :-?

  • I also tried the GoToLoop's "Efficient Serial Reading" but nothing...

  • Doing tests I found this on the Arduino side:

    /* How to use the HC-SR04 Ultrasonic Sensor with Arduino 
       Dev: Michalis Vasilakis // Date: 23/7/2015 // www.ardumotive.com */
    
    //Libraries
    #include "Ultrasonic.h"
    
    //Define pins ultrasonic(trig,echo)
    Ultrasonic ultrasonic(A0,A1);
    
    //Variables
    int distance;
    
    
    void setup() {
      Serial.begin(9600);
    
    }
    
    void loop(){
      distance = ultrasonic.distanceRead(CM); //Use 'CM' for centimeters or 'INC' for inches
      //Print distance...
      //Serial.print("objeto a:");
      Serial.print(distance);
      //Serial.println("cm");
    
    }
    

    It seems that the null answer it's because the Serial.print(distance) is not continued by a Serial.println() line.

    I did the tests and it works... but the sent "val" from Arduino acummulate in the serial buffer... like if I demand that if the distance is less than 150cm the program should print "SI", but only one time (that I don't know how to declare it) but every time that the readings are less than 150cm the program prints "SISISI" or "SISISISISISISISI"

    Then, I changed this:

    if (distance <= 150) {
        Serial.println("SI");
        digitalWrite(ledPin, HIGH);
      } else {
        Serial.println("NO");
        digitalWrite(ledPin, LOW);
    }
    

    Because I don't want to see the distance readings, but if an object is inside the limit distance. And it works...BUT! this function-that is inside the serialEvent() void- doesn't works:

    if (val.equals("SI")) {
        video1.stop();
        video2.stop();
        video3.stop();
      } else {
        video1.loop();
        video2.loop();
        video3.loop();
      }
    

    What could be wrong?

    Thanks for reading and any help you could give!

  • Hi, programmers. I'm still stuck in this code. It seems the "if" statement can't evaluate the readings. So, the video won't stop. I don't know what I'm missing...

    Here's the Processing code to play/stop only one video:

    import processing.serial.*;
    import processing.video.*; 
    
    Serial myPort;
    String val;    
    
    Movie video1, video2, video3;
    
    void setup() {
      //fullScreen(SPAN);
      size(640,480);
      video1 = new Movie(this,"estas ahi.mp4");
      //video2 = new Movie(this,"estas lejos.mp4");
      //video3 = new Movie(this,"me gustaria estar aqui.mp4");
      video1.loop();
      //video2.loop();
      //video3.loop();
      String portName = Serial.list()[0];
      myPort = new  Serial(this, portName, 9600);
      myPort.bufferUntil('\n');
    }
    
    void serialEvent (Serial myPort) {
      if (myPort.available() > 0) {
        val=myPort.readStringUntil('\n');
      }
      if (val.equals("SI")) {
        video1.stop();
        //video2.stop();
        //video3.stop();
      } else {
        video1.loop();
        //video2.loop();
        //video3.loop();
      }
    }
    
    void draw() {
      background(0);
      //image(video1,0,0);
      //image(video2,0,0);
      //image(video3,0,0);
      image(video1,320,120,640,480);
      //image(video2,1600,200,640,480);
      //image(video3,2880,120,640,480);
      println(val);
    } 
    
    void movieEvent(Movie video) {
      video.read();
    }
    

    Please if you could check and point out what's wrong and so I can continue with the rest. It's my last week before I present this project! :-SS [-O<

  • Answer ✓

    if you want to only play the vide once, add a boolean variable to check if the video it's been alredy played it would be something like this

    declare a global variable:

    boolean reproducido = false;

    when you want to play the video use this:

    if(!reproducido)
    {
      video1.loop();
      reproducido = true;
    }
    

    so once it stops the video will never play again (unless that you change the value of the "reproducido" variable). You should use one variable for each video if you want to play them on different instances. Last but not least, if i was the one making tha project i would fake the sensor readings in order to test the processing program, so i will pass trought some random values to check the logic of the program.

Sign In or Register to comment.