Repository navigation
Communication LoRa
LoRa is a long range, low power radio (433/868/915 MHz) that reaches several kilometers - but with a very small bandwidth of a few kbit/s up to some tens of kbit/s. This is enough for low quality voice or short sound clips, not for music. See Communication for the general considerations.
AudioLoRa (AudioTools/Communication/AudioLoRa.h) uses the arduino-LoRa library (install it) for SX127x based modules (e.g. RFM95, the Heltec and TTGO LoRa boards) and makes it an audio stream: what you write is collected into packets of max_size bytes and sent; received packets can be read.
If process_audio_info is true (the default), begin() first sends a small packet with the AudioInfo (sample rate, channels, bits), so that the receiver learns the audio format.
Field (AudioLoRaConfig) |
Default | Description |
|---|---|---|
frequency |
868E6 | the frequency band permitted in your region: 433E6, 868E6 (Europe) or 915E6 (America) |
spreading_factor |
6 | 6..12: higher = more range, but much slower |
signal_bandwidth |
500E3 | higher = faster, but less range |
tx_power |
20 | transmit power in dB |
sync_word |
0xF3 | only devices with the same sync word talk to each other |
max_size |
200 | the bytes in one packet |
pin_ss, pin_rst, pin_dio0
|
board specific | the pins of the LoRa module |
spi_speed |
the SPI speed | |
process_audio_info |
true | send/receive the AudioInfo header |
The defaults are already set for the highest possible speed.
From the lora examples. The sender:
#include "AudioTools.h"
#include "AudioTools/Communication/AudioLoRa.h"
AudioInfo info(8000, 1, 16);
SineGenerator<int16_t> sineWave(32000);
GeneratedSoundStream<int16_t> sound(sineWave);
AudioLoRa lora;
StreamCopy copier(lora, sound);
void setup() {
SPI.begin(SCK, MISO, MOSI, SS);
auto cfg = lora.defaultConfig();
cfg.copyFrom(info);
if (!lora.begin(cfg)) stop();
sineWave.begin(info, N_B4);
}
void loop() { copier.copy(); }The receiver (the example measures the throughput with a MeasuringStream - replace it with your output):
AudioLoRa lora;
MeasuringStream out;
StreamCopy copier(out, lora);
void setup() {
auto cfg = lora.defaultConfig();
lora.begin(cfg);
out.begin();
}
void loop() { copier.copy(); }-
Bandwidth: 8000 Hz 16 bit mono PCM needs 128 kbit/s - far more than LoRa can transmit. Measure what you get and reduce the data: 8 bit (
EncoderL8), a low sample rate and a speech codec (e.g. Codec2 at 0.7 - 3.2 kbit/s or GSM). Without such a codec, record the audio first and send it as a file instead of streaming it. - Duty cycle: in many regions (e.g. 868 MHz in Europe) a device may only transmit for 1% of the time - continuous streaming is not allowed.
-
Startup order: the AudioInfo header is sent only once in
begin(). Start the receiver first, or setprocess_audio_info = falseand configure the same format on both sides. - Lost packets are not repeated: use a codec that can resync (or a container, see Serial).
-
RadioHeadStream (
AudioTools/Communication/RadioHeadStream.h) is an alternative based on the RadioHead drivers (e.g.RH_RF95), so other LoRa and radio modules can be used too:RadioHeadStream radio(driver, TX_MODE);sends the written data in messages of the driver's maximum message length (callflush()to send the rest), and inRX_MODEthe received messages can be read like any other stream. It does not send an AudioInfo header, and there is no example yet.