# Larsio Paint Music

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/139/397/medium800/hacks_fj_larsio_03b.jpg?1756916919)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/926/medium800/hacks_LPMbeut.jpg?1747440018)

_ **Larsio Paint Music** _ is a love letter to_ **&nbsp;Mario Paint** _ -- the mouse-driven art creation cartridge for Super Nintendo. It included a wonderfully fun music composition mode where you could draw notes on a music staff using different samples and synth voices and then play them. I decided to recreate this classic on a modern microcontroller in CircuitPython as _**Larsio Paint Music (LPM)**_.

_ **LPM** _ runs on a Metro RP2350 or the Fruit Jam. With USB mouse-input, HDMI video output, and stereo I2S DAC audio output for synthesized and sampled sounds, you can try your hand at making music the semi old-fashioned way -- with a music staff and pixelated sprites for notes!

![](https://cdn-learn.adafruit.com/assets/assets/000/136/903/medium800/hacks_smp.jpg?1747356127 )

https://youtu.be/1IVyyB9OG90

Danger: Some of the functionality used here (USB Host for mouse in particular) is hot off the press. You'll want to install CircuitPython 10.0.0-beta.3 or higher on your board rather than the 9.2.7 release version mentioned in the CircuitPython Install page.

## Parts

The project can be built using the Adafruit Metro RP2350 with PSRAM and some additional parts (DAC and DVI breakout) or the Adafruit Fruit Jam.

### Adafruit Metro RP2350 with PSRAM

[Adafruit Metro RP2350 with PSRAM](https://www.adafruit.com/product/6267)
Choo! Choo! This is the RP2350 Metro Line, making all station stops at "Dual Cortex M33 mountain", "528K RAM round-about" and "16 Megabytes of Flash town" and a bonus stop at "8 Megabytes of PSRAM village". This train is piled high with hardware that...

In Stock
[Buy Now](https://www.adafruit.com/product/6267)
[Related Guides to the Product](https://learn.adafruit.com/products/6267/guides)
![Angled shot of black, credit card-sized microcontroller.](https://cdn-shop.adafruit.com/640x480/6267-00.jpg)

### Adafruit TLV320DAC3100 - I2S DAC with Headphone and Speaker Out

[Adafruit TLV320DAC3100 - I2S DAC with Headphone and Speaker Out](https://www.adafruit.com/product/6309)
We&nbsp;stock a lot of chips and development boards&nbsp;that are able to do high quality digital I2S out, which makes for great quality audio playback. That's great when you have enough processing power to decode WAVs or MP3s in real time. However, most give you stereo...

In Stock
[Buy Now](https://www.adafruit.com/product/6309)
[Related Guides to the Product](https://learn.adafruit.com/products/6309/guides)
![Angled shot of black, square-shaped DAC breakout board.](https://cdn-shop.adafruit.com/640x480/6309-00.jpg)

### Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays

[Adafruit RP2350 22-pin FPC HSTX to DVI Adapter for HDMI Displays](https://www.adafruit.com/product/6055)
You may have noticed that our [RP2350 Feather](https://www.adafruit.com/product/6000) has an FPC output connector on the end&nbsp;for accessing the HSTX (High Speed Transmission)&nbsp;peripheral. This new capability, not available on the RP2040, is specifically designed to allow the...

In Stock
[Buy Now](https://www.adafruit.com/product/6055)
[Related Guides to the Product](https://learn.adafruit.com/products/6055/guides)
![black, square-shaped breakout board with DVI and 22-pin FPC connectors connected to a black, rectangular microcontroller.](https://cdn-shop.adafruit.com/640x480/6055-01.jpg)

### Part: 22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX
quantity: 1
5 cm
[22-pin 0.5mm pitch FPC Flex Cable for DSI CSI or HSTX](https://www.adafruit.com/product/6034)

### Part: Break-away 0.1" 36-pin strip male header
quantity: 1
10 pack
[Break-away 0.1" 36-pin strip male header](https://www.adafruit.com/product/392)

### Part: USB Type A Jack Breakout Cable with Premium Female Jumpers
quantity: 1
30cm long
[USB Type A Jack Breakout Cable with Premium Female Jumpers](https://www.adafruit.com/product/4449)

## **- or -**
### Adafruit Fruit Jam - Mini RP2350 Computer

[Adafruit Fruit Jam - Mini RP2350 Computer](https://www.adafruit.com/product/6200)
We were catching up on a recent [hackaday hackchat with eben upton](https://hackaday.io/event/202122-raspberry-pi-hack-chat-with-eben-upton)&nbsp;and learned some fun facts: such as the DVI hack for the RP2040 was inspired by <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/6200)
[Related Guides to the Product](https://learn.adafruit.com/products/6200/guides)
![Angled shot of assembled mini computer PCB with plate.](https://cdn-shop.adafruit.com/640x480/6200-10.jpg)

Other project parts (used with either microcontroller dev board):

### USB Wired Mouse - Two Buttons plus Wheel

[USB Wired Mouse - Two Buttons plus Wheel](https://www.adafruit.com/product/2025)
This is a mouse. &nbsp;A nice, simple mouse. &nbsp;No bells or whistles. &nbsp;Just a mouse.  
  
But that doesn't mean it's not the best simple mouse!&nbsp; We compared a few and liked this one quite a bit. &nbsp;It's optical for good resolution and precision, has two...

In Stock
[Buy Now](https://www.adafruit.com/product/2025)
[Related Guides to the Product](https://learn.adafruit.com/products/2025/guides)
![Angled Shot of the USB Wired Mouse - Two Buttons plus Wheel](https://cdn-shop.adafruit.com/640x480/2025-05.jpg)

### Part: 3.5mm Male/Male Stereo Cable - 1m3.5mm Male/Male Stereo Cable 3.5mm Male/Male Stereo Cable
quantity: 1
1m
[3.5mm Male/Male Stereo Cable - 1m3.5mm Male/Male Stereo Cable 3.5mm Male/Male Stereo Cable](https://www.adafruit.com/product/2698)

### Part: Vertical Wall Power Supply with USB C
quantity: 1
5V 3A Output and Switch
[Vertical Wall Power Supply with USB C](https://www.adafruit.com/product/5801)

### Part: Pink and Purple Woven USB A to USB C Cable
quantity: 1
1 meter long
[Pink and Purple Woven USB A to USB C Cable](https://www.adafruit.com/product/5153)

## HDMI/DVI Display

An HDMI/DVI display that can be set to 640x480 mode.

[This one](https://www.adafruit.com/product/1667) is great because it can be set to 4:3 mode so your image won't be stretched, and it has a 3.5mm TRS audio input for the internal speakers.

![hdmi monitor](https://cdn-learn.adafruit.com/assets/assets/000/136/242/medium640/hacks_monitor.jpg?1744218858)

### Part: Slim HDMI Cable
quantity: 1
900mm / 3 feet long
[Slim HDMI Cable](https://www.adafruit.com/product/2421)

### USB Powered Speakers

[USB Powered Speakers](https://www.adafruit.com/product/1363)
Add some extra boom to your audio project with these powered loudspeakers. We sampled half a dozen different models to find ones with a good frequency response, so you'll get quality audio output for music playback. Simply connect the standard 3.5mm stereo plug into your Raspberry Pi model...

In Stock
[Buy Now](https://www.adafruit.com/product/1363)
[Related Guides to the Product](https://learn.adafruit.com/products/1363/guides)
![Two square-ish USB Powered Speakers](https://cdn-shop.adafruit.com/640x480/1363-07.jpg)

### Plastic mounting plate for breadboard and Arduino - rubber feet!

[Plastic mounting plate for breadboard and Arduino - rubber feet!](https://www.adafruit.com/product/275)
By popular demand! We now have the plates from the [ARDX](http://www.adafruit.com/products/170) available separately. Acrylic plate is engraved and cut here at the Adafruit factory. There are mounting holes for your [Arduino](http://www.adafruit.com/products/50) and a...

In Stock
[Buy Now](https://www.adafruit.com/product/275)
[Related Guides to the Product](https://learn.adafruit.com/products/275/guides)
![Top down view of a Plastic mounting plate for breadboard and Arduino with rubber bummper and mounting screws. ](https://cdn-shop.adafruit.com/640x480/275-00.jpg)

### Part: Hook-up Wire Spool Set
quantity: 1
22AWG Stranded-Core - 6 x 25ft
[Hook-up Wire Spool Set](https://www.adafruit.com/product/3111)

### Part: Half Sized Premium Breadboard
quantity: 1
400 Tie Points
[Half Sized Premium Breadboard](https://www.adafruit.com/product/64)

### Part: Black Nylon Machine Screw and Stand-off Set – M2.5 Thread
quantity: 1
Black Nylon Machine Screw and Stand-off Set – M2.5 Thread
[Black Nylon Machine Screw and Stand-off Set – M2.5 Thread](https://www.adafruit.com/product/3299)

# Larsio Paint Music

## For Fruit Jam

The pages in this section are for setting up Larsio Paint Music on the Fruit Jam.

![](https://cdn-learn.adafruit.com/assets/assets/000/139/629/medium800/hacks_IMG_7771.jpg?1757549890)

# Larsio Paint Music

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

Warning: Please use the latest release of 10.x or higher for the Fruit Jam. Also use the latest libraries for the best functionality.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_fruit_jam/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![reset and boot highlighted](https://cdn-learn.adafruit.com/assets/assets/000/138/708/medium800/adafruit_products_Resetboot.jpg?1754331128 )

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RP2350 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RP2350**.

&nbsp;

Drag the **adafruit-circuitpython-_boardname_-_language_-_version_.uf2** file to **RP2350.**

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png](https://cdn-learn.adafruit.com/assets/assets/000/132/253/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png?1726067809)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png](https://cdn-learn.adafruit.com/assets/assets/000/132/254/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png?1726067866)

The **RP2350** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png](https://cdn-learn.adafruit.com/assets/assets/000/132/255/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png?1726067932)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RP2350. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2 for RP2350](https://cdn-learn.adafruit.com/assets/assets/000/132/526/original/rp2350_flash_nuke.uf2)
# Larsio Paint Music

## Code Larsio Paint Music

Danger: Some of the functionality used here (USB Host for mouse in particular) is hot off the press. You'll want to install CircuitPython 10.0.0-alpha.5 or higher on your board rather than the 9.2.7 release version mentioned in the CircuitPython Install page.

## Download the Project Bundle

Your project will use a specific set of CircuitPython libraries, sprite assets, sound assets, and&nbsp; **.py** &nbsp;files. To get everything you need, click on the&nbsp; **Download Project Bundle** &nbsp;link below, and uncompress the .zip file.

Drag the contents of the uncompressed bundle directory onto your board's&nbsp; **CIRCUITPY** &nbsp;drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.

![Larsio_Paint_Music.png](https://adafruit.github.io/Adafruit_Learning_System_Guides//Fruit_Jam_Larsio_Paint_Music.png )

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/Larsio_Paint_Music/code.py

## How It Works
To keep things manageable,&nbsp;_ **Larsio Paint Music** _ uses a modular design with each component handling a specific set of related tasks:

| Module | Use |
| --- | --- |
| `code.py` | Main application entry point |
| `sound_manager.py` | Audio handling (WAV samples, and synthio) |
| `note_manager.py` | Manages note positions and properties |
| `ui_manager.py` | Coordinates UI elements and user interaction |
| `display_manager.py` | Configures and initializes the display |
| `staff_view.py` | Creates and manages the music staff visuals |
| `control_panel.py` | Handles buttons and controls |
| `input_handler.py` | Processes mouse input |
| `sprite_manager.py` | Loads and manages graphics assets |
| `cursor_manager.py` | Manages the mouse cursor |
| `playback_controller.py` | Controls playback and timing |

Here's how these modules work.

## Main Application ( **code.py** )

This file runs when the board starts up and then it coordinates the other modules.

## Sound Manager

The `SoundManager` handles all audio playback, including WAV samples, MIDI output, and synthesized sounds. It's one of the more complex parts of the application.&nbsp;

It also auto-detects which board is being used (Metro RP2350 or Fruit Jam) and configures the I2S pins appropriately.

### Audio Mixer

The app uses an audio mixer with multiple voices, enabling simultaneous sounds.

### Multi-Channel Sound

The program supports multiple instrument channels:

- **Channel 1 (Lars)**: Custom WAV samples of everyone's favorite sloth
- **Channel 2 (Heart)**: Bass
- **Channel 3 (Drums)**: Percussion sounds
- **Channels 4-6** : Synthesizer voices with different waveforms

## Note Manager

The `NoteManager` handles the positions of notes on the staff and their pitch values. It maintains a mapping of staff positions to MIDI note numbers.

When a note is added, the manager:

- Finds the closest valid position
- Creates a visual note at that position
- Adds ledger lines if needed
- Stores the note's data for playback

### UI Manager and Display Manger

These coordinate all user interface elements and interactions, as well as displaying them to the screen.

- Setting up the display
- Creating the staff view
- Handling the control panel
- Processing user input
- Managing the playback

## Staff View

The `StaffView` class creates the musical staff display with proper music notation spacing. It draws the staff lines, measure bars, and quarter note dividers so you can more easily see the bar subdivisions.

## Control Panel

The `ControlPanel` class handles all the UI controls for the application, including transport buttons and channel selectors.

## Input Handling

The `InputHandler` processes mouse input for interacting with the application, including mouse position and interactions:

- Left-click to add notes
- Right-click to delete notes
- Click on channel icons to switch instruments
- Control playback with transport buttons
- Adjust tempo

## Sprite Manager

The `SpriteManager` loads and manages all graphical assets using BMP files:

Each instrument channel has its own unique sprite:

- Channel 1: Lars
- Channel 2: Heart (bass)
- Channel 3: Drum
- Channel 4: Meatball sprite for sine wave notes
- Channel 5: star sprite for triangle wave notes
- Channel 6: Adabot Head sprite for sawtooth wave notes

The sprite manager also handles preview notes shown during mouse hover, and handles button sprites for the transport controls.

## Cursor Manager

The `CursorManager` handles the mouse cursor visuals, switching between different cursor styles based on context:

- **Crosshair Cursor** : Used when over the staff for precise note placement
- **Triangle Cursor** : Used when over buttons or controls

The offsets for each cursor ensure that the "hot spot" or active point of the cursor is properly aligned with the actual mouse position, making interaction more intuitive.

## Playback Controller

The `PlaybackController` manages the playback of notes:

- Moves a playhead across the staff
- Triggers all notes at the current position
- Handles looping when enabled
- Stops playback when finished

## Main Loop

The application's main loop continuously:

- Updates the playback (if active)
- Processes mouse input
- Updates the cursor position
- Handles button clicks

## Memory Management

Throughout the code, you'll notice calls to `gc.collect()` - this is garbage collection to free up memory. CircuitPython has limited RAM, and audio/graphics can use a lot of it!

# Larsio Paint Music

## Prep Fruit Jam

![](https://cdn-learn.adafruit.com/assets/assets/000/139/398/medium800/hacks_fj_larsio_01.jpg?1756917419)

## Connections

- Plug an HDMI cable into **HSTX DVI-D Video Output** on the Fruit Jam, then plug other end of cable into your HDMI TV or monitor
- Plug a set of headphones or 3.5mm TRS stereo cable into the DAC output port (labeled&nbsp; **Stereo Headphone** ). You can use headphones or plug the cable into the input of an amplifier or powered speakers, just watch the levels
- Plug a USB mouse into the **USB 1** port on the Fruit Jam
- Power the Fruit Jam by plugging a USB C cable into the USB C Power & Data port

![](https://cdn-learn.adafruit.com/assets/assets/000/139/399/medium640/hacks_fj_larsio_02.jpg?1756917450)

Turn on the monitor, speaker amplifier, and the Fruit Jam and you're ready to go.

![](https://cdn-learn.adafruit.com/assets/assets/000/139/400/medium800/hacks_fj_larsio_03b.jpg?1756917745)

# Larsio Paint Music

## For Metro RP2350

The pages in this section are for setting up Larsio Paint Music on the Metro RP2350.

![](https://cdn-learn.adafruit.com/assets/assets/000/139/630/medium800/hacks_assembledMetro.jpg?1757549911)

# Larsio Paint Music

## Install CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_metro_rp2350/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![](https://cdn-learn.adafruit.com/assets/assets/000/135/292/medium800/adafruit_products_boot_reset_btn_highlights.png?1739467365)

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RP2350 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RP2350**.

&nbsp;

Drag the **adafruit-circuitpython-_boardname_-_language_-_version_.uf2** file to **RP2350.**

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png](https://cdn-learn.adafruit.com/assets/assets/000/132/253/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111518.png?1726067809)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png](https://cdn-learn.adafruit.com/assets/assets/000/132/254/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111742.png?1726067866)

The **RP2350** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png](https://cdn-learn.adafruit.com/assets/assets/000/132/255/medium640/install_circuitpython_on_rp2350_Screenshot_2024-09-11_111843.png?1726067932)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RP2350. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2 for RP2350](https://cdn-learn.adafruit.com/assets/assets/000/132/526/original/rp2350_flash_nuke.uf2)
# Larsio Paint Music

## Preparing the Metro RP2350

The USB Host port is the only part of this project that required soldering.

The USB Host pin connections are highlighted on the Metro image to the left. You will need a small piece of standard 0.1 inch male header, with 4 pins, to fit the holes.

You can cut header with diagonal cutters or break them with pliers or even your fingers. Just be sure to wear eye protection as they can fly when cut.&nbsp;

![Metro RP2350 with USB Host pins 5V, D-, D+, and GND highlighted. They sit between the main chip and the HSTX connector.](https://cdn-learn.adafruit.com/assets/assets/000/135/704/medium640/gaming_raspberry_pi_adafruit_products_pinouts_usbhost_highlight.png?1741378462)

![A row of 4 standard male header pins ready to be soldered to Metro](https://cdn-learn.adafruit.com/assets/assets/000/135/705/medium640/gaming_usb_host_pins.jpg?1741378510)

Put the short end of the header into the holes in the Metro marked USB Host and secure them with putty, blutack, tape, etc. Turn the Metro over and you should see the header barely poking out of the bottom of the board. If the pins stick through a great deal you may have the header pins upside down, double check the short end is sticking into the board.

Solder the 4 pin "nubbins" to the board.

![Metro RP2350 upside down next to HAKO soldering station](https://cdn-learn.adafruit.com/assets/assets/000/135/706/medium640/gaming_usb_host_soldering.jpeg?1741378603)

![Male header pins poking through the USB host pin holes on the Metro RP2350](https://cdn-learn.adafruit.com/assets/assets/000/135/707/medium640/gaming_usb_host_unsoldered.jpg?1741378690)

![Metro RP2350 upside down with USB Host pins soldered.](https://cdn-learn.adafruit.com/assets/assets/000/135/708/medium640/gaming_usb_host_soldered.jpg?1741378758)

Turn the board over and remove the material securing the pins. Now there is a new 4-pin header.&nbsp;

Get the USB Host cable and wire as follows:

**GRD** to **Black**

**D+** to **Green**

**D-** to **White**

**5V** to **Red**

![Metro RP2350 right side up with the USB Host male header pins soldered.](https://cdn-learn.adafruit.com/assets/assets/000/135/709/medium640/gaming_usb_host_pins_complete.jpg?1741378869)

![](https://cdn-learn.adafruit.com/assets/assets/000/135/710/medium800/gaming_usb_host_wire_attached.jpg?1741378939)

## HSTX Connection to DVI
![](https://cdn-learn.adafruit.com/assets/assets/000/135/711/medium800/gaming_hstx_breakout_ribbon_connected.png?1741378983)

Get the HSTX cable. Any length Adafruit sells is fine. CAREFULLY lift the dark grey bar up on the Metro, insert the cable silver side down, blue side up, then put the bar CAREFULLY down, ensuring it locks. If it feels like it doesn't want to go, do not force it.

Do the same with the other end and the DVI breakout. Note that the DVI breakout will be inverted/upside down when compared to the Metro - this is normal for these boards and the Adafruit cables.

# Larsio Paint Music

## Metro RP2350 DAC Circuit

![](https://cdn-learn.adafruit.com/assets/assets/000/136/905/medium800/hacks_metro_larsio_fritz.jpg?1747363073)

## DAC Wiring

The TVL320DAC3100 is wired up with I2S for digital audio, I2C for settings, power, ground, and a reset line. Make the following connections between the Metro and the DAC either on a breadboard or Perma Proto board:

- **Metro 3V to DAC VIN**
- **Metro GND to DAC GND**
- **Metro SDA to DAC SDA**
- **Metro SCL to DAC SCL**
- **Metro D9 to DAC BCLK**
- **Metro D10 to DAC WSEL**
- **Metro D11 to DAC DIN**
- **Metro D7 to DAC RST**

![](https://cdn-learn.adafruit.com/assets/assets/000/136/906/medium640/hacks_dacfrtiz.jpg?1747363260)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/907/medium640/hacks_DACwire.jpg?1747363991)

![](https://cdn-learn.adafruit.com/assets/assets/000/136/908/medium800/hacks_assembledMetro.jpg?1747364011)

Danger: Some of the functionality used here (USB Host for mouse in particular) is hot off the press. You'll want to install CircuitPython 10.0.0-alpha.5 or higher on your board rather than the 9.2.7 release version mentioned in the CircuitPython Install page.

# Larsio Paint Music

## Code Larsio Paint Music

Danger: Some of the functionality used here (USB Host for mouse in particular) is hot off the press. You'll want to install CircuitPython 10.0.0-alpha.5 or higher on your board rather than the 9.2.7 release version mentioned in the CircuitPython Install page.

## Download the Project Bundle

Your project will use a specific set of CircuitPython libraries, sprite assets, sound assets, and&nbsp; **.py** &nbsp;files. To get everything you need, click on the&nbsp; **Download Project Bundle** &nbsp;link below, and uncompress the .zip file.

Drag the contents of the uncompressed bundle directory onto your board's&nbsp; **CIRCUITPY** &nbsp;drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary.

![Larsio_Paint_Music.png](https://adafruit.github.io/Adafruit_Learning_System_Guides//Fruit_Jam_Larsio_Paint_Music.png )

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Fruit_Jam/Larsio_Paint_Music/code.py

## How It Works
To keep things manageable,&nbsp;_ **Larsio Paint Music** _ uses a modular design with each component handling a specific set of related tasks:

| Module | Use |
| --- | --- |
| `code.py` | Main application entry point |
| `sound_manager.py` | Audio handling (WAV samples, and synthio) |
| `note_manager.py` | Manages note positions and properties |
| `ui_manager.py` | Coordinates UI elements and user interaction |
| `display_manager.py` | Configures and initializes the display |
| `staff_view.py` | Creates and manages the music staff visuals |
| `control_panel.py` | Handles buttons and controls |
| `input_handler.py` | Processes mouse input |
| `sprite_manager.py` | Loads and manages graphics assets |
| `cursor_manager.py` | Manages the mouse cursor |
| `playback_controller.py` | Controls playback and timing |

Here's how these modules work.

## Main Application ( **code.py** )

This file runs when the board starts up and then it coordinates the other modules.

## Sound Manager

The `SoundManager` handles all audio playback, including WAV samples, MIDI output, and synthesized sounds. It's one of the more complex parts of the application.&nbsp;

It also auto-detects which board is being used (Metro RP2350 or Fruit Jam) and configures the I2S pins appropriately.

### Audio Mixer

The app uses an audio mixer with multiple voices, enabling simultaneous sounds.

### Multi-Channel Sound

The program supports multiple instrument channels:

- **Channel 1 (Lars)**: Custom WAV samples of everyone's favorite sloth
- **Channel 2 (Heart)**: Bass
- **Channel 3 (Drums)**: Percussion sounds
- **Channels 4-6** : Synthesizer voices with different waveforms

## Note Manager

The `NoteManager` handles the positions of notes on the staff and their pitch values. It maintains a mapping of staff positions to MIDI note numbers.

When a note is added, the manager:

- Finds the closest valid position
- Creates a visual note at that position
- Adds ledger lines if needed
- Stores the note's data for playback

### UI Manager and Display Manger

These coordinate all user interface elements and interactions, as well as displaying them to the screen.

- Setting up the display
- Creating the staff view
- Handling the control panel
- Processing user input
- Managing the playback

## Staff View

The `StaffView` class creates the musical staff display with proper music notation spacing. It draws the staff lines, measure bars, and quarter note dividers so you can more easily see the bar subdivisions.

## Control Panel

The `ControlPanel` class handles all the UI controls for the application, including transport buttons and channel selectors.

## Input Handling

The `InputHandler` processes mouse input for interacting with the application, including mouse position and interactions:

- Left-click to add notes
- Right-click to delete notes
- Click on channel icons to switch instruments
- Control playback with transport buttons
- Adjust tempo

## Sprite Manager

The `SpriteManager` loads and manages all graphical assets using BMP files:

Each instrument channel has its own unique sprite:

- Channel 1: Lars
- Channel 2: Heart (bass)
- Channel 3: Drum
- Channel 4: Meatball sprite for sine wave notes
- Channel 5: star sprite for triangle wave notes
- Channel 6: Adabot Head sprite for sawtooth wave notes

The sprite manager also handles preview notes shown during mouse hover, and handles button sprites for the transport controls.

## Cursor Manager

The `CursorManager` handles the mouse cursor visuals, switching between different cursor styles based on context:

- **Crosshair Cursor** : Used when over the staff for precise note placement
- **Triangle Cursor** : Used when over buttons or controls

The offsets for each cursor ensure that the "hot spot" or active point of the cursor is properly aligned with the actual mouse position, making interaction more intuitive.

## Playback Controller

The `PlaybackController` manages the playback of notes:

- Moves a playhead across the staff
- Triggers all notes at the current position
- Handles looping when enabled
- Stops playback when finished

## Main Loop

The application's main loop continuously:

- Updates the playback (if active)
- Processes mouse input
- Updates the cursor position
- Handles button clicks

## Memory Management

Throughout the code, you'll notice calls to `gc.collect()` - this is garbage collection to free up memory. CircuitPython has limited RAM, and audio/graphics can use a lot of it!

# Larsio Paint Music

## Plug in Metro

https://youtu.be/hqSvbptKp_I

![](https://cdn-learn.adafruit.com/assets/assets/000/136/930/medium800/hacks_LPMbeut.jpg?1747527592)

## Video Output

Plug the HDMI cable out of the DVI video output on the Metro RP2350 and into your HDMI monitor.&nbsp;

Note: some monitors aren't capable of displaying 640x480, in which case you'll see a blank screen.&nbsp;

The [monitor linked in the Parts section](https://www.adafruit.com/product/1667) of this guide is a good bet if you need a small 640x480 4:3 ratio display. You'll also often find that older LCD televisions are 640x480 capable.

## Audio Output

Plug a 3.5mm TRS audio cable into the DAC output and either your TV's audio input if available or a set of powered speakers or headphones.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/927/medium800/hacks_IMG_5734b.jpg?1747525371)

## Mouse Input

Just like with Mario Paint, the only input device you'll need for Larsio Paint Music is a mouse. Plug a USB mouse into the USB A connector.

## Power

Power the board with a USB C power supply.

![](https://cdn-learn.adafruit.com/assets/assets/000/136/929/medium800/hacks_IMG_5739b.jpg?1747527526)

# Larsio Paint Music

## Use Larsio Paint Music

https://www.youtube.com/watch?v=1IVyyB9OG90

## Usage

Making music with Larsio Paint Music is fun and simple -- just add notes where you like and hit play! You can add notes while it's playing for fast composition. Watch the above video for a demonstration.

![](https://cdn-learn.adafruit.com/assets/assets/000/139/401/medium800/hacks_screen.jpg?1756918584)

## Voice Select

There are six types of sounds (called "voices") you can play with. Click the icons in the upper left corner to choose among them. The first three are wav samples, the other three are synthio synthesizer voices.

- Lars - pitched sample of eveyone's favorite creepy sloth, Lars
- Heart - bass multi-sample
- Drums - multiple drum samples: kick, snare, closed hihat, open hihat, crash cymbal
- Meatball - synthesizer sine wave notes
- Star - synthesizer triangle wave notes
- Robot - synthesizer sawtooth wave notes

### Add Notes

Hover the cursor over the music staff -- you'll see that you're dragging a Lars note around. Click anywhere on the staff with the left mouse button (LMB) to place a note and hear a preview.&nbsp;

### Delete Notes

If you don't like where you placed the note, delete it by hovering over it and right mouse button (RMB) clicking it.

Warning: There is no strict limit to polyphony, so you can stack up chords, beats, and melodies, but it is likely that you'll run into timing issues at hire tempo rates with lots and lots of notes.

## Play

Hover over the transport control section on the bottom and click the triangle Play button to play the four bars.

## Stop

Click the square Stop button to stop playback. The playhead will return to the beginning of the first bar.

## Loop

Click the Loop button and the song will play over and over and over again until you press stop or the power goes out!

## Clear

If you want to clear all the notes at once, click the bomb-shaped Clear button.

## Tempo

You can decrease or increase the tempo by clicking the +/- buttons in the upper right corner.

![](https://cdn-learn.adafruit.com/assets/assets/000/139/402/medium800/hacks_image.png?1756918621)


## Featured Products

### Adafruit Fruit Jam - Mini RP2350 Computer

[Adafruit Fruit Jam - Mini RP2350 Computer](https://www.adafruit.com/product/6200)
We were catching up on a recent [hackaday hackchat with eben upton](https://hackaday.io/event/202122-raspberry-pi-hack-chat-with-eben-upton)&nbsp;and learned some fun facts: such as the DVI hack for the RP2040 was inspired by <a...></a...>

Out of Stock
[Buy Now](https://www.adafruit.com/product/6200)
[Related Guides to the Product](https://learn.adafruit.com/products/6200/guides)
### Adafruit Metro RP2350 with PSRAM

[Adafruit Metro RP2350 with PSRAM](https://www.adafruit.com/product/6267)
Choo! Choo! This is the RP2350 Metro Line, making all station stops at "Dual Cortex M33 mountain", "528K RAM round-about" and "16 Megabytes of Flash town" and a bonus stop at "8 Megabytes of PSRAM village". This train is piled high with hardware that...

In Stock
[Buy Now](https://www.adafruit.com/product/6267)
[Related Guides to the Product](https://learn.adafruit.com/products/6267/guides)
### USB Wired Mouse - Two Buttons plus Wheel

[USB Wired Mouse - Two Buttons plus Wheel](https://www.adafruit.com/product/2025)
This is a mouse. &nbsp;A nice, simple mouse. &nbsp;No bells or whistles. &nbsp;Just a mouse.  
  
But that doesn't mean it's not the best simple mouse!&nbsp; We compared a few and liked this one quite a bit. &nbsp;It's optical for good resolution and precision, has two...

In Stock
[Buy Now](https://www.adafruit.com/product/2025)
[Related Guides to the Product](https://learn.adafruit.com/products/2025/guides)
### USB Type A Jack Breakout Cable with Premium Female Jumpers

[USB Type A Jack Breakout Cable with Premium Female Jumpers](https://www.adafruit.com/product/4449)
If you'd like to connect a USB-host-capable chip to your USB peripheral, this cable will make the task very simple.&nbsp; **There is no converter chip in this cable!** &nbsp;It's basically a plain USB cable that's cut in half and with jumper sockets on the power and data...

In Stock
[Buy Now](https://www.adafruit.com/product/4449)
[Related Guides to the Product](https://learn.adafruit.com/products/4449/guides)
### 3.5mm Male/Male Stereo Cable

[3.5mm Male/Male Stereo Cable](https://www.adafruit.com/product/2698)
Seamlessly transmit high-quality stereo audio with this&nbsp; **3.5mm Male/Male Stereo Cable.&nbsp;**

Ideal for "passing the AUX cord," or&nbsp;connecting audio devices&nbsp;such as&nbsp;smartphones, tablets, MP3 players, car stereos, portable speakers or any other...

In Stock
[Buy Now](https://www.adafruit.com/product/2698)
[Related Guides to the Product](https://learn.adafruit.com/products/2698/guides)
### Vertical Wall Power Supply with USB C - 5V 3A Output and Switch

[Vertical Wall Power Supply with USB C - 5V 3A Output and Switch](https://www.adafruit.com/product/5801)
We love the Raspberry Pi 4 and 5, with their fancy new USB Type C power connectors. Now we have an even&nbsp;_better_&nbsp;power supply that can be used with either Pi 4 or even a Pi 5 with 5V output, 3A of current to handle builds with accessories and displays. The vertical-style plug...

In Stock
[Buy Now](https://www.adafruit.com/product/5801)
[Related Guides to the Product](https://learn.adafruit.com/products/5801/guides)
### Slim HDMI Cable - 900mm / 3 feet long

[Slim HDMI Cable - 900mm / 3 feet long](https://www.adafruit.com/product/2421)
Connect two HDMI devices together and save space with this slim, high quality HDMI cable. It has nice molded grips for easy installation and&nbsp;is 914mm long (~3 feet). Sporting a&nbsp;teeny&nbsp;4mm diameter this cable stays out of your way!

We also have slim HDMI cables at <a...></a...>

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/2421)
[Related Guides to the Product](https://learn.adafruit.com/products/2421/guides)
### Pink and Purple Woven USB A to USB C Cable - 1 meter long

[Pink and Purple Woven USB A to USB C Cable - 1 meter long](https://www.adafruit.com/product/5153)
This cable is not only super-fashionable, with a woven pink and purple Blinka-like pattern, it's also made for USB C for our modernized breakout boards, Feathers, and more.&nbsp;&nbsp;[If you want something just like it but for Micro B, we...](https://www.adafruit.com/product/4111)

Out of Stock
[Buy Now](https://www.adafruit.com/product/5153)
[Related Guides to the Product](https://learn.adafruit.com/products/5153/guides)

## Related Guides

- [Adafruit RP2350 22-pin FPC HSTX to DVI Adapter](https://learn.adafruit.com/adafruit-rp2350-22-pin-fpc-hstx-to-dvi-adapter.md)
- [Adafruit Metro RP2350](https://learn.adafruit.com/adafruit-metro-rp2350.md)
- [Adafruit TLV320DAC3100 I2S DAC](https://learn.adafruit.com/adafruit-tlv320dac3100-i2s-dac.md)
- [Using a Mouse with USB Host](https://learn.adafruit.com/using-a-mouse-with-usb-host.md)
- [Adafruit Fruit Jam](https://learn.adafruit.com/adafruit-fruit-jam.md)
- [Pi SSD Media Server](https://learn.adafruit.com/pi-ssd-media-server.md)
- [Holiday Tree with Feather RP2040 Scorpio](https://learn.adafruit.com/holiday-tree-with-scorpio.md)
- [Homefruit FeatherWing Tester](https://learn.adafruit.com/homefruit-featherwing-tester.md)
- [Tyrell Desktop Synthesizer](https://learn.adafruit.com/tyrell-desktop-synthesizer.md)
- [Feather Fingerboard](https://learn.adafruit.com/feather-fingerboard.md)
- [PyPortal Case](https://learn.adafruit.com/pyportal-case.md)
- [USB MIDI Host Messenger](https://learn.adafruit.com/usb-midi-host-messenger.md)
- [Bricktunes: LEGO Synthesizer Glove](https://learn.adafruit.com/bricktunes-lego-glove-synthesizer.md)
- [Knobby Sequencer](https://learn.adafruit.com/knobby-sequencer.md)
- [PyPortal Guitar Tuner](https://learn.adafruit.com/pyportal-guitar-tuner.md)
- [Wireless NeoPixel Controller](https://learn.adafruit.com/neotrellis-neopixel-controller.md)
- [No-Code Indoor Grow Monitor with PPFD and VPD Measurements](https://learn.adafruit.com/no-code-indoor-grow-monitor.md)
- [Pico W HTTP Server with CircuitPython](https://learn.adafruit.com/pico-w-http-server-with-circuitpython.md)
- [HalloWing Magic 9 Ball](https://learn.adafruit.com/hallowing-magic-9-ball.md)
- [MP3 Playback in CircuitPython with Lars the Sloth Puppet](https://learn.adafruit.com/mp3-circuitpython-lars.md)
