Helmut Tschemernjak / Mbed 2 deprecated Turtle_RadioShuttle

Dependencies:   mbed BufferedSerial SX1276GenericLib OLED_SSD1306 HELIOS_Si7021 NVProperty RadioShuttle-STM32L4 USBDeviceHT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RadioTestSample.cpp Source File

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