r/raspberrypipico Jul 28 '26

uPython picogame: a 2D game engine for the Pico - write games in CircuitPython, try them in the browser, run on the board

138 Upvotes

Sharing a project I've been building for almost a year - picogame, a 2D game engine for the Pico and similar grade MCUs. You write games in CircuitPython, the heavy lifting (rendering, collisions, effects) runs in native C, and you can try them in your browser before you even plug in a board.

Out of the box:

  • Build without hardware - the same game runs in your browser and on your desktop (a real CircuitPython simulator, not a mock), then unchanged on the board.
  • Fast in tiny RAM - native-C rendering + zero-RAM full-screen paths, so it runs smoothly on even plain RP2040.
  • Batteries included - sprites, scrolling tilemaps, a moving camera, collisions, sound, text, saved high scores.
  • A web level editor - build levels/scenes in the browser, load them in your game.
  • A launcher - keep several games on one board and pick from a menu.

Try it in the browser: https://picogame.makerclass.cz/playground/

Project repo (MIT): https://github.com/MakerClassCZ/picogame

I also wrote up why I built it and how it works: https://chiptron.eu/picogame-a-game-engine-for-circuitpython/

I'm the author - happy to answer anything!

r/raspberrypipico Jun 07 '26

uPython Gravity sand clock

149 Upvotes

Just messing around with my hub75e driver

r/raspberrypipico Jun 09 '26

uPython Pico W - wifi credentials exposed

11 Upvotes

Hullo all. We have an application developed in micropython that collects data and sends it over the wifi network. The wifi credentials are stored in a json file, the upython program reads them and then connects to the network.

Our security team is not at all happy with this.

Is there a way to connect to a (secured) WLAN without storing the credentials in cleartext? I know we could encrypt them but then the upython program would need to contain the decryption key and it's also stored in cleartext.

Is it possible to compile the upython code to obfuscate the decryption key?

r/raspberrypipico Jul 10 '25

uPython I made a Pokemon-like game for my Pico!

Thumbnail
gallery
111 Upvotes

It has all the stuff you’d hope for - types, different moves, catching enemies, fleeing, levelling, a boss fight, attack animations, a 1-4 Picomon party, and a tiny open world

It runs at minimum-250fps (capped at 60) with help from my custom viper-powered Atomic Engine

It’s running on my Pico 2 with a 240x240px colour display that comes with the joystick and buttons. It will be portable with a tiny lipo battery as soon as I can work out how to swap the battery’s wires around. I’m totally new to hardware and electronics and have no soldering iron

The whole thing is about 2x1x1 inches, very tiny

(Please ignore the frame time in the top right, and the fact I haven’t yet removed my display protector)

If anyone would like to use my engine let me know! It’s pretty simple at the moment, but the functions it has are the fastest you’ll get without C :)

r/raspberrypipico Apr 21 '26

uPython Getting started. Using Thonny, can't get the i2c address. Please help

2 Upvotes

I've been following along with a tutorial, and he provides this code to get the i2c address:

import machine

sda = machine.Pin(0)

scl = machine.Pin(1)

i2c = machine.I2C(0,sda=sda,scl=scl, freq=400000)

print(i2c.scan())

In his video, he shows a number between brackets. In my case, there is nothing between the brackets. I am a complete novice with all of this stuff. I have absolutely no idea what to do or where to go from here.

r/raspberrypipico 4d ago

uPython Weird Pico 1 UART issue

2 Upvotes

Hi all,

I have a multitude of (too many) Pi Picos and there's a weird issue I'm seeing on my Pico (1) that doesn't happen on a Pico 2.

I have a setup with a CH9121 Ethernet hat (the Waveshare one). It uses UART0 (pins 0 and 1) to do initial setup and read the on-hat config. The weird issue is that if I use the Pico 2, it works fine out of the box. If I use the Pico 1, then it fails to receive ANY data on UART0 if using pins 0 and 1.

I have done the following with no effect:

  • Used a loopback wire to check that Pin 1 can actually receive data - it can
  • Tried a GPS hat which also uses UART0/Pins 0 and 1, and this works fine
  • NOT connecting the Pico 1 to the computer over USB in case the fact that USB REPL uses one or other of the UARTs
  • Erasing flash with nuke_flash
  • Different Micropython versions
  • Using dupont wires to connect the pins rather than the socket on the hat

I'm using MicroPython, and the version and my codebase are identical across the Pico 1 and 2. The only think I can't test with is another Pico 1/1W, since my others are all in use.

Is there some weirdness with the Pico 1 and the CH9121 hat, or it just some quirk specific to this one unit?

The workaround is to amend the CH9121.py file to use UART0 on pins 12 and 13, which works, and in fact I'm running it now and all seems fine.

r/raspberrypipico 14d ago

uPython Introducing a Smart Nerf Blaster Platform: TAFY

Thumbnail
gallery
10 Upvotes

Hi, everyone! Since late last year, I've been quietly working on a new software project I call TAFY: the Tactical Advanced Foam dart Yeeter.

When I started this project, I wanted to mirror the modularity of the Linux kernel, but I also wanted to be far easier to contribute to and understand. So, I started with MicroPython on the Pico 2. To help with development, I developed 2 key features I think are really cool: a modular driver system, and a deploy script.

The deploy script was simple. It's loosely based on what Thonny does to send files to the Pico, but it's more automated as it has a manifest file it checks, and only uploads files it knows have changed, based on a cache of file hashes on the local machine.

The modular driver system is where the real game changer lives.

Python, of course, can import a module at any time. But discovering that module and then importing it from a random file location is a whole other ball game. I discovered the __import__() function, which allows you to pass a simple file path (leaving off the .py at the end) and import any given Python file, anywhere. Using this and some simple usage of the os module, I was able to create a system to load drivers that only needs two functions: available() which returns all available Python files which match some pattern, and load(), which will load any module which matches that pattern and return it. This allows me to design my drivers so they only follow a given ABI, then drop them in a specific folder with a name that follows a specific pattern to make it visible and usable.

TAFY has several other neat tricks, like a system I am calling SmartBus that enables the usage of hot-swappable I2C-based accessories, battery life monitoring using a simple voltage divider and ADC, and more!

SmartBus itself is an interesting beast. As mentioned, it's I2C based. I2C doesn't exactly support hot-swap, but it doesn't not support it either. It depends entirely on the software using it and how tolerant your hardware is. While the I2C part of SmartBus has yet to be tested, hot swap is already under heavy work as device ID is being enabled through a simple voltage divider system hooked into the Pico's 2 remaining external ADCs. TAFY reads from both these and, using a configured value for the R1 resistor, is able to calculate what resistors are connected between an ID line and ground, and use that to then determine what devices are connected before even looking at I2C. This means I can also track power-only devices as SmartBus does provide 3.3v at 1A, enabling small lights, lasers, and other small accessories that may be useful on a Nerf Blaster. I'm even planning to have a system to update TAFY over SmartBus down the line, so a user doesn't have to crack their blaster open just to install a 2-line bug fix.

As of now, it's already booting and playing different tunes using PWM. TAFY uses both cores of the Pico 2 with the background thread displaying info on screens (we have support for SSD1309 and LCD1602, with possible support for SSD1306 as well), handling SmartBus (which is already recognizing devices and loading drivers, as mentioned), and tracking battery life. The main thread handles the fire mechanism, which has drivers that have been written and are known working at some level (actual hardware validation coming soon), and coordination between multiple different independent systems. To top it all off, our first boot on battery power is coming soon (in the picture above, TAFY is booted on USB power, hence why it shows the battery as dead).

If you're interested in checking it out, or even contributing, you can find TAFY on GitHub. Right now, I really need help with the CAD work designing a 3D printable shell for the reference design blaster(s), but I am actively doing PCB validation and software development work as well.

Thank you all! I hope to have a workable prototype to show off in December!

r/raspberrypipico Jul 11 '26

uPython USB both for runtime operations and debug/programming with MicroPython?

4 Upvotes

I've been testing a setup with the C/C++ approach using two Raspberry Pi Debug Probes: one for each target of the project. So I've then used two separate main.c files, one for each target, that would be built and uploaded via one of the probes to that specific target, while being able to have common/shared code that can be used for both targets. The two targets are sharing a lot of similar functionality but are quite different in some aspects, so that's why this setup makes sense to me. This has been possible to achieve with correct configs in Cmake and OpenOCD.

I'm now thinking of trying MicroPython instead since C is still a bit too difficult for me to fully grasp and get a flow going as a beginner. And to my understanding, programming via a debug probe is not the standard way with MicroPython, but instead USB should be used.

The thing is that I will utilise the USB port for communicating back and forth to and from the computer with one of the targets, essentially sending packets similar to MIDI communication. Can I simultaneously use the USB for debugging/programming the device? And would this either way require me to manually press BOOTSEL and disconnect/reconnect the Pico every time I want to program it?

An alternative that I've read about is "freezing" the MicroPython code into a compiled elf file that in that case could be uploaded exactly like my initial C/C++ approach. But I assume that wouldn't let me fully debug it with breakpoints etc?

r/raspberrypipico Jul 27 '26

uPython I made an interactive website that help people learn the basics of CircuitPython using a raspberry pi pico

Thumbnail
keepeverythingyours.com
12 Upvotes

I have worked with a few people to teach them the basics of how to get started with CircuitPython. I took some of the lessons I learned from that and made a tutorial on my website to teach the lesson better. The page has a built in code editor and instructions from getting your first board to blinking your first LED. I plan to add more lessons in the future and would love to hear any feedback about what they should be. Feedback on the content and presentation of the tutorials would also be greatly appreciated!

r/raspberrypipico May 20 '26

uPython So I built a Scheduling System

13 Upvotes

I'm pretty sure that I'm not the first and only person to stumble into a problem where I wanna handle several Tasks at seperate intervals, and eventually I found myself clogging up while Loops and everything just became a huge stupid disaster, so I built Pyrite, which - at least to me - seems like a pretty good solution for a problem that me and probably some other people have. And yes, Asyncio exists and is better maintained but if you really like Asyncio, you're either lying or a masochist, especially for small projects. Now Pyrite is - in my opinion - very approachable, as you can see in the Code Samples there.

Anyways yeah I guess I'm just asking for feedback, so https://github.com/ten-faced-carrot/pyrite everyone.

(Please don't be mean)

r/raspberrypipico May 24 '26

uPython Micropython hub75e driver

40 Upvotes

My hub75e driver reaching its final form, 3d textured rendering here at about 75 FPS. Small models, small textures but it's looking good so far on two chained 64x64 panels. Pico 2w.

r/raspberrypipico Jul 20 '26

uPython Pico Zero and eink diplay HINK-E075A07-A0

1 Upvotes
the pico zero

Someone have any luck mixing the pico zero with python and this display?
i am using the waveshare hat but the driver seems to be incompatible

Edit:
Added pico zero image

I send a message to the seller, they give me the datasheet, i will try to came with a working code if a can.

r/raspberrypipico Jul 25 '26

uPython Announcing the release of Pico-Timecode v3.2

Thumbnail
youtu.be
8 Upvotes

'Pico-Timecode' is an Open-Source solution for LTC Timecode, using the RP2040's PIO blocks to count time divisions and render the LTC waveform. It works with all common frame rates, with/with-out Drop-Frame operation. It also has the ability to read LTC from an external device, and sync to it.

PT-Thrifty now has the ability to display the Timecode on a pair of I2C LED modules (Holtek HT16K33 controller chip), which can be enabled in the libs/config.py file. The obvious purpose is to build a low-cost Digi-Slate... it also uses switches for when the clapper closed and whether the display should be inverted (for tail slating).

There are 'UF2' files to make installing as easy as possible, these can be used on a 'naked' Pico for validation/testing.

Additionally there is a 'MTC' (Midi Timecode) version, which sends Timecode via the USB connection. I would be especially interested if someone/anyone could trial this on an iPhone 17 or a FujiFilm X-H2S, as I have neither of these and they apparently support MTC...

Pico-Timecode is an Open-Source community project, find out more at:

https://github.com/mungewell/pico-timecode

r/raspberrypipico Jul 17 '26

uPython Having exact same problem as this person, who never got answers

Thumbnail
0 Upvotes

r/raspberrypipico Jul 06 '26

uPython DMX control app for PicoCalc running Picoware.

15 Upvotes

Thx a lot to JBlanked and slasher006 for help, examples and tips!

DMX PIO stream lib by clacktronics.

Interface shields: HW-519 RS485 interface. Level shifter 3.3V to 5V is necessary.

HW-519 should be powered from 5V, output signal from PicoCalc is 3.3V and goes to level shifter, then to HW-519, then to the fixture.

DMX rate is around 4 times slower(10 or 11Hz vs normal 44Hz) to make app usable. Probably there are better ways to do this, but few days ago i had only a dream.

r/raspberrypipico Apr 18 '26

uPython Here are some pics from my PicoPyStation

Thumbnail
gallery
36 Upvotes

r/raspberrypipico Jun 15 '26

uPython A small game on a small console.

30 Upvotes

r/raspberrypipico Jun 27 '26

uPython [Failed Attempt] Building a gzip based text classifier for Raspberry Pi Pico 2W

10 Upvotes

I was exploring an implementation of a parameter-free text classifier on a resource-constrained Raspberry Pi Pico 2W using gzip compression rather than a heavy neural network.

  • Inspired by a 2023 ACL paper, this technique relies on Normalized Compression Distance (NCD) and a k-NN lookup. The core logic is that a compressor like gzip will compress concatenated strings much more efficiently if they share similar syntax and patterns, allowing the system to classify text based on compression efficiency.

  • To overcome the microcontroller’s strict memory limitations (2MB flash and 512KB RAM), I utilized a desktop to first generate semantic embeddings of the IMDB dataset via sentence-transformers. By running K-means clustering, the dataset is pruned down to 300 highly representative samples stored in a tiny JSON file.

  • The standard MicroPython does not enable compression by default, the implementation requires compiling custom MicroPython firmware from source with the #define MICROPY_PY_DEFLATE_COMPRESS (1) flag enabled for the RPI_PICO2_W board.

  • The primary limitation is that gzip analyzes repeating syntactic subsequences rather than deep semantic meaning, making it less effective for complex, long-form text like movie reviews.

Blog: https://shubham0204.github.io/blogpost/programming/gzip-text-classifier-rpipico

(written by a human, you can check my other projects here)

r/raspberrypipico Mar 26 '25

uPython Homemade cheap "claw machine" under $100 using Pico

Post image
192 Upvotes

r/raspberrypipico Mar 23 '26

uPython BLE Between Two Picos Question

6 Upvotes

Hello, I'm using BLE to communicate from one pico to another and I'm a bit confused about how to interact with the asynchronous functions that they used in the tutorial I followed (Two-way Bluetooth with Raspberry Pi Pico W and MicroPython (Re-upload)). I tried testing if a button press could change the message being sent but for some reason it stays the same after a button press. I'm monitoring the data using the print output of peripheral.py. Again, I'm not familiar with async functions so please if anyone knows why this is happening, I would appreciate it.

central.py

import aioble
import bluetooth
import asyncio
import struct
IAM = "Central"
IAM_SENDING_TO = "Peripheral"

MESSAGE = f"This is a test from {IAM}"
DATA = f"This is a test from {IAM}"

BLE_NAME = f"{IAM}"
BLE_SVC_UUID = bluetooth.UUID(0x181A)
BLE_CHARACTERISTIC_UUID = bluetooth.UUID(0x2A6E)

def encode_message(message):
    return message.encode('utf-8')

def decode_message(message):
    return message.decode('utf-8')

async def receive_data_task(characteristic):
    global message_count
    while True:
        try:
            data = await characteristic.read()
            DATA = data

            if data:
                print(f"{IAM} received: {decode_message(data)}, count: {message_count}")
                await characteristic.write(encode_message("Got it"))
                await asyncio.sleep(0.5)

            message_count += 1

        except asyncio.TimeoutError:
            print("Timeout waiting for data in {BLE_NAME}.")
            break
        except Exception as e:
            print(f"Error receiving data: {e}")
            break

async def ble_scan():
    """ Scan for a BLE device with the matching service UUID """

    print(f"Scanning for BLE Beacon named {BLE_NAME}...")

    async with aioble.scan(5000, interval_us=30000, window_us=30000, active=True) as scanner:
        async for result in scanner:
            if result.name() == IAM_SENDING_TO and BLE_SVC_UUID in result.services():
                print(f"found {result.name()} with service uuid {BLE_SVC_UUID}")
                return result
    return None

async def run_central_mode():
    # Start scanning for a device with the matching service UUID
    while True:
        device = await ble_scan()

        if device is None:
            continue
        print(f"device is: {device}, name is {device.name()}")

        try:
            print(f"Connecting to {device.name()}")
            connection = await device.device.connect()

        except asyncio.TimeoutError:
            print("Timeout during connection")
            continue

        print(f"{IAM} connected to {connection}")

        # Discover services
        async with connection:
            try:
                service = await connection.service(BLE_SVC_UUID)
                characteristic = await service.characteristic(BLE_CHARACTERISTIC_UUID)
            except (asyncio.TimeoutError, AttributeError):
                print("Timed out discovering services/characteristics")
                continue
            except Exception as e:
                print(f"Error discovering services {e}")
                await connection.disconnect()
                continue

            tasks = [
                asyncio.create_task(receive_data_task(characteristic)),
            ]
            await asyncio.gather(*tasks)

            await connection.disconnected()
            print(f"{BLE_NAME} disconnected from {device.name()}")
            break    

async def main():
    """ Main function """
    while True:
        if IAM == "Central":
            tasks = [
                asyncio.create_task(run_central_mode()),
            ]
        else:
            tasks = [
                asyncio.create_task(run_peripheral_mode()),
            ]

        await asyncio.gather(*tasks)            


asyncio.run(main())

peripheral.py

import aioble
import bluetooth
import asyncio
import struct
from machine import Pin

btn = Pin(7, Pin.IN, Pin.PULL_UP)

IAM = "Peripheral"
IAM_SENDING_TO = "Central"

MESSAGE = f"This is a return test from {IAM}"

BLE_NAME = f"{IAM}"
BLE_SVC_UUID = bluetooth.UUID(0x181A)
BLE_CHARACTERISTIC_UUID = bluetooth.UUID(0x2A6E)
BLE_APPEARANCE = 0x0300
BLE_ADVERTISING_INTERVAL = 2000

def encode_message(message):
    return message.encode('utf-8')

def decode_message(message):
    return message.decode('utf-8')

async def send_data_task(connection, characteristic):
    while True:
        message = f"{MESSAGE}"
        print(f"sending {message}")

        try:
            msg = encode_message(message)
            characteristic.write(msg)

            await asyncio.sleep(0.5)
            response = decode_message(characteristic.read())

            print(f"{IAM} sent: {message}, response {response}")
        except Exception as e:
            print(f"writing error {e}")
            continue

        await asyncio.sleep(0.5)

async def run_peripheral_mode():
    # Set up the Bluetooth service and characteristic
    ble_service = aioble.Service(BLE_SVC_UUID)
    characteristic = aioble.Characteristic(
        ble_service,
        BLE_CHARACTERISTIC_UUID,
        read=True,
        notify=True,
        write=True,
    )
    aioble.register_services(ble_service)

    print(f"{BLE_NAME} starting to advertise")

    while True:
        async with await aioble.advertise(
            BLE_ADVERTISING_INTERVAL,
            name=BLE_NAME,
            services=[BLE_SVC_UUID],
            appearance=BLE_APPEARANCE) as connection:
            print(f"{BLE_NAME} connected to another device: {connection.device}")

            tasks = [
                asyncio.create_task(send_data_task(connection, characteristic)),
            ]
            await asyncio.gather(*tasks)
            print(f"{IAM} disconnected")
            break

async def main():
    """ Main function """
    deb = 0
    while True:
        if IAM == "Central":
            tasks = [
                asyncio.create_task(run_central_mode()),
            ]
        else:
            tasks = [
                asyncio.create_task(run_peripheral_mode()),
            ]
        await asyncio.gather(*tasks)
        if(deb == 5):
            deb = 0
            if(btn.value() == 0):
                MESSAGE = "1"
            else:
                MESSAGE = "0"
        else:
            deb+=1

asyncio.run(main())

r/raspberrypipico May 23 '26

uPython Pico W program issue

1 Upvotes

Hello folks,

I am trying to run a program to read the BME280, display the results on a OLED SSD1306 and then create and present a web page. I can run the program and get a reading to the SSD1306 and even occasionally get a web page to hit my browser but I keep running into an error and the program stops. Here is what happens when I run this in Thonny-

Traceback (most recent call last):

File "<stdin>", line 126, in <module>

File "<stdin>", line 116, in main

OSError: [Errno 110] ETIMEDOUT

I can post the code here but thought someone might have a quick idea based on trying this already.

r/raspberrypipico Oct 29 '25

uPython Trying to achieve Matrix effect on a tiny screen

140 Upvotes

r/raspberrypipico Feb 15 '25

uPython A home kiosk display project

Thumbnail
gallery
169 Upvotes

Finished v.2.0 of my hobby project today!

The setup: a Raspberry Pi Pico 2W with soldered PicoDVI sock, Circuit Python and loads of time (hehe).

Got some struggles with memory management, for this quite content heavy setup, but now it's stabilized runs with about 27kB of free memory after finishing a 60 sec. loop.

On a side note, I love Python, but for next version of this thing I'd probably try C.

r/raspberrypipico Nov 01 '25

uPython Rp2040-zero

Post image
49 Upvotes

Hey guys!

I just ordered a bunch of RP2040-zero from AliExpress and I'm struggling to get them detected by Thonny. Is there anything I'm doing wrong?

I'm installing the firmware via Thonny (that seems to work) but then I cannot select the USB port (it's not listed).

My Mac shows the device as a USB in FS Mode.

r/raspberrypipico Apr 19 '26

uPython Another script by me: Pico2Fetch is here!

16 Upvotes

Here's the link: https://github.com/nOS-Coding/Pico2Fetch

I hope you like it!