【问题标题】:Sending color to Arduino through serial using Objective-c使用 Objective-c 通过串行向 Arduino 发送颜色
【发布时间】:2013-10-08 19:19:21
【问题描述】:

我正在尝试通过串行向 Arduino 发送颜色。这是在我的 mac 上运行的 Objective-C 代码,它将颜色发送到 Arduino:

unsigned char rgb[4];
rgb[1] = ...some color
rgb[2] = ...some color
rgb[3] = ...some color
rgb[0]=0xff; //I am setting the first value to 0xff so I know where to start reading the bytes
if(_serialFileDescriptor!=-1) {
    write(_serialFileDescriptor, rgb, 4);
}

在我发送它之后,Arduino 接收它。我首先检查它读取的第一个字节是否为 0xff 以使 Arduino 与计算机同步。如果是,我继续并获得颜色。现在的问题是,显然第一个字节永远不会是 0xff,并且永远不会输入 if 语句。

    void loop(){
         //protocol expects data in format of 4 bytes
         //(xff) as a marker to ensure proper synchronization always
         //followed by red, green, blue bytes
         char buffer[4];
         if (Serial.available()>3) {
          Serial.readBytes(buffer, 4);
          if(buffer[0] == 0xff){ //when I comment out the if statement code works fine but    //the colors which are read are wrong
           red = buffer[1];
           green= buffer[2];
           blue = buffer[3];
          }
         }
         //finally control led brightness through pulse-width modulation
         analogWrite (redPin, red);
         analogWrite (greenPin, green);
         analogWrite (bluePin, blue);
        }

我不明白为什么第一个读取字节是 bever 0xff,即使在 Objective-C 代码中将其设置为这个。

【问题讨论】:

  • 您的代码中rgbrgba 之间似乎有些混淆。
  • 如果第一个字节 not 0xFF 那么你可能应该只读取一个字节而不是 4 个字节(或者记住/移动缓冲区中的剩余字节)。
  • 我的代码有点乱,很抱歉。不过我更正了。如果第一个字节不是 0xff,我实际上打算根本不读取字节。
  • 顺便说一句,在 Arduino 上使用实际的 Objective-C 非常具有挑战性,而且您的代码最多完全是 C++/C。重新标记。

标签: c++ serial-port arduino iokit


【解决方案1】:

我会做的是:

  1. 从计算机,发送一个头字节到 Arduino 以知道 接下来是有用的信息。
  2. 从电脑发送号码 即将到来的数据包数
  3. 在 Arduino 上,循环通过 每次串行读取到buffer[i] 的数据数。

所以代码看起来像这样(可能需要改进):

uint8_t dataHeader = 0xff;
uint8_t numberOfData;
uint8_t rgb[3];
uint8_t redPin, greenPin, bluePin;

void setup(){

    Serial.begin(9600);

    // INITIALIZE YOUR PINS AS YOU NEED
    //
    //


}

void loop(){

    if (Serial.available() > 1) {

        uint8_t recievedByte = Serial.read();

        if (recievedByte  == dataHeader) { // read first byte and check if it is the beginning of the stream

            delay(10);
            numberOfData = Serial.read(); // get the number of data to be received.

            for (int i = 0 ; i < numberOfData ; i++) {
                delay(10);
                rgb[i] = Serial.read();
            }

        }

    }

    analogWrite (redPin, rgb[0]);
    analogWrite (greenPin, rgb[1]);
    analogWrite (bluePin, rgb[2]);

}

希望对你有帮助!

【讨论】:

  • 嗯,数据的长度总是应该是3,所以我认为没有必要发送长度。我尝试使用 serial.readbytes() 和 serial.read() 都没有工作,我也有同样的感觉。但是我有点担心头字节,因为在我的代码中虽然我确实发送了头字节,但是当我添加 IF 语句来检查头字节时,代码永远不会进入 IF 语句。标头字节应该是 int 还是 char?
  • 对于您的严格情况,确实不需要数据的数量。但是,您可能想稍后改进您的代码,添加电机,添加更多不同颜色的 LED。使用此代码,您将能够以更少的重写添加更多案例。至于dataHeaderif 语句,请尝试我的编辑。但是有一个问题:如何从计算机发送这些字节?
  • 在 Arduino 语言中,char 用于存储字符值。 Serial.read() 读取第一个 byte,8 位,因此需要将其存储为 byte 类型。有时,Arduino 数据类型与基本 C/C++ 数据类型不同,因此我更喜欢使用 int8_t 或 uint8_t 等来准确了解我需要多少位以及它是有符号还是无符号。
  • 我实际上认为我应该将数据头更改为不同的东西,因为 0xff 可能是一种颜色。它认为我应该从计算机发送字节的方式正如我在帖子中所示。但是我可能应该将其更改为 rgb[0] = 'header';我不确定是否应该使用带有单个 write() 或多个 write()s 的单个数组发送字节
  • 这里有一个更完整的例子来证明numberOfData 的用处:github.com/WeAreLeka/moti/blob/moti_v2/lib/Moti/Moti_Remote.cpp 我发现了一些错误,稍后我会更正,但你明白了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 2013-06-05
相关资源
最近更新 更多