首页 文章

Arduino - 阅读串行数据

提问于
浏览
0

我正在尝试使用串行数据向Arduino Mega 2560发送信息,以便控制LED Pixel Strips和传统的圣诞灯串 . 我也在使用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

    当您执行 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等 .

  • 0

    为了解决这个问题,我买了一个Arduino Uno来运行与LED灯相分离的标准(非LED)灯,这些灯从Arduino MEGA 2560上运行 . 非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软件中运行第二个控制器 . 我有两个12伏,50像素的WS2811型LED灯条 . Arduino使用FastLED库,可以从FastLED.io免费下载 . 我发现在LED条带的串行流中有一个字节的垃圾数据,我不得不移过那个字节的数据,以便LED接收正确的数据字节来控制它们的颜色,位置我使用此代码运行我的LED关闭Arduino MEGA 2560;

    #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!
    
        }
    }
    

相关问题