1

I am controlling WS2812 LEDs with Arduino nano using FastLED library. I want the LED patterns to change on receiving a command from another Arduino Nano over software serial, I don't have the option to use he hardware serial.

I have read that in order to write data to LEDs, the library disables all the interrupts. However the SoftwareSerial library also uses interrupts to transmit data properly. Is there any possible way to achieve this? Presently, when I am trying to do this I am getting garbage data.

3 Answers 3

1

How fast do you need to update the LEDs? The nice thing about WS2812s is that if you don't update them they maintain the current settings which means you only need to drive them once you have received a serial message.

The best way to do this would be to use some form of flow control over the serial port. e.g. you send a special control code over the serial line requesting the master to stop sending data. You then wait long enough for that to be sent and any data currently in transmission to arrive (so a absolute minimum of 20/(baud rate) seconds). After that time you call the function to update the LEDs. Once the LED update is done you send a second control code indicating that the other end can resume transmission.

This is the basic structure of software flow control (or XON/XOFF as it is also called) that most serial ports support as an option. You can either use the standard implementation or use something a little simpler since you only need data and flow control in one direction.

The other option is to design the system around rules that ensure you don't miss data. The system sending you the LED updates knows that once you get the update you will need to apply it to the LEDs and that during that time you can't receive serial data. So after an update it waits and doesn't send more data until you've had time to do that.

1

The FastLED and NeoPixel libraries turn off interrupts for the specific timing of the WS2812. The Adafruit NeoPixel has a few extra options to be able to still handle some interrupts. The FastLED has a wiki that describes the problem with interrupts: FastLED wiki interrupts

The SoftwareSerial requires interrupts. When the SoftwareSerial is busy, the Arduino is occupied.

To me it seems impossible to make both libraries work at the same time. I think you have to change something. For example use a Arduino Micro or Pro Micro and use the spare hardware serial port. Or use a ledstrip with leds that have a clock signal and don't need specific timing.

If that is not possible, you might have to use pin 0 (RX) and pin 1 (TX), which are also used by the serial monitor and to upload a sketch.
It is possible to split RX and TX. The only thing that RX and TX have in common is the baudrate, but you can use them for seperate tasks. For example, use TX to send (debug) messages to the serial monitor, and use the RX to receive commands from another Arduino board. Disconnect that other Arduino board to upload a sketch.

[ADDED] After reading the answer by @Andrew and the FastLED wiki about interrupts, I think that my answer and @Andrew's answer are equally good answers. Perhaps the best way is to do it all: faster Arduino board, hardware serial port for commands, do one thing at a time, implement some kind of XON/XOFF in software, and if possible use other leds.

1
  • Of course the best solution is to not use arduino at all. If you use a processor that lets you run an SPI bus with 12 bit data at 2.4 MHz then the hardware can handle the timing requirements and there is no need to disable interrupts to start with. Unfortunately that's not always an option.
    – Andrew
    Commented Jun 6, 2017 at 16:22
0

Another approach is to make the commands to change the pattern very short. Like, one letter/byte.

This assumes that the patterns are stored on your Arduino, and you just choose which one to show.

In order for that to work, the Arduino has to confirm commands it received, and return an error if it receives something it does not understand (e.g. only half of the command). This allows the host to check if the Arduino received the command or if it was animating at that time, in that case re-send the command.

This approach avoids the issue that you receive partial data (because the smallest transmission unit is used). Commands can still be lost, but then they can be re-sent.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.