I recently ported my data-over-sound library called "ggwave" to run on microcontrollers and I though it might be of interest for people working on various IoT project. Below are some technical details and if you just want a quick demo, you can watch this short demonstration:
The library is written in C++, but to make it work on embedded devices I had to avoid using the standard library and reduce the memory usage and memory allocations to a minimum. As a result, I am now considering porting it to plain C, since I don't gain much from C++ at this point.
The communication protocols are based on frequency-shift keying (FSK) modulation. The library has built-in forward error correction using Reed-Solomon codes and optionally supports Direct Sequence Spread which seems to improve the robustness of the transmission. The protocols that are suitable for microcontrollers provide data rate speeds of about 5-10 B/second and the transmission is reliable withinh 0.5 - 1.0 m. They operate in the [1.0kHz - 2.5kHz] range, so your device has to support a sample rate of at least 6000 Hz in order to be able to receive sound data.
I have tested the library using an Arduino RP2040 Connect board which has a built-in microphone. Also, I did tests using an ESP32 microcontroller with external analog microphone. The ESP32 has a 12-bit ADC that can be used to process the analog input from the microphone in real-time. Both devices are demonstrated in the video above.
The library also allows the microcontrollers to transmit data - you just need to attach a buzzer or a speaker to one of the digital output pins and use a suitable mono-tone "ggwave" transmission protocol as demonstrated in the examples.
The project is open-source and available on Github [0] and provides many different examples. I am looking forward to some interesting ideas of using this type of communication on low-end microcontrollers, so if you have one - definitely let me know!
Obviously you won't be using any of this for regular communication, but there's a whole world of cool uses for sending short (up to a few bytes) messages over the air. And despite knowing dial-up modems exist, people are constantly impressed by novel applications of it.
This is a hobby project that I have been working on and off for the past few years. It started with a simple PoC [0] for sharing files through WebRTC using sound signaling to exchange the SDP between peers and I recently decided to extract the data-over-sound part into a standalone library [1] so I can use it in different projects. The current post is one such project: "Waver" - a simple application with the primary purpose to showcase the capabilities of my data-over-sound library. The main functionality of the app is to exchange short text messages through sound with nearby devices. All you need to use it is to enable the device's speakers and microphone. The app also includes an early prototype for sharing files with sound signaling. The app runs on iOS, Android, Linux, Mac OS and Web - I put quite some effort to make it easy to try out :)
The implemented data-over-sound protocol is quite simple. It is essentially a 6-tone FSK modulation scheme with special markers to mark the start and end of the transmission. The bandwidth is quite low (8-16 B/s), but I think the transmission is reliable. I've been testing it with a few devices across the room and it seems robust enough. The ultrasound protocols especially are very robust to surrounding noise.
An additional challenge I had to solve while working on the data-over-sound protocol was to make the encoded data sound good to the human ear. Although the current sound is not the most pleasant thing to hear (especially the markers), I think it turned out relatively OK :-)
There are a few reasons about why I decided to implement this FSK approach instead of using an existing and well-known modulation scheme used by modems:
- My DSP knowledge is fairly limited
- Most modulations typically sound like noise (not very pleasant to the ear)
- Reliable air-gapped transmission seems to be much more difficult to achieve compared to over-the-wire
- But mainly because I find it more fun to implement something from scratch
There are similar solutions available on the market, but I feel they are difficult to try out. I wanted to make something free and very easy to test and see how it works. The data-over-sound library [1] still needs some work, but it's getting there. I am hoping to find some fun and potentially useful applications of this, so I am looking for ideas. Also, any feedback about the performance is very much appreciated.
If you decide to try out the Waver app, make sure to watch the 2 min video in the link [2] for a quick tutorial. Also, there is a small easter egg at the end of the video :-)
[0] - https://github.com/ggerganov/wave-share
Having said that, I am actually working on a small library for data-over-sound which can be used for small data chunk transmissions across the room [0].