Simple transmitter application for SX127x radio.

Dependencies:   MbedJSONValue SX127x sx12xx_hal

Committer:
corymast
Date:
Wed Oct 16 22:37:57 2019 +0000
Revision:
9:b6e3ffbfeabd
Parent:
8:738ab96d41da
Added scaling for ADC to read between 0 and 100%.

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 "MbedJSONValue/MbedJSONValue.h"
LoRaToolbox 0:44fb2db84011 4
LoRaToolbox 1:b277f5a65c1c 5 // Semtech radio definitions for SX127x, SX126x and SX128x
LoRaToolbox 1:b277f5a65c1c 6
LoRaToolbox 0:44fb2db84011 7 #if defined(SX127x_H)
LoRaToolbox 0:44fb2db84011 8 #define BW_KHZ 500
LoRaToolbox 0:44fb2db84011 9 #define SPREADING_FACTOR 11
LoRaToolbox 0:44fb2db84011 10 #define CF_HZ 912000000
LoRaToolbox 0:44fb2db84011 11 #define TX_DBM 20
LoRaToolbox 0:44fb2db84011 12 #elif defined(SX126x_H)
LoRaToolbox 0:44fb2db84011 13 #define BW_KHZ 500
LoRaToolbox 0:44fb2db84011 14 #define SPREADING_FACTOR 10
LoRaToolbox 0:44fb2db84011 15 #define CF_HZ 915000000
LoRaToolbox 0:44fb2db84011 16 #define TX_DBM (Radio::chipType == CHIP_TYPE_SX1262 ? 20 : 14)
LoRaToolbox 0:44fb2db84011 17 #elif defined(SX128x_H)
LoRaToolbox 0:44fb2db84011 18 #define BW_KHZ 200
LoRaToolbox 0:44fb2db84011 19 #define SPREADING_FACTOR 7
LoRaToolbox 0:44fb2db84011 20 #define CF_HZ 2487000000
LoRaToolbox 0:44fb2db84011 21 #define TX_DBM 6
LoRaToolbox 0:44fb2db84011 22 #endif
LoRaToolbox 0:44fb2db84011 23
corymast 3:5e25ec621190 24 // The buffer size should match the tx_buf length in sx12xx.h
corymast 3:5e25ec621190 25 #define BUF_SIZE 256
corymast 3:5e25ec621190 26
corymast 8:738ab96d41da 27 // The interval between automatic transmissions in seconds.
corymast 8:738ab96d41da 28 #define AUTO_TX_INTERVAL 2.0
corymast 8:738ab96d41da 29
LoRaToolbox 1:b277f5a65c1c 30 /******************** Setup radio transmitter ****************************/
LoRaToolbox 1:b277f5a65c1c 31
corymast 7:803a185d7021 32 // Analog Sensor setup
corymast 7:803a185d7021 33 AnalogIn sensor_light(A1);
corymast 7:803a185d7021 34 AnalogIn sensor_temp(A3);
corymast 7:803a185d7021 35 double light_val_analog;
corymast 7:803a185d7021 36 double temperature_analog;
corymast 5:a8b4e0857e8b 37
corymast 4:b2fc780be0b3 38 // Configure the User button as an interrupt
corymast 4:b2fc780be0b3 39 InterruptIn button(USER_BUTTON, PullUp);
corymast 4:b2fc780be0b3 40
corymast 4:b2fc780be0b3 41 // Initialize global variables
corymast 4:b2fc780be0b3 42 uint8_t seq = 0; // Set initial transmit sequence to 0
LoRaToolbox 0:44fb2db84011 43 volatile bool txDone;
corymast 4:b2fc780be0b3 44 MbedJSONValue message;
corymast 8:738ab96d41da 45 Timer timer_button;
corymast 8:738ab96d41da 46 Ticker ticker_tx;
LoRaToolbox 0:44fb2db84011 47
corymast 7:803a185d7021 48 // Forward declaration
corymast 7:803a185d7021 49 float convert_analog_light_resistance(double analog_val);
corymast 7:803a185d7021 50 float convert_analog_temperature(double analog_val);
corymast 8:738ab96d41da 51 void txDoneCB(void);
corymast 8:738ab96d41da 52 void rxDoneCB(uint8_t size, float rssi, float snr);
corymast 8:738ab96d41da 53 void txTimeoutCB(void);
LoRaToolbox 1:b277f5a65c1c 54
corymast 4:b2fc780be0b3 55 // Define radio events for transmitter
LoRaToolbox 0:44fb2db84011 56 const RadioEvents_t rev = {
LoRaToolbox 0:44fb2db84011 57 /* Dio0_top_half */ NULL,
LoRaToolbox 0:44fb2db84011 58 /* TxDone_topHalf */ NULL,
LoRaToolbox 0:44fb2db84011 59 /* TxDone_botHalf */ txDoneCB,
corymast 4:b2fc780be0b3 60 /* TxTimeout */ txTimeoutCB,
LoRaToolbox 0:44fb2db84011 61 /* RxDone */ rxDoneCB,
LoRaToolbox 0:44fb2db84011 62 /* RxTimeout */ NULL,
LoRaToolbox 0:44fb2db84011 63 /* RxError */ NULL,
LoRaToolbox 0:44fb2db84011 64 /* FhssChangeChannel */NULL,
LoRaToolbox 0:44fb2db84011 65 /* CadDone */ NULL
LoRaToolbox 0:44fb2db84011 66 };
LoRaToolbox 0:44fb2db84011 67
corymast 4:b2fc780be0b3 68 /**
corymast 8:738ab96d41da 69 * Transmit Done Callback Handler
corymast 8:738ab96d41da 70 */
corymast 8:738ab96d41da 71 void txDoneCB()
corymast 8:738ab96d41da 72 {
corymast 8:738ab96d41da 73 txDone = true;
corymast 8:738ab96d41da 74 printf("Tx Done.\r\n");
corymast 8:738ab96d41da 75 }
corymast 8:738ab96d41da 76
corymast 8:738ab96d41da 77 /**
corymast 8:738ab96d41da 78 * Receive Done Callback Handler
corymast 4:b2fc780be0b3 79 */
corymast 8:738ab96d41da 80 void rxDoneCB(uint8_t size, float rssi, float snr)
corymast 8:738ab96d41da 81 {
corymast 8:738ab96d41da 82 printf("Rx Done.\r\n");
corymast 8:738ab96d41da 83 }
corymast 8:738ab96d41da 84
corymast 8:738ab96d41da 85 /**
corymast 8:738ab96d41da 86 * Transmit Timeout Callback Handler
corymast 8:738ab96d41da 87 */
corymast 8:738ab96d41da 88 void txTimeoutCB()
corymast 8:738ab96d41da 89 {
corymast 8:738ab96d41da 90 printf("Tx Timeout.\r\n");
corymast 8:738ab96d41da 91 }
corymast 8:738ab96d41da 92
corymast 8:738ab96d41da 93 /**
corymast 8:738ab96d41da 94 * Function for building and sending a message.
corymast 8:738ab96d41da 95 */
corymast 8:738ab96d41da 96 void send_json()
corymast 4:b2fc780be0b3 97 {
corymast 4:b2fc780be0b3 98 string s;
corymast 4:b2fc780be0b3 99 seq++;
corymast 4:b2fc780be0b3 100
corymast 8:738ab96d41da 101 /* Fill the message */
corymast 8:738ab96d41da 102 message["btn_count"] = seq; // Total number of button presses since boot.
corymast 8:738ab96d41da 103 message["btn_timer"] = timer_button.read(); // Time since last button press.
corymast 9:b6e3ffbfeabd 104 // Scale ADC value to 0-100%
corymast 9:b6e3ffbfeabd 105 message["light_val"] = light_val_analog * 100; // Analog reading from light sensor
corymast 8:738ab96d41da 106 message["light_resistance"] = convert_analog_light_resistance(light_val_analog); // Light Sensor Resistance (Ohms)
corymast 8:738ab96d41da 107 message["temperature"] = convert_analog_temperature(temperature_analog); // Temperature (F)
corymast 8:738ab96d41da 108 message["my_str"] = "Hello World!"; // Sample String
corymast 8:738ab96d41da 109 message["my_boolean"] = false; // Sample Boolean
corymast 4:b2fc780be0b3 110
corymast 4:b2fc780be0b3 111 //serialize it into a JSON string
corymast 4:b2fc780be0b3 112 s = message.serialize();
corymast 4:b2fc780be0b3 113 printf("json: %s\r\n", s.c_str());
corymast 4:b2fc780be0b3 114
corymast 8:738ab96d41da 115 // Copy the serialized message to the radio's transmit buffer
corymast 4:b2fc780be0b3 116 memcpy(Radio::radio.tx_buf, s.c_str(), s.length());
corymast 8:738ab96d41da 117 // Clear the txDone flag
corymast 4:b2fc780be0b3 118 txDone = false;
corymast 8:738ab96d41da 119 // Begin transmission of payload
corymast 8:738ab96d41da 120 Radio::Send(s.length(), 0, 0, 0);
corymast 8:738ab96d41da 121 }
corymast 8:738ab96d41da 122
corymast 8:738ab96d41da 123 /**
corymast 8:738ab96d41da 124 * Interrupt Handler for the User button.
corymast 8:738ab96d41da 125 */
corymast 8:738ab96d41da 126 void button_send_json()
corymast 8:738ab96d41da 127 {
corymast 8:738ab96d41da 128 // Send the message
corymast 8:738ab96d41da 129 send_json();
corymast 8:738ab96d41da 130
corymast 8:738ab96d41da 131 // Restart the button timer
corymast 8:738ab96d41da 132 timer_button.reset();
corymast 4:b2fc780be0b3 133 }
corymast 4:b2fc780be0b3 134
corymast 4:b2fc780be0b3 135 /**
corymast 4:b2fc780be0b3 136 * Function for initializing the SX127x radio.
corymast 4:b2fc780be0b3 137 */
corymast 3:5e25ec621190 138 void radio_init()
corymast 3:5e25ec621190 139 {
LoRaToolbox 1:b277f5a65c1c 140 // Start radio transmitter after POR or reset
LoRaToolbox 0:44fb2db84011 141 Radio::Init(&rev);
LoRaToolbox 0:44fb2db84011 142
LoRaToolbox 1:b277f5a65c1c 143 //Set radio properties for transmitter
LoRaToolbox 0:44fb2db84011 144 Radio::Standby();
LoRaToolbox 0:44fb2db84011 145 Radio::LoRaModemConfig(BW_KHZ, SPREADING_FACTOR, 1);
LoRaToolbox 0:44fb2db84011 146 Radio::SetChannel(CF_HZ);
LoRaToolbox 0:44fb2db84011 147
LoRaToolbox 1:b277f5a65c1c 148 // Set transmitter output power
LoRaToolbox 0:44fb2db84011 149 Radio::set_tx_dbm(TX_DBM);
LoRaToolbox 0:44fb2db84011 150
LoRaToolbox 1:b277f5a65c1c 151 // Setup transmit packet payload -> preambleLen, fixLen, crcOn, invIQ
LoRaToolbox 0:44fb2db84011 152 Radio::LoRaPacketConfig(8, false, true, false);
corymast 3:5e25ec621190 153 }
corymast 3:5e25ec621190 154
corymast 8:738ab96d41da 155 /**
corymast 8:738ab96d41da 156 * Function for converting analog sensor reading to resistance in Ohms.
corymast 8:738ab96d41da 157 */
corymast 7:803a185d7021 158 float convert_analog_light_resistance(double analog_val)
corymast 7:803a185d7021 159 {
corymast 7:803a185d7021 160 float Rsensor=(float)(1023-analog_val)*10/analog_val;
corymast 7:803a185d7021 161 return Rsensor;
corymast 7:803a185d7021 162 }
corymast 7:803a185d7021 163
corymast 8:738ab96d41da 164 /**
corymast 8:738ab96d41da 165 * Function for converting analog sensor reading to temperature in degrees F.
corymast 8:738ab96d41da 166 */
corymast 7:803a185d7021 167 float convert_analog_temperature(double analog_val)
corymast 7:803a185d7021 168 {
corymast 7:803a185d7021 169 double a = analog_val*1023;
corymast 7:803a185d7021 170 double resistance=(float)(1023-a)*10000/a;
corymast 7:803a185d7021 171 double temperature=1/(log(resistance/10000)/3975+1/298.15)-276.05;
corymast 7:803a185d7021 172 double temperature_f = (9.0*temperature)/5.0 + 32.0;
corymast 7:803a185d7021 173 return temperature_f;
corymast 7:803a185d7021 174 }
corymast 7:803a185d7021 175
corymast 8:738ab96d41da 176 /**
corymast 8:738ab96d41da 177 * Function for initializing the application.
corymast 8:738ab96d41da 178 */
corymast 8:738ab96d41da 179 void application_init(bool enable_auto_tx)
corymast 8:738ab96d41da 180 {
corymast 8:738ab96d41da 181 // Configure falling-edge of button to send JSON message
corymast 8:738ab96d41da 182 button.fall(&button_send_json);
corymast 8:738ab96d41da 183
corymast 8:738ab96d41da 184 if(enable_auto_tx)
corymast 8:738ab96d41da 185 {
corymast 8:738ab96d41da 186 // Configure automatic transmissions on the interval AUTO_TX_INTERVAL
corymast 8:738ab96d41da 187 ticker_tx.attach(&send_json, AUTO_TX_INTERVAL);
corymast 8:738ab96d41da 188 }
corymast 8:738ab96d41da 189
corymast 8:738ab96d41da 190 // Start a timer to track time between button presses
corymast 8:738ab96d41da 191 timer_button.start();
corymast 8:738ab96d41da 192 }
corymast 8:738ab96d41da 193
corymast 3:5e25ec621190 194 int main()
corymast 3:5e25ec621190 195 {
corymast 3:5e25ec621190 196 printf("\r\nreset-tx \n");
LoRaToolbox 0:44fb2db84011 197
corymast 3:5e25ec621190 198 radio_init();
LoRaToolbox 0:44fb2db84011 199
corymast 9:b6e3ffbfeabd 200 application_init(true);
LoRaToolbox 0:44fb2db84011 201
corymast 4:b2fc780be0b3 202 for (;;)
corymast 4:b2fc780be0b3 203 {
corymast 4:b2fc780be0b3 204 // Transmit message on button press, service radio until tx complete.
corymast 4:b2fc780be0b3 205 while (!txDone)
corymast 4:b2fc780be0b3 206 {
corymast 4:b2fc780be0b3 207 Radio::service();
corymast 7:803a185d7021 208 light_val_analog = sensor_light.read();
corymast 7:803a185d7021 209 temperature_analog = sensor_temp.read();
LoRaToolbox 1:b277f5a65c1c 210 }
corymast 4:b2fc780be0b3 211 }
LoRaToolbox 0:44fb2db84011 212 }