finished

Dependencies:   C12832 mbed-rtos mbed

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
+    }
+}