Master_Node

Dependencies:   XBeeLib_Master mbed

main.cpp

Committer:
basvuyk
Date:
2018-07-25
Revision:
2:bd4ef614ebb6
Parent:
1:f28c98c04cbd

File content as of revision 2:bd4ef614ebb6:

#include "mbed.h"
#include "XBeeLib.h"

using namespace XBeeLib;
    
typedef enum
{
    BOOTING,    
    NORMAL_OPERATION,
    EMERGENCY,
    WAIT_FOR_RESET,
} state_t;

state_t currentState = BOOTING;

char *HEARTBEAT_MSG = "49";
char *EMERGENCY_MSG = "50"; 
char *RESET_MSG = "101";

int receivedData; 

//------------Define Digimesh Variables------------//
#define channel 0x15
#define networkId 0xD160
#define powerLevel 4
#define nodeId "masterNode"
#define baudRate 230400
//------------Define Digimesh Variables------------//

//------------Define Pinouts-----------------------//
DigitalOut statusLED(PB_5);
PwmOut powerLED(PB_4);

DigitalIn localEstop(PA_11);
DigitalIn resetButton(PA_12);
//------------Define Pinouts-----------------------//

//-----------TIMER CONFIG----------//
Timer runHeartbeatTimer, runSystemChecksTimer;
#define systemCheckTimeout 5    // ms   // Check system state every 5ms
#define heartbeatTimeout 200    // ms   // Check heartbeat every 100ms
//-----------TIMER CONFIG----------//

// Initiate XBEE Module
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("masterNode");
    temp = DMLocalNode.write_config();
}

void boot(XBeeDM &DMLocalNode){
    radioConfig(DMLocalNode);
    powerLED.write(255);
}

static void receive_cb(const RemoteXBeeDM& remote, bool broadcast, const uint8_t *const data, uint16_t len){
    receivedData = (data[0]-3); // -3 for offset
}

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 sendHeartbeat(XBeeDM &DMLocalNode){
    if (currentState == NORMAL_OPERATION){
        sendMessage(DMLocalNode, HEARTBEAT_MSG);
    }
}

void checkLocalEstop(){
    if (localEstop == 0){
        currentState = EMERGENCY;
    }
    if (localEstop == 1 && currentState == EMERGENCY){
        currentState = WAIT_FOR_RESET;
    }
}

void checkReset(XBeeDM &DMLocalNode){
    if (resetButton == 1 && localEstop == 1 && currentState == NORMAL_OPERATION){
        sendMessage(DMLocalNode, RESET_MSG);
    }
}

/* Function that avoids the misuse of the reset button,
If the button is continuously pressed, this function 
disables the reset button to prevent excessive network load */
void checkLocalReset(XBeeDM &DMLocalNode){
    static int resetCounter = 0, sendReset = 1;
    
    if (resetButton == 1 && resetCounter < 5){
        resetCounter++;
        sendReset = 1;
    }
    
    if (resetCounter == 5 && resetButton == 1){
        resetCounter = 50;
        sendReset = 0; 
    }
    
    if (resetButton == 0 && resetCounter > 0){
        resetCounter--;
    }
    
    if (sendReset == 1 && resetButton == 1 && localEstop == 1 && currentState == WAIT_FOR_RESET){
        sendMessage(DMLocalNode, RESET_MSG);
        currentState = NORMAL_OPERATION;
    }
}

void stateHandler(XBeeDM &DMLocalNode){
    static int currentMessageCounter;
    
    if (currentState == NORMAL_OPERATION){
        checkLocalEstop(); 
        statusLED.write(1);
    }
    if (currentState == EMERGENCY && currentMessageCounter != 5){
        sendMessage(DMLocalNode, EMERGENCY_MSG);
        currentMessageCounter++;
        statusLED = 0;
    }
    else if (currentState == WAIT_FOR_RESET){
        currentMessageCounter = 0;
        statusLED = 0;
    }
}

void handleMessages(XBeeDM &DMLocalNode){
    if (receivedData == 50){
        currentState = EMERGENCY;
    }
}

void runSystemChecks(XBeeDM &DMLocalNode){
    checkLocalEstop();
    stateHandler(DMLocalNode);
    checkLocalReset(DMLocalNode);
    handleMessages(DMLocalNode);
}

int main() {
    XBeeDM DMLocalNode = XBeeDM(RADIO_TX, RADIO_RX, RADIO_RESET, NC, NC, baudRate);

    boot(DMLocalNode);

    DMLocalNode.register_receive_cb(&receive_cb);

    runSystemChecksTimer.start();
    runHeartbeatTimer.start();
    
    currentState = NORMAL_OPERATION;
    
    static int systemTaskCounter, heartbeatCounter;

    while(1){
        systemTaskCounter = runSystemChecksTimer.read_ms();
        heartbeatCounter = runHeartbeatTimer.read_ms();
        
        if (systemTaskCounter > systemCheckTimeout){
            DMLocalNode.process_rx_frames(); 
            systemTaskCounter = 0; 
            runSystemChecksTimer.reset();
            runSystemChecks(DMLocalNode);
            receivedData = 0; 
        }  
        
        if (heartbeatCounter > heartbeatTimeout){
            sendHeartbeat(DMLocalNode);
            checkReset(DMLocalNode);

            heartbeatCounter = 0; 
            runHeartbeatTimer.reset();
        }   
    }
}