Connect PIR sensor to launch a webcam and a sound

edited February 2018 in Arduino

Hi again,

I am trying to connect Arduino with Processing using a PIR Sensor. The code in Arduino is alright, however I can not synchronize both to detect the movement and open the webcam and the sound. Please, Can you help me?.

Arduino:

//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 30;       

//the time when the sensor outputs a low impulse
long unsigned int lowIn;        

//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 5000; 

boolean lockLow = true;
boolean takeLowTime; 

int pirPin = 3;    //the digital pin connected to the PIR sensor's output
int ledPin = 13;


/////////////////////////////
//SETUP
void setup(){
Serial.begin(9600);
pinMode(pirPin, INPUT);
pinMode(ledPin, OUTPUT);
digitalWrite(pirPin, LOW);

//give the sensor some time to calibrate
Serial.print("calibrating sensor ");
for(int i = 0; i < calibrationTime; i++){
  Serial.print(".");
  delay(1000);
  }
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
}

 ////////////////////////////
 //LOOP
 void loop(){

 if(digitalRead(pirPin) == HIGH){
   digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state
   if(lockLow){ 
     //makes sure we wait for a transition to LOW before any further output is made:
     lockLow = false;           
     Serial.println("---");
     Serial.print("motion detected at ");
     Serial.print(millis()/1000);
     Serial.println(" sec");
     delay(50);
     }        
     takeLowTime = true;
    }

   if(digitalRead(pirPin) == LOW){      
   digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state

   if(takeLowTime){
    lowIn = millis();          //save the time of the transition from high to LOW
    takeLowTime = false;       //make sure this is only done at the start of a LOW phase
    }
   //if the sensor is low for more than the given pause,
   //we assume that no more motion is going to happen
   if(!lockLow && millis() - lowIn > pause){ 
       //makes sure this block of code is only executed again after
       //a new motion sequence has been detected
       lockLow = true;                       
       Serial.print("motion ended at ");      //output
       Serial.print((millis() - pause)/1000);
       Serial.println(" sec");
       delay(50);
       }
     }
     }

Processing:

import processing.serial.*;
import processing.video.*;
import ddf.minim.*;
import ddf.minim.AudioPlayer;

// Size of each cell in the grid
int cellSize = 20;
// Number of columns and rows in our system
int cols, rows;
// Variable for capture device
Capture inputCam01;
Movie topLayer;
Minim minim;
AudioPlayer song;
Serial myPort;

void setup() 
{
size(1280, 720);
frameRate(30);
cols = width / cellSize;
rows = height / cellSize;
colorMode(RGB, 255, 255, 255, 100);

// This the default video input, see the GettingStartedCapture 
// example if it creates an error
inputCam01 = new Capture(this, width, height);

// Start capturing the images from the camera
inputCam01.start();  
background(0);

// we pass this to Minim so that it can load files from the data directory
minim = new Minim(this);

// loadFile will look in all the same places as loadImage does.
// this means you can find files that are in the data folder and the 
// sketch folder. you can also pass an absolute path, or a URL.
song = minim.loadFile("data/untitled.wav");
song.play();
song.loop();
}
{
// 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 portName = Serial.list()[0]; //change the 0 to a 1 or 2 etc. to match your port
 myPort = new Serial(this, portName, 9600);
}
void movieEvent(Movie topLayer)  
{  
topLayer.read();
}


void draw() 
{ 
if (inputCam01.available()) {
inputCam01.read();
inputCam01.loadPixels();
image(inputCam01, 0, 0);

// Begin loop for columns
for (int i = 0; i < cols; i++) {
  // Begin loop for rows
  for (int j = 0; j < rows; j++) {
    // Where are we, pixel-wise?
    int x = i*cellSize;
    int y = j*cellSize;
    int loc = (inputCam01.width - x - 1) + y*inputCam01.width; // Reversing x to mirror       the image

    float r = red(inputCam01.pixels[loc]);
    // Make a new color with an alpha component
    color c = color(r, 50, 50, 75);

    // Code for drawing a single rect
    // Using translate in order for rotation to work properly
    pushMatrix();
    translate(x+cellSize/2, y+cellSize/2);
    // Rotation formula based on brightness
    rotate((2 * PI * brightness(c) / 255.0));
    rectMode(CENTER);
    fill(c);
    noStroke();
    // Rects are larger than the cell for some overlap
    rect(0, 0, cellSize+6, cellSize+6);
    popMatrix();
}
}
}
}

Answers

  • The following error appears: error opening serial port/dev/tty.Bluetooth-Incoming-Port: Port busy

  • Port issue solved. Now What should I do to add this code in draw?:

    if(pir){ song.play(); video.start();}

  • Please use Ctrl + t in the Processing IDE to auto-magically format your code. Code that is not indented properly is a pain to read, and often causes issues. For example, in the above chunk of code, it looks like your setup() function ends too early and you have a block of code just sitting at the global scope!

    If you have managed to resolve an issue, REPOST YOUR CODE. Are we supposed to work on a resolved issue? No way!

  • edited February 2018
        import processing.serial.*;
    import processing.video.*;
    import ddf.minim.*;
    import ddf.minim.AudioPlayer;
    import cc.arduino.*;
    
    // Size of each cell in the grid
    int cellSize = 20;
    // Number of columns and rows in our system
    int cols, rows;
    // Variable for capture device
    Capture inputCam01;
    Movie topLayer;
    Minim minim;
    AudioPlayer song;
    Serial myPort;
    Arduino arduino;
    int ledPin = 13;
    
    
    void setup() 
    
    {
    size(1280, 720);
    frameRate(30);
    cols = width / cellSize;
    rows = height / cellSize;
    colorMode(RGB, 255, 255, 255, 100);
    
    // This the default video input, see the GettingStartedCapture 
    // example if it creates an error
    inputCam01 = new Capture(this, width, height);
    
    // Start capturing the images from the camera
    inputCam01.start();  
    background(0);
    
    // we pass this to Minim so that it can load files from the data directory
    minim = new Minim(this);
    
    // loadFile will look in all the same places as loadImage does.
    // this means you can find files that are in the data folder and the 
    // sketch folder. you can also pass an absolute path, or a URL.
    song = minim.loadFile("data/untitled.wav");
    song.play();
    song.loop();
    }
    {
    // 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 portName = Serial.list()[3]; //change the 0 to a 1 or 2 etc. to match your port
     myPort = new Serial(this, portName, 9600);
    }
    void movieEvent(Movie topLayer)  
    {  
    topLayer.read();
    }
    
    {
    //println(Arduino.list());
    arduino = new Arduino(this, Arduino.list()[2], 57600);
    arduino.pinMode(ledPin, Arduino.OUTPUT);
    }
    void draw() 
    
    {
    arduino.digitalWrite(ledPin, Arduino.HIGH);
    delay(1000);
    arduino.digitalWrite(ledPin, Arduino.LOW);
    delay(1000);
    }
    { 
    if (inputCam01.available()) {
        inputCam01.read();
        inputCam01.loadPixels();
        image(inputCam01, 0, 0);
    
        // Begin loop for columns
        for (int i = 0; i < cols; i++) {
        // Begin loop for rows
        for (int j = 0; j < rows; j++) {
        // Where are we, pixel-wise?
        int x = i*cellSize;
        int y = j*cellSize;
        int loc = (inputCam01.width - x - 1) + y*inputCam01.width; // Reversing x to mirror       the image
    
        float r = red(inputCam01.pixels[loc]);
        // Make a new color with an alpha component
        color c = color(r, 50, 50, 75);
    
        // Code for drawing a single rect
        // Using translate in order for rotation to work properly
        pushMatrix();
        translate(x+cellSize/2, y+cellSize/2);
        // Rotation formula based on brightness
        rotate((2 * PI * brightness(c) / 255.0));
        rectMode(CENTER);
        fill(c);
        noStroke();
        // Rects are larger than the cell for some overlap
        rect(0, 0, cellSize+6, cellSize+6);
        popMatrix();
        }
        }
    }
    }
    
  • Is that right?.

  • No. If you had pressed Ctrl + t like I suggested, you would see why. Look:

    import processing.serial.*;
    import processing.video.*;
    import ddf.minim.*;
    import ddf.minim.AudioPlayer;
    import cc.arduino.*;
    
    // Size of each cell in the grid
    int cellSize = 20;
    // Number of columns and rows in our system
    int cols, rows;
    // Variable for capture device
    Capture inputCam01;
    Movie topLayer;
    Minim minim;
    AudioPlayer song;
    Serial myPort;
    Arduino arduino;
    int ledPin = 13;
    
    
    void setup() {
      size(1280, 720);
      frameRate(30);
      cols = width / cellSize;
      rows = height / cellSize;
      colorMode(RGB, 255, 255, 255, 100);
    
      // This the default video input, see the GettingStartedCapture 
      // example if it creates an error
      inputCam01 = new Capture(this, width, height);
    
      // Start capturing the images from the camera
      inputCam01.start();  
      background(0);
    
      // we pass this to Minim so that it can load files from the data directory
      minim = new Minim(this);
    
      // loadFile will look in all the same places as loadImage does.
      // this means you can find files that are in the data folder and the 
      // sketch folder. you can also pass an absolute path, or a URL.
      song = minim.loadFile("data/untitled.wav");
      song.play();
      song.loop();
    }
    
    
    //// THIS CODE IS NOT IN ANY FUNCTION! THIS CAN'T BE RIGHT.
    {
      // 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 portName = Serial.list()[3]; //change the 0 to a 1 or 2 etc. to match your port
      myPort = new Serial(this, portName, 9600);
    }
    //// ---- TO HERE
    
    
    void movieEvent(Movie topLayer)  
    {  
      topLayer.read();
    }
    
    
    //// THIS CODE IS NOT IN ANY FUNCTION! THIS CAN'T BE RIGHT.
    {
      //println(Arduino.list());
      arduino = new Arduino(this, Arduino.list()[2], 57600);
      arduino.pinMode(ledPin, Arduino.OUTPUT);
    }
    //// ---- TO HERE
    
    void draw() {
      arduino.digitalWrite(ledPin, Arduino.HIGH);
      delay(1000);
      arduino.digitalWrite(ledPin, Arduino.LOW);
      delay(1000);
    } // End of draw()!
    
    
    //// THIS CODE IS NOT IN ANY FUNCTION! THIS CAN'T BE RIGHT.
    { 
      if (inputCam01.available()) {
        inputCam01.read();
        inputCam01.loadPixels();
        image(inputCam01, 0, 0);
    
        // Begin loop for columns
        for (int i = 0; i < cols; i++) {
          // Begin loop for rows
          for (int j = 0; j < rows; j++) {
            // Where are we, pixel-wise?
            int x = i*cellSize;
            int y = j*cellSize;
            int loc = (inputCam01.width - x - 1) + y*inputCam01.width; // Reversing x to mirror       the image
    
            float r = red(inputCam01.pixels[loc]);
            // Make a new color with an alpha component
            color c = color(r, 50, 50, 75);
    
            // Code for drawing a single rect
            // Using translate in order for rotation to work properly
            pushMatrix();
            translate(x+cellSize/2, y+cellSize/2);
            // Rotation formula based on brightness
            rotate((2 * PI * brightness(c) / 255.0));
            rectMode(CENTER);
            fill(c);
            noStroke();
            // Rects are larger than the cell for some overlap
            rect(0, 0, cellSize+6, cellSize+6);
            popMatrix();
          }
        }
      }
    }
    //// ---- TO HERE
    
  • Basically, what you just posted is the same as this:

    import processing.serial.*;
    import processing.video.*;
    import ddf.minim.*;
    import ddf.minim.AudioPlayer;
    import cc.arduino.*;
    
    // Size of each cell in the grid
    int cellSize = 20;
    // Number of columns and rows in our system
    int cols, rows;
    // Variable for capture device
    Capture inputCam01;
    Movie topLayer;
    Minim minim;
    AudioPlayer song;
    Serial myPort;
    Arduino arduino;
    int ledPin = 13;
    
    
    void setup() {
      size(1280, 720);
      frameRate(30);
      cols = width / cellSize;
      rows = height / cellSize;
      colorMode(RGB, 255, 255, 255, 100);
    
      // This the default video input, see the GettingStartedCapture 
      // example if it creates an error
      inputCam01 = new Capture(this, width, height);
    
      // Start capturing the images from the camera
      inputCam01.start();  
      background(0);
    
      // we pass this to Minim so that it can load files from the data directory
      minim = new Minim(this);
    
      // loadFile will look in all the same places as loadImage does.
      // this means you can find files that are in the data folder and the 
      // sketch folder. you can also pass an absolute path, or a URL.
      song = minim.loadFile("data/untitled.wav");
      song.play();
      song.loop();
    }
    
    void movieEvent(Movie topLayer)  
    {  
      topLayer.read();
    }
    
    void draw() {
      arduino.digitalWrite(ledPin, Arduino.HIGH);
      delay(1000);
      arduino.digitalWrite(ledPin, Arduino.LOW);
      delay(1000);
    }
    

    Notice how LARGE SECTION of your code have just GONE MISSING? That's because that code is NOT inside ANY function and thus NEVER GETS CALLED.

  • I think is missed the if(pir or what){ song.play(); video.start();}

  • How Can I synchronize it with Arduino?, Is not via port 9600?.

  • edited February 2018 Answer ✓

    I decided to have a look at your code logically (so far the issue has been a structural one - you have large sections of code that aren't inside functions, which is clearly wrong).

    Anyway, actually looking at the code, one thing jumps out at me right away:

    void draw(){
      // ...
      delay(1000);
      // ...
    }
    

    OH DEAR. This is probably not good. You are using delay(). You probably do not want to be using delay(). It does not do what you think it does. It is a terrible function and likely the cause of many of your issues.

    What does delay() do? It BLOCKS EVERYTHING ELSE IN THE SKETCH FROM DOING ANYTHING for some amount of time. In this case, 1 second. It's not a nice way to wait. It's not a good way to make two events happen some time apart. It is the absolutely wrongest function for this.

    Worse, you have it inside draw(). The draw() function is supposed to be re-rendering your sketch's graphics - and normally it calls draw() about 60 times every second. So these two delay() calls in draw() mean that your sketch is only rendering a single frame of animation every 2 seconds! This is probably not what you want!


    Let's forget about the code you have. Let's just talk about your project. What are you trying to do? What is the sketch? You keep talking about wanting to synchronize sound and video to some sort of sensor, but that's not telling us what the sketch should do!

    In simple terms, list the steps of things that the sketch does in order. An example might be:

    • The sketch doesn't display anything initially (just a black screen), but it does find and actives some sensor.
    • The sensor looks for something to sense.
    • When the sensor finds the thing it is looking for, a video starts playing.
    • The sensor doesn't bother to do anything while the video is playing.
    • When the video is done, the sensor starts looking for the thing to sense again.

    Once we have a plain English description of what your goal is, we might be able to help you better.

  • edited February 2018

    And How Can I do it?. There is a certain thing, I have the code in Arduine and the sensor runs perfectly.

  • What code should I put in Processing to synchronize a PIR sensor to open the webcam with an effect and an audio track?.

    Look at the examples of arduino.

    should be something like

    arduino.digitalRead(....

    connect this with if....

  • Thanks for the help, but, Where should I put these lines of code?. Patience, please.

  • in draw()

    Did you read the first 3 tutorials? Did you play with the examples?

    Maybe this is too hard for you yet since you make basic mistakes

  • edited February 2018

    I think if I get a logic solution for this problem I can fix it, I understand setup and draw and I do not think that it is a difficult problem to deal. I just need a little help to understand how to connect Arduino to Processing and a few lines of code. Just that.

    I think Chrisir you can do it perfectly, and that is what I am searching for, the help of an expert.

  • edited February 2018

    I can do it if you show me the correct way to do.

  • ??

    Look at the reference for arduino

    There is code for checking switches or pins of the arduino Did you look at the reference for digitalRead?

  • Answer ✓

    Look, I don’t know the lines, I never connected my arduino to processing I think

  • Answer ✓

    If you post the links to the arduino reference I can look it up maybe

  • I only have one issue, How should I fix the port COM6 that appear in the code for my own port from Arduino?.

  • Can you list the ports?

    Try 4

  • edited February 2018

    myPort = new Serial(this, "COM6", 9600); and my port is [2] connected with the Arduino, What happens?.

  • edited February 2018

    In 3 appears the screen in black, no image and no sound. Here is the new code:

    import processing.video.*;
    import ddf.minim.*;
    import ddf.minim.AudioPlayer;
    import processing.serial.*;
    
    // Size of each cell in the grid
    int cellSize = 20;
    // Number of columns and rows in our system
    int cols, rows;
    int pirval =0;
    // Variable for capture device
    Capture inputCam01;
    Movie topLayer;
    Minim minim;
    AudioPlayer song;
    Serial myPort;  // Create object from Serial class
    String val;     // Data received from the serial port
    void setup() 
    {
    

    size(1280, 720); frameRate(30); cols = width / cellSize; rows = height / cellSize; colorMode(RGB, 255, 255, 255, 100);

    // This the default video input, see the GettingStartedCapture // example if it creates an error inputCam01 = new Capture(this, width, height);

    // Start capturing the images from the camera inputCam01.start();
    background(0);

    // we pass this to Minim so that it can load files from the data directory minim = new Minim(this);

    // loadFile will look in all the same places as loadImage does. // this means you can find files that are in the data folder and the // sketch folder. you can also pass an absolute path, or a URL. song = minim.loadFile("untitled.wav");

    myPort = new Serial(this, Serial.list()[3], 9600);  // change to your com port number
    }
    
    void movieEvent(Movie topLayer)  
    {  
    topLayer.read();
    }
    
    
    void draw() 
    { 
    
    
    if ( pirval == 1)
    {
    playCamera();
    }
    
    
    if ( pirval == 0)
    {
    song.pause();
    }
    
    thread( "checkSerial");
     }
    
    void playCamera()
    {
    if (inputCam01.available()) {
    song.play();
    
    inputCam01.read();
    inputCam01.loadPixels();
    image(inputCam01, 0, 0);
    
    // Begin loop for columns
    for (int i = 0; i < cols; i++) {
      // Begin loop for rows
      for (int j = 0; j < rows; j++) {
        // Where are we, pixel-wise?
        int x = i*cellSize;
        int y = j*cellSize;
        int loc = (inputCam01.width - x - 1) + y*inputCam01.width; // Reversing x to                                           mirror the image
    
        float r = red(inputCam01.pixels[loc]);
        // Make a new color with an alpha component
        color c = color(r, 50, 50, 75);
    
        // Code for drawing a single rect
        // Using translate in order for rotation to work properly
        pushMatrix();
        translate(x+cellSize/2, y+cellSize/2);
        // Rotation formula based on brightness
        rotate((2 * PI * brightness(c) / 255.0));
        rectMode(CENTER);
        fill(c);
        noStroke();
        // Rects are larger than the cell for some overlap
        rect(0, 0, cellSize+6, cellSize+6);
        popMatrix();
       }
       }
      }
    }
    void checkSerial()
    {
    

    if ( myPort.available() > 0) { // If data is available, val = myPort.readString(); // read it and store it in val if ( trim(val).equals("A") ) { pirval =1; } else { pirval =0; } //print it out in the console println(pirval); } }

  • Answer ✓

    put 2 here?? instead of 3

    myPort = new Serial(this, Serial.list()[3], 9600);  // change to your com port number }  

  • edited February 2018

    Do you know how to put in black each time the PIR sensor is triggered?. And the code to loop the audio to infinite via Minim?.

  • depending what you mean by black: background(0);

    loop audio: song.loop();

  • song loop(); does not work.

  • Look at the reference

    It’s either song.loop(); and then play

    or song.loop(); instead of song.play

  • Solved!, Thanks Chrisir!.

  • you‘re welcome!

Sign In or Register to comment.