Arduino Uno ledstrip issue

I have 60 WS2812B leds on a strip, connected to an arduino uno.
when I run a adafruit neonpixel test code, it works fine.

When I upload my own code, it stops at 31 leds. i need at least 36 for my project.

Is it a memory issue? i'm thinking about moving to another board for size-reasons (like esp32 eth01). will that solve it?

Thanks

when I compile the code, i get:

Sketch uses 12254 bytes (37%) of program storage space. Maximum is 32256 bytes.
Global variables use 1178 bytes (57%) of dynamic memory, leaving 870 bytes for local variables. Maximum is 2048 bytes.
#include "Ethernet.h"
#include "sACN.h"
#include "Adafruit_NeoPixel.h"

//Setup Ethernet
uint8_t mac[] = {0x90, 0xA2, 0xDA, 0x10, 0x14, 0x48}; 
IPAddress ip(169, 254, 89, 67); 
IPAddress dns(169, 254, 89, 1); 
IPAddress gateway(169, 254, 89, 1); 
IPAddress subnet(255, 255, 0, 0); 

//Setup sACN
EthernetUDP sacn;
Receiver recv(sacn);
const int Universe= 32;
const int NUM_CHAN= 36;
const int Channel[NUM_CHAN]= {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36};
int DMX[NUM_CHAN];

//Setup LED
const int DATA_PIN= 7;
const int NUM_LEDS=36;
Adafruit_NeoPixel Led(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);

// Define colours
#define On 255,75,0
#define Off 0,65,255
#define Other 255,0,0
#define None  0,0,0
int Brightness=100;


void setup() {
	Serial.begin(9600);
  Ethernet.begin(mac, ip, dns, gateway, subnet);
 	recv.begin(Universe);
  Led.begin();
  Led.clear();
  Led.show();
  Led.setBrightness(Brightness);
 	}

void loop() {
	recv.update();

  for (int i=0; i<NUM_CHAN; i++){
    // Read Channel input, Write to DMX value
    DMX[i]= (recv.dmx(Channel[i]));
    //Apply values to Leds
    if (DMX[i]> 127){
      Led.setPixelColor(i, Led.Color(On));
    } else {
      Led.setPixelColor(i, Led.Color(Off));
      } 
    Led.show();
  }

}

How do you power the NeoPixels?

I do not think it's a memory issue. Adding 180 bytes (60 LEDs) to the 1178 bytes of dynamic memory should still be in the safe area.

What do you see if you print the values received from the DMX interface ? Are they what you expect ?

I assume that you are going to expand the code to do more, but as written you don't need the Channel and DMX arrays but memory seems unlikely to be a problem

1 Like

HI @sterretje and @UKHeliBob ,

interesting issue ... I copied the sketch to Wokwi and made some changes for testing purposes:

/*
  Forum: https://forum.arduino.cc/t/arduino-uno-ledstrip-issue/1400615
  Wokwi: https://wokwi.com/projects/423791454389927937

  Changes done to original sketch:

  * const int Channel is outcommented - not used here
  * NUM_CHAN set to 51
  * NUM_LEDS equals NUm_CHAN so that a change of NUM_CHAN also changes NUM_LEDS
  * //DMX[i]= (recv.dmx(Channel[i])); outcommented and replaced by  DMX[i]= random(0,256);
  * Led.show(); has been moved outside the for-loop;  makes sense to call show after all changes are done
  * Added delay(100) in loop to slow down the color changes

  Effect found:

  * works for up to 51 channels/leds
  * does not work for 52 or more

*/

#include "Ethernet.h"
#include "sACN.h"
#include "Adafruit_NeoPixel.h"

//Setup Ethernet
uint8_t mac[] = {0x90, 0xA2, 0xDA, 0x10, 0x14, 0x48}; 
IPAddress ip(169, 254, 89, 67); 
IPAddress dns(169, 254, 89, 1); 
IPAddress gateway(169, 254, 89, 1); 
IPAddress subnet(255, 255, 0, 0); 

//Setup sACN
EthernetUDP sacn;
Receiver recv(sacn);
const int Universe= 32;
const int NUM_CHAN= 51;
//const int Channel[NUM_CHAN]= {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36};
int DMX[NUM_CHAN];

//Setup LED
const int DATA_PIN= 7;
const int NUM_LEDS= NUM_CHAN;
Adafruit_NeoPixel Led(NUM_LEDS, DATA_PIN, NEO_GRB + NEO_KHZ800);

// Define colours
#define On 255,75,0
#define Off 0,65,255
#define Other 255,0,0
#define None  0,0,0
int Brightness=100;


void setup() {
	Serial.begin(9600);
  Ethernet.begin(mac, ip, dns, gateway, subnet);
 	recv.begin(Universe);
  Led.begin();
  Led.clear();
  Led.show();
  Led.setBrightness(Brightness);
 	}

void loop() {
	recv.update();

  for (int i=0; i<NUM_CHAN; i++){
    // Read Channel input, Write to DMX value
    //DMX[i]= (recv.dmx(Channel[i]));
    DMX[i]= random(0,256);
    //Apply values to Leds
    if (DMX[i]> 127){
      Led.setPixelColor(i, Led.Color(On));
    } else {
      Led.setPixelColor(i, Led.Color(Off));
      } 
  }
  Led.show();
  delay(100);
}

See here https://wokwi.com/projects/438548675385929729

The sketch works for 51 leds. With NUM_CHAN = 52 the strip does not show an effect ...

I'll be out of home n a few minutes :wink: Maybe you like to follow this issue?

Good luck!
ec2021

I have a dedicated power supply for the ledstrip. They work fine with another code (all 60 of them)

I havent checked the dmx input, but I have a loop running on a controller that sends dmx to the arduino.
31 leds run fine (the loop is showing). When I try 32 leds or more, the loop doesnt show.

Ill take a look at this later, see if it works for me.

I need the channel array, because the end project will have different numbers inside, that are not consecutive (i just did this for convenience)

I also might use some extra leds for functions outside the channel array, that is why num_chan =/= num_leds.
But only if this works!

Thanks for that, ec2021.

I've downloaded the sACN library, checked it and it used dynamic memory allocation.

sACN.cpp

Receiver::Receiver(UDP& udp) {
	this->udp = &udp;
	sacnPacket = new uint8_t [SACN_BUFFER_MAX];
	}

and SACN_BUFFER_MAX is 638 bytes
sACNDefs.h

#define SACN_BUFFER_MAX 638

Compiling for a classic Nano

Sketch uses 12636 bytes (41%) of program storage space. Maximum is 30720 bytes.
Global variables use 1110 bytes (54%) of dynamic memory, leaving 938 bytes for local variables. Maximum is 2048 bytes.

Subtract 51*3 bytes and the 638 bytes and one is in danger area when it comes to memory usage (only 147 bytes left).

1 Like

It looks like a memory issue.

If you comment out either the Ethernet of UDP code it works OK with larger numbers of LEDs

Hi @sterretje ,

thanks for checking it thoroughly... The behavior on Wokwi definitely looked like a memory issue.

I'm sorry, that last bit went a little over my head.

Am i right to conclude that I need another board?

Yes.

Consider Arduino Mega (8k RAM) or Arduino Nano Every (6K RAM). Before committing, you can compile for those boards. I don't expect problems with the Mega but the libraries that you use might not be compatible with the Nano Every; I leave that testing op to you.

Notes:

  1. If the form factor is important you can consider an Arduino Uno WiFi Rev2.
  2. For the Nano Every (and Arduino Uno WiFi Rev2.) you need to install the board package.

Thanks a lot people, I appreciate the quick responses!

I'll go shopping for another board.

Why use memory for the Channel[] array, when Channel[i] is the same as i-1...

    DMX[i]= (recv.dmx(Channel[i]));

same as...

    DMX[i]= (recv.dmx(i - 1));

[edit] oops... replace my "i - 1" with "i + 1" above...

Come to that, why use the DMX array at all ?

For those wondering, the eventual Channel array will look something like this:
(5,4,3,2,1,101,102,103,104,105,13,12,11,111,112,113,21,36,35,34,33,31,131,133,134,135,136,121,30,130,40,140)

so when dmx channel 5 is over 127, the first led will light up, et cetera.

Just to make sure you don’t run into a further problem without notice:

The control of WS2812 ledstrips is sensitive to timing. Therefore libraries as Fastled and - to my knowledge - also Adafruit NeoPixel usually disable interrupts during the data transfer. For 60 leds this counts up to about 1.9 ms. During this time further interrupts are blocked,

(For explanations see here https://github.com/fastled/fastled/wiki/interrupt-problems )

Whether the disabling of interrupts is or is not a problem will quite likely depend on the board chosen and on the behavior of the other libraries you use!

The linked page provides a workaround for the Fastled lib but that might interfere with the data transfer to the leds.

You can just give it a try!

If you cannot find a solution this way there is still a possibility to use one board for the DMX communication and a second board that only controls the leds. Both can be connected e.g. by Serial communication.

For a different thread (in German language :wink: ) I implemented an example with an UNO and a NANO board where one board receives MIDI data and the second controls a WS2812 ledstrip with 60 leds:

https://forum.arduino.cc/t/neopixel-oder-fastled-library-welche-ist-schneller/1385662/62

To (absolutely) make sure that no data is lost between board one and two the latter signalizes the time when interrupts are disabled via a simple digital connection.

It might not be necessary in your case but probably worth to know …

Good luck!

ec2021

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.