Motion detection send to arduino

Hi you all! Im an art student from berlin and for my latest project I need to send Data I get from Processing to Arduino. I use a serial port to communicate and I basically want to find the x Position of an person in Front of the camera and want to send this position to arduino. I think in the Code the Position of a perso is lerpX so this is what I try to send to arduino. The problem I have now is that im not shure if it really is the Position and if it is how I map it to a range from 0 to 90 which is the range i need for a servo motor for the arduino. And now some data is send to arduino but im not shure if it is the x Position. I would really appreciate your help!! Thank ou so much!

import processing.video.*; 
import processing.serial.*; 
 
Capture video;
Serial myPort; 
 
PImage pprev;
PImage prev;
PImage comprasion; //This will be the result of combining pprev with prev
 
float threshold = 60;
 
float motionX = 0 ;
float motionY = 0;
 
float lerpX = 0 ;
float lerpY = 0;
float sen = 0;

 

void setup() 
{
  size(640, 480);
  myPort = new Serial(this, "COM9", 9600);
  //String[] cameras = Capture.list();
  //printArray(cameras);
  video = new Capture(this, width, height, 30);
  video.start();
  pprev = createImage(640, 480, RGB);
  prev = createImage(640, 480, RGB);
  comprasion = createImage(640, 480, RGB);
  // Start off tracking for red
}
 
void captureEvent(Capture video) 
{ 
  pprev.copy(prev, 0, 0, prev.width, prev.height, 0, 0, prev.width, prev.height); 
  pprev.updatePixels();
 
  prev.copy(video, 0, 0, video.width, video.height, 0, 0, prev.width, prev.height);
  prev.updatePixels();
 
  video.read();
}
 
void draw() 
{  
  video.loadPixels();
  pprev.loadPixels();
  prev.loadPixels();
  comprasion.loadPixels();
 
  image(video, 0, 0);
 
  //threshold = map(mouseX, 0, width, 0, 100);
  threshold = 60;
  int count = 0;
  float avgX = 0;
  float avgY = 0;
 
  loadPixels();
 
  for (int x = 0; x < video.width; x++ ) 
  {
    for (int y = 0; y < video.height; y++ ) 
    {
      int loc = x + y * video.width;
 
      //comprasion = GetFrame(pprev, prev);
 
      color currentColor = video.pixels[loc];
      float r1 = red(currentColor);
      float g1 = green(currentColor);
      float b1 = blue(currentColor);
 
      color prevColor = prev.pixels[loc];
      float r2 = red(prevColor);
      float g2 = green(prevColor);
      float b2 = blue(prevColor);
 
      float d = distSq(r1, g1, b1, r2, g2, b2); 
 
      if (d > threshold*threshold) {
        //stroke(255);
        //strokeWeight(1);
        //point(x, y);
        avgX += x;
        avgY += y;
        count++;
        //myPort.write('1');
        //pixels[loc] = color(0);
      } else {
        //pixels[loc] = color(255);
      }
    }
  }
  updatePixels();
 
  //We decide to detect motion or not
  if (count > 4000) 
  { 
    //myPort.write('1');
    motionX = avgX / count;
    motionY = avgY / count;
    // Draw a circle at the tracked pixel
 
    lerpX = lerp(lerpX, motionX, 0.2); 
    lerpY = lerp(lerpY, motionY, 0.2); 
 
    fill(255, 50, 50);
    strokeWeight(2.0);
    stroke(0);
    ellipse(lerpX, lerpY, 36, 36);
    //Hier ist x Position, dieser Wert muss Motor drehen
    print(lerpX);
  } else
  {
    //myPort.write('0');
  }
  //image(video, 0, 0);y
  //image(prev, 100, 0, 100, 100);
 
  //println(mouseX, threshold);
}
 
float distSq(float x1, float y1, float z1, float x2, float y2, float z2) 
{
  float d = (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) +(z2-z1)*(z2-z1);
  return d;
}
 
PImage GetFrame (PImage a, PImage b) //This fuction should return an average frame of two previous frames.
{
  PImage c = createImage(640, 480, RGB);
 
  a.loadPixels();
  b.loadPixels();
  c.loadPixels();
 
  for (int x = 0; x < video.width; x++ ) 
  {
    for (int y = 0; y < video.height; y++ ) 
    {
      int loc = x + y * video.width;
 
      c.pixels[loc] = a.pixels[loc]*(99/100) + b.pixels[loc]*(1/100); //This should fill c image with correct pixels.
    }
  }
  updatePixels();
  return c;
  
}
void mousePressed() {
  // create random number
  int number = (int) lerpX;
  // debug
  println("now sending number: "+number);
  // send number
  myPort.write(Integer.toString(number));
  // write any charcter that marks the end of a number
  myPort.write('e');
   
  
}
 
// this part is executed, when serial-data is received
void serialEvent(Serial p) {
  try {
    // get message till line break (ASCII > 13)
    String message = p.readStringUntil(13);
    // just if there is data
    if (message != null) {
      println("message received: "+trim(message));
    }
  }
  catch (Exception e) {
  }
}
1 Like

Hi @kanktonk,

You don’t say what code you have in the Arduino. From your write lines in your Processing sketch I guess it’s from one of the very simple examples. I think things will work better for you if you start with Processing’s Arduino Servo example.

Install the Arduino library for Processing: Sketch, Import Library, Add Library. Where it says ‘Filter’ type ‘Arduino’. See the Arduino Firmata library and install it. Stop all Processing windows, restart Processing. Now the library has given you some more examples. File, Examples, Contributed Libraries, Arduino(firmata), arduino_servo. Read it through! Adjust the com port name. (Save in your own directory) In the Arduino IDE find the firmata in the examples and load that into the Arduino.(Firmata is just a slave program giving Procssing easy connection with the Arduino I.O.) When you see this example working you’ll realise what lines to copy into your Processing sketch.

Ask again if anything there takes more than a few minutes.

1 Like