7. API - pi-top Peripheral Devices
7.1. pi-topPROTO+
This module provides 2 classes - a simple way to use a pi-topPROTO+’s onboard ADC (analog-to-digital converter), and another to use it as a distance sensor.
These classes will work with original pi-top, pi-topCEED and pi-top [3]. pi-top [4] does not support the pi-topPROTO+’s modular rail connector, and so will not work.
7.1.1. Using the pi-topPROTO+ as a Distance Sensor
from time import sleep
from pitop.protoplus import DistanceSensor
ultrasonic = DistanceSensor()
while True:
print(ultrasonic.distance)
sleep(1)
7.1.2. Class Reference: pi-topPROTO+ Distance Sensor
- class pitop.protoplus.sensors.DistanceSensor(*args, **kwargs)[source]
Encapsulates the behaviour of a simple DistanceSensor that can be turned on and off.
- Parameters:
- close()[source]
Shut down the device and release all associated resources. This method can be called on an already closed device without raising an exception.
This method is primarily intended for interactive use at the command line. It disables the device and releases its pin(s) for use by another device.
You can attempt to do this simply by deleting an object, but unless you’ve cleaned up all references to the object this may not work (even if you’ve cleaned up all references, there’s still no guarantee the garbage collector will actually delete the object at that point). By contrast, the close method provides a means of ensuring that the object is shut down.
For example, if you have a buzzer connected to port D0, but then wish to attach an LED instead:
>>> from pitop import Buzzer, LED >>> bz = Buzzer("D0") >>> bz.on() >>> bz.off() >>> bz.close() >>> led = LED("D0") >>> led.blink()
Device
descendents can also be used as context managers using thewith
statement. For example:>>> from pitop import Buzzer, LED >>> with Buzzer("D0") as bz: ... bz.on() ... >>> with LED("D0") as led: ... led.on() ...
- property raw_distance
7.1.3. Using the pi-topPROTO+’s onboard ADC
from time import sleep
from pitop.protoplus import ADCProbe
temp_sensor = ADCProbe()
while True:
print(temp_sensor.read_value(1))
sleep(0.5)
7.1.4. Class Reference: pi-topPROTO+ ADC Probe
7.2. pi-topPULSE
This module provides a simple way to use a pi-topPULSE, and will work with any Raspberry Pi and/or pi-top.
The hardware representation of each color is 5 bits (i.e. only 32 different values). Without gamma correction, this would mean the actual color value changes only every 8th color intensity value. This module applies gamma correction, which means that pixels with seemingly different intensities actually have the same.
7.2.1. Using the pi-topPULSE’s microphone
from time import sleep
from pitop.pulse import ledmatrix, microphone
def set_bit_rate_to_unsigned_8():
print("Setting bit rate to 8...")
microphone.set_bit_rate_to_unsigned_8()
def set_bit_rate_to_signed_16():
print("Setting bit rate to 16...")
microphone.set_bit_rate_to_signed_16()
def set_sample_rate_to_16khz():
print("Setting sample rate to 16KHz...")
microphone.set_sample_rate_to_16khz()
def set_sample_rate_to_22khz():
print("Setting sample rate to 22KHz...")
microphone.set_sample_rate_to_22khz()
def pause(length):
ledmatrix.off()
sleep(length)
def record(record_time, output_file, pause_time=1):
print("Recording audio for " + str(record_time) + "s...")
ledmatrix.set_all(255, 0, 0)
ledmatrix.show()
microphone.record()
sleep(record_time)
microphone.stop()
ledmatrix.off()
microphone.save(output_file, True)
print("Saved to " + output_file)
print("")
pause(pause_time)
set_sample_rate_to_22khz()
set_bit_rate_to_unsigned_8()
record(5, "/tmp/test22-8.wav")
set_bit_rate_to_signed_16()
record(5, "/tmp/test22-16.wav")
set_sample_rate_to_16khz()
set_bit_rate_to_unsigned_8()
record(5, "/tmp/test16-8.wav")
set_bit_rate_to_signed_16()
record(5, "/tmp/test16-16.wav")
7.2.2. Using the pi-topPULSE’s LED matrix: Test colors
import time
from pitop.pulse import ledmatrix
def show_map(r, g, b):
for x in range(0, 7):
for y in range(0, 7):
z = (float(y) + 7.0 * float(x)) / 49.0
rr = int(z * r)
gg = int(z * g)
bb = int(z * b)
ledmatrix.set_pixel(x, y, rr, gg, bb)
ledmatrix.show()
ledmatrix.rotation(0)
ledmatrix.clear()
# Display 49 different color intensities
for r in range(0, 2):
for g in range(0, 2):
for b in range(2):
if r + g + b > 0:
rr = 255 * r
gg = 255 * g
bb = 255 * b
print(rr, gg, bb)
show_map(rr, gg, bb)
time.sleep(5)
ledmatrix.clear()
ledmatrix.show()
7.2.3. Using the pi-topPULSE’s LED matrix: Fancy Light Show!
import colorsys
import math
from pitop.pulse import ledmatrix
s_width, s_height = ledmatrix.get_shape()
# twisty swirly goodness
def swirl(x, y, step):
x -= s_width / 2
y -= s_height / 2
dist = math.sqrt(pow(x, 2) + pow(y, 2)) / 2.0
angle = (step / 10.0) + (dist * 1.5)
s = math.sin(angle)
c = math.cos(angle)
xs = x * c - y * s
ys = x * s + y * c
r = abs(xs + ys)
r = r * 64.0
r -= 20
return (r, r + (s * 130), r + (c * 130))
# roto-zooming checker board
def checker(x, y, step):
x -= s_width / 2
y -= s_height / 2
angle = step / 10.0
s = math.sin(angle)
c = math.cos(angle)
xs = x * c - y * s
ys = x * s + y * c
xs -= math.sin(step / 200.0) * 40.0
ys -= math.cos(step / 200.0) * 40.0
scale = step % 20
scale /= 20
scale = (math.sin(step / 50.0) / 8.0) + 0.25
xs *= scale
ys *= scale
xo = abs(xs) - int(abs(xs))
yo = abs(ys) - int(abs(ys))
val = (
0
if (math.floor(xs) + math.floor(ys)) % 2
else 1 if xo > 0.1 and yo > 0.1 else 0.5
)
r, g, b = colorsys.hsv_to_rgb((step % 255) / 255.0, 1, val)
return (r * 255, g * 255, b * 255)
# weeee waaaah
def blues_and_twos(x, y, step):
x -= s_width / 2
y -= s_height / 2
scale = math.sin(step / 6.0) / 1.5
r = math.sin((x * scale) / 1.0) + math.cos((y * scale) / 1.0)
b = math.sin(x * scale / 2.0) + math.cos(y * scale / 2.0)
g = r - 0.8
g = 0 if g < 0 else g
b -= r
b /= 1.4
return (r * 255, (b + g) * 255, g * 255)
# rainbow search spotlights
def rainbow_search(x, y, step):
xs = math.sin((step) / 100.0) * 20.0
ys = math.cos((step) / 100.0) * 20.0
scale = ((math.sin(step / 60.0) + 1.0) / 5.0) + 0.2
r = math.sin((x + xs) * scale) + math.cos((y + xs) * scale)
g = math.sin((x + xs) * scale) + math.cos((y + ys) * scale)
b = math.sin((x + ys) * scale) + math.cos((y + ys) * scale)
return (r * 255, g * 255, b * 255)
# zoom tunnel
def tunnel(x, y, step):
speed = step / 100.0
x -= s_width / 2
y -= s_height / 2
xo = math.sin(step / 27.0) * 2
yo = math.cos(step / 18.0) * 2
x += xo
y += yo
if y == 0:
if x < 0:
angle = -(math.pi / 2)
else:
angle = math.pi / 2
else:
angle = math.atan(x / y)
if y > 0:
angle += math.pi
angle /= 2 * math.pi # convert angle to 0...1 range
shade = math.sqrt(math.pow(x, 2) + math.pow(y, 2)) / 2.1
shade = 1 if shade > 1 else shade
angle += speed
depth = speed + (math.sqrt(math.pow(x, 2) + math.pow(y, 2)) / 10)
col1 = colorsys.hsv_to_rgb((step % 255) / 255.0, 1, 0.8)
col2 = colorsys.hsv_to_rgb((step % 255) / 255.0, 1, 0.3)
col = col1 if int(abs(angle * 6.0)) % 2 == 0 else col2
td = 0.3 if int(abs(depth * 3.0)) % 2 == 0 else 0
col = (col[0] + td, col[1] + td, col[2] + td)
col = (col[0] * shade, col[1] * shade, col[2] * shade)
return (col[0] * 255, col[1] * 255, col[2] * 255)
effects = [tunnel, rainbow_search, checker, swirl]
step = 0
while True:
for i in range(500):
for y in range(s_height):
for x in range(s_width):
r, g, b = effects[0](x, y, step)
if i > 400:
r2, g2, b2 = effects[-1](x, y, step)
ratio = (500.00 - i) / 100.0
r = r * ratio + r2 * (1.0 - ratio)
g = g * ratio + g2 * (1.0 - ratio)
b = b * ratio + b2 * (1.0 - ratio)
r = int(max(0, min(255, r)))
g = int(max(0, min(255, g)))
b = int(max(0, min(255, b)))
ledmatrix.set_pixel(x, y, r, g, b)
step += 1
ledmatrix.show()
effect = effects.pop()
effects.insert(0, effect)
7.2.4. Using the pi-topPULSE’s LED matrix: Showing CPU temperature
import time
from pitop.pulse import ledmatrix
def getCpuTemperature():
tempFile = open("/sys/class/thermal/thermal_zone0/temp")
cpu_temp = tempFile.read()
tempFile.close()
return int(int(cpu_temp) / 1000)
OFFSET_LEFT = 0
OFFSET_TOP = 2
# fmt: off
NUMS = [1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, # 0
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, # 1
1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, # 2
1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, # 3
1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1, # 4
1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, # 5
1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, # 6
1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, # 7
1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, # 8
1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 1] # 9
# fmt: on
# Displays a single digit (0-9)
def show_digit(val, xd, yd, r, g, b):
offset = val * 15
for p in range(offset, offset + 15):
xt = p % 3
yt = (p - offset) // 3
ledmatrix.set_pixel(xt + xd, 7 - yt - yd, r * NUMS[p], g * NUMS[p], b * NUMS[p])
ledmatrix.show()
# Displays a two-digits positive number (0-99)
def show_number(val, r, g, b):
abs_val = abs(val)
tens = abs_val // 10
units = abs_val % 10
if abs_val > 9:
show_digit(tens, OFFSET_LEFT, OFFSET_TOP, r, g, b)
show_digit(units, OFFSET_LEFT + 4, OFFSET_TOP, r, g, b)
###########################################################
# MAIN
###########################################################
ledmatrix.rotation(0)
ledmatrix.clear()
lastTemperature = -1
try:
while True:
temperature = getCpuTemperature()
if temperature != lastTemperature:
if temperature < 60:
show_number(temperature, 0, 255, 0)
elif temperature < 70:
show_number(temperature, 255, 255, 0)
else:
show_number(temperature, 255, 0, 0)
lastemperature = temperature
time.sleep(2)
except KeyboardInterrupt:
ledmatrix.clear()
ledmatrix.show()
7.2.5. Using the pi-topPULSE’s LED matrix: Showing CPU usage
import time
from pitop.pulse import ledmatrix
last_work = [0, 0, 0, 0]
last_idle = [0, 0, 0, 0]
def get_cpu_rates():
global last_work, last_idle
rate = [0, 0, 0, 0]
f = open("/proc/stat", "r")
line = ""
for i in range(0, 4):
while not "cpu" + str(i) in line:
line = f.readline()
# print(line)
splitline = line.split()
work = int(splitline[1]) + int(splitline[2]) + int(splitline[3])
idle = int(splitline[4])
diff_work = work - last_work[i]
diff_idle = idle - last_idle[i]
rate[i] = float(diff_work) / float(diff_idle + diff_work)
last_work[i] = work
last_idle[i] = idle
f.close()
return rate
ledmatrix.rotation(0)
try:
while True:
rate = get_cpu_rates()
ledmatrix.clear()
for i in range(0, 4):
level = int(6.99 * rate[i])
if level < 4:
r = 0
g = 255
b = 0
elif level < 6:
r = 255
g = 255
b = 6
else:
r = 255
g = 0
b = 0
for y in range(0, level + 1):
ledmatrix.set_pixel(2 * i, y, r, g, b)
ledmatrix.show()
time.sleep(1)
except KeyboardInterrupt:
ledmatrix.clear()
ledmatrix.show()
7.2.6. Module Reference: pi-topPULSE Configuration
- pitop.pulse.configuration.set_microphone_sample_rate_to_16khz()[source]
Set the appropriate I2C bits to enable 16,000Hz recording on the microphone.
- pitop.pulse.configuration.set_microphone_sample_rate_to_22khz()[source]
Set the appropriate I2C bits to enable 22,050Hz recording on the microphone.
7.2.7. Module Reference: pi-topPULSE LED Matrix
- pitop.pulse.ledmatrix.brightness(new_brightness)[source]
Set the display brightness between 0.0 and 1.0.
- Parameters:
new_brightness – Brightness from 0.0 to 1.0 (default 1.0)
- pitop.pulse.ledmatrix.get_brightness()[source]
Get the display brightness value.
Returns a float between 0.0 and 1.0.
- pitop.pulse.ledmatrix.rotation(new_rotation=0)[source]
Set the display rotation.
- Parameters:
new_rotation – Specify the rotation in degrees: 0, 90, 180 or 270
- pitop.pulse.ledmatrix.get_pixel(x, y)[source]
Get the RGB value of a single pixel.
- Parameters:
x – Horizontal position from 0 to 7
y – Veritcal position from 0 to 7
- pitop.pulse.ledmatrix.set_pixel(x, y, r, g, b)[source]
Set a single pixel to RGB color.
- Parameters:
x – Horizontal position from 0 to 7
y – Veritcal position from 0 to 7
r – Amount of red from 0 to 255
g – Amount of green from 0 to 255
b – Amount of blue from 0 to 255
- pitop.pulse.ledmatrix.run_tests()[source]
Runs a series of tests to check the LED board is working as expected.
7.2.8. Module Reference: pi-topPULSE Microphone
- pitop.pulse.microphone.is_recording()[source]
Returns recording state of the pi-topPULSE microphone.
- pitop.pulse.microphone.set_sample_rate_to_16khz()[source]
Set the appropriate I2C bits to enable 16,000Hz recording on the microphone.
7.2.9. Advanced: EEPROM
The pi-topPULSE contains an EEPROM which was programmed using this settings file. during factory production.
See the Raspberry Pi Foundation’s HAT Github repository for more information.