We've been doing lots of audio projects using Arduino and IDF code.
All in C++
But what about Micropython - does it support audio?
So, let's check this.
I've got my TinyPico wired up and I've flashed it with the latest Mircopython firmware.
Let's see if we can use I2S
It looks like I2S support is not built-in yet,
but fortunately, when we look on GitHub we do find a pull request that will add support.
Let's do a custom build of Micropython and try it out.
But first I'd like to thank PCBWay for sponsoring this video,
PCBWay offer PCB Production, CNC and 3D Printing, PCB Assembly and much much more.
They are great to deal with and offer excellent quality, service and value for money.
Check out the link in the description.
Building Micropython is actually pretty straightforward.
The first thing we'll need is an installation of the Esspresif IDF
I'm also going to set my Python version using a program called pyenv.
This will make sure I'm using python3 for everything.
We clone the ESP-IDF from GitHub using this command:
This will clone the repository at release 4.2 and include all the required git submodules.
I'm using 4.2 as this is the latest version that the Micopython README says is compatible
If you're feeling brave you can try other releases. And even try the bleeding edge releases.
Once we've got the IDF cloned we just need to change into the directory and run this command.
This will download all the required dependencies and gets everything set up.
From now on, when we want to use the IDF to build a project
we just change into the ESP-IDF directory and run this little snipped of code.
This configures all our paths and environment variables for the IDF.
To get our custom version of Micropython we just clone the main Micropython repository.
Using this command.
This gives us the latest code
and then to add support for I2S we need to get the pull request using this command:
This command fetches the pull request with id 7183 and puts it in a local branch called i2s_support.
We can now simply merge that branch into our current branch using git merge:
Obviously, this does come with a big caveat.
The pull request has not been finished so the APIs and the functionality may change.
We can now follow the instructions for building Micropython for the ESP32.
First, we build the cross-compiler in the root of the repository:
And then we build the ESP32 port.
I'm going to build explicitly for the TinyPICO board.
You can also build for Generic boards and Generic boards with SPI ram.
Once the build is finished it actually tells us the command to run to flash the new firmware to the device.
We just need to copy and paste this and our board will be updated.
Now if we go back to the Thonny IDE and reconnect can see that I2S is now available.
I've created a pretty simple python script to record audio to flash and then play it back.
I'll run through the bits of this code
and put the equivalent C++ code next to it so we can compare implementations.
The first thing we do is import I2S and Pin. This is very similar to the hash includes that we see in the C++ code.
Here we have the code for setting up a GPIO pin. We are defining it as an input pin and setting it to have an internal pull-down resistor.
And I've created a little helper function to wait for the button to be pressed with a small delay to handle any bouncing.
You can see that the code pretty much maps across between Python and C++
Here we have the setup for the I2S microphone. This is very similar to the C++ code but it's a bit less verbose.
This is true again for setting up the I2S amplifier. It all looks quite familiar - again the python code is less verbose than the C++ code.
Here’s the code for recording the audio to a file.
We open up the file for writing binary.
We're using the with operator which ensures that the file is closed when we are finished with it.
We read in the samples from the I2S device.
Amplify them by using this helper function that shifts values to the left.
Initially, I tried doing this in python code, but it was pretty slow.
And then we simply write the samples to the file.
Playback is pretty similar looking code.
Once again we open up the file - this time for reading binary.
We read in the samples.
And repeatedly write the samples to the i2s device until there is no more data in the file.
I’ve put the complete code side by side here, python on the left and C++ on the right
so you can get an idea of how long each implementation is.
Obviously, you could make the C++ code shorter by removing comments and merging lines together
but the python code is definitely less verbose and possibly easier to understand.
but this does come at the code of some flexibility
We don't have all the options that we have in C++ world with access to all the Arduino and IDF functions.
Let's see it in action
I've copied the script into Thonny.
All we have to do is hit run.
It seems to work pretty well.
I've put my sample code on GitHub - there's a link in the description.
There's a repo on GitHub as well with a lot more examples
That's linked from the PR on MicroPyhton.
I've added a link to it as well.
As I have already said - the code is likely to change before it makes it into the main release of Micropython
so keep an eye out.
Once the PR has been finished and merged into the main release I'll revisit this topic and make any updates necessary.
Thanks for watching
I'll see you in the next video!