Non-python API for Blinkt device

I’m not a python user but want to use the Blinkt module. Is there a command line program, or library with defined API that I can call from other languages like PHP or Pascal? Free Pascal is my go-to language and would be my first choice.

If nothing is available, any documentation the would enable me to create a FPC module? I’d be glad to share the results.

Thanks,
Joe

There’s no hardware documentation as such, but the Blinkt! is just a chain of 8 APA102 LED pixels, albeit ones with a particularly quirky implementation of the protocol, which can be driven by just toggling a couple of GPIO pins (data and clock).

It would be easy to, for example, create a C library you could bind into. I started with C for Blinkt!, intending to bind against it with Python, until I realized that it was simply overkill for most uses.

Anyway. The Blinkt! protocol is relatively straight forward. It’s just like driving a shift register, toggling the clock line and setting data bits in turn.

It comprises 8 APA102 pixels, the protocol of which is explored here: https://cpldcpu.com/2014/08/27/apa102/

The data line is connected to BCM 23 and the clock line to BCM 24.

The pixels are 24bits, 8bits per colour and include an 8bit “start frame” that has a 5bit brightness value for a total of 32bits per pixel:

   start       blue     green    red
   111   00000 00000000 00000000 00000000
           ^
           5-bit brightness value

All of the important stuff happens here: https://github.com/pimoroni/blinkt/blob/master/library/blinkt.py#L62-L79

Here’s that chunk with just the interesting bits of code:

def show():
    """Output the buffer to Blinkt!"""
    _sof()

    for pixel in pixels:
        r, g, b, brightness = pixel
        _write_byte(0b11100000 | brightness)
        _write_byte(b)
        _write_byte(g)
        _write_byte(r)

    _eof()

For each pixel, you need to clock out the pixel start frame which is 0b11100000 plus a brightness value from 0 to 31.

Then the b, g and r values are clocked out in the same way.

_write_byte() does simply that, it outputs each bit of a byte to the data line and pulses the clock: https://github.com/pimoroni/blinkt/blob/master/library/blinkt.py#L41-L46

It does this by clocking out the most significant bit of the byte and shifting that byte left once for each bit.

def _write_byte(byte):
    for x in range(8):
        GPIO.output(DAT, byte & 0b10000000)
        GPIO.output(CLK, 1)
        byte <<= 1
        GPIO.output(CLK, 0)

_sof() and _eof() stand for Start Of Frame and End Of Frame, these are the data bits that reset and latch the APA102 pixels: https://github.com/pimoroni/blinkt/blob/master/library/blinkt.py#L50-L60

def _eof():
    GPIO.output(DAT, 0)
    for x in range(36):
        GPIO.output(CLK, 1)
        GPIO.output(CLK, 0)

def _sof():
    GPIO.output(DAT,0)
    for x in range(32):
        GPIO.output(CLK, 1)
        GPIO.output(CLK, 0)

In this case, they’re just setting the data line and pulsing the clock. _eof() pulses the clock 36 times, clocking out 36 zeros. _sof() pulses the clock 32 times, clocking out 32 zeros.

So to summarize, in order to drive Blintk! you should:

  • Clock out 36 zeros
  • Clock out 8 pixels, for each pixel:
    • Clock out start frame with brightness from 0 to 31: 0b11100000 | brightness
      • Bytes are clocked out most-significant-bit (the left-most bit) first
    • Clock out blue byte
    • Clock out red byte
    • Clock out green byte
  • Clock out 32 zeros

Phil,

Thank you for your detailed response. I’m going to give it a try.

This is an old thread, and I don’t know if this is still needed, but … (and I am still working with this) …

The link above has info on my go interfaces to the Blinkt,and my method for remotely running them across a LAN. All in go.

The latest example has mreply_a.go and mreq.go showing remote access of Blinkt AND control of the pantilt hat via across the local network.