comms not ready
Dependencies: NRF2401P mbed-rtos mbed
main.cpp@1:51a5cfbfd25c, 2015-06-12 (annotated)
- Committer:
- newc4420
- Date:
- Fri Jun 12 13:46:53 2015 +0000
- Revision:
- 1:51a5cfbfd25c
- Parent:
- 0:05989ea2d008
V4
;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
newc4420 | 0:05989ea2d008 | 1 | #include "mbed.h" |
newc4420 | 0:05989ea2d008 | 2 | #include "rtos.h" |
newc4420 | 1:51a5cfbfd25c | 3 | #include "NRF2401P.h" |
newc4420 | 1:51a5cfbfd25c | 4 | |
newc4420 | 1:51a5cfbfd25c | 5 | Serial pc(USBTX, USBRX); // tx, rx |
newc4420 | 0:05989ea2d008 | 6 | |
newc4420 | 0:05989ea2d008 | 7 | /*Program to open locker when a signal level (lock) is sent in from an external controller. |
newc4420 | 0:05989ea2d008 | 8 | System is split into threads so main loop can run even when waiting in door unlock function. |
newc4420 | 0:05989ea2d008 | 9 | |
newc4420 | 0:05989ea2d008 | 10 | The circuit uses a metal contact to detect if the door is open/closed(latch engaged or not) and sends out an external signal. |
newc4420 | 0:05989ea2d008 | 11 | Main loop checks if door needs to be unlocked(from external signal) and if door is open. |
newc4420 | 0:05989ea2d008 | 12 | Door unlock solenoid is controlled by function unlock*/ |
newc4420 | 0:05989ea2d008 | 13 | |
newc4420 | 0:05989ea2d008 | 14 | /*function definitions*/ |
newc4420 | 0:05989ea2d008 | 15 | void unlock (void const *args); //function statement to unlock door, |
newc4420 | 0:05989ea2d008 | 16 | |
newc4420 | 1:51a5cfbfd25c | 17 | void battcomms (void const *args); //function statement to communicate with battery |
newc4420 | 1:51a5cfbfd25c | 18 | |
newc4420 | 0:05989ea2d008 | 19 | /*set pins*/ |
newc4420 | 0:05989ea2d008 | 20 | DigitalOut latch(D0); //signal out to open door |
newc4420 | 0:05989ea2d008 | 21 | DigitalIn lock(D1); //signal in from interface to unlock door |
newc4420 | 0:05989ea2d008 | 22 | DigitalIn doorclosed(D2); //detect if door is closed(logic 1 for door closed) |
newc4420 | 0:05989ea2d008 | 23 | DigitalOut flagdoor(D3); //flag out if door is open |
newc4420 | 0:05989ea2d008 | 24 | PwmOut alarm(PTE20); //alarm via pulse width modulated signal on pin PTE20 |
newc4420 | 0:05989ea2d008 | 25 | |
newc4420 | 0:05989ea2d008 | 26 | //testing parameters |
newc4420 | 0:05989ea2d008 | 27 | DigitalOut led(LED1); //light to denote unlock thread |
newc4420 | 0:05989ea2d008 | 28 | DigitalOut led2(LED2); //light to denote cycle |
newc4420 | 0:05989ea2d008 | 29 | |
newc4420 | 0:05989ea2d008 | 30 | //global flags used in both treads, hence volatile |
newc4420 | 0:05989ea2d008 | 31 | volatile int unlockflag = 0; //internal flag to denote need to unlock door |
newc4420 | 0:05989ea2d008 | 32 | volatile int alarmflag = 1; //alarm activated flag |
newc4420 | 0:05989ea2d008 | 33 | |
newc4420 | 0:05989ea2d008 | 34 | volatile int justarmed = 0; //flag to remember if alarm has just been armed to not run unlocking process |
newc4420 | 0:05989ea2d008 | 35 | int main() |
newc4420 | 0:05989ea2d008 | 36 | { |
newc4420 | 0:05989ea2d008 | 37 | //initital set up for system |
newc4420 | 0:05989ea2d008 | 38 | led=1; |
newc4420 | 0:05989ea2d008 | 39 | alarmflag = 1; //initially alarm armed |
newc4420 | 0:05989ea2d008 | 40 | unlockflag = 0; //initially no call to unlock |
newc4420 | 0:05989ea2d008 | 41 | alarm = 0; //initialise alarm as not sounding |
newc4420 | 0:05989ea2d008 | 42 | latch = 1; //solenoid initially locked |
newc4420 | 0:05989ea2d008 | 43 | |
newc4420 | 0:05989ea2d008 | 44 | Thread Tunlock(unlock); //set up unlock function as a thread, thread should not run while unlockflag ==0 |
newc4420 | 1:51a5cfbfd25c | 45 | Thread Tbattcomms(battcomms); //set up battcomms as a thread |
newc4420 | 0:05989ea2d008 | 46 | |
newc4420 | 0:05989ea2d008 | 47 | //main loop that runs forever, checking for external flags and if door open/closed and to fire off alarm(status thread) |
newc4420 | 0:05989ea2d008 | 48 | while(true) |
newc4420 | 0:05989ea2d008 | 49 | { |
newc4420 | 0:05989ea2d008 | 50 | led2 = !led2; |
newc4420 | 0:05989ea2d008 | 51 | //check if need to unlock door(external flag, lock), setting internal flag(unlockflag) so unlock function will run accordingly |
newc4420 | 0:05989ea2d008 | 52 | if (lock == 0 && alarmflag ==1 && justarmed == 0) { |
newc4420 | 0:05989ea2d008 | 53 | unlockflag = 1; |
newc4420 | 0:05989ea2d008 | 54 | Thread :: wait(100); |
newc4420 | 0:05989ea2d008 | 55 | } |
newc4420 | 0:05989ea2d008 | 56 | //after one cycle from arming alarm, turn off justarmed flag and wait for more than a second before testing for next unlock signal |
newc4420 | 0:05989ea2d008 | 57 | else if(justarmed ==1 && alarmflag==1) |
newc4420 | 0:05989ea2d008 | 58 | { |
newc4420 | 0:05989ea2d008 | 59 | justarmed = 0; |
newc4420 | 0:05989ea2d008 | 60 | Thread :: wait(1100); |
newc4420 | 0:05989ea2d008 | 61 | } |
newc4420 | 0:05989ea2d008 | 62 | |
newc4420 | 0:05989ea2d008 | 63 | //check if door is open |
newc4420 | 0:05989ea2d008 | 64 | if (doorclosed == 1) { //if door is open(electric contact lost), send out flag(logic 1) |
newc4420 | 0:05989ea2d008 | 65 | flagdoor = 0; |
newc4420 | 0:05989ea2d008 | 66 | } else { |
newc4420 | 0:05989ea2d008 | 67 | flagdoor = 1; |
newc4420 | 0:05989ea2d008 | 68 | } |
newc4420 | 0:05989ea2d008 | 69 | Thread :: wait(200); //only check door status every 0.2s |
newc4420 | 0:05989ea2d008 | 70 | |
newc4420 | 0:05989ea2d008 | 71 | //check if door broken into(alarm active, no unlock signal and door open) |
newc4420 | 0:05989ea2d008 | 72 | if(alarmflag == 1 && lock == 1 && doorclosed == 0) |
newc4420 | 0:05989ea2d008 | 73 | { |
newc4420 | 0:05989ea2d008 | 74 | alarm = 0.5; //alarm goes off, doesnt stop until investigated by operator |
newc4420 | 0:05989ea2d008 | 75 | } |
newc4420 | 0:05989ea2d008 | 76 | } |
newc4420 | 0:05989ea2d008 | 77 | } |
newc4420 | 0:05989ea2d008 | 78 | |
newc4420 | 1:51a5cfbfd25c | 79 | |
newc4420 | 1:51a5cfbfd25c | 80 | |
newc4420 | 0:05989ea2d008 | 81 | /*function to unlock door to be called in thread. Note time limit on solenoid open to prevent overheating |
newc4420 | 0:05989ea2d008 | 82 | (should put spring to force door open once unlocked) unlock protocol thread*/ |
newc4420 | 0:05989ea2d008 | 83 | void unlock (void const *args) |
newc4420 | 0:05989ea2d008 | 84 | { |
newc4420 | 0:05989ea2d008 | 85 | (void)args; //to note thread function has no input parameter |
newc4420 | 0:05989ea2d008 | 86 | |
newc4420 | 0:05989ea2d008 | 87 | |
newc4420 | 0:05989ea2d008 | 88 | while (true) { |
newc4420 | 0:05989ea2d008 | 89 | //unlock process should only run code below if unlockflag == 1, checks every cycle, does nothing if internal flag(unlockflag)==0 |
newc4420 | 0:05989ea2d008 | 90 | if (unlockflag == 1) |
newc4420 | 0:05989ea2d008 | 91 | { |
newc4420 | 0:05989ea2d008 | 92 | alarmflag = 0; //deactivate alarm |
newc4420 | 0:05989ea2d008 | 93 | latch = 0; //open latch via relay activating solenoid |
newc4420 | 0:05989ea2d008 | 94 | led = 0; //test light on to tell if solenoid should be on |
newc4420 | 0:05989ea2d008 | 95 | Thread :: wait(5000); //latch stays open(solenoid activated) for 5 seconds |
newc4420 | 0:05989ea2d008 | 96 | latch = 1; //turn off solenoid, let latch closed |
newc4420 | 0:05989ea2d008 | 97 | led = 1; //turn off test light |
newc4420 | 0:05989ea2d008 | 98 | unlockflag = 0; //reset internal flag for door lock |
newc4420 | 0:05989ea2d008 | 99 | |
newc4420 | 0:05989ea2d008 | 100 | //wait for door to be closed, do other loop checks |
newc4420 | 0:05989ea2d008 | 101 | while (doorclosed == 0) |
newc4420 | 0:05989ea2d008 | 102 | { |
newc4420 | 0:05989ea2d008 | 103 | Thread :: wait(100); //wait 0.5s, allowing other threads to run |
newc4420 | 0:05989ea2d008 | 104 | } |
newc4420 | 0:05989ea2d008 | 105 | //if door is closed and alarm not activated, activate alarm and remember that alarm is just armed |
newc4420 | 0:05989ea2d008 | 106 | if (doorclosed == 1 && alarmflag==0 && justarmed ==0) |
newc4420 | 0:05989ea2d008 | 107 | { |
newc4420 | 0:05989ea2d008 | 108 | alarmflag = 1; |
newc4420 | 0:05989ea2d008 | 109 | justarmed = 1; |
newc4420 | 0:05989ea2d008 | 110 | } |
newc4420 | 0:05989ea2d008 | 111 | else |
newc4420 | 0:05989ea2d008 | 112 | { |
newc4420 | 0:05989ea2d008 | 113 | Thread :: wait(200); //do main thread checks while waiting(superfluous code from previous iteration?) |
newc4420 | 0:05989ea2d008 | 114 | } |
newc4420 | 0:05989ea2d008 | 115 | |
newc4420 | 0:05989ea2d008 | 116 | } |
newc4420 | 0:05989ea2d008 | 117 | } |
newc4420 | 0:05989ea2d008 | 118 | } |
newc4420 | 1:51a5cfbfd25c | 119 | |
newc4420 | 1:51a5cfbfd25c | 120 | /*battery communication function to be called in thread*/ |
newc4420 | 1:51a5cfbfd25c | 121 | void battcomms (void const *args) |
newc4420 | 1:51a5cfbfd25c | 122 | { |
newc4420 | 1:51a5cfbfd25c | 123 | |
newc4420 | 1:51a5cfbfd25c | 124 | long long addr1=0xAB12CD; // setup address - any 5 byte number - same as TX |
newc4420 | 1:51a5cfbfd25c | 125 | int channel =52; // [0-126] setup channel, must be same as TX |
newc4420 | 1:51a5cfbfd25c | 126 | bool txOK; |
newc4420 | 1:51a5cfbfd25c | 127 | char msg[32]; |
newc4420 | 1:51a5cfbfd25c | 128 | char ackData[32]; |
newc4420 | 1:51a5cfbfd25c | 129 | char len; |
newc4420 | 1:51a5cfbfd25c | 130 | |
newc4420 | 1:51a5cfbfd25c | 131 | // Setup |
newc4420 | 1:51a5cfbfd25c | 132 | NRF2401P nrf1(PTD2,PTD3, PTD1,PTA13, PTD0); //pins on mosi, miso, sclk, csn, ce) |
newc4420 | 1:51a5cfbfd25c | 133 | |
newc4420 | 1:51a5cfbfd25c | 134 | nrf1.quickRxSetup(channel, addr1); // sets nrf24l01+ as receiver, using pipe 1 |
newc4420 | 1:51a5cfbfd25c | 135 | while(true) |
newc4420 | 1:51a5cfbfd25c | 136 | { |
newc4420 | 1:51a5cfbfd25c | 137 | |
newc4420 | 1:51a5cfbfd25c | 138 | // receive |
newc4420 | 1:51a5cfbfd25c | 139 | pc.printf("Waiting for Data ...\r\n"); |
newc4420 | 1:51a5cfbfd25c | 140 | while (! nrf1.isRxData()); // note this blocks until RX data |
newc4420 | 1:51a5cfbfd25c | 141 | len= nrf1.getRxData(msg); // gets the message, len is length of msg |
newc4420 | 1:51a5cfbfd25c | 142 | msg[len] = '\0'; |
newc4420 | 1:51a5cfbfd25c | 143 | pc.printf("Received %d bytes: %s\r\n",len, msg); |
newc4420 | 1:51a5cfbfd25c | 144 | // set ack data |
newc4420 | 1:51a5cfbfd25c | 145 | sprintf(ackData,"HELLO"); |
newc4420 | 1:51a5cfbfd25c | 146 | nrf1.acknowledgeData(ackData, strlen(ackData),1); // ack for pipe 1 |
newc4420 | 1:51a5cfbfd25c | 147 | pc.printf("Sent HELLO\r\n"); |
newc4420 | 1:51a5cfbfd25c | 148 | |
newc4420 | 1:51a5cfbfd25c | 149 | wait(0.1); |
newc4420 | 1:51a5cfbfd25c | 150 | } |
newc4420 | 1:51a5cfbfd25c | 151 | } |