![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Handheld_Node
Dependencies: XBeeLib buzzer mbed
Diff: main.cpp
- Revision:
- 0:2ab14db2fd40
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Jul 25 09:11:48 2018 +0000 @@ -0,0 +1,256 @@ +#include "mbed.h" +#include "XBeeLib.h" +#include "buzzer.h" + +using namespace XBeeLib; + +typedef enum +{ + BOOTING, + NORMAL_OPERATION, + EMERGENCY, + WAIT_FOR_RESET, + HEARTBEAT_ERROR, + GRACE_PERIOD, +} state_t; + +state_t currentState = BOOTING; + +int receivedData, currentMessageCounter, graceCounter, currentTimerValue; + +/* +STATE_MESSAGES: +HEARTBEAT = 49 +EMERGENCY = 50 +RESET = 46 +*/ + +//------------Define Digimesh Variables------------// +#define channel 0x18 +#define networkId 0xD164 +#define powerLevel 4 +#define nodeId "handheld" +//------------Define Digimesh Variables------------// + +//------------Define Pinouts------------// +DigitalOut statusLED(PB_4); +DigitalOut powerLED(PB_5); + +DigitalIn localEstop(PA_12); + +DigitalOut BATT_100(PB_1); +DigitalOut BATT_50(PB_7); +DigitalOut BATT_0(PB_6); +AnalogIn BATT_MON(PA_3); + +DigitalOut buzzerPin(PF_1); +//------------Define Pinouts------------// + +// Initialize Buzzer +//Beep buzzer(PF_1); + +Timer runHeartbeatTimer, runSystemChecksTimer, runBatteryTimer; + +void radioConfig(XBeeDM &DMLocalNode){ + RadioStatus temp = DMLocalNode.init(); + temp = DMLocalNode.set_channel(channel); + temp = DMLocalNode.set_network_id(networkId); + temp = DMLocalNode.set_power_level(powerLevel); + temp = DMLocalNode.set_node_identifier(nodeId); + temp = DMLocalNode.write_config(); +} + +void buzzer(int times){ + for (int x = 0; x < times; x++){ + buzzerPin.write(1); + wait (0.000125); + buzzerPin.write(0); + wait (0.000125); + } +} + +void boot(XBeeDM &DMLocalNode){ + radioConfig(DMLocalNode); + buzzer(300); +} + +static void receive_cb(const RemoteXBeeDM& remote, bool broadcast, const uint8_t *const data, uint16_t len){ + receivedData = (data[0]-3); +} + +static void sendMessage(XBeeDM &DMLocalNode, char *sendData){ + const char data[] = {*sendData}; + const uint16_t data_len = strlen(data); + + const TxStatus txStatus = DMLocalNode.send_data_broadcast((const uint8_t *)data, data_len); + + powerLED = !powerLED; +} + +void checkLocalEstop(){ + if (localEstop == 0){ + currentState = EMERGENCY; + } + if (localEstop == 1 && currentState == EMERGENCY){ + currentState = WAIT_FOR_RESET; + } +} + +void stateHandler(XBeeDM &DMLocalNode){ + if (currentState == NORMAL_OPERATION){ + checkLocalEstop(); + + statusLED.write(1); + powerLED.write(1); + } + + if (currentState == EMERGENCY && currentMessageCounter != 5){ + sendMessage(DMLocalNode, "50"); + checkLocalEstop(); + currentMessageCounter++; + + statusLED.write(0); + powerLED.write(1); + } + + if (currentState == WAIT_FOR_RESET){ + currentMessageCounter = 0; + + statusLED.write(1); + powerLED.write(0); + } + + if (currentState == HEARTBEAT_ERROR){ + statusLED.write(0); + powerLED.write(0); + } + + if (currentState == GRACE_PERIOD){ + graceCounter++; + if (graceCounter == 100){ + currentState = NORMAL_OPERATION; + graceCounter = 0; + } + } +} + +void heartbeatTimerReset(){ + currentTimerValue = 0; +} + +void checkHeartbeat(){ + if (currentState == NORMAL_OPERATION){ + currentTimerValue++; + if (currentTimerValue > 7){ + currentState = HEARTBEAT_ERROR; + } + } +} + +void handleMessages(XBeeDM &DMLocalNode){ + if (receivedData == 50){ + currentState = EMERGENCY; + graceCounter = 0; + } + + if (localEstop == 1 && currentState == EMERGENCY){ + currentState = WAIT_FOR_RESET; + } + + if (currentState == WAIT_FOR_RESET && localEstop == 1 && receivedData == 46){ + currentState = GRACE_PERIOD; + } + + if (receivedData == 49){ + heartbeatTimerReset(); + } + + if (receivedData == 49 && currentState == HEARTBEAT_ERROR){ + currentState = WAIT_FOR_RESET; + heartbeatTimerReset(); + } + + if (currentState == EMERGENCY && currentMessageCounter == 5 && receivedData == 46){ + currentMessageCounter = 0; + } +} + +void runSystemChecks(XBeeDM &DMLocalNode){ + stateHandler(DMLocalNode); + handleMessages(DMLocalNode); +} + +void batteryMonitor(){ + float batVal = BATT_MON*6.6f; + + if (batVal > 3.9f){ + BATT_100.write(1); + BATT_50.write(1); + BATT_0.write(1); + } + else if (batVal < 3.89f && batVal > 3.65f){ + BATT_100.write(0); + BATT_50.write(1); + BATT_0.write(1); + } + else if (batVal < 3.64f && batVal > 3.4f){ + BATT_100.write(0); + BATT_50.write(0); + BATT_0.write(1); + } + else if (batVal < 3.39f){ + BATT_100.write(0); + BATT_50.write(0); + BATT_0.write(0); + buzzer(600); + } +} + + +int main() { + XBeeDM DMLocalNode = XBeeDM(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, 230400); + + boot(DMLocalNode); + batteryMonitor(); + DMLocalNode.register_receive_cb(&receive_cb); + + currentState = WAIT_FOR_RESET; + + runSystemChecksTimer.start(); + runHeartbeatTimer.start(); + runBatteryTimer.start(); + + static int systemTaskCounter, heartbeatCounter, batteryCounter; + + while(1){ + + systemTaskCounter = runSystemChecksTimer.read_ms(); + heartbeatCounter = runHeartbeatTimer.read_ms(); + batteryCounter = runBatteryTimer.read_ms(); + + checkLocalEstop(); + if ( systemTaskCounter > 3){ + DMLocalNode.process_rx_frames(); + runSystemChecks(DMLocalNode); + + systemTaskCounter = 0; + runSystemChecksTimer.reset(); + receivedData = 0; + } + + if ( heartbeatCounter > 100){ + DMLocalNode.process_rx_frames(); + + checkHeartbeat(); + heartbeatCounter = 0; + runHeartbeatTimer.reset(); + receivedData = 0; + } + + if (batteryCounter > 5000){ + batteryMonitor(); + batteryCounter = 0; + runBatteryTimer.reset(); + } + } +} \ No newline at end of file