2013-10-19 21 views
0

我目前正在使用termios作爲串行通信手段來處理g ++編譯程序和Arduino ATMega2560之間的串行通信。 g ++程序發送一個由Arduino解析的5個uint8_t值的數組。 Arduino然後使用這些字節打開條上的特定LED。使用gcc和termios將uint8_t數組傳遞給Arduino

下面是使用g ++編譯的C++程序代碼:

#include <stdlib.h> 
    #include <stdio.h> 
    #include <string.h> 
    #include <unistd.h> 
    #include <termios.h> 
    #include <inttypes.h> 
    #include <fcntl.h> 
    #include <fstream> 
    #include <iostream> 

    #define BAUD B115200 
    #define ARDUINO "/dev/ttyACM0" 

    using namespace std; 

    struct termios old_io, new_io; 
    int arduinoFD, c, res; 

    int main (int argc, char* argv[]) { 

    arduinoFD = open(ARDUINO, O_RDWR | O_NOCTTY); 
    if (arduinoFD < 0){perror(ARDUINO); exit(EXIT_FAILURE);} 

    new_io.c_cflag = BAUD | CRTSCTS | CS8 | CLOCAL | CREAD; 
    new_io.c_iflag = IGNPAR | ICRNL; 
    new_io.c_oflag = 0; 
    new_io.c_lflag = ICANON; 
    cfsetospeed(&new_io, BAUD); 
    cfsetispeed(&new_io, BAUD); 
    tcflush(arduinoFD, TCOFLUSH); 

     //Byte that tells the arduino to start parsing. 
    uint8_t* STARTCMD = (uint8_t*)malloc(1); 
    STARTCMD[0]=0x0A; 
    write(arduinoFD, STARTCMD, 1); 

     //Enable debugging. 
    STARTCMD[0]=(uint8_t)'d'; 
    write(arduinoFD, STARTCMD, 1); 

     while(true){ 
      //Allocate array for LED info. 
      uint8_t* testWrite = (uint8_t*)malloc(5); 
      for(uint8_t i = 0; i < 240; i++){ 
      //Loop through all LEDs, setting their (R,G,B) to (220,220,220). 
      testWrite[0] = 0x73; // 's' 
    testWrite[1] = 0xc8; // Red - 220 
    testWrite[2] = 0xc8; // Green - 220 
    testWrite[3] = 0xc8; // Blue - 220 
    testWrite[4] = (uint8_t)i; // Led Address - i 

      //Print out the values to stdout. 
    char* outPrint = (char*)malloc(17); 
    sprintf(outPrint, "R%03dG%03dB%03dL%03d\n", 
     testWrite[1], testWrite[2], testWrite[3], testWrite[4]); 
    fwrite(outPrint,17,1,stdout); 

      //Send the values from the buffer to the arduino, then sleep for 24 milliseconds. 
    write(arduinoFD, testWrite, 4); 
    usleep(24*1000); 
     } 
      //Deallocate the buffer and reallocate a space to send the update value. 
     free(testWrite); 
     testWrite = (uint8_t*)malloc(1); 
     testWrite[0] = (uint8_t)'z'; 
     write(arduinoFD, testWrite, 1); 

      //Deallocate and sleep for 550ms. 
     free(testWrite); 
     usleep(550*1000);  
     } 
    } 

這裏是Arduino的草圖: 的#include

Adafruit_NeoPixel strip = Adafruit_NeoPixel(240, 6, NEO_GRB + NEO_KHZ800); 

    int pinRangeStart = 0; 
    int pinRangeStop = 0; 
    char inByte; 
    uint8_t* colorBytes; 
    boolean debug = false; 

    void setup(){ 
     Serial.begin(115200); 
     while(!Serial); 

     Serial.print("Desktop LED Ambience\n"); 

     strip.begin(); 
     strip.show(); 
    } 

    void loop(){ 
     while(Serial.available() > 0){ 
     while(Serial.read() != 0x0A); 
     Serial.print("Start Byte read!"); 

     while(true){ 
      //inByte is the first of 5 bytes to be read. The other four are (R,G,B,L) where 
     //R = Red 
     //G = Green 
     //B = Blue 
     //L = LED Number. 
      inByte = Serial.read(); 
      switch(inByte){ 
      case('r'): { 
       for(int i = 0 ; i < strip.numPixels(); i++) 
       strip.setPixelColor(i, strip.Color(0,0,0)); 
       strip.show(); 
       Serial.println("Reset!"); 
       Serial.flush(); 
       break; 
      } 
      case('d'): { 
       Serial.print("Debugging "); 
       debug =! debug; 
       if(!debug) 
       Serial.println("DISABLED"); 
       else 
       Serial.println("ENABLED"); 
       break; 
      } 
      case('s'): { 
       colorBytes = new uint8_t[4]; 
       colorBytes[0] = Serial.read(); // Red 
       colorBytes[1] = Serial.read(); // Green 
       colorBytes[2] = Serial.read(); // Blue 
       colorBytes[3] = Serial.read(); // LED Number 
       if(debug){ 
       Serial.println("Set lights without updating."); 
       Serial.print("R="); 
       Serial.println(colorBytes[0]); 
       Serial.print("G="); 
       Serial.println(colorBytes[1]); 
       Serial.print("B="); 
       Serial.println(colorBytes[2]); 
       Serial.print("LED="); 
       Serial.println(colorBytes[3]); 
       } 
       uint32_t newColor = strip.Color(colorBytes[0], colorBytes[1], colorBytes[2]); 
       strip.setPixelColor(colorBytes[3], newColor); 
       break; 
      } 
      case('z'): { 
       strip.show(); 
       Serial.println("Updating Lights"); 
       break; 
      } 
      } 
     } 
     } 
    } 

的克++程序的輸出可以顯示爲一組字節,按{}分組在一起,表示對write()的單獨調用。

{0x0a} 
    {0x64} 
    {0x73 0xc8 0xc8 0xc8 0x00} 
    {0x73 0xc8 0xc8 0xc8 0x01} 
    {...} 
    {0x73 0xc8 0xc8 0xc8 0xee} 
    {0x73 0xc8 0xc8 0xc8 0xef} 
    {0x7a} 

Arduino的拾取頭兩個字節就好並正確解釋每組5的第一個字節被髮送作爲0x73(也被稱爲「S」),但該組中的下列字節不是正確讀取和風能利用Arduino的解釋爲255

預期輸出的價值觀是:

Desktop LED Ambience 
    Start Byte read! 
    Debugging ENABLED 
    Set lights without updating. 
    R=200 
    G=200 
    B=200 
    LED=0 
    Set lights without updating. 
    R=200 
    G=200 
    B=200 
    LED=1 
    ... 
    Set lights without updating. 
    R=200 
    G=200 
    B=200 
    LED=238 
    Set lights without updating. 
    R=200 
    G=200 
    B=200 
    LED=239 
    Updating Lights 

這是實際的輸出:

Desktop LED Ambience 
    Start Byte read! 
    Debugging ENABLED 
    Set lights without updating. 
    R=255 
    G=255 
    B=255 
    LED=255 
    Set lights without updating. 
    R=255 
    G=255 
    B=255 
    LED=255 
    ... 
    Set lights without updating. 
    R=255 
    G=255 
    B=255 
    LED=255 
    Set lights without updating. 
    R=255 
    G=255 
    B=255 
    LED=255 
    Updating Lights 

會有人碰巧知道在我的代碼中造成這種情況嗎?起初我以爲公共汽車已經飽和,所以我試着把我的波特率降到19600,但它沒有解決任何問題。

編輯:另一個問題是,經過四到五次迭代設置LED後,綠色通道會隨機丟失,所以Arduino所得到的是一個更加錯誤的{'s',255,0,255,255}。

回答

1

您的內循環while(true)不會評估Serial.available。因此即使沒有數據可用,它也會嘗試讀取。這是當它得到255而不是預期的值。有很多方法可以解決這個問題。一種方法是阻止數據可用。

... 
while (true) { 
    while (!Serial.available()) {} 
... 
+0

您的回答給了我我需要的建議。看起來Arduino對於C++程序的閱讀速度太快了,所以Arduino正在接受0xff而不是等待實際輸入。 從那裏,我改變: 'colorBytes [0] = Serial.read()//紅色 colorBytes [1] = Serial.read()//綠色 colorBytes [2] = Serial.read()/ /藍 colorBytes [3] = Serial.read()// LED address' 到 '爲(INT I = 0; I <4;我++){ 而(Serial.available!); colorBytes [i] = Serial.read(); }' 這給我正在讀取的字節。 – MSalmo