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