-
Android Walkie-Talkies
07/01/2022 at 01:58 • 0 commentsA few months ago, I discovered a plethora of Android phones that are designed to work as walkie-talikies (HT's): they have a loud speaker (1W-2W output), a good omnidirectional microphone, a separate, special Push-To-Talk (PTT) button. They also have a port where you can connect a headset, speaker, mic, etc., like a regular HT.
These devices market themselves for use with Zello. Some of them are dirt cheap, and have pretty low-end features, but there are some higher-end ones with larger screens, faster processors, more RAM/storage, etc. Seeing this as a possible good voice "front end" for QMesh, I purchased one of the low-midrange ones, the Uniwa B8000 (https://www.aliexpress.com/item/3256802817133484.html?spm=a2g0o.order_list.0.0.14cc1802tUsWqY).
It arrived at my house this week, and I decided to check it out. While the specs are fairly low-end (four 1.5GHz ARM Cortex-A53's, 1GB RAM, 8GB storage), it was more than enough to run the Codec2 Walkie Talkie app. The screen is good enough for the intended use, and the physical buttons seemed to work well.
Overall, this should work out well for running Codec2 Walkie Talkie and interfacing with a QMesh node over Wi-Fi or Bluetooth. -
Inverting Bits to Avoid Interference
08/03/2021 at 12:34 • 0 commentsIdea
One (experimental) parameter I'm exploring for COMA (Chirp Offset Multiple Access) is to invert the data bits on some transmissions as a way to help keep keep LoRa chirps from overlapping and interfering with each other. The idea here is that LoRa is a chirped version of an m-ary FSK. Basically, it appears that the "breaks" in the chirps correspond to a tone in this m-ary FSK. Moving around the "breaks" in the chirps should thus move around the chips somewhat in space-time.
Implementation
There's no direct way for the receiver to know whether the bits have been inverted. Instead, the receiver attempts to decode both the inverted and non-inverted versions of the received packet. The correct one is then determined using the CRC. One issue I did encounter was that the Reed-Solomon decoder would fail on the "bad" packet, and produce a packet with all zeros. The CRC-8 algorithm used would treat this as correct, as the CRC algorithm would deliver a 0x00 value for an all-zeros packet. Since the CRC extracted from this all-zeros packet was 0x00, the CRC check would cause the packet to appear correct. Changing to the CRC-8 parameters to the ones used by CDMA2000 fixed this issue.
Testing
Of course, to really know whether this helps to mitigate interference will require some thorough testing with multiple nodes, which will...take some time.
-
Walsh-Hadamard Codes
08/03/2021 at 12:21 • 0 commentsUp to this point, the various parameters that make up the COMA anti-interference mechanism were chosen randomly at every packet. To prevent overlap, the Mersenne Twister-based pseudo-random number generator was seeded with the address of the node. While this did a good job keeping nodes from interfering from each other, it's probabilistically possible that interfering/overlapping COMA parameters are selected.
I started experimenting with instead choosing these parameters using Walsh-Hadamard Codes instead. These codes are used in many CDMA systems to find orthogonal pseudo-noise (PN) codes for the different users. Doing some very crude experimenting, it looks like they have a lot of potential as a way to choose the different anti-interference factors that QMesh uses (frequency offset, timing offset, channel, and inverted bits).
It does seem to do a pretty good job of selecting parameters that are fairly far apart from each other:
Node Frequency
OffsetChannel Timing
OffsetInvert
Bits0 -88316 0 0 No 1 87137 1 5 No 2 67957 0 3 Yes 3 -35199 1 6 Yes 4 35471 0 7 No 5 87932 1 2 No 6 89777 0 4 Yes 7 -11096 1 1 Yes -
ESP32 Serial-to-Wifi Bridge Complete
06/25/2021 at 18:40 • 0 commentsTo make administration (monitoring, firmware updates, etc.) easier for outdoor nodes in possibly-inaccessible locations, I decided to develop a "Wireless UART bridge" out of an ESP32. The basic idea is that the ESP32 connects to my home network over Wi-Fi and provides a socket server I can connect to.
It was fairly straightforward to do, and it looks like it works well. The source code for it (I did it in the Arduino IDE) is at https://github.com/faydr/QMesh-ESP32
In addition to making remote administration possible, the QMesh "serial client" seems to work a lot better communicating with the board over network sockets than it does over pyserial.
-
UART-Based "Remote" Firmware Update Completed
06/20/2021 at 05:35 • 0 commentsThe ability to update a QMesh device's firmware over a UART, which will enable remote firmware update, is complete. I can now update the QMesh firmware over a UART, including both a "wired" USB-to-UART adapter as well as over an HC-05 Bluetooth-to-UART module. Next, I'm working on setting up an ESP32 board to provide a Wi-Fi-to-UART bridge that will allow me to communicate with QMesh boards via a sockets interface.
Some things I learned along the way:
- Using gzip to compress firmware updates is fairly straightforward to do, so long as you have a POSIX-y stuff available like malloc() and various file operators. If you have all of this, working on a gzip'ed file isn't much different from working on a regular file. Do note, however, that zlib uses a significant amount of both RAM and ROM. As a result, I only have zlib built into the bootloader.
- Mbed OS makes it fairly easy to implement a bootloader. Since I decided to make a bootloader that was just the QMesh app with some functionality removed, it was fairly large, totaling 150-200KB. I have plenty of program flash, so this isn't a big deal, but it might be if I try to fit everything inside of a smaller device.
- You can use the watchdog timer to implement a fallback capability for a botched firmware update. Basically, set the watchdog timer to some relatively short time period that's long enough to allow the main firmware to boot up and disable or pet the watchdog. If the firmware update is botched and it doesn't boot, the watchdog timer will reboot the board back into the bootloader, where a golden firmware image can be loaded instead.
- Static analyzers are interesting and fairly useful. The easiest one to do is to just enable clang-tidy in Mbed Studio. It definitely forced me to clean up my C++ code. I also set up codechecker (which runs clang-tidy and the Clang Static Analyzer) as well as Facebook Infer. While these are more cumbersome to use, Facebook Infer did some deeper analysis of my code and managed to find some code where I wasn't closing files that I had already opened.
Hopefully, once I get the remote firmware stuff done, I'll have multiple solar-powered QMesh nodes that I can access and manage over Wi-Fi. This will make testing and improving the protocol much easier!
-
Protobufs Done, KISS Support Added
05/22/2021 at 03:56 • 0 commentsFinished implementing protobufs as the serialization protocol to be used throughout the system, including over the serial port and in the log and configuration files on the NOR flash.
In the process of implementing protobufs, I realized that I also needed a framing format to "wrap" the protobufs in. I originally considered SLIP's framing, and then realized that the KISS protocol was an easier-to-parse superset of SLIP, with the bonus of being directly supported by many amateur radio applications.
As a result, my journey through protobufs has made QMesh a KISS-compatible TNC. This means that, using e.g. an HC-05 (HC-05 info/usage) UART-to-Bluetooth bridge, APRSDroid now works with QMesh. Codec2 Walkie Talkie (Github repo here) should also work with it, but I've been focusing on performance tweaks/enhancements to QMesh before giving it a try. Note that I also added in the ability to fragment KISS frames across multiple QMesh frames if the KISS frames are larger than a single QMesh frame.
After burning up an STM32 board and an HC-05 board trying to update an outdoor QMesh node, I've been working on developing a wireless, ESP32-based remote administration of the outdoor nodes. Basically, the ESP32 would connect to my Wi-Fi network, and allow me a network-based method to access the UART for testing and remotely updating the firmware (I'm also working on a bootloader to update the "main" firmware).
-
Moving to protobufs
12/27/2020 at 17:40 • 0 commentsI'm currently replacing the JSON-based serial communications setup with Google Protobufs. So far, it seems to be a win: simpler coding, more compact representation, and pretty easy to use.
-
Frequency Hopping Added
12/01/2020 at 03:52 • 0 commentsI decided to play around with the CAD feature on the SX126X a bit, and developed a simple scanning-based frequency hopping scheme. As a result, QMesh can now do a hybrid spread-spectrum scheme (CSS+FHSS).
Some things I learned along the way:
1. The CAD has a lot of false positives. Doing a "double CAD" helps reduce this issue. Basically, do a CAD, and if it comes back positive, do a CAD+Rx for the final receive.
2. The CAD starts the oscillator "fresh". This means that, with a TCXO, the CAD will not start until the programmed TCXO stabilization delay completes. I may consider cutting the stabilization time for CADs, as a bunch of correlators just trying to detect some chirps probably doesn't need the TCXO's full accuracy.
-
TAPR DCC Submission and New Results
08/16/2020 at 14:35 • 0 commentsJust submitted a paper about QMesh to TAPR DCC (https://tapr.org/).
As part of this paper, I tested the packet receive rate (PRR) when two and three nodes are retransmitting. When I use Reed-Solomon-Viterbi (RSV) forward error correction, I'm seeing 99% PRR's. I believe that these results are real, since when I turn off FEC, I instead get 93% (for two retransmitting nodes) and 90% (for three retransmitting nodes). Moreover, this setup is a worst-case scenario where the antennas are right next to each other and are separated by a quarter wavelength. Real-world situations should be less challenging than this, so this is a very good sign.
At this point, *knocks on wood* the underlying protocol is sufficiently reliable that it's ready to handle streaming voice.
-
Testing Results
03/06/2020 at 03:25 • 0 commentsIt looks like the basic principle of QMesh -- that a synchronized, flooded mesh network can achieve a decently-high packet receive rate via the capture effect -- is valid.
If I place two relay nodes right next to each other, I can get a packet receive rate (PRR) of around 80-100% when the received signals are strong. For marginal signal strengths, the collisions seem to effectively raise the noise floor.