add senet packet format

Dependencies:   Senet_Packet mDot_X_NUCLEO_IKS01A1 libmDot-dev-mbed5-deprecated

Fork of mDot-IKS01A1 by Peter Ferland

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "mDot.h"
00003 #include "x_nucleo_iks01a1.h"
00004 #include "dot_util.h"
00005 #include "RadioEvent.h"
00006 #include "senet_packet.h"
00007 #include <cmath>
00008 
00009 // mDot UDK board demo with X-NUCLEO-IKS01A1 sensor card
00010 // For more examples see the Dot-Examples project:
00011 // https://developer.mbed.org/teams/MultiTech/code/Dot-Examples/
00012 
00013 // This triggers an I2C issue in mbed-os 5.1.5
00014 // Use any other revision to compile. (Tested with libmDot-dev/mbed-os 5.2.2
00015 #define SENET
00016 #ifdef ACTILITY
00017 // Network Id for Senet public network
00018 static uint8_t network_id[] = {0xF0, 0x3D, 0x29,0xAC,0x71,0x00,0x00, 0x00};
00019 // Register at or Sign in to http://portal.senetco.com/ and register your NodeId to receive your AppId
00020 // {0xD3,0x5A,0x30,0x60,0xA6,0x0D,0x9E,0xEA,0xD9,0xA1,0x19,0x61,0x4F,0x29,0x9E,0x5B}
00021 static uint8_t network_key[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //{0xD3,0x5A,0x30,0x60,0xA6,0x0D,0x9E,0xEA,0xD9,0xA1,0x19,0x61,0x4F,0x29,0x9E,0x5B};
00022 static uint8_t frequency_sub_band = 0;
00023 static bool public_network = true;
00024 #elif defined(SENET)
00025 // Network Id for Senet public network
00026 static uint8_t network_id[] = { 0x00, 0x25, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x01 };
00027 // Register at or Sign in to http://portal.senetco.com/ and register your NodeId to receive your AppId
00028 // {0xD3,0x5A,0x30,0x60,0xA6,0x0D,0x9E,0xEA,0xD9,0xA1,0x19,0x61,0x4F,0x29,0x9E,0x5B}
00029 static uint8_t network_key[] =  { 0xFD, 0x68, 0xE9, 0xB5, 0x7C, 0xCA, 0x5E, 0xD6, 0xAD, 0xF6, 0x23, 0xCB, 0x03, 0x26, 0x68, 0xF4 };
00030 // 1 For Senet, configurable on your Conduit
00031 static uint8_t frequency_sub_band = 0;
00032 // True for Senet, false for your Conduit.
00033 static bool public_network = true;
00034 #else
00035 //Replace with settings on your Conduit
00036 static std::string network_name = "EcoLabTest";
00037 static std::string network_passphrase = "EcoLabTest"; 
00038 // 1 For Senet, configurable on your Conduit
00039 static uint8_t frequency_sub_band = 1;
00040 // True for Senet, false for your Conduit.
00041 static bool public_network = false;
00042 #endif
00043 static uint8_t ack = 0;
00044 static uint8_t tx_datarate = mDot::SF_7;
00045 
00046 // deepsleep consumes slightly less current than sleep
00047 // in sleep mode, IO state is maintained, RAM is retained, and application will resume after waking up
00048 // in deepsleep mode, IOs float, RAM is lost, and application will start from beginning after waking up
00049 // if deep_sleep == true, device will enter deepsleep mode
00050 static bool deep_sleep = false;
00051 
00052 mDot *dot = NULL;
00053 
00054 int main()
00055 {
00056     Serial pc(USBTX, USBRX);
00057     
00058     /* Instantiate the expansion board */
00059     X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(I2C_SDA, I2C_SCL, PC_1);
00060     
00061     /* Retrieve the composing elements of the expansion board */
00062     GyroSensor *gyroscope = mems_expansion_board->GetGyroscope();
00063     MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer();
00064     MagneticSensor *magnetometer = mems_expansion_board->magnetometer;
00065     HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;
00066     PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor;
00067     TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor;
00068     TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor;
00069     // Custom event handler for automatically displaying RX data
00070     RadioEvent events;
00071     pc.baud(115200);
00072 
00073     /* Initialize mDot */
00074     dot = mDot::getInstance();
00075 
00076     //dot->setAdr(true);
00077     mts::MTSLog::setLogLevel(mts::MTSLog::INFO_LEVEL);
00078     dot->setEvents(&events);
00079     
00080 
00081     if (!dot->getStandbyFlag()) {
00082         logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
00083         // start from a well-known state
00084         logInfo("defaulting Dot configuration");
00085         dot->resetConfig();
00086         dot->resetNetworkSession();
00087         
00088         // update configuration if necessary
00089         // in AUTO_OTA mode the session is automatically saved, so saveNetworkSession and restoreNetworkSession are not needed
00090         if (dot->getJoinMode() != mDot::AUTO_OTA) {
00091             logInfo("changing network join mode to AUTO_OTA");
00092             if (dot->setJoinMode(mDot::AUTO_OTA) != mDot::MDOT_OK) {
00093                 logError("failed to set network join mode to AUTO_OTA");
00094             }
00095         }
00096         
00097         uint32_t current_tx_datarate = dot->getTxDataRate();
00098         if (current_tx_datarate != tx_datarate) {
00099             logInfo("changing TX datarate from %u to %u", current_tx_datarate, tx_datarate);
00100             if (dot->setTxDataRate(tx_datarate) != mDot::MDOT_OK) {
00101                 logError("failed to set TX datarate to %u", tx_datarate);
00102             }
00103         }
00104         // in OTA and AUTO_OTA join modes, the credentials can be passed to the library as a name and passphrase or an ID and KEY
00105         // only one method or the other should be used!
00106         // network ID = crc64(network name)
00107 #if defined(SENET) || defined(ACTILITY)
00108         // network KEY = cmac(network passphrase)
00109         update_ota_config_id_key(network_id, network_key, frequency_sub_band, public_network, ack);
00110 #else
00111         update_ota_config_name_phrase(network_name, network_passphrase, frequency_sub_band, public_network, ack);
00112 #endif
00113         
00114         // configure network link checks
00115         // network link checks are a good alternative to requiring the gateway to ACK every packet and should allow a single gateway to handle more Dots
00116         // check the link every count packets
00117         // declare the Dot disconnected after threshold failed link checks
00118         // for count = 3 and threshold = 5, the Dot will be considered disconnected after 15 missed packets in a row
00119         update_network_link_check_config(3, 5);
00120         
00121         // save changes to configuration
00122         logInfo("saving configuration");
00123         if (!dot->saveConfig()) {
00124             logError("failed to save configuration");
00125         }
00126     
00127         // display configuration
00128         display_config();
00129     }  else {
00130         // restore the saved session if the dot woke from deepsleep mode
00131         // useful to use with deepsleep because session info is otherwise lost when the dot enters deepsleep
00132         logInfo("restoring network session from NVM");
00133         dot->restoreNetworkSession();
00134     }
00135 
00136 
00137     
00138     while (true) {
00139         // join network if not joined
00140         if (!dot->getNetworkJoinStatus()) {
00141             join_network();
00142         }
00143 
00144         // Payload structure for mydevices cayenne:
00145         // 1 byte Data1 ID
00146         // 1 Byte Data1 Type
00147         // N Bytes Data1 
00148         // 1 byte data 2 ID
00149         // 1 byte data 2 type
00150         // n Bytes data 2
00151         // ... 
00152         
00153         // formats:
00154         // Temperature sensor:
00155         /*
00156          * IPSO: 3303
00157          * LPP 103
00158          * HEX: 67
00159          * Data size: 2
00160          * Resolution: 0.1 degres C
00161          
00162          * Humidity sensor
00163          * IPSO: 3304
00164          * LPP: 104
00165          * Hex: 68
00166          * Datasize: 1
00167          * Resolution: 0.5% unsigned
00168          
00169          * Barometer/pressure sensor
00170          * IPSO: 3315
00171          * LPP: 115
00172          * Hex: 73
00173          * Datasize: 2
00174          * Resolution 0.1hPa unsigned MSB
00175          
00176          * Accelerometer
00177          * IPSO: 3313
00178          * LPP: 113
00179          * Hex: 71
00180          * Data size: 6
00181          * Resolution: 0.001G signed MSB per axis
00182          
00183          * Gyrometer
00184          * IPSO: 3334
00185          * LPP: 134
00186          * Hex: 86
00187          * Data size: 6
00188          * Resolution: 0.01 degrees/s signed msb per axis
00189         */
00190         
00191         /*
00192         //temp floats
00193         float value1, value2;
00194         
00195         // HTS221 Humidity sensor
00196         temp_sensor1->GetTemperature(&value1);
00197         humidity_sensor->GetHumidity(&value2);
00198         
00199         //serialize data and append to packet
00200         // Cayenne data: temperature; tag is 0x67, 2 bytes signed, 0.1 C/bit
00201         tx_data.push_back(uint8_t(1)); // data id
00202         tx_data.push_back(uint8_t(0x67)); // data type - temp
00203         int16_t temp = floor(value1*10 + 0.5f);
00204         logInfo("Temp payload: %d", temp);
00205         tx_data.push_back(uint8_t( 0xFF & (temp >> 8)));
00206         tx_data.push_back(uint8_t(0xFF & temp));
00207         
00208         
00209         tx_data.push_back(uint8_t(2)); // data id
00210         tx_data.push_back(uint8_t(0x68)); // data type - humidity
00211         temp = floor(value2 * 2.0f + 0.5f);
00212         tx_data.push_back(uint8_t(0xFF & temp ));
00213 
00214         logInfo("Temperature data %f", value1);
00215         logInfo("Humidity data: %f", value2);
00216         
00217         pressure_sensor->GetPressure(&value1);
00218         logInfo("PRessure data: %f", value1);
00219         // pressure is reported in mbar, cayenne wants it in 0.1 hPa
00220         // 1mbar = 1 hPa
00221         temp = floor(value1 * 100.0f + 0.5f);
00222         tx_data.push_back(uint8_t(3)); // data id
00223         tx_data.push_back(uint8_t(0x73)); // data type - pressure
00224         temp = floor(value1 / 0.1f + 0.5f);
00225         tx_data.push_back(uint8_t(0xFF & (temp >> 8)));
00226         tx_data.push_back(uint8_t(0xFF & temp));
00227         
00228         
00229         // Get accelerometer data
00230         int32_t accel_vector[3];
00231         // returns in mG
00232         accelerometer->Get_X_Axes(accel_vector);
00233         logInfo("Acclerometer Z axis: %d", accel_vector[2]);
00234         
00235         tx_data.push_back(uint8_t(4)); // data id
00236         tx_data.push_back(uint8_t(0x71)); // data type - accelerometer
00237         for(int i=0; i<3; i++){
00238             tx_data.push_back(uint8_t(0xFF & accel_vector[i]) >> 8);
00239             tx_data.push_back(uint8_t(0xFF & accel_vector[i]));
00240         }
00241         
00242         // Get gyro data
00243         gyroscope->Get_G_Axes(accel_vector);
00244         // gyro reports in milidegrees/sec, cayenne wants centidegrees/sec
00245         tx_data.push_back(uint8_t(5)); //data id
00246         tx_data.push_back(uint8_t(0x86)); // data type - gyrometer
00247         for(int i=0; i<3; i++){
00248             accel_vector[i] /= 10;
00249             tx_data.push_back(uint8_t(0xFF & (accel_vector[i] >> 8)));
00250             tx_data.push_back(uint8_t(0xFF & accel_vector[i]));
00251         }
00252         */
00253         
00254         std::vector<uint8_t> tx_data;
00255         uint8_t buffer[64];
00256         float value;
00257         
00258         SensorPacket packet(buffer, sizeof(buffer));
00259         
00260         // get temperature
00261         temp_sensor1->GetTemperature(&value);
00262         logInfo("temperature: %2.1f C", value);
00263         packet.addSensorValue(0, 2, (int16_t)(value*10));
00264         packet.serialize();
00265         
00266         tx_data.assign(packet.payload(), packet.payload() + packet.length());
00267         send_data(tx_data);
00268         
00269         if(deep_sleep){
00270         // if going into deepsleep mode, save the session so we don't need to join again after waking up
00271         // not necessary if going into sleep mode since RAM is retained
00272             logInfo("saving network session to NVM");
00273             dot->saveNetworkSession();
00274         }
00275         
00276 
00277         // ONLY ONE of the three functions below should be uncommented depending on the desired wakeup method
00278         //sleep_wake_rtc_only(deep_sleep);
00279         //sleep_wake_interrupt_only(deep_sleep);
00280         //sleep_wake_rtc_or_interrupt(deep_sleep);
00281         
00282         wait(5);
00283         
00284     }
00285 
00286     return 0;    
00287 }