0

我正在开发一个家庭自动化系统,其中一部分包括一个通过 USB 连接到RaspberryPi 3 Model B的Arduino Mega2560。Arduino 通过串行从 Pi 接收两个简短的简单命令;第一个命令设置 LED 灯的“区域”,第二个命令在前面描述的区域上设置颜色。两个命令的语法如下,其中括号中的项目是单字节,len+off 是 3 个 ascii 字节,解释为 base-10,r+g+b 是 2 个 ascii 字节,每个字节都解释为十六进制。color set 命令支持可变数量的区域,如下所示:

区域设置命令

!c[regionId][stripId][len2][len1][len0][off2][off1][off0]\r

颜色设置命令

!b[r1][r0][g1][g0][b1][b0][numRegions][regionId0]([regionId1]...)\r

每个命令都会发送肯定/否定确认,因此您会认为我能够知道出了什么问题,但是当我尝试使用第二个命令设置浅色时,我得到了意外的行为,尽管按预期得到了确认。 到目前为止,我能得出的唯一合理的结论是,对于全局数组,区域会丢弃更改并始终保持为零。 比如这个交换导致没有灯亮(实际交换中没有评论)

Pi sends: !c00144000\r  // create regionId 0 on stripId 0; length 144 offset 0
Pi recieves: O          // positive confirmation?
Pi sends: !b00009910\r  // set regionId 0 to color 0x000099 (blue)
Pi recieves: O          // positive confirmation, but no lights?
Pi sends: !x\r          // invalid command; triggers default in switch
Pi recieves: X          // as expected, all lights turn red

这是 Arduino 的精简源代码:

#include "Arduino.h"
#include "FastLED.h"
#define WAIT while(!Serial.available()) ;; 

// Forward Declarations
const int max_strips = 2;
const int max_strip_length = 300;
const int max_leds = max_strips * max_strip_length;
CRGB leds[max_strips][max_strip_length];

const int max_regions = 20;
int regions[max_regions][3];

const int baud_rate = 9600;
unsigned char buffer[64];
unsigned char currentByte = 0;
unsigned char incommingByte;
unsigned char startChar = '!';
unsigned char endChar = '\r';
bool store = false;

// Helper Functions
void set(CRGB c) {
  for(int i = 0; i < max_strips; i++) {
      for(int j = 0; j < max_strip_length; j++) {
          leds[i][j] = c;
      }
  }
}

void set(int stripId, int length, int offset, CRGB c) {
    for(int i = offset; i < offset+length; i++) {
        leds[stripId][i] = c;
    }
}

void setup() {
  Serial.begin(baud_rate);
  for(int i = 0; i < max_strips; i++) {
      switch(i) {
          case 0: {
              FastLED.addLeds<WS2812B, 2, GRB>(leds[0], max_strip_length);
          } break;
          case 1: {
              FastLED.addLeds<WS2812B, 3, GRB>(leds[1], max_strip_length);
          } break;
      }
  }
  set(CRGB::Black);
}

void loop() {
    if(Serial.available() > 0) {
        unsigned char incomingByte = Serial.read();
        if(incomingByte == startChar) {
            currentByte = 0;
            store = true;
        }
        if(store) {
            if(incomingByte == endChar) {
                buffer[currentByte++] = incomingByte;
                store = false;
                switch(buffer[1]) {
                    case 'b': {
                        int red = (buffer[2] - '0')*16 + (buffer[3] - '0');
                        int green = (buffer[4] - '0')*16 + (buffer[5] - '0');
                        int blue = (buffer[6] - '0')*16 + (buffer[7] - '0');
                        int numRegions = buffer[8] - '0';

                        for(int i = 0; i < numRegions; i++) {
                            int regionId = buffer[9+i] - '0';

                            if(regionId >= max_regions) {
                                Serial.write('S');
                                return;
                            }

                            // Never sets anything
                            set(regions[regionId][0], regions[regionId][1], regions[regionId][2], CRGB(red, green, blue));
                        }

                        Serial.write('O');
                    } break;

                    case 'c': {
                        int regionId = buffer[2] - '0';
                        int stripId = buffer[3] - '0';
                        int length = (buffer[4] - '0')*100 + (buffer[5] - '0')*10 + (buffer[6] -'0');
                        int offset = (buffer[7] - '0')*100 + (buffer[8] - '0')*10 + (buffer[9] -'0');

                        if(regionId >= max_regions) {
                            Serial.write('R');
                            return;
                        }

                        if(stripId >= max_strips) {
                            Serial.write('S');
                            return;
                        }

                        regions[regionId][0] = stripId; // WE LOSE THESE VALUES??
                        regions[regionId][1] = length;  // ??
                        regions[regionId][2] = offset;  // ??

                        Serial.write('O');

                    } break;

                    default: {
                        set(CRGB::Red);
                        Serial.write('X');
                    } break;
                }
                currentByte = 0;
            }else if(currentByte > 64){
                store = false;
                currentByte = 0;
            } else {
                buffer[currentByte++] = incomingByte;
            }
        }
    }
    FastLED.show();
}

对于我在这里缺少的任何建议,我将不胜感激,无论如何,感谢您阅读本文!

4

1 回答 1

0

发生这种情况是因为我正在测试的 Arduino 的串行接口上​​显示了很多垃圾。将波特率降低到 2400bps 可以解决此设备上的问题。系统中的其他 Arduino 以更高的串行速率运行良好——我怀疑这个特定 Arduino 上的晶体存在硬件问题,因此时钟速度在串行连接的两侧之间没有正确匹配。

于 2017-06-23T02:10:14.643 回答