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: mbed BufferedSerial SX1276GenericLib OLED_SSD1306 HELIOS_Si7021 NVProperty RadioShuttle-STM32L4 USBDeviceHT
RadioTestSample.cpp
00001 /* 00002 * The file is Licensed under the Apache License, Version 2.0 00003 * (c) 2017 Helmut Tschemernjak 00004 * 30826 Garbsen (Hannover) Germany 00005 */ 00006 00007 #include "mbed.h" 00008 #include "PinMap.h" 00009 00010 #if defined(FEATURE_LORA) && defined(FEATURE_RADIOTESTSAMPLE) 00011 00012 #include "sx1276-mbed-hal.h" 00013 #include "RadioShuttle.h" 00014 #include "RadioStatus.h" 00015 #include "RadioSecurity.h" 00016 #include "main.h" 00017 #ifdef FEATURE_NVPROPERTY 00018 #include <NVPropertyProviderInterface.h> 00019 #include "NVProperty.h" 00020 #endif 00021 00022 00023 00024 #define CHECK_ERROR_RET(func, err) { \ 00025 if (err) { \ 00026 dprintf("Error in %s: %s", func, rs->StrError(err)); \ 00027 return err; \ 00028 } \ 00029 } 00030 00031 // #define RADIO_SERVER 1 00032 00033 00034 bool usePassword = false; // password the can used indepenend of AES 00035 bool server; // automatically being set if radioTypeMode RadioShuttle::RS_Station_Basic 00036 bool useAES = false; // AES needs the usePassword option on 00037 const char *appPassword; // the AES password 00038 00039 static const int myTempSensorApp = 0x0001; // Must be unique world wide. 00040 #ifdef RADIO_SERVER 00041 int myDeviceID = 1; 00042 int remoteDeviceID = 14; 00043 uint32_t myCode = 0; 00044 RadioShuttle::RadioType radioTypeMode = RadioShuttle::RS_Station_Basic; // 1 = RS_Node_Offline, 3 = RS_Node_Online, 4 = RS_Station_Basic 00045 #else 00046 int myDeviceID = 14; 00047 int remoteDeviceID = 1; 00048 uint32_t myCode = 0; 00049 RadioShuttle::RadioType radioTypeMode = RadioShuttle::RS_Node_Offline; // 1 = RS_Node_Offline, 3 = RS_Node_Online, 4 = RS_Station_Basic 00050 #endif 00051 00052 00053 /* 00054 * For details review: SX1276GenericLib/sx1276/sx1276.h 00055 * Supported spreading factors SF 7,8, 9, 10, 11, (12 does not work well) 00056 * Working frequencies using the 125000 bandwidth which leaves 00057 * sufficient distance to the neighbour channel 00058 * EU: 868.1, 868.3, 868.5 (Default LoRaWAN EU channels) 00059 * EU: 865.1, 865.3, 865.5, 865.7, 865.9 (additional channels) 00060 * EU: 866.1, 866.3, 866.5, 866.7, 866.9 (additional channels) 00061 * EU: 867.1, 867.3, 867.5, 867.7, 867.9 (additional channels) 00062 * Utilisation of these channels should not exceed 1% per hour per node 00063 * Bandwidth changes other than 125k requires different channels distances 00064 */ 00065 RadioShuttle::RadioProfile myProfile[] = { 00066 /* 00067 * Our default profile 00068 * frequency, bandwidth, TX power, spreading factor, frequency-offset 00069 */ 00070 { 868100000, 125000, 14, 7, 0 }, 00071 { 0, 0, 0, 0, 0 }, 00072 }; 00073 00074 00075 struct sensor { 00076 uint8_t version; 00077 uint8_t padding; 00078 uint16_t pm25; 00079 uint16_t pm10; 00080 uint16_t id; 00081 } PMAppData; 00082 00083 00084 void TempSensorRecvHandler(int AppID, RadioShuttle::devid_t stationID, int msgID, int status, void *buffer, int length) 00085 { 00086 switch(status) { 00087 case RadioShuttle::MS_SentCompleted: // A SendMsg has been sent. 00088 dprintf("MSG_SentCompleted: id=%d %d bytes", msgID, length); 00089 break; 00090 case RadioShuttle::MS_SentCompletedConfirmed:// A SendMsg has been sent and confirmed 00091 dprintf("MSG_SentCompletedConfirmed: id=%d %d bytes", msgID, length); 00092 break; 00093 case RadioShuttle::MS_SentTimeout: // A timeout occurred, number of retries exceeded 00094 dprintf("MSG_SentTimeout ID: %d", msgID); 00095 break; 00096 00097 case RadioShuttle::MS_RecvData: // a simple input message 00098 dprintf("MSG_RecvData ID: %d, len=%d", msgID, length); 00099 // dump("MSG_RecvData", buffer, length); 00100 break; 00101 case RadioShuttle::MS_RecvDataConfirmed: // received a confirmed message 00102 dprintf("MSG_RecvDataConfirmed ID: %d, len=%d", msgID, length); 00103 // dump("MSG_RecvDataConfirmed", buffer, length); 00104 break; 00105 case RadioShuttle::MS_NoStationFound: 00106 dprintf("MSG_NoStationFound"); 00107 break; 00108 case RadioShuttle::MS_NoStationSupportsApp: 00109 dprintf("MSG_NoStationSupportsApp"); 00110 break; 00111 case RadioShuttle::MS_AuthenicationRequired: // the password does not match. 00112 dprintf("MSG_AuthenicationRequired"); 00113 break; 00114 00115 case RadioShuttle::MS_StationConnected: // a confirmation that the connection was accepted 00116 dprintf("MSG_StationConnected"); 00117 break; 00118 case RadioShuttle::MS_StationDisconnected: // a confirmation that the disconnect was accepted 00119 dprintf("MSG_StationDisconnected"); 00120 break; 00121 default: 00122 break; 00123 } 00124 } 00125 00126 00127 Radio *radio; 00128 RadioShuttle *rs; 00129 RadioStatusInterface *statusIntf; 00130 RadioSecurityInterface *securityIntf; 00131 00132 int InitRadio() 00133 { 00134 Radio *radio; 00135 RSCode err; 00136 00137 #ifdef FEATURE_NVPROPERTY 00138 NVProperty prop; 00139 int value; 00140 00141 myDeviceID = prop.GetProperty(prop.LORA_DEVICE_ID, 0); 00142 myCode = prop.GetProperty(prop.LORA_CODE_ID, 0); 00143 if ((value = prop.GetProperty(prop.LORA_RADIO_TYPE, 0)) != 0) 00144 radioTypeMode = (RadioShuttle::RadioType)value; 00145 00146 if (myDeviceID == 0 || myCode == 0 || radioTypeMode == 0) { 00147 dprintf("LORA_DEVICE_ID or LORA_CODE_ID or LORA_RADIO_TYPE not set, use PropertyEditor to set this!"); 00148 return -1; 00149 } 00150 /* 00151 * Here are optional properties for custom settings 00152 */ 00153 if ((value = prop.GetProperty(prop.LORA_REMOTE_ID, 0)) != 0) 00154 remoteDeviceID = value; 00155 if ((value = prop.GetProperty(prop.LORA_FREQUENCY, 0)) != 0) 00156 myProfile[0].Frequency = value; 00157 if ((value = prop.GetProperty(prop.LORA_BANDWIDTH, 0)) != 0) 00158 myProfile[0].Bandwidth = value; 00159 if ((value = prop.GetProperty(prop.LORA_SPREADING_FACTOR, 0)) != 0) 00160 myProfile[0].SpreadingFaktor = value; 00161 if ((value = prop.GetProperty(prop.LORA_TXPOWER, 0)) != 0) 00162 myProfile[0].TXPower = value; 00163 if ((value = prop.GetProperty(prop.LORA_FREQUENCY_OFFSET, 0)) != 0) 00164 myProfile[0].FrequencyOffset = value; 00165 appPassword = prop.GetProperty(prop.LORA_APP_PWD, (const char *)NULL); 00166 #endif 00167 00168 if (radioTypeMode >= RadioShuttle::RS_Station_Basic) 00169 server = true; 00170 00171 #ifdef TARGET_DISCO_L072CZ_LRWAN1 00172 radio = new SX1276Generic(NULL, MURATA_SX1276, 00173 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00174 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5, 00175 LORA_ANT_RX, LORA_ANT_TX, LORA_ANT_BOOST, LORA_TCXO); 00176 #elif defined(HELTECL432_REV1) 00177 radio = new SX1276Generic(NULL, HELTEC_L4_1276, 00178 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00179 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5, 00180 LORA_ANT_PWR); 00181 #else // RFM95 00182 radio = new SX1276Generic(NULL, RFM95_SX1276, 00183 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00184 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5); 00185 #endif 00186 00187 00188 statusIntf = new MyRadioStatus(); 00189 securityIntf = new RadioSecurity(); 00190 00191 rs = new RadioShuttle("MyRadioShuttle"); 00192 00193 rs->EnablePacketTrace(RadioShuttle::DEV_ID_ANY, true, true); 00194 00195 err = rs->AddLicense(myDeviceID, myCode); 00196 CHECK_ERROR_RET("AddLicense", err); 00197 00198 err = rs->AddRadio(radio, MODEM_LORA, myProfile); 00199 CHECK_ERROR_RET("AddRadio", err); 00200 dprintf("Radio: %.1f MHz, SF%d, %.f kHz", (float)myProfile[0].Frequency/1000000.0, myProfile[0].SpreadingFaktor, (float)myProfile[0].Bandwidth/1000.0); 00201 00202 rs->AddRadioStatus(statusIntf); 00203 CHECK_ERROR_RET("AddRadioStatus", err); 00204 00205 rs->AddRadioSecurity(securityIntf); 00206 CHECK_ERROR_RET("AddRadioSecurity", err); 00207 00208 /* 00209 * The password parameter can be NULL if no password is required 00210 */ 00211 err = rs->RegisterApplication(myTempSensorApp, &TempSensorRecvHandler, (void *)appPassword); 00212 CHECK_ERROR_RET("RegisterApplication", err); 00213 00214 if (server) { 00215 // usually RadioShuttle::RS_Station_Basic, set via properties 00216 err = rs->Startup(radioTypeMode); 00217 dprintf("Startup as a Server: %s ID=%d", rs->GetRadioName(rs->GetRadioType()), myDeviceID); 00218 } else { 00219 // usually RadioShuttle::RS_Node_Online or RadioShuttle, set via properties 00220 err = rs->Startup(radioTypeMode); 00221 dprintf("Startup as a Node: %s ID=%d", rs->GetRadioName(rs->GetRadioType()), myDeviceID); 00222 if (!err && rs->AppRequiresAuthentication(myTempSensorApp) == RS_PasswordSet) { 00223 err = rs->Connect(myTempSensorApp, remoteDeviceID); 00224 } 00225 } 00226 CHECK_ERROR_RET("Startup", err); 00227 return 0; 00228 } 00229 00230 void DeInitRadio() 00231 { 00232 if (securityIntf) { 00233 delete securityIntf; 00234 securityIntf = NULL; 00235 } 00236 if (statusIntf) { 00237 delete statusIntf; 00238 statusIntf = NULL; 00239 } 00240 if (rs) { 00241 delete rs; 00242 rs = NULL; 00243 } 00244 if (radio) { 00245 delete radio; 00246 radio = NULL; 00247 } 00248 } 00249 00250 00251 int RadioUpdate(bool keyPressed) 00252 { 00253 if (!rs) 00254 return 0; 00255 00256 if (keyPressed) { 00257 int flags = 0; 00258 flags |= RadioShuttle::MF_NeedsConfirm; // optional 00259 if (usePassword && useAES) 00260 flags |= RadioShuttle::MF_Encrypted; 00261 if (server) { 00262 static char msg[] = "The server feels very good today"; 00263 rs->SendMsg(myTempSensorApp, msg, sizeof(msg), flags, remoteDeviceID); 00264 } else { 00265 static char msg[] = "Hello, the temperature is 26 celsius"; 00266 rs->SendMsg(myTempSensorApp, msg, sizeof(msg), flags, remoteDeviceID); 00267 } 00268 } 00269 rs->RunShuttle(); 00270 return 0; 00271 } 00272 00273 bool RadioISIdle() 00274 { 00275 if (!rs) 00276 return true; 00277 return rs->Idle(); 00278 } 00279 00280 void InitLoRaChipWithShutdown() 00281 { 00282 #ifdef LORA_CS 00283 if (LORA_CS == NC) 00284 return; 00285 #ifdef HELTECL432_REV1 00286 Radio *radio = new SX1276Generic(NULL, HELTEC_L4_1276, 00287 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00288 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5, LORA_ANT_PWR); 00289 #else 00290 Radio *radio = new SX1276Generic(NULL, RFM95_SX1276, 00291 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00292 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5); 00293 #endif 00294 00295 RadioEvents_t radioEvents; 00296 memset(&radioEvents, 0, sizeof(radioEvents)); 00297 if (radio->Init(&radioEvents)) { 00298 radio->Sleep(); 00299 delete radio; 00300 } 00301 #endif 00302 } 00303 00304 00305 void RadioContinuesTX(void) 00306 { 00307 Radio *radio; 00308 00309 #ifdef FEATURE_NVPROPERTY 00310 NVProperty prop; 00311 int value; 00312 00313 /* 00314 * Here are optional properties for custom settings 00315 */ 00316 if ((value = prop.GetProperty(prop.LORA_FREQUENCY, 0)) != 0) 00317 myProfile[0].Frequency = value; 00318 if ((value = prop.GetProperty(prop.LORA_TXPOWER, 0)) != 0) 00319 myProfile[0].TXPower = value; 00320 if ((value = prop.GetProperty(prop.LORA_SPREADING_FACTOR, 0)) != 0) 00321 myProfile[0].SpreadingFaktor = value; 00322 #endif 00323 00324 00325 #ifdef TARGET_DISCO_L072CZ_LRWAN1 00326 radio = new SX1276Generic(NULL, MURATA_SX1276, 00327 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00328 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5, 00329 LORA_ANT_RX, LORA_ANT_TX, LORA_ANT_BOOST, LORA_TCXO); 00330 #elif defined(HELTECL432_REV1) 00331 radio = new SX1276Generic(NULL, HELTEC_L4_1276, 00332 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00333 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5, 00334 LORA_ANT_PWR); 00335 #else // RFM95 00336 radio = new SX1276Generic(NULL, RFM95_SX1276, 00337 LORA_SPI_MOSI, LORA_SPI_MISO, LORA_SPI_SCLK, LORA_CS, LORA_RESET, 00338 LORA_DIO0, LORA_DIO1, LORA_DIO2, LORA_DIO3, LORA_DIO4, LORA_DIO5); 00339 #endif 00340 00341 dprintf("RadioContinuesTX test, press reset to abort"); 00342 while(true) { 00343 int secs = 10; 00344 radio->SetTxContinuousWave(myProfile[0].Frequency, myProfile[0].TXPower, secs); 00345 wait_ms(secs * 1000); 00346 rprintf("."); 00347 } 00348 } 00349 00350 #endif // FEATURE_LORA
Generated on Wed Jul 13 2022 12:02:31 by
1.7.2