finished
Dependencies: C12832 mbed-rtos mbed
Diff: main.cpp
- Revision:
- 0:b0b296a7503f
- Child:
- 1:d7e31ae56923
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Apr 26 12:00:40 2015 +0000 @@ -0,0 +1,296 @@ +//Cathal Deehy-Power +#include "mbed.h" +#include "rtos.h" +#include "C12832.h" + +//Value of threshold +#define PUSH_THRES 0.01 +#define TILT_THRES 0.2 + +//Comms Setup +Serial pc(USBTX, USBRX); // tx, rx + +//counter/timer +char counter = 0; +//Ticker ticker; +#define TIME_VALUE 3000 + +//Mutex +Mutex LED_RGB; +Mutex Button_Press_Mutex; +Mutex Heartbeat_timer_Mutex; + +//Setup Hardware +C12832 lcd(p5, p7, p6, p8, p11); +CAN can1(p9, p10); +CAN can2(p30, p29); + +//leds for debug +DigitalOut led4(LED4); //LED +DigitalOut led3(LED3); //LED +DigitalOut led2(LED2); //LED +DigitalOut led1(LED1); //LED + +//Analog input +AnalogIn pot1(p19); +AnalogIn pot2(p20); + +//PWM Output +PwmOut servo1(p21); +PwmOut servo2(p22); +PwmOut LED_R(p23); +PwmOut LED_G(p24); +PwmOut LED_B(p25); +PwmOut speaker(p26); + + +//Interrupts +InterruptIn down_intrp(p12); +InterruptIn left_intrp(p13); +InterruptIn fire_intrp(p14); +InterruptIn up_intrp(p15); +InterruptIn right_intrp(p16); + + +//Global varible +char button_down=0; +char button_left=0; +char button_fire=0; +char button_up=0; +char button_right=0; +bool heatbeat_timeout=1; //variable for timer + +//pass event via message queue +typedef struct { + int can_id; //ID of the can_bus message + char msg_data_mem[8]; //CANbus message data +} message_t; + +MemoryPool<message_t, 16> mpool; +Queue<message_t, 16> queue; + +/////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////timer heartbeat/////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// +void timeout_heartbeat_event(void const *n) +{ + + if(can1.write(CANMessage(79, &counter, 1))) //send heartbeat message + { + counter++; //increament counter + pc.printf("Heartbeat Message sent: %d\n", counter); + Heartbeat_timer_Mutex.lock(); + heatbeat_timeout = 1; //set that the timer has run out and message sent + Heartbeat_timer_Mutex.unlock(); + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////send//////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////////////////////// +void CANBus_send_thread(void const *argument) +{ + while(1) + { + osEvent evt = queue.get(); //get message in queue + if (evt.status == osEventMessage) //check if message in queue + { + message_t *message = (message_t*)evt.value.p; + can1.write(CANMessage(message->can_id, message->msg_data_mem, 8)); //send the store in the queue + 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]); + + mpool.free(message); //dump the message in the mpool + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////joystick//////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +void joystick_event_thread(void const *argument) { + char down=0; + char left=0; + char fire=0; + char up=0; + char right=0; + + while(1) + { + //pc.printf("Debug 1: \n\r"); + //read the value into the thread first so you can release the mutex for the variable + //it should be noted that the interrupt can be mutex protected, due to the compiler. + //__disable_irq(); // Disable Interrupts //Noted that when disable the interrput program would work. + Button_Press_Mutex.lock(); //Mutex lock the gobal variables to read them into the thread + down = button_down; //read the button_down into down in the thread. + left = button_left; //read the button_left into down in the thread. + fire = button_fire; //read the button_fire into down in the thread. + up = button_up; //read the button_up into down in the thread. + right = button_right; //read the button_right into down in the thread. + button_down = 0; //after reading the variable, init the variable to zero + button_left = 0; //after reading the variable, init the variable to zero + button_fire = 0; //after reading the variable, init the variable to zero + button_up = 0; //after reading the variable, init the variable to zero + button_right = 0; //after reading the variable, init the variable to zero + Button_Press_Mutex.unlock(); //Mutex unlock the gobal variables to leave other thread use them + //__enable_irq(); // Enable Interrupts + + //pc.printf("Debug 2: \n\r"); //for debugging + + + //Cheack to see if any of the variables equals to '1' if any of the variables + //equals to '1' then send all of the value of the button on the canbus with + //the addrress 70 to match the design layout. the 'if' statment 'or' each of + //the variable together and then compares them to '1'. if the statement is + //true, then send the CANbus message. + if (down || left || fire || up || right == 1) + { + message_t *message = mpool.alloc(); //alocate memory in the mpool for message + message-> can_id = 70; //set the address of the CANbus message + message-> msg_data_mem[0] = fire; //store the value of fire in msg.data[0] + message-> msg_data_mem[1] = left; //store the value of left in msg.data[1] + message-> msg_data_mem[2] = right; //store the value of right in msg.data[2] + message-> msg_data_mem[3] = up; //store the value of up in msg.data[3] + message-> msg_data_mem[4] = down; //store the value of down in msg.data[4] + message-> msg_data_mem[5] = 0; //store the value of 0 in msg.data[5] + message-> msg_data_mem[6] = 0; //store the value of 0 in msg.data[6] + message-> msg_data_mem[7] = 0; //store the value of 0 in msg.data[7] + queue.put(message); //add the message to the queue to send on CANbus + + //led3 = !led3; //debugging + down = 0; //init the variable to '0' + left = 0; //init the variable to '0' + fire = 0; //init the variable to '0' + up = 0; //init the variable to '0' + right = 0; //init the variable to '0' + } + Thread::wait(500); //debounce delay for thread + } +} + + +//////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////Analog in/////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +void AnalogIn_event_thread(void const *argument) { + float pot1_value = pot1.read(); //init pot1 value + float pot2_value = pot2.read(); //init pot2 value + + while (true) + { + + //comapre the value for the pot1.read() - PUSH_THRES (threshold) and if it's greater than 'xor' less then + //the value stored in pot1_value, then send the message on CANbus. This statment also is 'or' + // with the same statment for the pot2. As if either of the statements are true, you need to + //send both of the values on CANbus. + 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) ) + { + //event via a message queue + message_t *message = mpool.alloc(); + message-> can_id = 71; //store the address 71, as per the design layout + message-> msg_data_mem[0] = pot1.read()*255; //read the value of the pot1 and store it in msg.data[0] + //and scale the value from 0-1 to 0-255 + message-> msg_data_mem[1] = pot2.read()*255; //read the value of the pot2 and store it in msg.data[1] + //and scale the value from 0-1 to 0-255 + message-> msg_data_mem[2] = 0; //store the value of 0 in msg.data[2] + message-> msg_data_mem[3] = 0; //store the value of 0 in msg.data[3] + message-> msg_data_mem[4] = 0; //store the value of 0 in msg.data[4] + message-> msg_data_mem[5] = 0; //store the value of 0 in msg.data[5] + message-> msg_data_mem[6] = 0; //store the value of 0 in msg.data[6] + message-> msg_data_mem[7] = 0; //store the value of 0 in msg.data[7] + queue.put(message); //add the message to the queue to send on CANbus + + //led3 = !led3; //Toggle the LED3 for debugging + Thread::wait(500); //debouce delay for switch to settle + pot1_value = pot1.read(); //store value in pot1_value to coma + pot2_value = pot2.read(); //store value in pot2_value + }//end if + }//end while +}//end thread + + +//////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////interrupts////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +void Button_down_Intrp() { +button_down = 1; //set the varible to 1 when button press +} + +void Button_left_Intrp() { +button_left = 1; //set the varible to 1 when button press +} + +void Button_fire_Intrp() { +button_fire = 1; //set the varible to 1 when button press +} + +void Button_up_Intrp() { +button_up = 1; //set the varible to 1 when button press +} + +void Button_right_Intrp() { +button_right = 1; //set the varible to 1 when button press +} + + +//////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////Main//////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////// +int main() { + pc.printf("main()\n"); //printf for debugging + //ticker.attach(&send, 1); //disbale the ticker timer, as doesn't work with threading + CANMessage msg; //Setup the canbus message variable + + Thread joystick_event(joystick_event_thread); //start the joystick_event_thread + Thread AnalogIn_event(AnalogIn_event_thread); //start the AnalogIn_event_thread + Thread CANBus_Send_Event(CANBus_send_thread); //start the CANBus_send_thread + + //Start the timer to send the hearthbeat, instead of the ticker timer + RtosTimer timer(timeout_heartbeat_event, osTimerPeriodic, (void *)0); + + //Setup Interrupts + down_intrp.rise(&Button_down_Intrp); //joystick down + left_intrp.rise(&Button_left_Intrp); //joystick left + fire_intrp.rise(&Button_fire_Intrp); //joystick fire + up_intrp.rise(&Button_up_Intrp); //joystick up + right_intrp.rise(&Button_right_Intrp); //joystick right + + timer.start(2000); //start the timer + + while(1) + { + //pc.printf("loop()\n"); + if(can1.read(msg)) + { + if(msg.id ==72) //Cheack to see if the msg.id address is 72 + { + led1 = msg.data[0]; //turn on or off the LED1 depending on what stored in msg.data[0] + led2 = msg.data[1]; //turn on or off the LED2 depending on what stored in msg.data[1] + led3 = msg.data[2]; //turn on or off the LED3 depending on what stored in msg.data[2] + led4 = msg.data[3]; //turn on or off the LED4 depending on what stored in msg.data[3] + } + else if(msg.id ==73) //Cheack to see if the msg.id address is 72 + { + //scale the recieved messages from 0-255 to 0-1 + servo1 = msg.data[0]/255; //move servo1 to position stored in msg.data[0] + servo2 = msg.data[1]/255; //move servo2 to position stored in msg.data[1] + LED_R = msg.data[2]/255; //PWM the red LED depending on what stored in msg.data[2] + LED_G = msg.data[3]/255; //PWM the red LED depending on what stored in msg.data[3] + LED_B = msg.data[4]/255; //PWM the red LED depending on what stored in msg.data[4] + speaker = msg.data[5]/255; //PWM the speaker depending on what stored in msg.data[5] + } + 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]); + } + + //check to see if a heartbeat message was sent on the CANbus + // if the message was sent, start the timer again with the + //value defined in TIME_VALUE + Heartbeat_timer_Mutex.lock(); //Mutex lock + if(heatbeat_timeout== 1) + { + timer.start(TIME_VALUE); //start the timer + heatbeat_timeout = 0; //set that the timer as + } + Heartbeat_timer_Mutex.unlock(); //Mutex lock + } +}