Skip to content

Latest commit

 

History

History
87 lines (61 loc) · 5.14 KB

README.md

File metadata and controls

87 lines (61 loc) · 5.14 KB

Horus Binary 4FSK Transmit Example, using RadioLib

This repository contains a worked example of generating and transmitting Horus Binary v1 and v2 high-altitude balloon telemetry packets on an Arduino-compatible platform, using RadioLib.

This is not a complete high-altitude-balloon tracker codebase, just an example of generating and transmitting Horus Binary packets, for integration into other codebases.

This example uses a Semtech SX1278-compatible radio module (in my case, a HopeRF RFM98W), connected to an Arduino-compatible microcontroller (I used a Seeduino Mega 2560 because it would do 3.3v logic levels). In my case, the module has the usual SPI connections, and the following other pins are used:

  • NSS pin: 10
  • DIO0 pin: 2
  • RESET pin: 9
  • DIO1 pin: 3

Contacts

Dependencies

Compiling this Example

It should be possible to just open the horusbinary_radiolib.ino file in the Arduino IDE, select your target platform, and compile/flash.

Note that I am using some AVR-specific CRC16 libraries (util/crc16.h), which will probably need to be replaced for use on other platforms (refer util.ino).

Horus Binary Generation & Transmission Overview

Packet Structure

The Horus Binary packet formats are represented in this codebase as structs located here (v1) and here (v2). The last 9 bytes (before the CRC16 checksum) of the v2 packet format are customisable by the user (refer here for more info).

Generating a Packet

The two functions build_horus_binary_packet_v1 and build_horus_binary_packet_v2 instantiate a struct, and write data into it. The struct bytes are then written out to a buffer (in this example, rawbuffer) supplied as a function argument, and the function returns the length of the packet in bytes.

int pkt_len = build_horus_binary_packet_v1(rawbuffer);

These functions are the main bit of code that you would need to modify to insert telemetry data from wherever you are obtaining it (GPS libraries, sensors, etc).

Encoding the Packet

Next, we need to apply the Golay(23,12) forward-error-correction, interleaving and scrambling which protect the telemetry data. This is performed using the horus_l2_encode_packet function, which is located in horus_l2.cpp. This function takes a pointer to a destination and source buffer, and the packet length:

int coded_len = horus_l2_encode_tx_packet((unsigned char*)codedbuffer,(unsigned char*)rawbuffer,pkt_len);

At this stage we now have the encoded packet in codedbuffer, and the length of the encoded packet in coded_len.

Transmitting the Packet

In this example codebase, we are using RadioLib to provide a nice abstracted interface to a range of radio transmitter modules. In my case I'm using a SX127x-compatible module, which is started as follows:

// SX1278 has the following connections:
// NSS pin:   10
// DIO0 pin:  2
// RESET pin: 9
// DIO1 pin:  3
SX1278 radio = new Module(10, 2, 9, 3);

The radio has to be initialised in FSK mode:

int state = radio.beginFSK();

Next, I have provided some functions in FSK4_Mod.ino which will make use of the radio modules 'transmitDirect' functionality to transmit the 4FSK modulation. We have to initialise these functions using the fsk4_setup function:

state = fsk4_setup(&radio, TX_FREQ, FSK4_SPACING, FSK4_BAUD);

TX_FREQ is the frequency of the lowest 4FSK tone in MHz, FSK4_BAUD is the desired baud rate (recommended to be 100 baud, though 50 and 300 baud are supported in the decoders), and FSK4_SPACING is the spacing between the tones in Hz (should be >=2x the baud rate).

Note that the acheived tone spacing depends on the frequency resolution of the radio module. In the case of the SX127x the resolution is 61 Hz, so while I specify a 270 Hz tone spacing, we end up with an acheived tone spacing of 244 Hz.

Once we have our encoded packet, we can transmit as follows:

fsk4_idle(&radio);
delay(1000);
fsk4_preamble(&radio, 8);
fsk4_write(&radio, codedbuffer, coded_len);

fsk4_idle turns the transmitter on, and configures it to transmit a carrier on the lowest 4FSK tone. fsk4_preamble sends a repeated sequence of incrementing 4FSK tones, allowing the decoder to lock-on to the signal. Finally, fsk4_write transmits the encoded payload, and turns the transmitter off once done.

TODO List

  • Split out Horus-specific code into separate files, for easier integration into other codebases.