Raspberry Pi SPI Speed and LPD8806 RGB Strips using Python

So we recently decided to move this project to the Raspberry Pi board away from Arduino. The capabilities and processing power of the Pi are much greater than Arduino. The Raspberry Pi community is growing extremely fast and amazing projects are happening everywhere.

We have successfully loaded images into the SGEB, but the refresh rate is too slow, much slower then the Arduino was. We need some help figuring out how to turn up the SPI speed with our current software arrangement.

I used  Brian Hensley’s method for loading the SPI drivers on to Wheezy http://www.brianhensley.net/2012/07/getting-spi-working-on-raspberry-pi.html

Then used Phillip Burgess’ at Adafruit ‘Light Painting’ Python script to process images and output to the LPD8806 http://learn.adafruit.com/light-painting-with-raspberry-pi/software

The image processing script is amazing and solves tons of problems we had with the Arduino.

But I can’t figure out how to set the SPI speed through the Python scripts. 

I had attempted to use the Occidentalis OS as Adafruit suggested but the SPI Max Speed is set to 500 Khz in arch/arm/machbc2708/bcm2708.c   Compiling a Kernel proved to difficult for me to manage.

Am I mistaken that the SPI drivers are different between the 2 methods?

6 thoughts on “Raspberry Pi SPI Speed and LPD8806 RGB Strips using Python

    1. Jason J Post author

      Afraid not. I am willing to pay money… just can’t find anyone competent that wants to do it.

  1. Grant

    Hi Jason,

    You and I happen to be in very similar circumstances: I’m working on a POV project using LPD8806 strips and currently switching from Arduino to Raspberry Pi. My project will be a single stationary column of the strips; the viewer’s eye will be the thing that moves. You weren’t planning to take this to Burning Man, were you? 😉

    I’m using Occidentalis 0.2 and still sorting out the various options: write my own C code, use the LPD8806 python module, use the spidev python module, etc. For now I will say that I’ve found a somewhat strange way to set the speed of Phillip’s script, which uses the write-to-device-file method. (I assume there’s some nice way to set the clock speed using the same driver that exposes that file, but I haven’t found it yet.)

    Brian’s spidev_test.c program takes a speed argument like so:
    > sudo ./a.out -s 4000000 # 4 MHz
    With an LPD8806 strip plugged in, this sets an uninteresting light pattern, but the speed used appears to stick. If I then run Phillip’s lightpaint.py script, my image data is pushed at the last speed used by the C program.

    I seem to be able to drive it as high as the LPD’s max 20MHz (probably rounded down to 16MHz).


    1. Grant

      The line that sets speed in spidev_test.c is:
      ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
      where SPI_IOC_WR_MAX_SPEED_HZ is defined somewhere to be 40046b04 in hex.

      So this line can be replicated in Python as:
      fcntl.ioctl(spidev, 0x40046b04, array.array('L', [4000000]))
      I’m not sure why it needs a buffer just to set it properly; using a straight int doesn’t seem to work.
      It’s bad practice to reference the SPI_IOC_WR_MAX_SPEED_HZ constant as hex, but I can’t think of a good way to get this into Python, save from a module that includes linux/spi/spidev.h and sets up a Python constant.

      While it lacks documentation, the best approach is probably to use py-spidev.

      1. Jason J Post author

        Grant, THANK YOU!!!! We got this to work last night with the help of your code. We had to make a few tweaks. We will post the updated code very soon.

  2. Grant

    Great, glad I could help! Yeah, I’ve been using that python ioctl call; it works great and seems the lightest-weight option. I’m still concerned that some future kernel update will change the value of SPI_IOC_WR_MAX_SPEED_HZ, but it shouldn’t be too hard to change if/when that happens.

    Here’s a video of my 5-meter strip running at 8Mhz (through about 20 feet of Cat5 cable, no less!):


Leave a Reply

Your email address will not be published. Required fields are marked *