我正在使用Arduino IDE来编程ESP32,我遇到了一个令人沮丧的问题。我正在使用一个新像素的环(adafruit克隆)。
我已经使用了adafruit neopixel演示片段,它们工作得很好。现在我正试着把它拆开。
我想做的是监听串行端口,然后根据结果改变新像素环的模式。请参阅下面的代码-请原谅混乱…我一直在忙着复制和粘贴:)
#include <Adafruit_NeoPixel.h>
#define LED_PIN 4
#define LED_COUNT 16
String inputString = "";
String controlstring = "";
int ledrange = 0;
bool stringComplete = false;
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
void setup() {
Serial.begin(115200);
strip.begin();
strip.setBrightness(20);
strip.show(); // Initialize all pixels to 'off'
// rainbow();
}
void loop() {
switch (ledrange){
case 0:
Serial.println("firing case 0");
rainbow();
break;
case 1:
Serial.println("firing case 1");
colorWipe(strip.Color( 0, 0, 255), 50); // Blue
break;
}
}
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
}
}
// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow() {
// Hue of first pixel runs 5 complete loops through the color wheel.
// Color wheel has a range of 65536 but it's OK if we roll over, so
// just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
// means we'll make 5*65536/256 = 1280 passes through this loop:
for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
// strip.rainbow() can take a single argument (first pixel hue) or
// optionally a few extras: number of rainbow repetitions (default 1),
// saturation and value (brightness) (both 0-255, similar to the
// ColorHSV() function, default 255), and a true/false flag for whether
// to apply gamma correction to provide 'truer' colors (default true).
strip.rainbow(firstPixelHue);
// Above line is equivalent to:
// strip.rainbow(firstPixelHue, 1, 255, 255, true);
strip.show(); // Update strip with new contents
delay(10); // Pause for a moment
}
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void serialEvent() {
inputString = "";
ledrange = 0;
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == 'n') {
stringComplete = true;
controlstring = inputString;
ledrange = inputString.toInt();
Serial.println(ledrange);
}
}
}
它确实工作....我说"有点"是因为它根本就没那么好用。切换速度很慢,主要是在运行彩虹动画的时候。它有时也会漏掉一个开关....我相信这可能是因为动画在循环,这里有一个延迟。
我不太熟悉arduino…这种设置和循环对我来说是新的。理想情况下,我想要的是一个事件处理程序来监听串行端口,但似乎我必须连续轮询它?这是真的吗?甚至这个serialevent()似乎在每次主循环之后都运行。
如果我使用micropython代替以更类似于在visual studio中编程。net应用程序的方式完成这项工作-我的舒适区…相对来说还不错。
感谢安德鲁
根据我的评论,这里有一个可以改进代码计时的示例。
我正在使用类来将每个模式所需的变量分组在一起。
您甚至可以从doLoop()
作为虚函数的公共类派生这些,以使loop()
代码更简单,但我尽量不改变您的原始代码太多。
颜色扫描是相当快的,所以我把它作为一个循环-但你可以改变它类似于彩虹代码。
希望这将给你一个想法,你需要做的事情时,运行响应式arduino代码。
#include <Adafruit_NeoPixel.h>
#define LED_PIN 4
#define LED_COUNT 16
String inputString = "";
String controlstring = "";
int ledrange = 0;
bool stringComplete = false;
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
class Rainbow {
private:
long firstPixelHue = 0 ;
public:
void doLoop() {
strip.rainbow(firstPixelHue);
strip.show();
firstPixelHue += 256;
if ( firstPixelHue >= 5*65536 ) {
firstPixelHue = 0 ;
}
delay(10);
}
};
class ColorWipe {
private:
uint32_t color ;
int wait ;
public:
ColorWipe(uint32_t color_p, int wait_p) : color(color_p), wait(wait_p) {
}
void doLoop() {
// Clear leds before the sweep.
strip.fill(0);
strip.show();
delay(wait);
// This loop is quite quick, so let it run to completion each time.
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
}
}
};
ColorWipe colorWipePattern(strip.Color(0,0,255), 50);
Rainbow rainbowPattern ;
void setup() {
Serial.begin(115200);
strip.begin();
strip.setBrightness(20);
strip.show(); // Initialize all pixels to 'off'
// rainbow();
}
void loop() {
switch (ledrange){
case 0:
Serial.println("firing case 0");
rainbowPattern.doLoop() ;
break;
case 1:
Serial.println("firing case 1");
colorWipePattern.doLoop() ;
break;
}
}
uint32_t Wheel(byte WheelPos) {
WheelPos = 255 - WheelPos;
if(WheelPos < 85) {
return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
}
if(WheelPos < 170) {
WheelPos -= 85;
return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
}
WheelPos -= 170;
return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}
void serialEvent() {
inputString = "";
ledrange = 0;
while (Serial.available()) {
char inChar = (char)Serial.read();
inputString += inChar;
if (inChar == 'n') {
stringComplete = true;
controlstring = inputString;
ledrange = inputString.toInt();
Serial.println(ledrange);
}
}
}