Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Badger2040 Micropython battery improvements #313

Merged
merged 33 commits into from
Mar 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
51b0e47
Add ability to halt the Badger from Micropython and get wake button p…
MichaelBell Mar 23, 2022
78c11d2
Enable battery power on wake, expose pressed_to_wake on Badger object
MichaelBell Mar 23, 2022
a901064
Use halt in image app
MichaelBell Mar 23, 2022
40d22a0
Appease the linter
MichaelBell Mar 23, 2022
a0baae3
Once more with a very long line
MichaelBell Mar 23, 2022
c41714c
Actually enable 3v3 at startup
MichaelBell Mar 24, 2022
946de6f
Take Gadgetoid's proposed change, reduce magic
MichaelBell Mar 24, 2022
a7f2014
Add woken method
MichaelBell Mar 24, 2022
0ab44ef
Only record front button state at init time
MichaelBell Mar 24, 2022
5bd13a5
Badger2040: Create badger_os utils module.
Gadgetoid Mar 24, 2022
fe943a0
Include USER button in button state
MichaelBell Mar 24, 2022
994ddba
Badge, image and launcher all now sleep when on battery
MichaelBell Mar 25, 2022
e19fe9c
Apparently Thonny doesn't clear blank lines on save
MichaelBell Mar 25, 2022
d313a9d
Quit app on A+C pressed using an interrupt handler.
MichaelBell Mar 25, 2022
f332dcd
Remove unused clear_pressed_to_wake method
MichaelBell Mar 25, 2022
b1fd893
Badger2040: Enforce minimum update blocking time.
Gadgetoid Mar 25, 2022
a23cc59
Badger2040: Use Act LED. Avoid recreating files on every load.
Gadgetoid Mar 25, 2022
a862a6d
Badger2040: Use Act LED in Launcher
Gadgetoid Mar 25, 2022
d3c8811
Badger2040: Fixup examples for Act LED and A+C to exit.
Gadgetoid Mar 25, 2022
b8d5a3d
Badger2040: Bring back clear pressed to wake.
Gadgetoid Mar 25, 2022
b85792f
Badger2040: JSON app state.
Gadgetoid Mar 25, 2022
6dee15a
Badger2040: ebook now uses badger_os
MichaelBell Mar 25, 2022
eb2e55b
I learn how to run the linter locally
MichaelBell Mar 25, 2022
1f1f9b0
Badger2040: Light the act LED immediately on wake
MichaelBell Mar 25, 2022
75d0112
Badger2040: Wait for buttons to be released. Rename woken.
Gadgetoid Mar 25, 2022
5c2cc7e
Badger2040: Improve launcher.
Gadgetoid Mar 25, 2022
b497422
Badger2040: Remove button release wait from clear.
Gadgetoid Mar 25, 2022
3042191
Badger2040: Fix exit to launcher.
Gadgetoid Mar 25, 2022
88dd6e6
Badger2040: qrgen now halts
MichaelBell Mar 25, 2022
be0f135
Merge remote-tracking branch 'origin/MichaelBell-battery-improvements…
MichaelBell Mar 25, 2022
47122d9
Badger2040: fonts uses new framwork, clock more reactive to buttons
MichaelBell Mar 25, 2022
e0e34fe
Badger2040: Put state files in their own directory to keep things tidy
MichaelBell Mar 25, 2022
72ff77a
Badger2040: Sleep after writing the book, to fix possible write delay…
MichaelBell Mar 25, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions drivers/uc8151/uc8151.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,8 @@ namespace pimoroni {
void UC8151::setup(uint8_t speed) {
reset();

_update_speed = speed;

if(speed == 0) {
command(PSR, {
RES_128x296 | LUT_OTP | FORMAT_BW | SHIFT_RIGHT | BOOSTER_ON | RESET_NONE
Expand Down Expand Up @@ -468,6 +470,25 @@ namespace pimoroni {
setup(speed);
}

uint8_t UC8151::update_speed() {
return _update_speed;
}

uint32_t UC8151::update_time() {
switch(_update_speed) {
case 0:
return 5500;
case 1:
return 2600;
case 2:
return 1000;
case 3:
return 300;
default:
return 5500;
}
}

void UC8151::partial_update(int x, int y, int w, int h, bool blocking) {
// y is given in columns ("banks"), which are groups of 8 horiontal pixels
// x is given in pixels
Expand Down
4 changes: 4 additions & 0 deletions drivers/uc8151/uc8151.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ namespace pimoroni {

bool inverted = false;

uint8_t _update_speed = 0;

public:
UC8151(uint16_t width, uint16_t height) :
width(width), height(height), frame_buffer(new uint8_t[width * height / 8]) {
Expand Down Expand Up @@ -199,6 +201,8 @@ namespace pimoroni {

void invert(bool invert);
void update_speed(uint8_t speed);
uint8_t update_speed();
uint32_t update_time();
void update(bool blocking = true);
void partial_update(int x, int y, int w, int h, bool blocking = true);
void off();
Expand Down
9 changes: 7 additions & 2 deletions libraries/badger2040/badger2040.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ namespace pimoroni {

gpio_set_function(USER, GPIO_FUNC_SIO);
gpio_set_dir(USER, GPIO_IN);
gpio_set_pulls(USER, false, true);
gpio_set_pulls(USER, true, false);

gpio_set_function(VBUS_DETECT, GPIO_FUNC_SIO);
gpio_set_dir(VBUS_DETECT, GPIO_IN);
Expand Down Expand Up @@ -195,8 +195,9 @@ namespace pimoroni {
}

void Badger2040::update_button_states() {
uint32_t mask = (1UL << A) | (1UL << B) | (1UL << C) | (1UL << D) | (1UL << E);
uint32_t mask = (1UL << A) | (1UL << B) | (1UL << C) | (1UL << D) | (1UL << E) | (1UL << USER);
_button_states = gpio_get_all() & mask;
_button_states ^= (1UL << USER); // USER button state is inverted
}

uint32_t Badger2040::button_states() {
Expand All @@ -219,6 +220,10 @@ namespace pimoroni {
uc8151.update_speed(speed);
}

uint32_t Badger2040::update_time() {
return uc8151.update_time();
}

void Badger2040::partial_update(int x, int y, int w, int h, bool blocking) {
uc8151.partial_update(x, y, w, h, blocking);
}
Expand Down
1 change: 1 addition & 0 deletions libraries/badger2040/badger2040.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ namespace pimoroni {
void update(bool blocking=false);
void partial_update(int x, int y, int w, int h, bool blocking=false);
void update_speed(uint8_t speed);
uint32_t update_time();
void halt();
void sleep();
bool is_busy();
Expand Down
112 changes: 14 additions & 98 deletions micropython/examples/badger2040/badge.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import badger2040
import machine
import time
import badger2040
import badger_os

# Global Constants
WIDTH = badger2040.WIDTH
Expand All @@ -20,10 +20,6 @@
NAME_PADDING = 20
DETAIL_SPACING = 10

OVERLAY_BORDER = 40
OVERLAY_SPACING = 20
OVERLAY_TEXT_SIZE = 0.6

DEFAULT_TEXT = """mustelid inc
H. Badger
RP2040
Expand Down Expand Up @@ -63,42 +59,6 @@ def truncatestring(text, text_size, width):
# Drawing functions
# ------------------------------

# Draw an overlay box with a given message within it
def draw_overlay(message, width, height, line_spacing, text_size):

# Draw a light grey background
display.pen(12)
display.rectangle((WIDTH - width) // 2, (HEIGHT - height) // 2, width, height)

# Take the provided message and split it up into
# lines that fit within the specified width
words = message.split(" ")
lines = []
line = ""
appended_line = ""
for word in words:
if len(word) > 0:
appended_line += " "
appended_line += word
if display.measure_text(appended_line, text_size) >= width:
lines.append(line)
appended_line = word
else:
line = appended_line
if len(line) != 0:
lines.append(line)

display.pen(0)
display.thickness(2)

# Display each line of text from the message, centre-aligned
num_lines = len(lines)
for i in range(num_lines):
length = display.measure_text(lines[i], text_size)
current_line = (i * line_spacing) - ((num_lines - 1) * line_spacing) // 2
display.text(lines[i], (WIDTH - length) // 2, (HEIGHT // 2) + current_line, text_size)


# Draw the badge, including user text
def draw_badge():
display.pen(0)
Expand Down Expand Up @@ -170,21 +130,19 @@ def draw_badge():
# Program setup
# ------------------------------

# Global variables
show_overlay = False

# Create a new Badger and set it to update NORMAL
display = badger2040.Badger2040()
display.led(128)
display.update_speed(badger2040.UPDATE_NORMAL)

# Open the badge file
try:
badge = open("badge.txt", "r")
except OSError:
badge = open("badge.txt", "w")
badge.write(DEFAULT_TEXT)
badge.flush()
badge.seek(0)
with open("badge.txt", "w") as f:
f.write(DEFAULT_TEXT)
f.flush()
badge = open("badge.txt", "r")

# Read in the next 6 lines
company = badge.readline() # "mustelid inc"
Expand All @@ -205,63 +163,21 @@ def draw_badge():
detail2_text = truncatestring(detail2_text, DETAILS_TEXT_SIZE,
TEXT_WIDTH - DETAIL_SPACING - display.measure_text(detail2_title, DETAILS_TEXT_SIZE))

# Set up the buttons
button_a = machine.Pin(badger2040.BUTTON_A, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_b = machine.Pin(badger2040.BUTTON_B, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_c = machine.Pin(badger2040.BUTTON_C, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_up = machine.Pin(badger2040.BUTTON_UP, machine.Pin.IN, machine.Pin.PULL_DOWN)
button_down = machine.Pin(badger2040.BUTTON_DOWN, machine.Pin.IN, machine.Pin.PULL_DOWN)


# Button handling function
def button(pin):
global show_overlay

if pin == button_a:
show_overlay = True
return

if pin == button_b:
show_overlay = True
return

if pin == button_c:
show_overlay = True
return

if pin == button_up:
show_overlay = True
return

if pin == button_down:
show_overlay = True
return


# Register the button handling function with the buttons
button_a.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
button_b.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
button_c.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
button_up.irq(trigger=machine.Pin.IRQ_RISING, handler=button)
button_down.irq(trigger=machine.Pin.IRQ_RISING, handler=button)


# ------------------------------
# Main program loop
# Main program
# ------------------------------

draw_badge()
display.update()

while True:
if show_overlay:
draw_overlay("To change the text, connect Badger2040 to a PC, load up Thonny, and modify badge.txt",
WIDTH - OVERLAY_BORDER, HEIGHT - OVERLAY_BORDER, OVERLAY_SPACING, OVERLAY_TEXT_SIZE)
display.update()
if display.pressed(badger2040.BUTTON_A) or display.pressed(badger2040.BUTTON_B) or display.pressed(badger2040.BUTTON_C) or display.pressed(badger2040.BUTTON_UP) or display.pressed(badger2040.BUTTON_DOWN):
badger_os.warning(display, "To change the text, connect Badger2040 to a PC, load up Thonny, and modify badge.txt")
time.sleep(4)

draw_badge()
display.update()
show_overlay = False

time.sleep(0.1)
display.update()

# If on battery, halt the Badger to save power, it will wake up if any of the front buttons are pressed
display.halt()
Loading