Handheld_Node

Dependencies:   XBeeLib_Handheld_V2 mbed

main.cpp

Committer:
basvuyk
Date:
2018-07-25
Revision:
0:02cdf2401901

File content as of revision 0:02cdf2401901:

#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();
        }
    }
}