Closed wecoy76 closed 3 years ago
Can you post an example of your code and explain what isn't working? Are you setting the LED length once in the setup() function, or dynamically changing the length in the loop() function?
`
WS2812FX *ws2812fx;
uint16_t LED_COUNT = 30; //Number of leds in the stripe uint8_t m = 43; //mode uint32_t c = 0x7F007F; //color bool auto_cycle = false; //auto cycle uint16_t s = 500; //speed uint8_t b = 15; //brightness
void setup() { Serial.begin(9600); / other setup /
ws2812fx = new WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); ws2812fx->begin(); ws2812fx->setPin(LED_PIN); ws2812fx->updateType(NEO_GRB + NEO_KHZ800); ws2812fx->updateLength(LED_COUNT); ws2812fx->init(); ws2812fx->setBrightness(b); ws2812fx->setSpeed(s); ws2812fx->setColor(c); ws2812fx->setMode(m);
Serial.print(F("Set LED_COUNT to: ")); LED_COUNT = ws2812fx->numPixels(); Serial.print(LED_COUNT); Serial.println(" leds"); ws2812fx->start();
void loop() { ws2812fx->clear(); digitalWrite(LED, LED_STAT ? HIGH : LOW); unsigned long now = millis(); ws2812fx->service();
recvChar(); // read serial comm
if(cmd_complete) { process_command(); }
if(auto_cycle && (now - auto_last_change > 10000)) { // cycle effect mode every 10 seconds uint8_t next_mode = (ws2812fx->getMode() + 1) % (ws2812fx->getModeCount()-8);
ws2812fx->setMode(next_mode);
Serial.print("mode is "); Serial.println(ws2812fx->getModeName(ws2812fx->getMode()));
auto_last_change = now;
} }
void process_command() { if (strcmp(cmd,"b+") == 0) { b = ws2812fx->getBrightness(); if (b>=105) { ws2812fx->increaseBrightness(15); Serial.print(F("Increased brightness by 15 to: ")); b = ws2812fx->getBrightness(); } else { ws2812fx->increaseBrightness(5); Serial.print(F("Increased brightness by 5 to: ")); b = ws2812fx->getBrightness(); } Serial.println(b); } / other command from serial / if (strncmp(cmd,"numofleds ",10) == 0) { LED_COUNT = (uint16_t)atoi(cmd + 10); Serial.println(LED_COUNT); clearPixel(); ws2812fx->updateLength(LED_COUNT); Serial.print(F("Set LED_COUNT to: ")); LED_COUNT = ws2812fx->numPixels(); Serial.println(LED_COUNT); Serial.print(" leds"); delay(1000); wdt_disable(); wdt_enable(WDTO_15MS); while (1) {} }
cmd[0] = '\0'; // reset the commandstring cmd_complete = false; // reset command complete }
void clearPixel() { ws2812fx->clear(); }
void recvChar(void) { static byte index = 0; while (Serial.available() > 0 && cmd_complete == false) { char rc = Serial.read(); if (rc != '\n') { if(index < MAX_NUM_CHARS) cmd[index++] = rc; } else { cmd[index] = '\0'; // terminate the string index = 0; cmd_complete = true; Serial.print("received '"); Serial.print(cmd); Serial.println("'"); } } } ` This is not a complete code, but I hope it is enough to see the idea. Here are the effects on which the problem can be spotted: Running Random Running Lights Comet Larson Scanner
I can reproduce your issue. I think you should call the WS2812FX setLength() function instead of the Adafruit_Neopixel updateLength() function in processs_command(). This works on my Arduino Nano:
#include <WS2812FX.h>
//#include <avr/pgmspace.h> //enable use of flash memory
//#include <EEPROM.h> //enable use of eeprom
//#include <avr/wdt.h>
#define LED_PIN 8
#define MAX_NUM_CHARS 16 // maximum number of characters read from the Serial Monitor
bool LED_STAT = false;
char cmd[MAX_NUM_CHARS]; // char[] to store incoming serial commands
bool cmd_complete = false; // whether the command string is complete
WS2812FX *ws2812fx;
uint16_t LED_COUNT = 144; //Number of leds in the stripe
uint8_t m = FX_MODE_LARSON_SCANNER; //mode
uint32_t c = 0x7F007F; //color
uint16_t s = 500; //speed
uint8_t b = 15; //brightness
bool auto_cycle = false;
unsigned long auto_last_change = 0;
void setup() {
Serial.begin(115200);
delay(500);
ws2812fx = new WS2812FX(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// ws2812fx->begin();
// ws2812fx->setPin(LED_PIN);
// ws2812fx->updateType(NEO_GRB + NEO_KHZ800);
// ws2812fx->updateLength(LED_COUNT);
ws2812fx->init();
ws2812fx->setBrightness(b);
ws2812fx->setSpeed(s);
ws2812fx->setColor(c);
ws2812fx->setMode(m);
uint16_t numPixels = ws2812fx->numPixels();
Serial.print(F("numPixels: ")); Serial.println(numPixels);
ws2812fx->start();
}
void loop() {
unsigned long now = millis();
// ws2812fx->clear(); // ??
digitalWrite(LED_BUILTIN, LED_STAT ? HIGH : LOW);
ws2812fx->service();
recvChar(); // read serial comm
if (cmd_complete) {
process_command();
}
if (auto_cycle && (now - auto_last_change > 10000)) { // cycle effect mode every 10 seconds
uint8_t next_mode = (ws2812fx->getMode() + 1) % (ws2812fx->getModeCount() - 8);
ws2812fx->setMode(next_mode);
Serial.print("mode is "); Serial.println(ws2812fx->getModeName(ws2812fx->getMode()));
auto_last_change = now;
}
}
void process_command() {
if (strcmp(cmd, "b+") == 0) {
b = ws2812fx->getBrightness();
if (b >= 105) {
ws2812fx->increaseBrightness(15);
Serial.print(F("Increased brightness by 15 to: "));
b = ws2812fx->getBrightness();
} else {
ws2812fx->increaseBrightness(5);
Serial.print(F("Increased brightness by 5 to: "));
b = ws2812fx->getBrightness();
}
Serial.println(b);
}
if (strncmp(cmd, "numofleds ", 10) == 0) {
uint16_t numofleds = (uint16_t)atoi(cmd + 10);
Serial.print("numofleds:"); Serial.println(numofleds);
// ws2812fx->updateLength(numofleds);
ws2812fx->setLength(numofleds); // use setLength() instead of updateLength()
uint16_t numPixels = ws2812fx->numPixels();
Serial.print(F("numPixels: ")); Serial.println(numPixels);
// ??????
// delay(1000);
// wdt_disable();
// wdt_enable(WDTO_15MS);
// while (1) {}
// ??????
}
cmd[0] = '\0'; // reset the commandstring
cmd_complete = false; // reset command complete
}
void recvChar(void) {
static byte index = 0;
while (Serial.available() > 0 && cmd_complete == false) {
char rc = Serial.read();
if (rc != '\n') {
if (index < MAX_NUM_CHARS) cmd[index++] = rc;
} else {
cmd[index] = '\0'; // terminate the string
index = 0;
cmd_complete = true;
Serial.print("received '"); Serial.print(cmd); Serial.println("'");
}
}
}
Thanks a lot, everything works. :-)
This library is really remarkable, but I have a problem using the updateLength () option, due to the need to use led strips of different lengths after compile. I used the simple_new_operator.ino example and it works, but the predefined effects no longer work as they should. Is there a way to use the updateLength () option, and the effects work as when the number of segments is declared at the beginning of the code. Thanks in advance.