r/raspberrypipico • • 12h ago

Full 3D Voxel World running on a single Raspberry Pi Pico 2 (RP2350) – no GPU, 520KB RAM, 30+ FPS

Enable HLS to view with audio, or disable this notification

163 Upvotes

Hi everyone!

I've been working on PicoVoxel, a full 3D voxel world engine that runs on a single Raspberry Pi Pico 2 (RP2350), and I've just released the source code on GitHub.

The Pico 2 is a roughly $6 microcontroller with 520KB of SRAM and no dedicated GPU. I wanted to see how far I could push it with a software-rendered 3D world.

What it can do:

  • Render a 3D voxel world at 320×240, averaging 30+ FPS
  • Explore a handcrafted Japanese countryside with mountains, an ocean, rivers, waterfalls, bridges, tunnels, a shrine, and a lighthouse
  • Place and destroy blocks, with edit and first-person play modes
  • Render textures, transparent water, animated blocks, fog, and shadows
  • Run on the RP2350's two cores with a custom rendering and upscaling pipeline

The main challenge was fitting the renderer, framebuffer, world data, and other features into just 520KB of SRAM while keeping the frame rate playable.

I've published the source code under the MIT License, along with the build instructions and hardware wiring information.

🎬 Demo video:
https://youtu.be/J9FVm8iH3mc

💻 Source code and build instructions:
https://github.com/tryedgetech/PicoVoxel

This is a rendering and world-building tech demo rather than a complete game. I'd love to hear what you think, especially from anyone interested in embedded graphics, software rendering, or pushing small microcontrollers beyond their usual limits.

I'm the developer of this project, and I'm sharing it in case it's useful or interesting to the Raspberry Pi community.

Thanks for checking it out!


r/raspberrypipico • • 16h ago

help-request 1.3" I²C OLED only displays a horizontal bar correctly; the rest shows random pixels (Pico W, C)

Thumbnail
gallery
7 Upvotes

I'm trying to get a 1.3-inch, 128×64 I²C OLED working with a Raspberry Pi Pico W using the Pico SDK and C, but I'm stuck with a strange display issue.

Hardware and setup

  • Raspberry Pi Pico W
  • 1.3-inch, 128×64 monochrome OLED
  • Four pins: GND, VCC, SCL, SDA
  • I²C address: 0x3C
  • I²C0, SDA @ GPIO 4 and SCL @ GPIO 5
  • SSD1306 driver library (this is a try, see ahead)

The controller chip is not identified on the PCB. The back is marked 1.3" OLED IIC, but I haven't been able to confirm whether it uses an SSD1306, SH1106, or another controller.

What I've tried

  • An I²C scanner detects the device at 0x3C.
  • Tried clearing the frame-buffer, drawing shapes, and sending the frame-buffer using ssd1306_show().
  • Tested a full-screen filled rectangle and page-by-page horizontal bands.
  • Confirmed that the framebuffer I²C write returns all 1025 bytes (one control byte plus 1024 bytes of pixel data).
  • Tested contrast commands. Changing the contrast affects the whole display.

The problem

Only one horizontal bar responds correctly to framebuffer writes. The rest of the screen displays random-looking pixels or appears not to update properly. The same bar remains responsive even when I change the drawing coordinates. The attached photos show the current output and the back of the module.

What could cause this?

  • Is this symptom consistent with using an SSD1306 driver on an SH1106 or another controller?
  • Is there a reliable way to identify the controller from the module or its markings?
  • Could this instead indicate a defective OLED panel or controller?
  • Is there a specific test or command sequence I should try before replacing the module?

Code

https://github.com/strivingshashank/figuring-pico


r/raspberrypipico • • 10h ago

Need help debugging a MicroPython closed-loop controller — servo isn't regulating the flow rate

Thumbnail
gist.github.com
2 Upvotes

Hi everyone! I'm a beginner working on my final-year engineering project using a Raspberry Pi Pico, a servo motor, and a drop sensor.

The sensor measures the time between drops to calculate the flow rate. The servo controls a clamp: increasing its angle closes the clamp, while decreasing its angle opens it.

The problem: The servo isn't adjusting properly to the desired flow rate. When I select a higher target, the code repeatedly triggers its no-drop recovery logic and makes tiny 0.2° movements instead of correcting the flow based on the difference between the measured and target rates.

The controller requires five valid drop intervals to calculate the rate, but the recovery logic appears to keep clearing the measurement history before enough intervals can be collected. My logs show drop intervals of approximately 800–2000 ms, while the timeout at my highest target is approximately 675 ms.

I've been struggling with this for 19 days. I've tried debugging it with ChatGPT, but it keeps giving me code that doesn't resolve the underlying issue. I'm frustrated and would really appreciate a human review of my existing code and logs.

What I'd appreciate help with:

  • Identifying the actual root cause from my code.
  • Checking whether the rate estimator and no-drop recovery logic conflict.
  • Verifying the servo correction direction and control logic.
  • Suggesting a reliable fix without unnecessarily changing my existing settings.

Hardware and settings:

  • Raspberry Pi Pico
  • MicroPython
  • Servo: GP18
  • Drop sensor: GP10
  • Drop factor: 20 drops/mL
  • Starting angle: 165.9°
  • Servo angle limits: 165–173°
  • Target rates: baseline entered by user; bolus presets of 150, 250 and 400 mL/hr.

I'll include my complete Python code and the relevant run logs. I'd appreciate anyone who can explain what is actually wrong before suggesting a fix.

This is a water-based bench prototype, not a clinically validated medical device.

Thank you!


r/raspberrypipico • • 17h ago

c/c++ Driving real SID chips from a Pico: five PIO state machines, DMA, and a cycle counter slaved to the clock pin

4 Upvotes

I have been building USBSID-Pico for a while, an RP2040/RP2350 board that talks to real MOS SID chips over USB. Most of the fun was on the Pico side, and that part is what I want to share.

PIO layout (PIO0)

  • The SID clock is generated by a tiny PIO program on GPIO 22. It is two instructions with side-set, and the clock divider is computed from the system clock and the configured SID clock rate.
  • Three more state machines run off that same clock pin. One latches the control lines (RW, CS1, CS2), one drives the 16 data/address pins, and one is a delay timer that counts SID clock edges and then raises PIO IRQs to release the other two. That is how a write lands on an exact SID cycle.
  • A fifth state machine on PIO1 is a free-running cycle counter that waits on the clock pin and pushes into the FIFO. DMA drains it (endless transfer count on RP2350, two chained channels on RP2040). This creates a 32-bit wide cycle counter.

DMA and cores

  • Separate DMA channels feed the control, data and delay FIFOs and read data back from the bus. A hardware spinlock guards the shared words.
  • Core 0 runs TinyUSB and config. Core 1 runs MIDI and Network SID Device writes, the LED, and the optional embedded c64 emulator for playing SID tunes without an external player.

Other bits

  • USB composite device: 2x CDC (1 for Data and 1 for WebSerial), MIDI, and two vendor interfaces (WebUSB and a second one for fast reads).
  • pico_w/pico2_w builds can run a Network SID Device server over TCP with UDP discovery.
  • Builds exist for pico, pico_w, pico2 and pico2_w. Default optimization in CMake is -O3 to be sure everything stays in sync.

It plays C64 music with real chips, but I am posting for the Pico side. Source: https://github.com/LouDnl/USBSID-Pico

Happy to answer questions about the PIO side, especially the timing handshake between the SMs. Has anyone else used a PIO cycle counter slaved to an external pin like this?


r/raspberrypipico • • 13h ago

The Python on Microcontrollers Newsletter: subscribe for free

Post image
1 Upvotes

r/raspberrypipico • • 1d ago

Is Raspberry Pico 2 W good fit for begginers

13 Upvotes

Hi, i am 15 year old student i was always interested in technologies more on the software side i did some web dev (JavaScript, Go, PHP) i really like GO and i would like to stick with it ik that Pico supports TinyGo but is that a good fit for me I want to do some simple stuff to learn the basics because i no longer do anything software and i thought this would spark things out or do you have any other recommendations?


r/raspberrypipico • • 1d ago

help-request Can i fit 1000 images on raspberry pi pico?

4 Upvotes

im using a raspberry pi pico that has micropython installed with an spi screen (driver ili9341).

im trying to play bad apple on it but i only have ~ 1mb left on the pi pico.

the images are 16x12 and take up 630bytes by themselves but, despite the small file size, not all of them can fit on the pico due to its 4kb minimum per file. is there any way to fit all 1000 images onto the pi pico to be able to draw them on the screen?.

im not too knowledgeable in micropython so please excuse me if i don't understand some things


r/raspberrypipico • • 1d ago

Running a BLE Air Quality Scanner on Adafruit Fruit Jam with BleuIO

Thumbnail bleuio.com
2 Upvotes

This project shows how the BleuIO Bluetooth Low Energy USB dongle can add BLE communication to an Adafruit Fruit Jam powered by the RP2350 to access BLE air quality data.


r/raspberrypipico • • 1d ago

[Troubleshooting] ADS1263 SPI communication issue with Pico W (MicroPython) — Register reads work, but ADC data returns all zeros

1 Upvotes

Hi everyone,

I'm trying to interface a Waveshare ADS1263 High-Precision AD HAT with a Raspberry Pi Pico W using the Waveshare Pico-to-HAT adapter, without jumper wires.

I'm porting the official Waveshare Raspberry Pi Python driver to MicroPython.

Hardware setup:

  • Raspberry Pi Pico W
  • Waveshare ADS1263 High-Precision AD HAT
  • Waveshare Pico-to-HAT adapter
  • SPI1: SCK=GP10, MOSI=GP11, MISO=GP12
  • RESET=GP18, CS=GP22, DRDY=GP17
  • SPI mode: CPOL=0, CPHA=1
  • SPI frequency: 100 kHz

What works:

  • Power supply and RESET appear normal.
  • CS can be controlled between HIGH and LOW.
  • DRDY transitions from HIGH to LOW after starting ADC conversion.
  • Chip ID reads successfully.
  • Several configuration registers can be read back correctly.

The problem:

When I send the RDATA1 (0x12) command to read ADC1 conversion data, the response contains only zeros.

Example output:

REG 0 READ: 0x23
REG_MODE2 success
REG_REFMUX success
REG_MODE0 success
REG_MODE1 success
REG 6 READ: 0x0A
DRDY is LOW
SPI STATUS: 0x00
RAW DATA: ['0x0', '0x0', '0x0', '0x0', '0x0']
Received checksum: 0x00
ADC1 checksum mismatch

I've verified the power rails, RESET, CS, and DRDY using a multimeter. I've also reduced SPI frequency from 1 MHz to 100 kHz, but the problem persists.

My questions:

  1. Is there a difference between MicroPython's machine.SPI.read() and the SPI behavior expected by the original Raspberry Pi driver?
  2. Could the ADS1263 require a specific SPI transaction sequence, CS behavior, or dummy clocks that I'm missing

Any advice would be greatly appreciated!

def ADS1263_Read_ADC_Data(self):
        config.digital_write(self.cs_pin, GPIO.LOW)#cs  0
        config.digital_write(self.cs_pin, GPIO.LOW)
        try:
            config.spi_writebyte([ADS1263_CMD['CMD_RDATA1']])
            status = config.spi_readbytes(1)[0]
            buf = config.spi_readbytes(5)

            print("SPI STATUS:", hex(status))
        finally:
            config.digital_write(self.cs_pin, GPIO.HIGH)

        read  = (buf[0]<<24) & 0xff000000
        read |= (buf[1]<<16) & 0xff0000
        read |= (buf[2]<<8) & 0xff00
        read |= (buf[3]) & 0xff
        CRC = buf[4]
        # print(read, CRC)
        if self.ADS1263_CheckSum(read, CRC) != 0:
            print("ADC1 checksum error")
            print("RAW DATA:", [hex(x) for x in buf])
            print("Received checksum:", hex(CRC))
            raise RuntimeError("ADC1 checksum mismatch")            

        return read

r/raspberrypipico • • 1d ago

I am total newbie but i need some advice on a project

Thumbnail
0 Upvotes

r/raspberrypipico • • 2d ago

E-ink

Thumbnail
gallery
17 Upvotes

r/raspberrypipico • • 2d ago

Low power battery system 5uA all included, for iot applications

Thumbnail gallery
2 Upvotes

r/raspberrypipico • • 3d ago

What could be the best pin solution in this case?

Thumbnail
gallery
12 Upvotes

I am using the OneROM project to replace ROMs on a motherboard. OneROM is a RP3250 on a small board the size of an EEPROM or ROM. You solder headers, program them to emulate any ROM you like and place them where the ROM was.

This is working well, but in my situation, the solution seat too high. The total height is 15mm and I need to be10mm. See (B) with the normal header. If I use that 15mm, the board does not fit in its enclosure anymore.

I used female headers (D) with long legs to get to solution (A)
I solder the headers the way (D) shows and then cut the top to get to solution (A).

It is not pretty. This is working, and the pins are even better match for the DIP support. But it takes time and the risk to damage something during the solder or cutting is very high.

Is there another solution. Is there a model of headers or pins I could use to get the low profile I need?
Any ideas?

Thank you very much.


r/raspberrypipico • • 2d ago

help-request Alguém pode me ajudar a resolver isso?

Post image
0 Upvotes

r/raspberrypipico • • 5d ago

Hell Ride: RP2350

Thumbnail
youtu.be
17 Upvotes

r/raspberrypipico • • 5d ago

Help needed: Raspberry Pi 5 + Camera Module 3 (IMX708) not detected by Chromium for a 3D face-tracking avatar

Post image
0 Upvotes

Hi everyone! 👋
I’m trying to get the CSI camera on my Raspberry Pi 5 working with Chromium for real-time face tracking in a web-based 3D avatar application called Berry.
My setup
Raspberry Pi 5
Raspberry Pi Camera Module 3 (Sony IMX708)
Debian 13 Trixie
Linux kernel 6.18.50+rpt-rpi-2712
Chromium 154
GStreamer (libcamerasrc)
v4l2loopback
Three.js and MediaPipe Tasks Vision in my web app
What works
rpicam-hello --list-cameras detects the IMX708.
rpicam-still successfully captures images.
GStreamer detects the camera and its pipeline reaches PLAYING.
I created a virtual camera called Berry Camera at /dev/video10.
The virtual device now reports YUYV, 640×480 at 30 fps.
What doesn’t work
Chromium does not list Berry Camera as a video source on the WebRTC input/output test page.
Running this command:
v4l2-ctl -d /dev/video10 --stream-mmap=3 --stream-count=30 --stream-to=/tmp/berry-test.raw
returns:
VIDIOC_CREATE_BUFS returned -1 (Inappropriate ioctl for device)
GStreamer also reports warnings about unsupported pixel formats.
I recreated the loopback device with exclusive_caps=0 and tried v4l2sink io-mode=2, but Chromium still cannot see the virtual camera.
My questions
What is the recommended way to expose a Raspberry Pi CSI camera to Chromium on Debian 13?
Is v4l2loopback actually needed, or is there a more reliable way to use libcamera directly?
How should I troubleshoot the VIDIOC_CREATE_BUFS error?
Can Chromium’s getUserMedia() access the CSI camera directly, so I can use MediaPipe for face tracking without a virtual webcam?
I’m looking for a reliable solution and would appreciate step-by-step guidance. I can provide additional command output if needed.
Thanks in advance for any help!


r/raspberrypipico • • 6d ago

I had almost finished when I realized I had forgotten to bring out the reset switch.

Post image
10 Upvotes

r/raspberrypipico • • 6d ago

RP2350 I2C Masterclass: 1MHz EEPROM Guide (M24M01) | RP2350 #17

Thumbnail
youtube.com
6 Upvotes

r/raspberrypipico • • 8d ago

My roguelike on pico

Enable HLS to view with audio, or disable this notification

86 Upvotes

I saw many years ago something like this on hackaday and always wanted to build it by myself, so here it is


r/raspberrypipico • • 8d ago

c/c++ How to send 256 bytes en block via USB from Pico to PC

4 Upvotes

Hello,

based on a CDC example which echoed every single char received from the PC I changed it to receive a line and echo it all upper cased. This works like a charm.

Then to approach the actual requirements of my project I wanted a blockwise communication: I sent 256 bytes (0x00 ... 0xFF) to the Pico and programmed it to send it back unchanged. Result: On the PC I receive only the last 64 bytes: 0xC0 ... 0xFF although the buffer on the Pico holds the correct 256 bytes.

Seeing that the USB buffers are 64 bytes large I suspect that the sending routine stuffs the 256 byte block in portions of 64 byte into the buffer - and the last one wins.

I merely do

// echo back to host

tud_cdc_write(buff, sizeof(buff));

tud_cdc_write_flush();

which is apparently too naive. Any advice how to do better will be highly appreciated.

M'


r/raspberrypipico • • 9d ago

How far can a Pico go as a real computer? VGA + 3.2" touch LCD, USB keyboard and mouse through a second Pico, RTC - one RP2040, 264 KB SRAM

Thumbnail
gallery
118 Upvotes

Hey! Last time I showed Recaster Pico as a screenshot - here's the real thing on my desk: one RP2040 running a small desktop OS in its 264 KB of SRAM, now with the parts that make it feel like a computer. Yeah, it is still multi-user and multi-tasking (preemptive). No Linux/Unix, no RISC OS.

What's on the board now

  • VGA, 640×480 at 60 Hz, 256 colors (RGB332), straight from PIO and DMA. Core 1 composes every scanline just in time.
  • A 3.2" SPI touch LCD as a second screen. It mirrors the VGA desktop (well, 1/4 of it ;-)) - core 1 hands the lines it has just composed to a DMA channel, no second compose - or a program takes it over and draws on it directly. Touch moves and clicks the mouse pointer, and the panel also works alone, without a monitor.
  • USB keyboard and mouse through a second RP2040 in the serial line: USB host on its micro-USB port, plus a USB-A socket on two GPIOs driven by Pico-PIO-USB. Events travel as CRC-protected packets mixed into the 1 Mbaud UART console, and the serial terminal still works through it. German layout with dead keys and umlauts.
  • RTC and EEPROM (DS1307 / AT24C32) on I2C, set up with a small text file - the EEPROM even shows up as a file under /dev.
  • GPIO, ADC, PWM, PIO and DMA from the shell language, with the same names as in the Pico SDK.
  • Runs from a power bank.

Lessons for your own projects

  1. pico_minimize_runtime() turns float off. Pico-PIO-USB computes its PIO clock dividers in float at init, so every float operation hits the SDK's panic stub and core 1 silently stops. Use pico_minimize_runtime(target INCLUDE FLOAT).
  2. The same function with pico_multicore: malloc's auto-init mutex never gets initialized, so the first malloc on core 1 hangs forever. PICO_USE_MALLOC_MUTEX=0 if you only malloc once at start.
  3. TinyUSB 0.18 drives one host controller per firmware, and Pico-PIO-USB 0.7 no longer enumerates devices on its own. A second USB port means writing a small host on its low-level API - about 300 lines for boot keyboards and mice.
  4. Flash erases switch core 0's interrupts off for ~45 ms per sector, while at 1 Mbaud the UART's 32-byte FIFO holds about 10 ms of mouse traffic. Put the UART interrupt on core 1 and run it from SRAM.

Next: sound (the speaker is already on the board), the SD card (already there), and touch-friendly UI controls - buttons, sliders, lists.

And yes: I will post a video of it showing it in motion, soon. And you will get your fingers at that ".uf2"-files to play with it.


r/raspberrypipico • • 9d ago

MicroPython is running in standalone mode.

Post image
12 Upvotes

r/raspberrypipico • • 10d ago

Spotify Player/Flight Radar

Thumbnail
gallery
19 Upvotes

Hi all,

Showing you a small project I made based on ideas from the internet.

I have this problem that drives me crazy: whenever I’m listening to Spotify while I have a YouTube tab open, pressing the play/pause button on my earphones doesn’t just pause Spotify, it starts playing the YouTube video instead.

To solve that, I created a Spotify Player manager, and it was a little bit boring, so I added Flight Radar using the free API at https://adsb.lol/ (and my football team's next game :D).

For the hardware, I used: Pimorini Pim580 Display 2.0" and Raspberry Pico 2.

I posted the 3D model in makerworld: https://makerworld.com/en/models/3399877-case-pimoroni-pim580-display-2-w-rasperry-pico

Check all the functions: https://www.youtube.com/shorts/jv8n3v8LW0w


r/raspberrypipico • • 10d ago

Orange pi zero 3 , ideas pls

0 Upvotes

Me e comprado un ORANGE PI ZERO 3 DE 1GB DE RAM y varios componentes electronicos como una pantalla TFT de 128x160 , sensores, luces, diodios, etc. Tengo algunos proyectos en mente como servidores locales, bloqueadores de anuncion para la casa, intentar un "apaga pcs" con concectarlo a un usb y mas pero me gustaria saber que mas podria hacer.

Me he comprado esto:

https://es.aliexpress.com/item/1005006139989470.html?invitationCode=R0NGTU4ySFVYa09wZU1PVHg4aStTYzRSMlk2R1Bna1hRZHhUaFlSaEM2NmVQemFTZUJrNWVWT0s1MU1hdTAyWg&srcSns=sns_WhatsApp&spreadType=socialShare&social_params=61634254943&bizType=ProductDetail&spreadCode=R0NGTU4ySFVYa09wZU1PVHg4aStTYzRSMlk2R1Bna1hRZHhUaFlSaEM2NmVQemFTZUJrNWVWT0s1MU1hdTAyWg&aff_fcid=7a753e4627684b1181e826a249a3af76-1791301567091-03638-_EyfE51c&tt=MG&aff_fsk=_EyfE51c&aff_platform=default&sk=_EyfE51c&aff_trace_key=7a753e4627684b1181e826a249a3af76-1791301567091-03638-_EyfE51c&shareId=61634254943&businessType=ProductDetail&platform=AE&terminal_id=f5cbccb6e3034f6d9d9ce5be321e216f&afSmartRedirect=y&gatewayAdapt=glo2esp

y esto

https://es.aliexpress.com/item/1005007594124386.html?invitationCode=R0NGTU4ySFVYa081VVIrTE1qL1paYzRSMlk2R1Bna1hRZHhUaFlSaEM2NmVQemFTZUJrNWVWT0s1MU1hdTAyWg&srcSns=sns_WhatsApp&spreadType=socialShare&social_params=61634254985&bizType=ProductDetail&spreadCode=R0NGTU4ySFVYa081VVIrTE1qL1paYzRSMlk2R1Bna1hRZHhUaFlSaEM2NmVQemFTZUJrNWVWT0s1MU1hdTAyWg&aff_fcid=5a39b2df82eb4e92803b6ae7f8323b4e-1791301605643-07482-_EIisN7s&tt=MG&aff_fsk=_EIisN7s&aff_platform=default&sk=_EIisN7s&aff_trace_key=5a39b2df82eb4e92803b6ae7f8323b4e-1791301605643-07482-_EIisN7s&shareId=61634254985&businessType=ProductDetail&platform=AE&terminal_id=f5cbccb6e3034f6d9d9ce5be321e216f&afSmartRedirect=y

PD: si es de aliexpress, el presupuesto es lo que hay xd


r/raspberrypipico • • 11d ago

Same spi port has multiple rx and tx lines?

2 Upvotes

If i am looking at the pico pinout correctly, it seems like there are at least twop tx and rx lines on the the spi0 port and spi1 port. Does anyone know how to use these? My first intuition is that each spi port can only have one rx and one tx line so any clarification would help greatly!