MicroPython

From Badge team
Revision as of 17:08, 23 August 2019 by SynQ (talk | contribs) (Putting outdated banner on top of page and updating buzzer info)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

This page is hugely outdated by the newer firmware versions starting July 2019, we are working on updating everything. If you want to help, please do!

Introduction[edit]

This page details the MicroPython libraries and functions specific to the environment on your badge.team badge. If you are a seasoned MicroPython coder and are familiar with badge development, this should provide the introduction you need.

But I'm new here! Help, what do I do![edit]

Our firmware supports apps, which we refer to as eggs. We encourage you to write your own eggs in MicroPython, and to that end we've produced some tutorials aimed at the first-time egg developer.

MicroPython[edit]

Specific badge MicroPython API versions[edit]

SHA2017Badge

Disobey2019Badge

HackerHotel2019Badge

CampZone 2019Badge

help()[edit]

This should get you started hacking right away.

import esp[edit]

This module hosts some of the low-level ESP32 features.

import esp
esp.rtc_get_reset_reason(cpu)

Where CPU is 0 or 1, other values for CPU always return 0.

Returns the reset reason of last reset event.

esp.start_sleeping(miliseconds)

Put the processors to sleep for the given amount of time . .

Reading and writing of RTC memory currently doesn't keep contents over deep-sleep!

esp.rtcmem_write(offset, value)

Sets value at offset.

esp.rtcmem_read(offset)

Returns value stored at offset.

esp.rtcmem_write_string(string, offset = 2)

Sets string value at optional offset.

esp.rtcmem_read_string(offset = 2)

Returns string value stored at optional offset.

NB: To set a program for boot run, put in the name at offset two and make sure the values of offset 0 and 1 are not each others inverse ;)

import badge[edit]

The first thing you would want to do is get the display working, this is currently done by the boot.py script.

import badge
badge.init()

Initialise all badge peripherals, this is probably the way you want to start your app.

badge.eink_init()

Just init the screen.

badge.eink_busy()

Returns a boolean value to indicate eink is currently being flushed.

badge.eink_busy_wait()

Waits for the eink to be flushed, handy to use before you deepsleep.

badge.power_init()

Initialise power sensing and related pin states.

badge.battery_charge_status()

Returns a boolean, true for charging, false for not charging.

badge.battery_volt_sense()

Returns a value somewhat representing the battery voltage in milivolts (needs calibration)!

badge.usb_volt_sense()

Returns a value somewhat representing the USB voltage in milivolts (needs calibration)!

badge.leds_init()

Initialise power to the LEDs and setup the SPI bus.

badge.leds_enable()

Initialise power to the LEDs (automagically done by badge.leds.init().

badge.leds_disable()

Disable power to the LEDs.

badge.leds_send_data(grbw_values, length)

Stream a given length GRBW values to the LEDs over the SPI bus.

Length should probably be 24 (4 bytes, 6 LEDs) . .

A bytestring can be generated from a list by using something like: bytes([255, 0, 0, 100, 255, 0, 0, 100, 255, 0, 0, 100, 255, 0, 0, 100, 255, 0, 0, 100, 255, 0, 0, 100])

badge.vibrator_init()

Setup the vibrator driver.

badge.vibrator_activate(time)

Makes the vibrator buss for time miliseconds.

badge.nvs_get_str(namespace, key, default)

Return a string from Non Volatile Storage under namespace, key fall back to default if None.

badge.nvs_set_str(namespace, key, value)

Write a string value to Non Volatile Storage under namespace, key.

badge.nvs_get_u8(namespace, key, default)

Return an unsigned 8 bit value from Non Volatile Storage under namespace, key fall back to default if None.

badge.nvs_set_u8(namespace, key, value)

Write an unsigned 8 bit value to Non Volatile Storage under namespace, key.

badge.nvs_get_u16(namespace, key, default)

Return an unsigned 16 bit value from Non Volatile Storage under namespace, key fall back to default if None.

badge.nvs_set_u16(namespace, key, value)

Write an unsigned 16 bit value to Non Volatile Storage under namespace, key.

More about the Non Volatile Storage namespaces and values.

import wifi[edit]

wifi.init()

Connect to the wifi, using NVS badge, wifi.ssid and badge, wifi.password data.

To wait for wifi connection, try:

while not wifi.sta_if.isconnected():
    time.sleep(0.1)
    pass

import system[edit]

Function Description
system.reboot() Reboot the badge, restarts the current app / does whatever you manually set in the rtc memory
system.sleep(<duration>, [show]) Sleep for <duration> milliseconds, if duration is 0 or more than a full day then sleep forever. If show is true then a message will be printed on the serial port.
system.isColdBoot() Returns true if the badge started from cold boot (no power). Generally only true for the homescreen/splash application.
system.isWakeup([timer], [button], [ir], [ulp]) Returns true if the wakeup reason is one of the enabled arguments. Default is all enabled.
system.start(app, [status]) Start an app. If status is true a message will be shown to the user while starting the application.
system.home() Reboot and start the homescreen
system.ota() Reboot and start the OTA updater
system.serialWarning() Print a warning to the display stating that the current app can only be controlled using the serial port. Usefull for serial port only apps.
system.currentApp() Returns the name of the currently started app

import ugfx[edit]

import ugfx

ugfx.init()

Initialises the uGFX modules for use.

In case you want to unload the ugfx library to clear up memory or something, you can use ugfx.deinit()

Flush[edit]

Since this is a ultra low power bi-stable display, you'll need to flush your buffer to the screen!

ugfx.flush()

You can select a different way the E-Ink display updates.

ugfx.set_lut(lut)

Where the lut is one of the defined constants . .

Primitives[edit]

ugfx.clear(colour)

For colours, see constants.

ugfx.fonts_list()

Gives you a list of usable fonts.

ugfx.fonts_dump(name)

Dump the contents of the given font, you can write this to flash or use it directly.

ugfx.fonts_load(dump)

Import the fiven font data from a dump to be used with ugfx.

ugfx.get_char_width(char, font)

Returns the with of a given character, font combination in pixels.

ugfx.get_string_width(string, font)

Returns the with of a given string, font combination in pixels.

ugfx.char(x, y, char, font, colour)

Draws the given character at the position `(x, y)` using the given font and colour.

ugfx.string(x, y, string, font, colour)

Draws the given string of text at the position `(x, y)` using the given font and colour.

ugfx.string_box(x, y, a, b, str, font, colour, justify)

Draws the given text in a box at position `(x, y)` with lengths a,b using the given font, colour and justification.

ugfx.pixel(x, y, colour)

Draws a pixel at (x,y) using the given colour.

ugfx.line(x1, y1, x2, y2, colour)

Draws a line from (x1,y1) to (x2,y2) using the given colour.

ugfx.box(x, y, a, b, colour)

Draws a box from (x,y), with lengths a,b, using the given colour.

ugfx.rounded_box(x, y, a, b, radius, colour)

Draws a box from (x,y), with lengths a,b, rounded corners with radius r, using the given colour.

ugfx.fill_rounded_box(x, y, a, b, radius, colour)

Draw a box from (x,y), with lengths a,b, rounded corners with radius r, using the given colour.

ugfx.area(x, y, a, b, colour)

Fill area from (x,y), with lengths a,b, using the given colour.

ugfx.thickline(x1, y1, x2, y2, colour, width, round)

Draw a line with a given thickness from (x1,y1) to (x2,y2) using the given colour, with an option to round the ends.

ugfx.circle(x, y, r, colour)

Draw a circle having a centre point at (x,y), radius r, using the given colour.

ugfx.fill_circle(x, y, r, colour)

Fill a circle having a centre point at (x,y), radius r, using the given colour.

ugfx.ellipse(x, y, a, b, colour)

Draw an ellipse having a centre point at (x,y), lengths a,b, using the given colour.

ugfx.fill_ellipse(x,y, a, b, colour)

Fill an ellipse having a centre point at (x,y), lengths a,b, using the given colour.

ugfx.arc(x, y, r, angle1, angle2, colour)

Draw an arc having a centre point at (x,y), radius r, using the given colour.

ugfx.fill_arc(x, y, r, angle1, angle2, colour)

Fill an arc having a centre point at (x,y), radius r, using the given colour.

ugfx.polygon(x, y, array, colour)

Draw a polygon starting at (x,y), using the array of points, using the given colour.

ugfx.fill_polygon(x, y, array, colour)

Fill a polygon starting at (x,y), using the array of points, using the given colour.

ugfx.demo("Hacking")

Expects a string, displays the Still Hacking Anyway sticker 😉

Input[edit]

ugfx.input_init()

Needs badge.init() and ugfx.init() to have ran before it.

ugfx.input_attach(button, callback)

The callback has one boolean argument, pressed.

ugfx.input_attach(ugfx.JOY_UP, lambda pressed: print(pressed))

This example attaches a simple print function to the UP button, showing True for press and False for release.

Constants[edit]

Colours:

ugfx.BLACK
ugfx.WHITE

Justification:

ugfx.justifyLeft
ugfx.justifyCenter
ugfx.justifyRight

Inputs:

ugfx.JOY_UP
ugfx.JOY_DOWN
ugfx.JOY_LEFT
ugfx.JOY_RIGHT
ugfx.BTN_A
ugfx.BTN_B
ugfx.BTN_SELECT
ugfx.BTN_START
ugfx.BTN_FLASH

E-Ink LUT:

ugfx.LUT_FULL
ugfx.LUT_NORMAL
ugfx.LUT_FASTER
ugfx.LUT_FASTEST
ugfx.GREYSCALE

GREYSCALE is technically not a lut but a special rendering mode.

Fonts[edit]

  • Roboto_Regular12
  • Roboto_Regular18
  • Roboto_Regular22
  • Roboto_Black22
  • Roboto_BlackItalic24
  • PermanentMarker22
  • PermanentMarker36
  • pixelade13
  • DejaVuSans20
  • weather42

Have Fun!![edit]

Let's get started!!

import badge
import ugfx

badge.init()
ugfx.init()

ugfx.clear(ugfx.BLACK)

ugfx.fill_circle(60, 60, 50, ugfx.WHITE);
ugfx.fill_circle(60, 60, 40, ugfx.BLACK);
ugfx.fill_circle(60, 60, 30, ugfx.WHITE);
ugfx.fill_circle(60, 60, 20, ugfx.BLACK);
ugfx.fill_circle(60, 60, 10, ugfx.WHITE);

ugfx.thickline(1,1,100,100,ugfx.WHITE,10,5)
ugfx.box(30,30,50,50,ugfx.WHITE)

ugfx.string(150,25,"STILL","Roboto_BlackItalic24",ugfx.WHITE)
ugfx.string(130,50,"Hacking","PermanentMarker22",ugfx.WHITE)
len = ugfx.get_string_width("Hacking","PermanentMarker22")
ugfx.line(130, 72, 144 + len, 72, ugfx.WHITE)
ugfx.line(140 + len, 52, 140 + len, 70, ugfx.WHITE)
ugfx.string(140,75,"Anyway","Roboto_BlackItalic24",ugfx.WHITE)

ugfx.flush()

def render(text, pushed):
    if(pushed):
        ugfx.string(100,10,text,"PermanentMarker22",ugfx.WHITE)
    else:
        ugfx.string(100,10,text,"PermanentMarker22",ugfx.BLACK)
    ugfx.flush()

ugfx.input_init()
ugfx.input_attach(ugfx.JOY_UP, lambda pressed: render('UP', pressed))
ugfx.input_attach(ugfx.JOY_DOWN, lambda pressed: render('DOWN', pressed))
ugfx.input_attach(ugfx.JOY_LEFT, lambda pressed: render('LEFT', pressed))
ugfx.input_attach(ugfx.JOY_RIGHT, lambda pressed: render('RIGHT', pressed))
ugfx.input_attach(ugfx.BTN_A, lambda pressed: render('A', pressed))
ugfx.input_attach(ugfx.BTN_B, lambda pressed: render('B', pressed))
ugfx.input_attach(ugfx.BTN_START, lambda pressed: render('Start', pressed))
ugfx.input_attach(ugfx.BTN_SELECT, lambda pressed: render('Select', pressed))

while True:
    pass