Remote Code Execution and Audio Streaming to Pico W

by malonesm in Circuits > Raspberry Pi

0 Views, 0 Favorites, 0 Comments

Remote Code Execution and Audio Streaming to Pico W

covered_transmitter.jpeg
uncovered_transmitter.jpeg

Have you ever wanted to update your Pico without having to reconnect your build? Maybe its buried somewhere deep in a breadboard, and you just want to tweak a setting or two. Or, maybe you've got a few music files and you'd like to switch between them without deleting and moving around filenames.

Supplies

A speaker, a Pico W, and some breadboarding wires. I've also used a 5 mm LED to spice up the remote code execution. Beyond that, it is whatever you'd like to execute on the board.

The Case

container lid off.jpeg
container lid on.jpeg

I found a simple box with a grill for the speaker to work best. One of the sides is left off in order to have wires fit into the casing. There is also a space to wire an LED. The precision is good enough that you can just stick the LED on top and have its legs hang down, then solder some wires onto the end. I've also attached the stl file so that you can print it yourself. It was printed in about two hours on the Bambu Lab X1 Mini.

Downloads

The Wiring

wiring.jpeg

There are a few sections of the wiring. First, I have an audio jack connected to my breakout board, which I recommend as it makes connecting the speaker much more stable. Then, have a jumper wire connecting the outside of both pins on audio jack and connect it to GP15. I also have a button connected to ground and GP0. This is so that we can put our board into write mode, which I will go over later. You don't need this, but it will make debugging harder/slower late. I have a button spanning RUN and GND, which allows me to quickly short and restart the board. More on that later. Finally, I have an LED connected to GP16 for demonstration purposes. Use a LED in series with a resistor to limit amps pulling through the LED so that we don't burn it out.

Code, Part 1

The first part of the code we have to go over is boot.py. boot.py is a special file that gets run only when the board is initially turned on, and not when it undergoes a soft reset. This allows the board to enter write mode so that it can write to its own filesystem. The reason we need this is that we are going to be sending wav files and code.py needs to be able to save the code to the Pico W filesystem, and it can't do that if the board is in its default state, which is read only (for itself). This is also why I have the button wired between GP0 and GND. If you don't want to use a button, you can tie GP0 low when you want to use the board and remove the jumper low when you want to edit the code.

Downloads

Code, Part 2

This part covers the Pico W code. The main places to pay attention to are where it sets the wifi SSID, PASSWORD, and SERVER_URL. The SERVER_URL will be the server of your flask app, which we will set up later. For now, we can take a look through code.py. This program handles interacting with a web server which will handle all of the sending of information. We have functions like update(), which check with the server to see if we need to do anything different (like, for instance, removing the saved wavs or if they have a wav they'd like us to download). grab_remote_code(), execute_remote_code(), get_wav_files(), and play_sound() all should be self-explanatory.

Downloads

The Flask App

Flask is a python library that allows us to write web apps extremely quickly. The general way that we will use this is making GET and POST endpoints that will allow our user app and our pico app to communicate with our computer, which can then send it code and wav files.


Setting up the flask app is relatively simple. Create a virtual environment, enter that environment, and then pip install flask, and you can run the server from there:

> python3 -m venv .venv

> source .venv/bin/active

> pip install flask

> python3 server.py

You will also need to install the requests library later, following similar procedures.

The first part of the program (the "@app.route" parts) handle the endpoints. Then, we connect those endpoints to associated functions within a class (for good variable management). The biggest thing that the server handles is the wav file sending.

Sending wav Files

If you've ever tried to send a large wav file to the Pico W over the internet using GET requests, you will have run into an issue. The Pico doesn't have enough memory to load large-ish wav files all at once. When the Pico tries to play music, it uses a buffer to manage the memory load. Thus, we have to do the same. The bulk of the server code is handling this buffering. There is an endpoint for getting information about the file that it is about to download. There is another endpoint that sends the wav file in chunks to the pico. There is also an "error" endpoint that allows the server to look at the output of the pico to make sure that everything goes correctly.

Downloads

The User App

The user app is relatively simple. It is a python app that uses the requests library to send requests to the server. It has the ability to send code examples to the pico, which then get uploaded every ten seconds. If you are going to write new programs, you should take care to follow the set up of those code examples. You have to deinit any used resources, and the while loop needs to use the environmental variables that were passed in from the "exec" call. For the wav file, it uses whatever wav files are in the root folder that the user app is in, and can send them to the pico. When the pico gets the command to download a new wav file, it deletes the other wav files by being sent a command through update().

Downloads

Git Repo

In case you are interested in downloading all the files at once, or seeing the structure of the project, please check out the github link here:

https://github.com/SawyerMaloney/PicoRemoteControl