Handheld_Node
Dependencies: XBeeLib buzzer mbed
main.cpp@0:2ab14db2fd40, 2018-07-25 (annotated)
- Committer:
- basvuyk
- Date:
- Wed Jul 25 09:11:48 2018 +0000
- Revision:
- 0:2ab14db2fd40
Handheld_Node
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
basvuyk | 0:2ab14db2fd40 | 1 | #include "mbed.h" |
basvuyk | 0:2ab14db2fd40 | 2 | #include "XBeeLib.h" |
basvuyk | 0:2ab14db2fd40 | 3 | #include "buzzer.h" |
basvuyk | 0:2ab14db2fd40 | 4 | |
basvuyk | 0:2ab14db2fd40 | 5 | using namespace XBeeLib; |
basvuyk | 0:2ab14db2fd40 | 6 | |
basvuyk | 0:2ab14db2fd40 | 7 | typedef enum |
basvuyk | 0:2ab14db2fd40 | 8 | { |
basvuyk | 0:2ab14db2fd40 | 9 | BOOTING, |
basvuyk | 0:2ab14db2fd40 | 10 | NORMAL_OPERATION, |
basvuyk | 0:2ab14db2fd40 | 11 | EMERGENCY, |
basvuyk | 0:2ab14db2fd40 | 12 | WAIT_FOR_RESET, |
basvuyk | 0:2ab14db2fd40 | 13 | HEARTBEAT_ERROR, |
basvuyk | 0:2ab14db2fd40 | 14 | GRACE_PERIOD, |
basvuyk | 0:2ab14db2fd40 | 15 | } state_t; |
basvuyk | 0:2ab14db2fd40 | 16 | |
basvuyk | 0:2ab14db2fd40 | 17 | state_t currentState = BOOTING; |
basvuyk | 0:2ab14db2fd40 | 18 | |
basvuyk | 0:2ab14db2fd40 | 19 | int receivedData, currentMessageCounter, graceCounter, currentTimerValue; |
basvuyk | 0:2ab14db2fd40 | 20 | |
basvuyk | 0:2ab14db2fd40 | 21 | /* |
basvuyk | 0:2ab14db2fd40 | 22 | STATE_MESSAGES: |
basvuyk | 0:2ab14db2fd40 | 23 | HEARTBEAT = 49 |
basvuyk | 0:2ab14db2fd40 | 24 | EMERGENCY = 50 |
basvuyk | 0:2ab14db2fd40 | 25 | RESET = 46 |
basvuyk | 0:2ab14db2fd40 | 26 | */ |
basvuyk | 0:2ab14db2fd40 | 27 | |
basvuyk | 0:2ab14db2fd40 | 28 | //------------Define Digimesh Variables------------// |
basvuyk | 0:2ab14db2fd40 | 29 | #define channel 0x18 |
basvuyk | 0:2ab14db2fd40 | 30 | #define networkId 0xD164 |
basvuyk | 0:2ab14db2fd40 | 31 | #define powerLevel 4 |
basvuyk | 0:2ab14db2fd40 | 32 | #define nodeId "handheld" |
basvuyk | 0:2ab14db2fd40 | 33 | //------------Define Digimesh Variables------------// |
basvuyk | 0:2ab14db2fd40 | 34 | |
basvuyk | 0:2ab14db2fd40 | 35 | //------------Define Pinouts------------// |
basvuyk | 0:2ab14db2fd40 | 36 | DigitalOut statusLED(PB_4); |
basvuyk | 0:2ab14db2fd40 | 37 | DigitalOut powerLED(PB_5); |
basvuyk | 0:2ab14db2fd40 | 38 | |
basvuyk | 0:2ab14db2fd40 | 39 | DigitalIn localEstop(PA_12); |
basvuyk | 0:2ab14db2fd40 | 40 | |
basvuyk | 0:2ab14db2fd40 | 41 | DigitalOut BATT_100(PB_1); |
basvuyk | 0:2ab14db2fd40 | 42 | DigitalOut BATT_50(PB_7); |
basvuyk | 0:2ab14db2fd40 | 43 | DigitalOut BATT_0(PB_6); |
basvuyk | 0:2ab14db2fd40 | 44 | AnalogIn BATT_MON(PA_3); |
basvuyk | 0:2ab14db2fd40 | 45 | |
basvuyk | 0:2ab14db2fd40 | 46 | DigitalOut buzzerPin(PF_1); |
basvuyk | 0:2ab14db2fd40 | 47 | //------------Define Pinouts------------// |
basvuyk | 0:2ab14db2fd40 | 48 | |
basvuyk | 0:2ab14db2fd40 | 49 | // Initialize Buzzer |
basvuyk | 0:2ab14db2fd40 | 50 | //Beep buzzer(PF_1); |
basvuyk | 0:2ab14db2fd40 | 51 | |
basvuyk | 0:2ab14db2fd40 | 52 | Timer runHeartbeatTimer, runSystemChecksTimer, runBatteryTimer; |
basvuyk | 0:2ab14db2fd40 | 53 | |
basvuyk | 0:2ab14db2fd40 | 54 | void radioConfig(XBeeDM &DMLocalNode){ |
basvuyk | 0:2ab14db2fd40 | 55 | RadioStatus temp = DMLocalNode.init(); |
basvuyk | 0:2ab14db2fd40 | 56 | temp = DMLocalNode.set_channel(channel); |
basvuyk | 0:2ab14db2fd40 | 57 | temp = DMLocalNode.set_network_id(networkId); |
basvuyk | 0:2ab14db2fd40 | 58 | temp = DMLocalNode.set_power_level(powerLevel); |
basvuyk | 0:2ab14db2fd40 | 59 | temp = DMLocalNode.set_node_identifier(nodeId); |
basvuyk | 0:2ab14db2fd40 | 60 | temp = DMLocalNode.write_config(); |
basvuyk | 0:2ab14db2fd40 | 61 | } |
basvuyk | 0:2ab14db2fd40 | 62 | |
basvuyk | 0:2ab14db2fd40 | 63 | void buzzer(int times){ |
basvuyk | 0:2ab14db2fd40 | 64 | for (int x = 0; x < times; x++){ |
basvuyk | 0:2ab14db2fd40 | 65 | buzzerPin.write(1); |
basvuyk | 0:2ab14db2fd40 | 66 | wait (0.000125); |
basvuyk | 0:2ab14db2fd40 | 67 | buzzerPin.write(0); |
basvuyk | 0:2ab14db2fd40 | 68 | wait (0.000125); |
basvuyk | 0:2ab14db2fd40 | 69 | } |
basvuyk | 0:2ab14db2fd40 | 70 | } |
basvuyk | 0:2ab14db2fd40 | 71 | |
basvuyk | 0:2ab14db2fd40 | 72 | void boot(XBeeDM &DMLocalNode){ |
basvuyk | 0:2ab14db2fd40 | 73 | radioConfig(DMLocalNode); |
basvuyk | 0:2ab14db2fd40 | 74 | buzzer(300); |
basvuyk | 0:2ab14db2fd40 | 75 | } |
basvuyk | 0:2ab14db2fd40 | 76 | |
basvuyk | 0:2ab14db2fd40 | 77 | static void receive_cb(const RemoteXBeeDM& remote, bool broadcast, const uint8_t *const data, uint16_t len){ |
basvuyk | 0:2ab14db2fd40 | 78 | receivedData = (data[0]-3); |
basvuyk | 0:2ab14db2fd40 | 79 | } |
basvuyk | 0:2ab14db2fd40 | 80 | |
basvuyk | 0:2ab14db2fd40 | 81 | static void sendMessage(XBeeDM &DMLocalNode, char *sendData){ |
basvuyk | 0:2ab14db2fd40 | 82 | const char data[] = {*sendData}; |
basvuyk | 0:2ab14db2fd40 | 83 | const uint16_t data_len = strlen(data); |
basvuyk | 0:2ab14db2fd40 | 84 | |
basvuyk | 0:2ab14db2fd40 | 85 | const TxStatus txStatus = DMLocalNode.send_data_broadcast((const uint8_t *)data, data_len); |
basvuyk | 0:2ab14db2fd40 | 86 | |
basvuyk | 0:2ab14db2fd40 | 87 | powerLED = !powerLED; |
basvuyk | 0:2ab14db2fd40 | 88 | } |
basvuyk | 0:2ab14db2fd40 | 89 | |
basvuyk | 0:2ab14db2fd40 | 90 | void checkLocalEstop(){ |
basvuyk | 0:2ab14db2fd40 | 91 | if (localEstop == 0){ |
basvuyk | 0:2ab14db2fd40 | 92 | currentState = EMERGENCY; |
basvuyk | 0:2ab14db2fd40 | 93 | } |
basvuyk | 0:2ab14db2fd40 | 94 | if (localEstop == 1 && currentState == EMERGENCY){ |
basvuyk | 0:2ab14db2fd40 | 95 | currentState = WAIT_FOR_RESET; |
basvuyk | 0:2ab14db2fd40 | 96 | } |
basvuyk | 0:2ab14db2fd40 | 97 | } |
basvuyk | 0:2ab14db2fd40 | 98 | |
basvuyk | 0:2ab14db2fd40 | 99 | void stateHandler(XBeeDM &DMLocalNode){ |
basvuyk | 0:2ab14db2fd40 | 100 | if (currentState == NORMAL_OPERATION){ |
basvuyk | 0:2ab14db2fd40 | 101 | checkLocalEstop(); |
basvuyk | 0:2ab14db2fd40 | 102 | |
basvuyk | 0:2ab14db2fd40 | 103 | statusLED.write(1); |
basvuyk | 0:2ab14db2fd40 | 104 | powerLED.write(1); |
basvuyk | 0:2ab14db2fd40 | 105 | } |
basvuyk | 0:2ab14db2fd40 | 106 | |
basvuyk | 0:2ab14db2fd40 | 107 | if (currentState == EMERGENCY && currentMessageCounter != 5){ |
basvuyk | 0:2ab14db2fd40 | 108 | sendMessage(DMLocalNode, "50"); |
basvuyk | 0:2ab14db2fd40 | 109 | checkLocalEstop(); |
basvuyk | 0:2ab14db2fd40 | 110 | currentMessageCounter++; |
basvuyk | 0:2ab14db2fd40 | 111 | |
basvuyk | 0:2ab14db2fd40 | 112 | statusLED.write(0); |
basvuyk | 0:2ab14db2fd40 | 113 | powerLED.write(1); |
basvuyk | 0:2ab14db2fd40 | 114 | } |
basvuyk | 0:2ab14db2fd40 | 115 | |
basvuyk | 0:2ab14db2fd40 | 116 | if (currentState == WAIT_FOR_RESET){ |
basvuyk | 0:2ab14db2fd40 | 117 | currentMessageCounter = 0; |
basvuyk | 0:2ab14db2fd40 | 118 | |
basvuyk | 0:2ab14db2fd40 | 119 | statusLED.write(1); |
basvuyk | 0:2ab14db2fd40 | 120 | powerLED.write(0); |
basvuyk | 0:2ab14db2fd40 | 121 | } |
basvuyk | 0:2ab14db2fd40 | 122 | |
basvuyk | 0:2ab14db2fd40 | 123 | if (currentState == HEARTBEAT_ERROR){ |
basvuyk | 0:2ab14db2fd40 | 124 | statusLED.write(0); |
basvuyk | 0:2ab14db2fd40 | 125 | powerLED.write(0); |
basvuyk | 0:2ab14db2fd40 | 126 | } |
basvuyk | 0:2ab14db2fd40 | 127 | |
basvuyk | 0:2ab14db2fd40 | 128 | if (currentState == GRACE_PERIOD){ |
basvuyk | 0:2ab14db2fd40 | 129 | graceCounter++; |
basvuyk | 0:2ab14db2fd40 | 130 | if (graceCounter == 100){ |
basvuyk | 0:2ab14db2fd40 | 131 | currentState = NORMAL_OPERATION; |
basvuyk | 0:2ab14db2fd40 | 132 | graceCounter = 0; |
basvuyk | 0:2ab14db2fd40 | 133 | } |
basvuyk | 0:2ab14db2fd40 | 134 | } |
basvuyk | 0:2ab14db2fd40 | 135 | } |
basvuyk | 0:2ab14db2fd40 | 136 | |
basvuyk | 0:2ab14db2fd40 | 137 | void heartbeatTimerReset(){ |
basvuyk | 0:2ab14db2fd40 | 138 | currentTimerValue = 0; |
basvuyk | 0:2ab14db2fd40 | 139 | } |
basvuyk | 0:2ab14db2fd40 | 140 | |
basvuyk | 0:2ab14db2fd40 | 141 | void checkHeartbeat(){ |
basvuyk | 0:2ab14db2fd40 | 142 | if (currentState == NORMAL_OPERATION){ |
basvuyk | 0:2ab14db2fd40 | 143 | currentTimerValue++; |
basvuyk | 0:2ab14db2fd40 | 144 | if (currentTimerValue > 7){ |
basvuyk | 0:2ab14db2fd40 | 145 | currentState = HEARTBEAT_ERROR; |
basvuyk | 0:2ab14db2fd40 | 146 | } |
basvuyk | 0:2ab14db2fd40 | 147 | } |
basvuyk | 0:2ab14db2fd40 | 148 | } |
basvuyk | 0:2ab14db2fd40 | 149 | |
basvuyk | 0:2ab14db2fd40 | 150 | void handleMessages(XBeeDM &DMLocalNode){ |
basvuyk | 0:2ab14db2fd40 | 151 | if (receivedData == 50){ |
basvuyk | 0:2ab14db2fd40 | 152 | currentState = EMERGENCY; |
basvuyk | 0:2ab14db2fd40 | 153 | graceCounter = 0; |
basvuyk | 0:2ab14db2fd40 | 154 | } |
basvuyk | 0:2ab14db2fd40 | 155 | |
basvuyk | 0:2ab14db2fd40 | 156 | if (localEstop == 1 && currentState == EMERGENCY){ |
basvuyk | 0:2ab14db2fd40 | 157 | currentState = WAIT_FOR_RESET; |
basvuyk | 0:2ab14db2fd40 | 158 | } |
basvuyk | 0:2ab14db2fd40 | 159 | |
basvuyk | 0:2ab14db2fd40 | 160 | if (currentState == WAIT_FOR_RESET && localEstop == 1 && receivedData == 46){ |
basvuyk | 0:2ab14db2fd40 | 161 | currentState = GRACE_PERIOD; |
basvuyk | 0:2ab14db2fd40 | 162 | } |
basvuyk | 0:2ab14db2fd40 | 163 | |
basvuyk | 0:2ab14db2fd40 | 164 | if (receivedData == 49){ |
basvuyk | 0:2ab14db2fd40 | 165 | heartbeatTimerReset(); |
basvuyk | 0:2ab14db2fd40 | 166 | } |
basvuyk | 0:2ab14db2fd40 | 167 | |
basvuyk | 0:2ab14db2fd40 | 168 | if (receivedData == 49 && currentState == HEARTBEAT_ERROR){ |
basvuyk | 0:2ab14db2fd40 | 169 | currentState = WAIT_FOR_RESET; |
basvuyk | 0:2ab14db2fd40 | 170 | heartbeatTimerReset(); |
basvuyk | 0:2ab14db2fd40 | 171 | } |
basvuyk | 0:2ab14db2fd40 | 172 | |
basvuyk | 0:2ab14db2fd40 | 173 | if (currentState == EMERGENCY && currentMessageCounter == 5 && receivedData == 46){ |
basvuyk | 0:2ab14db2fd40 | 174 | currentMessageCounter = 0; |
basvuyk | 0:2ab14db2fd40 | 175 | } |
basvuyk | 0:2ab14db2fd40 | 176 | } |
basvuyk | 0:2ab14db2fd40 | 177 | |
basvuyk | 0:2ab14db2fd40 | 178 | void runSystemChecks(XBeeDM &DMLocalNode){ |
basvuyk | 0:2ab14db2fd40 | 179 | stateHandler(DMLocalNode); |
basvuyk | 0:2ab14db2fd40 | 180 | handleMessages(DMLocalNode); |
basvuyk | 0:2ab14db2fd40 | 181 | } |
basvuyk | 0:2ab14db2fd40 | 182 | |
basvuyk | 0:2ab14db2fd40 | 183 | void batteryMonitor(){ |
basvuyk | 0:2ab14db2fd40 | 184 | float batVal = BATT_MON*6.6f; |
basvuyk | 0:2ab14db2fd40 | 185 | |
basvuyk | 0:2ab14db2fd40 | 186 | if (batVal > 3.9f){ |
basvuyk | 0:2ab14db2fd40 | 187 | BATT_100.write(1); |
basvuyk | 0:2ab14db2fd40 | 188 | BATT_50.write(1); |
basvuyk | 0:2ab14db2fd40 | 189 | BATT_0.write(1); |
basvuyk | 0:2ab14db2fd40 | 190 | } |
basvuyk | 0:2ab14db2fd40 | 191 | else if (batVal < 3.89f && batVal > 3.65f){ |
basvuyk | 0:2ab14db2fd40 | 192 | BATT_100.write(0); |
basvuyk | 0:2ab14db2fd40 | 193 | BATT_50.write(1); |
basvuyk | 0:2ab14db2fd40 | 194 | BATT_0.write(1); |
basvuyk | 0:2ab14db2fd40 | 195 | } |
basvuyk | 0:2ab14db2fd40 | 196 | else if (batVal < 3.64f && batVal > 3.4f){ |
basvuyk | 0:2ab14db2fd40 | 197 | BATT_100.write(0); |
basvuyk | 0:2ab14db2fd40 | 198 | BATT_50.write(0); |
basvuyk | 0:2ab14db2fd40 | 199 | BATT_0.write(1); |
basvuyk | 0:2ab14db2fd40 | 200 | } |
basvuyk | 0:2ab14db2fd40 | 201 | else if (batVal < 3.39f){ |
basvuyk | 0:2ab14db2fd40 | 202 | BATT_100.write(0); |
basvuyk | 0:2ab14db2fd40 | 203 | BATT_50.write(0); |
basvuyk | 0:2ab14db2fd40 | 204 | BATT_0.write(0); |
basvuyk | 0:2ab14db2fd40 | 205 | buzzer(600); |
basvuyk | 0:2ab14db2fd40 | 206 | } |
basvuyk | 0:2ab14db2fd40 | 207 | } |
basvuyk | 0:2ab14db2fd40 | 208 | |
basvuyk | 0:2ab14db2fd40 | 209 | |
basvuyk | 0:2ab14db2fd40 | 210 | int main() { |
basvuyk | 0:2ab14db2fd40 | 211 | XBeeDM DMLocalNode = XBeeDM(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, 230400); |
basvuyk | 0:2ab14db2fd40 | 212 | |
basvuyk | 0:2ab14db2fd40 | 213 | boot(DMLocalNode); |
basvuyk | 0:2ab14db2fd40 | 214 | batteryMonitor(); |
basvuyk | 0:2ab14db2fd40 | 215 | DMLocalNode.register_receive_cb(&receive_cb); |
basvuyk | 0:2ab14db2fd40 | 216 | |
basvuyk | 0:2ab14db2fd40 | 217 | currentState = WAIT_FOR_RESET; |
basvuyk | 0:2ab14db2fd40 | 218 | |
basvuyk | 0:2ab14db2fd40 | 219 | runSystemChecksTimer.start(); |
basvuyk | 0:2ab14db2fd40 | 220 | runHeartbeatTimer.start(); |
basvuyk | 0:2ab14db2fd40 | 221 | runBatteryTimer.start(); |
basvuyk | 0:2ab14db2fd40 | 222 | |
basvuyk | 0:2ab14db2fd40 | 223 | static int systemTaskCounter, heartbeatCounter, batteryCounter; |
basvuyk | 0:2ab14db2fd40 | 224 | |
basvuyk | 0:2ab14db2fd40 | 225 | while(1){ |
basvuyk | 0:2ab14db2fd40 | 226 | |
basvuyk | 0:2ab14db2fd40 | 227 | systemTaskCounter = runSystemChecksTimer.read_ms(); |
basvuyk | 0:2ab14db2fd40 | 228 | heartbeatCounter = runHeartbeatTimer.read_ms(); |
basvuyk | 0:2ab14db2fd40 | 229 | batteryCounter = runBatteryTimer.read_ms(); |
basvuyk | 0:2ab14db2fd40 | 230 | |
basvuyk | 0:2ab14db2fd40 | 231 | checkLocalEstop(); |
basvuyk | 0:2ab14db2fd40 | 232 | if ( systemTaskCounter > 3){ |
basvuyk | 0:2ab14db2fd40 | 233 | DMLocalNode.process_rx_frames(); |
basvuyk | 0:2ab14db2fd40 | 234 | runSystemChecks(DMLocalNode); |
basvuyk | 0:2ab14db2fd40 | 235 | |
basvuyk | 0:2ab14db2fd40 | 236 | systemTaskCounter = 0; |
basvuyk | 0:2ab14db2fd40 | 237 | runSystemChecksTimer.reset(); |
basvuyk | 0:2ab14db2fd40 | 238 | receivedData = 0; |
basvuyk | 0:2ab14db2fd40 | 239 | } |
basvuyk | 0:2ab14db2fd40 | 240 | |
basvuyk | 0:2ab14db2fd40 | 241 | if ( heartbeatCounter > 100){ |
basvuyk | 0:2ab14db2fd40 | 242 | DMLocalNode.process_rx_frames(); |
basvuyk | 0:2ab14db2fd40 | 243 | |
basvuyk | 0:2ab14db2fd40 | 244 | checkHeartbeat(); |
basvuyk | 0:2ab14db2fd40 | 245 | heartbeatCounter = 0; |
basvuyk | 0:2ab14db2fd40 | 246 | runHeartbeatTimer.reset(); |
basvuyk | 0:2ab14db2fd40 | 247 | receivedData = 0; |
basvuyk | 0:2ab14db2fd40 | 248 | } |
basvuyk | 0:2ab14db2fd40 | 249 | |
basvuyk | 0:2ab14db2fd40 | 250 | if (batteryCounter > 5000){ |
basvuyk | 0:2ab14db2fd40 | 251 | batteryMonitor(); |
basvuyk | 0:2ab14db2fd40 | 252 | batteryCounter = 0; |
basvuyk | 0:2ab14db2fd40 | 253 | runBatteryTimer.reset(); |
basvuyk | 0:2ab14db2fd40 | 254 | } |
basvuyk | 0:2ab14db2fd40 | 255 | } |
basvuyk | 0:2ab14db2fd40 | 256 | } |