我目前正在使用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}。
您的回答給了我我需要的建議。看起來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