Play video using Processing, Arduino and PIR Sensor

edited December 2017 in Arduino

Hi. A friend and I are in the middle of a video installation tests. I'm using an Arduino PIR Sensor and an Arduino Uno board.

I need to stop a video when the PIR is "On" (Detects motion) and to play that video if the PIR is "Off".

Checking the Processing and Arduino websites, examples and references I couldn't figured out what I'm doing wrong. Please let me know if something is missing or left. Thanks in advance for any help!

This is the Arduino Code (copied from Arduino and Processing communication tutorials found on the web):

/*
   PIR sensor tester
*/

int ledPin = 13;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;                    // variable for reading the pin status

void setup() {
  pinMode(ledPin, OUTPUT);      // declare LED as output
  pinMode(inputPin, INPUT);     // declare sensor as input

  Serial.begin(9600);
}

void loop() {
  val = digitalRead(inputPin);  // read input value
  if (val == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, HIGH);  // turn LED ON
    if (pirState == LOW) {
      // we have just turned on
      Serial.println("Motion detected!");
      // We only want to print on the output change, not state
      pirState = HIGH;
    }
  } else {
    digitalWrite(ledPin, LOW); // turn LED OFF
    if (pirState == HIGH) {
      // we have just turned of
      Serial.println("Motion ended!");
      // We only want to print on the output change, not state
      pirState = LOW;
    }
  }
}

And here is the Processing code:

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

Serial myPort;
String val;    

Movie video;

void setup() {
  size(640,480);
  video = new Movie(this,"sujeto1.mp4");
  video.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=="Motion detected!") {
    video.stop();
  } else {
    video.loop();
  }
  println(val);

}
void draw() {
  background(0);
  image(video,0,0);

} 

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

Answers

  • Thanks for the answer @GoToLoop ! I visited both references but I still don't get it. With the equals() issue I understood that if you want to compare too strings is necessary to declare them before(?). But, how could I make Processing to read the String "Motion detected!" inside an "if" block? Or to read the value stored in "myString"?

    I'm kinda new in Processing and newer in Arduino so I don't know if this code is closer to the right one.

    /**
     * Efficient Serial Reading (v1.01)
     * GoToLoop (2016-Jan-19)
     *
     * forum.Processing.org/two/discussion/14534/
     * myport-available-always-0#Item_1
     *
     * forum.Processing.org/two/discussion/16618/
     * processing-with-arduino-void-serialevent#Item_5
     */
    import processing.video.*;
    import processing.serial.Serial;
    
    static final int PORT_INDEX = 0, BAUDS = 9600;
    String myString;
    
    Movie video;
    
    void setup() {
      size(640,480);
      video = new Movie(this,"sujeto1.mp4");
      video.loop();
      noLoop();
      final String[] ports = Serial.list();
      printArray(ports);
      new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
    }
    
    void draw() {
      background(0);
      image(video,0,0);
    
      println(myString);
    }
    
    void serialEvent(final Serial s) {
      myString = s.readString().trim();
      redraw = true;
      if (myString.equals("Motion detected!")) {
        video.stop();
      } else {
        video.loop();
    }
    }
    

    Thanks!!!

  • Try this modified code for your Processing's serialEvent(). This is not the solution but you can see how the serial port is behaving (or if you are receiving any data). Notice you were missing a line in your function... the one that was reading the data from the serial stream.

    Kf

    void serialEvent(final Serial s) {
      if (myPort.available() > 0) {
        val=myPort.readStringUntil('\n');      
        println("Received=[ "+val+" ]");
        myString = s.readString().trim();
        redraw = true;
        if (myString.equals("Motion detected!")) {
          video.stop();
        } else {
          video.loop();
        }
      }
    }
    
  • Thanks @kfrajer for your answer. I could not integrate your code very well, but I'm receiving the data pretty well. The operation of the PIR is 10/10 and the communication between the serial port and processing is well too.

    glt

    The thing that I don't know is how to go from the string that is received in Processing to make the video to play from that string. I explain myself well? (English is not my native language as you could notice :D)

  • Hi. Mixing the answers I got to this code:

    /**
     * Efficient Serial Reading (v1.01)
     * GoToLoop (2016-Jan-19)
     *
     * forum.Processing.org/two/discussion/14534/
     * myport-available-always-0#Item_1
     *
     * forum.Processing.org/two/discussion/16618/
     * processing-with-arduino-void-serialevent#Item_5
     */
    import processing.video.*;
    import processing.serial.Serial;
    
    static final int PORT_INDEX = 0, BAUDS = 9600;
    String myString;
    
    Movie video;
    
    void setup() {
      size(640,480);
      video = new Movie(this,"sujeto1.mp4");
      video.loop();
      noLoop();
      final String[] ports = Serial.list();
      printArray(ports);
      new Serial(this, ports[PORT_INDEX], BAUDS).bufferUntil(ENTER);
    }
    
    void draw() {
      background(0);
      image(video,0,0);
    
      println(myString);
    }
    
    void serialEvent(final Serial s) {
      myString = s.readString().trim();
      redraw = true;
      if (myString.equals("Motion detected!")) {
        video.stop();
      } 
    }
    
    void movieEvent(Movie video) {
      video.read();
    }
    

    The thing now is that the video is "playing" in loop but not "showing" in loop. When the PIR is "On" the video stops when the value "Motion detected!" appears (all ok with that) but when the other value appears (Motion ended!") the video doesn't continue in loop but it's still reading as loop, so everytime the value appears it seems like I advanced the video :-?? Could I be missing something in void draw() ? or the void movieEvent() :-?

  • edited December 2017 Answer ✓

    Problem is noLoop()! The original example code didn't need to have draw() called back at 60 FPS.

    However, in order to display each arrived video frame, draw() needs to happen. #-o

    You can move redraw = true; into movieEvent(). *-:)
    Or even delete noLoop() & redraw = true; from the sketch entirely. 8-X

    More about noLoop() & redraw(): :-B

    1. https://Processing.org/reference/noLoop_.html
    2. https://Processing.org/reference/redraw_.html
  • Thank you @GoToLoop and @kfrajer for your comments, knowledge and advices. The code works fine now and I can continue with the other parts of my project.

    :D :D :D :D

Sign In or Register to comment.