a
Dependencies: Sensor2 MAX31855-1 libmDot-1
radio_sensor.cpp@1:2d0abfac692b, 2018-01-04 (annotated)
- Committer:
- jortronm2
- Date:
- Thu Jan 04 03:44:09 2018 +0000
- Revision:
- 1:2d0abfac692b
- Parent:
- 0:1441b10e38a6
1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jortronm2 | 0:1441b10e38a6 | 1 | /* |
jortronm2 | 0:1441b10e38a6 | 2 | ** Because we're working with relatively small packet sizes (~10 bytes) each set |
jortronm2 | 0:1441b10e38a6 | 3 | ** of sensor data must be split up and sent in multiple packets. To keep track |
jortronm2 | 0:1441b10e38a6 | 4 | ** of these packets they will each contain a id which indicates the set of |
jortronm2 | 0:1441b10e38a6 | 5 | ** sensor data they belong to and a sequence number which indicates their |
jortronm2 | 0:1441b10e38a6 | 6 | ** position in that set of sensor data. The first packet of each set will also |
jortronm2 | 0:1441b10e38a6 | 7 | ** include and additional field which will be the number of packets to expect. |
jortronm2 | 0:1441b10e38a6 | 8 | ** This will make it easy to determine if packets have been dropped and |
jortronm2 | 0:1441b10e38a6 | 9 | ** therefore if the set of sensor data will be valid. |
jortronm2 | 0:1441b10e38a6 | 10 | ** The packet structure: |
jortronm2 | 0:1441b10e38a6 | 11 | ** [id (1 byte)] [sequence (1 byte)] [expected packets (1 byte)] [data (n - 3 bytes)] |
jortronm2 | 0:1441b10e38a6 | 12 | ** [id (1 byte)] [sequence (1 byte)] [data (n - 2 bytes)] |
jortronm2 | 0:1441b10e38a6 | 13 | ** Note: |
jortronm2 | 0:1441b10e38a6 | 14 | ** The ID is allowed to and will be expected to overflow back to 0. |
jortronm2 | 0:1441b10e38a6 | 15 | */ |
jortronm2 | 0:1441b10e38a6 | 16 | |
jortronm2 | 0:1441b10e38a6 | 17 | |
jortronm2 | 0:1441b10e38a6 | 18 | #include "radio_sensor.h" |
jortronm2 | 0:1441b10e38a6 | 19 | |
jortronm2 | 0:1441b10e38a6 | 20 | |
jortronm2 | 0:1441b10e38a6 | 21 | mDot* dot = NULL; |
jortronm2 | 0:1441b10e38a6 | 22 | |
jortronm2 | 0:1441b10e38a6 | 23 | // Network settings. |
jortronm2 | 0:1441b10e38a6 | 24 | static uint8_t radio_network_address[] = {0x65, 0x34, 0x03, 0x04}; |
jortronm2 | 0:1441b10e38a6 | 25 | static uint8_t radio_network_session_key[] = {0x23, 0x45, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}; |
jortronm2 | 0:1441b10e38a6 | 26 | static uint8_t radio_data_session_key[] = {0xF0, 0x34, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04, 0x01, 0x02, 0x03, 0x04}; |
jortronm2 | 0:1441b10e38a6 | 27 | |
jortronm2 | 0:1441b10e38a6 | 28 | static uint8_t radio_packet_current_id; |
jortronm2 | 0:1441b10e38a6 | 29 | |
jortronm2 | 0:1441b10e38a6 | 30 | |
jortronm2 | 0:1441b10e38a6 | 31 | extern int8_t radio_sensor_init(enum mts::MTSLog::logLevel logging_level) { |
jortronm2 | 0:1441b10e38a6 | 32 | uint8_t radio_data_rate, radio_power, radio_frequency_band; |
jortronm2 | 0:1441b10e38a6 | 33 | uint32_t radio_frequency; |
jortronm2 | 0:1441b10e38a6 | 34 | lora::ChannelPlan* plan; |
jortronm2 | 0:1441b10e38a6 | 35 | |
jortronm2 | 0:1441b10e38a6 | 36 | |
jortronm2 | 0:1441b10e38a6 | 37 | radio_packet_current_id = 0; |
jortronm2 | 0:1441b10e38a6 | 38 | |
jortronm2 | 0:1441b10e38a6 | 39 | |
jortronm2 | 0:1441b10e38a6 | 40 | // Configure the logging level and instatiate the mDot with the correct channel plan. |
jortronm2 | 0:1441b10e38a6 | 41 | mts::MTSLog::setLogLevel(logging_level); |
jortronm2 | 0:1441b10e38a6 | 42 | |
jortronm2 | 0:1441b10e38a6 | 43 | #if RADIO_CHANNEL_PLAN == CP_US915 |
jortronm2 | 0:1441b10e38a6 | 44 | plan = new lora::ChannelPlan_US915(); |
jortronm2 | 0:1441b10e38a6 | 45 | #elif RADIO_CHANNEL_PLAN == CP_AU915 |
jortronm2 | 0:1441b10e38a6 | 46 | plan = new lora::ChannelPlan_AU915(); |
jortronm2 | 0:1441b10e38a6 | 47 | #elif RADIO_CHANNEL_PLAN == CP_EU868 |
jortronm2 | 0:1441b10e38a6 | 48 | plan = new lora::ChannelPlan_EU868(); |
jortronm2 | 0:1441b10e38a6 | 49 | #elif RADIO_CHANNEL_PLAN == CP_KR920 |
jortronm2 | 0:1441b10e38a6 | 50 | plan = new lora::ChannelPlan_KR920(); |
jortronm2 | 0:1441b10e38a6 | 51 | #elif RADIO_CHANNEL_PLAN == CP_AS923 |
jortronm2 | 0:1441b10e38a6 | 52 | plan = new lora::ChannelPlan_AS923(); |
jortronm2 | 0:1441b10e38a6 | 53 | #elif RADIO_CHANNEL_PLAN == CP_AS923_JAPAN |
jortronm2 | 0:1441b10e38a6 | 54 | plan = new lora::ChannelPlan_AS923_Japan(); |
jortronm2 | 0:1441b10e38a6 | 55 | #elif RADIO_CHANNEL_PLAN == CP_IN865 |
jortronm2 | 0:1441b10e38a6 | 56 | plan = new lora::ChannelPlan_IN865(); |
jortronm2 | 0:1441b10e38a6 | 57 | #endif |
jortronm2 | 0:1441b10e38a6 | 58 | assert(plan); |
jortronm2 | 0:1441b10e38a6 | 59 | |
jortronm2 | 0:1441b10e38a6 | 60 | dot = mDot::getInstance(plan); |
jortronm2 | 0:1441b10e38a6 | 61 | assert(dot); |
jortronm2 | 0:1441b10e38a6 | 62 | dot->setLogLevel(logging_level); |
jortronm2 | 0:1441b10e38a6 | 63 | |
jortronm2 | 0:1441b10e38a6 | 64 | // Return the mdot to a known state. |
jortronm2 | 0:1441b10e38a6 | 65 | dot->resetConfig(); |
jortronm2 | 0:1441b10e38a6 | 66 | |
jortronm2 | 0:1441b10e38a6 | 67 | // Configure MDOT network settings. |
jortronm2 | 0:1441b10e38a6 | 68 | if (dot->getJoinMode() != mDot::PEER_TO_PEER) { |
jortronm2 | 0:1441b10e38a6 | 69 | logInfo("changing network join mode to PEER_TO_PEER"); |
jortronm2 | 0:1441b10e38a6 | 70 | if (dot->setJoinMode(mDot::PEER_TO_PEER) != mDot::MDOT_OK) { |
jortronm2 | 0:1441b10e38a6 | 71 | logError("failed to set network join mode to PEER_TO_PEER"); |
jortronm2 | 0:1441b10e38a6 | 72 | } |
jortronm2 | 0:1441b10e38a6 | 73 | } |
jortronm2 | 0:1441b10e38a6 | 74 | |
jortronm2 | 0:1441b10e38a6 | 75 | radio_frequency_band = dot->getFrequencyBand(); |
jortronm2 | 0:1441b10e38a6 | 76 | switch (radio_frequency_band) { |
jortronm2 | 0:1441b10e38a6 | 77 | case lora::ChannelPlan::EU868_OLD: |
jortronm2 | 0:1441b10e38a6 | 78 | case lora::ChannelPlan::EU868: |
jortronm2 | 0:1441b10e38a6 | 79 | // 250kHz channels achieve higher throughput |
jortronm2 | 0:1441b10e38a6 | 80 | // DR_6 : SF7 @ 250kHz |
jortronm2 | 0:1441b10e38a6 | 81 | // DR_0 - DR_5 (125kHz channels) available but much slower |
jortronm2 | 0:1441b10e38a6 | 82 | radio_frequency = 869850000; |
jortronm2 | 0:1441b10e38a6 | 83 | radio_data_rate = lora::DR_6; |
jortronm2 | 0:1441b10e38a6 | 84 | // the 869850000 frequency is 100% duty cycle if the total power is under 7 dBm - tx power 4 + antenna gain 3 = 7 |
jortronm2 | 0:1441b10e38a6 | 85 | radio_power = 4; |
jortronm2 | 0:1441b10e38a6 | 86 | break; |
jortronm2 | 0:1441b10e38a6 | 87 | |
jortronm2 | 0:1441b10e38a6 | 88 | case lora::ChannelPlan::US915_OLD: |
jortronm2 | 0:1441b10e38a6 | 89 | case lora::ChannelPlan::US915: |
jortronm2 | 0:1441b10e38a6 | 90 | case lora::ChannelPlan::AU915_OLD: |
jortronm2 | 0:1441b10e38a6 | 91 | case lora::ChannelPlan::AU915: |
jortronm2 | 0:1441b10e38a6 | 92 | // 500kHz channels achieve highest throughput |
jortronm2 | 0:1441b10e38a6 | 93 | // DR_8 : SF12 @ 500kHz |
jortronm2 | 0:1441b10e38a6 | 94 | // DR_9 : SF11 @ 500kHz |
jortronm2 | 0:1441b10e38a6 | 95 | // DR_10 : SF10 @ 500kHz |
jortronm2 | 0:1441b10e38a6 | 96 | // DR_11 : SF9 @ 500kHz |
jortronm2 | 0:1441b10e38a6 | 97 | // DR_12 : SF8 @ 500kHz |
jortronm2 | 0:1441b10e38a6 | 98 | // DR_13 : SF7 @ 500kHz |
jortronm2 | 0:1441b10e38a6 | 99 | // DR_0 - DR_3 (125kHz channels) available but much slower |
jortronm2 | 0:1441b10e38a6 | 100 | radio_frequency = 915500000; |
jortronm2 | 0:1441b10e38a6 | 101 | radio_data_rate = lora::DR_13; |
jortronm2 | 0:1441b10e38a6 | 102 | // 915 bands have no duty cycle restrictions, set tx power to max |
jortronm2 | 0:1441b10e38a6 | 103 | radio_power = 20; |
jortronm2 | 0:1441b10e38a6 | 104 | break; |
jortronm2 | 0:1441b10e38a6 | 105 | |
jortronm2 | 0:1441b10e38a6 | 106 | case lora::ChannelPlan::AS923: |
jortronm2 | 0:1441b10e38a6 | 107 | case lora::ChannelPlan::AS923_JAPAN: |
jortronm2 | 0:1441b10e38a6 | 108 | // 250kHz channels achieve higher throughput |
jortronm2 | 0:1441b10e38a6 | 109 | // DR_6 : SF7 @ 250kHz |
jortronm2 | 0:1441b10e38a6 | 110 | // DR_0 - DR_5 (125kHz channels) available but much slower |
jortronm2 | 0:1441b10e38a6 | 111 | radio_frequency = 924800000; |
jortronm2 | 0:1441b10e38a6 | 112 | radio_data_rate = lora::DR_6; |
jortronm2 | 0:1441b10e38a6 | 113 | radio_power = 16; |
jortronm2 | 0:1441b10e38a6 | 114 | break; |
jortronm2 | 0:1441b10e38a6 | 115 | |
jortronm2 | 0:1441b10e38a6 | 116 | case lora::ChannelPlan::KR920: |
jortronm2 | 0:1441b10e38a6 | 117 | // DR_5 : SF7 @ 125kHz |
jortronm2 | 0:1441b10e38a6 | 118 | radio_frequency = 922700000; |
jortronm2 | 0:1441b10e38a6 | 119 | radio_data_rate = lora::DR_5; |
jortronm2 | 0:1441b10e38a6 | 120 | radio_power = 14; |
jortronm2 | 0:1441b10e38a6 | 121 | break; |
jortronm2 | 0:1441b10e38a6 | 122 | |
jortronm2 | 0:1441b10e38a6 | 123 | default: |
jortronm2 | 0:1441b10e38a6 | 124 | while (true) { |
jortronm2 | 0:1441b10e38a6 | 125 | logFatal("no known channel plan in use - extra configuration is needed!"); |
jortronm2 | 0:1441b10e38a6 | 126 | wait(5); |
jortronm2 | 0:1441b10e38a6 | 127 | } |
jortronm2 | 0:1441b10e38a6 | 128 | } |
jortronm2 | 0:1441b10e38a6 | 129 | |
jortronm2 | 0:1441b10e38a6 | 130 | update_peer_to_peer_config(radio_network_address, radio_network_session_key, radio_data_session_key, radio_frequency, radio_data_rate, radio_power); |
jortronm2 | 0:1441b10e38a6 | 131 | |
jortronm2 | 0:1441b10e38a6 | 132 | // Save changes to configuration. |
jortronm2 | 0:1441b10e38a6 | 133 | logInfo("saving configuration"); |
jortronm2 | 0:1441b10e38a6 | 134 | if (!dot->saveConfig()) { |
jortronm2 | 0:1441b10e38a6 | 135 | logError("failed to save configuration"); |
jortronm2 | 0:1441b10e38a6 | 136 | } |
jortronm2 | 0:1441b10e38a6 | 137 | |
jortronm2 | 0:1441b10e38a6 | 138 | // Join network if not joined. |
jortronm2 | 0:1441b10e38a6 | 139 | if (!dot->getNetworkJoinStatus()) { |
jortronm2 | 0:1441b10e38a6 | 140 | join_network(); |
jortronm2 | 0:1441b10e38a6 | 141 | } |
jortronm2 | 0:1441b10e38a6 | 142 | |
jortronm2 | 0:1441b10e38a6 | 143 | // Display configuration. |
jortronm2 | 0:1441b10e38a6 | 144 | display_config(); |
jortronm2 | 0:1441b10e38a6 | 145 | |
jortronm2 | 0:1441b10e38a6 | 146 | return 0; |
jortronm2 | 0:1441b10e38a6 | 147 | } |
jortronm2 | 0:1441b10e38a6 | 148 | |
jortronm2 | 0:1441b10e38a6 | 149 | extern int8_t radio_sensor_transmit(struct sensor_data_raw data) { |
jortronm2 | 0:1441b10e38a6 | 150 | uint8_t packet_length_max, packet_seq, packets_required; |
jortronm2 | 0:1441b10e38a6 | 151 | uint8_t tx_buffer[sizeof(struct sensor_data_raw)]; |
jortronm2 | 0:1441b10e38a6 | 152 | uint32_t packet_length_data, tx_buffer_size; |
jortronm2 | 0:1441b10e38a6 | 153 | std::vector<uint8_t> radio_packet; |
jortronm2 | 0:1441b10e38a6 | 154 | |
jortronm2 | 0:1441b10e38a6 | 155 | packet_length_max = dot->getMaxPacketLength(); |
jortronm2 | 0:1441b10e38a6 | 156 | logDebug("The maximum packet length is %i.", packet_length_max); |
jortronm2 | 0:1441b10e38a6 | 157 | |
jortronm2 | 0:1441b10e38a6 | 158 | if(packet_length_max < 3) { |
jortronm2 | 0:1441b10e38a6 | 159 | logError("The packet length allowed by the mDot is too small (%u).", packet_length_max); |
jortronm2 | 0:1441b10e38a6 | 160 | return -1; |
jortronm2 | 0:1441b10e38a6 | 161 | } |
jortronm2 | 0:1441b10e38a6 | 162 | |
jortronm2 | 0:1441b10e38a6 | 163 | |
jortronm2 | 0:1441b10e38a6 | 164 | packet_length_data = packet_length_max - 2; |
jortronm2 | 0:1441b10e38a6 | 165 | tx_buffer_size = sizeof(struct sensor_data_raw); |
jortronm2 | 0:1441b10e38a6 | 166 | // This performs an integer division and round up operation. |
jortronm2 | 0:1441b10e38a6 | 167 | packets_required = (tx_buffer_size + packet_length_data - 1) / packet_length_data; |
jortronm2 | 0:1441b10e38a6 | 168 | |
jortronm2 | 0:1441b10e38a6 | 169 | // Turn the sensor data into a stream of bytes. |
jortronm2 | 0:1441b10e38a6 | 170 | serialize_sensor_to_bytes(data, tx_buffer); |
jortronm2 | 0:1441b10e38a6 | 171 | |
jortronm2 | 0:1441b10e38a6 | 172 | packet_seq = 0; |
jortronm2 | 0:1441b10e38a6 | 173 | |
jortronm2 | 0:1441b10e38a6 | 174 | // For the first |
jortronm2 | 0:1441b10e38a6 | 175 | //radio_packet.push_back(radio_packet_current_id); |
jortronm2 | 0:1441b10e38a6 | 176 | //radio_packet.push_back(packet_seq); |
jortronm2 | 0:1441b10e38a6 | 177 | //radio_packet.push_back(packets_required); |
jortronm2 | 0:1441b10e38a6 | 178 | |
jortronm2 | 0:1441b10e38a6 | 179 | for(uint32_t i = 0; i < tx_buffer_size; i++) { |
jortronm2 | 0:1441b10e38a6 | 180 | // Current packet finished constructing, send it and begin again. |
jortronm2 | 0:1441b10e38a6 | 181 | if(radio_packet.size() >= packet_length_max) { |
jortronm2 | 0:1441b10e38a6 | 182 | send_data(radio_packet); |
jortronm2 | 0:1441b10e38a6 | 183 | radio_packet.clear(); |
jortronm2 | 0:1441b10e38a6 | 184 | |
jortronm2 | 0:1441b10e38a6 | 185 | packet_seq++; |
jortronm2 | 0:1441b10e38a6 | 186 | |
jortronm2 | 0:1441b10e38a6 | 187 | radio_packet.push_back(radio_packet_current_id); |
jortronm2 | 0:1441b10e38a6 | 188 | radio_packet.push_back(packet_seq); |
jortronm2 | 0:1441b10e38a6 | 189 | } |
jortronm2 | 0:1441b10e38a6 | 190 | |
jortronm2 | 0:1441b10e38a6 | 191 | radio_packet.push_back(tx_buffer[i]); |
jortronm2 | 0:1441b10e38a6 | 192 | } |
jortronm2 | 0:1441b10e38a6 | 193 | |
jortronm2 | 0:1441b10e38a6 | 194 | // Send the last packet. This will happen if the data is not divisible by the number of required packets. |
jortronm2 | 0:1441b10e38a6 | 195 | if(radio_packet.size() > 0) { |
jortronm2 | 0:1441b10e38a6 | 196 | send_data(radio_packet); |
jortronm2 | 0:1441b10e38a6 | 197 | radio_packet.clear(); |
jortronm2 | 0:1441b10e38a6 | 198 | } |
jortronm2 | 0:1441b10e38a6 | 199 | |
jortronm2 | 0:1441b10e38a6 | 200 | radio_packet_current_id++; |
jortronm2 | 0:1441b10e38a6 | 201 | |
jortronm2 | 0:1441b10e38a6 | 202 | return 0; |
jortronm2 | 0:1441b10e38a6 | 203 | } |