finished

Dependencies:   C12832 mbed-rtos mbed

Committer:
cathal66
Date:
Sun Apr 26 12:00:40 2015 +0000
Revision:
0:b0b296a7503f
Child:
1:d7e31ae56923
added comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cathal66 0:b0b296a7503f 1 //Cathal Deehy-Power
cathal66 0:b0b296a7503f 2 #include "mbed.h"
cathal66 0:b0b296a7503f 3 #include "rtos.h"
cathal66 0:b0b296a7503f 4 #include "C12832.h"
cathal66 0:b0b296a7503f 5
cathal66 0:b0b296a7503f 6 //Value of threshold
cathal66 0:b0b296a7503f 7 #define PUSH_THRES 0.01
cathal66 0:b0b296a7503f 8 #define TILT_THRES 0.2
cathal66 0:b0b296a7503f 9
cathal66 0:b0b296a7503f 10 //Comms Setup
cathal66 0:b0b296a7503f 11 Serial pc(USBTX, USBRX); // tx, rx
cathal66 0:b0b296a7503f 12
cathal66 0:b0b296a7503f 13 //counter/timer
cathal66 0:b0b296a7503f 14 char counter = 0;
cathal66 0:b0b296a7503f 15 //Ticker ticker;
cathal66 0:b0b296a7503f 16 #define TIME_VALUE 3000
cathal66 0:b0b296a7503f 17
cathal66 0:b0b296a7503f 18 //Mutex
cathal66 0:b0b296a7503f 19 Mutex LED_RGB;
cathal66 0:b0b296a7503f 20 Mutex Button_Press_Mutex;
cathal66 0:b0b296a7503f 21 Mutex Heartbeat_timer_Mutex;
cathal66 0:b0b296a7503f 22
cathal66 0:b0b296a7503f 23 //Setup Hardware
cathal66 0:b0b296a7503f 24 C12832 lcd(p5, p7, p6, p8, p11);
cathal66 0:b0b296a7503f 25 CAN can1(p9, p10);
cathal66 0:b0b296a7503f 26 CAN can2(p30, p29);
cathal66 0:b0b296a7503f 27
cathal66 0:b0b296a7503f 28 //leds for debug
cathal66 0:b0b296a7503f 29 DigitalOut led4(LED4); //LED
cathal66 0:b0b296a7503f 30 DigitalOut led3(LED3); //LED
cathal66 0:b0b296a7503f 31 DigitalOut led2(LED2); //LED
cathal66 0:b0b296a7503f 32 DigitalOut led1(LED1); //LED
cathal66 0:b0b296a7503f 33
cathal66 0:b0b296a7503f 34 //Analog input
cathal66 0:b0b296a7503f 35 AnalogIn pot1(p19);
cathal66 0:b0b296a7503f 36 AnalogIn pot2(p20);
cathal66 0:b0b296a7503f 37
cathal66 0:b0b296a7503f 38 //PWM Output
cathal66 0:b0b296a7503f 39 PwmOut servo1(p21);
cathal66 0:b0b296a7503f 40 PwmOut servo2(p22);
cathal66 0:b0b296a7503f 41 PwmOut LED_R(p23);
cathal66 0:b0b296a7503f 42 PwmOut LED_G(p24);
cathal66 0:b0b296a7503f 43 PwmOut LED_B(p25);
cathal66 0:b0b296a7503f 44 PwmOut speaker(p26);
cathal66 0:b0b296a7503f 45
cathal66 0:b0b296a7503f 46
cathal66 0:b0b296a7503f 47 //Interrupts
cathal66 0:b0b296a7503f 48 InterruptIn down_intrp(p12);
cathal66 0:b0b296a7503f 49 InterruptIn left_intrp(p13);
cathal66 0:b0b296a7503f 50 InterruptIn fire_intrp(p14);
cathal66 0:b0b296a7503f 51 InterruptIn up_intrp(p15);
cathal66 0:b0b296a7503f 52 InterruptIn right_intrp(p16);
cathal66 0:b0b296a7503f 53
cathal66 0:b0b296a7503f 54
cathal66 0:b0b296a7503f 55 //Global varible
cathal66 0:b0b296a7503f 56 char button_down=0;
cathal66 0:b0b296a7503f 57 char button_left=0;
cathal66 0:b0b296a7503f 58 char button_fire=0;
cathal66 0:b0b296a7503f 59 char button_up=0;
cathal66 0:b0b296a7503f 60 char button_right=0;
cathal66 0:b0b296a7503f 61 bool heatbeat_timeout=1; //variable for timer
cathal66 0:b0b296a7503f 62
cathal66 0:b0b296a7503f 63 //pass event via message queue
cathal66 0:b0b296a7503f 64 typedef struct {
cathal66 0:b0b296a7503f 65 int can_id; //ID of the can_bus message
cathal66 0:b0b296a7503f 66 char msg_data_mem[8]; //CANbus message data
cathal66 0:b0b296a7503f 67 } message_t;
cathal66 0:b0b296a7503f 68
cathal66 0:b0b296a7503f 69 MemoryPool<message_t, 16> mpool;
cathal66 0:b0b296a7503f 70 Queue<message_t, 16> queue;
cathal66 0:b0b296a7503f 71
cathal66 0:b0b296a7503f 72 ///////////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 73 //////////////////////////////////////timer heartbeat///////////////////////////////////////////
cathal66 0:b0b296a7503f 74 ///////////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 75 void timeout_heartbeat_event(void const *n)
cathal66 0:b0b296a7503f 76 {
cathal66 0:b0b296a7503f 77
cathal66 0:b0b296a7503f 78 if(can1.write(CANMessage(79, &counter, 1))) //send heartbeat message
cathal66 0:b0b296a7503f 79 {
cathal66 0:b0b296a7503f 80 counter++; //increament counter
cathal66 0:b0b296a7503f 81 pc.printf("Heartbeat Message sent: %d\n", counter);
cathal66 0:b0b296a7503f 82 Heartbeat_timer_Mutex.lock();
cathal66 0:b0b296a7503f 83 heatbeat_timeout = 1; //set that the timer has run out and message sent
cathal66 0:b0b296a7503f 84 Heartbeat_timer_Mutex.unlock();
cathal66 0:b0b296a7503f 85 }
cathal66 0:b0b296a7503f 86 }
cathal66 0:b0b296a7503f 87
cathal66 0:b0b296a7503f 88
cathal66 0:b0b296a7503f 89 ///////////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 90 //////////////////////////////////////send////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 91 ///////////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 92 void CANBus_send_thread(void const *argument)
cathal66 0:b0b296a7503f 93 {
cathal66 0:b0b296a7503f 94 while(1)
cathal66 0:b0b296a7503f 95 {
cathal66 0:b0b296a7503f 96 osEvent evt = queue.get(); //get message in queue
cathal66 0:b0b296a7503f 97 if (evt.status == osEventMessage) //check if message in queue
cathal66 0:b0b296a7503f 98 {
cathal66 0:b0b296a7503f 99 message_t *message = (message_t*)evt.value.p;
cathal66 0:b0b296a7503f 100 can1.write(CANMessage(message->can_id, message->msg_data_mem, 8)); //send the store in the queue
cathal66 0:b0b296a7503f 101 printf("cad: %d cmd: %4d %4d %4d %4d %4d %4d %4d %4d\n\r",message->can_id, message->msg_data_mem[0],message->msg_data_mem[1],message->msg_data_mem[2],message->msg_data_mem[3],message->msg_data_mem[4],message->msg_data_mem[5],message->msg_data_mem[6],message->msg_data_mem[7]);
cathal66 0:b0b296a7503f 102
cathal66 0:b0b296a7503f 103 mpool.free(message); //dump the message in the mpool
cathal66 0:b0b296a7503f 104 }
cathal66 0:b0b296a7503f 105 }
cathal66 0:b0b296a7503f 106 }
cathal66 0:b0b296a7503f 107
cathal66 0:b0b296a7503f 108 ////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 109 ////////////////////////////////joystick////////////////////////////////////////////////
cathal66 0:b0b296a7503f 110 ////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 111 void joystick_event_thread(void const *argument) {
cathal66 0:b0b296a7503f 112 char down=0;
cathal66 0:b0b296a7503f 113 char left=0;
cathal66 0:b0b296a7503f 114 char fire=0;
cathal66 0:b0b296a7503f 115 char up=0;
cathal66 0:b0b296a7503f 116 char right=0;
cathal66 0:b0b296a7503f 117
cathal66 0:b0b296a7503f 118 while(1)
cathal66 0:b0b296a7503f 119 {
cathal66 0:b0b296a7503f 120 //pc.printf("Debug 1: \n\r");
cathal66 0:b0b296a7503f 121 //read the value into the thread first so you can release the mutex for the variable
cathal66 0:b0b296a7503f 122 //it should be noted that the interrupt can be mutex protected, due to the compiler.
cathal66 0:b0b296a7503f 123 //__disable_irq(); // Disable Interrupts //Noted that when disable the interrput program would work.
cathal66 0:b0b296a7503f 124 Button_Press_Mutex.lock(); //Mutex lock the gobal variables to read them into the thread
cathal66 0:b0b296a7503f 125 down = button_down; //read the button_down into down in the thread.
cathal66 0:b0b296a7503f 126 left = button_left; //read the button_left into down in the thread.
cathal66 0:b0b296a7503f 127 fire = button_fire; //read the button_fire into down in the thread.
cathal66 0:b0b296a7503f 128 up = button_up; //read the button_up into down in the thread.
cathal66 0:b0b296a7503f 129 right = button_right; //read the button_right into down in the thread.
cathal66 0:b0b296a7503f 130 button_down = 0; //after reading the variable, init the variable to zero
cathal66 0:b0b296a7503f 131 button_left = 0; //after reading the variable, init the variable to zero
cathal66 0:b0b296a7503f 132 button_fire = 0; //after reading the variable, init the variable to zero
cathal66 0:b0b296a7503f 133 button_up = 0; //after reading the variable, init the variable to zero
cathal66 0:b0b296a7503f 134 button_right = 0; //after reading the variable, init the variable to zero
cathal66 0:b0b296a7503f 135 Button_Press_Mutex.unlock(); //Mutex unlock the gobal variables to leave other thread use them
cathal66 0:b0b296a7503f 136 //__enable_irq(); // Enable Interrupts
cathal66 0:b0b296a7503f 137
cathal66 0:b0b296a7503f 138 //pc.printf("Debug 2: \n\r"); //for debugging
cathal66 0:b0b296a7503f 139
cathal66 0:b0b296a7503f 140
cathal66 0:b0b296a7503f 141 //Cheack to see if any of the variables equals to '1' if any of the variables
cathal66 0:b0b296a7503f 142 //equals to '1' then send all of the value of the button on the canbus with
cathal66 0:b0b296a7503f 143 //the addrress 70 to match the design layout. the 'if' statment 'or' each of
cathal66 0:b0b296a7503f 144 //the variable together and then compares them to '1'. if the statement is
cathal66 0:b0b296a7503f 145 //true, then send the CANbus message.
cathal66 0:b0b296a7503f 146 if (down || left || fire || up || right == 1)
cathal66 0:b0b296a7503f 147 {
cathal66 0:b0b296a7503f 148 message_t *message = mpool.alloc(); //alocate memory in the mpool for message
cathal66 0:b0b296a7503f 149 message-> can_id = 70; //set the address of the CANbus message
cathal66 0:b0b296a7503f 150 message-> msg_data_mem[0] = fire; //store the value of fire in msg.data[0]
cathal66 0:b0b296a7503f 151 message-> msg_data_mem[1] = left; //store the value of left in msg.data[1]
cathal66 0:b0b296a7503f 152 message-> msg_data_mem[2] = right; //store the value of right in msg.data[2]
cathal66 0:b0b296a7503f 153 message-> msg_data_mem[3] = up; //store the value of up in msg.data[3]
cathal66 0:b0b296a7503f 154 message-> msg_data_mem[4] = down; //store the value of down in msg.data[4]
cathal66 0:b0b296a7503f 155 message-> msg_data_mem[5] = 0; //store the value of 0 in msg.data[5]
cathal66 0:b0b296a7503f 156 message-> msg_data_mem[6] = 0; //store the value of 0 in msg.data[6]
cathal66 0:b0b296a7503f 157 message-> msg_data_mem[7] = 0; //store the value of 0 in msg.data[7]
cathal66 0:b0b296a7503f 158 queue.put(message); //add the message to the queue to send on CANbus
cathal66 0:b0b296a7503f 159
cathal66 0:b0b296a7503f 160 //led3 = !led3; //debugging
cathal66 0:b0b296a7503f 161 down = 0; //init the variable to '0'
cathal66 0:b0b296a7503f 162 left = 0; //init the variable to '0'
cathal66 0:b0b296a7503f 163 fire = 0; //init the variable to '0'
cathal66 0:b0b296a7503f 164 up = 0; //init the variable to '0'
cathal66 0:b0b296a7503f 165 right = 0; //init the variable to '0'
cathal66 0:b0b296a7503f 166 }
cathal66 0:b0b296a7503f 167 Thread::wait(500); //debounce delay for thread
cathal66 0:b0b296a7503f 168 }
cathal66 0:b0b296a7503f 169 }
cathal66 0:b0b296a7503f 170
cathal66 0:b0b296a7503f 171
cathal66 0:b0b296a7503f 172 ////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 173 ////////////////////////////////Analog in///////////////////////////////////////////////
cathal66 0:b0b296a7503f 174 ////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 175 void AnalogIn_event_thread(void const *argument) {
cathal66 0:b0b296a7503f 176 float pot1_value = pot1.read(); //init pot1 value
cathal66 0:b0b296a7503f 177 float pot2_value = pot2.read(); //init pot2 value
cathal66 0:b0b296a7503f 178
cathal66 0:b0b296a7503f 179 while (true)
cathal66 0:b0b296a7503f 180 {
cathal66 0:b0b296a7503f 181
cathal66 0:b0b296a7503f 182 //comapre the value for the pot1.read() - PUSH_THRES (threshold) and if it's greater than 'xor' less then
cathal66 0:b0b296a7503f 183 //the value stored in pot1_value, then send the message on CANbus. This statment also is 'or'
cathal66 0:b0b296a7503f 184 // with the same statment for the pot2. As if either of the statements are true, you need to
cathal66 0:b0b296a7503f 185 //send both of the values on CANbus.
cathal66 0:b0b296a7503f 186 if ((pot1_value >= pot1.read()- PUSH_THRES ^ pot1_value <= pot1.read()+ PUSH_THRES) || (pot2_value >= pot2.read()- PUSH_THRES ^ pot2_value <= pot2.read()+ PUSH_THRES) )
cathal66 0:b0b296a7503f 187 {
cathal66 0:b0b296a7503f 188 //event via a message queue
cathal66 0:b0b296a7503f 189 message_t *message = mpool.alloc();
cathal66 0:b0b296a7503f 190 message-> can_id = 71; //store the address 71, as per the design layout
cathal66 0:b0b296a7503f 191 message-> msg_data_mem[0] = pot1.read()*255; //read the value of the pot1 and store it in msg.data[0]
cathal66 0:b0b296a7503f 192 //and scale the value from 0-1 to 0-255
cathal66 0:b0b296a7503f 193 message-> msg_data_mem[1] = pot2.read()*255; //read the value of the pot2 and store it in msg.data[1]
cathal66 0:b0b296a7503f 194 //and scale the value from 0-1 to 0-255
cathal66 0:b0b296a7503f 195 message-> msg_data_mem[2] = 0; //store the value of 0 in msg.data[2]
cathal66 0:b0b296a7503f 196 message-> msg_data_mem[3] = 0; //store the value of 0 in msg.data[3]
cathal66 0:b0b296a7503f 197 message-> msg_data_mem[4] = 0; //store the value of 0 in msg.data[4]
cathal66 0:b0b296a7503f 198 message-> msg_data_mem[5] = 0; //store the value of 0 in msg.data[5]
cathal66 0:b0b296a7503f 199 message-> msg_data_mem[6] = 0; //store the value of 0 in msg.data[6]
cathal66 0:b0b296a7503f 200 message-> msg_data_mem[7] = 0; //store the value of 0 in msg.data[7]
cathal66 0:b0b296a7503f 201 queue.put(message); //add the message to the queue to send on CANbus
cathal66 0:b0b296a7503f 202
cathal66 0:b0b296a7503f 203 //led3 = !led3; //Toggle the LED3 for debugging
cathal66 0:b0b296a7503f 204 Thread::wait(500); //debouce delay for switch to settle
cathal66 0:b0b296a7503f 205 pot1_value = pot1.read(); //store value in pot1_value to coma
cathal66 0:b0b296a7503f 206 pot2_value = pot2.read(); //store value in pot2_value
cathal66 0:b0b296a7503f 207 }//end if
cathal66 0:b0b296a7503f 208 }//end while
cathal66 0:b0b296a7503f 209 }//end thread
cathal66 0:b0b296a7503f 210
cathal66 0:b0b296a7503f 211
cathal66 0:b0b296a7503f 212 ////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 213 ////////////////////////////////interrupts//////////////////////////////////////////////
cathal66 0:b0b296a7503f 214 ////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 215 void Button_down_Intrp() {
cathal66 0:b0b296a7503f 216 button_down = 1; //set the varible to 1 when button press
cathal66 0:b0b296a7503f 217 }
cathal66 0:b0b296a7503f 218
cathal66 0:b0b296a7503f 219 void Button_left_Intrp() {
cathal66 0:b0b296a7503f 220 button_left = 1; //set the varible to 1 when button press
cathal66 0:b0b296a7503f 221 }
cathal66 0:b0b296a7503f 222
cathal66 0:b0b296a7503f 223 void Button_fire_Intrp() {
cathal66 0:b0b296a7503f 224 button_fire = 1; //set the varible to 1 when button press
cathal66 0:b0b296a7503f 225 }
cathal66 0:b0b296a7503f 226
cathal66 0:b0b296a7503f 227 void Button_up_Intrp() {
cathal66 0:b0b296a7503f 228 button_up = 1; //set the varible to 1 when button press
cathal66 0:b0b296a7503f 229 }
cathal66 0:b0b296a7503f 230
cathal66 0:b0b296a7503f 231 void Button_right_Intrp() {
cathal66 0:b0b296a7503f 232 button_right = 1; //set the varible to 1 when button press
cathal66 0:b0b296a7503f 233 }
cathal66 0:b0b296a7503f 234
cathal66 0:b0b296a7503f 235
cathal66 0:b0b296a7503f 236 ////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 237 ////////////////////////////////Main////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 238 ////////////////////////////////////////////////////////////////////////////////////////
cathal66 0:b0b296a7503f 239 int main() {
cathal66 0:b0b296a7503f 240 pc.printf("main()\n"); //printf for debugging
cathal66 0:b0b296a7503f 241 //ticker.attach(&send, 1); //disbale the ticker timer, as doesn't work with threading
cathal66 0:b0b296a7503f 242 CANMessage msg; //Setup the canbus message variable
cathal66 0:b0b296a7503f 243
cathal66 0:b0b296a7503f 244 Thread joystick_event(joystick_event_thread); //start the joystick_event_thread
cathal66 0:b0b296a7503f 245 Thread AnalogIn_event(AnalogIn_event_thread); //start the AnalogIn_event_thread
cathal66 0:b0b296a7503f 246 Thread CANBus_Send_Event(CANBus_send_thread); //start the CANBus_send_thread
cathal66 0:b0b296a7503f 247
cathal66 0:b0b296a7503f 248 //Start the timer to send the hearthbeat, instead of the ticker timer
cathal66 0:b0b296a7503f 249 RtosTimer timer(timeout_heartbeat_event, osTimerPeriodic, (void *)0);
cathal66 0:b0b296a7503f 250
cathal66 0:b0b296a7503f 251 //Setup Interrupts
cathal66 0:b0b296a7503f 252 down_intrp.rise(&Button_down_Intrp); //joystick down
cathal66 0:b0b296a7503f 253 left_intrp.rise(&Button_left_Intrp); //joystick left
cathal66 0:b0b296a7503f 254 fire_intrp.rise(&Button_fire_Intrp); //joystick fire
cathal66 0:b0b296a7503f 255 up_intrp.rise(&Button_up_Intrp); //joystick up
cathal66 0:b0b296a7503f 256 right_intrp.rise(&Button_right_Intrp); //joystick right
cathal66 0:b0b296a7503f 257
cathal66 0:b0b296a7503f 258 timer.start(2000); //start the timer
cathal66 0:b0b296a7503f 259
cathal66 0:b0b296a7503f 260 while(1)
cathal66 0:b0b296a7503f 261 {
cathal66 0:b0b296a7503f 262 //pc.printf("loop()\n");
cathal66 0:b0b296a7503f 263 if(can1.read(msg))
cathal66 0:b0b296a7503f 264 {
cathal66 0:b0b296a7503f 265 if(msg.id ==72) //Cheack to see if the msg.id address is 72
cathal66 0:b0b296a7503f 266 {
cathal66 0:b0b296a7503f 267 led1 = msg.data[0]; //turn on or off the LED1 depending on what stored in msg.data[0]
cathal66 0:b0b296a7503f 268 led2 = msg.data[1]; //turn on or off the LED2 depending on what stored in msg.data[1]
cathal66 0:b0b296a7503f 269 led3 = msg.data[2]; //turn on or off the LED3 depending on what stored in msg.data[2]
cathal66 0:b0b296a7503f 270 led4 = msg.data[3]; //turn on or off the LED4 depending on what stored in msg.data[3]
cathal66 0:b0b296a7503f 271 }
cathal66 0:b0b296a7503f 272 else if(msg.id ==73) //Cheack to see if the msg.id address is 72
cathal66 0:b0b296a7503f 273 {
cathal66 0:b0b296a7503f 274 //scale the recieved messages from 0-255 to 0-1
cathal66 0:b0b296a7503f 275 servo1 = msg.data[0]/255; //move servo1 to position stored in msg.data[0]
cathal66 0:b0b296a7503f 276 servo2 = msg.data[1]/255; //move servo2 to position stored in msg.data[1]
cathal66 0:b0b296a7503f 277 LED_R = msg.data[2]/255; //PWM the red LED depending on what stored in msg.data[2]
cathal66 0:b0b296a7503f 278 LED_G = msg.data[3]/255; //PWM the red LED depending on what stored in msg.data[3]
cathal66 0:b0b296a7503f 279 LED_B = msg.data[4]/255; //PWM the red LED depending on what stored in msg.data[4]
cathal66 0:b0b296a7503f 280 speaker = msg.data[5]/255; //PWM the speaker depending on what stored in msg.data[5]
cathal66 0:b0b296a7503f 281 }
cathal66 0:b0b296a7503f 282 pc.printf("cad: %d cmd: %4d %4d %4d %4d %4d %4d %4d %4d\n\r",msg.id, msg.data[0],msg.data[1],msg.data[2],msg.data[3],msg.data[4],msg.data[5],msg.data[6],msg.data[7]);
cathal66 0:b0b296a7503f 283 }
cathal66 0:b0b296a7503f 284
cathal66 0:b0b296a7503f 285 //check to see if a heartbeat message was sent on the CANbus
cathal66 0:b0b296a7503f 286 // if the message was sent, start the timer again with the
cathal66 0:b0b296a7503f 287 //value defined in TIME_VALUE
cathal66 0:b0b296a7503f 288 Heartbeat_timer_Mutex.lock(); //Mutex lock
cathal66 0:b0b296a7503f 289 if(heatbeat_timeout== 1)
cathal66 0:b0b296a7503f 290 {
cathal66 0:b0b296a7503f 291 timer.start(TIME_VALUE); //start the timer
cathal66 0:b0b296a7503f 292 heatbeat_timeout = 0; //set that the timer as
cathal66 0:b0b296a7503f 293 }
cathal66 0:b0b296a7503f 294 Heartbeat_timer_Mutex.unlock(); //Mutex lock
cathal66 0:b0b296a7503f 295 }
cathal66 0:b0b296a7503f 296 }