Skip to content

Version v2.0.0

Choose a tag to compare

@Gadgetoid Gadgetoid released this 26 Feb 13:21
· 3 commits to main since this release

Change All The Things

⚠️ See https://github.com/pimoroni/badger2350/releases/tag/v2.0.1

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).

⚠️ You will need to flash the 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.py is missing
  • Output an error message if /system fails to mount

Drawing

  • color.black and color.white are now set to pure black/white on Badger and Blinky
  • The builtin pen() has been removed, use screen.pen = v

Advanced Drawing

  • vspan_tex is now blit_vspan and we have a new blit_hspan counterpart.
  • A new multi-ray raycast algorithm, and a single-ray dda

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)

  • io is now badge and some straggler functions have been moved to badge:
    • io.ticks to badge.ticks
    • io.ticks_delta to badge.ticks_delta
    • badgeware.get_battery_level() is now badge.battery_level()
    • badgeware.is_charging() is now badge.is_charging()
    • badge.model (new) returns "tufty", "blinky" or "badger" depending on the board.
    • badge.uid returns the board UID (hex) as an ASCII string.
    • set_caselights() is now badge.caselights(), and caselights are gamma corrected.
    • badge.first_update (Badger only)
    • mode() is now badge.mode()
    • mode() now supports VSYNC† (Tufty only)
    • badgeware.get_disk_usage() moved to badge.disk_free() and now returns total, used and free in bytes
    • new badge.default_clear and badge.default_pen to 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

  • SpriteSheet and AnimatedSprite are 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

  • rtc now 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 from scroll_text()
  • text.tokenise()
  • text.draw() which should now return the correct bounds

Two new ROM fonts have been added:

  • badgeware
  • badgewaremax

The font yolk has been updated with better language support.

Technical Stuff

  • Fix display update stability at some overclocks (Tufty only)
  • Switched MICROPY_OBJ_REPR to MICROPY_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

Full Changelog: v1.0.0...v2.0.0