Projects:Badge/MicroPython

From SHA2017 Wiki
Jump to: navigation, search

Badge Badge project - Documentation - Github - Sponsorship - Organisation

MicroPython

WIP

Currently a fast moving target, documentation should be up-to-date though . .

Connect to your badge with your favourite serial terminal (e.g. `picocom /dev/ttyUSB0 -b115200`) for a REPL, or start the emulator.

You can use ampy or mpfshell to connect to your badge too.

To be able to start a REPL you need the clean_repl egg from the hatchery: https://badge.sha2017.org/projects/clean_repl . This will restart the badge, starts nothing and makes it possible to use the REPL.

help()

This should get you started hacking right away.

import esp

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

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(pattern)

Send some interesting buzz patterns to the vibrator. .

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

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 ugfx

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

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

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

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

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

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

Have Fun!!

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