kitesurfer1404 / WS2812FX

WS2812 FX Library for Arduino and ESP8266

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ws2812fx.updateLength()

wecoy76 opened this issue · comments

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.

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?

`
#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

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. :-)