Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BufferedSerial SX1276GenericLib mbed
Fork of DISCO-L072CZ-LRWAN1_LoRa_PingPong by
GenericPingPong.cpp
00001 /* 00002 * This file contains a copy of the master content sx1276PingPong 00003 * with adaption for the SX1276Generic environment 00004 * (c) 2017 Helmut Tschemernjak 00005 * 30826 Garbsen (Hannover) Germany 00006 */ 00007 00008 #include "mbed.h" 00009 #include "PinMap.h" 00010 #include "GenericPingPong.h" 00011 #include "sx1276-mbed-hal.h" 00012 #include "main.h" 00013 #include <string> 00014 00015 #ifdef FEATURE_LORA 00016 00017 /* Set this flag to '1' to display debug messages on the console */ 00018 #define DEBUG_MESSAGE 1 00019 00020 /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */ 00021 #define USE_MODEM_LORA 1 00022 #define USE_MODEM_FSK !USE_MODEM_LORA 00023 #define RF_FREQUENCY RF_FREQUENCY_915_0 // Hz 00024 #define TX_OUTPUT_POWER 20 // 20 dBm 00025 00026 #if USE_MODEM_LORA == 1 00027 00028 #define LORA_BANDWIDTH 125000 // LoRa default, details in SX1276::BandwidthMap 00029 #define LORA_SPREADING_FACTOR LORA_SF7 00030 #define LORA_CODINGRATE LORA_ERROR_CODING_RATE_4_5 00031 00032 #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx 00033 #define LORA_SYMBOL_TIMEOUT 5 // Symbols 00034 #define LORA_FIX_LENGTH_PAYLOAD_ON false 00035 #define LORA_FHSS_ENABLED true 00036 #define LORA_NB_SYMB_HOP 4 00037 #define LORA_IQ_INVERSION_ON false 00038 #define LORA_CRC_ENABLED true 00039 00040 #elif USE_MODEM_FSK == 1 00041 00042 #define FSK_FDEV 25000 // Hz 00043 #define FSK_DATARATE 19200 // bps 00044 #define FSK_BANDWIDTH 50000 // Hz 00045 #define FSK_AFC_BANDWIDTH 83333 // Hz 00046 #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx 00047 #define FSK_FIX_LENGTH_PAYLOAD_ON false 00048 #define FSK_CRC_ENABLED true 00049 00050 #else 00051 #error "Please define a modem in the compiler options." 00052 #endif 00053 00054 00055 #define RX_TIMEOUT_VALUE 3500 // in ms 00056 00057 //#define BUFFER_SIZE 32 // Define the payload size here 00058 #define BUFFER_SIZE 256 // Define the payload size here 00059 00060 /* 00061 * Global variables declarations 00062 */ 00063 typedef enum { 00064 LOWPOWER = 0, 00065 IDLE, 00066 00067 RX, 00068 RX_TIMEOUT, 00069 RX_ERROR, 00070 00071 TX, 00072 TX_TIMEOUT, 00073 00074 CAD, 00075 CAD_DONE 00076 } AppStates_t; 00077 00078 volatile AppStates_t State = LOWPOWER; 00079 00080 /*! 00081 * Radio events function pointer 00082 */ 00083 static RadioEvents_t RadioEvents; 00084 00085 /* 00086 * Global variables declarations 00087 */ 00088 SX1276Generic *Radio; 00089 00090 00091 //const uint8_t PingMsg[] = { 0xff, 0xff, 0x00, 0x00, 'P', 'I', 'N', 'G'};// "PING"; 00092 //const uint8_t PongMsg[] = { 0xff, 0xff, 0x00, 0x00, 'P', 'O', 'N', 'G'};// "PONG"; 00093 //const uint8_t PingMsg[] = { 'M', 'S', 'J', ' ','G','I','L'};// "PING"; 00094 //const uint8_t PongMsg[] = { 'R', 'P', 'T', 'A',' ','G','I','L'};// "PONG"; 00095 00096 //construccion de la trama 00097 const char EUI[] = "0A01";// 4 bytes que definen el identificador del dispositivo (copiar los bytes en string) 00098 const char AppEUI[] = "AAAA";// 4 bytes que definen el identificador de la aplicacion (copiar los bytes en string) 00099 const char AppKey[] = "1A1B";// 4 bytes que definen la clave de la aplicacion (copiar los bytes en string) - El protocolo LoRaWAN establece la clave de 16 bytes pero para efectos de prueba se hara de 4 00100 char MsgTX[256] = "";// Mensaje de transmision, se pueden usar los 52 bytes faltantes para completar el payload de 64 bytes. Se puede poner directamente en string. 00101 char MsgRX[256] = "";// Mensaje de recepcion, carga el payload entrante a esta cadena. 00102 char MsgRet[] = "RECIBIDO"; 00103 char DestEUI[4] = ""; 00104 char euiAux[4]=""; 00105 uint16_t BufferSize = BUFFER_SIZE; 00106 uint8_t *Buffer; 00107 string msjDeco=""; 00108 char *retParse; 00109 char *srcEUI; 00110 char *msjDestEUI; 00111 char *msjContent; 00112 Serial serRPi(PA_9, PA_10); 00113 00114 DigitalOut *led3; 00115 00116 00117 int SX1276PingPong() 00118 { 00119 #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) ) 00120 DigitalOut *led = new DigitalOut(LED2); 00121 #elif defined(TARGET_NUCLEO_L073RZ) || defined(TARGET_DISCO_L072CZ_LRWAN1) 00122 DigitalOut *led = new DigitalOut(LED4); // RX red 00123 led3 = new DigitalOut(LED3); // TX blue 00124 #else 00125 DigitalOut *led = new DigitalOut(LED1); 00126 led3 = led; 00127 #endif 00128 00129 Buffer = new uint8_t[BUFFER_SIZE]; 00130 *led3 = 1; 00131 00132 #ifdef B_L072Z_LRWAN1_LORA 00133 Radio = new SX1276Generic(NULL, MURATA_SX1276, 00134 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00135 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5, 00136 LORA_ANT_RX, LORA_ANT_TX, LORA_ANT_BOOST, LORA_TCXO); 00137 #else // RFM95 00138 Radio = new SX1276Generic(NULL, RFM95_SX1276, 00139 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00140 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5); 00141 00142 #endif 00143 //serRPi = new BufferedSerial(PA_9, PA_10); 00144 serRPi.baud(115200); 00145 serRPi.format(8); 00146 uint8_t i; 00147 bool isServer = true; 00148 00149 dprintf("Aplicacion de comunicacion LoRa punto a punto" ); 00150 dprintf("Frecuencia: %.1f", (double)RF_FREQUENCY/1000000.0); 00151 dprintf("TXPower: %d dBm", TX_OUTPUT_POWER); 00152 #if USE_MODEM_LORA == 1 00153 dprintf("Bandwidth: %d Hz", LORA_BANDWIDTH); 00154 dprintf("Spreading factor: SF%d", LORA_SPREADING_FACTOR); 00155 #elif USE_MODEM_FSK == 1 00156 dprintf("Bandwidth: %d kHz", FSK_BANDWIDTH); 00157 dprintf("Baudrate: %d", FSK_DATARATE); 00158 #endif 00159 // Initialize Radio driver 00160 RadioEvents.TxDone = OnTxDone; 00161 RadioEvents.RxDone = OnRxDone; 00162 RadioEvents.RxError = OnRxError; 00163 RadioEvents.TxTimeout = OnTxTimeout; 00164 RadioEvents.RxTimeout = OnRxTimeout; 00165 if (Radio->Init( &RadioEvents ) == false) { 00166 while(1) { 00167 dprintf("Radio could not be detected!"); 00168 wait( 1 ); 00169 } 00170 } 00171 00172 00173 switch(Radio->DetectBoardType()) { 00174 case SX1276MB1LAS: 00175 if (DEBUG_MESSAGE) 00176 dprintf(" > Board Type: SX1276MB1LAS <"); 00177 break; 00178 case SX1276MB1MAS: 00179 if (DEBUG_MESSAGE) 00180 dprintf(" > Board Type: SX1276MB1LAS <"); 00181 case MURATA_SX1276: 00182 if (DEBUG_MESSAGE) 00183 dprintf(" > Board Type: MURATA_SX1276_STM32L0 <"); 00184 break; 00185 case RFM95_SX1276: 00186 if (DEBUG_MESSAGE) 00187 dprintf(" > HopeRF RFM95xx <"); 00188 break; 00189 default: 00190 dprintf(" > Board Type: unknown <"); 00191 } 00192 00193 Radio->SetChannel(RF_FREQUENCY ); 00194 00195 #if USE_MODEM_LORA == 1 00196 00197 if (LORA_FHSS_ENABLED) 00198 dprintf(" > LORA FHSS Mode <"); 00199 if (!LORA_FHSS_ENABLED) 00200 dprintf(" > LORA Mode <"); 00201 00202 Radio->SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, 00203 LORA_SPREADING_FACTOR, LORA_CODINGRATE, 00204 LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, 00205 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 00206 LORA_IQ_INVERSION_ON, 2000 ); 00207 00208 Radio->SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, 00209 LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, 00210 LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, 00211 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 00212 LORA_IQ_INVERSION_ON, true ); 00213 00214 #elif USE_MODEM_FSK == 1 00215 00216 dprintf(" > FSK Mode <"); 00217 Radio->SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, 00218 FSK_DATARATE, 0, 00219 FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, 00220 FSK_CRC_ENABLED, 0, 0, 0, 2000 ); 00221 00222 Radio->SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, 00223 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, 00224 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED, 00225 0, 0, false, true ); 00226 00227 #else 00228 00229 #error "Please define a modem in the compiler options." 00230 00231 #endif 00232 00233 if (DEBUG_MESSAGE) 00234 dprintf("Inicializando el servidor"); 00235 dprintf("EUI (ID): %s",EUI); 00236 00237 Radio->Rx( RX_TIMEOUT_VALUE ); 00238 00239 while( 1 ) { 00240 #ifdef TARGET_STM32L4 00241 WatchDogUpdate(); 00242 #endif 00243 00244 switch( State ) { 00245 case RX: 00246 //dprintf( "Recibiendo informacion" ); 00247 *led = !*led; 00248 dprintf("Mensaje para depurar: %s",MsgRX); 00249 //strcpy(DestEUI,"A010"); 00250 msjDeco=MsgRX; 00251 //vector<string> x = split(msjDeco, '|'); 00252 splitOnPosition(MsgRX, 0); 00253 //msjDestEUI=splitOnPosition(MsgRX, 3); 00254 //msjContent=splitOnPosition(MsgRX, 4); 00255 00256 dprintf("Source EUI: %s, Destination EUI: %s, Content: %s",srcEUI,msjDestEUI,msjContent); 00257 if(strcmp(EUI,msjDestEUI) == 0) { 00258 dprintf("Mismo EUI, Soy el destinatario"); 00259 00260 } else { 00261 dprintf("Diferente EUI, ignorar mensaje"); 00262 Radio->Rx( RX_TIMEOUT_VALUE ); 00263 wait_ms( 500 ); 00264 *led = !*led; 00265 State = LOWPOWER; 00266 break; 00267 } 00268 strcpy(MsgRet,"RECIBIDO"); 00269 strcpy(MsgTX, EUI); 00270 strcat(MsgTX, "|"); 00271 strcat(MsgTX, AppEUI); 00272 strcat(MsgTX, "|"); 00273 strcat(MsgTX, AppKey); 00274 strcat(MsgTX, "|"); 00275 strcat(MsgTX, srcEUI); 00276 strcat(MsgTX, "|"); 00277 strcat(MsgTX, MsgRet); 00278 //strcat(MsgTX, ";"); 00279 //MsgRX = "RECIBIDO"; 00280 memcpy(Buffer, MsgTX, sizeof(MsgTX)); 00281 // Se llena el buffer con la informacion a enviar 00282 for( i = sizeof(MsgTX); i < BufferSize; i++ ) { 00283 Buffer[i] = i - sizeof(MsgTX); 00284 } 00285 //dprintf("enviando mensaje a raspberry"); 00286 serRPi.printf("contenido: %s \r\n",msjContent); 00287 Radio->Send( Buffer, BufferSize ); 00288 Radio->Rx( RX_TIMEOUT_VALUE ); 00289 wait_ms( 500 ); 00290 00291 /*Enviar contenido a la raspberry por puerto serial*/ 00292 00293 00294 /***************************************************/ 00295 00296 *led = !*led; 00297 State = LOWPOWER; 00298 break; 00299 case TX: 00300 *led3 = !*led3; 00301 if( isServer == true ) { 00302 //dprintf("Enviando respuesta al nodo" ); 00303 //dprintf("Mensaje a enviar: %s",MsgTX); 00304 } 00305 wait_ms( 500 ); 00306 *led3 = !*led3; 00307 Radio->Rx( RX_TIMEOUT_VALUE ); 00308 State = LOWPOWER; 00309 break; 00310 case RX_TIMEOUT: 00311 00312 Radio->Rx( RX_TIMEOUT_VALUE ); 00313 State = LOWPOWER; 00314 break; 00315 case RX_ERROR: 00316 // We have received a Packet with a CRC error, send reply as if packet was correct 00317 /*strcpy(MsgRet,"ERROR"); 00318 strcpy(MsgTX, EUI); 00319 strcat(MsgTX, "|"); 00320 strcat(MsgTX, AppEUI); 00321 strcat(MsgTX, "|"); 00322 strcat(MsgTX, AppKey); 00323 strcat(MsgTX, "|"); 00324 strcat(MsgTX, "A010"); 00325 strcat(MsgTX, "|"); 00326 strcat(MsgTX, MsgRet); 00327 //MsgRX = "ERROR"; 00328 if( isServer == true ) { 00329 // Se llena el buffer para el envio del error 00330 memcpy(Buffer, MsgTX, sizeof(MsgTX)); 00331 for( i = sizeof(MsgTX); i < BufferSize; i++ ) { 00332 Buffer[i] = i - sizeof(MsgTX); 00333 } 00334 wait_ms( 1000 ); 00335 Radio->Send( Buffer, BufferSize ); 00336 }*/ 00337 Radio->Rx( RX_TIMEOUT_VALUE ); 00338 State = LOWPOWER; 00339 break; 00340 case TX_TIMEOUT: 00341 Radio->Rx( RX_TIMEOUT_VALUE ); 00342 State = LOWPOWER; 00343 break; 00344 case LOWPOWER: 00345 sleep(); 00346 break; 00347 default: 00348 State = LOWPOWER; 00349 break; 00350 } 00351 } 00352 } 00353 00354 char *splitOnPosition(char *msj, int pos) 00355 { 00356 00357 int i=0; 00358 char *substring = strtok (msj,"|"); 00359 char *strOutput=""; 00360 while (substring != NULL) { 00361 //dprintf ("substring: %s, index: %d",substring,i); 00362 00363 if(i == 0) { 00364 srcEUI = substring; 00365 } else if(i == 3) { 00366 msjDestEUI = substring; 00367 } else if(i == 4) { 00368 msjContent = substring; 00369 } else if(i > 4) { 00370 strcat(msjContent," "); 00371 strcat(msjContent,substring); 00372 //dprintf ("contenido: %s, substring: %s, i: %d",msjContent, substring, i); 00373 } 00374 substring = strtok (NULL, "|"); 00375 i++; 00376 } 00377 return strOutput; 00378 } 00379 00380 void OnTxDone(void *radio, void *userThisPtr, void *userData) 00381 { 00382 Radio->Sleep( ); 00383 State = TX; 00384 if (DEBUG_MESSAGE) 00385 dprintf("> OnTxDone"); 00386 } 00387 00388 void OnRxDone(void *radio, void *userThisPtr, void *userData, uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) 00389 { 00390 Radio->Sleep( ); 00391 BufferSize = size; 00392 memcpy( Buffer, payload, BufferSize ); 00393 State = RX; 00394 if (DEBUG_MESSAGE) 00395 dprintf("> OnRxDone: RssiValue=%d dBm, SnrValue=%d", rssi, snr); 00396 //dump("Data:", payload, size); 00397 strcpy(MsgRX,(char*)payload); 00398 //dprintf("Msj: %s", MsgRX); 00399 } 00400 00401 void OnTxTimeout(void *radio, void *userThisPtr, void *userData) 00402 { 00403 *led3 = 0; 00404 Radio->Sleep( ); 00405 State = TX_TIMEOUT; 00406 if(DEBUG_MESSAGE) 00407 dprintf("> OnTxTimeout"); 00408 } 00409 00410 void OnRxTimeout(void *radio, void *userThisPtr, void *userData) 00411 { 00412 *led3 = 0; 00413 Radio->Sleep( ); 00414 Buffer[BufferSize-1] = 0; 00415 State = RX_TIMEOUT; 00416 if (DEBUG_MESSAGE) 00417 dprintf("> OnRxTimeout"); 00418 } 00419 00420 void OnRxError(void *radio, void *userThisPtr, void *userData) 00421 { 00422 Radio->Sleep( ); 00423 State = RX_ERROR; 00424 if (DEBUG_MESSAGE) 00425 dprintf("> OnRxError"); 00426 } 00427 00428 #endif
Generated on Fri Jul 15 2022 20:51:17 by
