Skip to content

Commit

Permalink
Merge pull request #313 from MichaelBell/battery-improvements
Browse files Browse the repository at this point in the history
Badger2040 Micropython battery improvements
  • Loading branch information
Gadgetoid committed Mar 25, 2022
2 parents 938134b + 72ff77a commit 522c83d
Show file tree
Hide file tree
Showing 19 changed files with 629 additions and 464 deletions.
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

0 comments on commit 522c83d

Please sign in to comment.