Blinkt with Filesystem Device Drivers

The Blinkt from Pimoroni is a strip of 8 bright RGB leds that plugs into the GPIO header of your Raspberry Pi.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/env python3
# -*- mode: Python; -*-

import sys, time, os

# Pimoroni Blinkt uses 2 pins to control LEDs
data = 23
clock = 24

def write(fn,n):
  with open(fn, "w") as f:
    f.write(str(n))

def writepin(p,n):
  write("/sys/class/gpio/gpio" + str(p) + "/value", n)

def xmitbit(n):
  # Approximate 2 microseconds; this holdtime works on my Pi3.
  # I am assuming time.sleep uses usleep, so I don't want to go lower.
  # Don't know what the real holdtime should be.
  holdtime = 0.000002
  writepin(data, n)
  time.sleep(holdtime)
  writepin(clock, 1)
  time.sleep(holdtime)
  writepin(clock, 0)
  time.sleep(holdtime)

def write_byte(byte):
  for x in range(8):
    xmitbit((byte >> (7 - x)) & 1)

def clamp01_scale_int(x, i):
  if x < 0.0:
    return 0
  elif x > 1.0:
    return 0
  else:
    return int(x * i + 0.5)

# Export data and clock pins in filesystem
if not os.path.exists("/sys/class/gpio/gpio" + str(data)):
  write("/sys/class/gpio/export", data)
if not os.path.exists("/sys/class/gpio/gpio" + str(clock)):
  write("/sys/class/gpio/export", clock)

# Configure the pins for output
write("/sys/class/gpio/gpio" + str(data) + "/direction", "out")
write("/sys/class/gpio/gpio" + str(clock) + "/direction", "out")

# Convert floating point values to range for LEDs
r = clamp01_scale_int(float(sys.argv[1]), 255)
g = clamp01_scale_int(float(sys.argv[2]), 255)
b = clamp01_scale_int(float(sys.argv[3]), 255)
a = clamp01_scale_int(float(sys.argv[4]), 31)

# Sync to start sending; count from Pimoroni
for x in range(32):
  xmitbit(0)

# Send the same value to all 8 LEDs
for pixel in range(8):
  write_byte(0b11100000 | a)
  write_byte(b)
  write_byte(g)
  write_byte(r)

# Sync to finish sending; count from Pimoroni
for x in range(36):
  xmitbit(0)

exit(0)