SX1276 Ping Pong FHSS Demo Application

Dependencies:   SX1276Lib mbed

Ping-Pong demo application using FHSS (Frequency Hoping Spread Spectrum) between two SX1276MB1xAs demo board.

Application demonstrating simple Tx/Rx between two boards. By default, each board starts as a "master" and will transmit a "Ping" message, and then wait for an answer. The first board receiving a "Ping" message will become a slave and answer the "master" with a "Pong". The Ping-Pong is then started...

Committer:
mluis
Date:
Tue Dec 16 12:52:53 2014 +0000
Revision:
3:99bd9ae6906f
Parent:
2:b03bdfedfafa
Child:
4:cd44376a1408
Updated according to radio library API change

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GregCr 0:db48addeabda 1 #include "mbed.h"
GregCr 2:b03bdfedfafa 2 #include "main.h"
GregCr 1:41b10c760ff2 3 #include "sx1276-hal.h"
GregCr 2:b03bdfedfafa 4 #include "debug.h"
GregCr 0:db48addeabda 5
GregCr 0:db48addeabda 6 /* Set this flag to '1' to display debug messages on the console */
GregCr 2:b03bdfedfafa 7 #define DEBUG_MESSAGE 0
GregCr 0:db48addeabda 8
GregCr 0:db48addeabda 9 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */
GregCr 0:db48addeabda 10 #define USE_MODEM_LORA 1
GregCr 0:db48addeabda 11 #define USE_MODEM_FSK !USE_MODEM_LORA
GregCr 0:db48addeabda 12
GregCr 0:db48addeabda 13 #define RF_FREQUENCY 915000000 // Hz
GregCr 0:db48addeabda 14 #define TX_OUTPUT_POWER 14 // 14 dBm
GregCr 0:db48addeabda 15
GregCr 0:db48addeabda 16 #if USE_MODEM_LORA == 1
GregCr 0:db48addeabda 17
GregCr 0:db48addeabda 18 #define LORA_BANDWIDTH 1 // [0: 125 kHz,
GregCr 0:db48addeabda 19 // 1: 250 kHz,
GregCr 0:db48addeabda 20 // 2: 500 kHz,
GregCr 0:db48addeabda 21 // 3: Reserved]
GregCr 0:db48addeabda 22 #define LORA_SPREADING_FACTOR 10 // [SF7..SF12]
GregCr 0:db48addeabda 23 #define LORA_CODINGRATE 1 // [1: 4/5,
GregCr 0:db48addeabda 24 // 2: 4/6,
GregCr 0:db48addeabda 25 // 3: 4/7,
GregCr 0:db48addeabda 26 // 4: 4/8]
GregCr 0:db48addeabda 27 #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx
GregCr 0:db48addeabda 28 #define LORA_SYMBOL_TIMEOUT 5 // Symbols
GregCr 0:db48addeabda 29 #define LORA_FIX_LENGTH_PAYLOAD_ON false
GregCr 0:db48addeabda 30 #define LORA_FHSS_ENABLED true
GregCr 0:db48addeabda 31 #define LORA_NB_SYMB_HOP 4
GregCr 0:db48addeabda 32 #define LORA_IQ_INVERSION_ON false
GregCr 0:db48addeabda 33 #define LORA_CRC_ENABLED true
GregCr 0:db48addeabda 34
GregCr 0:db48addeabda 35 #elif USE_MODEM_FSK == 1
GregCr 0:db48addeabda 36
GregCr 0:db48addeabda 37 #define FSK_FDEV 25000 // Hz
GregCr 0:db48addeabda 38 #define FSK_DATARATE 19200 // bps
GregCr 0:db48addeabda 39 #define FSK_BANDWIDTH 50000 // Hz
GregCr 0:db48addeabda 40 #define FSK_AFC_BANDWIDTH 83333 // Hz
GregCr 0:db48addeabda 41 #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx
GregCr 0:db48addeabda 42 #define FSK_FIX_LENGTH_PAYLOAD_ON false
GregCr 0:db48addeabda 43 #define FSK_CRC_ENABLED true
GregCr 0:db48addeabda 44
GregCr 0:db48addeabda 45 #else
GregCr 0:db48addeabda 46 #error "Please define a modem in the compiler options."
GregCr 0:db48addeabda 47 #endif
GregCr 0:db48addeabda 48
GregCr 2:b03bdfedfafa 49 #define RX_TIMEOUT_VALUE 3500000 // in us
GregCr 2:b03bdfedfafa 50 #define BUFFER_SIZE 32 // Define the payload size here [min:1 max:255]
GregCr 0:db48addeabda 51
GregCr 2:b03bdfedfafa 52 #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) )
GregCr 0:db48addeabda 53 DigitalOut led(LED2);
GregCr 0:db48addeabda 54 #else
GregCr 0:db48addeabda 55 DigitalOut led(LED1);
GregCr 0:db48addeabda 56 #endif
GregCr 0:db48addeabda 57
GregCr 0:db48addeabda 58 /*
GregCr 0:db48addeabda 59 * Global variables declarations
GregCr 0:db48addeabda 60 */
GregCr 0:db48addeabda 61 typedef RadioState States_t;
GregCr 2:b03bdfedfafa 62 volatile States_t State = LOWPOWER;
GregCr 0:db48addeabda 63
GregCr 0:db48addeabda 64 /*
GregCr 0:db48addeabda 65 * Global variables declarations
GregCr 0:db48addeabda 66 */
GregCr 0:db48addeabda 67 SX1276MB1xAS Radio( OnTxDone, OnTxTimeout, OnRxDone, OnRxTimeout, OnRxError, OnFhssChangeChannel, NULL );
GregCr 0:db48addeabda 68
GregCr 0:db48addeabda 69 const uint8_t PingMsg[] = "PING";
GregCr 0:db48addeabda 70 const uint8_t PongMsg[] = "PONG";
GregCr 0:db48addeabda 71
GregCr 0:db48addeabda 72 uint16_t BufferSize = BUFFER_SIZE;
GregCr 0:db48addeabda 73 uint8_t Buffer[BUFFER_SIZE];
GregCr 0:db48addeabda 74
GregCr 0:db48addeabda 75 int16_t RssiValue = 0.0;
GregCr 0:db48addeabda 76 int8_t SnrValue = 0.0;
GregCr 0:db48addeabda 77
GregCr 0:db48addeabda 78 int main()
GregCr 0:db48addeabda 79 {
GregCr 0:db48addeabda 80 uint8_t i;
GregCr 0:db48addeabda 81 bool isMaster = true;
GregCr 0:db48addeabda 82
GregCr 2:b03bdfedfafa 83 debug( "\n\n\r SX1276 Ping Pong Demo Application \n\n\r" );
GregCr 0:db48addeabda 84
GregCr 2:b03bdfedfafa 85 // verify the connection with the board
GregCr 2:b03bdfedfafa 86 while( Radio.Read( REG_VERSION ) == 0x00 )
GregCr 0:db48addeabda 87 {
GregCr 2:b03bdfedfafa 88 debug( "Radio could not be detected!\n\r", NULL );
GregCr 2:b03bdfedfafa 89 wait( 1 );
GregCr 0:db48addeabda 90 }
GregCr 2:b03bdfedfafa 91
GregCr 2:b03bdfedfafa 92 debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1LAS ) ) , "\n\r > Board Type: SX1276MB1LAS < \n\r" );
GregCr 2:b03bdfedfafa 93 debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1276MB1MAS ) ) , "\n\r > Board Type: SX1276MB1MAS < \n\r" );
GregCr 0:db48addeabda 94
GregCr 0:db48addeabda 95 Radio.SetChannel( HoppingFrequencies[0] );
GregCr 0:db48addeabda 96
GregCr 0:db48addeabda 97 #if USE_MODEM_LORA == 1
GregCr 0:db48addeabda 98
GregCr 2:b03bdfedfafa 99 debug_if( LORA_FHSS_ENABLED, "\n\n\r > LORA FHSS Mode < \n\n\r");
GregCr 2:b03bdfedfafa 100 debug_if( !LORA_FHSS_ENABLED, "\n\n\r > LORA Mode < \n\n\r");
GregCr 2:b03bdfedfafa 101
GregCr 0:db48addeabda 102 Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
GregCr 0:db48addeabda 103 LORA_SPREADING_FACTOR, LORA_CODINGRATE,
GregCr 0:db48addeabda 104 LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
GregCr 0:db48addeabda 105 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
GregCr 0:db48addeabda 106 LORA_IQ_INVERSION_ON, 4000000 );
GregCr 0:db48addeabda 107
GregCr 0:db48addeabda 108 Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
GregCr 0:db48addeabda 109 LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
mluis 3:99bd9ae6906f 110 LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
GregCr 0:db48addeabda 111 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
GregCr 0:db48addeabda 112 LORA_IQ_INVERSION_ON, true );
GregCr 0:db48addeabda 113
GregCr 0:db48addeabda 114 #elif USE_MODEM_FSK == 1
GregCr 0:db48addeabda 115
GregCr 2:b03bdfedfafa 116 debug("\n\n\r > FSK Mode < \n\n\r");
GregCr 0:db48addeabda 117 Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
GregCr 0:db48addeabda 118 FSK_DATARATE, 0,
GregCr 0:db48addeabda 119 FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
GregCr 0:db48addeabda 120 FSK_CRC_ENABLED, 0, 0, 0, 3000000 );
GregCr 0:db48addeabda 121
GregCr 0:db48addeabda 122 Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
GregCr 0:db48addeabda 123 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
mluis 3:99bd9ae6906f 124 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
GregCr 0:db48addeabda 125 0, 0, false, true );
GregCr 0:db48addeabda 126
GregCr 0:db48addeabda 127 #else
GregCr 0:db48addeabda 128
GregCr 0:db48addeabda 129 #error "Please define a modem in the compiler options."
GregCr 0:db48addeabda 130
GregCr 0:db48addeabda 131 #endif
GregCr 0:db48addeabda 132
GregCr 2:b03bdfedfafa 133 debug_if( DEBUG_MESSAGE, "Starting Ping-Pong loop\r\n" );
GregCr 0:db48addeabda 134
GregCr 0:db48addeabda 135 led = 0;
GregCr 0:db48addeabda 136
GregCr 0:db48addeabda 137 Radio.Rx( RX_TIMEOUT_VALUE );
GregCr 0:db48addeabda 138
GregCr 0:db48addeabda 139 while( 1 )
GregCr 0:db48addeabda 140 {
GregCr 0:db48addeabda 141 switch( State )
GregCr 0:db48addeabda 142 {
GregCr 0:db48addeabda 143 case RX:
GregCr 0:db48addeabda 144 if( isMaster == true )
GregCr 0:db48addeabda 145 {
GregCr 0:db48addeabda 146 if( BufferSize > 0 )
GregCr 0:db48addeabda 147 {
GregCr 0:db48addeabda 148 if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 )
GregCr 0:db48addeabda 149 {
GregCr 0:db48addeabda 150 led = !led;
GregCr 0:db48addeabda 151 debug( "...Pong\r\n" );
GregCr 0:db48addeabda 152 // Send the next PING frame
GregCr 2:b03bdfedfafa 153 strcpy( ( char* )Buffer, ( char* )PingMsg );
GregCr 0:db48addeabda 154 // We fill the buffer with numbers for the payload
GregCr 0:db48addeabda 155 for( i = 4; i < BufferSize; i++ )
GregCr 0:db48addeabda 156 {
GregCr 0:db48addeabda 157 Buffer[i] = i - 4;
GregCr 0:db48addeabda 158 }
GregCr 0:db48addeabda 159 wait_ms( 10 );
GregCr 0:db48addeabda 160 Radio.Send( Buffer, BufferSize );
GregCr 0:db48addeabda 161 }
GregCr 0:db48addeabda 162 else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
GregCr 0:db48addeabda 163 { // A master already exists then become a slave
GregCr 0:db48addeabda 164 debug( "...Ping\r\n" );
GregCr 0:db48addeabda 165 led = !led;
GregCr 0:db48addeabda 166 isMaster = false;
GregCr 2:b03bdfedfafa 167 // Send the next PONG frame
GregCr 2:b03bdfedfafa 168 strcpy( ( char* )Buffer, ( char* )PongMsg );
GregCr 0:db48addeabda 169 // We fill the buffer with numbers for the payload
GregCr 0:db48addeabda 170 for( i = 4; i < BufferSize; i++ )
GregCr 0:db48addeabda 171 {
GregCr 0:db48addeabda 172 Buffer[i] = i - 4;
GregCr 0:db48addeabda 173 }
GregCr 0:db48addeabda 174 wait_ms( 10 );
GregCr 0:db48addeabda 175 Radio.Send( Buffer, BufferSize );
GregCr 0:db48addeabda 176 }
GregCr 0:db48addeabda 177 else // valid reception but neither a PING or a PONG message
GregCr 0:db48addeabda 178 { // Set device as master ans start again
GregCr 0:db48addeabda 179 isMaster = true;
GregCr 0:db48addeabda 180 Radio.Rx( RX_TIMEOUT_VALUE );
GregCr 0:db48addeabda 181 }
GregCr 0:db48addeabda 182 }
GregCr 0:db48addeabda 183 }
GregCr 0:db48addeabda 184 else
GregCr 0:db48addeabda 185 {
GregCr 0:db48addeabda 186 if( BufferSize > 0 )
GregCr 0:db48addeabda 187 {
GregCr 0:db48addeabda 188 if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
GregCr 0:db48addeabda 189 {
GregCr 0:db48addeabda 190 led = !led;
GregCr 0:db48addeabda 191 debug( "...Ping\r\n" );
GregCr 0:db48addeabda 192 // Send the reply to the PING string
GregCr 2:b03bdfedfafa 193 strcpy( ( char* )Buffer, ( char* )PongMsg );
GregCr 0:db48addeabda 194 // We fill the buffer with numbers for the payload
GregCr 0:db48addeabda 195 for( i = 4; i < BufferSize; i++ )
GregCr 0:db48addeabda 196 {
GregCr 0:db48addeabda 197 Buffer[i] = i - 4;
GregCr 0:db48addeabda 198 }
GregCr 0:db48addeabda 199 wait_ms( 10 );
GregCr 0:db48addeabda 200 Radio.Send( Buffer, BufferSize );
GregCr 0:db48addeabda 201 }
GregCr 0:db48addeabda 202 else // valid reception but not a PING as expected
GregCr 0:db48addeabda 203 { // Set device as master and start again
GregCr 0:db48addeabda 204 isMaster = true;
GregCr 0:db48addeabda 205 Radio.Rx( RX_TIMEOUT_VALUE );
GregCr 0:db48addeabda 206 }
GregCr 0:db48addeabda 207 }
GregCr 0:db48addeabda 208 }
GregCr 0:db48addeabda 209 State = LOWPOWER;
GregCr 0:db48addeabda 210 break;
GregCr 0:db48addeabda 211 case TX:
GregCr 0:db48addeabda 212 led = !led;
GregCr 0:db48addeabda 213 if( isMaster == true )
GregCr 0:db48addeabda 214 {
GregCr 0:db48addeabda 215 debug( "Ping...\r\n" );
GregCr 0:db48addeabda 216 }
GregCr 0:db48addeabda 217 else
GregCr 0:db48addeabda 218 {
GregCr 0:db48addeabda 219 debug( "Pong...\r\n" );
GregCr 0:db48addeabda 220 }
GregCr 0:db48addeabda 221 Radio.Rx( RX_TIMEOUT_VALUE );
GregCr 0:db48addeabda 222 State = LOWPOWER;
GregCr 0:db48addeabda 223 break;
GregCr 0:db48addeabda 224 case RX_TIMEOUT:
GregCr 0:db48addeabda 225 if( isMaster == true )
GregCr 0:db48addeabda 226 {
GregCr 0:db48addeabda 227 // Send the next PING frame
GregCr 2:b03bdfedfafa 228 strcpy( ( char* )Buffer, ( char* )PingMsg );
GregCr 0:db48addeabda 229 for( i = 4; i < BufferSize; i++ )
GregCr 0:db48addeabda 230 {
GregCr 0:db48addeabda 231 Buffer[i] = i - 4;
GregCr 0:db48addeabda 232 }
GregCr 0:db48addeabda 233 wait_ms( 10 );
GregCr 0:db48addeabda 234 Radio.Send( Buffer, BufferSize );
GregCr 0:db48addeabda 235 }
GregCr 0:db48addeabda 236 else
GregCr 0:db48addeabda 237 {
GregCr 0:db48addeabda 238 Radio.Rx( RX_TIMEOUT_VALUE );
GregCr 0:db48addeabda 239 }
GregCr 0:db48addeabda 240 State = LOWPOWER;
GregCr 0:db48addeabda 241 break;
GregCr 0:db48addeabda 242 case RX_ERROR:
GregCr 2:b03bdfedfafa 243 // We have received a Packet with a CRC error, send reply as if packet was correct
GregCr 0:db48addeabda 244 if( isMaster == true )
GregCr 0:db48addeabda 245 {
GregCr 0:db48addeabda 246 // Send the next PING frame
GregCr 2:b03bdfedfafa 247 strcpy( ( char* )Buffer, ( char* )PingMsg );
GregCr 0:db48addeabda 248 for( i = 4; i < BufferSize; i++ )
GregCr 0:db48addeabda 249 {
GregCr 0:db48addeabda 250 Buffer[i] = i - 4;
GregCr 0:db48addeabda 251 }
GregCr 0:db48addeabda 252 wait_ms( 10 );
GregCr 0:db48addeabda 253 Radio.Send( Buffer, BufferSize );
GregCr 0:db48addeabda 254 }
GregCr 0:db48addeabda 255 else
GregCr 0:db48addeabda 256 {
GregCr 0:db48addeabda 257 // Send the next PONG frame
GregCr 2:b03bdfedfafa 258 strcpy( ( char* )Buffer, ( char* )PongMsg );
GregCr 0:db48addeabda 259 for( i = 4; i < BufferSize; i++ )
GregCr 0:db48addeabda 260 {
GregCr 0:db48addeabda 261 Buffer[i] = i - 4;
GregCr 0:db48addeabda 262 }
GregCr 0:db48addeabda 263 wait_ms( 10 );
GregCr 0:db48addeabda 264 Radio.Send( Buffer, BufferSize );
GregCr 0:db48addeabda 265 }
GregCr 0:db48addeabda 266 State = LOWPOWER;
GregCr 0:db48addeabda 267 break;
GregCr 0:db48addeabda 268 case TX_TIMEOUT:
GregCr 0:db48addeabda 269 Radio.Rx( RX_TIMEOUT_VALUE );
GregCr 0:db48addeabda 270 State = LOWPOWER;
GregCr 0:db48addeabda 271 break;
GregCr 0:db48addeabda 272 case LOWPOWER:
GregCr 0:db48addeabda 273 break;
GregCr 0:db48addeabda 274 default:
GregCr 0:db48addeabda 275 State = LOWPOWER;
GregCr 0:db48addeabda 276 break;
GregCr 0:db48addeabda 277 }
GregCr 0:db48addeabda 278 }
GregCr 0:db48addeabda 279 }
GregCr 0:db48addeabda 280
GregCr 0:db48addeabda 281 void OnTxDone( void )
GregCr 0:db48addeabda 282 {
GregCr 0:db48addeabda 283 Radio.SetChannel( HoppingFrequencies[0] );
GregCr 0:db48addeabda 284 Radio.Sleep( );
GregCr 0:db48addeabda 285 State = TX;
GregCr 2:b03bdfedfafa 286 debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" );
GregCr 0:db48addeabda 287 }
GregCr 0:db48addeabda 288
GregCr 0:db48addeabda 289 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
GregCr 0:db48addeabda 290 {
GregCr 0:db48addeabda 291 Radio.SetChannel( HoppingFrequencies[0] );
GregCr 0:db48addeabda 292 Radio.Sleep( );
GregCr 0:db48addeabda 293 BufferSize = size;
GregCr 0:db48addeabda 294 memcpy( Buffer, payload, BufferSize );
GregCr 0:db48addeabda 295 RssiValue = rssi;
GregCr 0:db48addeabda 296 SnrValue = snr;
GregCr 0:db48addeabda 297 State = RX;
GregCr 2:b03bdfedfafa 298 debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
GregCr 0:db48addeabda 299 }
GregCr 0:db48addeabda 300
GregCr 0:db48addeabda 301 void OnTxTimeout( void )
GregCr 0:db48addeabda 302 {
GregCr 0:db48addeabda 303 Radio.SetChannel( HoppingFrequencies[0] );
GregCr 0:db48addeabda 304 Radio.Sleep( );
GregCr 0:db48addeabda 305 State = TX_TIMEOUT;
GregCr 2:b03bdfedfafa 306 debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
GregCr 0:db48addeabda 307 }
GregCr 0:db48addeabda 308
GregCr 0:db48addeabda 309 void OnRxTimeout( void )
GregCr 0:db48addeabda 310 {
GregCr 0:db48addeabda 311 Radio.SetChannel( HoppingFrequencies[0] );
GregCr 0:db48addeabda 312 Radio.Sleep( );
GregCr 0:db48addeabda 313 Buffer[ BufferSize ] = 0;
GregCr 0:db48addeabda 314 State = RX_TIMEOUT;
GregCr 2:b03bdfedfafa 315 debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
GregCr 0:db48addeabda 316 }
GregCr 0:db48addeabda 317
GregCr 0:db48addeabda 318 void OnRxError( void )
GregCr 0:db48addeabda 319 {
GregCr 0:db48addeabda 320 Radio.SetChannel( HoppingFrequencies[0] );
GregCr 0:db48addeabda 321 Radio.Sleep( );
GregCr 0:db48addeabda 322 State = RX_ERROR;
GregCr 2:b03bdfedfafa 323 debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
GregCr 0:db48addeabda 324 }
GregCr 0:db48addeabda 325
GregCr 0:db48addeabda 326 void OnFhssChangeChannel( uint8_t channelIndex )
GregCr 0:db48addeabda 327 {
GregCr 0:db48addeabda 328 Radio.SetChannel( HoppingFrequencies[channelIndex] );
GregCr 1:41b10c760ff2 329 debug_if( DEBUG_MESSAGE, "F%d-", channelIndex);
GregCr 0:db48addeabda 330 }