Arduino-读取串行数据

时间:2018-08-19 21:30:20

标签: serialization arduino pixels led

我正在尝试使用串行数据将信息发送到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()只是读取第一个字节(我认为)。用户如何遍历串行数据的字节并仅选择他们想要的字节?

2 个答案:

答案 0 :(得分:0)

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

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,依此类推。

答案 1 :(得分:0)

为解决此问题,我购买了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库,该库可从FastLED.io免费下载。我发现,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!

    }
}