Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 14:25 05 Jul 2026 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Next project: Micropython on the Pico Computer 3 - progress reports

Author Message
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11589
Posted: 03:22pm 02 Jul 2026
Copy link to clipboard 
Print this post

It is clear that, as good as MMbasic is, there is a category of users who will go "yuck - basic"

However in MMBasic on the PicoMite there is a huge amount of useful IP so I thought why not integrate some of that into Micropython

My target platform is the Pico Computer 3 (One board to rule them all) as that has everything that any self-respecting stand-alone Micropython computer could need for hardware.

There is a bit of a learning curve getting a micropython build environment up and running, particularly on windows where it has to run under Ubuntu on wsl. However, with that out of the way I could start integrating.

I used as a starting point the Pico2-W version of micropython. This give things like pin access (digital in/out, analogue in, i2c, spi) as well as web support and a LFS file system in the flash memory (same as the MMbasic A: drive).

First thing was then to enable PSRAM and the extra RP2350B pins.

Next job was to swap the cdc console for a serial one so the USB could be reserved for USB host activiites.

Then the sdcard drivers from MMbasic were ported across so the sd could be read.

Next an editor was added (pye at the moment but this may get upgraded) and the ability to run a program from SDcard added.

Last easy bit was adding support for all the standard command line actions
  Quote  Command Action
pwd() print working directory
cd("/sd") change directory (no arg → /)
ls("/sd") list (dirs first, sizes, dates)
mkdir("/sd/proj") make directory
rmdir("/sd/proj") remove empty directory
rm("/sd/old.py") delete a file
cat("/sd/notes.txt") print a text file
cp("/sd/a.py", "/sd/b.py") copy a file
mv("/sd/a.py", "/flash") move/rename
edit(...), run(...) editor / launch


That was the easy stuff out of the way now the fun bit

First big decision was what HDMI resolutions should be supported. This may come back to bite but currently 307,200bytes are allocated to a framebuffer allowing 640x480 RGB332 and 320x240 RGB565.
This has been implemented and so far so good. HDMI is up and running and you can swap between the two modes without rebooting.
Micropython includes a framebuf module that has the usual graphics commands - circles etc. so this has been integrated.
Now underway is reflecting the serial console commands onto the screen. that works but is still WIP.
The next crucial bit of the jigsaw will be moving the MMbasic HID host functionality across. AFAIK this is not typically available in any micropython port so that will be an adventure. I'll keep you informed. If you want to play get yourself a PicoComputer 3 or patch wire something using the same pinout.
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1979
Posted: 07:18pm 02 Jul 2026
Copy link to clipboard 
Print this post

I wanted to ask about the plan but didn't want to distract you.

Does this mean compatibility with Mpython libraries (they seem to support every darned thing)?
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11589
Posted: 11:17am 03 Jul 2026
Copy link to clipboard 
Print this post

HID host functionality now running with USB keyboard able to interact in the full set of language variants so we have achieved
"stand-alone status".
I'm now working on audio.
Whatever, anyone has claimed before Micropython is significantly slower than MMBasic. Taking approximately twice the time to run functionally equivalent benchmarks.
All Micropython libraries that are available should work with no issues. For example, the first test of audio required no code changes as I2S can be called direct from python
from machine import I2S, Pin
import array, math
N = 100                                   # 44100/100 = exactly 441 Hz
cyc = array.array('h')                    # array append is amortised O(1)
for i in range(N):
   v = int(18000 * math.sin(2*math.pi*i/N))
   cyc.append(v); cyc.append(v)          # L, R
mv = memoryview(cyc)
i2s = I2S(0, sck=Pin(10), ws=Pin(11), sd=Pin(22),
         mode=I2S.TX, bits=16, format=I2S.STEREO, rate=44100, ibuf=8192)
for _ in range(441):                      # ~1 s, starts instantly
   i2s.write(mv)

Edited 2026-07-03 21:19 by matherp
 
PhenixRising
Guru

Joined: 07/11/2023
Location: United Kingdom
Posts: 1979
Posted: 12:13pm 03 Jul 2026
Copy link to clipboard 
Print this post

  matherp said  
Whatever, anyone has claimed before Micropython is significantly slower than MMBasic. Taking approximately twice the time to run functionally equivalent benchmarks.


Makes me even more proud of the awesome MMBasic    
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11589
Posted: 02:29pm 03 Jul 2026
Copy link to clipboard 
Print this post

Audio WAV, Flac and MP3 playback all now working. DS3231 integrated and working. Next is some enhancements to HDMI and then to enhance the ls command and a first release is there.
Edited 2026-07-04 02:06 by matherp
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11589
Posted: 07:05pm 03 Jul 2026
Copy link to clipboard 
Print this post

Continuing to go well.
We now have a 512x300x16-bit mode (MMBasic can't do this) as well as allowing 640x480x8 and 320x240x16-bits at 252 or 378MHz. The  512x300x16-bit mode has been tested while playing an mp3 and connecting to wifi at the same time. Not bad when the video bandwidth is 19.3 M words/s.
ls now allows filtering ls("/sd/*.jpg") and yet more code is being imported from MMbasic jpg, png, bmp display and bmp save.
After that it is some small niceties and I will release a first beta.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 11589
Posted: 02:41pm 04 Jul 2026
Copy link to clipboard 
Print this post

Here is the first cut uf2 and the user manual. Note, it will probably run up on any RP2350B but only if there is PSRAM on GP47, its uses a serial console on GP8,GP9. The usb port is dedicated to host functionality so after flashing it is best to disconnect the USB and use a power supply.


Pico Computer 3 Micropython firmware V0.1.zip


  Quote  # Pico Computer 3 — MicroPython User Manual

**Firmware:** MicroPython (RP2350B port) for the Pico Computer 3 — version **0.1** (test release).
The REPL banner reports the version:

```
MicroPython v1.29.0 on PICO COMPUTER 3 v0.1 with RP2350B
```

This is a customised build of MicroPython that turns the Pico Computer 3 into a
self-contained computer: HDMI display, USB keyboard/mouse/touch, SD card, audio,
a real-time clock and Wi-Fi, all usable directly from the Python prompt. Much of
the functionality is ported from the PicoMite MMBasic firmware.

For the core Python language and the standard library, see the official
MicroPython documentation: **https://docs.micropython.org/** (choose the version
shown in the banner). This manual documents only what is *specific to the Pico
Computer 3*.

---

## 1. Getting started

There are two consoles, and both are active at once:

- **Serial console** — UART1 on **GP8 (TX)** / **GP9 (RX)**, **115200 8N1**.
 Connect a USB-serial adapter and open a terminal (TeraTerm, PuTTY, `screen`,
 `mpremote`). The Delete key works as forward-delete.
- **On-screen console** — text appears on the HDMI monitor and a USB keyboard
 drives it. This starts automatically at boot. `console(False)` detaches it,
 `console()` re-attaches it.

The USB device port is disabled (there is no USB-CDC prompt); the USB port is a
**host** port for keyboards, mice and touch panels.

At the prompt you can type Python directly, or use the shell-style helpers
(section 4). To run a program from the SD card or flash:

```python
run("/sd/myprog.py")
```

---

## 2. Pin allocations

The Pico Computer 3 is based on the RP2350B (48 GPIO). The following pins are
dedicated to on-board functions. Pins marked **reserved** are protected and
cannot be claimed with `machine.Pin()`.

| Function | Pin(s) | Notes |
|---|---|---|
| Console UART1 | **GP8** TX, **GP9** RX | 115200 8N1 — *reserved* |
| HDMI (HSTX DVI) | **GP12–GP19** | CLK GP13/12, D0 GP15/14, D1 GP17/16, D2 GP19/18 (differential pairs) — *reserved* |
| SD card (SPI1) | SCK **GP30**, MOSI **GP31**, MISO **GP28**, CS **GP33** | also `machine.SPI(1)` — *reserved* |
| Audio I2S (PCM5102 DAC) | BCLK **GP10**, LRCK **GP11**, DIN **GP22** | SCK pin grounded on the board |
| RTC (DS3231, I2C0) | SDA **GP20**, SCL **GP21** | 400 kHz, address 0x68 |
| PSRAM chip-select | **GP47** | 8 MB PSRAM |
| Wi-Fi / Bluetooth (CYW43) | REG_ON **GP23**, DATA **GP24**, CS **GP25**, CLK **GP29** | wireless chip over PIO-SPI — *reserved* |
| Status LED | CYW43 **GPIO0** | on the wireless chip (not an RP2350 pin) — named pin `"LED"` |
| USB host | native USB port | keyboard / mouse / touch |

The **status LED** is on the CYW43 wireless chip, not on an RP2350 GPIO. It is
exposed as the named pin `"LED"` (an "extended" pin) and driven like any output —
the driver relays the value to the chip over the internal SPI link:

```python
from machine import Pin
led = Pin("LED", Pin.OUT)
led.on(); led.off(); led.toggle()   # also aliased as Pin("WL_GPIO0")
```

Reserved GPIOs (unavailable to `machine.Pin`): **8, 9, 12–19, 23, 24, 25, 28,
29, 30, 31, 33**. Of these, **23/24/25/29** are the CYW43 Wi-Fi/Bluetooth
interface. All other GPIOs are free for your own use with `machine.Pin`,
`machine.ADC`, `machine.PWM`, `machine.I2C`, `machine.SPI`, `rp2.PIO`, etc.

### System configuration

- **CPU clock:** 252 MHz from boot (can be raised to 315 or 378 MHz — see
 `screen()` in section 5). `machine.freq()` reports it. The clock is coupled to
 the HDMI pixel clock, so it must be changed *together with* the display mode via
 `screen(mode, clock)` — the raw `machine.freq(hz)` setter is disabled and raises
 an error pointing you to `screen()`.
- **Floats:** double precision (64-bit). Integers are arbitrary precision.
- **Flash filesystem:** 12 MB LittleFS mounted at `/`.
- **SD card:** FAT, mounted at `/sd`, hot-swappable (section 12).
- **PSRAM:** 8 MB — the Python heap lives here, so large data/images/audio
 buffers are fine.

---

## 3. Modules imported automatically at boot

At start-up the board adds a set of names to the interactive namespace (`__main__`)
so they are available without an `import`. A program launched with `run()`
inherits the same names. The most useful are:

**Modules / objects:** `os`, `machine`, `Pin` (= `machine.Pin`), `framebuf`,
`hdmi`, `Display`, and the named colour palette (`RED`, `GREEN`, `BLUE`, `WHITE`,
`BLACK`, `YELLOW`, `CYAN`, `MAGENTA`, …).

**Shell commands:** `ls`, `run`, `edit`, `pwd`, `cd`, `mkdir`, `rmdir`, `rm`,
`cat`, `cp`, `mv`, `console`.

**Display / settings:** `screen`, `keymap`, `keymaps`.

**Audio:** `play`, `volume`, `beep`, `stop`, `is_playing`.

**Clock:** `settime`, `gettime`, `synctime`.

**Images:** `draw_jpg`, `draw_bmp`, `draw_png`, `save_image`.

**Input devices:** `touch`, `mouse`, `mouse_speed`.

Each is described in the sections below.

---

## 4. Shell commands

Unix-like helpers for working with the filesystem from the prompt. Paths may be
on the flash (`/…`) or the SD card (`/sd/…`).

| Command | Description |
|---|---|
| `ls([path])` | List a directory. Accepts glob patterns: `ls("/sd/*.mp3")` |
| `cd(path)` / `pwd()` | Change / show the working directory |
| `cat(path)` | Print a text file |
| `cp(src, dst)` / `mv(src, dst)` | Copy / move (rename) a file |
| `rm(path)` | Delete a file |
| `mkdir(path)` / `rmdir(path)` | Create / remove a directory |
| `run(path)` | Run a `.py` program (fresh namespace, inherits the REPL helpers) |
| `edit(path)` | Open the full-screen **pye** editor (Ctrl-S save, Ctrl-Q quit) |

---

## 5. Display (HDMI)

The HDMI output is a hardware DVI signal generated by the RP2350 HSTX and scanned
out on core 1. Three modes are available:

| Mode constant | Resolution | Colour |
|---|---|---|
| `hdmi.RGB640` | 640 × 480 | 8-bit (256 colours) — **default** |
| `hdmi.RGB320` | 320 × 240 | 16-bit (RGB565), pixel-doubled to 640 × 480 |
| `hdmi.RGB512` | 512 × 300 | 16-bit, doubled to 1024 × 600 |

The framebuffer lives in SRAM. In `RGB640` each pixel is one byte (RGB332); in
the two 16-bit modes each pixel is an RGB565 half-word. The image decoders
(section 10) and the on-screen console draw into this same buffer.

### Changing mode: `screen()` — the easy, persistent way

`screen(mode, clock=252)` is the recommended way to change the display. It stops
and restarts the scanout, saves the choice, and re-establishes the on-screen
console at the new geometry:

```python
screen(hdmi.RGB320)        # 320x240 16-bit, 252 MHz
screen(hdmi.RGB640, 378)   # 640x480 8-bit at 378 MHz
screen(hdmi.RGB512)        # 1024x600 16-bit (fixed at 252 MHz)
screen()                   # returns the saved (mode, clock)
```

The optional `clock` is the CPU/pixel clock and applies **only to `RGB640` and
`RGB320`**, which accept one of **252**, **315** or **378** MHz (default 252).
`RGB512` is fixed at 252 MHz — passing any other clock for it raises a
`ValueError`. The chosen mode/clock is saved and restored on the next boot
(section 13). If a saved mode does not suit your monitor, the serial console
still works — use `screen(hdmi.RGB640)` to reset it.

### Low-level control: `hdmi.init()` / `hdmi.deinit()`

`screen()` is a wrapper around the `hdmi` module. You can drive it directly for a
**one-off** (non-persisted) change, but you must stop the current scanout before
starting a new mode:

```python
hdmi.deinit()              # stop the scanout (frees core 1, aborts its DMA)
hdmi.init(hdmi.RGB320)     # start a new mode (default 640x480 @ 252)
import pcconsole; pcconsole.console()   # re-attach the on-screen console
```

- `hdmi.init(mode=hdmi.RGB640, clock=252)` — start the scanout. Raises
 `ValueError` on a bad mode or clock. **No-op if already running** — call
 `hdmi.deinit()` first to switch modes.
- `hdmi.deinit()` — stop the scanout: halts core 1, cleanly aborts the DMA and
 stops the HSTX output. After this the screen goes blank until the next
 `hdmi.init()`.

Because a raw `hdmi.init/deinit` does **not** move the console or save the
setting, prefer `screen()` unless you specifically want a temporary change or are
managing the framebuffer yourself.

### Drawing

`hdmi.fb()` returns a **`Display`** object — a `framebuf.FrameBuffer` subclass
with all the usual `framebuf` methods (`pixel`, `hline`, `vline`, `line`, `rect`,
`fill_rect`, `ellipse`, `text`, `blit`, `scroll`, …) plus a colour helper:

```python
d = hdmi.fb()
d.fill(d.colour(0x000080))              # 24-bit RGB -> current format
d.rect(10, 10, 100, 60, d.colour(RED))  # named palette colour
d.text("Hello", 20, 30, d.colour(WHITE))
```

Rebuild the `Display` (call `hdmi.fb()` again) after any mode change, because the
geometry and pixel format change.

**Colours must be converted first.** The `framebuf` drawing methods take a colour
in the framebuffer's *native* pixel format, so always wrap a colour in
`d.colour(...)`: `d.colour(0xRRGGBB)` or `d.colour(r, g, b)` converts a 24-bit
RGB value (including the named palette constants `RED`, `WHITE`, …) to the current
format. Passing a raw 24-bit value straight to `rect`/`text`/etc. gives the wrong
colour. (`d.color(...)` is an accepted US-spelling alias.) `d.text()` uses
framebuf's built-in 8×8 font; the console uses a larger 8×12 font.

### `hdmi` module reference

| Member | Description |
|---|---|
| `hdmi.RGB640` / `RGB320` / `RGB512` | mode constants (see the table above) |
| `hdmi.init(mode=RGB640, clock=252)` | start the scanout (no-op if running) |
| `hdmi.deinit()` | stop the scanout (call before re-`init()` for a new mode) |
| `hdmi.fb()` | a `Display` (framebuf subclass) over the framebuffer — rebuild after a mode change |
| `hdmi.framebuffer()` | the raw framebuffer as a writable `bytearray` (for `framebuf.FrameBuffer` or the image decoders) |
| `hdmi.width()` / `hdmi.height()` | current logical width / height in pixels |
| `hdmi.rgb565()` | `True` if the framebuffer is RGB565 (RGB320/RGB512), `False` if RGB332 (RGB640) |
| `hdmi.fill(colour)` | fast fill of the whole framebuffer with a **native-format** colour (e.g. `hdmi.fill(hdmi.fb().colour(BLUE))`) |
| `hdmi.scroll(rows, colour=0)` | fast vertical scroll up by `rows` pixels, filling the exposed bottom with `colour` (native format) |
| `hdmi.putc(x, y, ch, fg, bg)` | blit one 8×12 console glyph at pixel `x,y` (native-format `fg`/`bg`) |
| `hdmi.test()` | draw an 8-bar colour test pattern |
| `hdmi.gen()` | mode-change counter (used internally by the console) |

Note that `hdmi.fill()`, `hdmi.scroll()` and `hdmi.putc()` take colours already
in the framebuffer's native format — convert with `hdmi.fb().colour(...)` first.

The on-screen text console uses an 8×12 font (80 columns × 40 rows at 640×480).

---

## 6. USB keyboard

A USB keyboard is detected automatically and drives both the on-screen console
and the serial REPL. On connect you will see `USB keyboard -> slot 1`.

### Layouts

```python
keymap("UK")      # set the layout (persisted across reboots)
keymap()          # return the current layout name
keymaps()         # list available layouts
```

Layouts: **US, UK, DE, FR, ES, BE**. The choice is saved and restored at boot.

### Lock LEDs

Caps Lock, Num Lock and Scroll Lock toggle the keyboard's physical LEDs, and the
correct LED state is set when a keyboard is plugged in.

---

## 7. USB mouse

A USB mouse is detected automatically (`USB mouse -> slot 2`). It maintains a
virtual cursor position (accumulated from movement, clamped to the screen,
starting centred). Read it with **`mouse(code)`**:

| `mouse(code)` | Returns |
|---|---|
| `"X"` / `"Y"` | cursor position in pixels |
| `"L"` / `"R"` / `"M"` | left / right / middle button (1 = pressed) |
| `"W"` | scroll-wheel accumulator |
| `"B"` | button bitmap (1 = L, 2 = R, 4 = M) |
| `"D"` | left-button double-click (within 500 ms; clears on read) |
| `"T"` | 3 if the mouse has a wheel, else 0 |
| `"PRESENT"` | 1 if a mouse is connected |
| `"SLOT"` | the HID slot (2) |

`mouse_speed(v)` sets movement sensitivity (higher = slower); `mouse_speed()`
returns it. Standard, high-resolution and 16-bit gaming mice are supported.

```python
import time
while True:
   print(mouse("X"), mouse("Y"), mouse("L"))
   time.sleep_ms(100)
```

---

## 8. USB touch screen

A USB multi-touch panel is detected automatically (`USB touch -> slot 4`). It
begins reporting a couple of seconds after connection. Read it with
**`touch(code)`**. Coordinates are in screen pixels; latched gestures are
one-shot (reading them clears the event).

**Position / contacts**

| `touch(code)` | Returns |
|---|---|
| `"X"` / `"Y"` | first contact, or **-1** when nothing is touching |
| `"DOWN"` / `"UP"` | 1/0 — is the screen being touched |
| `"X2"` / `"Y2"` | second contact, or -1 |
| `"XN", n` / `"YN", n` | nth contact (n = 1…); **n = 0 → number of contacts** |
| `"PRESENT"` / `"SLOT"` | panel connected? / its slot (4) |

**Gestures** (each clears when read)

| `touch(code)` | Returns |
|---|---|
| `"SWIPE"` | 0 none / 1 left / 2 right / 3 up / 4 down |
| `"SWL"` / `"SWR"` / `"SWU"` / `"SWD"` | 1 if that swipe just happened |
| `"TAP"` / `"HOLD"` / `"DTAP"` | tap / long-press / double-tap |
| `"PINCH"` | 0 none / 1 expand / 2 contract |
| `"EXPAND"` / `"CONTRACT"` | 1 if that pinch just happened |
| `"ROTATE"` | 0 none / 1 clockwise / 2 counter-clockwise |
| `"CW"` / `"CCW"` / `"TTAP"` | rotate CW / CCW / two-finger tap |

```python
import time
while True:
   if touch("DOWN"):
       print(touch("X"), touch("Y"))
   s = touch("SWIPE")
   if s:
       print("swipe", s)
   time.sleep_ms(20)
```

---

## 9. Audio

Audio plays through the on-board PCM5102 I2S DAC, in the **background** (the
prompt stays live while a track plays).

| Command | Description |
|---|---|
| `play(path)` | Play a `.wav`, `.mp3` or `.flac` file (dispatched by extension) |
| `play(path, wait=True)` | Play and block until finished |
| `stop()` | Stop playback immediately |
| `is_playing()` | True while a track is playing |
| `volume(v)` | Set volume 0–100 (perceptual/log taper); `volume()` returns it |
| `beep(freq=880, ms=150)` | Play a short tone |

```python
volume(70)
play("/sd/music/song.flac")
```

WAV, MP3 and FLAC are decoded on the fly. A short sound also plays when a USB
device is plugged in or removed (set `pcaudio.usb_sounds = False` to disable).

---

## 10. Images

Load pictures onto the HDMI framebuffer, or save the screen to a file.

| Command | Description |
|---|---|
| `draw_jpg(path, x=0, y=0, scale=1)` | Draw a JPEG (scale 1/2/4/8 downscales) |
| `draw_bmp(path, x=0, y=0)` | Draw a BMP (all common variants) |
| `draw_png(path, x=0, y=0, cutoff=20)` | Draw a PNG (alpha ≤ cutoff = transparent) |
| `save_image(path)` | Save the framebuffer to a 24-bit BMP file |

```python
draw_jpg("/sd/photo.jpg")
save_image("/sd/screen.bmp")
```

---

## 11. Real-time clock (DS3231)

The battery-backed DS3231 keeps time across power cycles. At boot the system
clock is synchronised from it automatically.

| Command | Description |
|---|---|
| `settime(year, month, day, hour, minute, second)` | Set the DS3231 (and system clock) |
| `settime()` | Set the DS3231 from the current system clock |
| `gettime()` | Read the DS3231, returns a `time.localtime`-style tuple |
| `synctime()` | Set the system clock from the DS3231 |

```python
settime(2026, 7, 4, 14, 30, 0)
print(gettime())
```

---

## 12. SD card

A FAT-formatted SD card is mounted at **`/sd`**. Cards are **hot-swappable**: a
background check (~twice a second) notices when a card is removed and unmounts it
(`Warning: SDcard removed`); inserting a card mounts it again
(`SDcard inserted`). Use the normal file API and the shell commands on `/sd`.

```python
ls("/sd")
f = open("/sd/data.txt", "w"); f.write("hello"); f.close()
```

---

## 13. Persistent settings

The keyboard layout and the HDMI mode/clock are saved in `/settings.json` on the
flash filesystem and restored at boot. `keymap("UK")` and `screen(...)` update
and persist automatically. Delete `/settings.json` (`rm("/settings.json")`) to
return to the defaults (US keyboard, 640×480 @ 252 MHz).

---

## 14. Networking (Wi-Fi / Bluetooth)

Wi-Fi and Bluetooth use the on-board CYW43 chip and the standard MicroPython
APIs — see the MicroPython docs for full details.

```python
import network
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ssid", "password")
print(wlan.isconnected(), wlan.ifconfig())
```

Bluetooth is available via the `bluetooth` module and the frozen `aioble`
helper. Networking helpers `mip`, `requests` and `ntptime` (from
bundle-networking) are included.

### HTTPS

TLS is built in (mbedTLS, TLS 1.2, client side). The `requests` module makes
HTTPS requests directly:

```python
import requests
r = requests.get("https://api.github.com")
print(r.status_code)
print(r.json())
r.close()
```

By default the server certificate is **not** verified; for verified HTTPS, pass
your CA certificate(s) to the underlying `ssl` context. See the `ssl` module docs.

### MQTT

The **`umqtt.simple`** and **`umqtt.robust`** MQTT clients are frozen in for
publish/subscribe messaging (over plain TCP or TLS). `umqtt.robust` adds
automatic reconnection.

```python
from umqtt.simple import MQTTClient

c = MQTTClient("picocomputer3", "broker.example.com")
c.connect()
c.publish(b"pc3/status", b"hello")

def on_msg(topic, msg):
   print(topic, msg)

c.set_callback(on_msg)
c.subscribe(b"pc3/cmd")
while True:
   c.check_msg()      # or c.wait_msg() to block
```

(Connect a WLAN first, as in the example above.)

---

## 15. Standard MicroPython modules in this build

All the usual MicroPython modules are present. The definitive list on your board
is `help('modules')`. Notable ones:

- **Core language / library:** `sys`, `gc`, `micropython`, `builtins`, `array`,
 `binascii`, `collections`, `errno`, `hashlib`, `heapq`, `io`, `json`, `math`,
 `cmath`, `os`, `platform`, `random`, `re`, `select`, `struct`, `time`,
 `deflate`, `asyncio`.
- **Hardware / board:** `machine`, `rp2`, `framebuf`, `vfs`.
- **Networking:** `network`, `socket`, `ssl`, `bluetooth`, plus `aioble`, `mip`,
 `requests`, `ntptime`, `umqtt.simple`, `umqtt.robust`.
- **Numerics:** `ulab` (a NumPy/SciPy-compatible array library — `ulab.numpy`,
 `ulab.scipy`).

For the API of every standard module, refer to the MicroPython documentation:
**https://docs.micropython.org/en/latest/library/index.html**

### Board-specific extension modules

These low-level C modules back the friendly commands above and can also be used
directly: `hdmi`, `keyboard`, `mouse`, `touch`, `audio`, `jpeg`, `bmp`, `png`.
Most users will prefer the auto-imported helpers (`play`, `draw_jpg`, `touch`,
`mouse`, `screen`, …) rather than these directly.

---

## Quick reference

```python
# Display
screen(hdmi.RGB320)             # change mode (persisted)
d = hdmi.fb(); d.text("hi", 0, 0, d.colour(WHITE))

# Input
touch("DOWN"); touch("X"); touch("SWIPE")
mouse("X"); mouse("L")
keymap("UK")

# Audio
volume(70); play("/sd/song.mp3"); stop()

# Files
ls("/sd/*.jpg"); run("/sd/app.py"); edit("/sd/app.py")

# Images / clock
draw_jpg("/sd/pic.jpg"); save_image("/sd/screen.bmp")
settime(2026, 7, 4, 14, 30, 0); print(gettime())
```

*Pico Computer 3 firmware v0.1 — based on MicroPython. See
https://docs.micropython.org/ for the Python language and standard library.*


Edited 2026-07-05 00:47 by matherp
 
Print this page


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2026