finished

Dependencies:   C12832 mbed-rtos mbed

main.cpp

Committer:
cathal66
Date:
2015-05-08
Revision:
1:d7e31ae56923
Parent:
0:b0b296a7503f

File content as of revision 1:d7e31ae56923:

//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\r", 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 
            pc.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;
    int  high_to_low= 1;
     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_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
        //pc.printf("data: %4d %4d %4d %4d %4d HtL: %4d \n\r",down , left , fire , up , right, high_to_low);
        
        //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) && (high_to_low == 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
            high_to_low = 0;
            } 
        if ((!down && !left && !fire && !up && !right == 1) && (high_to_low == 0))
            {
            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
            high_to_low = 1;
            } 
        Thread::wait(10);                      //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_rise() {
button_down = 1;            //set the varible to 1 when button press
} 

void Button_left_Intrp_rise() {
button_left = 1;            //set the varible to 1 when button press
} 

void Button_fire_Intrp_rise() {
button_fire = 1;            //set the varible to 1 when button press 
}
 
void Button_up_Intrp_rise() {
button_up = 1;              //set the varible to 1 when button press
}
 
void Button_right_Intrp_rise() {
button_right = 1;           //set the varible to 1 when button press 
} 
/////
void Button_down_Intrp_fall() {
button_down = 0;            //set the varible to 0 when button press
} 

void Button_left_Intrp_fall() {
button_left = 0;            //set the varible to 0 when button press
} 

void Button_fire_Intrp_fall() {
button_fire = 0;            //set the varible to 0 when button press 
}
 
void Button_up_Intrp_fall() {
button_up = 0;              //set the varible to 0 when button press
}
 
void Button_right_Intrp_fall() {
button_right = 0;           //set the varible to 0 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_rise);    //joystick down
    left_intrp.rise(&Button_left_Intrp_rise);    //joystick left
    fire_intrp.rise(&Button_fire_Intrp_rise);    //joystick fire
    up_intrp.rise(&Button_up_Intrp_rise);        //joystick up
    right_intrp.rise(&Button_right_Intrp_rise);  //joystick right
    down_intrp.fall(&Button_down_Intrp_fall);    //joystick down
    left_intrp.fall(&Button_left_Intrp_fall);    //joystick left
    fire_intrp.fall(&Button_fire_Intrp_fall);    //joystick fire
    up_intrp.fall(&Button_up_Intrp_fall);        //joystick up
    right_intrp.fall(&Button_right_Intrp_fall);  //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
    }
}