Processing Video and Ultrasonic Sensor

edited November 2014 in Arduino

Hey there,

I'm trying to control a video through an ultrasonic sensor on my arduino board. I already got the code for the arduino to get the sensor data.

#define echoPin 7 
#define trigPin 8

int maximumRange = 200; 
int minimumRange = 0; 
long duration, distance; 

void setup() {
 Serial.begin (9600);
 pinMode(trigPin, OUTPUT);
 pinMode(echoPin, INPUT);
}

void loop() {
 digitalWrite(trigPin, LOW); 
 delayMicroseconds(2); 

 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10); 

 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);

 distance = duration/58.2;

 if (distance >= maximumRange || distance <= minimumRange){
 Serial.println("-1");
 }
 else {
 Serial.println(distance);
 }

 //Delay 50ms before next reading.
 delay(50);
}

Where I'm having trouble with is writing a processing code which is playing a video when the range is at 30 and showing nothing when the range is above that.

Maybe someone can help me with this problem.

Thanks in advance!

«1

Answers

  • I got it to go on my own. The video is now playing when I'm close to the sensor and it pauses when I'm not. The only problem I have now, is that the video should not at all be shown when I'm not close to the sensor. There should be nothing on the screen till something comes close to the sensor and then the video should start playing. Here's my code so for:

    //Arduino//

    #define trigPin 8
    #define echoPin 9
    
    void setup() {
      Serial.begin (9600);
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
    }
    
    void loop() {
      long distance;
      digitalWrite(trigPin, LOW);
      delayMicroseconds(2); 
      digitalWrite(trigPin, HIGH);
      delayMicroseconds(10); 
      digitalWrite(trigPin, LOW);
      distance = pulseIn(echoPin, HIGH);
    
      if (distance <= 200){
        Serial.print("1");
      }
      else {
        Serial.print("0");
      }
      delay(500);
    }
    

    //Processing//

    import processing.serial.*;
    import processing.video.*;
    Movie myMovie;
    import processing.serial.*;
    Serial myPort; // The serial port:
    String instring  = "";
    
    
    
    void setup() {
      myPort = new Serial(this, "/dev/cu.usbmodemfd121", 9600);
      myPort.bufferUntil('\n');
      size(500, 500);
      frameRate(30);
      myMovie = new Movie(this, "israel.mpeg");
      myMovie.loop();
      myMovie.stop();  
    }
    
    
    void draw() {
    
      if (myMovie.available()) {
        myMovie.read();
      }
      image(myMovie, 0, 0);
      while (myPort.available () > 0) {
       instring = myPort.readString();
       println(instring);
       int sensorAct = Integer.parseInt(instring, 10);
         if (sensorAct == 1){
           println("TEST");
           myMovie.play();
          }
          else {
          myMovie.pause();};
          }
    }
    

    Would be great if somebody could help me out here because I'm absolutely lost now.

  • background(0);

    at the beginning of draw()

  • line 26 inside the if....

  • thank you, that works. but now if I don't put the framerate at around 10 (which is causing my video to be chopping) every second the background repeats shortly in front of the video. how can I manage to stop this behavior and just have the background in the back of the video and when its not active?

  • background() only after line 35?

  • yes you're right. strangely I already tried this but it didn't work then. but now it works. Just another question. I'm trying to put an animation on the place where the video is when it's not active. It is working but only very slow. When I got the animation on it's on sketch it's very fluid but in this sketch its a chopping animation.

    import processing.serial.*;
    import processing.video.*;
    Movie myMovie;
    import processing.serial.*;
    Serial myPort; // The serial port:
    String instring  = "";
    int pulse = 100;
    int bigsmall = 1;
    
    
    void setup() {
      myPort = new Serial(this, "/dev/cu.usbmodemfa131", 9600);
      myPort.bufferUntil('\n');
      size(1024, 768);
      frameRate(30);
      ellipseMode(CENTER);
      noStroke();
      fill(255, 0, 0);
      myMovie = new Movie(this, "israel.mpeg");
      myMovie.loop();
      myMovie.stop();  
    }
    
    
    void draw() {
      {
      if (pulse > 199) {
        bigsmall = 0;
        println("pulse: " + pulse + " bigsmall " + bigsmall);
      } else if (pulse < 101) {
        bigsmall = 1;
        println("pulse: " + pulse + " bigsmall " + bigsmall);
      }
    
      if (bigsmall == 1) {
        pulse += 2;
      } else if (bigsmall == 0) {
        pulse -= 2;  
      }
    
      if (myMovie.available()) {
        myMovie.read();
        image(myMovie, 40, 200);
      }
      while (myPort.available () > 0) {
       instring = myPort.readString();
       println(instring);
       int sensorAct = Integer.parseInt(instring, 10);
         if (sensorAct == 1){
           println("active");
           myMovie.play();
          }
          else {
          background(0);
          ellipse(250, 425, pulse, pulse);
          myMovie.pause();};
          }
    }
    }
    
  • you should put the animation in a function and called it after line 56

    line 41 to 44 after line 50

  • delete line 4

    line 27 to 40 in the new function

  • What do you mean by putting the animation in a function?

  • also the while-loop... shouldn't it be closed after line 46 }

    ?

  • void myAnimation() {

    // here lines 27 to 40 and 55

    }

    ;-)

  • edited December 2014

    say

    myAnimation();

    in line 55

  • you need to make clean code - in draw() either the movie is playing or the animation

    so read the sensor then have one if and else; outside it there shouldn't be anything

    thus you get clean code.

  • yeah I did it and now the animation is with more interim stages but very slow.

    import processing.serial.*;
    import processing.video.*;
    Movie myMovie;
    Serial myPort; // The serial port:
    String instring  = "";
    int pulse = 100;
    int bigsmall = 1;
    
    
    void setup() {
      myPort = new Serial(this, "/dev/cu.usbmodemfa131", 9600);
      myPort.bufferUntil('\n');
      size(1024, 768);
      frameRate(30);
      ellipseMode(CENTER);
      noStroke();
      fill(255, 0, 0);
      myMovie = new Movie(this, "israel.mpeg");
      myMovie.loop();
      myMovie.stop();  
    }
    
    void myAnimation() {
       {
      if (pulse > 199) {
        bigsmall = 0;
        println("pulse: " + pulse + " bigsmall " + bigsmall);
      } else if (pulse < 101) {
        bigsmall = 1;
        println("pulse: " + pulse + " bigsmall " + bigsmall);
      }
    
      if (bigsmall == 1) {
        pulse += 2;
      } else if (bigsmall == 0) {
        pulse -= 2;  
      }
      ellipse(250, 425, pulse, pulse);
       }
    }
    
    
    void draw() {
    
    
      if (myMovie.available()) {
        myMovie.read();
        image(myMovie, 40, 200);
      }
      while (myPort.available () > 0) {
       instring = myPort.readString();
       println(instring);
       int sensorAct = Integer.parseInt(instring, 10);
         if (sensorAct == 1){
           println("active");
           myMovie.play();
          }
          else {
          background(255);
          myAnimation();
          myMovie.pause();};
          }
    }
    
  • edited December 2014

    you haven't done a few things yet : while closing } must be earlier

    line 46 to 49 after 56

    also use ctrl-t to get auto-format (indents)

  • yes you were right. thank you so much. can you tell me why I had to do a different void for my animation so that it works?

  • edited December 2014

    no, I think we just did some house cleaning to see clearer what has to be done...

    the function myAnimation itself wouldn't be faster than without it

  • maybe instead of while we can just say if?

    i don't know

  • edited December 2014

    your animation would be faster without println

    also get rid of framerate?

  • no no it works now, so there's no need to change anything. but thank you! if something else comes up, can you maybe help me out?

  • sure, just pm me

  • edited December 2014

    the normal order btw setup, draw and then other functions

  • edited December 2014

    I better stick with the public posting, right?

    I got three different red points now and I want them to be gone when the sensor is active and the video is shown. They should only appear and pulsate when the sensor is not active. How can I make them disappear when the video is playing?

    It's always the same, just have global var sensorIsActive telling you, whether to show the 3 points or not.

    in draw() say if sensorIsActive { video is shown } else { red points appear and pulsate }

    just don't draw the points when you don't need them (when you have background() at the beginnig of draw() the canvas gets cleared)

    • when checking the sensors make sure to set sensorIsActive to true or to false
  • and

    My final goal is to have three different sensors and every sensor is playing a video on a different point on the sketch when it's active. Do you think this is possible?

    Absolutely, just like above : just have global var sensorIsActive1 and sensorIsActive2 and sensorIsActive3 telling you what to do.

    ;-)

  • Yeah I get what you are saying but isn't this already the case?

      if (sensorAct == 1) {
        println("active");
        myMovie.play();
      } else {
        background(map);
        myAnimation();
        myMovie.pause();
      };
    }
    

    Here it says when it's active play the movie and when it's not active show the animation. What else should I put there to make them disappear?

  • background() at the beginnig of draw() the canvas gets cleared

  • if (sensorAct == 1) {
        background(map);
        println("active");
        myMovie.play();
      } else {
    
  • Yeah I tried this before, but when I do this the video isn't shown anymore. There is only the background when the sensor is active...

  • edited December 2014

    ok then, no background at the beginning of draw()

    when the sensor turns to 1 (where you check the sensor) you can once say

    background(map);  
    

    and then not anymore while playing the movie...

      if (sensorAct == 1) {
        println("active");
        myMovie.play();
      } else {
        background(map);
        myAnimation();
        myMovie.pause();
      };
    }
    
  • edited December 2014

    It works, I put it here

    void draw() {
      if (myMovie.available()) {
        background(map);
        myMovie.read();
        image(myMovie, 200, 400, 300, 300);
    

    Thank you!

  • don't have background() at the beginning of draw()

    when the sensor turns to 1 (where you check the sensor) you can once say

    background(map);

  • So I now I want two (later three) different sensors to play three different movies on three different places in the sketch. But I'm not really getting behind how to start with this. I thought I'd have to change something in the arduino-part of the code and tried to give out a different number for the second sensor.

    This is my simple arduino sketch for one sensor:

    int eingang= A0;
    
    int sensorWert = 0;
    
    void setup()
    {
      Serial.begin(9600);
    }
    
    void loop()
    {
      sensorWert =analogRead(eingang); 
    
      if (sensorWert > 500 )
      {
        Serial.print("0");
      }
      else
      {
        Serial.print("1");
      }
      delay (50);
    }
    

    This is how I changed it with two sensors, but it didn't quite work out in processing:

    int eingang1 = A0;
    int eingang2 = A1;
    
    int sensorWert1 = 0;
    int sensorWert2 = 0;
    
    void setup()
    {
      Serial.begin(9600);
    }
    
    void loop()
    {
      sensorWert1 =analogRead(eingang1);
      sensorWert2 =analogRead(eingang2);  
    
      if (sensorWert1 > 500 )
      {
        Serial.print("0");
      }
      else
      {
        Serial.print("1");
      }
    
        if (sensorWert2 > 500 )
      {
        Serial.print("0");
      }
      else
      {
        Serial.print("2");
      }
      delay (50);
    }
    

    And do I just have to change the processing sketch with another number getting from the sensor or is there more to change?

    import processing.serial.*;
    import processing.video.*;
    Movie myMovie;
    Serial myPort; // The serial port:
    String instring  = "";
    int pulse = 100;
    int bigsmall = 1;
    PImage map;
    PFont mono;
    
    void setup() {
      myPort = new Serial(this, Serial.list()[2], 9600);
      myPort.bufferUntil('\n');
      size(1024, 768);
      frameRate(30);
      imageMode(CENTER);
      ellipseMode(CENTER);
      noStroke();
    
      map = loadImage("map.png");
      PGraphics pg = createGraphics(map.width, map.height);
      pg.beginDraw();
      pg.background(255);
      pg.noStroke();
      pg.fill(0);
      pg.ellipse(200, 400, 275, 275);
      pg.filter(BLUR, 7);
      pg.endDraw();
      map.mask(pg);
    
      mono = loadFont("BlueMono-48.vlw");
      myMovie = new Movie(this, "movie.mov");
      myMovie.loop();
      myMovie.stop();
    }
    
    void draw() {
      if (myMovie.available()) {
        background(map);
        myMovie.read();
        image(myMovie, 200, 400, 300, 300);
        image(map, width/2, height/2);
      }
      while (myPort.available () > 0) {
        instring = myPort.readString();
      }
      println(instring);
      int sensorAct = Integer.parseInt(instring, 10);
      if (sensorAct == 1) {
        println("active");
        myMovie.play();
      } else {
        background(map);
        myAnimation();
        myMovie.pause();
      };
    }
    
    void myAnimation() {
      {
        if (pulse > 199) {
          bigsmall = 0;
          println("pulse: " + pulse + " bigsmall " + bigsmall);
        } else if (pulse < 101) {
          bigsmall = 1;
          println("pulse: " + pulse + " bigsmall " + bigsmall);
        }
    
        if (bigsmall == 1) {
          pulse += 2;
        } else if (bigsmall == 0) {
          pulse -= 2;
        }
        fill(255, 0, 0, 200);
        ellipse(200, 400, pulse, pulse);
        ellipse(650, 450, pulse, pulse);
        ellipse(725, 225, pulse, pulse);
      }
    }
    
  • edited December 2014

    mono = loadFont("BlueMono-48.vlw"); myMovie = new Movie(this, "movie.mov"); myMovie.loop(); myMovie.stop();

  • edited December 2014

    I don't know

    delay (50); .... not delay (4); better ?

    here... you need to check: when sensor is ON, is its value > 500 then??

    point is here, you only want to send zero via Serial.print("0"); when both sensors are OFF, not when only one is off and the other is on.....

      if (sensorWert1 > 500 )
      {
        Serial.print("1");
      }
        else if (sensorWert2 > 500 )
      {
        Serial.print("2");
      }
      else
      {
        Serial.print("0");
      }
    
  • edited December 2014

    in the processing sketch:

    And do I just have to change the processing sketch with another number getting from the sensor or is there more to change?

    i depends... so you want to play 2 different movies...?

    line 44 if instead of while?

    line 49 and on

     if (sensorAct == 1) {
        println("active  #1 ");
        myMovie.play();   // 1
      } 
     else  if (sensorAct == 2) {
        println("active  #2 ");
        myMovie2.play();  // 2 
     else { 
        background(map);    // none
        myAnimation();
        myMovie.pause();
        myMovie2.pause();     // off 
      }
    
  • The arduino sketch isn't working. Strangely when nothing is active it is giving me a 1 and when I activate the sensor1 it is giving me a 2. When I'm activating sensor2 it is still giving me a 1. I really don't know how to write this for 2 or 3 sensors...

  • edited December 2014

    did you test it, does the sensor

    • when it's OFF deliver < 500

    • when it's ON give you > 500

    or not...? Or the other way round? Vice versa?

    maybe this:

    if (sensorWert1 < 500 )
    {
      Serial.print("1");
    }
      else if (sensorWert2 < 500 )
    {
      Serial.print("2");
    }
    else
    {
      Serial.print("0");
    }
    
  • Yeah this is working out, thank you! It's also working with 3 sensors. But I got a few problems with the processing sketch. I don't know how to implement three different movies and then put it in the right place. When I only changed the part you recommended only the movement of the circles stopped when the second sensor was active...

  • So I tweaked it a little bit and it's working! Thank you, thank you, thank you!

  • That's great news!

    Happy Christmas if I may say so!

    ;-)

  • It might be a nice gesture to post both working sketches here for others. ;-)

  • Here's the working code. And thanks again for taking the time and helping me out!

    import processing.serial.*;
    import processing.video.*;
    Movie myMovie;
    Movie myMovie2;
    Movie myMovie3;
    Serial myPort; // The serial port:
    String instring  = "";
    int pulse = 100;
    int bigsmall = 1;
    PImage map;
    PFont mono;
    
    void setup() {
      myPort = new Serial(this, Serial.list()[2], 9600);
      myPort.bufferUntil('\n');
      size(1024, 768);
      frameRate(30);
      imageMode(CENTER);
      ellipseMode(CENTER);
      noStroke();
    
      map = loadImage("map.png");
      PGraphics pg = createGraphics(map.width, map.height);
      pg.beginDraw();
      pg.background(255);
      pg.noStroke();
      pg.fill(0);
      pg.ellipse(200, 400, 275, 275);
      pg.ellipse(600, 500, 275, 275);
      pg.ellipse(800, 200, 275, 275);
      pg.filter(BLUR, 7);
      pg.endDraw();
      map.mask(pg);
    
      mono = loadFont("BlueMono-48.vlw");
      myMovie = new Movie(this, "movie.mov");
      myMovie.loop();
      myMovie.stop();
      myMovie2 = new Movie(this, "movie2.mov");
      myMovie2.loop();
      myMovie2.stop();
      myMovie3 = new Movie(this, "movie3.mov");
      myMovie3.loop();
      myMovie3.stop();
    }
    
    void draw() {
      if (myMovie.available()) {
        background(map);
        myMovie.read();
        image(myMovie, 200, 400, 300, 300);
        image(map, width/2, height/2);
      }
      if (myMovie2.available()) {
        background(map);
        myMovie2.read();
        image(myMovie2, 600, 500, 300, 300);
        image(map, width/2, height/2);
      }
      if (myMovie3.available()) {
        background(map);
        myMovie3.read();
        image(myMovie3, 800, 200, 300, 300);
        image(map, width/2, height/2);
      }
      while (myPort.available () > 0) {
        instring = myPort.readString();
      }
      println(instring);
      int sensorAct = Integer.parseInt(instring, 10);
      if (sensorAct == 1) {
        println("active  #1 ");
        myMovie.play();
      } else  if (sensorAct == 2) {
        println("active  #2 ");
        myMovie2.play();
      } else  if (sensorAct == 3) {
        println("active  #3 ");
        myMovie3.play();
      } else {
        background(map);
        myAnimation();
        myMovie.pause();
        myMovie2.pause();
        myMovie3.pause();
      };
    }
    
    void myAnimation() {
      {
        if (pulse > 199) {
          bigsmall = 0;
          println("pulse: " + pulse + " bigsmall " + bigsmall);
        } else if (pulse < 101) {
          bigsmall = 1;
          println("pulse: " + pulse + " bigsmall " + bigsmall);
        }
    
        if (bigsmall == 1) {
          pulse += 2;
        } else if (bigsmall == 0) {
          pulse -= 2;
        }
        fill(255, 0, 0, 200);
        ellipse(200, 400, pulse, pulse);
        ellipse(600, 500, pulse, pulse);
        ellipse(800, 200, pulse, pulse);
      }
    }
    
  • could you post the arduino code as well? thanks!

Sign In or Register to comment.