Skip to content

Releases: pimoroni/blinky2350

Version 2.0.2

10 Apr 14:21

Choose a tag to compare

Bugfixes & Improvements

This is a maintenance release to fix some bugs and quirks in PicoVector.

PicoVector

Fixes and Improvements:

  • Support for copying rects, eg: rect(old_rect) will produce a copy.
  • Support for in-place modification of rects, eg: rect(old_rect).inflate(10) will copy and inflate a rect.
  • Wider support for vec2 and rect as arguments. eg: mat3()translate(vec2), shape.rectangle(rect) and shape.regular_polygon(vec2, ...)
  • Add a default font size of 12 to text() for vector fonts.
  • Fix clipping when drawing spans, drawing a raster circle (screen.circle()) would fail to clip to the upper/left bounds of screen.clip()

vec2 arg support

  • shape.line() now supports shape.line(vec2 a, vec2 b)
  • shape.star() now supports shape.star(vec2, ...)
  • shape.pie() now supports shape.pie(vec2, ...)
  • shape.arc() now supports shape.arc(vec2, ...)
  • shape.squircle() now supports shape.squircle(vec2, ...)
  • shape.rectangle() now supports shape.rectangle(rect, ...)
  • shape.rounded_rectangle() now supports shape.rounded_rectangle(rect, ...)

What's Changed

Full Changelog: v2.0.1...v2.0.2

Version 2.0.1

26 Feb 17:00

Choose a tag to compare

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

⚠️ 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.1

Version v2.0.0

26 Feb 13:21

Choose a tag to compare

Version v2.0.0 Pre-release
Pre-release

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

⚠️ We're experiencing trouble with the (CI builds of) Blinky v2.0.0 firmware, causing it to work intermittently or not at all. We've investigating and downloads have been removed for now.

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

⚠️ 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

v1.0.0 - Shipping Firmware

27 Jan 16:07

Choose a tag to compare

Take the Adventure, heed the call, now ere the irrevocable moment passes!’ ‘Tis but a banging of the door behind you, a blithesome step forward, and you are out of the old life and into the new! Then some day, some day long hence, jog home here if you will, when the cup has been drained and the play has been played, and sit down by your quiet river with a store of goodly memories for company.