Some errors in this code. Requesting help.

Overall goal:

Use processing to control two servos for eye movement via a webcam.

I borrowed the code from somewhere on this forum but I am having issues naturally.

Arduino code:

#include <Servo.h>

Servo neck;
Servo neck2;

int xPos=0;
int yPos = 0;

void setup()  {
  Serial.begin(9600);
  neck.attach(9);
  neck.attach(10);
}

void loop()  {
  if(Serial.available() >0)  {
    xPos=Serial.read();
    yPos=Serial.read();
  }
  int xServo = map(xPos, 0, 320, 20, 70);
  int yServo = map(yPos, 0, 240, 20, 70);
  neck.write(xServo);
  neck2.write(yServo);
}

Processing Code:

import processing.serial.*;

// Learning Processing
// Daniel Shiffman
// http://www.learningprocessing.com

// Example 16-11: Simple color tracking

import processing.video.*;

// Variable for capture device
Capture video;
Serial arduino;

// A variable for the color we are searching for.
color trackColor;
boolean clicked;

void setup() {
  size(400,400);
  String portName = Serial.list()[0];
  arduino = new Serial(this, portName, 9600);
  video = new Capture(this,width,height,15);
  // Start off tracking for red
  trackColor = color(0,0,255);
  smooth();
}

void draw() {
  // Capture and display the video
  if (video.available()) {
    video.read();
  }
  video.loadPixels();
  image(video,0,0);

  // Before we begin searching, the "world record" for closest color is set to a high number that is easy for the first pixel to beat.
  float worldRecord = 500;

  // XY coordinate of closest color
  int closestX = 0;
  int closestY = 0;

  // Begin loop to walk through every pixel
  for (int x = 0; x < video.width; x ++ ) {
    for (int y = 0; y < video.height; y ++ ) {
      int loc = x + y*video.width;
      // What is current color
      color currentColor = video.pixels[loc];
      float r1 = red(currentColor);
      float g1 = green(currentColor);
      float b1 = blue(currentColor);
      float r2 = red(trackColor);
      float g2 = green(trackColor);
      float b2 = blue(trackColor);

      // Using euclidean distance to compare colors
      float d = dist(r1,g1,b1,r2,g2,b2); // We are using the dist( ) function to compare the current color with the color we are tracking.

      // If current color is more similar to tracked color than
      // closest color, save current location and current difference
      if (d < worldRecord) {
        worldRecord = d;
        closestX = x;
        closestY = y;
      }
    }
  }

  // We only consider the color found if its color distance is less than 10.
  // This threshold of 10 is arbitrary and you can adjust this number depending on how accurate you require the tracking to be.
  if (worldRecord < 10) {
    fill(trackColor);
    strokeWeight(4.0);
    stroke(0);
    ellipse(closestX,closestY,10,10);
    arduino.write(closestX);
    arduino.write(closestY);
    println(closestX);
println(closestY);

  }
 
}

void mousePressed() {

  // Save color where the mouse is clicked in trackColor variable
  int loc = mouseX + mouseY*video.width;
  trackColor = video.pixels[loc];
}

My error is:

ArrayIndexOutOfBoundsException: 0

void setup() {
  size(400,400);
  [glow=yellow,2,300]String portName = Serial.list()[0];
  arduino = new Serial(this, portName, 9600);[/glow]
  video = new Capture(this,width,height,15);
  // Start off tracking for red
  trackColor = color(0,0,255);
  smooth();
}

steinklatre:
My error is:

ArrayIndexOutOfBoundsException: 0

It seems unlikely that this message comes from the Arduino, but please don't leave us guessing. Where does this message appear, and when?

  if(Serial.available() >0)  {
    xPos=Serial.read();
    yPos=Serial.read();
  }

If there is at least one byte available to read, read both of them. You can probably tell that this is not a good idea.

  int xServo = map(xPos, 0, 320, 20, 70);
  int yServo = map(yPos, 0, 240, 20, 70);

The largest value that xPos and yPos can contain is 255. It doesn't make sense for the map from range to extend beyond 255.

My error is:

ArrayIndexOutOfBoundsException: 0

Is there something that is hard to understand about this?

Serial.list()

returns a list of COM ports that the Arduino MIGHT be connected to. That list might be empty.

  String portName = Serial.list()[0];

You assume, incorrectly, it appears, that it is not. Accessing the 0th element of an empty list will generate an exception.

    arduino.write(closestX);
    arduino.write(closestY);

You'll need to determine whether Processing's Serial.write() method behaves like Arduino's Serial.write() method or like Arduino's Serial.print() method. If it behaves like the write() method, you'll need to determine how many bytes it writes, and make the Arduino read that number of bytes, and reconstruct the int, however that needs to be done.

If it behaves like the print() method, you'llneedtodetermineawayfortheArduinototellwhenonevalueendsandtehnextbegins.

Paul and Peter,

Sorry let me clarify. My error is coming from processing.

Paul,

Holy crap man this is chinese! I took one class in Java and got by in the skin of my teeth!

Maybe I am going about this the wrong way but I figured it would be pretty easy to get the video camera to track a blob or face and send the outputs to the x and y servos (the eyes in my prop).

Lance :fearful:

Now you need to locate the source of the exception in your processing code. At first glance there don't seemto be a lot of arrays so you could just check them all for possible out-of-bounds access. Or using the Processing language's exception processing capabilities to locate where that exception was thrown from. (I don't know what capabilities it has, or whether it has any at all, but a language that allows exceptions to be thrown should allow them to be caught. If that's not practical for some reason then you can simply add debug statements around each array access to tell you which access was being performed when the exception was thrown. That could also be used to tell you what the array index was that caused the exception.

Doing face tracking on a PC and using an Arduino do move two servos under the control of the PC seems like a reasonable solution to me. None of it seems especially hard, but you'll still need to debug your code because it's unlikely to be perfect at the first attempt.

I agree it looks like that error message means Processing can't find your Arduino's usb serial port. I use that same standard Processing construct in several Processing sketches here without a problem.

May I raise a different issue? It looks to me like neck2 isn't getting attached in setup(), but rather that neck is being attached twice. Am I confused or misreading?

void setup()  {
  Serial.begin(9600);
  neck.attach(9);
  neck.attach(10);
}

-br

It looks to me like neck2 isn't getting attached in setup(), but rather that neck is being attached twice.

That's exactly why I hate numbering one variable and not the other. Attaching neck1 twice would clearly be seen as a mistake.

OK so I have spent 6 hours sitting here trying to get this thing to work... I have gotten the above code to work....kinda. It jitters and sort of tracks a color but even the shadow from the light throws it off.

I need to start from scratch but don't know how!

Ultimate goal is to get my animatronic eye setup to track "a blob" or change in scenery so as to have my Halloween prop look at and follow the children.

I know its fairly straight forward but like most tutorials they expect you to understand how all aspects work.

So will anyone guide me in this matter?

So far I have set up:

Two servos controlling the eyes:

Servo for X movement - pin 8

Servo for Y movement - pin 9

COM Port 3

USB Camera

Processing is installed and working.

OpenCV I don't think is working correct.

Thats where my knowledge ends and I am frustrated! :disappointed_relieved: