【问题标题】:Arduino - Reading Serial DataArduino - 读取串行数据
【发布时间】:2018-08-19 21:30:19
【问题描述】:

我正在尝试使用串行数据向 Arduino Mega 2560 发送信息,以控制 LED 像素条和传统的圣诞灯串。我也在使用 VIXEN 灯光软件。

我可以在 Arduino loop() 函数中使用此代码控制来自 Vixen 的一条 LED 像素;

          Serial.readBytes((char*)leds, NUM_LEDS * 3);//buffer to store things in, length (number of bytes to read)
          FastLED.show();//refresh the pixel LED's

我还可以使用此代码为常规灯控制一个继电器(或多个继电器);

#define CHANNEL_01 7 //Pin #7 on the Arduino Mega board

   void setup()
    {
      // Begin serial communication
      Serial.begin(BAUD_RATE);
      #define CHANNEL_COUNT 1 

    int channels[] = {CHANNEL_01}
    int incomingByte[16];
    // Define baud rate. This figure must match that of your profile configuration in Vixen!
    #define BAUD_RATE 9600 


      // Set up each channel as an output
      for(int i = 0; i < CHANNEL_COUNT; i++)
      {
        pinMode(channels[i], OUTPUT);
      }
    }

void loop()
{
  if (Serial.available() >= CHANNEL_COUNT)
  {
    // Read data from Vixen, store in array
    for (int i = 0; i < CHANNEL_COUNT; i++)
    {
      incomingByte[i] = Serial.read();
    }
    // Write data from array to a pin on Arduino
    for (int i = 0; i < CHANNEL_COUNT; i++)
    {
      digitalWrite(channels[i], incomingByte[i]);
    }
  }
}

问题是我不能同时做这两件事。我可以将 150 字节的 LED 数据分配给 LED 灯条,它工作正常,或者,我可以运行继电器,它们工作正常。我无法弄清楚如何从串行数据中分割字节并将其发送到适当的引脚。例如,也许我想使用引脚 7 控制继电器,使用引脚 6 控制 LED 像素条。

像素 LED 条使用串行数据的前 150 个字节数据。但是我怎样才能得到下一个字节来控制继电器,该继电器打开和关闭传统的圣诞灯串呢?控制灯串的字节将是串行数据中的第 151 个字节。有没有办法指定第 151 个字节? Serial.read() 只不过是读取第一个字节(我认为)。用户如何遍历串行数据的字节并仅选择他们想要的字节?

【问题讨论】:

    标签: serialization arduino pixels led


    【解决方案1】:

    当您执行Serial.readBytes((char*)leds, NUM_LEDS * 3); 时,您会读取前 150 个字节,假设您有 50 个 LED。因此,串行缓冲区中待处理的下一个字节将是第 151 个字节,因此如果您在 Serial.readBytes((char*)leds, NUM_LEDS * 3); 之后调用 Serial.read(),您将获得该字节。 请注意,如果需要,您可以使用一个字节来控制 8 个继电器,每个继电器一位,使用 bitRead() 一个例子。

    bool relayState[8];
    
    Serial.readBytes((char*)leds, NUM_LEDS * 3);
    
    byte relays = Serial.read();
    
    for(byte i=0;i<8;i++){
      relayState[i] = bitRead(relays, i);
    }
    
    for(byte i=0;i<8;i++) {
      digitalWrite(relay[i], relayState[i]);
    }
    

    那么值 1 将打开继电器 0,值 2 将打开继电器 1,值 3 将打开继电器 0 和继电器 1,依此类推。

    【讨论】:

    • 不幸的是,这并没有完全奏效。这就是我尝试过的; if ( Serial.available() >= 0 ) { Serial.readBytes((char*)leds, NUM_LEDS * 3);字节中继 = Serial.read(); } FastLED.show() digitalWrite(PIN_NUMBER, 继电器);灯的输出是错误的。 LED 的闪烁颜色随机,控制常规灯的引脚与 LED 同步间歇闪烁,而不是应有的开/关灯。
    • 尝试在Serial.readBytes((char*)leds, NUM_LEDS * 3); 之后添加延迟,例如delay(10);,以确保字节在调用byte relays = Serial.read();之前到达
    • 感谢您的建议,但即使延迟了,我也得到了相同的结果。我也尝试了不同的延迟长度,1、10、25、50 和 100。LED 闪烁随机颜色,常规灯的继电器与 LED 一起闪烁,当常规灯应该亮起时,单个 LED 亮起。就像我的字节混乱了,或者有额外的字节偏离了模式。
    • 你是在一个流中发送 151 个字节吗?你是先发送 150 个字节,然后是最后一个?
    • 我不确定我是否能够回答这个问题。但是,我可以告诉你,我在 Vixen 中使用了一个控制器,它有 151 个输出(150 个 LED,1 个普通灯)。这是否意味着我有两个“通道”或两个“流”数据?
    【解决方案2】:

    为了解决这个问题,我买了一个 Arduino Uno 来运行标准(非 LED)灯,与运行 Arduino MEGA 2560 的 LED 灯分开运行。非 LED 灯在 Vixen Lights 软件中的一个控制器上运行.控制器有 4 个输出(通道),每个非 LED 灯组一个。每个通道将控制固态继电器上的一条线路。 Arduino Uno 使用此代码运行继电器;

    #define PIN1 7 //Pin number seven
    #define PIN2 6 //Pin number six
    #define PIN3 5 //Pin number five
    #define PIN4 4 //Pin number four
    
    #define BAUD_RATE 9600 //just running 4 relay switches so we don't need much speed
    #define CHANNEL_COUNT 4 //there are 4 channels coming from the Vixen controller
    
    int bt[4]; //a variable we will use in the loop section of code
    int x; //another variable we will use in the loop section of code
    
    void setup() {
        delay(1000); //a little delay to give Uno some time on startup
        Serial.begin(BAUD_RATE); //set the baud rate of the serial stream
        pinMode(PIN1, OUTPUT); //set the four pins on the Arduino Uno to output
        pinMode(PIN2, OUTPUT);
        pinMode(PIN3, OUTPUT);
        pinMode(PIN4, OUTPUT);
    
    }
    
    void loop() {
        if (Serial.available() >= CHANNEL_COUNT) { 
            for (X = 0; x < CHANNEL_COUNT; x++) { //for every channel...
                bt[x] = Serial.read(); //we read a byte from the serial stream buffer and store it in an array for later use
            }
    
            digitalWrite(PIN1, bt[0]);  //we tell the pins on the arduino what to do... 
            digitalWrite(PIN2, bt[1]);  //using the array of integers that holds the byte values from the serial stream...
            digitalWrite(PIN3, bt[2]); 
            digitalWrite(PIN4, bt[3]);
    
        }   
    
    }
    

    LED 由 Vixen Lights 软件中的第二个控制器运行。我有两个 WS2811 类型的 12 伏、50 像素 LED 灯条。 Arduino 使用可以从 FastLED.io 免费下载的 FastLED 库。我发现 LED 灯条的串行流中有一个字节的垃圾数据,我必须越过那个字节的数据,以便 LED 接收正确的数据字节来控制它们的颜色、位置等等。我使用此代码在 Arduino MEGA 2560 上运行我的 LED;

    #include <FastLED.h> //include the FastLED library in the Arduino project
    #define LED_PIN1 7 //I am going to run one strip of 50 LEDs off of pin 7 on the MEGA
    #define LED_PIN2 6 //I am going to run a second strip of 50 LEDs off of pin 6 on the MEGA
    #define BAUD_RATE 115200 
    #define NUM_LEDS 50
    
    //It took me some time to figure out that my two pixel strips are set 
    //to different color codes. Why? I don't know, but they are.  
    #define RGB_ORDER RGB //one of my pixel strips is set to use RGB color codes
    #define BRG_ORDER BRG //the second strip came from the factory with BRG color codes
    
    #define LED_TYPE WS2811 //what type of LEDs are they? Mine are WS2811, yours may be different.
    
    //create an array to hold the FastLED CRBG code for each of the 50 pixels in the 
    //first strip.
    CRGB leds1[NUM_LEDS]; 
    
    //create another array to hold the FastLED CRBG codes for each of the 50 pixels in 
    //the second strip.
    CRGB leds2[NUM_LEDS]; 
    
    int g; //a variable we will use in the loop section
    
    int bufferGarbage[1]; //THIS IS THE KEY TO MAKING THIS WHOLE THING WORK. WE NEED TO 
     //GET PAST THE FIRST MYSTERY BYTE THAT IS SENT TO THE ARDUINO MEGA FROM THE VIXEN 
     //LIGHTS SOFTWARE. So we create a variable we will use in the loop section of code. 
    
    void setup() {
        delay(1000);
        Serial.begin(BAUD_RATE);
        pinMode(LED_PIN1, OUTPUT); //set our pins to output. PIN1 is pin 6 on the Arduino board.
        pinMode(LED_PIN2, OUTPUT); //set our pins to output. PIN2 is pin 7 on the Arduino board.
    
         //This line sets up the first pixel strip to run using FastLED
        FastLED<LED_TYPE, LED_PIN1, RGB_ORDER>(leds1, NUM_LEDS).setCorrection(TypicalLEDStrip); 
    
        //This line sets up the second pixel strip to run using FastLED
        FastLED<LED_TYPE, LED_PIN2, BRG_ORDER>(leds2, NUM_LEDS).setCorrection(TypicalLEDStrip); 
    }
    
    void loop() {
        if (Serial.available() >= 0) { //if there is data in the serial stream
               //bufferGarbage is to capture the first byte of garbage that comes across.
               //Without this the LED's are out of sync. 
               //In my case if I didn't capture this byte the first pixel on my 
               //second LED strip would match the color code that should be on the last 
               //pixel of the first strip. We don't do anything with this byte.
               //but we need to read it from the serial stream so we can move to the 
               //next byte in the stream.
               bufferGarbage[0] = Serial.read();  
    
            //then we need to populate the leds1 array so FastLED can tell the pixels what to do.
            //We have 50 pixels in the strip and each pixel has a CRGB property that uses 
            //a red, green, and blue attribute. So for each LED we need to capture 3
            //bytes from the serial stream. 50 LEDs * 3 bytes each means we need to read
            //150 bytes of data from the serial stream.
            for (g = 0; g < NUM_LEDS; g++) {
                Serial.readBytes( ( char*)(&leds1[g], 3);
            }
            for (g = 0; g < NUM_LEDS; g++) {//then we read the next 150 bytes for the second strip of LEDs
                Serial.readBytes( ( char*)(&leds2[g], 3);
            }
    
            FastLED.show(); //then we tell FastLED to show the pixels!
    
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多