Lighting up an LED from Processing to Arduino

edited April 2017 in Arduino

My project is a face tracking webcam and I want it to turn on an LED whenever it recognizes a face but can not figure out the if statement to accomplish this. My Processing code is as follows. Any help would be greatly appreciated.

import hypermedia.video.*;  //Include the video library to capture images from the webcam
import java.awt.Rectangle;  //A rectangle class which keeps track of the face coordinates.
import processing.serial.*; //The serial library is needed to communicate with the Arduino.

OpenCV opencv;  //Create an instance of the OpenCV library.

//Screen Size Parameters
int width = 320;
int height = 240;

// contrast/brightness values
int contrast_value    = 0;
int brightness_value  = 0;

Serial port; // The serial port

//Variables for keeping track of the current servo positions.
char servoTiltPosition = 90;
char servoPanPosition = 90;
//The pan/tilt servo ids for the Arduino serial command interface.
char tiltChannel = 0;
char panChannel = 1;

//These variables hold the x and y location for the middle of the detected face.
int midFaceY=0;
int midFaceX=0;

//The variables correspond to the middle of the screen, and will be compared to the midFace values
int midScreenY = (height/2);
int midScreenX = (width/2);
int midScreenWindow = 10;  //This is the acceptable 'error' for the center of the screen. 

//The degree of change that will be applied to the servo each time we update the position.
int stepSize=1;

void setup() {
  //Create a window for the sketch.
  size( width, height );

  opencv = new OpenCV( this );
  opencv.capture( width, height );                   // open video stream
  opencv.cascade( OpenCV.CASCADE_FRONTALFACE_ALT );  // load detection description, here-> front face detection : "haarcascade_frontalface_alt.xml"

  println(Serial.list()); // List COM-ports (Use this to figure out which port the Arduino is connected to)

  //select first com-port from the list (change the number in the [] if your sketch fails to connect to the Arduino)
  port = new Serial(this, Serial.list()[0], 57600);   //Baud rate is set to 57600 to match the Arduino baud rate.

  // print usage
  println( "Drag mouse on X-axis inside this sketch window to change contrast" );
  println( "Drag mouse on Y-axis inside this sketch window to change brightness" );

  //Send the initial pan/tilt angles to the Arduino to set the device up to look straight forward.
  port.write(tiltChannel);    //Send the Tilt Servo ID
  port.write(servoTiltPosition);  //Send the Tilt Position (currently 90 degrees)
  port.write(panChannel);         //Send the Pan Servo ID
  port.write(servoPanPosition);   //Send the Pan Position (currently 90 degrees)
}


public void stop() {
  opencv.stop();
  super.stop();
}



void draw() {
  // grab a new frame
  // and convert to gray
  opencv.read();
  opencv.convert( GRAY );
  opencv.contrast( contrast_value );
  opencv.brightness( brightness_value );

  // proceed detection
  Rectangle[] faces = opencv.detect( 1.2, 2, OpenCV.HAAR_DO_CANNY_PRUNING, 40, 40 );

  // display the image
  image( opencv.image(), 0, 0 );

  // draw face area(s)
  noFill();
  stroke(255,0,0);
  for( int i=0; i<faces.length; i++ ) {
    rect( faces[i].x, faces[i].y, faces[i].width, faces[i].height );
  }

  //Find out if any faces were detected.
  if(faces.length > 0){
    //If a face was found, find the midpoint of the first face in the frame.
    //NOTE: The .x and .y of the face rectangle corresponds to the upper left corner of the rectangle,
    //      so we manipulate these values to find the midpoint of the rectangle.
    midFaceY = faces[0].y + (faces[0].height/2);
    midFaceX = faces[0].x + (faces[0].width/2);

    //Find out if the Y component of the face is below the middle of the screen.
    if(midFaceY < (midScreenY - midScreenWindow)){
      if(servoTiltPosition >= 5)servoTiltPosition += stepSize; //If it is below the middle of the screen, update the tilt position variable to lower the tilt servo.
    }
    //Find out if the Y component of the face is above the middle of the screen.
    else if(midFaceY > (midScreenY + midScreenWindow)){
      if(servoTiltPosition <= 175)servoTiltPosition -=stepSize; //Update the tilt position variable to raise the tilt servo.
    }
    //Find out if the X component of the face is to the left of the middle of the screen.
    if(midFaceX < (midScreenX - midScreenWindow)){
      if(servoPanPosition >= 5)servoPanPosition -= stepSize; //Update the pan position variable to move the servo to the left.
    }
    //Find out if the X component of the face is to the right of the middle of the screen.
    else if(midFaceX > (midScreenX + midScreenWindow)){
      if(servoPanPosition <= 175)servoPanPosition +=stepSize; //Update the pan position variable to move the servo to the right.
    }

  }
  //Update the servo positions by sending the serial command to the Arduino.
  port.write(tiltChannel);      //Send the tilt servo ID
  port.write(servoTiltPosition); //Send the updated tilt position.
  port.write(panChannel);        //Send the Pan servo ID
  port.write(servoPanPosition);  //Send the updated pan position.
  delay(1);
}



/**
 * Changes contrast/brigthness values
 */
void mouseDragged() {
  contrast_value   = (int) map( mouseX, 0, width, -128, 128 );
  brightness_value = (int) map( mouseY, 0, width, -128, 128 );
}

Answers

  • edited April 2017

    This is my Arduino Code:

     #include <Servo.h>  //Used to control the Pan/Tilt Servos
        int GreenLED = 13;
        int RedLED = 12;
        //These are variables that hold the servo IDs.
        char tiltChannel=0, panChannel=1;
    
        //These are the objects for each servo.
        Servo servoTilt, servoPan;
    
        //This is a character that will hold data from the Serial port.
        char serialChar=0;
    
    
        void setup(){
          servoTilt.attach(5);  //The Tilt servo is attached to pin 2.
          servoPan.attach(3);   //The Pan servo is attached to pin 3.
          servoTilt.write(15);  
          servoPan.write(45);    
    
    
          Serial.begin(57600);  //Set up a serial connection for 57600 bps.
        }
    
        void loop(){
          while(Serial.available() <=0);  //Wait for a character on the serial port.
          serialChar = Serial.read();     //Copy the character from the serial port to the variable
          if(serialChar == tiltChannel){  //Check to see if the character is the servo ID for the tilt servo
            while(Serial.available() <=0);  //Wait for the second command byte from the serial port.
            servoTilt.write(Serial.read());  //Set the tilt servo position to the value of the second command byte received on the serial port
          }
          else if(serialChar == panChannel){ //Check to see if the initial serial character was the servo ID for the pan servo.
            while(Serial.available() <= 0);  //Wait for the second command byte from the serial port.
            servoPan.write(Serial.read());   //Set the pan servo position to the value of the second command byte received from the serial port.
          }
        }
    
  • Below I present a concept you could use in your program. Untested btw.

    Kf

    final int myLEDpin = ? ;  //Need to define your output pin where your LED is hooked 
    
    boolean ledFaceON=false;
    boolean prevState=ledFaceON;
    
    void setup(){
    
      .... YOUR setup code here
    
    }
    
    void draw(){
    
       ....HERE code related to laoding image and face detection
    
       ledFaceON =faces.length > 0;  //True if there are any faces, false otherwise
       if(ledFaceON!=prevState){
          update_INO_led();  //Only updates arduino's led if face/noFace status change
       }
       prevState=ledFaceON;
    
    }
    
    
    
    void  update_INO_led(){
       //Next sends 1 if any face detected, 0 
       //It is assume than in the arduino code, 1 will drive the pin HIGH, 
       //  0 will set it to LOW
       port.write(myLEDpin,ledFaceON?1:0);  otherwise
    }
    
  • I am getting an error message that says "the method write(int) in the Serial is not applicable for the arguements (int,int)" It highlights this line of code

    port.write(myLEDpin,ledFaceON?1:0);

    not quite sure how to fix this either.

  • You need to build a second sketch were you interact directly with your arduino. In that sketch you will:

    • Configure your LED as set in the arduino
    • Test the commands you are sending to the arduino

    For the commands, you need to look at the documentation and examples related to your unit. You need to setup your own circuit (if you haven't done so) and assign it a pin. You might need to write your arduino code that fits your design. You might be able to use provided examples with some minor modifications from the arduino site. Notice your arduino code above defines a RED and GREEN pin but it doesn't manipulate them. You need to implement this part. I don't know what experience you have doing this. To make it easier for you, take my suggestion and start from a simpler sketch and some ardunino code, do some testing and take it from there.

    Check previous posts:
    https://forum.processing.org/two/search?Search=LEDs+arduino
    https://forum.processing.org/two/search?Search=ledpin

    Specifically:
    https://forum.processing.org/two/discussion/comment/95152/#Comment_95152
    https://forum.processing.org/two/discussion/comment/92348/#Comment_92348
    https://forum.processing.org/two/discussion/21768/interface-with-mux-controlled-led-rope/p1

    Kf

Sign In or Register to comment.