diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml index d3009c53..9d1be061 100644 --- a/.github/workflows/cmake.yml +++ b/.github/workflows/cmake.yml @@ -23,8 +23,12 @@ jobs: env: PICO_SDK_PATH: $GITHUB_WORKSPACE/pico-sdk - + steps: + - name: Compiler Cache Fixup + run: | + mkdir -p /home/runner/.ccache + - name: Compiler Cache uses: actions/cache@v4 with: diff --git a/.github/workflows/micropython.yml b/.github/workflows/micropython.yml index f9b44b06..2680a4d1 100644 --- a/.github/workflows/micropython.yml +++ b/.github/workflows/micropython.yml @@ -42,8 +42,6 @@ jobs: board: RPI_PICO_W - name: stellar_unicorn board: RPI_PICO_W - - name: inky_frame - board: PICO_W_INKY env: # MicroPython version will be contained in github.event.release.tag_name for releases diff --git a/ci/micropython.sh b/ci/micropython.sh index 3f044e76..2157ba2c 100644 --- a/ci/micropython.sh +++ b/ci/micropython.sh @@ -29,7 +29,7 @@ function micropython_clone { function micropython_build_mpy_cross { cd micropython/mpy-cross ccache --zero-stats || true - CROSS_COMPILE="ccache " make + CROSS_COMPILE="ccache " USER_C_MODULES= make ccache --show-stats || true cd ../../ } diff --git a/micropython/board/PICO_W_INKY/board.json b/micropython/board/PICO_W_INKY/board.json deleted file mode 100644 index a85d7e04..00000000 --- a/micropython/board/PICO_W_INKY/board.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "deploy": [ - "../deploy.md" - ], - "docs": "", - "features": [ - "Breadboard friendly", - "Castellated Pads", - "Micro USB", - "WiFi", - "Bluetooth" - ], - "id": "rp2-pico-w", - "images": [ - "rp2-pico-w.jpg" - ], - "mcu": "rp2040", - "product": "Pico W", - "thumbnail": "", - "url": "https://www.raspberrypi.com/products/raspberry-pi-pico/", - "vendor": "Raspberry Pi" -} diff --git a/micropython/board/PICO_W_INKY/manifest.py b/micropython/board/PICO_W_INKY/manifest.py deleted file mode 100644 index 77511bf9..00000000 --- a/micropython/board/PICO_W_INKY/manifest.py +++ /dev/null @@ -1,15 +0,0 @@ -include("$(PORT_DIR)/boards/manifest.py") - -# https://github.com/micropython/micropython-lib/blob/master/micropython/bundles/bundle-networking/manifest.py -require("bundle-networking") -require("urllib.urequest") -require("umqtt.simple") - -# SD Card -require("sdcard") - -# Bluetooth -require("aioble") - -freeze("../../modules_py", "pimoroni.py") -freeze("../../modules_py", "boot.py") \ No newline at end of file diff --git a/micropython/board/PICO_W_INKY/mpconfigboard.cmake b/micropython/board/PICO_W_INKY/mpconfigboard.cmake deleted file mode 100644 index 7feece04..00000000 --- a/micropython/board/PICO_W_INKY/mpconfigboard.cmake +++ /dev/null @@ -1,17 +0,0 @@ -# cmake file for Pimoroni Inky with Raspberry Pi Pico W -set(MICROPY_BOARD RPI_PICO_W) -set(PICO_BOARD "pico_w") - -# The C malloc is needed by cyw43-driver Bluetooth and Pimoroni Pico modules -set(MICROPY_C_HEAP_SIZE 4096) - -set(MICROPY_PY_LWIP ON) -set(MICROPY_PY_NETWORK_CYW43 ON) - -# Bluetooth -set(MICROPY_PY_BLUETOOTH ON) -set(MICROPY_BLUETOOTH_BTSTACK ON) -set(MICROPY_PY_BLUETOOTH_CYW43 ON) - -# Board specific version of the frozen manifest -set(MICROPY_FROZEN_MANIFEST ${MICROPY_BOARD_DIR}/manifest.py) \ No newline at end of file diff --git a/micropython/board/PICO_W_INKY/mpconfigboard.h b/micropython/board/PICO_W_INKY/mpconfigboard.h deleted file mode 100644 index a4da1cd9..00000000 --- a/micropython/board/PICO_W_INKY/mpconfigboard.h +++ /dev/null @@ -1,23 +0,0 @@ -// Board and hardware specific configuration -#define MICROPY_HW_BOARD_NAME "Raspberry Pi Pico W" - -// todo: We need something to check our binary size -#define MICROPY_HW_FLASH_STORAGE_BYTES (848 * 1024) - -// Enable networking. -#define MICROPY_PY_NETWORK 1 -#define MICROPY_PY_NETWORK_HOSTNAME_DEFAULT "InkyW" - -// CYW43 driver configuration. -#define CYW43_USE_SPI (1) -#define CYW43_LWIP (1) -#define CYW43_GPIO (1) -#define CYW43_SPI_PIO (1) - -// For debugging mbedtls - also set -// Debug level (0-4) 1=warning, 2=info, 3=debug, 4=verbose -// #define MODUSSL_MBEDTLS_DEBUG_LEVEL 1 - -#define MICROPY_HW_PIN_EXT_COUNT CYW43_WL_GPIO_COUNT - -#define MICROPY_HW_PIN_RESERVED(i) ((i) == CYW43_PIN_WL_HOST_WAKE || (i) == CYW43_PIN_WL_REG_ON) diff --git a/micropython/board/PICO_W_INKY/pins.csv b/micropython/board/PICO_W_INKY/pins.csv deleted file mode 100644 index 8debb632..00000000 --- a/micropython/board/PICO_W_INKY/pins.csv +++ /dev/null @@ -1,30 +0,0 @@ -GP0,GPIO0 -GP1,GPIO1 -GP2,GPIO2 -GP3,GPIO3 -GP4,GPIO4 -GP5,GPIO5 -GP6,GPIO6 -GP7,GPIO7 -GP8,GPIO8 -GP9,GPIO9 -GP10,GPIO10 -GP11,GPIO11 -GP12,GPIO12 -GP13,GPIO13 -GP14,GPIO14 -GP15,GPIO15 -GP16,GPIO16 -GP17,GPIO17 -GP18,GPIO18 -GP19,GPIO19 -GP20,GPIO20 -GP21,GPIO21 -GP22,GPIO22 -GP26,GPIO26 -GP27,GPIO27 -GP28,GPIO28 -WL_GPIO0,EXT_GPIO0 -WL_GPIO1,EXT_GPIO1 -WL_GPIO2,EXT_GPIO2 -LED,EXT_GPIO0 diff --git a/micropython/examples/inky_frame/README.md b/micropython/examples/inky_frame/README.md index 7f4c5bea..45c2e522 100644 --- a/micropython/examples/inky_frame/README.md +++ b/micropython/examples/inky_frame/README.md @@ -1,110 +1,3 @@ # Pico Inky Frame MicroPython Examples -- [PicoGraphics](#picographics) -- [Examples](#examples) - - [Button Test](#button-test) - - [Carbon Intensity](#carbon-intensity) - - [Daily Activity](#daily-activity) - - [Dithering](#dithering) - - [Image Gallery](#image-gallery) - - [LED PWM](#led-pwm) - - [News](#news) - - [PlaceKitten](#placekitten) - - [Quote of the Day](#quote-of-the-day) - - [Random Joke](#random-joke) - - [RTC Demo](#rtc-demo) - - [SD Card Test](#sd-card-test) - - [XKCD Daily](#xkcd-daily) - -## PicoGraphics - -You can draw on Inky Frame using our tiny PicoGraphics display library. -- [PicoGraphics MicroPython function reference](../../modules/picographics) - -## Examples - -The wireless examples need `network_manager.py` and `WIFI_CONFIG.py` from the `common` directory to be saved to your Pico W. Open up `WIFI_CONFIG.py` in Thonny to add your wifi details (and save it when you're done). - -You'll also need to install the `micropython-urllib.urequest` library using Thonny's 'Tools' > 'Manage Packages' or `common/lib/urllib` which contains a compiled `.mpy` version that uses less RAM. You should place this directory in `lib` on your Pico W. - -### Button Test -[button_test.py](button_test.py) - -Inky Frame's buttons (and the RTC alarm, busy signal from the screen and external trigger from the hack header) are connected to a shift register to help conserve pins, and to allow these inputs to wake the board up from sleep. - -This example demonstrates a simple way of reading when a button has been pushed by reading the shift register and checking if the bit in a specific position is 0 or 1. - -### Carbon Intensity -[carbon_intensity.py](carbon_intensity.py) - -This example connects to the Carbon Intensity API to give you a regional forecast of how your (UK) electricity is being generated and its carbon impact. - -Find out more at https://carbonintensity.org.uk/ - -### Daily Activity -[inky_frame_daily_activity.py](inky_frame_daily_activity.py) - -Generate a random activity from Bored API. - -### Dithering -[inky_frame_dithering.py](inky_frame_dithering.py) - -A basic example showing automatic dithering in action, as PicoGraphics tries to use Inky Frame's limited colour palette to match arbitrary colours. - -### Image Gallery -[/image_gallery](../inky_frame/image_gallery) - -This photo frame example displays local images on Inky Frame and lets you switch between them with the buttons. Use `image_gallery.py` if your images are stored on your Pico, or `image_gallery_sd.py` if the images are on your SD card. - -### LED PWM -[led_pwm.py](led_pwm.py) - -A basic example showing how you can control the brightness of Inky Frame's LEDs using PWM. - -### News -[inky_frame_news.py](inky_frame_news.py) - -Display headlines from BBC News. - -### PlaceKitten -[inky_frame_placekitten.py](inky_frame_placekitten.py) - -Download a random (from a small subset) image from PlaceKitten. - -### Quote of the Day -[inky_frame_quote_of_the_day.py](inky_frame_quote_of_the_day.py) - -Load the WikiQuotes Quote of the Day and display it. - -### Random Joke -[inky_frame_random_joke.py](inky_frame_random_joke.py) - -Load a random joke from JokeAPI.dev and display it. - -Jokes are rendered into images "offline" by our feed2image service for two reasons: - -1. Saves the Pico W having to process them -2. JokeAPI.dev needs TLS1.3 which Pico W does not support! - -For bugs/contributions or to complain about a joke, see: https://github.com/pimoroni/feed2image - -### RTC Demo -[inky_frame_rtc_demo.py](inky_frame_rtc_demo.py) - -A basic example that sets the time/date from an NTP server, syncs the Inky and Pico RTCs and and makes Inky Frame wake up on a timer. - -### SD Card Test -[sd_test.py](sd_test.py) - -This simple example shows how to read and write from the SD card on Inky Frame. - -### XKCD Daily -[inky_frame_xkcd_daily.py](inky_frame_xkcd_daily.py) - -Download and display the daily webcomic from https://xkcd.com/ - -The webcomic is rendered "offline" by our feed2image service since xkcd.com requires TLS1.3! - -For bugs/contributions see: https://github.com/pimoroni/feed2image - - +Moved to: [https://github.com/pimoroni/inky-frame/tree/main/examples](https://github.com/pimoroni/inky-frame/tree/main/examples) diff --git a/micropython/examples/inky_frame/button_demo.py b/micropython/examples/inky_frame/button_demo.py deleted file mode 100644 index 8feed68a..00000000 --- a/micropython/examples/inky_frame/button_demo.py +++ /dev/null @@ -1,86 +0,0 @@ -# This example shows you a simple, non-interrupt way of reading Inky Frame's buttons with a loop that checks to see if buttons are pressed. - -from pimoroni import ShiftRegister -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" -from machine import Pin - -display = PicoGraphics(display=DISPLAY) - -display.set_font("bitmap8") - -# Inky Frame uses a shift register to read the buttons -SR_CLOCK = 8 -SR_LATCH = 9 -SR_OUT = 10 - -sr = ShiftRegister(SR_CLOCK, SR_LATCH, SR_OUT) - -# set up the button LEDs -button_a_led = Pin(11, Pin.OUT) -button_b_led = Pin(12, Pin.OUT) -button_c_led = Pin(13, Pin.OUT) -button_d_led = Pin(14, Pin.OUT) -button_e_led = Pin(15, Pin.OUT) - - -# a handy function we can call to clear the screen -# display.set_pen(1) is white and display.set_pen(0) is black -def clear(): - display.set_pen(1) - display.clear() - - -# set up -clear() -display.set_pen(0) -display.text("Press any button!", 10, 10, scale=4) -display.update() - -while True: - button_a_led.off() - button_b_led.off() - button_c_led.off() - button_d_led.off() - button_e_led.off() - - # read the shift register - # we can tell which button has been pressed by checking if a specific bit is 0 or 1 - result = sr.read() - button_a = sr[7] - button_b = sr[6] - button_c = sr[5] - button_d = sr[4] - button_e = sr[3] - - if button_a == 1: # if a button press is detected then... - button_a_led.on() - clear() # clear to white - display.set_pen(4) # change the pen colour - display.text("Button A pressed", 10, 10, scale=4) # display some text on the screen - display.update() # update the display - elif button_b == 1: - button_b_led.on() - clear() - display.set_pen(6) - display.text("Button B pressed", 10, 50, scale=4) - display.update() - elif button_c == 1: - button_c_led.on() - clear() - display.set_pen(5) - display.text("Button C pressed", 10, 90, scale=4) - display.update() - elif button_d == 1: - button_d_led.on() - clear() - display.set_pen(2) - display.text("Button D pressed", 10, 130, scale=4) - display.update() - elif button_e == 1: - button_e_led.on() - clear() - display.set_pen(3) - display.text("Button E pressed", 10, 170, scale=4) - display.update() diff --git a/micropython/examples/inky_frame/button_test.py b/micropython/examples/inky_frame/button_test.py deleted file mode 100644 index 62c44db2..00000000 --- a/micropython/examples/inky_frame/button_test.py +++ /dev/null @@ -1,59 +0,0 @@ -# This example allows you to test Inky Frame's buttons -# It does not update the screen. - -from pimoroni import ShiftRegister -from machine import Pin -import time - - -# Inky Frame uses a shift register to read the buttons -SR_CLOCK = 8 -SR_LATCH = 9 -SR_OUT = 10 - -sr = ShiftRegister(SR_CLOCK, SR_LATCH, SR_OUT) - - -# Simple class to debounce button input and handle LED -class Button: - def __init__(self, idx, led, debounce=50): - self.led = Pin(led, Pin.OUT) # LEDs are just regular IOs - self.led.on() - self._idx = idx - self._debounce_time = debounce - self._changed = time.ticks_ms() - self._last_value = None - - def debounced(self): - return time.ticks_ms() - self._changed > self._debounce_time - - def get(self, sr): - value = sr[self._idx] - if value != self._last_value and self.debounced(): - self._last_value = value - self._changed = time.ticks_ms() - return value - - -button_a = Button(7, 11) -button_b = Button(6, 12) -button_c = Button(5, 13) -button_d = Button(4, 14) -button_e = Button(3, 15) - - -while True: - sr.read() - - if button_a.get(sr): - button_a.led.toggle() - if button_b.get(sr): - button_b.led.toggle() - if button_c.get(sr): - button_c.led.toggle() - if button_d.get(sr): - button_d.led.toggle() - if button_e.get(sr): - button_e.led.toggle() - - time.sleep(1.0 / 60) # Poll 60 times/second diff --git a/micropython/examples/inky_frame/carbon_intensity.py b/micropython/examples/inky_frame/carbon_intensity.py deleted file mode 100644 index 20c41421..00000000 --- a/micropython/examples/inky_frame/carbon_intensity.py +++ /dev/null @@ -1,149 +0,0 @@ -""" -This example connects to the Carbon Intensity API to give you a regional -forecast of how your (UK) electricity is being generated and its carbon impact. - -Carbon Intensity API only reports data from the UK National Grid. - -Find out more about what the numbers mean at: -https://carbonintensity.org.uk/ - -Make sure to uncomment the correct size for your display! - -""" - -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" -import urequests -import inky_frame -import uasyncio -from network_manager import NetworkManager -import WIFI_CONFIG - -# Set (the first half) of your UK postcode here -POSTCODE = "S9" - -URL = "https://api.carbonintensity.org.uk/regional/postcode/" + str(POSTCODE) - - -def get_data(): - global region, forecast, index, power_list, datetime_to, datetime_from - print(f"Requesting URL: {URL}") - r = urequests.get(URL) - # open the json data - j = r.json() - print("Data obtained!") - print(j) - - # parse the json data - region = j["data"][0]["shortname"] - - forecast = j["data"][0]["data"][0]["intensity"]["forecast"] - index = j["data"][0]["data"][0]["intensity"]["index"] - - power_list = [] - for power in j["data"][0]["data"][0]["generationmix"]: - power_list.append(power['perc']) - - datetime_to = j["data"][0]["data"][0]["to"].split("T") - datetime_from = j["data"][0]["data"][0]["from"].split("T") - - # close the socket - r.close() - - -def draw(): - global graphics - # we're setting up our PicoGraphics buffer after we've made our RAM intensive https request - graphics = PicoGraphics(DISPLAY) - w, h = graphics.get_bounds() - graphics.set_pen(inky_frame.WHITE) - graphics.clear() - - # draw lines - graphics.set_pen(inky_frame.BLACK) - graphics.line(0, int((h / 100) * 0), w, int((h / 100) * 0)) - graphics.line(0, int((h / 100) * 50), w, int((h / 100) * 50)) - graphics.set_font("bitmap8") - graphics.text('100%', w - 40, 10, scale=2) - graphics.text('50%', w - 40, int((h / 100) * 50 + 10), scale=2) - - # draw bars - bar_colours = [ - inky_frame.ORANGE, - inky_frame.RED, - inky_frame.ORANGE, - inky_frame.RED, - inky_frame.BLUE, - inky_frame.ORANGE, - inky_frame.GREEN, - inky_frame.GREEN, - inky_frame.GREEN - ] - for p in power_list: - graphics.set_pen(bar_colours[power_list.index(p)]) - graphics.rectangle(int(power_list.index(p) * w / 9), int(h - p * (h / 100)), - int(w / 9), int(h / 100 * p)) - - # draw labels - graphics.set_font('sans') - # once in white for a background - graphics.set_pen(inky_frame.WHITE) - labels = ['biomass', 'coal', 'imports', 'gas', 'nuclear', 'other', 'hydro', 'solar', 'wind'] - graphics.set_thickness(4) - for label in labels: - graphics.text(f'{label}', int((labels.index(label) * w / 9) + (w / 9) / 2), h - 10, angle=270, scale=1) - # again in black - graphics.set_pen(inky_frame.BLACK) - labels = ['biomass', 'coal', 'imports', 'gas', 'nuclear', 'other', 'hydro', 'solar', 'wind'] - graphics.set_thickness(2) - for label in labels: - graphics.text(f'{label}', int((labels.index(label) * w / 9) + (w / 9) / 2), h - 10, angle=270, scale=1) - - # draw header - graphics.set_thickness(3) - graphics.set_pen(inky_frame.GREEN) - if index in ['high', 'very high']: - graphics.set_pen(inky_frame.RED) - if index in ['moderate']: - graphics.set_pen(inky_frame.ORANGE) - graphics.set_font("sans") - graphics.text('Carbon Intensity', 10, 35, scale=1.2, angle=0) - - # draw small text - graphics.set_pen(inky_frame.BLACK) - graphics.set_font("bitmap8") - graphics.text(f'Region: {region}', int((w / 2) + 30), 10, scale=2) - graphics.text(f'{forecast} gCO2/kWh ({index})', int((w / 2) + 30), 30, scale=2) - graphics.text(f'{datetime_from[0]} {datetime_from[1]} to {datetime_to[1]}', int((w / 2) + 30), 50, scale=2) - - graphics.update() - - -def status_handler(mode, status, ip): - print(mode, status, ip) - - -inky_frame.led_busy.on() -network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler) - -# connect to wifi -try: - uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK)) -except ImportError: - print("Add WIFI_CONFIG.py with your WiFi credentials") - -get_data() -draw() - -# Go to sleep if on battery power -inky_frame.turn_off() - -# Or comment out the line above and uncomment this one to wake up and update every half hour -# inky_frame.sleep_for(30) - -""" -Pico W RAM seems insufficient to decode a https request whilst having a PicoGraphics instance active. -If you are running off USB and want this to update periodically, you could incorporate a machine.reset() -to reset the Pico and start afresh every time. -""" diff --git a/micropython/examples/inky_frame/display_png.py b/micropython/examples/inky_frame/display_png.py deleted file mode 100644 index 7b3cd587..00000000 --- a/micropython/examples/inky_frame/display_png.py +++ /dev/null @@ -1,36 +0,0 @@ -from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" -import pngdec - -# Create a PicoGraphics instance -graphics = PicoGraphics(DISPLAY) -WIDTH, HEIGHT = graphics.get_bounds() - -# Set the font -graphics.set_font("bitmap8") - -# Create an instance of the PNG Decoder -png = pngdec.PNG(graphics) - -# Clear the screen -graphics.set_pen(1) -graphics.clear() -graphics.set_pen(0) - -# Few lines of text. -graphics.text("PNG Pencil", 70, 100, WIDTH, 3) - -# Open our PNG File from flash. In this example we're using a cartoon pencil. -# You can use Thonny to transfer PNG Images to your Inky Frame. -try: - png.open_file("pencil_256x256.png") - - # Decode our PNG file and set the X and Y - png.decode(200, 100) - -except OSError: - graphics.text("Unable to find PNG file! Copy 'pencil_256x256.png' to your Inky Frame using Thonny :)", 10, 70, WIDTH, 3) - -# Start the screen update -graphics.update() diff --git a/micropython/examples/inky_frame/image_gallery/600x448/jwst1.jpg b/micropython/examples/inky_frame/image_gallery/600x448/jwst1.jpg deleted file mode 100644 index 6bfbb681..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/600x448/jwst1.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/600x448/jwst2.jpg b/micropython/examples/inky_frame/image_gallery/600x448/jwst2.jpg deleted file mode 100644 index 5d0868d6..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/600x448/jwst2.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/600x448/jwst3.jpg b/micropython/examples/inky_frame/image_gallery/600x448/jwst3.jpg deleted file mode 100644 index d46e764d..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/600x448/jwst3.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/600x448/jwst4.jpg b/micropython/examples/inky_frame/image_gallery/600x448/jwst4.jpg deleted file mode 100644 index 0b9c7516..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/600x448/jwst4.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/600x448/jwst5.jpg b/micropython/examples/inky_frame/image_gallery/600x448/jwst5.jpg deleted file mode 100644 index 05d86f1f..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/600x448/jwst5.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/640x400/jwst1.jpg b/micropython/examples/inky_frame/image_gallery/640x400/jwst1.jpg deleted file mode 100644 index 202e747a..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/640x400/jwst1.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/640x400/jwst2.jpg b/micropython/examples/inky_frame/image_gallery/640x400/jwst2.jpg deleted file mode 100644 index 103341e6..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/640x400/jwst2.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/640x400/jwst3.jpg b/micropython/examples/inky_frame/image_gallery/640x400/jwst3.jpg deleted file mode 100644 index 4b66d651..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/640x400/jwst3.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/640x400/jwst4.jpg b/micropython/examples/inky_frame/image_gallery/640x400/jwst4.jpg deleted file mode 100644 index f1a541e3..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/640x400/jwst4.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/640x400/jwst5.jpg b/micropython/examples/inky_frame/image_gallery/640x400/jwst5.jpg deleted file mode 100644 index 21a70f3e..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/640x400/jwst5.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/800x480/jwst1.jpg b/micropython/examples/inky_frame/image_gallery/800x480/jwst1.jpg deleted file mode 100644 index c70f67ab..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/800x480/jwst1.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/800x480/jwst2.jpg b/micropython/examples/inky_frame/image_gallery/800x480/jwst2.jpg deleted file mode 100644 index 375775ff..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/800x480/jwst2.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/800x480/jwst3.jpg b/micropython/examples/inky_frame/image_gallery/800x480/jwst3.jpg deleted file mode 100644 index 38876f14..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/800x480/jwst3.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/800x480/jwst4.jpg b/micropython/examples/inky_frame/image_gallery/800x480/jwst4.jpg deleted file mode 100644 index 21f0ee7f..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/800x480/jwst4.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/800x480/jwst5.jpg b/micropython/examples/inky_frame/image_gallery/800x480/jwst5.jpg deleted file mode 100644 index 6d243d8b..00000000 Binary files a/micropython/examples/inky_frame/image_gallery/800x480/jwst5.jpg and /dev/null differ diff --git a/micropython/examples/inky_frame/image_gallery/README.md b/micropython/examples/inky_frame/image_gallery/README.md deleted file mode 100644 index ae36d847..00000000 --- a/micropython/examples/inky_frame/image_gallery/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Image Gallery - -- [Image transfer instructions](#image-transfer-instructions) - - [image\_gallery.py](#image_gallerypy) - - [image\_gallery\_sd.py / image\_gallery\_sd\_random.py](#image_gallery_sdpy--image_gallery_sd_randompy) -- [Image Credits](#image-credits) - -Some example programs to display images on your Inky Frame, plus sample images in different sizes. - -Use: -640x400 for Inky Frame 4.0" -600x448 for Inky Frame 5.7" -800x480 for Inky Frame 7.3" - -If you want to use your own images, they will need to be the correct dimensions for your screen and saved *without progressive encoding*. - -## Image transfer instructions - -In all cases the images will need to be copied to the root of your Pico W or SD card. - -### image_gallery.py - -Copy the images to your Pico W using Thonny. - -### image_gallery_sd.py / image_gallery_sd_random.py - -Pop an SD card into your computer to copy the images across. - -Alternatively, you can transfer them using Thonny, but you will have to mount the SD card using the REPL first: - -```python -import os -import sdcard -from machine import Pin, SPI -sd_spi = SPI(0, sck=Pin(18, Pin.OUT), mosi=Pin(19, Pin.OUT), miso=Pin(16, Pin.OUT)) -sd = sdcard.SDCard(sd_spi, Pin(22)) -os.mount(sd, "/sd") -``` - -## Image Credits - -Sample images from the Webb Space Telescope (credit: NASA, ESA, CSA, and STScI). -Find more gorgeous images and info @ https://webbtelescope.org/ - -... and Raspberry Pi <3 diff --git a/micropython/examples/inky_frame/image_gallery/image_gallery.py b/micropython/examples/inky_frame/image_gallery/image_gallery.py deleted file mode 100644 index 60b31e44..00000000 --- a/micropython/examples/inky_frame/image_gallery/image_gallery.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -An offline image gallery that switches between five jpg images. - -Copy images into the root of your Pico's flash using Thonny. - -If you want to use your own images they must be the screen dimensions -(or smaller) and saved as *non-progressive* jpgs. - -Make sure to uncomment the correct size for your display! -""" - -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" -import inky_frame -import jpegdec - -# you can change your file names here -IMAGE_A = "jwst1.jpg" -IMAGE_B = "jwst2.jpg" -IMAGE_C = "jwst3.jpg" -IMAGE_D = "jwst4.jpg" -IMAGE_E = "jwst5.jpg" - -# set up the display -graphics = PicoGraphics(DISPLAY) - -# Create a new JPEG decoder for our PicoGraphics -j = jpegdec.JPEG(graphics) - - -def display_image(filename): - - # Open the JPEG file - j.open_file(filename) - - # Decode the JPEG - j.decode(0, 0, jpegdec.JPEG_SCALE_FULL) - - # Display the result - graphics.update() - - -print('Press a button to display an image!') - -while True: - inky_frame.button_a.led_off() - inky_frame.button_b.led_off() - inky_frame.button_c.led_off() - inky_frame.button_d.led_off() - inky_frame.button_e.led_off() - - if inky_frame.button_a.read(): - print('Refreshing image A.') - inky_frame.button_a.led_on() - display_image(IMAGE_A) - elif inky_frame.button_b.read(): - print('Refreshing image B.') - inky_frame.button_b.led_on() - display_image(IMAGE_B) - elif inky_frame.button_c.read(): - print('Refreshing image C.') - inky_frame.button_c.led_on() - display_image(IMAGE_C) - elif inky_frame.button_d.read(): - print('Refreshing image D.') - inky_frame.button_d.led_on() - display_image(IMAGE_D) - elif inky_frame.button_e.read(): - print('Refreshing image E.') - inky_frame.button_e.led_on() - display_image(IMAGE_E) - - # Go to sleep if on battery power - inky_frame.turn_off() diff --git a/micropython/examples/inky_frame/image_gallery/image_gallery_sd.py b/micropython/examples/inky_frame/image_gallery/image_gallery_sd.py deleted file mode 100644 index 659ca291..00000000 --- a/micropython/examples/inky_frame/image_gallery/image_gallery_sd.py +++ /dev/null @@ -1,84 +0,0 @@ -""" -An offline image gallery that switches between five jpg images on your SD card. - -Copy images to the root of your SD card by plugging it into a computer. - -If you want to use your own images they must be the screen dimensions -(or smaller) and saved as *non-progressive* jpgs. - -Make sure to uncomment the correct size for your display! -""" - -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" -from machine import Pin, SPI -import jpegdec -import sdcard -import os -import inky_frame - -# you can change your file names here -IMAGE_A = "sd/jwst1.jpg" -IMAGE_B = "sd/jwst2.jpg" -IMAGE_C = "sd/jwst3.jpg" -IMAGE_D = "sd/jwst4.jpg" -IMAGE_E = "sd/jwst5.jpg" - -# set up the display -graphics = PicoGraphics(DISPLAY) - -# set up the SD card -sd_spi = SPI(0, sck=Pin(18, Pin.OUT), mosi=Pin(19, Pin.OUT), miso=Pin(16, Pin.OUT)) -sd = sdcard.SDCard(sd_spi, Pin(22)) -os.mount(sd, "/sd") - -# Create a new JPEG decoder for our PicoGraphics -j = jpegdec.JPEG(graphics) - - -def display_image(filename): - - # Open the JPEG file - j.open_file(filename) - - # Decode the JPEG - j.decode(0, 0, jpegdec.JPEG_SCALE_FULL) - - # Display the result - graphics.update() - - -# setup -print('Press a button to display an image!') - -while True: - inky_frame.button_a.led_off() - inky_frame.button_b.led_off() - inky_frame.button_c.led_off() - inky_frame.button_d.led_off() - inky_frame.button_e.led_off() - - if inky_frame.button_a.read(): - print('Refreshing image A.') - inky_frame.button_a.led_on() - display_image(IMAGE_A) - elif inky_frame.button_b.read(): - print('Refreshing image B.') - inky_frame.button_b.led_on() - display_image(IMAGE_B) - elif inky_frame.button_c.read(): - print('Refreshing image C.') - inky_frame.button_c.led_on() - display_image(IMAGE_C) - elif inky_frame.button_d.read(): - print('Refreshing image D.') - inky_frame.button_d.led_on() - display_image(IMAGE_D) - elif inky_frame.button_e.read(): - print('Refreshing image E.') - inky_frame.button_e.led_on() - display_image(IMAGE_E) - - # Go to sleep if on battery power - inky_frame.turn_off() diff --git a/micropython/examples/inky_frame/image_gallery/image_gallery_sd_random.py b/micropython/examples/inky_frame/image_gallery/image_gallery_sd_random.py deleted file mode 100644 index 965610a8..00000000 --- a/micropython/examples/inky_frame/image_gallery/image_gallery_sd_random.py +++ /dev/null @@ -1,67 +0,0 @@ -""" -An offline image gallery that displays a random image from your SD card -and updates on a timer. - -Copy images to the root of your SD card by plugging it into a computer. - -If you want to use your own images they must be the screen dimensions -(or smaller) and saved as *non-progressive* jpgs. - -Make sure to uncomment the correct size for your display! -""" - -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" -from machine import Pin, SPI -import jpegdec -import sdcard -import os -import inky_frame -import random - -# how often to change image (in minutes) -UPDATE_INTERVAL = 60 - -# set up the display -graphics = PicoGraphics(DISPLAY) - -# set up the SD card -sd_spi = SPI(0, sck=Pin(18, Pin.OUT), mosi=Pin(19, Pin.OUT), miso=Pin(16, Pin.OUT)) -sd = sdcard.SDCard(sd_spi, Pin(22)) -os.mount(sd, "/sd") - -# Create a new JPEG decoder for our PicoGraphics -j = jpegdec.JPEG(graphics) - - -def display_image(filename): - - # Open the JPEG file - j.open_file(filename) - - # Decode the JPEG - j.decode(0, 0, jpegdec.JPEG_SCALE_FULL) - - # Display the result - graphics.update() - - -inky_frame.led_busy.on() - -# Get a list of files that are in the directory -files = os.listdir("/sd") -# remove files from the list that aren't .jpgs or .jpegs -files = [f for f in files if f.endswith(".jpg") or f.endswith(".jpeg")] - -while True: - # pick a random file - file = files[random.randrange(len(files))] - - # Open the file - print(f"Displaying /sd/{file}") - display_image("/sd/" + file) - - # Sleep or wait for a bit - print(f"Sleeping for {UPDATE_INTERVAL} minutes") - inky_frame.sleep_for(UPDATE_INTERVAL) diff --git a/micropython/examples/inky_frame/inky_frame_daily_activity.py b/micropython/examples/inky_frame/inky_frame_daily_activity.py deleted file mode 100644 index a21e6b3a..00000000 --- a/micropython/examples/inky_frame/inky_frame_daily_activity.py +++ /dev/null @@ -1,143 +0,0 @@ -import gc -import WIFI_CONFIG -from network_manager import NetworkManager -import uasyncio -import ujson -from urllib import urequest -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" -from machine import Pin -from pimoroni_i2c import PimoroniI2C -from pcf85063a import PCF85063A -import time - - -I2C_SDA_PIN = 4 -I2C_SCL_PIN = 5 -HOLD_VSYS_EN_PIN = 2 - -# set up and enable vsys hold so we don't go to sleep -hold_vsys_en_pin = Pin(HOLD_VSYS_EN_PIN, Pin.OUT) -hold_vsys_en_pin.value(True) - -# intialise the pcf85063a real time clock chip -i2c = PimoroniI2C(I2C_SDA_PIN, I2C_SCL_PIN, 100000) -rtc = PCF85063A(i2c) - -# Length of time between updates in Seconds. -# Frequent updates will reduce battery life! -UPDATE_INTERVAL = 60 * 1 - -# API URL -URL = "https://www.boredapi.com/api/activity" - - -def status_handler(mode, status, ip): - print(mode, status, ip) - - -network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler) - -gc.collect() -graphics = PicoGraphics(DISPLAY) -WIDTH, HEIGHT = graphics.get_bounds() -gc.collect() - - -def display_quote(text, ox, oy, scale, wordwrap): - # Processing text is memory intensive - # so we'll do it one char at a time as we draw to the screen - line_height = 8 * scale - html = False - html_tag = "" - word = "" - space_width = graphics.measure_text(" ", scale=scale) - x = ox - y = oy - for char in text: - if char in "[]": - continue - if char == "<": - html = True - html_tag = "" - continue - if char == ">": - html = False - continue - if html: - if char in "/ ": - continue - html_tag += char - continue - if char in (" ", "\n") or html_tag == "br": - w = graphics.measure_text(word, scale=scale) - if x + w > wordwrap or char == "\n" or html_tag == "br": - x = ox - y += line_height - - graphics.text(word, x, y, scale=scale) - word = "" - html_tag = "" - x += w + space_width - continue - - word += char - - # Last word - w = graphics.measure_text(word, scale=scale) - if x + w > wordwrap: - x = ox - y += line_height - - graphics.text(word, x, y, scale=scale) - - -rtc.enable_timer_interrupt(True) - -while True: - # Connect to WiFi - uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK)) - - # Clear the screen - graphics.set_pen(1) - graphics.clear() - graphics.set_pen(0) - - # Grab the data - socket = urequest.urlopen(URL) - j = ujson.load(socket) - socket.close() - - text = [j['activity'], j['type'], j['participants']] - - # Page lines! - graphics.set_pen(3) - graphics.line(0, 65, WIDTH, 65) - for i in range(2, 13): - graphics.line(0, i * 35, WIDTH, i * 35) - - # Page margin - graphics.set_pen(4) - graphics.line(50, 0, 50, HEIGHT) - graphics.set_pen(0) - - # Main text - graphics.set_font("cursive") - graphics.set_pen(4) - graphics.set_font("cursive") - graphics.text("Activity Idea", 55, 30, WIDTH - 20, 2) - graphics.set_pen(0) - graphics.set_font("bitmap8") - display_quote(text[0], 55, 170, 5, WIDTH - 20) - - graphics.set_pen(2) - graphics.text("Activity Type: " + text[1], 55, HEIGHT - 45, WIDTH - 20, 2) - graphics.text("Participants: " + str(text[2]), 400, HEIGHT - 45, WIDTH - 20, 2) - - graphics.update() - - # Time to have a little nap until the next update - rtc.set_timer(UPDATE_INTERVAL) - hold_vsys_en_pin.init(Pin.IN) - time.sleep(UPDATE_INTERVAL) diff --git a/micropython/examples/inky_frame/inky_frame_dithering.py b/micropython/examples/inky_frame/inky_frame_dithering.py deleted file mode 100644 index 15c947ec..00000000 --- a/micropython/examples/inky_frame/inky_frame_dithering.py +++ /dev/null @@ -1,68 +0,0 @@ -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" - -graphics = PicoGraphics(DISPLAY) - -WIDTH, HEIGHT = graphics.get_bounds() - -graphics.set_pen(1) -graphics.clear() - -w = int(WIDTH / 8) - -# Solid Colours - -for p in range(8): - graphics.set_pen(p) - graphics.rectangle(w * p, 0, w, 50) - -# "Greydient" - -for x in range(WIDTH): - g = int(x / float(WIDTH) * 255) - graphics.set_pen(graphics.create_pen(g, g, g)) - for y in range(30): - graphics.pixel(x, 60 + y) - -# Rainbow Gradient - -for x in range(WIDTH): - h = x / float(WIDTH) - graphics.set_pen(graphics.create_pen_hsv(h, 1.0, 1.0)) - for y in range(100): - graphics.pixel(x, 100 + y) - -# Block Colours & Text - -graphics.set_pen(graphics.create_pen(128, 128, 0)) -graphics.rectangle(0, 210, 200, 100) -graphics.set_pen(graphics.create_pen(200, 200, 200)) -graphics.text("Hello", 10, 220) -graphics.text("Hello", 10, 240, scale=4.0) - -graphics.set_pen(graphics.create_pen(0, 128, 128)) -graphics.rectangle(200, 210, 200, 100) -graphics.set_pen(graphics.create_pen(200, 200, 200)) -graphics.text("Hello", 210, 220) -graphics.text("Hello", 210, 240, scale=4.0) - -graphics.set_pen(graphics.create_pen(128, 0, 128)) -graphics.rectangle(400, 210, 200, 100) -graphics.set_pen(graphics.create_pen(200, 200, 200)) -graphics.text("Hello", 410, 220) -graphics.text("Hello", 410, 240, scale=4.0) - -# Red, Green and Blue gradients - -for x in range(WIDTH): - g = int(x / float(WIDTH) * 255) - for y in range(20): - graphics.set_pen(graphics.create_pen(g, 0, 0)) - graphics.pixel(x, 320 + y) - graphics.set_pen(graphics.create_pen(0, g, 0)) - graphics.pixel(x, 350 + y) - graphics.set_pen(graphics.create_pen(0, 0, g)) - graphics.pixel(x, 380 + y) - -graphics.update() diff --git a/micropython/examples/inky_frame/inky_frame_news.py b/micropython/examples/inky_frame/inky_frame_news.py deleted file mode 100644 index b59df095..00000000 --- a/micropython/examples/inky_frame/inky_frame_news.py +++ /dev/null @@ -1,192 +0,0 @@ -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" -from network_manager import NetworkManager -import uasyncio -from urllib import urequest -import WIFI_CONFIG -import gc -import qrcode -from machine import Pin -from pimoroni_i2c import PimoroniI2C -from pcf85063a import PCF85063A -import time - -I2C_SDA_PIN = 4 -I2C_SCL_PIN = 5 -HOLD_VSYS_EN_PIN = 2 - -# set up and enable vsys hold so we don't go to sleep -hold_vsys_en_pin = Pin(HOLD_VSYS_EN_PIN, Pin.OUT) -hold_vsys_en_pin.value(True) - -# Uncomment one URL to use (Top Stories, World News and technology) -# URL = "http://feeds.bbci.co.uk/news/rss.xml" -# URL = "http://feeds.bbci.co.uk/news/world/rss.xml" -URL = "http://feeds.bbci.co.uk/news/technology/rss.xml" - -# Length of time between updates in Seconds. -# Frequent updates will reduce battery life! -UPDATE_INTERVAL = 60 * 1 - -graphics = PicoGraphics(DISPLAY) -WIDTH, HEIGHT = graphics.get_bounds() -graphics.set_font("bitmap8") -code = qrcode.QRCode() - -# intialise the pcf85063a real time clock chip -i2c = PimoroniI2C(I2C_SDA_PIN, I2C_SCL_PIN, 100000) -rtc = PCF85063A(i2c) - - -def status_handler(mode, status, ip): - print(mode, status, ip) - - -network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler) - - -def read_until(stream, char): - result = b"" - while True: - c = stream.read(1) - if c == char: - return result - result += c - - -def discard_until(stream, c): - while stream.read(1) != c: - pass - - -def parse_xml_stream(s, accept_tags, group_by, max_items=3): - tag = [] - text = b"" - count = 0 - current = {} - while True: - char = s.read(1) - if len(char) == 0: - break - - if char == b"<": - next_char = s.read(1) - - # Discard stuff like ") - continue - - # Detect ") # Discard ]> - gc.collect() - - elif next_char == b"/": - current_tag = read_until(s, b">") - top_tag = tag[-1] - - # Populate our result dict - if top_tag in accept_tags: - current[top_tag.decode("utf-8")] = text.decode("utf-8") - - # If we've found a group of items, yield the dict - elif top_tag == group_by: - yield current - current = {} - count += 1 - if count == max_items: - return - tag.pop() - text = b"" - gc.collect() - continue - - else: - current_tag = read_until(s, b">") - tag += [next_char + current_tag.split(b" ")[0]] - text = b"" - gc.collect() - - else: - text += char - - -def measure_qr_code(size, code): - w, h = code.get_size() - module_size = int(size / w) - return module_size * w, module_size - - -def draw_qr_code(ox, oy, size, code): - size, module_size = measure_qr_code(size, code) - graphics.set_pen(1) - graphics.rectangle(ox, oy, size, size) - graphics.set_pen(0) - for x in range(size): - for y in range(size): - if code.get_module(x, y): - graphics.rectangle(ox + x * module_size, oy + y * module_size, module_size, module_size) - - -def get_rss(): - try: - stream = urequest.urlopen(URL) - output = list(parse_xml_stream(stream, [b"title", b"description", b"guid", b"pubDate"], b"item")) - return output - - except OSError as e: - print(e) - return False - - -rtc.enable_timer_interrupt(True) - -while True: - # Connect to WiFi - uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK)) - - # Gets Feed Data - feed = get_rss() - - # Clear the screen - graphics.set_pen(1) - graphics.clear() - graphics.set_pen(0) - - # Title - graphics.text("Headlines from BBC News:", 10, 10, 300, 2) - - # Draws 3 articles from the feed if they're available. - if feed: - graphics.set_pen(4) - graphics.text(feed[0]["title"], 10, 40, WIDTH - 150, 3 if graphics.measure_text(feed[0]["title"]) < 650 else 2) - graphics.text(feed[1]["title"], 130, 180, WIDTH - 140, 3 if graphics.measure_text(feed[1]["title"]) < 650 else 2) - graphics.text(feed[2]["title"], 10, 320, WIDTH - 150, 3 if graphics.measure_text(feed[2]["title"]) < 650 else 2) - - graphics.set_pen(3) - graphics.text(feed[0]["description"], 10, 110 if graphics.measure_text(feed[0]["title"]) < 650 else 90, WIDTH - 150, 2) - graphics.text(feed[1]["description"], 130, 250 if graphics.measure_text(feed[1]["title"]) < 650 else 230, WIDTH - 145, 2) - graphics.text(feed[2]["description"], 10, 395 if graphics.measure_text(feed[2]["title"]) < 650 else 375, WIDTH - 150, 2) - - code.set_text(feed[0]["guid"]) - draw_qr_code(WIDTH - 110, 40, 100, code) - code.set_text(feed[1]["guid"]) - draw_qr_code(10, 180, 100, code) - code.set_text(feed[2]["guid"]) - draw_qr_code(WIDTH - 110, 320, 100, code) - - else: - graphics.set_pen(4) - graphics.text("Error: Unable to get feed :(", 10, 40, WIDTH - 150, 4) - - graphics.update() - - # Time to have a little nap until the next update - rtc.set_timer(UPDATE_INTERVAL) - hold_vsys_en_pin.init(Pin.IN) - time.sleep(UPDATE_INTERVAL) diff --git a/micropython/examples/inky_frame/inky_frame_placekitten.py b/micropython/examples/inky_frame/inky_frame_placekitten.py deleted file mode 100644 index 8f072496..00000000 --- a/micropython/examples/inky_frame/inky_frame_placekitten.py +++ /dev/null @@ -1,70 +0,0 @@ -import gc -import uos -import random -import machine -import jpegdec -import uasyncio -import sdcard -import WIFI_CONFIG -from urllib import urequest -from network_manager import NetworkManager -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" - -""" -random placekitten (from a very small set) - -You *must* insert an SD card into Inky Frame! -We need somewhere to save the jpg for display. -""" - -gc.collect() # We're really gonna need that RAM! - - -def status_handler(mode, status, ip): - print(mode, status, ip) - - -network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler) -uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK)) - - -graphics = PicoGraphics(DISPLAY) - -WIDTH, HEIGHT = graphics.get_bounds() -FILENAME = "/sd/placekitten.jpg" -ENDPOINT = "http://placecats.com/{0}/{1}" - - -sd_spi = machine.SPI(0, sck=machine.Pin(18, machine.Pin.OUT), mosi=machine.Pin(19, machine.Pin.OUT), miso=machine.Pin(16, machine.Pin.OUT)) -sd = sdcard.SDCard(sd_spi, machine.Pin(22)) -uos.mount(sd, "/sd") -gc.collect() # Claw back some RAM! - -url = ENDPOINT.format(WIDTH, HEIGHT + random.randint(0, 10)) - -socket = urequest.urlopen(url) - -# Stream the image data from the socket onto disk in 1024 byte chunks -# the 600x448-ish jpeg will be roughly ~24k, we really don't have the RAM! -data = bytearray(1024) -with open(FILENAME, "wb") as f: - while True: - if socket.readinto(data) == 0: - break - f.write(data) -socket.close() -gc.collect() # We really are tight on RAM! - - -jpeg = jpegdec.JPEG(graphics) -gc.collect() # For good measure... - -graphics.set_pen(1) -graphics.clear() - -jpeg.open_file(FILENAME) -jpeg.decode() - -graphics.update() diff --git a/micropython/examples/inky_frame/inky_frame_quote_of_the_day.py b/micropython/examples/inky_frame/inky_frame_quote_of_the_day.py deleted file mode 100644 index ed07297f..00000000 --- a/micropython/examples/inky_frame/inky_frame_quote_of_the_day.py +++ /dev/null @@ -1,171 +0,0 @@ -import gc -import time -import ujson -import uasyncio -import WIFI_CONFIG -from urllib import urequest -from network_manager import NetworkManager -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" - - -ENDPOINT = "https://en.wikiquote.org/w/api.php?format=json&action=expandtemplates&prop=wikitext&text={{{{Wikiquote:Quote%20of%20the%20day/{3}%20{2},%20{0}}}}}" -MONTHNAMES = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] - - -last_date = "" - - -def parse_qotd(text): - print(text) - text = text.split("\n") - author = text[8].split("|")[2][5:-4] - text = text[6][2:] - gc.collect() - return text, author - - -def status_handler(mode, status, ip): - print(mode, status, ip) - - -network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler) - -gc.collect() -graphics = PicoGraphics(DISPLAY) -WIDTH, HEIGHT = graphics.get_bounds() -graphics.set_font("bitmap8") -gc.collect() - - -BADCHARS = { - "’": "'", - "—": "", - "…": "..." -} - - -def display_quote(text, ox, oy, scale, wordwrap): - # Processing text is memory intensive - # so we'll do it one char at a time as we draw to the screen - line_height = 9 * scale - html_tag = "" - word = "" - extra_text = "" - space_width = graphics.measure_text(" ", scale=scale) - x = ox - y = oy - i = -1 - while True: - if len(extra_text) == 0: - i += 1 - if i >= len(text): - break - - if len(extra_text) > 0: - char = extra_text[0] - extra_text = extra_text[1:] - else: - char = text[i] - - if char in BADCHARS: - word += BADCHARS[char] - continue - - # Unpick stuff like [[word]] and [[disambiguation|word]] - # and [[w:wikipedia_page|word]] - # test cases: July 8th 2022, July 12th 2022 - if char == "[": - if text[i:i + 2] == "[[": - link = False - if text[i + 2:i + 4] == "w:": - link = True - i += 2 - end = text[i:].index("]]") - if "|" in text[i + 2:i + end]: - parts = text[i + 2:i + end].split("|") - word = parts[1] - if not link: - extra_text = " (" + parts[0] + ")" - else: - word = text[i + 2:i + end] - i += end + 1 - continue - - if char == "&": - if text[i:i + 5] == "&": - word += "&" - i += 4 - continue - - if char == "<": - j = i + text[i:].index(">") - html_tag = text[i + 1:j].replace("/", "").strip() - i = j - continue - - if char in (" ", "\n") or html_tag == "br": - w = graphics.measure_text(word, scale=scale) - if x + w > wordwrap or char == "\n" or html_tag == "br": - x = ox - y += line_height - - graphics.text(word, x, y, scale=scale) - word = "" - html_tag = "" - x += w + space_width - continue - - word += char - - # Last word - w = graphics.measure_text(word, scale=scale) - if x + w > wordwrap: - x = ox - y += line_height - - graphics.text(word, x, y, scale=scale) - - -while True: - gc.collect() - - uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK)) - - date = list(time.localtime())[:3] - date.append(MONTHNAMES[date[1] - 1]) - - if "{3} {2}, {0}".format(*date) == last_date: - time.sleep(60) - continue - - url = ENDPOINT.format(*date) - print("Requesting URL: {}".format(url)) - socket = urequest.urlopen(url) - j = ujson.load(socket) - socket.close() - - text = j['expandtemplates']['wikitext'] - del j - gc.collect() - - text, author = parse_qotd(text) - - print(text) - - graphics.set_pen(1) - graphics.clear() - graphics.set_pen(0) - graphics.text("QoTD - {2} {3} {0:04d}".format(*date), 10, 10, scale=3) - - display_quote(text, 10, 40, 2, wordwrap=WIDTH - 20) - - graphics.text(author, 10, HEIGHT - 20, scale=2) - - graphics.update() - gc.collect() - - last_date = "{3} {2}, {0}".format(*date) - - time.sleep(60) diff --git a/micropython/examples/inky_frame/inky_frame_random_joke.py b/micropython/examples/inky_frame/inky_frame_random_joke.py deleted file mode 100644 index f67c778e..00000000 --- a/micropython/examples/inky_frame/inky_frame_random_joke.py +++ /dev/null @@ -1,90 +0,0 @@ -import gc -import uos -import random -import machine -import jpegdec -import WIFI_CONFIG -import uasyncio -from network_manager import NetworkManager -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" -from urllib import urequest - - -gc.collect() # We're really gonna need that RAM! - - -def status_handler(mode, status, ip): - print(mode, status, ip) - - -network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler) -uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK)) - - -graphics = PicoGraphics(DISPLAY) - -WIDTH, HEIGHT = graphics.get_bounds() -FILENAME = "/sd/random-joke.jpg" - -JOKE_IDS = "https://pimoroni.github.io/feed2image/jokeapi-ids.txt" -JOKE_IMG = "https://pimoroni.github.io/feed2image/jokeapi-{}-{}x{}.jpg" - -import sdcard # noqa: E402 - putting this at the top causes an MBEDTLS OOM error!? -sd_spi = machine.SPI(0, sck=machine.Pin(18, machine.Pin.OUT), mosi=machine.Pin(19, machine.Pin.OUT), miso=machine.Pin(16, machine.Pin.OUT)) -sd = sdcard.SDCard(sd_spi, machine.Pin(22)) -uos.mount(sd, "/sd") -gc.collect() # Claw back some RAM! - -# We don't have the RAM to store the list of Joke IDs in memory. -# the first line of `jokeapi-ids.txt` is a COUNT of IDs. -# Grab it, then pick a random line between 0 and COUNT. -# Seek to that line and ...y'know... there's our totally random joke ID - -socket = urequest.urlopen(JOKE_IDS) - -# Get the first line, which is a count of the joke IDs -number_of_lines = int(socket.readline().decode("ascii")) -print("Total jokes {}".format(number_of_lines)) - -# Pick a random joke (by its line number) -line = random.randint(0, number_of_lines) -print("Getting ID from line {}".format(line)) - -for x in range(line): # Throw away lines to get where we need - socket.readline() - -# Read our chosen joke ID! -random_joke_id = int(socket.readline().decode("ascii")) -socket.close() - -print("Random joke ID: {}".format(random_joke_id)) - -url = JOKE_IMG.format(random_joke_id, WIDTH, HEIGHT) - -socket = urequest.urlopen(url) - -# Stream the image data from the socket onto disk in 1024 byte chunks -# the 600x448-ish jpeg will be roughly ~24k, we really don't have the RAM! -data = bytearray(1024) -with open(FILENAME, "wb") as f: - while True: - if socket.readinto(data) == 0: - break - f.write(data) -socket.close() -del data -gc.collect() # We really are tight on RAM! - - -jpeg = jpegdec.JPEG(graphics) -gc.collect() # For good measure... - -graphics.set_pen(1) -graphics.clear() - -jpeg.open_file(FILENAME) -jpeg.decode() - -graphics.update() diff --git a/micropython/examples/inky_frame/inky_frame_rtc_demo.py b/micropython/examples/inky_frame/inky_frame_rtc_demo.py deleted file mode 100644 index 004d0b7f..00000000 --- a/micropython/examples/inky_frame/inky_frame_rtc_demo.py +++ /dev/null @@ -1,88 +0,0 @@ -import time -import uasyncio -import WIFI_CONFIG -import inky_frame -from network_manager import NetworkManager -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" - -# Set tz_offset to be the number of hours off of UTC for your local zone. -# Examples: tz_offset = -7 # Pacific time (PST) -# tz_offset = 1 # CEST (Paris) -tz_offset = 0 -tz_seconds = tz_offset * 3600 - -# Sync the Inky (always on) RTC to the Pico W so that "time.localtime()" works. -inky_frame.pcf_to_pico_rtc() - -# Avoid running code unless we've been triggered by an event -# Keeps this example from locking up Thonny when we want to tweak the code -if inky_frame.woken_by_rtc() or inky_frame.woken_by_button(): - graphics = PicoGraphics(DISPLAY) - WIDTH, HEIGHT = graphics.get_bounds() - - graphics.set_pen(1) - graphics.clear() - - # Look, just because this is an RTC demo, - # doesn't mean we can't make it rainbow. - for x in range(WIDTH): - h = x / WIDTH - p = graphics.create_pen_hsv(h, 1.0, 1.0) - graphics.set_pen(p) - graphics.line(x, 0, x, HEIGHT) - - graphics.set_pen(0) - graphics.rectangle(0, 0, WIDTH, 14) - graphics.set_pen(1) - graphics.text("Inky Frame", 1, 0) - graphics.set_pen(0) - - def status_handler(mode, status, ip): - print(mode, status, ip) - - year, month, day, hour, minute, second, dow, _ = time.localtime(time.time() + tz_seconds) - - # Connect to the network and get the time if it's not set - if year < 2023: - connected = False - network_manager = NetworkManager(WIFI_CONFIG.COUNTRY, status_handler=status_handler, client_timeout=60) - - t_start = time.time() - try: - uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK)) - connected = True - except RuntimeError: - pass - t_end = time.time() - - if connected: - inky_frame.set_time() - - graphics.text("Setting time from network...", 0, 40) - graphics.text(f"Connection took: {t_end-t_start}s", 0, 60) - else: - graphics.text("Failed to connect!", 0, 40) - - # Display the date and time - year, month, day, hour, minute, second, dow, _ = time.localtime(time.time() + tz_seconds) - - date_time = f"{year:04}/{month:02}/{day:02} {hour:02}:{minute:02}:{second:02}" - - graphics.set_font("bitmap8") - - text_scale = 8 if WIDTH == 800 else 6 - text_height = 8 * text_scale - - offset_left = (WIDTH - graphics.measure_text(date_time, scale=text_scale)) // 2 - offset_top = (HEIGHT - text_height) // 2 - - graphics.set_pen(graphics.create_pen(50, 50, 50)) - graphics.text(date_time, offset_left + 2, offset_top + 2, scale=text_scale) - graphics.set_pen(1) - graphics.text(date_time, offset_left, offset_top, scale=text_scale) - - graphics.update() - - inky_frame.sleep_for(2) diff --git a/micropython/examples/inky_frame/inky_frame_xkcd_daily.py b/micropython/examples/inky_frame/inky_frame_xkcd_daily.py deleted file mode 100644 index 69e09093..00000000 --- a/micropython/examples/inky_frame/inky_frame_xkcd_daily.py +++ /dev/null @@ -1,78 +0,0 @@ -import gc -import uos -import machine -import jpegdec -import uasyncio -import sdcard -import WIFI_CONFIG -from urllib import urequest -from network_manager import NetworkManager -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME as DISPLAY # 5.7" -# from picographics import PicoGraphics, DISPLAY_INKY_FRAME_4 as DISPLAY # 4.0" -from picographics import PicoGraphics, DISPLAY_INKY_FRAME_7 as DISPLAY # 7.3" - -""" -xkcd daily - -You *must* insert an SD card into Inky Frame! -We need somewhere to save the jpg for display. - -Fetches a pre-processed XKCD daily image from: -https://pimoroni.github.io/feed2image/xkcd-daily.jpg - -See https://xkcd.com/ for more webcomics! -""" - -gc.collect() # We're really gonna need that RAM! - - -def status_handler(mode, status, ip): - print(mode, status, ip) - - -network_manager = NetworkManager("GB", status_handler=status_handler) -uasyncio.get_event_loop().run_until_complete(network_manager.client(WIFI_CONFIG.SSID, WIFI_CONFIG.PSK)) - - -graphics = PicoGraphics(DISPLAY) - -WIDTH, HEIGHT = graphics.get_bounds() -FILENAME = "/sd/xkcd-daily.jpg" -ENDPOINT = "https://pimoroni.github.io/feed2image/xkcd-daily.jpg" - - -sd_spi = machine.SPI(0, sck=machine.Pin(18, machine.Pin.OUT), mosi=machine.Pin(19, machine.Pin.OUT), miso=machine.Pin(16, machine.Pin.OUT)) -sd = sdcard.SDCard(sd_spi, machine.Pin(22)) -uos.mount(sd, "/sd") -gc.collect() # Claw back some RAM! - - -url = ENDPOINT - -if (WIDTH, HEIGHT) != (600, 448): - url = url.replace("xkcd-", f"xkcd-{WIDTH}x{HEIGHT}-") - -socket = urequest.urlopen(url) - -# Stream the image data from the socket onto disk in 1024 byte chunks -# the 600x448-ish jpeg will be roughly ~24k, we really don't have the RAM! -data = bytearray(1024) -with open(FILENAME, "wb") as f: - while True: - if socket.readinto(data) == 0: - break - f.write(data) -socket.close() -gc.collect() # We really are tight on RAM! - - -jpeg = jpegdec.JPEG(graphics) -gc.collect() # For good measure... - -graphics.set_pen(1) -graphics.clear() - -jpeg.open_file(FILENAME) -jpeg.decode() - -graphics.update() diff --git a/micropython/examples/inky_frame/inkylauncher/daily_activity.py b/micropython/examples/inky_frame/inkylauncher/daily_activity.py deleted file mode 100644 index 265c4d4a..00000000 --- a/micropython/examples/inky_frame/inkylauncher/daily_activity.py +++ /dev/null @@ -1,127 +0,0 @@ -import gc -import ujson -from urllib import urequest - -# Length of time between updates in Seconds. -# Frequent updates will reduce battery life! -UPDATE_INTERVAL = 240 - -# API URL -URL = "https://www.boredapi.com/api/activity" - -graphics = None -text = None - -gc.collect() - - -def display_quote(text, ox, oy, scale, wordwrap): - # Processing text is memory intensive - # so we'll do it one char at a time as we draw to the screen - line_height = 8 * scale - html = False - html_tag = "" - word = "" - space_width = graphics.measure_text(" ", scale=scale) - x = ox - y = oy - for char in text: - if char in "[]": - continue - if char == "<": - html = True - html_tag = "" - continue - if char == ">": - html = False - continue - if html: - if char in "/ ": - continue - html_tag += char - continue - if char in (" ", "\n") or html_tag == "br": - w = graphics.measure_text(word, scale=scale) - if x + w > wordwrap or char == "\n" or html_tag == "br": - x = ox - y += line_height - - graphics.text(word, x, y, scale=scale) - word = "" - html_tag = "" - x += w + space_width - continue - - word += char - - # Last word - w = graphics.measure_text(word, scale=scale) - if x + w > wordwrap: - x = ox - y += line_height - - graphics.text(word, x, y, scale=scale) - - -def update(): - global text - gc.collect() - - try: - # Grab the data - socket = urequest.urlopen(URL) - j = ujson.load(socket) - socket.close() - text = [j['activity'], j['type'], j['participants']] - gc.collect() - except OSError: - pass - - -def draw(): - global text - - WIDTH, HEIGHT = graphics.get_bounds() - - # Clear the screen - graphics.set_pen(1) - graphics.clear() - graphics.set_pen(0) - - # Page lines! - graphics.set_pen(3) - graphics.line(0, 65, WIDTH, 65) - for i in range(2, 13): - graphics.line(0, i * 35, WIDTH, i * 35) - - gc.collect() - - # Page margin - graphics.set_pen(4) - graphics.line(50, 0, 50, HEIGHT) - graphics.set_pen(0) - - # Main text - graphics.set_font("cursive") - graphics.set_pen(4) - graphics.set_font("cursive") - graphics.text("Activity Idea", 55, 30, WIDTH - 20, 2) - graphics.set_pen(0) - graphics.set_font("bitmap8") - - if text: - display_quote(text[0], 55, 170, 5, WIDTH - 20) - gc.collect() - graphics.set_pen(2) - graphics.text("Activity Type: " + text[1], 55, HEIGHT - 45, WIDTH - 20, 2) - graphics.text("Participants: " + str(text[2]), 400, HEIGHT - 45, WIDTH - 20, 2) - else: - graphics.set_pen(4) - graphics.rectangle(0, (HEIGHT // 2) - 20, WIDTH, 40) - graphics.set_pen(1) - graphics.text("Unable to get activity data!", 5, (HEIGHT // 2) - 15, WIDTH, 2) - graphics.text("Check your network settings in secrets.py", 5, (HEIGHT // 2) + 2, WIDTH, 2) - - graphics.update() - - gc.collect() diff --git a/micropython/examples/inky_frame/inkylauncher/inky_helper.py b/micropython/examples/inky_frame/inkylauncher/inky_helper.py deleted file mode 100644 index 2d680aee..00000000 --- a/micropython/examples/inky_frame/inkylauncher/inky_helper.py +++ /dev/null @@ -1,154 +0,0 @@ -from pimoroni_i2c import PimoroniI2C -from pcf85063a import PCF85063A -import math -from machine import Pin, PWM, Timer -import time -import inky_frame -import json -import network -import os - -# Pin setup for VSYS_HOLD needed to sleep and wake. -HOLD_VSYS_EN_PIN = 2 -hold_vsys_en_pin = Pin(HOLD_VSYS_EN_PIN, Pin.OUT) - -# intialise the pcf85063a real time clock chip -I2C_SDA_PIN = 4 -I2C_SCL_PIN = 5 -i2c = PimoroniI2C(I2C_SDA_PIN, I2C_SCL_PIN, 100000) -rtc = PCF85063A(i2c) - -led_warn = Pin(6, Pin.OUT) - -# set up for the network LED -network_led_pwm = PWM(Pin(7)) -network_led_pwm.freq(1000) -network_led_pwm.duty_u16(0) - - -# set the brightness of the network led -def network_led(brightness): - brightness = max(0, min(100, brightness)) # clamp to range - # gamma correct the brightness (gamma 2.8) - value = int(pow(brightness / 100.0, 2.8) * 65535.0 + 0.5) - network_led_pwm.duty_u16(value) - - -network_led_timer = Timer(-1) -network_led_pulse_speed_hz = 1 - - -def network_led_callback(t): - # updates the network led brightness based on a sinusoid seeded by the current time - brightness = (math.sin(time.ticks_ms() * math.pi * 2 / (1000 / network_led_pulse_speed_hz)) * 40) + 60 - value = int(pow(brightness / 100.0, 2.8) * 65535.0 + 0.5) - network_led_pwm.duty_u16(value) - - -# set the network led into pulsing mode -def pulse_network_led(speed_hz=1): - global network_led_timer, network_led_pulse_speed_hz - network_led_pulse_speed_hz = speed_hz - network_led_timer.deinit() - network_led_timer.init(period=50, mode=Timer.PERIODIC, callback=network_led_callback) - - -# turn off the network led and disable any pulsing animation that's running -def stop_network_led(): - global network_led_timer - network_led_timer.deinit() - network_led_pwm.duty_u16(0) - - -def sleep(t): - # Time to have a little nap until the next update - rtc.clear_timer_flag() - rtc.set_timer(t, ttp=rtc.TIMER_TICK_1_OVER_60HZ) - rtc.enable_timer_interrupt(True) - - # Set the HOLD VSYS pin to an input - # this allows the device to go into sleep mode when on battery power. - hold_vsys_en_pin.init(Pin.IN) - - # Regular time.sleep for those powering from USB - time.sleep(60 * t) - - -# Turns off the button LEDs -def clear_button_leds(): - inky_frame.button_a.led_off() - inky_frame.button_b.led_off() - inky_frame.button_c.led_off() - inky_frame.button_d.led_off() - inky_frame.button_e.led_off() - - -def network_connect(SSID, PSK): - # Enable the Wireless - wlan = network.WLAN(network.STA_IF) - wlan.active(True) - - # Number of attempts to make before timeout - max_wait = 10 - - # Sets the Wireless LED pulsing and attempts to connect to your local network. - pulse_network_led() - wlan.config(pm=0xa11140) # Turn WiFi power saving off for some slow APs - wlan.connect(SSID, PSK) - - while max_wait > 0: - if wlan.status() < 0 or wlan.status() >= 3: - break - max_wait -= 1 - print('waiting for connection...') - time.sleep(1) - - stop_network_led() - network_led_pwm.duty_u16(30000) - - # Handle connection error. Switches the Warn LED on. - if wlan.status() != 3: - stop_network_led() - led_warn.on() - - -state = {"run": None} -app = None - - -def file_exists(filename): - try: - return (os.stat(filename)[0] & 0x4000) == 0 - except OSError: - return False - - -def clear_state(): - if file_exists("state.json"): - os.remove("state.json") - - -def save_state(data): - with open("/state.json", "w") as f: - f.write(json.dumps(data)) - f.flush() - - -def load_state(): - global state - data = json.loads(open("/state.json", "r").read()) - if type(data) is dict: - state = data - - -def update_state(running): - global state - state['run'] = running - save_state(state) - - -def launch_app(app_name): - global app - app = __import__(app_name) - print(app) - update_state(app_name) diff --git a/micropython/examples/inky_frame/inkylauncher/lib/logging.mpy b/micropython/examples/inky_frame/inkylauncher/lib/logging.mpy deleted file mode 100644 index fc00426e..00000000 Binary files a/micropython/examples/inky_frame/inkylauncher/lib/logging.mpy and /dev/null differ diff --git a/micropython/examples/inky_frame/inkylauncher/lib/sdcard.mpy b/micropython/examples/inky_frame/inkylauncher/lib/sdcard.mpy deleted file mode 100644 index 7f3fd6bd..00000000 Binary files a/micropython/examples/inky_frame/inkylauncher/lib/sdcard.mpy and /dev/null differ diff --git a/micropython/examples/inky_frame/inkylauncher/lib/tinyweb/server.mpy b/micropython/examples/inky_frame/inkylauncher/lib/tinyweb/server.mpy deleted file mode 100644 index a8416347..00000000 Binary files a/micropython/examples/inky_frame/inkylauncher/lib/tinyweb/server.mpy and /dev/null differ diff --git a/micropython/examples/inky_frame/inkylauncher/lib/tinyweb/server.py b/micropython/examples/inky_frame/inkylauncher/lib/tinyweb/server.py deleted file mode 100644 index c61b8b00..00000000 --- a/micropython/examples/inky_frame/inkylauncher/lib/tinyweb/server.py +++ /dev/null @@ -1,662 +0,0 @@ -""" -Tiny Web - pretty simple and powerful web server for tiny platforms like ESP8266 / ESP32 -MIT license -(C) Konstantin Belyalov 2017-2018 -""" -import logging -import uasyncio as asyncio -import uasyncio.core -import ujson as json -import gc -import uos as os -import sys -import uerrno as errno -import usocket as socket - - -log = logging.getLogger('WEB') - -type_gen = type((lambda: (yield))()) # noqa: E275 - -# uasyncio v3 is shipped with MicroPython 1.13, and contains some subtle -# but breaking changes. See also https://github.com/peterhinch/micropython-async/blob/master/v3/README.md -IS_UASYNCIO_V3 = hasattr(asyncio, "__version__") and asyncio.__version__ >= (3,) - - -def urldecode_plus(s): - """Decode urlencoded string (including '+' char). - Returns decoded string - """ - s = s.replace('+', ' ') - arr = s.split('%') - res = arr[0] - for it in arr[1:]: - if len(it) >= 2: - res += chr(int(it[:2], 16)) + it[2:] - elif len(it) == 0: - res += '%' - else: - res += it - return res - - -def parse_query_string(s): - """Parse urlencoded string into dict. - Returns dict - """ - res = {} - pairs = s.split('&') - for p in pairs: - vals = [urldecode_plus(x) for x in p.split('=', 1)] - if len(vals) == 1: - res[vals[0]] = '' - else: - res[vals[0]] = vals[1] - return res - - -class HTTPException(Exception): - """HTTP protocol exceptions""" - - def __init__(self, code=400): - self.code = code - - -class request: - """HTTP Request class""" - - def __init__(self, _reader): - self.reader = _reader - self.headers = {} - self.method = b'' - self.path = b'' - self.query_string = b'' - - async def read_request_line(self): - """Read and parse first line (AKA HTTP Request Line). - Function is generator. - Request line is something like: - GET /something/script?param1=val1 HTTP/1.1 - """ - while True: - rl = await self.reader.readline() - # skip empty lines - if rl == b'\r\n' or rl == b'\n': - continue - break - rl_frags = rl.split() - if len(rl_frags) != 3: - raise HTTPException(400) - self.method = rl_frags[0] - url_frags = rl_frags[1].split(b'?', 1) - self.path = url_frags[0] - if len(url_frags) > 1: - self.query_string = url_frags[1] - - async def read_headers(self, save_headers=[]): - """Read and parse HTTP headers until \r\n\r\n: - Optional argument 'save_headers' controls which headers to save. - This is done mostly to deal with memory constrains. - Function is generator. - HTTP headers could be like: - Host: google.com - Content-Type: blah - \r\n - """ - while True: - gc.collect() - line = await self.reader.readline() - if line == b'\r\n': - break - frags = line.split(b':', 1) - if len(frags) != 2: - raise HTTPException(400) - if frags[0] in save_headers: - self.headers[frags[0]] = frags[1].strip() - - async def read_parse_form_data(self): - """Read HTTP form data (payload), if any. - Function is generator. - Returns: - - dict of key / value pairs - - None in case of no form data present - """ - # TODO: Probably there is better solution how to handle - # request body, at least for simple urlencoded forms - by processing - # chunks instead of accumulating payload. - gc.collect() - if b'Content-Length' not in self.headers: - return {} - # Parse payload depending on content type - if b'Content-Type' not in self.headers: - # Unknown content type, return unparsed, raw data - return {} - size = int(self.headers[b'Content-Length']) - if size > self.params['max_body_size'] or size < 0: - raise HTTPException(413) - data = await self.reader.readexactly(size) - # Use only string before ';', e.g: - # application/x-www-form-urlencoded; charset=UTF-8 - ct = self.headers[b'Content-Type'].split(b';', 1)[0] - try: - if ct == b'application/json': - return json.loads(data) - elif ct == b'application/x-www-form-urlencoded': - return parse_query_string(data.decode()) - except ValueError: - # Re-generate exception for malformed form data - raise HTTPException(400) - - -class response: - """HTTP Response class""" - - def __init__(self, _writer): - self.writer = _writer - self.send = _writer.awrite - self.code = 200 - self.version = '1.0' - self.headers = {} - - async def _send_headers(self): - """Compose and send: - - HTTP request line - - HTTP headers following by \r\n. - This function is generator. - P.S. - Because of usually we have only a few HTTP headers (2-5) it doesn't make sense - to send them separately - sometimes it could increase latency. - So combining headers together and send them as single "packet". - """ - # Request line - hdrs = 'HTTP/{} {} MSG\r\n'.format(self.version, self.code) - # Headers - for k, v in self.headers.items(): - hdrs += '{}: {}\r\n'.format(k, v) - hdrs += '\r\n' - # Collect garbage after small mallocs - gc.collect() - await self.send(hdrs) - - async def error(self, code, msg=None): - """Generate HTTP error response - This function is generator. - Arguments: - code - HTTP response code - Example: - # Not enough permissions. Send HTTP 403 - Forbidden - await resp.error(403) - """ - self.code = code - if msg: - self.add_header('Content-Length', len(msg)) - await self._send_headers() - if msg: - await self.send(msg) - - async def redirect(self, location, msg=None): - """Generate HTTP redirect response to 'location'. - Basically it will generate HTTP 302 with 'Location' header - Arguments: - location - URL to redirect to - Example: - # Redirect to /something - await resp.redirect('/something') - """ - self.code = 302 - self.add_header('Location', location) - if msg: - self.add_header('Content-Length', len(msg)) - await self._send_headers() - if msg: - await self.send(msg) - - def add_header(self, key, value): - """Add HTTP response header - Arguments: - key - header name - value - header value - Example: - resp.add_header('Content-Encoding', 'gzip') - """ - self.headers[key] = value - - def add_access_control_headers(self): - """Add Access Control related HTTP response headers. - This is required when working with RestApi (JSON requests) - """ - self.add_header('Access-Control-Allow-Origin', self.params['allowed_access_control_origins']) - self.add_header('Access-Control-Allow-Methods', self.params['allowed_access_control_methods']) - self.add_header('Access-Control-Allow-Headers', self.params['allowed_access_control_headers']) - - async def start_html(self): - """Start response with HTML content type. - This function is generator. - Example: - await resp.start_html() - await resp.send('