Version v2.0.0
Change All The Things
This release includes a significant leap toward making apps easier to write for Badgeware. We've removed the hard requirement to define an update function, and exposed more of the internals to - hopefully - let you write apps in a way that's more familiar to you. You'll need to make some changes to your own apps to make them work with this release. You can find more info on how to do this below, but in most cases you can just unconditionally call run(update) at the end of your apps __init__.py.
Note that mode() is now badge.mode() and button handling like BUTTON_A in io.pressed should now be BUTTON_A in badge.pressed() or button.pressed(BUTTON_A).
with-filesystem build since there are breaking changes which require the apps to be updated. Back up your filesystem first!
Release Notes
Building upon the shipping firmware we've made many changes to the shape and
function of the Badgeware API. A lot of these changes are breaking, and you
will have to update your code for this release.
Bugfixes
FAT Filesystem Corruption
Users were encountering problems with the FAT "/system" partition spontaneously
erasing itself. This usually presents as the badge becoming unresponsive, with
Badger in particular showing the same screen (since it's never updated again.)
After much deliberation I realised we're setting the filesystem label every
time the board boots. This means there's a write to the FAT filesystem which
could potentially go wrong†. This is now removed, with the label set in the
filesystem image instead. This should ensure a more robust filesystem.
† - by wrong, I mean that a flash write starts with a block erase and if your
board resets between the erase and the new data being written then you have
a 4k empty block where there should have been 1/4th of file allocation table.
Other Bugfixes
- Fix the right-hand edge of some vector shapes being cut off
- Fix image blit overflow
- Fix a sleep bug to decrease quiescent current
Changes
Running Apps
Our update loop setup for apps worked very well for games, and terribly for
everything else. We've heard your troubles with this approach, and had some
of our own.
launch has now been split into launch, which accepts a file path and loads
an app, and run which runs an update function, or any other function, in
either a continuous loop or one with a duration.
All apps now own their main loops, so you can simply while True your way to
app nirvana (at least on Blinky and Tufty, Badger is a whole different animal.)
To update your existing update based apps, you just need to add:
run(update)To the bottom of your __init__.py. If you've already got a Thonny fixup:
from badgeware import run
...
if __name__ == "__main___":
run(update)Then delete it and swap it to the above.
run will run a function for you, handling the clear, update and poll calls
needed to keep Badgeware ticking. You don't have to use it, though, and can
call the new badge.update() function to update, clear and poll, or call
screen.update(), badge.clear() and badge.poll() separately. Up to you!
A typical main loop might look like this:
while True:
# Do stuff
badge.update()You can now also access the buttons like they were ordinary MicroPython Pin
objects (because they are) so BUTTON_A.value() will give you the current
raw status of a button (0 when pressed) regardless of polling.
Badger
Since a display update is so costly on Badger, it works a little different
from the other boards. You can still run() your update function, but you
must call badge.update() to update the display when you want to.
You may also call wait_for_button_or_alarm(timeout=5000) which will sit in
a loop calling badge.poll() and waiting for a button press or an alarm
interrupt. After the timeout time (in ticks/milliseconds) your badge will go
into deep sleep to conserve battery. This timeout can be as long as you feel
is necessary for your app, or None to never automatically sleep.
Note: Badger will not sleep while connected to power!
To update an existing app, you would do:
def update():
...
badge.update()
wait_for_button_or_alarm(timeout=5000)
run(update)Badger also gets a new NON_BLOCKING mode flag, letting you update the display
asynchronously. We've deployed this in the Menu, making it feel more responsive.
General
- Output an error message if
/system/main.pyis missing - Output an error message if
/systemfails to mount
Drawing
color.blackandcolor.whiteare now set to pure black/white on Badger and Blinky- The builtin
pen()has been removed, usescreen.pen = v
Advanced Drawing
vspan_texis nowblit_vspanand we have a newblit_hspancounterpart.- A new multi-ray
raycastalgorithm, and a single-raydda
Builtin Functions
free()is now a builtin (call to show the memory delta)run()is now a builtin, and can take a filename, eg:run("/system/apps/menu")
Badge (formerly known as io)
iois nowbadgeand some straggler functions have been moved to badge:io.tickstobadge.ticksio.ticks_deltatobadge.ticks_deltabadgeware.get_battery_level()is nowbadge.battery_level()badgeware.is_charging()is nowbadge.is_charging()badge.model(new) returns "tufty", "blinky" or "badger" depending on the board.badge.uidreturns the board UID (hex) as an ASCII string.set_caselights()is nowbadge.caselights(), and caselights are gamma corrected.badge.first_update(Badger only)mode()is nowbadge.mode()mode()now supportsVSYNC† (Tufty only)badgeware.get_disk_usage()moved tobadge.disk_free()and now returns total, used and free in bytes- new
badge.default_clearandbadge.default_pento control the update better
† - Avoiding VSYNC will normally give you a better framerate where your app logic takes over ~8ms, since you wont be missing entire VSYNC periods and having to wait up to 16.6ms. Using VSYNC will fix screen tearing at the cost of raw framerate. Currently display.update() on Tufty blocks for around 7.7ms leaving you only 8ms for logic/drawing. To enable VSYNC when changing mode use badge.mode(HIRES | VSYNC) or badge.mode(LORES | VSYNC)
Images
SpriteSheetandAnimatedSpriteare now builtin, you need not- PNG now supports images up to 2048 pixels wide
- JPEG image support
- Loading images from RAM/buffer, eg:
image.load(open("image.jpg", "rb").read()) - Both JPEG and PNG images support downsizing on load
my_image = image.load(filename, max_width, max_height)
RTC
rtcnow has its own module.
Text
Both vector and pixel fonts now support UTF-8 codepoints, a fairly critical omission
from our shipping firmware- you can now use the degrees symbol and much, much more.
Advanced text layout functions have been moved to text, a builtin providing:
text.scroll()which has been modified heavily fromscroll_text()text.tokenise()text.draw()which should now return the correct bounds
Two new ROM fonts have been added:
badgewarebadgewaremax
The font yolk has been updated with better language support.
Technical Stuff
- Fix display update stability at some overclocks (Tufty only)
- Switched
MICROPY_OBJ_REPRtoMICROPY_OBJ_REPR_C, which is slightly faster at the cost of RAM - Set the VID and PID of each board to match our assigned values.
What's Changed
- Add README by @Gadgetoid in #7
- Development by @Gadgetoid in #13
Full Changelog: v1.0.0...v2.0.0