It's time for an update about WebJack. As you see from the picture above the decoder is in a functional state. It is not merged into the main repository yet, but is available here: https://rmeister.github.io/webjack/examples/. There were two major design decisions on the way to get it working, that I'll explain here.
1. Decoding Logic
Instead of evaluating the demodulated signal at fixed points after recognition of a preamble, the time between zero-crossings is measured and divided by the samples per bit. The result gets rounded to an integer. This integer is the amount of consecutive zeros or ones. A finite state machine will finally retrieve the data. Lets simplify the explanation with an example. So e.g. between the current and the last zero-crossing were 49 times 36 samples (per bit), which means it must be the preamble and the FSM goes into the 'START' state. Next comes the start bit, which is a zero, and eventually the first data bits are zero as well. Meaning if the amount X of equal bits since the preamble end is largen than 1 (and smaller than 9, as the 9th bit must be the stop bit == high == zero-crossing), we can assume that X - 1 zeros were sent. The FSM goes into 'DATA' state or in case of an error back into 'PREAMBLE' state. In the 'DATA' state the decoder adds retrieved bits until a byte is completed. Then in the 'STOP' state the decoder checks if another byte follows or if the transmission is over (push bit). I was inspired to build the decoder this way by the implementation of modem.js. The algorithmis less dependent on the shape of the demodulated signal and therefore less error-prone.
2. Used Frequencies
During development I plugged the cable from the Arduino into my notebook and everything was fine. But on my phone I received either nothing at all or heavily corrupted data. It took a while until I figured out that recording audio with webRTC on different machines can give you very different results. Here are three recordings (2x mobile, 1x notebook) made with https://webaudiodemos.appspot.com/AudioRecorder:
You can see that the amplitude is varying for the two mobile phones, depending on the frequency. For the notebook, both frequencies have almost the same amplitude. This totally makes sense after I've read this blog article about audio codecs in webRTC: https://bloggeek.me/single-voice-codec-webrtc/
WebRTC was build with voice communication in mind and therefore may cut down the transmitted frequency range to reduce bandwidth. The lowpass filter seems not to be that sharp, so the used 7350Hz for a logical 1 still can be found in my recordings. But the attenuation is clearly visible and causes difficulties in demodulation. Look closely at the difference of the following two pictures:
You may notice the asymmetry of the first signal, taken from the demodulated phone recording. This causes problems, because the decoding logic assumes a symmetrical signal, for which zero-crossings accur at the middle of the peak-to-peak distance. This results in too short or too long distances between zero-crossings, making it difficult to distinguish the exact number of consecutive bits. However, the solution to this problem is rather simple: utilizing frequencies that will not be attenuated. Based on the earlier error calculations and the given limit of 7kHz, these frequencies come into consideration:
- 2450Hz
- 3675Hz
- 4900Hz
First one I tried was 3675Hz, half of the former 7350Hz. It turned out that this will not work, due to overlapping thresholds at the decoder of the SoftModem implementation that break the correct detection of bits at the µC. After changing the frequencies to 2450Hz (zero) and 4900Hz (one), both transmission directions do work on mobile phones. I'v tested with two phones and three browsers (Chrome, Firefox, Opera) so far.
Questions and next steps
It would be great to test with much more recordings, made with plenty of different phones. Currently I'm using the SoftModem shield, but one could probably feed the wires directly (or at least with a protecting capacitor) into the Arduino pins. Maybe I should try that so I can instruct others to make recordings without the special shield.
5 Comments
Wow, some really impressive detective work here, Richard! Kudos.
I should be able to do a test with my phone and Chromebook but am still traveling. I wonder if an ask to the main Public Lab discussion list could be helpful, though it would probably require some more explanation of both how to contribute test data and what this whole project is about (a simple "what were trying to make possible" that'd appeal to Arduino users, maybe). What do you think? I like the idea of showing a simpler audio cable hookup and maybe even a short video to make the testing steps even easier?
Is this a question? Click here to post it to the Questions page.
Reply to this comment...
Log in to comment
Thanks Jeff!
You are right, the explanation is rather short. And in addition to asking at the main discussion list, I had the idea to write an article at Instructables.com. Or do you think the project is in an too early state for that?
Is this a question? Click here to post it to the Questions page.
Reply to this comment...
Log in to comment
I think that if you post on instructables, we should be sure there are clear ways to contribute, since you might get some good attention from folks, and we'd want there to be some clear entry points into the project.
I think this means:
That way, if you do get interest, people don't just fork and disappear; they have a set of expectations and the code is welcoming. Make sense?
Is this a question? Click here to post it to the Questions page.
Reply to this comment...
Log in to comment
Makes sense :)
I'll go for the main discussion list first, probably with a research note, as pictures don't go well with emails. Then I'll work along your list.
Thanks!
Reply to this comment...
Log in to comment
Hi, cool project!
What's news ?
https://rmeister.github.io/webjack/examples/ - don't sen and not recived.
https://webjack.io/examples/? - not recived? what speed default ?
When I click on the buttons for changing the frequency and speed, there are always the same values. speed 441 - What is it ? boudrate default ?
But boudrate speed very high of default not 441.
I opened the demo pages :https://webjack.io/examples/? on my computer and on my phone and turned on the speakers. I transmit from the phone, receive it on the computer and see that the spectrogram hears a signal on the computer, but nothing is displayed in the window.
Is this a question? Click here to post it to the Questions page.
Reply to this comment...
Log in to comment
Login to comment.