经过大约一周的桌面敲击后,我能够编写以下代码,它确实有效。问题是它的响应速度不快,大多数时候我不得不向手机上的按钮发送垃圾邮件,一遍又一遍地发送相同的命令,直到它赶上。
你能帮我清理一下代码吗?
正如您将看到的,有时我似乎过于复杂的事情,但这只是因为我发现它以这种方式工作得更好,而不是看起来更“合乎逻辑”的简单版本。我将编写代码,然后我将解释并提出我的问题。
#include <Adafruit_NeoPixel.h> // NeoPixel Lib
#include <SoftSerial.h> // Serial Lib
#define LED_PIN 2
#define LED_COUNT 30
SoftSerial bluetooth(4, 5); // RX TX
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
const byte numChars = 32;
char receivedChars[numChars];
char tempChars[numChars];
boolean newData = false;
boolean goLED0 = false;
boolean goLED1 = true;
boolean goLED2 = false;
boolean goLED3 = false;
boolean goLED4 = false;
int eFx = 1;
int rC1 = 255;
int gC1 = 0;
int bC1 = 0;
int xS = 20;
int xB = 125;
void setup() {
bluetooth.begin (9600);
strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
strip.show(); // Turn OFF all pixels ASAP
}
void loop() {
checkLedData();
delay(50);
runLED();
delay(50);
}
void recvWithStartEndMarkers() {
static boolean recvInProgress = false;
static byte ndx = 0;
char startMarker = '<';
char endMarker = '>';
char rc;
while (bluetooth.available() > 0 && newData == false) {
rc = bluetooth.read();
if (recvInProgress == true) {
if (rc != endMarker) {
receivedChars[ndx] = rc;
ndx++;
if (ndx >= numChars) {
ndx = numChars - 1;
}
} else {
receivedChars[ndx] = '\0'; // terminate the string
recvInProgress = false;
ndx = 0;
newData = true;
}
} else if (rc == startMarker) {
recvInProgress = true;
}
}
}
void parseData() { // split the data into its parts
char * strtokIndx; // this is used by strtok() as an index
strtokIndx = strtok(tempChars, ","); // get the first part - the string
eFx = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // get the first part - the string
rC1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
gC1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ","); // this continues where the previous call left off
bC1 = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
xS = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, ",");
xB = atoi(strtokIndx); // convert this part to an integer
strtokIndx = strtok(NULL, NULL);
}
void checkLedData() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
parseData();
newData = false;
strip.setBrightness(xB);
if (eFx == 0) {
goLED0 = true;
goLED1 = false;
goLED2 = false;
goLED3 = false;
goLED4 = false;
}
if (eFx == 1) {
goLED0 = false;
goLED1 = true;
goLED2 = false;
goLED3 = false;
goLED4 = false;
}
if (eFx == 2) {
goLED0 = false;
goLED1 = false;
goLED2 = true;
goLED3 = false;
goLED4 = false;
}
if (eFx == 3) {
goLED0 = false;
goLED1 = false;
goLED2 = false;
goLED3 = true;
goLED4 = false;
}
if (eFx == 4) {
goLED0 = false;
goLED1 = false;
goLED2 = false;
goLED3 = false;
goLED4 = true;
}}}
void runLED() {
if (goLED0 == true) {
}
if (goLED1 == true) {
colorWipe(strip.Color(rC1, gC1, bC1), xS);
delay(50);
recvWithStartEndMarkers();
}
if (goLED2 == true) {
colorWipe(strip.Color(bC1,rC1,gC1), xS);
colorWipe2(strip.Color(rC1, gC1, bC1), xS);
delay(50);
recvWithStartEndMarkers();
}
if (goLED3 == true) {
colorWipe(strip.Color(rC1, gC1, bC1), xS);
colorWipe2(strip.Color(rC1/2, gC1/2, bC1/2), xS);
colorWipe(strip.Color(rC1/5, gC1/5, bC1/5), xS);
colorWipe2(strip.Color(rC1/10, gC1/10, bC1/10), xS);
delay(50);
recvWithStartEndMarkers();
}
if (goLED4 == true) {
colorWipe(strip.Color(gC1,rC1,bC1), xS);
colorWipe2(strip.Color(bC1,gC1,rC1), xS);
colorWipe(strip.Color(bC1,rC1, gC1), xS);
colorWipe2(strip.Color(rC1, gC1, bC1), xS);
delay(50);
recvWithStartEndMarkers();
}
}
void colorWipe(uint32_t color, int wait) {
for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
delay(wait); // Pause for a moment
}
}
void colorWipe2(uint32_t color, int wait) {
for(int i=29; i<strip.numPixels(); i--) { // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
delay(wait); // Pause for a moment
}
}
所以我正在做的是我从手机发送一个代码,例如: <1,255,255,255,100,100> 它被void recvWithStartEndMarkers()
解析后被拾取,然后所有值都被存储为 INTvoid parseData()
在我得到的循环内部void checkLedData()
调用上面的 2 个函数,并根据第一个 INT 激活或停用这些布尔值,然后我void runLED()
检查哪些布尔值是真的并开始闪烁 LED
起初我让开关被激活INT eFx
但由于某种原因它工作得非常糟糕所以我决定使用这部分代码来翻转布尔值,在 runLED() 你会注意到我不断地调用这个发挥作用recvWithStartEndMarkers();
,因为这是让董事会真正做出回应的唯一方法。
我不确定发生了什么,我相信它是由于缓冲区溢出问题而起作用的,它崩溃了然后它可以接受一个新命令,第一个版本在它接受了 1 个命令之后就卡住了,它的 void colorWipe
工作方式是Leds 会打开和关闭,切换颜色等等,但是当我试图改变效果或颜色时,它根本没有响应。
我在这之前使用的下一个代码:
void loop() {
recvWithStartEndMarkers();
if (newData == true) {
strcpy(tempChars, receivedChars);
// this temporary copy is necessary to protect the original data
// because strtok() used in parseData() replaces the commas with \0
parseData();
strip.setBrightness(xbrithness);
controlLed();
newData = false;
}
}
void controlLed() {
colorWipe(strip.Color(redColor, greenColor, blueColor), xSpeed);
colorWipe(strip.Color( greenColor, redColor, blueColor), xSpeed);
}
现在这是非常敏感的,但问题是它会通过void controlLed()
一次并停止,而如果我在外部调用相同的函数recvWithStartEndMarkers();
,它会进入循环,就像我想要导致我试图产生循环效果一样。
有谁知道我可以做些什么来使其响应但仍然循环功能以制作“灯光秀”?
现在我发布了我在想的所有这些,不确定 arduino 是否是多任务处理我想知道 ATtiny85 是否是多任务处理,所以这可能是问题所在,它正忙于处理代码,以至于它不会在串行上监听进来的内容,有什么办法可以解决吗?