add senet packet format
Dependencies: Senet_Packet mDot_X_NUCLEO_IKS01A1 libmDot-dev-mbed5-deprecated
Fork of mDot-IKS01A1 by
main.cpp
- Committer:
- mfiore
- Date:
- 2017-04-07
- Revision:
- 13:3a0a00664054
- Parent:
- 12:922bb95e4c2e
File content as of revision 13:3a0a00664054:
#include "mbed.h"
#include "mDot.h"
#include "x_nucleo_iks01a1.h"
#include "dot_util.h"
#include "RadioEvent.h"
#include "senet_packet.h"
#include <cmath>
// mDot UDK board demo with X-NUCLEO-IKS01A1 sensor card
// For more examples see the Dot-Examples project:
// https://developer.mbed.org/teams/MultiTech/code/Dot-Examples/
// This triggers an I2C issue in mbed-os 5.1.5
// Use any other revision to compile. (Tested with libmDot-dev/mbed-os 5.2.2
#define SENET
#ifdef ACTILITY
// Network Id for Senet public network
static uint8_t network_id[] = {0xF0, 0x3D, 0x29,0xAC,0x71,0x00,0x00, 0x00};
// Register at or Sign in to http://portal.senetco.com/ and register your NodeId to receive your AppId
// {0xD3,0x5A,0x30,0x60,0xA6,0x0D,0x9E,0xEA,0xD9,0xA1,0x19,0x61,0x4F,0x29,0x9E,0x5B}
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};
static uint8_t frequency_sub_band = 0;
static bool public_network = true;
#elif defined(SENET)
// Network Id for Senet public network
static uint8_t network_id[] = { 0x00, 0x25, 0x0C, 0x00, 0x00, 0x01, 0x00, 0x01 };
// Register at or Sign in to http://portal.senetco.com/ and register your NodeId to receive your AppId
// {0xD3,0x5A,0x30,0x60,0xA6,0x0D,0x9E,0xEA,0xD9,0xA1,0x19,0x61,0x4F,0x29,0x9E,0x5B}
static uint8_t network_key[] = { 0xFD, 0x68, 0xE9, 0xB5, 0x7C, 0xCA, 0x5E, 0xD6, 0xAD, 0xF6, 0x23, 0xCB, 0x03, 0x26, 0x68, 0xF4 };
// 1 For Senet, configurable on your Conduit
static uint8_t frequency_sub_band = 0;
// True for Senet, false for your Conduit.
static bool public_network = true;
#else
//Replace with settings on your Conduit
static std::string network_name = "EcoLabTest";
static std::string network_passphrase = "EcoLabTest";
// 1 For Senet, configurable on your Conduit
static uint8_t frequency_sub_band = 1;
// True for Senet, false for your Conduit.
static bool public_network = false;
#endif
static uint8_t ack = 0;
static uint8_t tx_datarate = mDot::SF_7;
// deepsleep consumes slightly less current than sleep
// in sleep mode, IO state is maintained, RAM is retained, and application will resume after waking up
// in deepsleep mode, IOs float, RAM is lost, and application will start from beginning after waking up
// if deep_sleep == true, device will enter deepsleep mode
static bool deep_sleep = false;
mDot *dot = NULL;
int main()
{
Serial pc(USBTX, USBRX);
/* Instantiate the expansion board */
X_NUCLEO_IKS01A1 *mems_expansion_board = X_NUCLEO_IKS01A1::Instance(I2C_SDA, I2C_SCL, PC_1);
/* Retrieve the composing elements of the expansion board */
GyroSensor *gyroscope = mems_expansion_board->GetGyroscope();
MotionSensor *accelerometer = mems_expansion_board->GetAccelerometer();
MagneticSensor *magnetometer = mems_expansion_board->magnetometer;
HumiditySensor *humidity_sensor = mems_expansion_board->ht_sensor;
PressureSensor *pressure_sensor = mems_expansion_board->pt_sensor;
TempSensor *temp_sensor1 = mems_expansion_board->ht_sensor;
TempSensor *temp_sensor2 = mems_expansion_board->pt_sensor;
// Custom event handler for automatically displaying RX data
RadioEvent events;
pc.baud(115200);
/* Initialize mDot */
dot = mDot::getInstance();
//dot->setAdr(true);
mts::MTSLog::setLogLevel(mts::MTSLog::INFO_LEVEL);
dot->setEvents(&events);
if (!dot->getStandbyFlag()) {
logInfo("mbed-os library version: %d", MBED_LIBRARY_VERSION);
// start from a well-known state
logInfo("defaulting Dot configuration");
dot->resetConfig();
dot->resetNetworkSession();
// update configuration if necessary
// in AUTO_OTA mode the session is automatically saved, so saveNetworkSession and restoreNetworkSession are not needed
if (dot->getJoinMode() != mDot::AUTO_OTA) {
logInfo("changing network join mode to AUTO_OTA");
if (dot->setJoinMode(mDot::AUTO_OTA) != mDot::MDOT_OK) {
logError("failed to set network join mode to AUTO_OTA");
}
}
uint32_t current_tx_datarate = dot->getTxDataRate();
if (current_tx_datarate != tx_datarate) {
logInfo("changing TX datarate from %u to %u", current_tx_datarate, tx_datarate);
if (dot->setTxDataRate(tx_datarate) != mDot::MDOT_OK) {
logError("failed to set TX datarate to %u", tx_datarate);
}
}
// 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
// only one method or the other should be used!
// network ID = crc64(network name)
#if defined(SENET) || defined(ACTILITY)
// network KEY = cmac(network passphrase)
update_ota_config_id_key(network_id, network_key, frequency_sub_band, public_network, ack);
#else
update_ota_config_name_phrase(network_name, network_passphrase, frequency_sub_band, public_network, ack);
#endif
// configure network link checks
// 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
// check the link every count packets
// declare the Dot disconnected after threshold failed link checks
// for count = 3 and threshold = 5, the Dot will be considered disconnected after 15 missed packets in a row
update_network_link_check_config(3, 5);
// save changes to configuration
logInfo("saving configuration");
if (!dot->saveConfig()) {
logError("failed to save configuration");
}
// display configuration
display_config();
} else {
// restore the saved session if the dot woke from deepsleep mode
// useful to use with deepsleep because session info is otherwise lost when the dot enters deepsleep
logInfo("restoring network session from NVM");
dot->restoreNetworkSession();
}
while (true) {
// join network if not joined
if (!dot->getNetworkJoinStatus()) {
join_network();
}
// Payload structure for mydevices cayenne:
// 1 byte Data1 ID
// 1 Byte Data1 Type
// N Bytes Data1
// 1 byte data 2 ID
// 1 byte data 2 type
// n Bytes data 2
// ...
// formats:
// Temperature sensor:
/*
* IPSO: 3303
* LPP 103
* HEX: 67
* Data size: 2
* Resolution: 0.1 degres C
* Humidity sensor
* IPSO: 3304
* LPP: 104
* Hex: 68
* Datasize: 1
* Resolution: 0.5% unsigned
* Barometer/pressure sensor
* IPSO: 3315
* LPP: 115
* Hex: 73
* Datasize: 2
* Resolution 0.1hPa unsigned MSB
* Accelerometer
* IPSO: 3313
* LPP: 113
* Hex: 71
* Data size: 6
* Resolution: 0.001G signed MSB per axis
* Gyrometer
* IPSO: 3334
* LPP: 134
* Hex: 86
* Data size: 6
* Resolution: 0.01 degrees/s signed msb per axis
*/
/*
//temp floats
float value1, value2;
// HTS221 Humidity sensor
temp_sensor1->GetTemperature(&value1);
humidity_sensor->GetHumidity(&value2);
//serialize data and append to packet
// Cayenne data: temperature; tag is 0x67, 2 bytes signed, 0.1 C/bit
tx_data.push_back(uint8_t(1)); // data id
tx_data.push_back(uint8_t(0x67)); // data type - temp
int16_t temp = floor(value1*10 + 0.5f);
logInfo("Temp payload: %d", temp);
tx_data.push_back(uint8_t( 0xFF & (temp >> 8)));
tx_data.push_back(uint8_t(0xFF & temp));
tx_data.push_back(uint8_t(2)); // data id
tx_data.push_back(uint8_t(0x68)); // data type - humidity
temp = floor(value2 * 2.0f + 0.5f);
tx_data.push_back(uint8_t(0xFF & temp ));
logInfo("Temperature data %f", value1);
logInfo("Humidity data: %f", value2);
pressure_sensor->GetPressure(&value1);
logInfo("PRessure data: %f", value1);
// pressure is reported in mbar, cayenne wants it in 0.1 hPa
// 1mbar = 1 hPa
temp = floor(value1 * 100.0f + 0.5f);
tx_data.push_back(uint8_t(3)); // data id
tx_data.push_back(uint8_t(0x73)); // data type - pressure
temp = floor(value1 / 0.1f + 0.5f);
tx_data.push_back(uint8_t(0xFF & (temp >> 8)));
tx_data.push_back(uint8_t(0xFF & temp));
// Get accelerometer data
int32_t accel_vector[3];
// returns in mG
accelerometer->Get_X_Axes(accel_vector);
logInfo("Acclerometer Z axis: %d", accel_vector[2]);
tx_data.push_back(uint8_t(4)); // data id
tx_data.push_back(uint8_t(0x71)); // data type - accelerometer
for(int i=0; i<3; i++){
tx_data.push_back(uint8_t(0xFF & accel_vector[i]) >> 8);
tx_data.push_back(uint8_t(0xFF & accel_vector[i]));
}
// Get gyro data
gyroscope->Get_G_Axes(accel_vector);
// gyro reports in milidegrees/sec, cayenne wants centidegrees/sec
tx_data.push_back(uint8_t(5)); //data id
tx_data.push_back(uint8_t(0x86)); // data type - gyrometer
for(int i=0; i<3; i++){
accel_vector[i] /= 10;
tx_data.push_back(uint8_t(0xFF & (accel_vector[i] >> 8)));
tx_data.push_back(uint8_t(0xFF & accel_vector[i]));
}
*/
std::vector<uint8_t> tx_data;
uint8_t buffer[64];
float value;
SensorPacket packet(buffer, sizeof(buffer));
// get temperature
temp_sensor1->GetTemperature(&value);
logInfo("temperature: %2.1f C", value);
packet.addSensorValue(0, 2, (int16_t)(value*10));
packet.serialize();
tx_data.assign(packet.payload(), packet.payload() + packet.length());
send_data(tx_data);
if(deep_sleep){
// if going into deepsleep mode, save the session so we don't need to join again after waking up
// not necessary if going into sleep mode since RAM is retained
logInfo("saving network session to NVM");
dot->saveNetworkSession();
}
// ONLY ONE of the three functions below should be uncommented depending on the desired wakeup method
//sleep_wake_rtc_only(deep_sleep);
//sleep_wake_interrupt_only(deep_sleep);
//sleep_wake_rtc_or_interrupt(deep_sleep);
wait(5);
}
return 0;
}
