comms not ready

Dependencies:   NRF2401P mbed-rtos mbed

main.cpp

Committer:
newc4420
Date:
2015-06-12
Revision:
1:51a5cfbfd25c
Parent:
0:05989ea2d008

File content as of revision 1:51a5cfbfd25c:

#include "mbed.h"
#include "rtos.h"
#include "NRF2401P.h"

Serial pc(USBTX, USBRX); // tx, rx

/*Program to open locker when a signal level (lock) is sent in from an external controller. 
System is split into threads so main loop can run even when waiting in door unlock function.

The circuit uses a metal contact to detect if the door is open/closed(latch engaged or not) and sends out an external signal.
Main loop checks if door needs to be unlocked(from external signal) and if door is open.
Door unlock solenoid is controlled by function unlock*/

/*function definitions*/
void unlock (void const *args);           //function statement to unlock door,

void battcomms (void const *args);        //function statement to communicate with battery

/*set pins*/
DigitalOut latch(D0);       //signal out to open door
DigitalIn lock(D1);       //signal in from interface to unlock door
DigitalIn doorclosed(D2);   //detect if door is closed(logic 1 for door closed)
DigitalOut flagdoor(D3);    //flag out if door is open
PwmOut alarm(PTE20);        //alarm via pulse width modulated signal on pin PTE20

//testing parameters
DigitalOut led(LED1);           //light to denote unlock thread
DigitalOut led2(LED2);          //light to denote cycle

//global flags used in both treads, hence volatile
volatile int unlockflag = 0;             //internal flag to denote need to unlock door
volatile int alarmflag = 1;              //alarm activated flag

volatile int justarmed = 0;             //flag to remember if alarm has just been armed to not run unlocking process
int main()
{
    //initital set up for system
    led=1;
    alarmflag = 1;      //initially alarm armed
    unlockflag = 0;     //initially no call to unlock
    alarm = 0;          //initialise alarm as not sounding
    latch = 1;          //solenoid initially locked
    
    Thread Tunlock(unlock);     //set up unlock function as a thread, thread should not run while unlockflag ==0
    Thread Tbattcomms(battcomms);   //set up battcomms as a thread

    //main loop that runs forever, checking for external flags and if door open/closed and to fire off alarm(status thread)
    while(true) 
    {
        led2 = !led2;
        //check if need to unlock door(external flag, lock), setting internal flag(unlockflag) so unlock function will run accordingly
        if (lock == 0 && alarmflag ==1 && justarmed == 0) {            
            unlockflag = 1;
            Thread :: wait(100);
        }
            //after one cycle from arming alarm, turn off justarmed flag and wait for more than a second before testing for next unlock signal
            else if(justarmed ==1 && alarmflag==1)
            {
                justarmed = 0;
                Thread :: wait(1100);
            }    

        //check if door is open
        if (doorclosed == 1) {      //if door is open(electric contact lost), send out flag(logic 1)
            flagdoor = 0;
        } else {
            flagdoor = 1;
        }
        Thread :: wait(200);        //only check door status every 0.2s
        
        //check if door broken into(alarm active, no unlock signal and door open)
        if(alarmflag == 1 && lock == 1 && doorclosed == 0)
        {
            alarm = 0.5;      //alarm goes off, doesnt stop until investigated by operator
        }
    }
}



/*function to unlock door to be called in thread. Note time limit on solenoid open to prevent overheating
(should put spring to force door open once unlocked) unlock protocol thread*/
void unlock (void const *args)
{
    (void)args;     //to note thread function has no input parameter
    
   
    while (true) {
    //unlock process should only run code below if unlockflag == 1, checks every cycle, does nothing if internal flag(unlockflag)==0
        if (unlockflag == 1) 
        {      
            alarmflag = 0;  //deactivate alarm
            latch = 0;      //open latch via relay activating solenoid
            led = 0;        //test light on to tell if solenoid should be on
            Thread :: wait(5000);   //latch stays open(solenoid activated) for 5 seconds
            latch = 1;      //turn off solenoid, let latch closed
            led = 1;        //turn off test light
            unlockflag = 0;     //reset internal flag for door lock
            
            //wait for door to be closed, do other loop checks
            while (doorclosed == 0)
            {
                Thread :: wait(100);    //wait 0.5s, allowing other threads to run
            }
            //if door is closed and alarm not activated, activate alarm and remember that alarm is just armed
                if (doorclosed == 1 && alarmflag==0 && justarmed ==0)
                {
                    alarmflag = 1;
                    justarmed = 1;
                }    
                    else
                    {
                        Thread :: wait(200);            //do main thread checks while waiting(superfluous code from previous iteration?)
                    }
           
        }    
    }
}

/*battery communication function to be called in thread*/
void battcomms (void const *args)
{
    
    long long addr1=0xAB12CD; // setup address - any 5 byte number - same as TX
    int channel =52;  // [0-126] setup channel, must be same as TX
    bool txOK;
    char msg[32];
    char ackData[32];
    char len;
    
    // Setup 
    NRF2401P nrf1(PTD2,PTD3, PTD1,PTA13, PTD0); //pins on mosi, miso, sclk, csn, ce)
    
    nrf1.quickRxSetup(channel, addr1); // sets nrf24l01+ as  receiver, using pipe 1
    while(true)
    {

        // receive
        pc.printf("Waiting for Data ...\r\n");
        while (! nrf1.isRxData()); // note this blocks until RX data
        len= nrf1.getRxData(msg); // gets the message, len is length of msg
        msg[len] = '\0';
        pc.printf("Received %d bytes: %s\r\n",len, msg);
        // set ack data
        sprintf(ackData,"HELLO");
        nrf1.acknowledgeData(ackData, strlen(ackData),1); // ack for pipe 1
        pc.printf("Sent HELLO\r\n");
        
        wait(0.1);
    }    
}