diozero icon indicating copy to clipboard operation
diozero copied to clipboard

WS281x on RPi4

Open neil-benn opened this issue 2 years ago • 14 comments

Hello,

I'm running the WS281x (Neopixel) code on an RPi4, raspberry PiOS 64bit:

pi@raspberrypi:~/neopixeltest $ uname -a Linux raspberrypi 5.10.92-v8+ #1514 SMP PREEMPT Mon Jan 17 17:39:38 GMT 2022 aarch64 GNU/Linux

I've got a simple use case taken from the sample code:

import com.diozero.ws281xj.LedDriverInterface; import com.diozero.ws281xj.PixelAnimations; import com.diozero.ws281xj.PixelColour; import com.diozero.ws281xj.rpiws281x.WS281x;

public class TestNeo{

    public static void main(String args[]){
            System.out.println("Test Neo starting");
            int brightness = 64;
            int num_pixels = 1;
            LedDriverInterface statusLed = new WS281x(18, brightness, num_pixels);

            int[] colours = PixelColour.RAINBOW;

            for (int i=0; i<250; i++) {
                    for (int pixel=0; pixel<statusLed.getNumPixels(); pixel++) {
                            statusLed.setPixelColour(pixel, colours[(i+pixel) % colours.length]);
                    }

                    statusLed.render();
                    PixelAnimations.delay(50);
            }
    }

}

When executing as sudo it works:

pi@raspberrypi:~/neopixeltest $ sudo java -cp diozero-core-1.3.2.jar:diozero-ws281x-java-1.3.2.jar:. TestNeo Test Neo starting order=BIG_ENDIAN

However when executing as a normal user it does not because I don't haev access to /dev/mem#:

pi@raspberrypi:~/neopixeltest $ java -cp diozero-core-1.3.2.jar:diozero-ws281x-java-1.3.2.jar:. TestNeo Test Neo starting Can't open /dev/mem: Permission denied ws2811_init failed: mmap() failed Exception in thread "main" java.lang.RuntimeException: Error initialising the WS281x strip at com.diozero.ws281xj.rpiws281x.WS281x.(WS281x.java:154) at com.diozero.ws281xj.rpiws281x.WS281x.(WS281x.java:121) at TestNeo.main(TestNeo.java:12)

Looking for access to /dev/mem this is nto availabel but there is a /dev/gpiomem - can this be referenced to access the gpio ports for teh ws281 code? Note that the 'normal' gpio acccess does work without needing root access on the RPi.

Thanks.

Cheers,

Neil

neil-benn avatar Mar 02 '22 16:03 neil-benn

I've just read the issues on rpi_ws281x (here. This just isn't possible so the app either needs to run as root or it won't work. This is a bit of a shame but there is nothing we can do here.

neil-benn avatar Mar 02 '22 17:03 neil-benn

Have you tried my SPI driver? That will work without requiring root permissions.

mattjlewis avatar Mar 03 '22 09:03 mattjlewis

Hello,

Thanks, I'll look into it and move the ports around.

Cheers,

Neil

On Thu, 3 Mar 2022, 09:07 Matthew Lewis, @.***> wrote:

Have you tried my SPI driver? That will work without requiring root permissions.

— Reply to this email directly, view it on GitHub https://github.com/mattjlewis/diozero/issues/89#issuecomment-1057827631, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADY2NXUJMS6IGKXJ5TIE6CTU6B6MLANCNFSM5PX6AABA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you modified the open/close state.Message ID: @.***>

neil-benn avatar Mar 03 '22 10:03 neil-benn

Thanks, I'm trying to get the SPI working. I've got the neopxiel wired up to GPIO10 and the constructor of

LedDriverInterface statusLed = new WS281xSpi(0, 8, StripType.WS2812, 64, 1);

This is giving me the error of:

pi@raspberrypi:~/neopixeltest $ java -cp diozero-c:diozero-ws281x-java-1.3.2.jar:tinylog-api-2.4.1.jar:tinylog-impl-2.4.1.jar:. TestNeo Test Neo starting Exception in thread "main" com.diozero.api.RuntimeIOException: Error in spiTransfer(), response: -1 at com.diozero.internal.provider.builtin.spi.NativeSpiDevice.write(NativeSpiDevice.java:96) at com.diozero.internal.provider.builtin.spi.NativeSpiDevice.write(NativeSpiDevice.java:90) at com.diozero.internal.provider.builtin.DefaultNativeSpiDevice.write(DefaultNativeSpiDevice.java:76) at com.diozero.api.SpiDevice.write(SpiDevice.java:201) at com.diozero.ws281xj.spi.WS281xSpi.render(WS281xSpi.java:188) at TestNeo.main(TestNeo.java:23) open failed: No such file or directorySPI message transfer failed: Bad file descriptor

I'm not sure what values to put in for the controller, chipselect and what pin I should be using. I'm currently connected to GPIO 10 (SPI0 MOSI).

Cheers,

Neil

neil-benn avatar Mar 03 '22 11:03 neil-benn

Hello,

Still working on this; I've now got:

LedDriverInterface led_driver = new WS281xSpi(0, 0, strip_type, pixels, brightness);

With the data in pin on the NeoPixel connected to SPI0 MOSI (pin 10). The NeoPixel does indeed get power but when running the SampleApp in WS281xSpiTest (modified to use SPI0) all I get is white on the NeoPixel so I'm doing something wrong. GPIO 10 is indeed SPI0 MOSI:

pi@raspberrypi:~/neopixeltest $ raspi-gpio get 10 GPIO 10: level=0 fsel=4 alt=0 func=SPI0_MOSI pull=DOWN

I've managed to make it work in Python but I need it in Java as the body of code is Java and shelling a python process will add extra layers on complexity.

Any ideas would be gratefully received.

Cheers,

Neil

neil-benn avatar Mar 03 '22 18:03 neil-benn

This is like a running story! I've worked on the java code and simplified it:

`import com.diozero.ws281xj.LedDriverInterface; import com.diozero.ws281xj.PixelAnimations; import com.diozero.ws281xj.PixelColour; import com.diozero.ws281xj.spi.WS281xSpi; import com.diozero.ws281xj.StripType; import com.diozero.util.SleepUtil; import org.tinylog.Logger;

public class TestNeo{

    public static void main(String args[]){
            StripType strip_type = StripType.WS2812;
            int pixel = 1;
            int brightness = 127;

            try (LedDriverInterface led_driver = new WS281xSpi(0, 0, strip_type, pixel, brightness)) {
                    Logger.debug("All off");
                    led_driver.allOff();
                    SleepUtil.sleepMillis(500);
                    Logger.debug("red");
                    led_driver.setPixelColourRGB(0,255,0,0);
                    led_driver.render();
                    SleepUtil.sleepMillis(500);
                    Logger.debug("green");
                    led_driver.setPixelColourRGB(0,0,255,0);
                    led_driver.render();
                    SleepUtil.sleepMillis(500);
                    Logger.debug("blue");
                    led_driver.setPixelColourRGB(0,0,0,255);
                    led_driver.render();
                    SleepUtil.sleepMillis(500);
                    Logger.debug("All off");
                    led_driver.allOff();
                    led_driver.render();
            }
    }

}`

This works in that the NeoIxel turns on but the colours are all screwy. I'm meant to get off, red, green, blue, off but I'm getting Off, Purple, Yellow, Blue, White. If I up the delay between calls to something like 1 second then I get off, blue, red, off, white. Changing hte delay between calls gives me different combinations. Progress but not there yet.

neil-benn avatar Mar 03 '22 19:03 neil-benn

Next - upped the brightness to 255, dropped the pixel values for RGB to 10 and the colour is correct and cycled through the colours. We get good colour for a couple of runs and then it gets stuck on white. It seems that the timings are off a bit. Gotta go (left a soak test running from the python code) but if you have any advice that would be greatly appreciated!

neil-benn avatar Mar 03 '22 19:03 neil-benn

Thanks for your patience Neil. Unfortunately I cannot test this out myself right now, I do recall the SPI driving being a bit "experimental". Frustrating that it sort of works - as you know timing is critical with these devices. It might be worth experimenting with the different Protocol variants (400 and 800 kHz)?

mattjlewis avatar Mar 11 '22 17:03 mattjlewis

That's my thinking, right now I'm shelling python which works so I'll take a look at that source to look at what it does and bring that in. It is a task on our schedule so we'll allocate it (probably to me) next week.

Get Outlook for Androidhttps://aka.ms/AAb9ysg


From: Matthew Lewis @.> Sent: Friday, March 11, 2022 5:36:51 PM To: mattjlewis/diozero @.> Cc: Neil Benn @.>; State change @.> Subject: Re: [mattjlewis/diozero] WS281x on RPi4 (Issue #89)

Thanks for your patience Neil. Unfortunately I cannot test this out myself right now, I do recall the SPI driving being a bit "experimental". Frustrating that it sort of works - as you know timing is critical with these devices. It might be worth experimenting with the different Protocol variants (400 and 800 kHz)?

— Reply to this email directly, view it on GitHubhttps://github.com/mattjlewis/diozero/issues/89#issuecomment-1065333834, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ADY2NXWNZRWASNK5RUYQIRLU7OADHANCNFSM5PX6AABA. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you modified the open/close state.Message ID: @.***>

neil-benn avatar Mar 11 '22 17:03 neil-benn

Which Python library are you using? I'd be happy to look at that and see if how I can improve things with my code.

mattjlewis avatar Mar 11 '22 17:03 mattjlewis

Hello,

This is the installation:

sudo pip3 install rpi_ws281x adafruit-circuitpython-neopixel adafruit-circuitpython-neopixel-spi sudo python3 -m pip install --force-reinstall adafruit-blinka

The URL is at https://learn.adafruit.com/circuitpython-neopixels-using-spi.

Cheers,

Neil


From: Matthew Lewis @.> Sent: Friday, March 11, 2022 5:52:54 PM To: mattjlewis/diozero @.> Cc: Neil Benn @.>; State change @.> Subject: Re: [mattjlewis/diozero] WS281x on RPi4 (Issue #89)

Which Python library are you using? I'd be happy to look at that and see if how I can improve things with my code.

— Reply to this email directly, view it on GitHubhttps://github.com/mattjlewis/diozero/issues/89#issuecomment-1065345761, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ADY2NXR3DKMXX77DONZO4MDU7OB7NANCNFSM5PX6AABA. Triage notifications on the go with GitHub Mobile for iOShttps://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Androidhttps://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub. You are receiving this because you modified the open/close state.Message ID: @.***>

neil-benn avatar Mar 11 '22 18:03 neil-benn

Did you manage to make this work @neil-benn ?

mkpazon avatar Aug 04 '22 03:08 mkpazon

Hello,

No, sorry the timing was just out on the SPI so I eventually shelled out to Python.

Cheers,

Neil

Get Outlook for Androidhttps://aka.ms/AAb9ysg


From: Mark Pazon @.> Sent: Thursday, August 4, 2022 5:00:59 AM To: mattjlewis/diozero @.> Cc: Neil Benn @.>; Mention @.> Subject: Re: [mattjlewis/diozero] WS281x on RPi4 (Issue #89)

Did you manage to make this work @neil-bennhttps://github.com/neil-benn ?

— Reply to this email directly, view it on GitHubhttps://github.com/mattjlewis/diozero/issues/89#issuecomment-1204700352, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ADY2NXX5GF3AWECB3JJ55I3VXMW6XANCNFSM5PX6AABA. You are receiving this because you were mentioned.Message ID: @.***>

neil-benn avatar Aug 04 '22 07:08 neil-benn

I had a similar issue and got mine working with Raspberry Pi 3. Check out https://github.com/jgarff/rpi_ws281x as it mentions some configurations you need to do for Raspberry Pi 4.

Specifically in Raspberry Pi 4 you have to add these to /boot/config.txt and reboot:

core_freq=500
core_freq_min=500

I still ended up using new WS281x(gpio_num, brightness, num_pixels) instead of WS281xSpi one as it was giving the same /dev/mem error you mentioned.

mkpazon avatar Aug 04 '22 09:08 mkpazon

Thank you - will make a note of this.

mattjlewis avatar Jan 16 '23 21:01 mattjlewis