首页 文章

从处理到Arduino获得3个值

提问于
浏览
0

我在Processing中有一个颜色跟踪程序,它与Kinect一起使用 . 当我单击图片中的某个位置时,它会保存此颜色并在其周围绘制一个椭圆 . 我只想在myPort.write()上将3个int值(一个用于红色,绿色和蓝色)发送到Arduino,并将这三个值保存在Arduino中的2个变量中 . 我的目标是在红色变量最高的情况下点亮红色LED,如果绿色最高则点亮绿色LED,依此类推 .

我已经尝试了几个我用谷歌搜索发现的例子,但没有任何作用 . 我不知道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:是的,除了点亮LED之外,我还希望从压电蜂鸣器发出声音,但效果非常好,所以对此没有任何疑问 .

请帮忙!!

1 回答

  • 0

    与arduino的串行通信一次只能使用一个字节 . 幸运的是,Processing Color的三个组件也是三个字节 .

    • 一个红色(0-255)

    • 一个用于绿色(0-255)

    • 一个用于蓝色(0-255)

    现在我们所需要的只是更多信息,所以我们可以将它们分开 .

    因为字节的最小值和最大值是0-255,所以我们没有可用于跟踪三个不同字节的安全字符,因此我们需要一种方法来确定我们发送的信息的开始和结束位置 .

    一种简单的方法是为您的消息设置页眉和页脚;就像是 :

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

    如果我们要读取和解密这样格式化的消息,我们将需要一个缓冲区来存储我们从Processing接收的值,因此我们可以读回它们,看看我们是否可以匹配消息格式 .

    所以,在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">);
    

相关问题