Simple transmitter application for SX127x radio.

Dependencies:   MbedJSONValue SX127x sx12xx_hal

Committer:
corymast
Date:
Tue Sep 24 21:10:25 2019 +0000
Revision:
5:a8b4e0857e8b
Parent:
4:b2fc780be0b3
Child:
6:83bedc32acaf
Added support for reading analog light sensor input on pin A1.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
LoRaToolbox 0:44fb2db84011 1 #include "radio.h"
corymast 3:5e25ec621190 2 #include "mbed.h"
corymast 3:5e25ec621190 3 #include "platform/CircularBuffer.h"
corymast 3:5e25ec621190 4 #include "MbedJSONValue/MbedJSONValue.h"
LoRaToolbox 0:44fb2db84011 5
LoRaToolbox 1:b277f5a65c1c 6 // Semtech radio definitions for SX127x, SX126x and SX128x
LoRaToolbox 1:b277f5a65c1c 7
LoRaToolbox 0:44fb2db84011 8 #if defined(SX127x_H)
LoRaToolbox 0:44fb2db84011 9 #define BW_KHZ 500
LoRaToolbox 0:44fb2db84011 10 #define SPREADING_FACTOR 11
LoRaToolbox 0:44fb2db84011 11 #define CF_HZ 912000000
LoRaToolbox 0:44fb2db84011 12 #define TX_DBM 20
LoRaToolbox 0:44fb2db84011 13 #elif defined(SX126x_H)
LoRaToolbox 0:44fb2db84011 14 #define BW_KHZ 500
LoRaToolbox 0:44fb2db84011 15 #define SPREADING_FACTOR 10
LoRaToolbox 0:44fb2db84011 16 #define CF_HZ 915000000
LoRaToolbox 0:44fb2db84011 17 #define TX_DBM (Radio::chipType == CHIP_TYPE_SX1262 ? 20 : 14)
LoRaToolbox 0:44fb2db84011 18 #elif defined(SX128x_H)
LoRaToolbox 0:44fb2db84011 19 #define BW_KHZ 200
LoRaToolbox 0:44fb2db84011 20 #define SPREADING_FACTOR 7
LoRaToolbox 0:44fb2db84011 21 #define CF_HZ 2487000000
LoRaToolbox 0:44fb2db84011 22 #define TX_DBM 6
LoRaToolbox 0:44fb2db84011 23 #endif
LoRaToolbox 0:44fb2db84011 24
corymast 3:5e25ec621190 25 // The buffer size should match the tx_buf length in sx12xx.h
corymast 3:5e25ec621190 26 #define BUF_SIZE 256
corymast 3:5e25ec621190 27
LoRaToolbox 1:b277f5a65c1c 28 /******************** Setup radio transmitter ****************************/
LoRaToolbox 1:b277f5a65c1c 29
corymast 5:a8b4e0857e8b 30 // Configure A1 as Analog Input
corymast 5:a8b4e0857e8b 31 AnalogIn sensor(A1);
corymast 5:a8b4e0857e8b 32 float light_val;
corymast 5:a8b4e0857e8b 33
corymast 4:b2fc780be0b3 34 // Configure the User button as an interrupt
corymast 4:b2fc780be0b3 35 InterruptIn button(USER_BUTTON, PullUp);
corymast 4:b2fc780be0b3 36
corymast 4:b2fc780be0b3 37 // Initialize global variables
corymast 4:b2fc780be0b3 38 uint8_t seq = 0; // Set initial transmit sequence to 0
LoRaToolbox 0:44fb2db84011 39 volatile bool txDone;
corymast 3:5e25ec621190 40 CircularBuffer<uint8_t, BUF_SIZE> msg;
corymast 4:b2fc780be0b3 41 MbedJSONValue message;
corymast 4:b2fc780be0b3 42 Timer t;
LoRaToolbox 0:44fb2db84011 43
corymast 4:b2fc780be0b3 44 // Transmit Done Callback Handler
LoRaToolbox 0:44fb2db84011 45 void txDoneCB()
LoRaToolbox 0:44fb2db84011 46 {
LoRaToolbox 0:44fb2db84011 47 txDone = true;
corymast 4:b2fc780be0b3 48 printf("Tx Done.\r\n");
LoRaToolbox 0:44fb2db84011 49 }
LoRaToolbox 0:44fb2db84011 50
corymast 4:b2fc780be0b3 51 // Receive Done Callback Handler
LoRaToolbox 0:44fb2db84011 52 void rxDoneCB(uint8_t size, float rssi, float snr)
LoRaToolbox 0:44fb2db84011 53 {
corymast 4:b2fc780be0b3 54 printf("Rx Done.\r\n");
LoRaToolbox 0:44fb2db84011 55 }
LoRaToolbox 0:44fb2db84011 56
corymast 4:b2fc780be0b3 57 // Transmit Timeout Callback Handler
corymast 4:b2fc780be0b3 58 void txTimeoutCB()
corymast 4:b2fc780be0b3 59 {
corymast 4:b2fc780be0b3 60 printf("Tx Timeout.\r\n");
corymast 4:b2fc780be0b3 61 }
LoRaToolbox 1:b277f5a65c1c 62
corymast 4:b2fc780be0b3 63 // Define radio events for transmitter
LoRaToolbox 0:44fb2db84011 64 const RadioEvents_t rev = {
LoRaToolbox 0:44fb2db84011 65 /* Dio0_top_half */ NULL,
LoRaToolbox 0:44fb2db84011 66 /* TxDone_topHalf */ NULL,
LoRaToolbox 0:44fb2db84011 67 /* TxDone_botHalf */ txDoneCB,
corymast 4:b2fc780be0b3 68 /* TxTimeout */ txTimeoutCB,
LoRaToolbox 0:44fb2db84011 69 /* RxDone */ rxDoneCB,
LoRaToolbox 0:44fb2db84011 70 /* RxTimeout */ NULL,
LoRaToolbox 0:44fb2db84011 71 /* RxError */ NULL,
LoRaToolbox 0:44fb2db84011 72 /* FhssChangeChannel */NULL,
LoRaToolbox 0:44fb2db84011 73 /* CadDone */ NULL
LoRaToolbox 0:44fb2db84011 74 };
LoRaToolbox 0:44fb2db84011 75
corymast 4:b2fc780be0b3 76 /**
corymast 4:b2fc780be0b3 77 * Function for printing the contents of the SX127x transmit buffer
corymast 4:b2fc780be0b3 78 */
corymast 3:5e25ec621190 79 void print_radio_tx_buffer(uint8_t len)
corymast 3:5e25ec621190 80 {
corymast 3:5e25ec621190 81 printf("Tx Buffer = ");
corymast 3:5e25ec621190 82 for(int i=0; i<len; i++)
corymast 3:5e25ec621190 83 {
corymast 3:5e25ec621190 84 printf("%d ", Radio::radio.tx_buf[i]);
corymast 3:5e25ec621190 85 }
corymast 3:5e25ec621190 86 printf("\r\n\n");
corymast 3:5e25ec621190 87 }
corymast 3:5e25ec621190 88
corymast 4:b2fc780be0b3 89 /**
corymast 4:b2fc780be0b3 90 * Function for adding bytes to the circular buffer for the message.
corymast 4:b2fc780be0b3 91 */
corymast 3:5e25ec621190 92 void msg_append_bytes(uint8_t data[], uint8_t len)
corymast 3:5e25ec621190 93 {
corymast 3:5e25ec621190 94 for(int i=0; i < len; i++)
corymast 3:5e25ec621190 95 {
corymast 3:5e25ec621190 96 if(!msg.full())
corymast 3:5e25ec621190 97 {
corymast 3:5e25ec621190 98 msg.push(data[i]);
corymast 3:5e25ec621190 99 }
corymast 3:5e25ec621190 100 else{
corymast 3:5e25ec621190 101 // If buffer is full, contents will be over-written
corymast 3:5e25ec621190 102 // TODO: Handle this error case
corymast 3:5e25ec621190 103 printf("buffer is full\n");
corymast 3:5e25ec621190 104 }
corymast 3:5e25ec621190 105 }
corymast 3:5e25ec621190 106 }
corymast 3:5e25ec621190 107
corymast 4:b2fc780be0b3 108 /**
corymast 4:b2fc780be0b3 109 * Function for adding a string to the circular buffer for the message
corymast 4:b2fc780be0b3 110 */
corymast 3:5e25ec621190 111 void msg_append_string(string str, uint8_t len)
LoRaToolbox 0:44fb2db84011 112 {
corymast 3:5e25ec621190 113 msg_append_bytes(reinterpret_cast<uint8_t*>(&str[0]), len);
corymast 3:5e25ec621190 114 }
corymast 3:5e25ec621190 115
corymast 4:b2fc780be0b3 116 /**
corymast 4:b2fc780be0b3 117 * Function for sending the message.
corymast 4:b2fc780be0b3 118 *
corymast 4:b2fc780be0b3 119 * @note This function copies the contents of the circular buffer to the transmit
corymast 4:b2fc780be0b3 120 * buffer.
corymast 4:b2fc780be0b3 121 */
corymast 3:5e25ec621190 122 void msg_send()
corymast 3:5e25ec621190 123 {
corymast 3:5e25ec621190 124 uint8_t len = 0;
corymast 3:5e25ec621190 125 while(!msg.empty())
corymast 3:5e25ec621190 126 {
corymast 3:5e25ec621190 127 // Pop data from the circular buffer to Radio tx_buf
corymast 3:5e25ec621190 128 msg.pop(Radio::radio.tx_buf[len]);
corymast 3:5e25ec621190 129
corymast 3:5e25ec621190 130 // Track the size of the tx_buf
corymast 3:5e25ec621190 131 len++;
corymast 3:5e25ec621190 132 }
corymast 3:5e25ec621190 133 print_radio_tx_buffer(len);
corymast 3:5e25ec621190 134 txDone = false;
corymast 3:5e25ec621190 135 Radio::Send(len, 0, 0, 0); // begin transmission of payload
corymast 4:b2fc780be0b3 136 }
corymast 3:5e25ec621190 137
corymast 4:b2fc780be0b3 138 /**
corymast 4:b2fc780be0b3 139 * Interrupt handler for the User button.
corymast 4:b2fc780be0b3 140 */
corymast 4:b2fc780be0b3 141 void button_send()
corymast 4:b2fc780be0b3 142 {
corymast 4:b2fc780be0b3 143 // Create an array to hold byte data
corymast 4:b2fc780be0b3 144 uint8_t data[] = {seq};
corymast 4:b2fc780be0b3 145
corymast 4:b2fc780be0b3 146 // Append the byte array to the message
corymast 4:b2fc780be0b3 147 msg_append_bytes(data, sizeof(data)/sizeof(data[0]));
corymast 4:b2fc780be0b3 148
corymast 4:b2fc780be0b3 149 // Append a new value to the message
corymast 4:b2fc780be0b3 150 data[0] = seq+1;
corymast 4:b2fc780be0b3 151 msg_append_bytes(data, sizeof(data)/sizeof(data[0]));
corymast 4:b2fc780be0b3 152
corymast 4:b2fc780be0b3 153 // Append a string to the message
corymast 4:b2fc780be0b3 154 string myString = "Hello World!";
corymast 4:b2fc780be0b3 155 msg_append_string(myString, myString.length());
corymast 4:b2fc780be0b3 156 msg_send();
corymast 4:b2fc780be0b3 157
corymast 4:b2fc780be0b3 158 seq+=2; // change payload (increment sequence number)
corymast 3:5e25ec621190 159 }
corymast 3:5e25ec621190 160
corymast 4:b2fc780be0b3 161 /**
corymast 4:b2fc780be0b3 162 * Interrupt Handler for the User button.
corymast 4:b2fc780be0b3 163 */
corymast 4:b2fc780be0b3 164 void button_send_json()
corymast 4:b2fc780be0b3 165 {
corymast 4:b2fc780be0b3 166 string s;
corymast 4:b2fc780be0b3 167 seq++;
corymast 4:b2fc780be0b3 168
corymast 4:b2fc780be0b3 169 //fill the object
corymast 4:b2fc780be0b3 170 message["btn_count"] = seq;
corymast 4:b2fc780be0b3 171 message["btn_timer"] = t.read();
corymast 5:a8b4e0857e8b 172 message["light_val"] = light_val;
corymast 4:b2fc780be0b3 173 message["my_str"] = "Hello World!";
corymast 4:b2fc780be0b3 174 message["my_boolean"] = false;
corymast 4:b2fc780be0b3 175
corymast 4:b2fc780be0b3 176 //serialize it into a JSON string
corymast 4:b2fc780be0b3 177 s = message.serialize();
corymast 4:b2fc780be0b3 178 printf("json: %s\r\n", s.c_str());
corymast 4:b2fc780be0b3 179
corymast 4:b2fc780be0b3 180 memcpy(Radio::radio.tx_buf, s.c_str(), s.length());
corymast 4:b2fc780be0b3 181 txDone = false;
corymast 4:b2fc780be0b3 182 Radio::Send(s.length(), 0, 0, 0); // begin transmission of payload
corymast 4:b2fc780be0b3 183 t.reset();
corymast 4:b2fc780be0b3 184 }
corymast 4:b2fc780be0b3 185
corymast 4:b2fc780be0b3 186 /**
corymast 4:b2fc780be0b3 187 * Function for initializing the SX127x radio.
corymast 4:b2fc780be0b3 188 */
corymast 3:5e25ec621190 189 void radio_init()
corymast 3:5e25ec621190 190 {
LoRaToolbox 1:b277f5a65c1c 191 // Start radio transmitter after POR or reset
LoRaToolbox 0:44fb2db84011 192 Radio::Init(&rev);
LoRaToolbox 0:44fb2db84011 193
LoRaToolbox 1:b277f5a65c1c 194 //Set radio properties for transmitter
LoRaToolbox 0:44fb2db84011 195 Radio::Standby();
LoRaToolbox 0:44fb2db84011 196 Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1);
LoRaToolbox 0:44fb2db84011 197 Radio::SetChannel(CF_HZ);
LoRaToolbox 0:44fb2db84011 198
LoRaToolbox 1:b277f5a65c1c 199 // Set transmitter output power
LoRaToolbox 0:44fb2db84011 200 Radio::set_tx_dbm(TX_DBM);
LoRaToolbox 0:44fb2db84011 201
LoRaToolbox 1:b277f5a65c1c 202 // Setup transmit packet payload -> preambleLen, fixLen, crcOn, invIQ
LoRaToolbox 0:44fb2db84011 203 Radio::LoRaPacketConfig(8, false, true, false);
corymast 3:5e25ec621190 204 }
corymast 3:5e25ec621190 205
corymast 3:5e25ec621190 206 int main()
corymast 3:5e25ec621190 207 {
corymast 3:5e25ec621190 208 printf("\r\nreset-tx \n");
corymast 4:b2fc780be0b3 209 // button.fall(&button_send);
corymast 4:b2fc780be0b3 210 button.fall(&button_send_json);
LoRaToolbox 0:44fb2db84011 211
corymast 3:5e25ec621190 212 radio_init();
LoRaToolbox 0:44fb2db84011 213
corymast 4:b2fc780be0b3 214 // Start a timer to track time between button presses
corymast 4:b2fc780be0b3 215 t.start();
LoRaToolbox 0:44fb2db84011 216
corymast 4:b2fc780be0b3 217 for (;;)
corymast 4:b2fc780be0b3 218 {
corymast 4:b2fc780be0b3 219 // Transmit message on button press, service radio until tx complete.
corymast 4:b2fc780be0b3 220 while (!txDone)
corymast 4:b2fc780be0b3 221 {
corymast 4:b2fc780be0b3 222 Radio::service();
corymast 5:a8b4e0857e8b 223 light_val = sensor.read();
LoRaToolbox 1:b277f5a65c1c 224 }
corymast 4:b2fc780be0b3 225 }
LoRaToolbox 0:44fb2db84011 226 }