Trigger the video player when processing read a defined number

Hello everybody. I am very new to processing and i would like any help possible to make a project working. What i want to do is make processing read the serial port of an Arduino Uno that sends data from a sonar sensor. When someone approaches the sonar in (let’s say 100cm), i want processing to read that data and trigger a video file in my computer. After googling and trying to figure this out, i have the Arduino with the sonar running. I have made the processing to communicate with the Arduino serial port and print the data to the console and i also have a sketch which plays a specific video in my computer. What i need help with is to make the processing trigger the video player when the data from the Arduino is 100cm. Thanks in advance for any help provided!

Arduino Scetch

#include <NewPing.h>

#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.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.


void setup() {
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
  delay(500);  // Wait 500ms between pings (about 2 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
  Serial.print("Ping: ");
  Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance and print result (0 = outside set distance range, no ping echo)
  Serial.println("cm");
}

Processing sketch for communication with Arduino

import processing.serial.*;
Serial myPort;  // Create object from Serial class
String val;     // Data received from the serial port

void setup()
{
  // I know that the first port in the serial list on my mac
  // is Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  String COM1 = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, COM1, 115200);
}


void draw()
{
  if ( myPort.available() > 0)
  {  // If data is available,
  val = myPort.readStringUntil('\n');         // read it and store it in val
  } 
println(val); //print it out in the console
}

Processing Sketch for video player

import processing.video.*;

String PATH = "D:\\nikos\\NIKOS\\VIDEOS\\Inside.Man.2006.1080p.BluRay.x264.anoXmous_.mp4";
Movie mov;

void setup() {
  size(1920, 816);
  frameRate(23.98);
  mov = new Movie(this, PATH);
  mov.play();
  mov.speed(1);
  mov.volume(30);
}
void movieEvent(Movie m) {
  m.read();
}
void draw() {
  image(mov, 0, 0, width, height);
}
1 Like

Maybe ? :

import processing.serial.*;
import processing.video.*;
Serial myPort;  // Create object from Serial class
String val;     // Data received from the serial port
String PATH = "D:\\nikos\\NIKOS\\VIDEOS\\Inside.Man.2006.1080p.BluRay.x264.anoXmous_.mp4";
Movie mov;

void setup() {
  size(1920, 816);
  frameRate(23.98);
  mov = new Movie(this, PATH);
  mov.speed(1);
  mov.volume(30);

  String COM1 = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, COM1, 115200);
}

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

void draw() {
  if ( myPort.available() > 0) {  // If data is available,
    val = myPort.readStringUntil('\n');         // read it and store it in val
  } 
  
  if (val <= 100){ //If the sensor detect object at less 100cm
    mov.play();
  }else{
    mov.pause();
  }

  image(mov, 0, 0, width, height);
}

First thank you so much for your reply!
In Line 28

I get the following error “the operator <= is undefined for the argument type(s) String, int”

From what i am understanding from googling, i think that it can’t compare an integer (100) to a string. But i have no idea how to fix this.

Maybe try -

int val = 1000; // big enough not to trigger!

and

if (myPort.available() > 0) {
  try { 
    val = Integer.parseInt(myPort.readStringUntil('\n'));
  } catch (Exception ex) {
    // decide what to do if input wasn't a number.
  }
}

You also probably want a boolean flag for playing so you only call mov.play() if it isn’t already playing.

@neilcsmith I inserted your script, and added println(val) to see what values gets from the port. It prints only 0. When i run it, it starts playing the video in any case. Even if it is above or over 100 cm. It is listening to the port, because the program doesn’t run when i unplug the arduino from the pc. So, now it runs, but it plays the video always, no matter what.

import processing.serial.*;
import processing.video.*;
Serial myPort;  // Create object from Serial class
int val;     // Data received from the serial port
String PATH = "D:\\nikos\\NIKOS\\VIDEOS\\Inside.Man.2006.1080p.BluRay.x264.anoXmous_.mp4";
Movie mov;

void setup() {
  size(1920, 816);
  frameRate(23.98);
  mov = new Movie(this, PATH);
  mov.speed(1);
  mov.volume(30);

  String COM1 = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, COM1, 115200);

  
}

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

void draw() {
  if ( myPort.available() > 0) {  // If data is available,
         try { 
            val = Integer.parseInt(myPort.readStringUntil('\n'));
         } catch (Exception ex) {
                   // decide what to do if input wasn't a number.
         }
         println(val);
  } 
  
  if (val <= 100) { //If the sensor detect object at less 100cm
    mov.play();
  }else{
    mov.pause();
  }

  image(mov, 0, 0, width, height);
}

Note two things I put in comments. Firstly, make sure to initialize the val to a number bigger than your threshold (100). Secondly, decide what to do if the string you read isn’t a valid number - eg. print out the exception (this is the reason that I suggested Integer.parseInt() over the built-in parseInt(). Although the other thing you could do is print what you receive -

String s = myPort.readStringUntil('\n');
println(s);
val = Integer.parseInt(s);

EDIT - by the way, just noticed your Arduino sketch isn’t just sending numbers! You need to remove the Ping and cm if you want this to work (or parse them out of the string on the receiving end).

@neilcsmith, @GoToLoop I am trying to figure out what you proposed since yesterday. Thank you both for your help! I extremely appreciate it! I am trying to insert to the code what you said but i still have errors. In the case of neilcsmith, i managed to make it run but it only works when i put val = (Any Number Bellow 100). If, for exapmple i put val = 1000 it won’t run. Which is what i want, but the val should be equal to whatever number comes out of Arduino. I tried this Arduino Sketch

#include <NewPing.h>

#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.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.


void setup() {
  Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}

void loop() {
  delay(500);  // Wait 500ms between pings (about 2 pings/sec). 29ms should be the shortest delay between pings.
  unsigned int uS = sonar.ping(); // Send ping, get ping time in microseconds (uS).
 
  Serial.print(uS / US_ROUNDTRIP_CM); // Convert ping time to distance and print result (0 = outside set distance range, no ping echo)
  
}

in order to put out ping and cm (is that right?), but i can’t still figure out the rest of what you said in the processing code. In GoToLoop’s case, the script you showed me runs just fine when it’s alone. And the processing console prints whatever is in the Arduino serial port. But, again, i am having trouble to insert it in the rest of the processing code without messing something up. I don’t know coding, so i am trying to understand now how all these work. Can you explain me how can i insert the serial communication script, in a way that this

void draw() {
  if ( myPort.available() > 0) {  // If data is available,
    val = myPort.readStringUntil('\n');         // read it and store it in val
  } 
  
  if (val <= 100){ //If the sensor detect object at less 100cm
    mov.play();
  }else{
    mov.pause();
  }

  image(mov, 0, 0, width, height);
}

understands that it should use the value from the Arduino Serial port?

1 Like

You’ll need to use Serial.println(…) in the Arduino script I think - you’re reading until newline (\n) so if you don’t send a newline it won’t work.

In that example, the received value is still a String datatype:

In order to convert it to int or float, use their corresponding conversion function:

  1. int() / Reference / Processing.org
  2. float() / Reference / Processing.org
1 Like

In short, use println() in place of print() there. :innocent:

@GoToLoop @neilcsmith and josephh Guys, with your help and the help from a friend of mine, it’s done! He helped me to make it work! Thank you very much for your time and your precious help! All that is left, is to make the player window go full screen, instead of the exact movie dimensions, but i think i can manage to work this out! I also have to say that i am thrilled with these stuff and i really want to dig into them! Thank you again for your precious help and your answers! Here’s the final version of the script that did it for anyone that might need something similar! Thank you again so much!

import processing.serial.*;
import processing.video.*;
Serial myPort;  // Create object from Serial class
int val = 99;     // Data received from the serial port
String PATH = "D:\\nikos\\NIKOS\\VIDEOS\\Inside.Man.2006.1080p.BluRay.x264.anoXmous_.mp4";
Movie mov;
String inData = "";
int THRESHOLD = 100;
boolean playing = false;

void setup() {
  size(1920, 816);
  frameRate(23.98);
  mov = new Movie(this, PATH);
  mov.speed(1);
  mov.volume(30);
  mov.pause();

  String COM1 = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
  myPort = new Serial(this, COM1, 9600);
  
}

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

void draw() {
  if ( myPort.available() > 0) {  // If data is available,
         try { 
            inData = myPort.readStringUntil('\n');
            if ( inData == null ) {
               throw new Exception("Error reading: "+inData);
            }
            else
              inData = inData.trim();
            val = Integer.parseInt(inData);
            if (val <= THRESHOLD) { //If the sensor detect object at less 100cm
              if (!playing) {
                mov.jump(0);
                mov.loop();
                playing = true;
              }
            }else{
              if (playing) {
                mov.pause();
                playing = false;
              }
            }
       } catch (Exception ex) {
         println("Exception:"+ex.toString()+" Data:"+inData);
       }
       println(">"+inData+" -> "+val+"<");
  } 
  

  image(mov, 0, 0, width, height);
}
3 Likes

Thxs for sharing your solution.

Please edit your post and format your code. You can do this either two ways:

  • Enclose your code block with three back ticks
  • Select the code and hit the </> button which will do exactly that.

Kf

2 Likes

Done! Thank you very much!