kitesurfer1404 / WS2812FX

WS2812 FX Library for Arduino and ESP8266
MIT License
1.58k stars 344 forks source link

ws2812fx.updateLength() #274

Closed wecoy76 closed 3 years ago

wecoy76 commented 3 years ago

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.

moose4lord commented 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?

wecoy76 commented 3 years ago

`

include

include <avr/pgmspace.h> //enable use of flash memory

include //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

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

moose4lord commented 3 years ago

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("'");
    }
  }
}
wecoy76 commented 3 years ago

Thanks a lot, everything works. :-)