Hey Everyone!
We've made a Walkie Talkie based around the ESP32!
There's a link in the description to the Fusion360 project
and the STL files for the case - so feel free to print your own version if you want to.
Let's have at what's inside and see how it works.
We have the microphone - I've made space for my own ICS-43434 breakout board
and space for the popular INMP441 microphone board.
These are both I2S microphones that interface directly with the ESP32.
Above the microphone, we have an I2S 3W amplifier board
that's powering our speaker. This also directly interfaces with the ESP32.
We have our ESP32 board - I'm using a TinyPICO here,
but you should be able to use any generic ESP32 dev board
we're not using any special features in this project.
We've got a push-button switch for controlling transmission.
We've got a simple slider switch to turn the battery on and off.
You may have noticed that I'm using a custom PCB - I got this made up by the great people
at PCBWay - as usual, they did a great job and I'm really pleased with how the boards have come out.
I've got a lot of audio projects and it's really nice to be able to just plug things together
and not to have to worry about wires going everywhere.
The only slight omission I've made is not breaking out the remaining GPIO pins - so I think I'll do that in version 2 of the board.
I've included a link to both the schematic and the project on PCBWay in case you want to order your own version.
You can also clone the project on EasyEDA and customise it as needed.
Having said that, you really don't need a PCB, you can easily just connect everything
up on breadboard - and that's exactly what I did when I was prototyping.
The schematic is very simple - we're using I2S boards for both the microphone and
the speaker which makes the wiring up of these to the ESP32 very straightforward.
You can of course modify the code to use the built-in ADC for input and the built-in DAC
for output. Very handy if you want to use analogue microphone boards and a headphone jack for output.
I've added a bit of extra circuitry to my board to create a clean power supply for the microphones.
If you watch some of my earlier videos then you'll recall that we
were picking up quite a lot of noise on the microphones when using WiFi.
To fix this noise problem we are creating a clean 3.3v power supply for the microphones
we do this by taking a direct feed from the battery, we filter this with an LC filter and then
pass this to a Low Drop Out regulator. This gives us a really nice and clean
power supply for the microphones which removes a lot of the noise issues.
I've got quite a few videos on audio input and output which you might find
interesting - I've linked to the playlist in the description.
That's really all there is on the hardware side of things.
How does it actually work?
All the code is on GitHub - the link is in the description - it should be
mostly self-explanatory, but I'll give a high-level overview here.
The main challenge with this project
is how to get the audio broadcast from one walkie-talkie to all the other walkie-talkies.
I've implemented this in two different ways. You
can easily switch between these in the code with a simple #define.
The first way is using UDP broadcast.
UDP broadcast is a very simple mechanism. You send a UDP packet to a special IP address and
your router broadcasts this packet to all the other devices on your network.
We can safely send up to 1436 bytes in a UDP packet
so if we're sampling at 16KHz and using 8-bit samples that's around 90ms of audio data.
So we need to send around 11 packets per second. This is well within the capabilities of the ESP32.
The big advantage of using broadcast UDP is that we don't need to know about our peers,
we can just broadcast a message and anyone who is listening for it will receive it. We also don't
need a centralised server that everything connects to. All the heavy lifting is done by the router.
However, there are some disadvantages of UDP that we should be aware of.
Delivery of UDP packets is only best effort - there is
no guarantee that someone will receive the packet you send.
There is also no guarantee of packet ordering - someone
may receive the packets you have sent in a completely random order.
For this project, I've chosen to ignore these two issues.
With broadcast packets, we're generally staying in the same network
so we probably won't lose too many packets and our packets will probably also come in
the correct order. If they don't then we'll just get a bit of noise and distortion on the audio.
The other big advantage of UDP broadcast is that you can receive
the packets on your desktop computer or even your phone - so it would be quite
easy to create additional clients that are not based on the ESP32.
The second way I've implemented the transport is to use ESP-NOW.
ESP-NOW is a protocol developed by Esppresif which enables multiple
ESP devices to communicate with each other without needing WiFi.
This gives us one great advantage over the UDP option
in that we don't need a WiFi network to make our Walkie-Talkie work.
So you could use the Walkie-Talkie outside.
The disadvantage with ESP-NOW is that it has a much smaller packet size of 250 bytes.
This means that we need to be sending packets 64 times a second.
We also have all the same downsides as UDP broadcast - packet delivery is best effort
and there is no guarantee what order the packets will arrive in.
However, in my tests, it seems to have performed reasonably well.
With the transport problem solved we just need to hook everything up.
We have the I2S input - this reads samples from the microphone and passes them to our transport.
Once the transport has accumulated enough data to fill a packet
it sends the data through either UDP or ESP-NOW.
On the other side, we have the same transport listening for packets.
Every time a packet is received it queues the data up for playing
via our I2S output. The I2S output just pushes samples out to the I2S amplifier.
To allow for packets taking slightly longer to arrive we have a buffer
between the transport and the I2S output. We let a small amount of time elapse before
we start playing the samples - this gives us some spare time to allow for packet jitter.
It does come at the cost of some latency in the audio - with everything taken into account using UDP the
audio is played about half a second after it was made.
All in all though the project works. Quality is not amazing,
but it's certainly sufficient for a hobby project.
And sounds like a fairly low-quality Walkie-Talkie
As always, the code is all on GitHub. Let me know what you think in the comments.
And if you have any improvements then please open up a pull request.
Some ideas that would be good to look at:
Compression of the audio to reduce bandwidth.
Some kind of Automatic Gain Control
Echo cancellation so we can have full-duplex
And I'm sure there's much much more that can be improved.
So feel free to hack away!
So that's it for this video.
I hope you enjoyed it. I certainly enjoyed making it.
And if you did enjoy it please hit the subscribe button. There are more videos coming soon.
So I'll see you in the next video!