Получите 3 значения от обработки до Arduino

У меня есть программа отслеживания цвета в обработке, которая работает с Kinect. Когда я щелкаю где-нибудь на картинке, он сохраняет этот цвет и рисует вокруг него эллипс. Я просто хочу отправить 3 значения типа int (одно для красного, зеленого и синего) через myPort.write() в Arduino и сохранить эти 3 значения в Arduino в 2 переменных. Моя цель состоит в том, чтобы зажечь красный светодиод, если красная переменная самая высокая, и зеленый светодиод, если зеленый самый высокий, и так далее.

Я пробовал несколько примеров, которые я нашел, когда гуглил, но ничего не работает. Я не знаю, как Arduino должен получить правильные значения в переменных!

РЕДАКТИРОВАТЬ: Здесь у вас есть мой код обработки. Я склеил его из нескольких других уроков, пока чуть не заплакал.

    import processing.serial.*;
Serial myPort;

import SimpleOpenNI.*;

SimpleOpenNI kinect;
// Frame
PImage currentFrame;
color trackColor;

int r1, g1, b1, r2, g2, b2;


void setup()
{
  size(640, 480);

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

  kinect = new SimpleOpenNI(this);
  kinect.enableRGB();

  trackColor = color (255, 0, 0);
  smooth ();

  currentFrame = createImage (640, 480, RGB);
}

void draw()
{
  kinect.update();

  currentFrame = kinect.rgbImage ();
  image(currentFrame, 0, 0);

  currentFrame.loadPixels();

  // 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 < currentFrame.width; x ++ ) {
    for (int y = 0; y < currentFrame.height; y ++ ) {
      int loc = x + y*currentFrame.width;
      // What is current color
      color currentColor = currentFrame.pixels[loc];
      r1 = (int)red(currentColor);
      g1 = (int)green(currentColor);
      b1 = (int)blue(currentColor);
      r2 = (int)red(trackColor);
      g2 = (int)green(trackColor);
      b2 = (int)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) {
    // Draw a circle at the tracked pixel
    fill(trackColor);
    strokeWeight(4.0);
    stroke(0);
    ellipse(closestX, closestY, 30, 30);
  }




  if (mousePressed == true) {
    color c = get(mouseX, mouseY);
    //println("r: " + red(c) + " g: " + green(c) + " b: " + blue(c));

    // Save color where the mouse is clicked in trackColor variable
    int loc = mouseX + mouseY*(currentFrame.width);

    trackColor = currentFrame.pixels[loc];

 println("red " + r2);
 println("green " + g2);
 println("blue " + b2);

 int colors[] = {r2, g2, b2};

 for(int i=0; i < 3; i++) {
   myPort.write(colors[i]); 
 }

} 
 println("ClosestX " + closestX);
  myPort.write(closestX);
}

И мой код Arduino, где я не знаю, как получить несколько значений.

    int val;
int ledPin = 13;
int freq;
int piezoPin = 9;

int redLED = 3;
int greenLED = 5;
int blueLED = 7;

int red, green, blue;

void setup() {
  pinMode(ledPin, OUTPUT); // Set pin as OUTPUT
  Serial.begin(9600); // Start serial communication at 9600 bps

  digitalWrite(ledPin, LOW);
}

void loop() {
  if (Serial.available() > 0)
  { // If data is available to read,
    val = Serial.read(); // read it and store it in val
}

 if(red > green && red > blue) {
 digitalWrite(redLED, HIGH); //light Red LED
 }

  if(green > red && green > blue) {
 digitalWrite(greenLED, HIGH); //light Red LED
 }

 if(blue > red && blue > green) {
 digitalWrite(blueLED, HIGH); //light Red LED
 }


  //Piezo buzzing higher when X-Position of tracked color is higher. 
  if (val < 100) {
    freq = 50;
  }
  else if (val < 200) {
    freq = 200;
  }
  else if (val < 300) {
    freq = 400;
  }
  else if (val < 400) {
    freq = 600;
  }
  else if (val < 500) {
    freq = 800;    
  }
  else (freq = 1000); 

  tone(piezoPin, freq);

}

EDIT2: Да, помимо зажигания светодиодов, я также хочу получить звук от пьезо-зуммера, но это работает довольно хорошо, так что никаких вопросов по этому поводу... пока нет.

Помогите, пожалуйста!!

1 ответ

Последовательная связь с вашим Arduino работает с одним байтом за раз. По счастливой случайности, три компонента Обрабатывающего Цвета также составляют три байта.

  • Один для красных (0-255)
  • Один для зеленых (0-255)
  • Один для синего (0-255)

Теперь все, что нам нужно, это немного больше информации, чтобы мы могли держать их отдельно.

Поскольку минимальные и максимальные значения байта равны 0-255, мы не можем использовать безопасный символ для отслеживания трех разных байтов, поэтому нам нужен способ выяснить, где отправляемая нами информация начинается и заканчивается.

Простой способ сделать это - установить заголовок и нижний колонтитул для ваших сообщений; что-то вроде:

<color>[byte (red)][byte (green)][byte (blue)]</color>

Если мы собираемся читать и расшифровывать сообщения, отформатированные таким образом, нам понадобится небольшой буфер, в котором будут храниться значения, которые мы получаем от обработки, поэтому мы можем прочитать их обратно и посмотреть, можем ли мы соответствовать формату сообщения.

Итак, на стороне Arduino нам нужно это:

String buffer = "";

String messageBegin = "<color>";
String messageEnd = "</color>";


//we read our serial data in the SerialEvent() function
//this is called *after* a loop(), and only if there is serial data in the buffer.
void serialEvent()
{
   while(Serial.available())
   {
       buffer += (char)Serial.read();
   } 
}

void loop() 
{
  //now, inside loop, we no longer need to worry about gathering data from serial.
  //we do still need to figure out if our message is complete, and then parse it.

  //if our buffer contains both the beginning and the end of a message
  //in the right order.
  int beginIndex = buffer.lastIndexOf(messageBegin);
  int endIndex = buffer.lastIndexOf(messageEnd);

  if(beginIndex != -1 && endIndex != -1 && beginIndex < endIndex)
  {
       //we have a complete message!
       //our red color starts 7 characters after where the message begins,
       //because our "messageBegin" is 7 characters long
       string lastMessage = buffer.substring(beginIndex+7);
       //this is arguably not the prettiest way to get our byte values back.
       //see if you can do better for bonus points!
       byte messageAsBytes[80];
       lastMessage.getBytes(messageAsBytes, messageAsBytes.length());

       //we can now finally reconstruct the value we had from processing!
       byte r = (byte)messageAsBytes[0];
       byte g = (byte)messageAsBytes[1];
       byte b = (byte)messageAsBytes[2];

       //if we get a complete message, we can clear our buffer. (don't forget to do this!)
       buffer = "";
  }
}

На стороне обработки все, что нам нужно сделать, это убедиться, что наши messagebegin и messageend отправлены вместе для поездки:

myPort.write("<color">);
 for(int i=0; i < 3; i++) {
   myPort.write(colors[i]); 
 }
myPort.write("</color">);
Другие вопросы по тегам