Getting Started with Inky Frame
Inky Frame is a luscious, 7 colour, 5.7" (600 x 448 pixel) programmable E Ink display, powered by Raspberry Pi Pico W. It can go into a deep sleep mode between updates to preserve battery and can be woken back up with a button press or on a timer using the onboard Real Time Clock (RTC).
This beginner friendly tutorial will cover:
how to plug everything in
how to get started programming Inky Frame with MicroPython and Thonny
how to get to grips with our examples
how to display images
some troubleshooting suggestions
What you'll need
An Inky Frame
A micro-USB cable (for programming)
A micro SD card (required for some of the wireless examples)
Some sort of battery if you want to disconnect Inky Frame from your computer - we'll discuss a few options and their pros and cons!
A computer to program from (Windows, Mac or Linux/Raspberry Pi).
AA or AAA batteries
The easiest way to supply Inky Frame with power is via some good old fashioned double or triple A batteries, connected in series. You'll need a battery holder with a JST-PH connector to be able to plug it in. We'd recommend a 3 x AA or 3 x AAA battery pack which should give you plenty of juice to keep going for a good long time.
LiPo / LiIon batteries
Alternatively, you could power Inky Frame from a LiPo battery. Our hard case Galleon LiPo batteries make for a really neat power solution combined with Inky Frame's deep sleep capability, though you might prefer something with more capacity for longer battery life.
A few more things you should consider if you're using a LiPo:
- If you're using a soft LiPo battery you might want to consider fashioning a backplate or case to protect it.
- There's no battery protection included on Inky Frame, so you should only use it with LiPo batteries that include internal protection (all ours do).
- If you've sourced a battery from elsewhere, check that the connector has the red wire going to + and the black wire going to - on our board. Not all batteries have their connectors attached the same way up!
- Inky Frame doesn't have battery charging circuitry onboard. You'll need to plug your battery into an external LiPo charger (like a LiPo Amigo) to charge it.
- If you wanted to add USB-C battery charging capability (and a power button!) to Inky Frame you could add a LiPo Amigo Pro to the back (you'll also need one of these cables).
Assembling the Inky Frame Accessory Kit
Our Accessory Kit contains legs to let your Inky stand up, an AA battery pack and fixings, a USB cable and an SD card. Here's how to put it all together!
Attaching the legs
From the front, poke the rounded screws through the larger set of holes at the bottom of Inky Frame.
Then screw the legs onto the screw threads!
Inserting the SD card
The SD card goes into the slot on the back of Inky Frame (it will only go in one way). It's a spring loaded slot, so should you ever want to remove it you'll need to push it in to get it to pop out.
Attaching the battery pack
Our Inky Frame accessory kit comes with some Velcro for sticking the battery pack on. Before you start sticking things down, experiment a little bit with the positioning of the battery pack:
- If you're planning on hanging Inky Frame from a hook you'll want to make sure the battery pack is balanced in the middle to avoid it hanging lopsided.
- If you want to be able to use the on/off switch on your battery pack make sure you stick the Velcro to the other side!
- Make sure the reset button is accessible and not squashed down by the battery pack.
- Once you're happy with the placement, press the squares down (avoiding pressing directly on the screen) and then wait 10 minutes for the adhesive to set.
MicroPython and Inky Frame
Our custom MicroPython build is the easiest way to get started with Inky Frame. It comes with a built in tiny graphics library called PicoGraphics, which contains lots of tools for drawing on Inky Frame's screen, including drawing text and shapes, rendering images and generating QR codes!
Inky Frame ships without firmware (although we do put an image on the screen as part of our testing process) - you'll need to install our custom MicroPython build on it before you can run code on it.
First of all you'll need to download our most recent batteries included MicroPython image, and copy it to the Pico W. We'd recommend using v1.19.6 or later, as it includes a fix for an annoying bug that can crop up when saving code that connects to wireless as
If you're brand new to Raspberry Pi Pico/RP2040s, you might find the step by step instructions in our Getting Started with Raspberry Pi Pico tutorial useful - it will show you how to install our custom MicroPython build and goes into more detail about how to use Thonny . Here's a quick TLDR!
- Download the most recent MicroPython .uf2 from the Releases page of our pimoroni-pico Github repository. Click on 'assets' to expand the list of files - you'll want the Pico W flavoured image for Inky Frame.
- Connect Inky Frame to your computer with a USB cable.
- Hold down the BOOT button of Inky Frame, and then tap the RESET button. This will put it into bootloader mode, and it should appear as a drive on your computer called RPI-RP2.
- Copy the .uf2 file to the RPI-RP2 drive - once you've done that Inky Frame will reboot.
Programming Inky Frame with Thonny
Once MicroPython is installed, Inky Frame won't show up as a drive on your computer any more. To program it, you'll need to talk to it through an interpreter - we're using Thonny, which is available for Windows, Mac or Linux.
- Install Thonny
- Open up Thonny. Make sure the interpreter (shown in the box on the bottom right corner) is set to 'MicroPython (Raspberry Pi Pico)'.
- Plug Inky Frame into your computer, if it's not plugged in already.
- The flashing cursor next to the >>> in the 'Shell' box tells you that Inky Frame is talking to your computer and is ready to accept instructions. If you don't see the MicroPython prompt in the shell box, try pressing the red stop button in Thonny to interrupt whatever it's doing.
⚠Couldn't find the device automatically?
Our version of Thonny didn't manage to detect our board automatically - probably because the Pico W image is based on brand new v1.19 MicroPython. We had to specify the port our device was using, you can do this by clicking on 'MicroPython (Raspberry Pi Pico) at the bottom right, and selecting 'Configure Interpreter'. Select your device under 'Port' - ours was showing up as 'COM5.
Lighting up the activity LED
As a test that everything's working OK, let's light up the activity LED (that's the one with the flag next to it). Enter the following code line by line in the REPL (that's the bottom 'Shell' box in Thonny).
from machine import Pin led = Pin(6, Pin.OUT) led.value(1)
Let's turn off the LED again, to be tidy!
You can light up the other LEDs in the same way, just change the pin number in the code above. Inky Frame's LEDs are connected to the following pins on the Pico W:
Activity LED -
Connect LED -
A, B, C, D, E -
11, 12, 13, 14, 15
You can also set the brightness of the LEDs to values between 0 and 1 using PWM.
Writing text on the screen
Here's a simple example of how to display text on the E Ink screen using the PicoGraphics library. Copy and paste this code into a new tab in Thonny, and then click on the 'run' button.
from picographics import PicoGraphics, DISPLAY_INKY_FRAME display = PicoGraphics(display=DISPLAY_INKY_FRAME) BLACK = 0 WHITE = 1 GREEN = 2 BLUE = 3 RED = 4 YELLOW = 5 ORANGE = 6 TAUPE = 7 display.set_pen(WHITE) display.clear() display.set_pen(BLACK) display.text("Hello Inky", 0, 0, 600, 4) display.update()
The first two lines set up the Inky display - you'll need to start any code that uses the screen like this.
The rest of the code does this:
set_penline tells your program what pen you want to start writing with. Inky Frame has seven pen colours to choose from (plus a mysterious eighth 'cleaning' colour, taupe).
display.clear()fills the whole screen with the last selected pen colour - we're using it here to start with a white background.
display.textwrites text to the screen buffer. When using a bitmap font, the '0, 0' is the x/y co-ordinates of the top left of the text. '600' is when text will start wrapping onto the next line (so needs to be the width of the screen in most cases). The final number '4' is the scale of the text, reduce or increase it to shrink or embiggen!
display.updateupdates the screen (you can draw multiple things to your screen buffer before triggering an update).
The default font is
bitmap6, which is all uppercase and a little small and blocky. Switching to
bitmap8 gives you upper and lower case and a bit more definition (it also includes more special characters like °)
from picographics import PicoGraphics, DISPLAY_INKY_FRAME display = PicoGraphics(display=DISPLAY_INKY_FRAME) BLACK = 0 WHITE = 1 GREEN = 2 BLUE = 3 RED = 4 YELLOW = 5 ORANGE = 6 TAUPE = 7 display.set_pen(WHITE) display.clear() display.set_pen(BLACK) display.set_font('bitmap8') display.text("Hello Inky", 0, 0, 600, 4) display.update()
More drawing functions
There are more functions in the library for using vector fonts and drawing individual pixels, lines and shapes. Check out the PicoGraphics function reference for more info!
Running the examples
You can find all the Inky Frame examples at the link below:
Click on one to open it up, and copy and paste the code into a new tab in Thonny (if you click the 'raw' button on Github first it will make it easier to copy and paste). Press the green run button in Thonny to run the code.
Installing supporting libraries
To run the wireless examples (and the ones using the SD card) you'll need to copy some extra libraries to your Pico. You could copy and paste the files from the common folder on Github and save them to your Pico one by one if you wanted to, but we're going to download the whole lot as it's easier to move multiple files around.
On the front page of the pimoroni-pico repo, click on the green code button and select 'download ZIP' - this will download the whole repo to your computer. Unzip it somewhere where you can find it easily.
Then, switch back to Thonny. For the next step you'll need to have the Files window visible in Thonny, you can open it up with 'View > Files'.
The top box can be used to browse the local files in on your computer, and the bottom box shows the files on Inky Frame. Find your unzipped repo and navigate to
micropython/examples/common in the top box.
You'll need a bunch of stuff out of the
common/lib folder to run the examples, so you might as well grab the whole thing - right click on
lib in the top box and select 'Upload to /' to transfer it to your Pico. You'll also need
WIFI_CONFIG.py, so right click on those and upload them to your Pico as well.
Once you're done, the files on your Pico W should look something like this:
WIFI_CONFIG.py should be in the root directory of your Pico W, and the other libraries should be inside a folder called
Adding Wi-Fi credentials
For the examples that use wireless to work, your Pico W will need to know your wireless network details. Double click on the copy of
WIFI_CONFIG.py that's on your Pico W to open it up in Thonny. Add your network's SSID, password and country code (if you're in the UK like us then your country code should be "GB" - if not check this list). Note that SSID and password are case sensitive! Once that's done, click save.
If your credentials are correct, the wireless examples should now work!
Pirate flavour MicroPython can now decode jpegs, woohaa! Here's how to get an image onto that beautiful Inky Frame screen.
You should resize your images to 600 x 448 pixels (or smaller) using an image editor (we're using GIMP) before copying them across to Inky Frame. When exporting your jpeg, we found we had to open up 'advanced options' and untick the 'progressive' option for it to work with
jpegdec. We saved our images at 70% quality to help keep the file size down.
Navigate to your jpeg in the top Files window, right click on it and upload it to your Pico W. Here's how to show the image:
from picographics import PicoGraphics, DISPLAY_INKY_FRAME from jpegdec import JPEG display = PicoGraphics(display=DISPLAY_INKY_FRAME) j = JPEG(display) j.open_file("jwst1.jpg") j.decode() display.update()
You can find demo images to use, plus an offline photo frame example which switches between images and goes to sleep when on battery power here (or in
micropython/examples/inky_frame/image_gallery if you downloaded a local copy). Thanks Webb Space Telescope, we really loved your photos. Who'd have thought it would be possible to see the Raspberry Pi Picow from 1.5 million kilometers away?
PicoGraphics will dither your image into the eight colours that are available on Inky Frame to save RAM. When prepping our images, we found we got best results by boosting the saturation and black levels up a bit. In GIMP, you can do this with 'Colors' > 'Saturation' and 'Colors' > 'Exposure'.
Hopefully this tutorial will have helped you grok the basics of getting text and images onto Inky Frame - next stop The Interwebs! Drop us a line on Twitter or on our forums and let us know what you're using it for - we'd love to know!
How do I make an example run whenever Inky Frame's powered up?
Save your example as
main.py if you want it to run automatically every time Inky Frame is powered up or reset. It's a good idea to test your code is working as expected before you do this, as a malfunctioning
main.py can lock up your Pico and stop it from communicating with Thonny.
How do I factory reset?
If you do find yourself in a sticky
main.py situation, you can delete all your programs from Inky Frame's flash memory and start again from scratch by downloading this special .uf2 file and copying it to Inky Frame whilst it's in bootloader/DFU mode. Once you've done that, you'll need to copy the MicroPython image across again.
You may also find clearing the flash to be useful if you encounter problems after upgrading to the newest version of MicroPython - just make sure you save any code you've been working on to your computer first!
If Inky Frame is plugged in via USB, it will never go into deep sleep mode. It will spring into life and attempt to run
main.py as soon as it has USB power, just like any Pico/RP2040 board running MicroPython.
However, if you're powering Inky Frame by battery things will work a little differently - the hardware level power saving features will kick in, which can be a bit confusing and make it look like you have a duff battery.
Once you hit reset on a battery powered Inky, you'll have to press one of the buttons to trigger it to wake up and run
main.py. If this doesn't seem to be working, try holding one of the front buttons down for a second or two - it needs a fairly solid press to wake it up (this is because there's a short delay whilst MicroPython starts up, so it can miss quick button presses).
You can force Inky Frame to stay awake (which is useful when you're doing things with wireless, for example) by holding the vsys enable pin , like this:
import machine HOLD_VSYS_EN_PIN = 2 # set up and enable vsys hold so we don't go to sleep hold_vsys_en_pin = machine.Pin(HOLD_VSYS_EN_PIN, machine.Pin.OUT) hold_vsys_en_pin.value(True)
You can send it back to sleep by reversing the direction of this pin:
SD card problems?
We've found that MicroPython can be slightly fussy with SD cards, especially larger ones. If you're having trouble reading from your SD card, try reformatting it with FAT and a small block size - we managed to get most SD cards we tried working like this (though we did find a few that stubbornly refused to play).
Using the wireless stack currently uses lots of the Pico W's available RAM - which can be a problem when driving a large display. We're hoping for this situation to improve as MicroPython for Pico W enters a less beta state, but for the moment at least you'll need to be conscious of RAM usage when using wireless and Inky Frame together - the good news is that PicoGraphics is written with conservation of RAM in mind!
Things that we've found that help avoid memory errors (like
making sure you close HTTP sockets after opening them
downloading images to your SD card rather than straight into RAM
incorporating garbage collection (
gc.collect) into your code - see this example for a demonstration!
Some of our examples use the Real Time Clock's timer function to wake up Inky every so many seconds. If you try and increase the number of seconds over 255, you may see an error like this:
ValueError: ticks out of range. Expected 0 to 255
This is because the RTC is only able to keep track of a certain number of 'ticks'. It is possible to make it sleep for longer though - check out this Github issue for some suggestions of how to do that!
Search above to find more great tutorials and guides.