Handheld_Node

Dependencies:   XBeeLib_Handheld_V2 mbed

Revision:
0:02cdf2401901
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed Jul 25 09:15:06 2018 +0000
@@ -0,0 +1,253 @@
+#include "mbed.h"
+#include "XBeeLib.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 baudRate 230400
+//------------Define Digimesh Variables------------//
+
+//------------Define Pinouts------------//
+DigitalOut statusLED(PB_5);
+DigitalOut powerLED(PB_4);
+
+DigitalIn localEstop(PA_12);
+
+DigitalOut BATT_100(PB_1);
+DigitalOut BATT_50(PB_7);
+DigitalOut BATT_0(PB_6);
+AnalogIn BATT_MON(PA_3);
+DigitalIn BATT_CHAR(PF_1);
+
+DigitalOut buzzerPin(PB_0);
+//------------Define Pinouts------------//
+
+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 boot(XBeeDM &DMLocalNode){
+    radioConfig(DMLocalNode);
+    buzzerPin.write(1);
+    wait(0.2);
+    buzzerPin.write(0);
+}
+    
+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);
+}
+
+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(0);
+    }
+    
+    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(0);
+        powerLED.write(1);
+    }
+    
+    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*5.9f;
+    
+    if (batVal > 3.9f){
+        BATT_100.write(1);
+        BATT_50.write(1);
+        BATT_0.write(1);
+        buzzerPin.write(0); 
+    }
+    else if (batVal < 3.89f && batVal > 3.65f){
+        BATT_100.write(0);
+        BATT_50.write(1);
+        BATT_0.write(1);
+        buzzerPin.write(0); 
+    }
+    else if (batVal < 3.64f && batVal > 3.4f){
+        BATT_100.write(0);
+        BATT_50.write(0);
+        BATT_0.write(1);
+        buzzerPin.write(0); 
+    }
+    else if (batVal < 3.39f){
+        BATT_100.write(0);
+        BATT_50.write(0);
+        BATT_0.write(0);
+        if (BATT_CHAR == 0){
+           buzzerPin.write(1);    
+        }
+        else
+        {
+            buzzerPin.write(0); 
+        }    
+    }
+}
+
+int main() {
+    XBeeDM DMLocalNode = XBeeDM(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, baudRate);
+    
+    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