Saturday, December 2, 2017

Perl, Neopixels, Arduino and Pi

Some time ago I acquired an Adafruit 'Neopixel' stick.


If you're unfamiliar with these they are strings of WS2812 or compatible LEDs that you drive with a single PWM signal ( Neopixel stick described here ).

In recent releases of the HiPi Perl modules I've concentrated on having the modules operate without any requirement for root privileges and I'm committed to maintaining approach going forwards. That presents a problem with PWM. There is plenty of existing code for the Pi that allows you to drive  PWM signals directly. For Perl user-space code, interfacing with Joan's pigpio daemon looks the best option to me.

However for HiPi's device driver approach my only use of PWM so far has been driving servos and for that I've used external I2C PWM boards with HiPi::Interface::PCA9685. These boards can't provide the type of PWM signal the LED stick requires so something different was needed.

Four weeks ago I got my first Arduino. I wanted to drive a radio I2C breakout that was causing me grief with the Pi. It all came together rather easily. The Pi communicates with the Arduino using SPI and the Arduino controls the radio over I2C. I know I'm rather late to the party interfacing the Pi with Arduino but it's new to me and I wanted to do it using Perl.

Given the low cost of compatible boards based on the Open Source Arduino,  it seems a good option to use the devices in Pi projects and I remembered the Neopixel stick I owned.

"Arduino" Nanos and Pro Minis  duly arrived from China and I was controlling the pixel stick from a Pi using HiPi and I2C within a few hours.

I tried a 5v Nano, a 5v Pro Mini and a 3v3 Pro Mini, all with success.

Circuit for a 5v Pro Mini


According to spec, each pixel at full brightness might draw 60mA or 480mA for the whole 8 pixel stick so I needed a separate power solution.

A used a 2.5 amp 5v official Pi power supply to power a Pi Zero W, the "Arduino" Pro Mini, and the Neopixel stick all via a micro usb breakout. The 5v from the breakout is connected to a 5v pin on the Pi, the VCC pin on the Pro Mini, and the 5v pin on the Neopixels. All are connected to a common ground, of course.

SDA on the Pi is connected to A4 on the Pro Mini, and SCL to A5. These connections are made through a logic level converter as the Pro Mini logic is 5v. The 3v3 pin on the Pi provides the low voltage connection for the converter while the 5v on the high side is taken direct from the 5v power supply.

D6 on the Pro Mini is connected to the data pin on the Neopixel stick, but any of the PWM capable pins could be used.


Important - Don't Fry The Arduino


We have connected the 5v power directly to the VCC pin on the Pro Mini. The Pro Mini must be programmed using an FTDI cable or similar. You MUST remove the connection from the Pro Mini VCC to 5v before you connect the FTDI or bad things will happen ( from experience - I have a Pro Mini permanently running 'Blink' now ).


Code

I've posted the Arduino sketch and example Perl code to Raspduino Github that demonstrates controlling the pixels from a Pi.


Alternate Setup and Power


Arduino Nano

I tried the setup with a 5v Nano which apart from the different pin positions on the Nano was a drop in replacement. Again, although the Nano can be programmed via its USB connection, as we have the 5v supply connected to the 5v pin on the Nano for the working setup, I'm sure we must remove the connection to the 5v rail before we connect the USB.


3v3 8mhz Arduino Pro Mini

Dropping in an 8mhz 3v3 Pro Mini means that I don't need the logic level converter for the I2C connection so that's one less component. For the 3v3 Pro Mini the power connection from the 5v rail goes to the RAW pin on the Pro Mini, not the VCC. According to specification this also means that the inbuilt protections on the board allow me to connect the FTDI programmer (set to 3v3 ) without removing the 5v connection to RAW, but I confess I have not tried it. Connecting the 3v3 D6 logic pin from the Arduino to the data pin on the Neopixel stick is fine. The Neopixel remains connected to the 5v rail for power.


Alternate Power

I think it would be fine to power this whole setup by powering the Pi Zero directly and taking 5v from the Pi 5v pin. If you wanted to attach more Neopixels you would need to power those separately. In that case I think I'd power the Pi directly, the Arduino from the Pi 5v, and a separate supply for the pixels.

In all schemes, remember that everything needs to share a common ground and remember to disconnect the Arduino 5v/VCC pin from the 5v supply rail before attaching your FTDI or USB cable.


Next Steps

I'm interested in having a simple pixel flashing and text message display project up for Christmas. A previous random purchase means that I have a few nRF24L01+ boards that I've never used. I see they are well supported with Arduino libraries so I need to add support to HiPi so I can control the Arduino end of things at a distance. Python libraries exist for the Pi of course, but it's not Perl is it.