Nurbol Nurdaulet / Mbed 2 deprecated state_machine_24_11_11

Dependencies:   mbed WattBob_TextLCD

main.cpp

Committer:
Nurbol
Date:
2011-11-24
Revision:
3:0ce1c635a653
Parent:
2:0d0ec8aa4605

File content as of revision 3:0ce1c635a653:

//
// COM_test : program to communicate via a COM port to a PC/laptop
// ========
//
// Description
//      Program to receive ASCII format commands through a virtual COM port and
//      after executing the command return some data (optional, depending on
//      the command) and a status value.
//      The program understands two possible commands :
//          "s i j"     : move servo 'i (0 to 5) to postion 'j' (0 to 90)
//          "r"         : read the 'i' parameter of the last "s" command
//
// Version : 1.0
// Author : Jim Herd
// Date : 5th Oct 2011
//
#include "mbed.h"
#include "MCP23017.h"
#include "WattBob_TextLCD.h"
#include "cmd_io.h"
#include "globals.h"



Ticker timer1p;
Ticker timer2p;
Ticker timercounter1p;
Ticker timercounter2p;
Ticker timerstatemachine;

AnalogIn sensor1(p15);
AnalogIn sensor2(p16);
DigitalOut valueLED1(p23);
DigitalOut valueLED2(p25);


DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);

DigitalOut clk(p24);

DigitalIn counter1p(p5);
DigitalIn counter2p(p6);
DigitalIn SW1p(p11);
DigitalIn SW2p(p12);

bool Position1_1p;
bool Position2_1p;
bool Position1_2p;
bool Position2_2p;

int state;



//******************************************************************************
// declare functions 
//
void sensor1p (void);
void sensor2p (void);
void counter1 (void);
void counter2 (void);
void state_machine (void);
//    
//
// 2. five servo outputs
//

PwmOut servo_0(p26);
//PwmOut servo_1(p25);
//PwmOut servo_2(p24);
//PwmOut servo_3(p23);
PwmOut servo_4(p22);
PwmOut servo_5(p21);

//
// 3. objects necessary to use the 2*16 character MBED display
//
MCP23017            *par_port;
WattBob_TextLCD     *lcd;
//
// 4. Virtual COM port over USB link to laptop/PC
//
Serial      pc(USBTX, USBRX);

//******************************************************************************
// Defined GLOBAL variables and structures
//
CMD_STRUCT         ext_cmd, commandcounter2;     // structure to hold command data
STAT_STRUCT        ext_stat;    // structure to hold status reply


//CMD_STRUCT commandcounter2;

uint32_t   last_servo;          // store for last servo number

//************************************************************************
//************************************************************************
// init_sys : initialise the system
// ========
//
// 1. Configure 2*16 character display
// 2. Print "COM test" string
// 3. initialise relevant global variables
// 4. set COM port baud rate to 19200 bits per second
//
void init_sys(void) {

    par_port = new MCP23017(p9, p10, 0x40);
    lcd = new WattBob_TextLCD(par_port);

    par_port->write_bit(1,BL_BIT);   // turn LCD backlight ON
    lcd->cls();
    lcd->locate(0,0);
    lcd->printf("COM ");
    
    servo_0.period(0.020);    // servo requires a 20ms period, common for all 5 servo objects
    last_servo = SERVO_UNKNOWN; 
    pc.baud(19200);
    
    servo_0.pulsewidth_us(1000 + (0 * 1000) / 90);
    servo_4.pulsewidth_us(1000 + (25 * 1000) / 90);
    servo_5.pulsewidth_us(1000 + (0 * 1000) / 90); 

    Position1_1p = 1;
    Position2_1p = 0;
    Position1_2p = 1;
    Position2_2p = 0;
    
    state = 0;
    
    return;
}           // end init_sys

//************************************************************************
// process_cmd : decode and execute command
// ===========
uint32_t process_cmd(CMD_STRUCT *command)
{
int32_t pulse_width;

    switch (command->cmd_code) {
//
// move a servo
//
        case SERVO_CMD :
            command->nos_data = 0;                   // no data to be returned
    //
    // check that parameters are OK
    //
            if (command->nos_params != 2) {          // check for 2 parameters
                command->result_status = CMD_BAD_NUMBER_OF_PARAMETERS;
                break;
            }
            if (command->param[0] > MAX_SERVO_NUMBER ) {       // check servo number
                command->result_status = CMD_BAD_SERVO_NUMBER;
                break;
            }
            if ((command->param[1] < MIN_SERVO_ANGLE) ||
                (command->param[1] > MAX_SERVO_ANGLE) ) { 
                command->result_status = CMD_BAD_SERVO_VALUE;
                break;
            }
            if ((command->param[0] == 4) && (command->param[1] == 0)) {
                 pulse_width = 0;  // convert angle to pulse width
                 }
            else{ 
                pulse_width = 1000 + (command->param[1] * 1000) / MAX_SERVO_ANGLE;  // convert angle to pulse width   
            }
             
            
            
    //
    // implement servo move to all 5 servos
    //
            switch (command->param[0]) {
               case 0 : servo_0.pulsewidth_us(pulse_width); break;
           //     case 1 : servo_1.pulsewidth_us(pulse_width); break;
          //      case 2 : servo_2.pulsewidth_us(pulse_width); break;
           //     case 3 : servo_3.pulsewidth_us(pulse_width); break;
               case 4 : servo_4.pulsewidth_us(pulse_width); break;
           //     case 5 : servo_5.pulsewidth_us(pulse_width); break;
                
            }
            last_servo = command->param[0];
            break;
//
// return last servo number                                                
//
        case READ_CMD :
            command->nos_data = 2;                   // no data to be returned
            command->result_data[0] = valueLED1;
            command->result_data[1] = valueLED2;
            break;
//
// catch any problems
//            
        default:
            command->nos_data = 0;                   // no data to be returned
            command->result_status = CMD_BAD_SERVO_VALUE;
            break;
    }
    return  OK;
}

//************************************************************************

//function to send value on the FPGA when 1p is detected
void sensor1p (void){
    clk = !clk;
    wait(0.01);
    sensor1.read();
        if(sensor1 > 0.5) {
                led1 = 1;
                valueLED1 = 1;
        }
        else if(sensor1 < 0.5){
               led1 = 0;
                valueLED1 = 0;
        }
}

//function to send value on the FPGA when 2p is detected
void sensor2p (){
    sensor2.read();
        if(sensor2 > 0.5) {
                led2 = 1;
                valueLED2 = 1;
        }
        else if(sensor2 < 0.5){
               led2 = 0;
                valueLED2 = 0;
        }
}


//function for the state machine to move servos between 2 positions
void state_machine (){
    switch(state)
    {
        case 0:                                                  // initial state
             servo_4.pulsewidth_us(1000 + (25 * 1000) / 90);     // motor is run
             servo_0.pulsewidth_us(1000 + (0 * 1000) / 90);      // servo 1p go to position 1
             servo_5.pulsewidth_us(1000 + (0 * 1000) / 90);      // servo 2p go to position 1 
             Position1_1p = 1;
             Position2_1p = 0;
             Position1_2p = 1;
             Position2_2p = 0;
             led3 = 0;
             led4 = 0;
             counter1p.read();
             counter2p.read();
             if(SW1p == 0){
                 if(counter1p > 0.5){
                    state = 1;
                 }
             }
             if(SW2p == 0){
                 if(counter2p > 0.5){
                    state = 4;
                 }
             }
             break;
        case 1:                                                 // state 1 if counter1p = 1
             servo_4.pulsewidth_us(0);                          // motor stop
             servo_0.pulsewidth_us(1000 + (200 * 1000) / 90);   // servo 1p go to position 2 
             wait(1);
             Position1_1p = 0;
             Position2_1p = 1;
             if((Position2_1p == 1)&&(counter1p < 0.5)){
                state = 2;
             }
             break;
        case 2:                                                  // state 2 if servo 1p is in position 2
             servo_4.pulsewidth_us(1000 + (25 * 1000) / 90);     // motor is run   
             counter1p.read();
             if(counter1p > 0.5){
                state = 3;
             }
             break;
        case 3:                               // state 3 if counter 1p = 1
             servo_4.pulsewidth_us(0);        // motor stop
             led3 = 1; 
             if(SW1p == 1){                   // wait SW 1p to go to the initial state
                state = 0;
             }
             break;
        case 4:                                                // state 4 if counter 2p = 1
             servo_4.pulsewidth_us(0);                         // motor stop
             servo_5.pulsewidth_us(1000 + (200 * 1000) / 90);  // servo 2p go to position 2
             wait(1);
             Position1_2p = 0;
             Position2_2p = 1;
             if((Position2_2p == 1)&&(counter2p < 0.5)){
                state = 5;
             }
             break;
        case 5:                                               // state 5 if servo 2p is in position 2
             servo_4.pulsewidth_us(1000 + (25 * 1000) / 90);  // motor run
             counter2p.read();
             if(counter2p > 0.5){
                state = 6;
             }
             break;
        case 6:                          // state 6 if counter 2p = 1
             servo_4.pulsewidth_us(0);   // motor stop
             led4 = 1;
             if(SW2p == 1){              // wait SW 2p to go to the initial state
                    state = 0;
             }
             break;         
    }  
}


//************************************************************************
//
int main() {

    valueLED1=0;
    valueLED2=0;
    clk=0;
    init_sys();
    
    FOREVER {
    
     timer2p.attach(&sensor2p, 0.1);         //function sensor2p is reading all the 0.1 ms
     timer1p.attach(&sensor1p, 0.1);         //function sensor1p is reading all the 0.1 ms
    
    counter1p.read();
    counter2p.read();
    
    timerstatemachine.attach(&state_machine, 0.1);
    

     clk = !clk;
     wait(0.01);
    
        get_cmd(&ext_cmd);
    //
    // Check status of read command activity and return an error status if there was a problem
    // If there is a problem, then return status code only and wait for next command.
    //
        if (ext_cmd.result_status != OK){
            send_status(ext_cmd.result_status);
            continue;
        }
    //
    // Parse command and return an error staus if there is a problem
    // If there is a problem, then return status code only and wait for next command.
    //
        parse_cmd(&ext_cmd);
        lcd->locate(1,0); lcd->printf(ext_cmd.cmd_str);
        if ((ext_cmd.result_status != OK) && (ext_cmd.cmd_code != TEXT_CMD)){
            lcd->locate(1,0); lcd->printf("parse : error");
            send_status(ext_cmd.result_status);
            continue;
        }
    //
    // Execute command and return an error staus if there is a problem
    //
        process_cmd(&ext_cmd);
        reply_to_cmd(&ext_cmd);
        
       
    
    }
         
}