This is code is part of a Technion course project in advanced IoT, implementing a device to receive and present sensors data from a Formula racing car built by students at Technion - Israel Institute of Technology.

Dependencies:   mbed Buffer

Fork of DISCO-L072CZ-LRWAN1_LoRa_PingPong by ST

This is code is part of a Technion course project in advanced IoT, implementing a device to receive sensors data from another L072CZ-LRWAN1 installed on a Formula racing car (built by students at Technion - Israel Institute of Technology), and sends it to a GUI presenting the data (GUI project: github.com/ward-mattar/TechnionFormulaGUI).

How to install

  • Create an account on Mbed: https://os.mbed.com/account/signup/
  • Import project into Compiler
  • In the Program Workspace select "Formula_Nucleo_Receiver"
  • Select a Platform like so:
  1. Click button at top-left
  2. Add Board
  3. Search "NUCLEO F103RB" and then "Add to your Mbed Compiler"
  • Finally click "Compile", if the build was successful, the binary would download automatically
  • To install it on device simply plug it in to a PC, open device drive and drag then drop binary file in it
Committer:
wardm
Date:
Sat May 19 15:42:38 2018 +0000
Revision:
12:046346a16ff4
V1.0.0

Who changed what in which revision?

UserRevisionLine numberNew contents of line
wardm 12:046346a16ff4 1 /*
wardm 12:046346a16ff4 2 * This file contains a copy of the master content sx1276PingPong
wardm 12:046346a16ff4 3 * with adaption for the SX1276Generic environment
wardm 12:046346a16ff4 4 * (c) 2017 Helmut Tschemernjak
wardm 12:046346a16ff4 5 * 30826 Garbsen (Hannover) Germany
wardm 12:046346a16ff4 6 */
wardm 12:046346a16ff4 7
wardm 12:046346a16ff4 8 #include "mbed.h"
wardm 12:046346a16ff4 9 #include "PinMap.h"
wardm 12:046346a16ff4 10 #include "Receiver.h"
wardm 12:046346a16ff4 11 #include "sx1276-mbed-hal.h"
wardm 12:046346a16ff4 12 #include "main.h"
wardm 12:046346a16ff4 13
wardm 12:046346a16ff4 14 #ifdef FEATURE_LORA
wardm 12:046346a16ff4 15
wardm 12:046346a16ff4 16 /* Set this flag to '1' to display debug messages on the console */
wardm 12:046346a16ff4 17 #define DEBUG_MESSAGE 1
wardm 12:046346a16ff4 18
wardm 12:046346a16ff4 19 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */
wardm 12:046346a16ff4 20 #define USE_MODEM_LORA 1
wardm 12:046346a16ff4 21 #define USE_MODEM_FSK !USE_MODEM_LORA
wardm 12:046346a16ff4 22 #define RF_FREQUENCY RF_FREQUENCY_868_1 // Hz
wardm 12:046346a16ff4 23 #define TX_OUTPUT_POWER 14 // 14 dBm
wardm 12:046346a16ff4 24
wardm 12:046346a16ff4 25 #if USE_MODEM_LORA == 1
wardm 12:046346a16ff4 26
wardm 12:046346a16ff4 27 #define LORA_BANDWIDTH 125000 // LoRa default, details in SX1276::BandwidthMap
wardm 12:046346a16ff4 28 #define LORA_SPREADING_FACTOR LORA_SF7
wardm 12:046346a16ff4 29 #define LORA_CODINGRATE LORA_ERROR_CODING_RATE_4_5
wardm 12:046346a16ff4 30
wardm 12:046346a16ff4 31 #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx
wardm 12:046346a16ff4 32 #define LORA_SYMBOL_TIMEOUT 5 // Symbols
wardm 12:046346a16ff4 33 #define LORA_FIX_LENGTH_PAYLOAD_ON false
wardm 12:046346a16ff4 34 #define LORA_FHSS_ENABLED false
wardm 12:046346a16ff4 35 #define LORA_NB_SYMB_HOP 4
wardm 12:046346a16ff4 36 #define LORA_IQ_INVERSION_ON false
wardm 12:046346a16ff4 37 #define LORA_CRC_ENABLED true
wardm 12:046346a16ff4 38
wardm 12:046346a16ff4 39 #elif USE_MODEM_FSK == 1
wardm 12:046346a16ff4 40
wardm 12:046346a16ff4 41 #define FSK_FDEV 25000 // Hz
wardm 12:046346a16ff4 42 #define FSK_DATARATE 19200 // bps
wardm 12:046346a16ff4 43 #define FSK_BANDWIDTH 50000 // Hz
wardm 12:046346a16ff4 44 #define FSK_AFC_BANDWIDTH 83333 // Hz
wardm 12:046346a16ff4 45 #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx
wardm 12:046346a16ff4 46 #define FSK_FIX_LENGTH_PAYLOAD_ON false
wardm 12:046346a16ff4 47 #define FSK_CRC_ENABLED true
wardm 12:046346a16ff4 48
wardm 12:046346a16ff4 49 #else
wardm 12:046346a16ff4 50 #error "Please define a modem in the compiler options."
wardm 12:046346a16ff4 51 #endif
wardm 12:046346a16ff4 52
wardm 12:046346a16ff4 53
wardm 12:046346a16ff4 54 #define RX_TIMEOUT_VALUE 3500 // in ms
wardm 12:046346a16ff4 55
wardm 12:046346a16ff4 56 #define BUFFER_SIZE 2048
wardm 12:046346a16ff4 57
wardm 12:046346a16ff4 58 /*
wardm 12:046346a16ff4 59 * Global variables declarations
wardm 12:046346a16ff4 60 */
wardm 12:046346a16ff4 61 typedef enum
wardm 12:046346a16ff4 62 {
wardm 12:046346a16ff4 63 LOWPOWER = 0,
wardm 12:046346a16ff4 64 IDLE,
wardm 12:046346a16ff4 65
wardm 12:046346a16ff4 66 RX,
wardm 12:046346a16ff4 67 RX_TIMEOUT,
wardm 12:046346a16ff4 68 RX_ERROR,
wardm 12:046346a16ff4 69
wardm 12:046346a16ff4 70 TX,
wardm 12:046346a16ff4 71 TX_TIMEOUT,
wardm 12:046346a16ff4 72
wardm 12:046346a16ff4 73 CAD,
wardm 12:046346a16ff4 74 CAD_DONE
wardm 12:046346a16ff4 75 } AppStates_t;
wardm 12:046346a16ff4 76
wardm 12:046346a16ff4 77 volatile AppStates_t State = LOWPOWER;
wardm 12:046346a16ff4 78
wardm 12:046346a16ff4 79 /*!
wardm 12:046346a16ff4 80 * Radio events function pointer
wardm 12:046346a16ff4 81 */
wardm 12:046346a16ff4 82 static RadioEvents_t RadioEvents;
wardm 12:046346a16ff4 83
wardm 12:046346a16ff4 84 /*
wardm 12:046346a16ff4 85 * Global variables declarations
wardm 12:046346a16ff4 86 */
wardm 12:046346a16ff4 87 SX1276Generic *Radio;
wardm 12:046346a16ff4 88
wardm 12:046346a16ff4 89 uint16_t BufferSize = BUFFER_SIZE;
wardm 12:046346a16ff4 90 uint8_t *Buffer;
wardm 12:046346a16ff4 91
wardm 12:046346a16ff4 92 DigitalOut *led3;
wardm 12:046346a16ff4 93
wardm 12:046346a16ff4 94
wardm 12:046346a16ff4 95 int Receiver()
wardm 12:046346a16ff4 96 {
wardm 12:046346a16ff4 97 #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) )
wardm 12:046346a16ff4 98 DigitalOut *led = new DigitalOut(LED2);
wardm 12:046346a16ff4 99 #elif defined(TARGET_NUCLEO_L073RZ) || defined(TARGET_DISCO_L072CZ_LRWAN1)
wardm 12:046346a16ff4 100 DigitalOut *led = new DigitalOut(LED4); // RX red
wardm 12:046346a16ff4 101 led3 = new DigitalOut(LED3); // TX blue
wardm 12:046346a16ff4 102 #else
wardm 12:046346a16ff4 103 DigitalOut *led = new DigitalOut(LED1);
wardm 12:046346a16ff4 104 led3 = led;
wardm 12:046346a16ff4 105 #endif
wardm 12:046346a16ff4 106
wardm 12:046346a16ff4 107 Buffer = new uint8_t[BUFFER_SIZE];
wardm 12:046346a16ff4 108 *led3 = 1;
wardm 12:046346a16ff4 109
wardm 12:046346a16ff4 110 #ifdef B_L072Z_LRWAN1_LORA
wardm 12:046346a16ff4 111 Radio = new SX1276Generic(NULL, MURATA_SX1276,
wardm 12:046346a16ff4 112 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET,
wardm 12:046346a16ff4 113 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5,
wardm 12:046346a16ff4 114 LORA_ANT_RX, LORA_ANT_TX, LORA_ANT_BOOST, LORA_TCXO);
wardm 12:046346a16ff4 115 #else // RFM95
wardm 12:046346a16ff4 116 Radio = new SX1276Generic(NULL, RFM95_SX1276,
wardm 12:046346a16ff4 117 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET,
wardm 12:046346a16ff4 118 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5);
wardm 12:046346a16ff4 119
wardm 12:046346a16ff4 120 #endif
wardm 12:046346a16ff4 121
wardm 12:046346a16ff4 122 uint8_t i;
wardm 12:046346a16ff4 123
wardm 12:046346a16ff4 124 bool isMaster = false;
wardm 12:046346a16ff4 125
wardm 12:046346a16ff4 126 dprintf("Formula Technion GUI Application" );
wardm 12:046346a16ff4 127 dprintf("Freqency: %.1f", (double)RF_FREQUENCY/1000000.0);
wardm 12:046346a16ff4 128 dprintf("TXPower: %d dBm", TX_OUTPUT_POWER);
wardm 12:046346a16ff4 129 #if USE_MODEM_LORA == 1
wardm 12:046346a16ff4 130 dprintf("Bandwidth: %d Hz", LORA_BANDWIDTH);
wardm 12:046346a16ff4 131 dprintf("Spreading factor: SF%d", LORA_SPREADING_FACTOR);
wardm 12:046346a16ff4 132 #elif USE_MODEM_FSK == 1
wardm 12:046346a16ff4 133 dprintf("Bandwidth: %d kHz", FSK_BANDWIDTH);
wardm 12:046346a16ff4 134 dprintf("Baudrate: %d", FSK_DATARATE);
wardm 12:046346a16ff4 135 #endif
wardm 12:046346a16ff4 136 // Initialize Radio driver
wardm 12:046346a16ff4 137 RadioEvents.TxDone = OnTxDone;
wardm 12:046346a16ff4 138 RadioEvents.RxDone = OnRxDone;
wardm 12:046346a16ff4 139 RadioEvents.RxError = OnRxError;
wardm 12:046346a16ff4 140 RadioEvents.TxTimeout = OnTxTimeout;
wardm 12:046346a16ff4 141 RadioEvents.RxTimeout = OnRxTimeout;
wardm 12:046346a16ff4 142 if (Radio->Init( &RadioEvents ) == false) {
wardm 12:046346a16ff4 143 while(1) {
wardm 12:046346a16ff4 144 dprintf("Radio could not be detected!");
wardm 12:046346a16ff4 145 wait( 1 );
wardm 12:046346a16ff4 146 }
wardm 12:046346a16ff4 147 }
wardm 12:046346a16ff4 148
wardm 12:046346a16ff4 149
wardm 12:046346a16ff4 150 switch(Radio->DetectBoardType()) {
wardm 12:046346a16ff4 151 case SX1276MB1LAS:
wardm 12:046346a16ff4 152 if (DEBUG_MESSAGE)
wardm 12:046346a16ff4 153 dprintf(" > Board Type: SX1276MB1LAS <");
wardm 12:046346a16ff4 154 break;
wardm 12:046346a16ff4 155 case SX1276MB1MAS:
wardm 12:046346a16ff4 156 if (DEBUG_MESSAGE)
wardm 12:046346a16ff4 157 dprintf(" > Board Type: SX1276MB1LAS <");
wardm 12:046346a16ff4 158 case MURATA_SX1276:
wardm 12:046346a16ff4 159 if (DEBUG_MESSAGE)
wardm 12:046346a16ff4 160 dprintf(" > Board Type: MURATA_SX1276_STM32L0 <");
wardm 12:046346a16ff4 161 break;
wardm 12:046346a16ff4 162 case RFM95_SX1276:
wardm 12:046346a16ff4 163 if (DEBUG_MESSAGE)
wardm 12:046346a16ff4 164 dprintf(" > HopeRF RFM95xx <");
wardm 12:046346a16ff4 165 break;
wardm 12:046346a16ff4 166 default:
wardm 12:046346a16ff4 167 dprintf(" > Board Type: unknown <");
wardm 12:046346a16ff4 168 }
wardm 12:046346a16ff4 169
wardm 12:046346a16ff4 170 Radio->SetChannel(RF_FREQUENCY );
wardm 12:046346a16ff4 171
wardm 12:046346a16ff4 172 #if USE_MODEM_LORA == 1
wardm 12:046346a16ff4 173
wardm 12:046346a16ff4 174 if (LORA_FHSS_ENABLED)
wardm 12:046346a16ff4 175 dprintf(" > LORA FHSS Mode <");
wardm 12:046346a16ff4 176 if (!LORA_FHSS_ENABLED)
wardm 12:046346a16ff4 177 dprintf(" > LORA Mode <");
wardm 12:046346a16ff4 178
wardm 12:046346a16ff4 179 Radio->SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
wardm 12:046346a16ff4 180 LORA_SPREADING_FACTOR, LORA_CODINGRATE,
wardm 12:046346a16ff4 181 LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
wardm 12:046346a16ff4 182 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
wardm 12:046346a16ff4 183 LORA_IQ_INVERSION_ON, 2000 );
wardm 12:046346a16ff4 184
wardm 12:046346a16ff4 185 Radio->SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
wardm 12:046346a16ff4 186 LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
wardm 12:046346a16ff4 187 LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
wardm 12:046346a16ff4 188 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
wardm 12:046346a16ff4 189 LORA_IQ_INVERSION_ON, true );
wardm 12:046346a16ff4 190
wardm 12:046346a16ff4 191 #elif USE_MODEM_FSK == 1
wardm 12:046346a16ff4 192
wardm 12:046346a16ff4 193 dprintf(" > FSK Mode <");
wardm 12:046346a16ff4 194 Radio->SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
wardm 12:046346a16ff4 195 FSK_DATARATE, 0,
wardm 12:046346a16ff4 196 FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
wardm 12:046346a16ff4 197 FSK_CRC_ENABLED, 0, 0, 0, 2000 );
wardm 12:046346a16ff4 198
wardm 12:046346a16ff4 199 Radio->SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
wardm 12:046346a16ff4 200 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
wardm 12:046346a16ff4 201 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
wardm 12:046346a16ff4 202 0, 0, false, true );
wardm 12:046346a16ff4 203
wardm 12:046346a16ff4 204 #else
wardm 12:046346a16ff4 205
wardm 12:046346a16ff4 206 #error "Please define a modem in the compiler options."
wardm 12:046346a16ff4 207
wardm 12:046346a16ff4 208 #endif
wardm 12:046346a16ff4 209
wardm 12:046346a16ff4 210
wardm 12:046346a16ff4 211 Radio->Rx( RX_TIMEOUT_VALUE );
wardm 12:046346a16ff4 212 while( 1 )
wardm 12:046346a16ff4 213 {
wardm 12:046346a16ff4 214 #ifdef TARGET_STM32L4
wardm 12:046346a16ff4 215 WatchDogUpdate();
wardm 12:046346a16ff4 216 #endif
wardm 12:046346a16ff4 217
wardm 12:046346a16ff4 218 switch( State )
wardm 12:046346a16ff4 219 {
wardm 12:046346a16ff4 220 case RX:
wardm 12:046346a16ff4 221 dprintf("SWITCH:::: RX \n");
wardm 12:046346a16ff4 222 *led3 = 0;
wardm 12:046346a16ff4 223 *led = !*led;
wardm 12:046346a16ff4 224 wait_ms( 10 );
wardm 12:046346a16ff4 225 ///////////////////////////////
wardm 12:046346a16ff4 226 State = LOWPOWER;
wardm 12:046346a16ff4 227 break;
wardm 12:046346a16ff4 228 case RX_TIMEOUT:
wardm 12:046346a16ff4 229
wardm 12:046346a16ff4 230 State = LOWPOWER;
wardm 12:046346a16ff4 231 dprintf("SWTICH : RX_TIMEOUT");
wardm 12:046346a16ff4 232 break;
wardm 12:046346a16ff4 233 case RX_ERROR:
wardm 12:046346a16ff4 234 // We have received a Packet with a CRC error, send reply as if packet was correct
wardm 12:046346a16ff4 235 State = LOWPOWER;
wardm 12:046346a16ff4 236 dprintf("SWTICH : RX_ERROR");
wardm 12:046346a16ff4 237 break;
wardm 12:046346a16ff4 238 case LOWPOWER:
wardm 12:046346a16ff4 239 dprintf("LOWPOWER, wait for input");
wardm 12:046346a16ff4 240 wait(1);
wardm 12:046346a16ff4 241 Radio->Rx( RX_TIMEOUT_VALUE );
wardm 12:046346a16ff4 242 break;
wardm 12:046346a16ff4 243 default:
wardm 12:046346a16ff4 244 dprintf("SWTICH : defualt");
wardm 12:046346a16ff4 245 State = LOWPOWER;
wardm 12:046346a16ff4 246 break;
wardm 12:046346a16ff4 247 }
wardm 12:046346a16ff4 248 }
wardm 12:046346a16ff4 249 }
wardm 12:046346a16ff4 250
wardm 12:046346a16ff4 251 void OnTxDone(void *radio, void *userThisPtr, void *userData)
wardm 12:046346a16ff4 252 {
wardm 12:046346a16ff4 253 if (DEBUG_MESSAGE)
wardm 12:046346a16ff4 254 dprintf("> OnTxDone [7]");
wardm 12:046346a16ff4 255 }
wardm 12:046346a16ff4 256
wardm 12:046346a16ff4 257 void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
wardm 12:046346a16ff4 258 {
wardm 12:046346a16ff4 259 Radio->Sleep( );
wardm 12:046346a16ff4 260 BufferSize = size;
wardm 12:046346a16ff4 261 memcpy( Buffer, payload, BufferSize );
wardm 12:046346a16ff4 262 State = RX;
wardm 12:046346a16ff4 263 Buffer[500] = 0;
wardm 12:046346a16ff4 264 dprintf("%s", Buffer);
wardm 12:046346a16ff4 265 }
wardm 12:046346a16ff4 266
wardm 12:046346a16ff4 267 void OnTxTimeout(void *radio, void *userThisPtr, void *userData)
wardm 12:046346a16ff4 268 {
wardm 12:046346a16ff4 269 *led3 = 0;
wardm 12:046346a16ff4 270 Radio->Sleep( );
wardm 12:046346a16ff4 271 State = LOWPOWER;
wardm 12:046346a16ff4 272 }
wardm 12:046346a16ff4 273
wardm 12:046346a16ff4 274 void OnRxTimeout(void *radio, void *userThisPtr, void *userData)
wardm 12:046346a16ff4 275 {
wardm 12:046346a16ff4 276 *led3 = 0;
wardm 12:046346a16ff4 277 Radio->Sleep( );
wardm 12:046346a16ff4 278 Buffer[BufferSize-1] = 0;
wardm 12:046346a16ff4 279 State = RX_TIMEOUT;
wardm 12:046346a16ff4 280 }
wardm 12:046346a16ff4 281
wardm 12:046346a16ff4 282 void OnRxError(void *radio, void *userThisPtr, void *userData)
wardm 12:046346a16ff4 283 {
wardm 12:046346a16ff4 284 Radio->Sleep( );
wardm 12:046346a16ff4 285 State = RX_ERROR;
wardm 12:046346a16ff4 286 }
wardm 12:046346a16ff4 287
wardm 12:046346a16ff4 288 #endif