Sensor Code By Jorge Troncoso
Dependencies: Sensor2 MAX31855-1 libmDot-1
Fork of 0A101_mDot_Sensor_Rev3_AUS by
Diff: radio_sensor.cpp
- Revision:
- 0:1441b10e38a6
- Child:
- 2:0417c5cdceaf
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/radio_sensor.cpp Thu Jan 04 03:42:09 2018 +0000 @@ -0,0 +1,203 @@ +/* +** Because we're working with relatively small packet sizes (~10 bytes) each set +** of sensor data must be split up and sent in multiple packets. To keep track +** of these packets they will each contain a id which indicates the set of +** sensor data they belong to and a sequence number which indicates their +** position in that set of sensor data. The first packet of each set will also +** include and additional field which will be the number of packets to expect. +** This will make it easy to determine if packets have been dropped and +** therefore if the set of sensor data will be valid. +** The packet structure: +** [id (1 byte)] [sequence (1 byte)] [expected packets (1 byte)] [data (n - 3 bytes)] +** [id (1 byte)] [sequence (1 byte)] [data (n - 2 bytes)] +** Note: +** The ID is allowed to and will be expected to overflow back to 0. +*/ + + +#include "radio_sensor.h" + + +mDot* dot = NULL; + +// Network settings. +static uint8_t radio_network_address[] = {0x65, 0x34, 0x03, 0x04}; +static uint8_t radio_network_session_key[] = {0x23, 0x45, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}; +static uint8_t radio_data_session_key[] = {0xF0, 0x34, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}; + +static uint8_t radio_packet_current_id; + + +extern int8_t radio_sensor_init(enum mts::MTSLog::logLevel logging_level) { + uint8_t radio_data_rate, radio_power, radio_frequency_band; + uint32_t radio_frequency; + lora::ChannelPlan* plan; + + + radio_packet_current_id = 0; + + + // Configure the logging level and instatiate the mDot with the correct channel plan. + mts::MTSLog::setLogLevel(logging_level); + +#if RADIO_CHANNEL_PLAN == CP_US915 + plan = new lora::ChannelPlan_US915(); +#elif RADIO_CHANNEL_PLAN == CP_AU915 + plan = new lora::ChannelPlan_AU915(); +#elif RADIO_CHANNEL_PLAN == CP_EU868 + plan = new lora::ChannelPlan_EU868(); +#elif RADIO_CHANNEL_PLAN == CP_KR920 + plan = new lora::ChannelPlan_KR920(); +#elif RADIO_CHANNEL_PLAN == CP_AS923 + plan = new lora::ChannelPlan_AS923(); +#elif RADIO_CHANNEL_PLAN == CP_AS923_JAPAN + plan = new lora::ChannelPlan_AS923_Japan(); +#elif RADIO_CHANNEL_PLAN == CP_IN865 + plan = new lora::ChannelPlan_IN865(); +#endif + assert(plan); + + dot = mDot::getInstance(plan); + assert(dot); + dot->setLogLevel(logging_level); + + // Return the mdot to a known state. + dot->resetConfig(); + + // Configure MDOT network settings. + if (dot->getJoinMode() != mDot::PEER_TO_PEER) { + logInfo("changing network join mode to PEER_TO_PEER"); + if (dot->setJoinMode(mDot::PEER_TO_PEER) != mDot::MDOT_OK) { + logError("failed to set network join mode to PEER_TO_PEER"); + } + } + + radio_frequency_band = dot->getFrequencyBand(); + switch (radio_frequency_band) { + case lora::ChannelPlan::EU868_OLD: + case lora::ChannelPlan::EU868: + // 250kHz channels achieve higher throughput + // DR_6 : SF7 @ 250kHz + // DR_0 - DR_5 (125kHz channels) available but much slower + radio_frequency = 869850000; + radio_data_rate = lora::DR_6; + // the 869850000 frequency is 100% duty cycle if the total power is under 7 dBm - tx power 4 + antenna gain 3 = 7 + radio_power = 4; + break; + + case lora::ChannelPlan::US915_OLD: + case lora::ChannelPlan::US915: + case lora::ChannelPlan::AU915_OLD: + case lora::ChannelPlan::AU915: + // 500kHz channels achieve highest throughput + // DR_8 : SF12 @ 500kHz + // DR_9 : SF11 @ 500kHz + // DR_10 : SF10 @ 500kHz + // DR_11 : SF9 @ 500kHz + // DR_12 : SF8 @ 500kHz + // DR_13 : SF7 @ 500kHz + // DR_0 - DR_3 (125kHz channels) available but much slower + radio_frequency = 915500000; + radio_data_rate = lora::DR_13; + // 915 bands have no duty cycle restrictions, set tx power to max + radio_power = 20; + break; + + case lora::ChannelPlan::AS923: + case lora::ChannelPlan::AS923_JAPAN: + // 250kHz channels achieve higher throughput + // DR_6 : SF7 @ 250kHz + // DR_0 - DR_5 (125kHz channels) available but much slower + radio_frequency = 924800000; + radio_data_rate = lora::DR_6; + radio_power = 16; + break; + + case lora::ChannelPlan::KR920: + // DR_5 : SF7 @ 125kHz + radio_frequency = 922700000; + radio_data_rate = lora::DR_5; + radio_power = 14; + break; + + default: + while (true) { + logFatal("no known channel plan in use - extra configuration is needed!"); + wait(5); + } + } + + update_peer_to_peer_config(radio_network_address, radio_network_session_key, radio_data_session_key, radio_frequency, radio_data_rate, radio_power); + + // Save changes to configuration. + logInfo("saving configuration"); + if (!dot->saveConfig()) { + logError("failed to save configuration"); + } + + // Join network if not joined. + if (!dot->getNetworkJoinStatus()) { + join_network(); + } + + // Display configuration. + display_config(); + + return 0; +} + +extern int8_t radio_sensor_transmit(struct sensor_data_raw data) { + uint8_t packet_length_max, packet_seq, packets_required; + uint8_t tx_buffer[sizeof(struct sensor_data_raw)]; + uint32_t packet_length_data, tx_buffer_size; + std::vector<uint8_t> radio_packet; + + packet_length_max = dot->getMaxPacketLength(); + logDebug("The maximum packet length is %i.", packet_length_max); + + if(packet_length_max < 3) { + logError("The packet length allowed by the mDot is too small (%u).", packet_length_max); + return -1; + } + + + packet_length_data = packet_length_max - 2; + tx_buffer_size = sizeof(struct sensor_data_raw); + // This performs an integer division and round up operation. + packets_required = (tx_buffer_size + packet_length_data - 1) / packet_length_data; + + // Turn the sensor data into a stream of bytes. + serialize_sensor_to_bytes(data, tx_buffer); + + packet_seq = 0; + + // For the first + //radio_packet.push_back(radio_packet_current_id); + //radio_packet.push_back(packet_seq); + //radio_packet.push_back(packets_required); + + for(uint32_t i = 0; i < tx_buffer_size; i++) { + // Current packet finished constructing, send it and begin again. + if(radio_packet.size() >= packet_length_max) { + send_data(radio_packet); + radio_packet.clear(); + + packet_seq++; + + radio_packet.push_back(radio_packet_current_id); + radio_packet.push_back(packet_seq); + } + + radio_packet.push_back(tx_buffer[i]); + } + + // Send the last packet. This will happen if the data is not divisible by the number of required packets. + if(radio_packet.size() > 0) { + send_data(radio_packet); + radio_packet.clear(); + } + + radio_packet_current_id++; + + return 0; +} \ No newline at end of file