Cluster Duster

ramblings of software and hardware stuffs

How to Increase SPI Clock Speed in Python for the Raspberry Pi

When I first started working with the Raspberry Pi for the Helios project I noticed that the refresh rate was quite slow for long strings of LPD8806 RGB LEDs. After further investigation I found that the default clock rate for SPI was not configurable using the LPD8806.py library from Sh4d on Github. In my example below we will be using the LPD8806.py library built by Sh4d mentioned previously. We will be modifying this library so the library can also be used to increase the clock rate of the SPI device on the Raspberry Pi. This will allow the Raspberry Pi to send data faster and therefore increase the refresh rate of our LED rope.

Fist you will want to hop over to Github and checkout Sh4d’s version of the library. Once the Python library is downloaded, browse the code and try to find where the SPI device is being instantiated. Notice that the library is writing directly to the SPI device under /dev, using an output stream, which is the same method as writing to a file on the filesystem. This works, but this is not optimal. Using this method means we are piping data directly to the device using the kernel default settings (this includes the default clock value which is too slow for our application). This value is too low.

After doing some research into SPI libraries for Python I stumbled across SPIDEV, a Python library written in C which gives direct access to the device driver which allows the script to set driver values and communicate directly with the SPI port on the Raspberry Pi. To install SPIDEV on the Raspberry Pi follow the instructions at 100RandomTasks.

Once the SPI device library is installed we can start using this library to communicate with the device instead of streaming data to the device through IO operations. First we must import the library once it is installed:

1
import spidev

Once this is complete we will want to change the communication method in which we send data to the SPI device. To do this we first need to do is switch from the file input/output method to using the new SPIDEV library method:

Old:

1
self.spi = file(self.dev, "wb")

New:

1
2
3
self.spi = spidev.SpiDev()
self.spi.open(0, 0)
self.spi.max_speed_hz = 25000000

The first thing that we need to do is construct the device. This is done through line 1. The second step is to open the device so we can start changing the default driver settings. The example above is changing the clock speed to 25Mhz. This is just an example. Finding the exact clock rate for your application might take some trial and error and is beyond the scope of this article. I recommend trying different values until you find a proper value or reading the documentaion for the SPI slave devices. This documentation should steer you in the right direction to selecting the proper clock rate.

The next step is to modify how we send data to the SPI device. Since we are not using file I/O operations any more we need to change the way we “talk” to the device. For example, the SPIDEV driver does not contain a flush method which is used when working with file I/O. After reading through the SPIDEV code we notice that the write method (spidev.write) takes a single 8-bit value. This means we need to modify the “update” method in the LPD8806.py library. To do this we change the following lines:

Old:

1
2
3
4
5
for x in range(self.leds):
    self.spi.write(self.buffer[x])
    self.spi.flush()
    self.spi.write(bytearray(b'\x00'))
    self.spi.flush()

New:

1
2
3
4
5
6
7
final_buf = []
for i in range(0, self.leds):
    final_buf.append(self.buffer[i][0])
    final_buf.append(self.buffer[i][1])
    final_buf.append(self.buffer[i][2])
    final_buf.append(0)
self.spi.xfer(final_buf)

At this point we are now able to run our SPI port at any speed we select. There are many different options that can be set directly on the SPI device for the Raspberry Pi. I recommend reading the code for the SPIDEV library to find out what settings are available and what settings are best for your application needs.

Helio Release

Today I have released the latest version of Helios. Helios is a web driven LED controller for the Raspberry Pi and the LPD8806 RGB-LED rope. The application includes many different patterns, solid color, and color wheel pattern selection from a webpage served directly from the Raspberry Pi (Linux, Mac, Windows, iOS, and Android devices are supported). Check out the github page below for more details.

https://github.com/junkert/helios