SX1272 LoRa RF module PingPong Demo

Dependencies:   SX1272Lib XRange_mbed_src

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 
00003 /*
00004     Maintainers: www.netblocks.eu
00005     SX1272 LoRa RF module : http://www.netblocks.eu/xrange-sx1272-lora-datasheet/
00006 */
00007 
00008 #include "main.h"
00009 #include "sx1272-hal.h"
00010 #include "debug.h"
00011 
00012 /* Set this flag to '1' to display debug messages on the console */
00013 #define DEBUG_MESSAGE   0
00014 
00015 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */
00016 #define USE_MODEM_LORA  1
00017 #define USE_MODEM_FSK   !USE_MODEM_LORA
00018 
00019 #define RF_FREQUENCY                                    868000000 // Hz
00020 #define TX_OUTPUT_POWER                                 20        // 14 dBm
00021 
00022 #if USE_MODEM_LORA == 1
00023 
00024     #define LORA_BANDWIDTH                              2         // [0: 125 kHz,
00025                                                                   //  1: 250 kHz,
00026                                                                   //  2: 500 kHz,
00027                                                                   //  3: Reserved]
00028     #define LORA_SPREADING_FACTOR                       7         // [SF7..SF12]
00029     #define LORA_CODINGRATE                             1         // [1: 4/5,
00030                                                                   //  2: 4/6,
00031                                                                   //  3: 4/7,
00032                                                                   //  4: 4/8]
00033     #define LORA_PREAMBLE_LENGTH                        8         // Same for Tx and Rx
00034     #define LORA_SYMBOL_TIMEOUT                         5         // Symbols
00035     #define LORA_FIX_LENGTH_PAYLOAD_ON                  false
00036     #define LORA_FHSS_ENABLED                           false  
00037     #define LORA_NB_SYMB_HOP                            4     
00038     #define LORA_IQ_INVERSION_ON                        false
00039     #define LORA_CRC_ENABLED                            true
00040     
00041 #elif USE_MODEM_FSK == 1
00042 
00043     #define FSK_FDEV                                    25000     // Hz
00044     #define FSK_DATARATE                                19200     // bps
00045     #define FSK_BANDWIDTH                               50000     // Hz
00046     #define FSK_AFC_BANDWIDTH                           83333     // Hz
00047     #define FSK_PREAMBLE_LENGTH                         5         // Same for Tx and Rx
00048     #define FSK_FIX_LENGTH_PAYLOAD_ON                   false
00049     #define FSK_CRC_ENABLED                             true
00050     
00051 #else
00052     #error "Please define a modem in the compiler options."
00053 #endif
00054 
00055 #define RX_TIMEOUT_VALUE                                3500000   // in us
00056 #define BUFFER_SIZE                                     32        // Define the payload size here
00057 
00058 DigitalOut led(PA_8);
00059 
00060 
00061 /*
00062  *  Global variables declarations
00063  */
00064 typedef RadioState States_t;
00065 volatile States_t State = LOWPOWER;
00066 
00067 XRange Radio( OnTxDone, OnTxTimeout, OnRxDone, OnRxTimeout, OnRxError, NULL, NULL );
00068 
00069 const uint8_t PingMsg[] = "PING";
00070 const uint8_t PongMsg[] = "PONG";
00071 
00072 uint16_t BufferSize = BUFFER_SIZE;
00073 uint8_t Buffer[BUFFER_SIZE];
00074 
00075 int16_t RssiValue = 0.0;
00076 int8_t SnrValue = 0.0;
00077 
00078 int main() 
00079 {
00080     uint8_t i;
00081     bool isMaster = true;
00082     
00083     debug( "\n\n\r     SX1276 Ping Pong Demo Application \n\n\r" );
00084     
00085     // verify the connection with the board
00086             
00087 
00088     Radio.SetChannel( RF_FREQUENCY ); 
00089 
00090 #if USE_MODEM_LORA == 1
00091     
00092     debug_if( LORA_FHSS_ENABLED, "\n\n\r             > LORA FHSS Mode < \n\n\r");
00093     debug_if( !LORA_FHSS_ENABLED, "\n\n\r             > LORA Mode < \n\n\r");
00094 
00095     Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
00096                          LORA_SPREADING_FACTOR, LORA_CODINGRATE,
00097                          LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
00098                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
00099                          LORA_IQ_INVERSION_ON, 2000000 );
00100     
00101     Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
00102                          LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
00103                          LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
00104                          LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 
00105                          LORA_IQ_INVERSION_ON, true );
00106                          
00107 #elif USE_MODEM_FSK == 1
00108 
00109     debug("\n\n\r              > FSK Mode < \n\n\r");
00110     Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0,
00111                          FSK_DATARATE, 0,
00112                          FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON,
00113                          FSK_CRC_ENABLED, 0, 0, 0, 2000000 );
00114     
00115     Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE,
00116                          0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH,
00117                          0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED,
00118                          0, 0, false, true );
00119                          
00120 #else
00121 
00122 #error "Please define a modem in the compiler options."
00123 
00124 #endif
00125      
00126     debug_if( DEBUG_MESSAGE, "Starting Ping-Pong loop\r\n" ); 
00127         
00128     led = 0;
00129         
00130     Radio.Rx( RX_TIMEOUT_VALUE );
00131     
00132     while( 1 )
00133     {
00134         switch( State )
00135         {
00136         case RX:
00137             if( isMaster == true )
00138             {
00139                 if( BufferSize > 0 )
00140                 {
00141                     if( strncmp( ( const char* )Buffer, ( const char* )PongMsg, 4 ) == 0 )
00142                     {
00143                         led = !led;
00144                         debug( "...Pong\r\n" );
00145                         // Send the next PING frame            
00146                         strcpy( ( char* )Buffer, ( char* )PingMsg );
00147                         // We fill the buffer with numbers for the payload 
00148                         for( i = 4; i < BufferSize; i++ )
00149                         {
00150                             Buffer[i] = i - 4;
00151                         }
00152                         wait_ms( 10 ); 
00153                         Radio.Send( Buffer, BufferSize );
00154                     }
00155                     else if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
00156                     { // A master already exists then become a slave
00157                         debug( "...Ping\r\n" );
00158                         led = !led;
00159                         isMaster = false;
00160                         // Send the next PONG frame            
00161                         strcpy( ( char* )Buffer, ( char* )PongMsg );
00162                         // We fill the buffer with numbers for the payload 
00163                         for( i = 4; i < BufferSize; i++ )
00164                         {
00165                             Buffer[i] = i - 4;
00166                         }
00167                         wait_ms( 10 ); 
00168                         Radio.Send( Buffer, BufferSize );
00169                     }
00170                     else // valid reception but neither a PING or a PONG message
00171                     {    // Set device as master ans start again
00172                         isMaster = true;
00173                         Radio.Rx( RX_TIMEOUT_VALUE );
00174                     }    
00175                 }
00176             }
00177             else
00178             {
00179                 if( BufferSize > 0 )
00180                 {
00181                     if( strncmp( ( const char* )Buffer, ( const char* )PingMsg, 4 ) == 0 )
00182                     {
00183                         led = !led;
00184                         debug( "...Ping\r\n" );
00185                         // Send the reply to the PING string
00186                         strcpy( ( char* )Buffer, ( char* )PongMsg );
00187                         // We fill the buffer with numbers for the payload 
00188                         for( i = 4; i < BufferSize; i++ )
00189                         {
00190                             Buffer[i] = i - 4;
00191                         }
00192                         wait_ms( 10 );  
00193                         Radio.Send( Buffer, BufferSize );
00194                     }
00195                     else // valid reception but not a PING as expected
00196                     {    // Set device as master and start again
00197                         isMaster = true;
00198                         Radio.Rx( RX_TIMEOUT_VALUE );
00199                     }    
00200                 }
00201             }
00202             State = LOWPOWER;
00203             break;
00204         case TX:    
00205             led = !led; 
00206             if( isMaster == true )  
00207             {
00208                 debug( "Ping...\r\n" );
00209             }
00210             else
00211             {
00212                 debug( "Pong...\r\n" );
00213             }
00214             Radio.Rx( RX_TIMEOUT_VALUE );
00215             State = LOWPOWER;
00216             break;
00217         case RX_TIMEOUT:
00218             if( isMaster == true )
00219             {
00220                 // Send the next PING frame
00221                 strcpy( ( char* )Buffer, ( char* )PingMsg );
00222                 for( i = 4; i < BufferSize; i++ )
00223                 {
00224                     Buffer[i] = i - 4;
00225                 }
00226                 wait_ms( 10 ); 
00227                 Radio.Send( Buffer, BufferSize );
00228             }
00229             else
00230             {
00231                 Radio.Rx( RX_TIMEOUT_VALUE );  
00232             }             
00233             State = LOWPOWER;
00234             break;
00235         case RX_ERROR:
00236             // We have received a Packet with a CRC error, send reply as if packet was correct
00237             if( isMaster == true )
00238             {
00239                 // Send the next PING frame
00240                 strcpy( ( char* )Buffer, ( char* )PingMsg );
00241                 for( i = 4; i < BufferSize; i++ )
00242                 {
00243                     Buffer[i] = i - 4;
00244                 }
00245                 wait_ms( 10 );  
00246                 Radio.Send( Buffer, BufferSize );
00247             }
00248             else
00249             {
00250                 // Send the next PONG frame
00251                 strcpy( ( char* )Buffer, ( char* )PongMsg );
00252                 for( i = 4; i < BufferSize; i++ )
00253                 {
00254                     Buffer[i] = i - 4;
00255                 }
00256                 wait_ms( 10 );  
00257                 Radio.Send( Buffer, BufferSize );
00258             }
00259             State = LOWPOWER;
00260             break;
00261         case TX_TIMEOUT:
00262             Radio.Rx( RX_TIMEOUT_VALUE );
00263             State = LOWPOWER;
00264             break;
00265         case LOWPOWER:
00266             break;
00267         default:
00268             State = LOWPOWER;
00269             break;
00270         }    
00271     }
00272 }
00273 
00274 void OnTxDone( void )
00275 {
00276     Radio.Sleep( );
00277     State = TX;
00278     debug_if( DEBUG_MESSAGE, "> OnTxDone\n\r" );
00279 }
00280 
00281 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
00282 {
00283     Radio.Sleep( );
00284     BufferSize = size;
00285     memcpy( Buffer, payload, BufferSize );
00286     RssiValue = rssi;
00287     SnrValue = snr;
00288     State = RX;
00289     debug_if( DEBUG_MESSAGE, "> OnRxDone\n\r" );
00290 }
00291 
00292 void OnTxTimeout( void )
00293 {
00294     Radio.Sleep( );
00295     State = TX_TIMEOUT;
00296     debug_if( DEBUG_MESSAGE, "> OnTxTimeout\n\r" );
00297 }
00298 
00299 void OnRxTimeout( void )
00300 {
00301     Radio.Sleep( );
00302     Buffer[ BufferSize ] = 0;
00303     State = RX_TIMEOUT;
00304     debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
00305     debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" );
00306     
00307 }
00308 
00309 void OnRxError( void )
00310 {
00311     Radio.Sleep( );
00312     State = RX_ERROR;
00313     debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" );
00314 }