令人沮丧的Arduino问题 - 循环和案例

发布于 2025-02-09 08:57:43 字数 3252 浏览 3 评论 0原文

我正在使用Arduino IDE来编程ESP32,我遇到了一个令人沮丧的问题。我正在使用Neopixel环(Adafruit Clone)。

我使用了Adafruit Neopixel演示片段,它们工作正常。现在我试图将其分开。

我想做的是聆听串行端口,然后根据结果更改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应用更相似的方式进行此项工作 - 我的舒适区域...相对而言。

谢谢

安德鲁

I'm using the Arduino IDE to program an ESP32, I'm having a bit of a frustrating problem. I'm using a neopixel ring (adafruit clone).

I've used the adafruit neopixel demo snippets and they work fine. Now I'm trying to hack it apart.

What I would like to do is listen to the serial port, and then change the pattern of the neopixel ring depending on the result. Please see code below - excuse the mess... i've been busy bodging copy and pasting :)

#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);
    }
   }
}

It does kind of work.... I say kind of because it's not really working that well at all. It is very slow to switch, mainly when it's running the rainbow animation. It also sometimes misses a switch.... I believe this is probably because the animation is looping, there is a delay in there.

I'm not too familiar with arduino... the setup and loop is new to me. What I wanted ideally was an event handler to listen to the serial port, but it appears that I have to poll it continuously? Is this true? Even this serialevent() appears to run every time after the main loop.

If I used micropython instead does this work in a more similar way to programming .net apps in visual studio - my comfort area... well relatively speaking.

Thanks

Andrew

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

软糯酥胸 2025-02-16 08:57:44

遵循我的评论 - 这是您可以采取的措施来改善代码时机的示例。

我正在使用类将每个模式所需的任何变量分组在一起。

您甚至可以从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);
    }
   }
}

Following my comment - here's an example of what you could do to improve the code timing.

I'm using classes to group any variables you need for each pattern together.

You could even derive these from a common class with doLoop() as a virtual function to make the loop() code simpler, but I've tried not to change your original code too much.

The colour sweep is quite quick, so I've left that as a loop - but you could change that to be similar to the rainbow code.

Hopefully this will give you an idea of the sort of thing you need to do when running responsive arduino code.

#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);
    }
   }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文