5. API - pi-top Device
5.1. Pitop
This class represents a pi-top device. Each of the on-board features of pi-tops can be accessed from this object.
Note
This class has been built with pi-top [4] in mind, as is in early development. You may notice that some features do not behave as expected on other platforms.
If you would like to help us with development, please refer to the Contributing document in this repository for information!
Here is some sample code demonstrating how the various subsystems of a pi-top [4] can be accessed and used:
from time import sleep
from PIL import Image
from pitop import Pitop
# Set up pi-top
pitop = Pitop()
# Say hi!
pitop.miniscreen.display_text("Hello!")
sleep(2)
# Display battery info
battery_capacity = pitop.battery.capacity
battery_charging = pitop.battery.is_charging
pitop.miniscreen.display_multiline_text(
"Battery Status:\n"
f"-Capacity: {battery_capacity}%\n"
f"-Charging: {battery_charging}",
font_size=15,
)
sleep(2)
# Configure buttons to do something
keep_running = True
def display_gif_and_exit():
image = Image.open(
"/usr/lib/python3/dist-packages/pitop/miniscreen/images/rocket.gif"
)
pitop.miniscreen.play_animated_image(image)
pitop.miniscreen.display_text("Bye!")
sleep(2)
global keep_running
keep_running = False
pitop.miniscreen.select_button.when_pressed = display_gif_and_exit
pitop.miniscreen.cancel_button.when_pressed = display_gif_and_exit
pitop.miniscreen.up_button.when_pressed = display_gif_and_exit
pitop.miniscreen.down_button.when_pressed = display_gif_and_exit
pitop.miniscreen.display_multiline_text("Press any button...", font_size=25)
# Sleep until `display_gif_and_exit` runs
while keep_running:
sleep(0.3)
Although it is possible to access pi-top subsystems individually, it is recommended to access them via this class.
5.1.1. Class Reference: Pitop
- class pitop.Pitop(*args, **kwargs)[source]
Represents a pi-top Device.
When creating a Pitop object, multiple properties will be set, depending on the pi-top device that it’s running the code. For example, if run on a pi-top [4], a miniscreen attribute will be created as an interface to control the miniscreen OLED display, but that won’t be available for other pi-top devices.
The Pitop class is a Singleton. This means that only one instance per process will be created. In practice, this means that if in a particular project you instance a Pitop class in 2 different files, they will share the internal state.
- property miniscreen
If using a pi-top [4], this property returns a
pitop.miniscreen.Miniscreen
object, to interact with the device’s Miniscreen.- property oled
Refer to miniscreen.
- property battery
If using a pi-top with a battery, this property returns a
pitop.battery.Battery
object, to interact with the device’s battery.
- property own_state
Representation of an object state that will be used to determine the current state of an object.
All pi-tops come with some software-controllable onboard hardware. These sections of the API make it easy to access and change the state of your pi-top hardware.
5.1.2. Using the Pitop object
5.1.2.1. Attaching objects and saving configuration to a file
from time import sleep
from pitop import LED, Pitop
from pitop.robotics.drive_controller import DriveController
pitop = Pitop()
drive_controller = DriveController()
led = LED("D0", name="red_led")
# Add components to the Pitop object
pitop.add_component(drive_controller)
pitop.add_component(led)
# Do something with the object
pitop.red_led.on()
pitop.drive.forward(0.5)
sleep(2)
pitop.red_led.off()
pitop.drive.stop()
# Store configuration to a file
pitop.save_config("/home/pi/my_custom_config.json")
5.1.2.2. Loading an existing configuration
from time import sleep
from pitop import Pitop
# Load configuration from a previous session
pitop = Pitop.from_file("/home/pi/my_custom_config.json")
# Check the loaded configuration
print(pitop.config)
# Do something with your device
pitop.red_led.on()
pitop.drive.forward(0.5)
sleep(2)
pitop.red_led.off()
pitop.drive.stop()
# Check the state of all the components attached to the Pitop object
pitop.print_state()
5.2. pi-top Battery
This class provides a simple way to check the current onboard pi-top battery state, and handle some state change events.
This class will work with original pi-top, pi-top [3] and pi-top [4]. pi-topCEED has no onboard battery, and so will not work.
from pitop import Pitop
battery = Pitop().battery
print(f"Battery capacity: {battery.capacity}")
print(f"Battery time remaining: {battery.time_remaining}")
print(f"Battery is charging: {battery.is_charging}")
print(f"Battery is full: {battery.is_full}")
print(f"Battery wattage: {battery.wattage}")
def do_low_battery_thing():
print("Battery is low!")
def do_critical_battery_thing():
print("Battery is critically low!")
def do_full_battery_thing():
print("Battery is full!")
def do_charging_battery_thing():
print("Battery is charging!")
def do_discharging_battery_thing():
print("Battery is discharging!")
# To invoke a function when the battery changes state, you can assign the function to various 'when_' data members
battery.when_low = do_low_battery_thing
battery.when_critical = do_critical_battery_thing
battery.when_full = do_full_battery_thing
battery.when_charging = do_charging_battery_thing
battery.when_discharging = do_discharging_battery_thing
# Another way to react to battery events is to poll
while True:
if battery.is_full:
do_full_battery_thing()
5.2.1. Class Reference: pi-top Battery
5.3. pi-top Display
This class provides a simple way to check the current onboard pi-top display state, and handle state change events.
This class will work with original pi-top, pi-topCEED and pi-top [3].
Note
Not compatible with pi-top [4].
pi-top [4] has no onboard display, and the official pi-top [4] FHD Display is not software-controllable.
from signal import pause
from time import sleep
from pitop import Pitop
pitop = Pitop()
display = pitop.display
# Get display information
print(f"Display brightness: {display.brightness}")
print(f"Display blanking timeout: {display.blanking_timeout}")
print(f"Display backlight is on: {display.backlight}")
print(f"Display lid is open: {display.lid_is_open}")
# Change the brightness levels incrementally
display.increment_brightness()
display.decrement_brightness()
# Set brightness explicitly
display.brightness = 7
# Set screen blank state
display.blank()
display.unblank()
# Set screen blanking timeout (s)
display.blanking_timeout = 60
# Define some functions to call on events
def do_brightness_changed_thing(new_brightness):
print(new_brightness)
print("Display brightness has changed!")
def do_screen_blanked_thing():
print("Display is blanked!")
def do_screen_unblanked_thing():
print("Display is unblanked!")
def do_lid_closed_thing():
print("Display lid is closed!")
def do_lid_opened_thing():
print("Display lid is open!")
# 'Wire up' functions to display events
display.when_brightness_changed = do_brightness_changed_thing
display.when_screen_blanked = do_screen_blanked_thing
display.when_screen_unblanked = do_screen_unblanked_thing
display.when_lid_closed = do_lid_closed_thing
display.when_lid_opened = do_lid_opened_thing
# Wait indefinitely for events to be handled in the background
pause()
# Or alternatively poll
print("Polling for if lid is open (Original pi-top/pi-top [3] only)")
while True:
if display.lid_is_open:
do_lid_opened_thing()
sleep(0.1)
5.3.1. Class Reference: pi-top Display
5.4. pi-top [4] Miniscreen
The miniscreen of the pi-top [4] can be found on the front, comprised of an 128x64 pixel OLED screen and 4 programmable buttons.
Check out Key Concepts: pi-top [4] Miniscreen for useful information about how this class works.
5.4.1. Using the Miniscreen’s OLED Display
The OLED display is an array of pixels that can be either on or off. Unlike the pixels in a more advanced display, such as the monitor you are most likely reading this on, the display is a “1-bit monochromatic” display. Text and images can be displayed by directly manipulating the pixels.
The pitop.miniscreen.Miniscreen
class directly provides display functions for the OLED.
5.4.1.1. Displaying text
from time import sleep
from pitop import Pitop
pitop = Pitop()
miniscreen = pitop.miniscreen
miniscreen.display_multiline_text("Hello, world!", font_size=20)
sleep(5)
5.4.1.2. Showing an image
from time import sleep
from pitop import Pitop
pitop = Pitop()
miniscreen = pitop.miniscreen
miniscreen.display_image_file(
"/usr/lib/python3/dist-packages/pitop/miniscreen/images/rocket.gif"
)
sleep(2)
5.4.1.3. Loop a GIF
from PIL import Image, ImageSequence
from pitop import Pitop
pitop = Pitop()
miniscreen = pitop.miniscreen
rocket = Image.open("/usr/lib/python3/dist-packages/pitop/miniscreen/images/rocket.gif")
while True:
for frame in ImageSequence.Iterator(rocket):
miniscreen.display_image(frame)
5.4.1.4. Displaying an GIF once
from PIL import Image
from pitop import Pitop
pitop = Pitop()
miniscreen = pitop.miniscreen
rocket = Image.open("/usr/lib/python3/dist-packages/pitop/miniscreen/images/rocket.gif")
miniscreen.play_animated_image(rocket)
5.4.1.5. Displaying an GIF once through frame by frame
from PIL import Image, ImageSequence
from pitop import Pitop
pitop = Pitop()
miniscreen = pitop.miniscreen
rocket = Image.open("/usr/lib/python3/dist-packages/pitop/miniscreen/images/rocket.gif")
for frame in ImageSequence.Iterator(rocket):
miniscreen.display_image(frame)
5.4.1.6. Displaying an GIF looping in background
from time import sleep
from PIL import Image
from pitop import Pitop
pitop = Pitop()
miniscreen = pitop.miniscreen
image = Image.open("/usr/lib/python3/dist-packages/pitop/miniscreen/images/rocket.gif")
# Run animation loop in background by setting `background` to True
miniscreen.play_animated_image(image, background=True, loop=True)
# Do stuff while showing image
print("Counting to 100 while showing animated image on miniscreen...")
for i in range(100):
print("\r{}".format(i), end="", flush=True)
sleep(0.2)
print("\rFinished!")
# Stop animation
miniscreen.stop_animated_image()
5.4.1.7. Handling basic 2D graphics drawing and displaying
from PIL import Image, ImageDraw, ImageFont
from pitop import Pitop
pitop = Pitop()
miniscreen = pitop.miniscreen
image = Image.new(
miniscreen.mode,
miniscreen.size,
)
canvas = ImageDraw.Draw(image)
miniscreen.set_max_fps(1)
def clear():
canvas.rectangle(miniscreen.bounding_box, fill=0)
print("Drawing an arc")
canvas.arc(miniscreen.bounding_box, 0, 180, fill=1, width=1)
miniscreen.display_image(image)
clear()
print("Drawing an image")
# Note: this is an animated file, but this approach will only show the first frame
demo_image = Image.open(
"/usr/lib/python3/dist-packages/pitop/miniscreen/images/rocket.gif"
).convert("1")
canvas.bitmap((0, 0), demo_image, fill=1)
miniscreen.display_image(image)
clear()
print("Drawing a chord")
canvas.chord(miniscreen.bounding_box, 0, 180, fill=1)
miniscreen.display_image(image)
clear()
print("Drawing an ellipse")
canvas.ellipse(miniscreen.bounding_box, fill=1)
miniscreen.display_image(image)
clear()
print("Drawing a line")
canvas.line(miniscreen.bounding_box, fill=1)
miniscreen.display_image(image)
clear()
print("Drawing a pieslice")
canvas.pieslice(miniscreen.bounding_box, 0, 180, fill=1)
miniscreen.display_image(image)
clear()
print("Drawing a point")
canvas.point(miniscreen.bounding_box, fill=1)
miniscreen.display_image(image)
clear()
print("Drawing a polygon")
canvas.polygon(miniscreen.bounding_box, fill=1)
miniscreen.display_image(image)
clear()
print("Drawing a rectangle")
canvas.rectangle(miniscreen.bounding_box, fill=1)
miniscreen.display_image(image)
clear()
print("Drawing some text")
canvas.text((0, 0), "Hello\nWorld!", font=ImageFont.load_default(), fill=1)
miniscreen.display_image(image)
5.4.1.8. Displaying a clock
from datetime import datetime
from PIL import Image, ImageDraw
from pitop import Pitop
pitop = Pitop()
miniscreen = pitop.miniscreen
miniscreen.set_max_fps(1)
image = Image.new(
miniscreen.mode,
miniscreen.size,
)
canvas = ImageDraw.Draw(image)
bounding_box = (32, 0, 95, 63)
big_hand_box = (
bounding_box[0] + 5,
bounding_box[1] + 5,
bounding_box[2] - 5,
bounding_box[3] - 5,
)
little_hand_box = (
bounding_box[0] + 15,
bounding_box[1] + 15,
bounding_box[2] - 15,
bounding_box[3] - 15,
)
while True:
current_time = datetime.now()
# Clear
canvas.rectangle(bounding_box, fill=0)
# Draw face
canvas.ellipse(bounding_box, fill=1)
# Draw hands
angle_second = (current_time.second * 360 / 60) - 90
canvas.pieslice(big_hand_box, angle_second, angle_second + 2, fill=0)
angle_minute = (current_time.minute * 360 / 60) - 90
canvas.pieslice(big_hand_box, angle_minute, angle_minute + 5, fill=0)
angle_hour = (
(current_time.hour * 360 / 12) + (current_time.minute * 360 / 12 / 60)
) - 90
canvas.pieslice(little_hand_box, angle_hour, angle_hour + 5, fill=0)
# Display to screen
miniscreen.display_image(image)
5.4.1.9. Display a particle-based screensaver
from random import randint
from PIL import Image, ImageDraw
from pitop import Pitop
pitop = Pitop()
miniscreen = pitop.miniscreen
image = Image.new(
miniscreen.mode,
miniscreen.size,
)
canvas = ImageDraw.Draw(image)
speed_factor = 15
particles = []
class Particle:
def __init__(self, x, y):
self.x = x
self.y = y
self.update()
def get_position(self):
return (self.x, self.y)
def update(self):
dx = (
(self.x - (miniscreen.width / 2)) / speed_factor
if self.x < (miniscreen.width / 2)
else (self.x - (miniscreen.width / 2)) / speed_factor
)
dy = (
(self.y - (miniscreen.height / 2)) / speed_factor
if self.y < (miniscreen.height / 2)
else (self.y - (miniscreen.height / 2)) / speed_factor
)
self.x += dx
self.y += dy
def add_new_particle():
x = randint(0, miniscreen.width)
y = randint(0, miniscreen.height)
particles.append(Particle(x, y))
while True:
# Clear display
canvas.rectangle(miniscreen.bounding_box, fill=0)
particles.clear()
speed_factor = randint(5, 30)
particle_count = randint(5, 50)
for count in range(particle_count):
add_new_particle()
for _ in range(100):
for particle in particles:
x, y = particle.get_position()
if (x < 0 or x > miniscreen.width) or (y < 0 or y > miniscreen.height):
particles.remove(particle)
add_new_particle()
else:
canvas.point((x, y), fill=1)
particle.update()
miniscreen.display_image(image)
5.4.1.10. Prim’s algorithm
from random import randint, random
from time import sleep
from PIL import Image, ImageDraw
from pitop import Pitop
# https://en.wikipedia.org/wiki/Maze_generation_algorithm
pitop = Pitop()
miniscreen = pitop.miniscreen
image = Image.new(
miniscreen.mode,
miniscreen.size,
)
canvas = ImageDraw.Draw(image)
miniscreen.set_max_fps(50)
def draw_pixel(pos):
canvas.point(pos, fill=1)
miniscreen.display_image(image)
drawn_pixels.append(pos)
width = (miniscreen.width // 2) * 2 - 1
height = (miniscreen.height // 2) * 2 - 1
while True:
print("Initialising...")
canvas.rectangle(miniscreen.bounding_box, fill=0)
drawn_pixels = list()
complexity = int(random() * (5 * (width + height)))
density = int(random() * ((width // 2) * (height // 2)))
print("Drawing the borders...")
for x in range(width):
draw_pixel((x, 0))
draw_pixel((x, (height // 2) * 2))
for y in range(height):
draw_pixel((0, y))
draw_pixel(((width // 2) * 2, y))
print("Filling the maze...")
for i in range(density):
x, y = randint(0, width // 2) * 2, randint(0, height // 2) * 2
if (x, y) not in drawn_pixels:
draw_pixel((x, y))
for j in range(complexity):
neighbours = []
if x > 1:
neighbours.append((x - 2, y))
if x < width - 3:
neighbours.append((x + 2, y))
if y > 1:
neighbours.append((x, y - 2))
if y < height - 3:
neighbours.append((x, y + 2))
if len(neighbours):
x_, y_ = neighbours[randint(0, len(neighbours) - 1)]
if (x_, y_) not in drawn_pixels:
draw_pixel((x_, y_))
draw_pixel((x_ + (x - x_) // 2, y_ + (y - y_) // 2))
x, y = x_, y_
print("Done!")
sleep(10)
5.4.1.11. 2-Player Pong Game
from random import randrange
from time import sleep
from PIL import Image, ImageDraw, ImageFont
from pitop import Pitop
# Game variables
BALL_RADIUS = 2
PADDLE_SIZE = (2, 20)
PADDLE_CTRL_VEL = 4
class Ball:
def __init__(self):
self.pos = [0, 0]
self.vel = [0, 0]
# 50/50 chance of direction
self.init(move_right=randrange(0, 2) == 0)
def init(self, move_right):
self.pos = [miniscreen.width // 2, miniscreen.height // 2]
horz = randrange(1, 3)
vert = randrange(1, 3)
if move_right is False:
horz = -horz
self.vel = [horz, -vert]
@property
def x_pos(self):
return self.pos[0]
@property
def y_pos(self):
return self.pos[1]
def is_aligned_with_paddle_horizontally(self, paddle):
return abs(self.x_pos - paddle.x_pos) <= BALL_RADIUS + PADDLE_SIZE[0] // 2
def is_aligned_with_paddle_vertically(self, paddle):
return abs(self.y_pos - paddle.y_pos) <= BALL_RADIUS + PADDLE_SIZE[1] // 2
def is_touching_paddle(self, paddle):
hor = self.is_aligned_with_paddle_horizontally(paddle)
ver = self.is_aligned_with_paddle_vertically(paddle)
return hor and ver
@property
def is_touching_vertical_walls(self):
return (
self.y_pos <= BALL_RADIUS
or self.y_pos >= miniscreen.height + 1 - BALL_RADIUS
)
def change_direction(self, change_x=False, change_y=False, speed_factor=1.0):
x_vel = -self.vel[0] if change_x else self.vel[0]
self.vel[0] = speed_factor * x_vel
y_vel = -self.vel[1] if change_y else self.vel[1]
self.vel[1] = speed_factor * y_vel
def update(self):
self.pos = [x + y for x, y in zip(self.pos, self.vel)]
if self.is_touching_vertical_walls:
self.change_direction(change_y=True, speed_factor=1.0)
@property
def bounding_box(self):
def get_circle_bounds(center, radius):
x0 = center[0] - radius
y0 = center[1] - radius
x1 = center[0] + radius
y1 = center[1] + radius
return (x0, y0, x1, y1)
return get_circle_bounds(self.pos, BALL_RADIUS)
class Paddle:
def __init__(self, start_pos=[0, 0]):
self.pos = start_pos
self.vel = 0
self.score = 0
def increase_score(self):
self.score += 1
@property
def x_pos(self):
return self.pos[0]
@property
def y_pos(self):
return self.pos[1]
@y_pos.setter
def y_pos(self, new_y):
self.pos[1] = new_y
@property
def touching_top(self):
return self.y_pos - PADDLE_SIZE[1] // 2 <= 0
@property
def touching_bottom(self):
return self.y_pos + PADDLE_SIZE[1] // 2 >= miniscreen.height - 1
def update(self):
moving_down = self.vel > 0
if self.touching_top and not moving_down:
return
if self.touching_bottom and moving_down:
return
self.y_pos += self.vel
if self.touching_top:
self.y_pos = PADDLE_SIZE[1] // 2
if self.touching_bottom:
self.y_pos = miniscreen.height - PADDLE_SIZE[1] // 2 - 1
@property
def bounding_box(self):
return (
self.x_pos,
self.y_pos - PADDLE_SIZE[1] // 2,
self.x_pos,
self.y_pos + PADDLE_SIZE[1] // 2,
)
def update_button_state():
down_pressed = miniscreen.down_button.is_pressed
up_pressed = miniscreen.up_button.is_pressed
select_pressed = miniscreen.select_button.is_pressed
cancel_pressed = miniscreen.cancel_button.is_pressed
if down_pressed == up_pressed:
l_paddle.vel = 0
elif down_pressed:
l_paddle.vel = PADDLE_CTRL_VEL
elif up_pressed:
l_paddle.vel = -PADDLE_CTRL_VEL
if select_pressed == cancel_pressed:
r_paddle.vel = 0
elif select_pressed:
r_paddle.vel = PADDLE_CTRL_VEL
elif cancel_pressed:
r_paddle.vel = -PADDLE_CTRL_VEL
def update_positions():
round_finished = False
l_paddle.update()
r_paddle.update()
ball.update()
paddles = {l_paddle, r_paddle}
for paddle in paddles:
if ball.is_aligned_with_paddle_horizontally(paddle):
if ball.is_touching_paddle(paddle):
ball.change_direction(change_x=True, speed_factor=1.1)
else:
other_paddle = paddles - {paddle}
other_paddle = other_paddle.pop()
other_paddle.increase_score()
ball.init(move_right=other_paddle == r_paddle)
paddle.y_pos = miniscreen.height // 2
other_paddle.y_pos = miniscreen.height // 2
round_finished = True
break
return round_finished
def draw(wait=False):
canvas = ImageDraw.Draw(image)
# Clear screen
canvas.rectangle(miniscreen.bounding_box, fill=0)
# Draw ball
canvas.ellipse(ball.bounding_box, fill=1)
# Draw paddles
canvas.line(l_paddle.bounding_box, fill=1, width=PADDLE_SIZE[0])
canvas.line(r_paddle.bounding_box, fill=1, width=PADDLE_SIZE[0])
# Draw score
font = ImageFont.truetype("VeraMono.ttf", size=12)
canvas.multiline_text(
(1 * miniscreen.width // 3, 2),
str(l_paddle.score),
fill=1,
font=font,
align="center",
)
canvas.multiline_text(
(2 * miniscreen.width // 3, 2),
str(r_paddle.score),
fill=1,
font=font,
align="center",
)
# Display image
miniscreen.display_image(image)
if wait:
sleep(1.5)
# Internal variables
pitop = Pitop()
miniscreen = pitop.miniscreen
miniscreen.set_max_fps(30)
ball = Ball()
l_paddle = Paddle([PADDLE_SIZE[0] // 2 - 1, miniscreen.height // 2])
r_paddle = Paddle([miniscreen.width - 1 - PADDLE_SIZE[0] // 2, miniscreen.height // 2])
image = Image.new(
miniscreen.mode,
miniscreen.size,
)
def main():
while True:
update_button_state()
draw(update_positions())
if __name__ == "__main__":
main()
5.4.2. Class Reference: pi-top [4] Miniscreen
- class pitop.miniscreen.Miniscreen[source]
Represents a pi-top [4]’s miniscreen display.
Also owns the surrounding 4 buttons as properties (
up_button
,down_button
,select_button
,cancel_button
). Seepitop.miniscreen.miniscreen.MiniscreenButton
for how to use these buttons.- property is_active
Determine if the current miniscreen instance is in control of the miniscreen hardware.
- Returns:
whether the miniscreen instance is in control of the miniscreen hardware.
- Return type:
- property up_button
Gets the up button of the pi-top [4] miniscreen.
- Returns:
A gpiozero-like button instance representing the up button of the pi-top [4] miniscreen.
- Return type:
- property down_button
Gets the down button of the pi-top [4] miniscreen.
- Returns:
A gpiozero-like button instance representing the down button of the pi-top [4] miniscreen.
- Return type:
- property select_button
Gets the select button of the pi-top [4] miniscreen.
- Returns:
A gpiozero-like button instance representing the select button of the pi-top [4] miniscreen.
- Return type:
- property cancel_button
Gets the cancel button of the pi-top [4] miniscreen.
- Returns:
A gpiozero-like button instance representing the cancel button of the pi-top [4] miniscreen.
- Return type:
- property when_user_controlled
Function to call when user takes control of the miniscreen.
This is used by pt-miniscreen to update its ‘user-controlled’ application state.
- property when_system_controlled
Function to call when user gives back control of the miniscreen to the system.
This is used by pt-miniscreen to update its ‘user-controlled’ application state.
- property bottom_left
Gets the bottom-left corner of the miniscreen display.
- Returns:
The coordinates of the bottom left of the display’s bounding box as an (x,y) tuple.
- Return type:
- property bottom_right
Gets the bottom-right corner of the miniscreen display.
- Returns:
The coordinates of the bottom right of the display’s bounding box as an (x,y) tuple.
- Return type:
- property bounding_box
Gets the bounding box of the miniscreen display.
- Returns:
The device’s bounding box as an (top-left x, top-left y, bottom-right x, bottom-right y) tuple.
- Return type:
- property center
Gets the center of the miniscreen display.
- Returns:
The coordinates of the center of the display’s bounding box as an (x,y) tuple.
- Return type:
- clear()
Clears any content displayed in the miniscreen display.
- contrast(new_contrast_value)
Sets the contrast value of the miniscreen display to the provided value.
- Parameters:
new_contrast_value (int) – contrast value to set, between 0 and 255.
- property device
Gets the miniscreen display device instance.
- Return type:
pitop.miniscreen.oled.core.contrib.luma.oled.device.sh1106
- display(force=False)
Displays what is on the current canvas to the screen as a single frame.
Warning
This method is deprecated and will be deleted on the next major release of the SDK.
This method does not need to be called when using the other draw functions in this class, but is used when the caller wants to use the canvas object to draw composite objects and then render them to screen in a single frame.
- display_image(image, xy=None, invert=False)
Render a static image to the screen from a file or URL at a given position.
The image should be provided as a PIL Image object.
- display_image_file(file_path_or_url, xy=None, invert=False)
Render a static image to the screen from a file or URL at a given position.
The display’s positional properties (e.g. top_left, top_right) can be used to assist with specifying the xy position parameter.
- display_multiline_text(text, xy=None, font_size=None, font=None, invert=False, anchor=None, align=None)
Renders multi-lined text to the screen at a given position and size. Text that is too long for the screen will automatically wrap to the next line.
The display’s positional properties (e.g. top_left, top_right) can be used to assist with specifying the xy position parameter.
- Parameters:
text (string) – The text to render
xy (tuple) – The position on the screen to render the image. If not provided or passed as None the image will be drawn in the top-left of the screen.
font_size (int) – The font size in pixels. If not provided or passed as None, the default font size will be used
font (string) – A filename or path of a TrueType or OpenType font. If not provided or passed as None, the default font will be used
invert (bool) – Set to True to flip the on/off state of each pixel in the image
align (str) – PIL ImageDraw alignment to use
anchor (str) – PIL ImageDraw text anchor to use
- display_text(text, xy=None, font_size=None, font=None, invert=False, align=None, anchor=None)
Renders a single line of text to the screen at a given position and size.
The display’s positional properties (e.g. top_left, top_right) can be used to assist with specifying the xy position parameter.
- Parameters:
text (string) – The text to render
xy (tuple) – The position on the screen to render the image. If not provided or passed as None the image will be drawn in the top-left of the screen.
font_size (int) – The font size in pixels. If not provided or passed as None, the default font size will be used
font (string) – A filename or path of a TrueType or OpenType font. If not provided or passed as None, the default font will be used
invert (bool) – Set to True to flip the on/off state of each pixel in the image
align (str) – PIL ImageDraw alignment to use
anchor (str) – PIL ImageDraw text anchor to use
- draw()
warning:: This method is deprecated in favor of
display_image()
anddisplay_text()
, and will be deleted on the next major release of the SDK.
- draw_image(image, xy=None)
warning:: This method is deprecated in favor of
display_image()
, and will be deleted on the next major release of the SDK.
- draw_image_file(file_path_or_url, xy=None)
warning:: This method is deprecated in favor of
display_image_file()
, and will be deleted on the next major release of the SDK.
- draw_multiline_text(text, xy=None, font_size=None)
warning:: This method is deprecated in favor of
display_multiline_text()
, and will be deleted on the next major release of the SDK.
- draw_text(text, xy=None, font_size=None)
warning:: This method is deprecated in favor of
display_text()
, and will be deleted on the next major release of the SDK.
- hide()
The miniscreen display is put into low power mode.
The previously shown image will re-appear when show() is given, even if the internal frame buffer has been changed (so long as display() has not been called).
- property mode
- play_animated_image(image, background=False, loop=False)
Render an animation or a image to the screen.
Use stop_animated_image() to end a background animation
- play_animated_image_file(file_path_or_url, background=False, loop=False)
Render an animated image to the screen from a file or URL.
- prepare_image(image_to_prepare)
Formats the given image into one that can be used directly by the OLED.
- Parameters:
image_to_prepare (
PIL.Image.Image
) – Image to be formatted.- Return type:
- refresh()
- reset(force=True)
Gives the caller access to the miniscreen display (i.e. in the case the system is currently rendering information to the screen) and clears the screen.
- set_control_to_hub()
Signals the pi-top hub to take control of the miniscreen display.
- set_control_to_pi()
Signals the pi-top hub to give control of the miniscreen display to the Raspberry Pi.
- set_max_fps(max_fps)
Set the maximum frames per second that the miniscreen display can display. This method can be useful to control or limit the speed of animations.
This works by blocking on the OLED’s display methods if called before the amount of time that a frame should last is not exceeded.
- Parameters:
max_fps (int) – The maximum frames that can be rendered per second
- should_redisplay(image_to_display=None)
Determines if the miniscreen display needs to be refreshed, based on the provided image. If no image is provided, the content of the display’s deprecated internal canvas property will be used.
- Parameters:
image_to_display (
PIL.Image.Image
or None) – Image to be displayed.- Return type:
- show()
The miniscreen display comes out of low power mode showing the previous image shown before hide() was called (so long as display() has not been called)
- property size
Gets the size of the miniscreen display as a (width, height) tuple.
- Return type:
- sleep()
The miniscreen display in set to low contrast mode, without modifying the content of the screen.
- property spi_bus
Gets the SPI bus used by the miniscreen display to receive data as an integer. Setting this property will modify the SPI bus that the OLED uses. You might notice a flicker in the screen.
- Parameters:
bus (int) – Number of the SPI bus for the OLED to use. Accepted values are 0 or 1.
- stop_animated_image()
Stop background animation started using start(), if currently running.
- property top_left
Gets the top left corner of the miniscreen display.
- Returns:
The coordinates of the center of the display’s bounding box as an (x,y) tuple.
- Return type:
- property top_right
Gets the top-right corner of the miniscreen display.
- Returns:
The coordinates of the top right of the display’s bounding box as an (x,y) tuple.
- Return type:
- property visible
Gets whether the device is currently in low power state.
- Returns:
whether the screen is in low power mode
- Return type:
- wake()
The miniscreen display is set to high contrast mode, without modifying the content of the screen.