Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: cmd_io mbed WattBob_TextLCD MCP23017 globals
main.cpp
- Committer:
- Nurbol
- Date:
- 2011-12-01
- Revision:
- 0:247c337c230a
- Child:
- 1:8a1818e89c49
File content as of revision 0:247c337c230a:
#include "mbed.h"
#include "MCP23017.h"
#include "WattBob_TextLCD.h"
#include "cmd_io.h"
#include "globals.h"
//******************************************************************************
//declare ticker
//
Ticker timersensor;
Ticker timerstatemachine;
//******************************************************************************
//declare Pin
//
DigitalIn sensor1(p8);
DigitalIn sensor2(p7);
DigitalIn counter1p(p5); // Value when counter 1p = 10
DigitalIn counter2p(p6); // Value when counter 2p = 5
DigitalIn SW1p(p11); // Switch for the 1p
DigitalIn SW2p(p12); // Switch for the 2p
DigitalOut valueLED1(p23); // value sensor 2p send to the FPGA
DigitalOut valueLED2(p25); // value sensor 1p send to the FPGA
DigitalOut Reset(p27);
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
DigitalOut clk(p24);
//******************************************************************************
//declare variable
//
bool Position1_1p; // Position 1 for the 1p
bool Position2_1p; // Position 2 for the 1p
bool Position1_2p; // Position 1 for the 2p
bool Position2_2p; // Position 2 for the 2p
bool Motor;
bool bSort_Mode; //to use in the code to define the mode
bool bMaint_Mode; //to use in the code to define the mode
int state;
//******************************************************************************
// declare functions
//
void sensor (void); // Function to read sensors
void state_machine (void); // Function to go in the state machine to move the servos and the motor
//
// 3 servo outputs
//
PwmOut servo_0(p26);
PwmOut servo_4(p22);
PwmOut servo_5(p21);
//
// objects necessary to use the 2*16 character MBED display
//
MCP23017 *par_port;
WattBob_TextLCD *lcd;
//
// Virtual COM port over USB link to laptop/PC
//
Serial pc(USBTX, USBRX);
//******************************************************************************
// Defined GLOBAL variables and structures
//
CMD_STRUCT ext_cmd; // 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,7);
lcd->printf("W3C");
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 1p initialise in position 1
servo_5.pulsewidth_us(1000 + (0 * 1000) / 90); // Servo 2p initialise in position 1
servo_4.pulsewidth_us(0); // Motor stop
Position1_1p = 1;
Position2_1p = 0;
Position1_2p = 1;
Position2_2p = 0;
state = 10;
Reset = 1;
valueLED1=0;
valueLED2=0;
clk=0;
Motor = 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) / 90; // 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 4 : servo_4.pulsewidth_us(pulse_width); break;
case 5 : servo_5.pulsewidth_us(pulse_width); break;
}
last_servo = command->param[0];
break;
//
// return data of the value of sensor 1p and sensor 2p
//
case READ_CMD :
if((bSort_Mode == 0)&&(bMaint_Mode == 1)){ // when we are on sort mode
command->nos_data = 2;
command->result_data[0] = valueLED1;
command->result_data[1] = valueLED2;
}
break;
//
// Mode value
//
case MAINT_MODE : // Maintenance mode
bSort_Mode = 0;
bMaint_Mode = 1;
Reset = 1;
servo_4.pulsewidth_us(0); // Motor stop
servo_0.pulsewidth_us(0); // Servo 1p stop
servo_5.pulsewidth_us(0); // Servo 2p stop
lcd->cls();
lcd->locate(0,7);
lcd->printf("W3C");
lcd->locate(1,0);
lcd->printf("maintenance mode");
break;
case SORT_MODE : // sort mode
bSort_Mode = 1;
bMaint_Mode = 0;
Reset = 0;
state = 10;
lcd->cls();
lcd->locate(0,7);
lcd->printf("W3C");
lcd->locate(1,0);
lcd->printf("sort mode");
break;
//
// Urgency mode
//
case URGENCY :
Reset = 1;
bSort_Mode = 0;
bMaint_Mode = 0;
state = 10;
servo_4.pulsewidth_us(0); // Motor stop
servo_0.pulsewidth_us(0); // Servo 1p stop
servo_5.pulsewidth_us(0); // Servo 2p stop
lcd->cls();
lcd->locate(0,7);
lcd->printf("W3C");
lcd->locate(1,0);
lcd->printf("urgency mode");
break;
//
// Exit mode
//
case EXIT :
Reset = 1;
bSort_Mode = 0;
bMaint_Mode = 0;
state = 10;
servo_4.pulsewidth_us(0); // Motor stop
servo_0.pulsewidth_us(0); // sensor 1p stop
servo_5.pulsewidth_us(0); // sensor 2p stop
lcd->cls();
lcd->locate(0,7);
lcd->printf("W3C");
break;
// Send data of the value led 2p
case VALUE_LED1 :
command->nos_data = 1;
command->result_data[0] = valueLED1;
break;
// Send data of the value led 1p
case VALUE_LED2 :
command->nos_data = 2;
command->result_data[1] = valueLED2;
break;
// Send data of the value counter 1p
case COUNTER1P :
command->nos_data = 3;
command->result_data[2] = counter1p;
break;
// Send data of the value counter 2p
case COUNTER2P :
command->nos_data = 4;
command->result_data[3] = counter2p;
break;
// Send data of the value position1 1p
case POSITION1_1P :
command->nos_data = 1;
command->result_data[0] = Position1_1p;
break;
// Send data of the value position1 2p
case POSITION1_2P :
command->nos_data = 2;
command->result_data[1] = Position1_2p;
break;
// Send data of the motor
case MOTOR :
command->nos_data = 3;
command->result_data[2] = Motor;
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 or 2p are detected
void sensor (void){
sensor1.read();
sensor2.read();
clk = !clk;
wait(0.01);
if(sensor1 > 0.5) {
led1 = 1;
valueLED1 = 1;
}
else if(sensor1 < 0.5){
led1 = 0;
valueLED1 = 0;
}
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 (){
if((bSort_Mode == 1)&&(bMaint_Mode == 0)){
switch(state)
{
case 10 :
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;
Motor = 1;
led3 = 0;
led4 = 0;
state = 0;
break;
case 0: // initial state
Motor = 1;
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
wait(2);
servo_0.pulsewidth_us(1000 + (200 * 1000) / 90); // servo 1p go to position 2
wait(1);
Position1_1p = 0;
Position2_1p = 1;
Motor = 0;
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
Motor = 1;
counter1p.read();
counter2p.read();
if(counter1p > 0.5){
state = 3;
}
else if((counter2p > 0.5)&&(Position1_2p == 1)){
state = 4;
}
else if((counter2p > 0.5)&&(Position2_2p == 1)){
state = 6;
}
break;
case 3: // state 3 if counter 1p = 1
servo_4.pulsewidth_us(0); // motor stop
Motor = 0;
led3 = 1;
if(SW1p == 1){ // wait SW 1p to go to the initial state
servo_0.pulsewidth_us(1000 + (0 * 1000) / 90);
state = 0;
}
break;
case 4: // state 4 if counter 2p = 1
servo_4.pulsewidth_us(0); // motor stop
wait(2);
servo_5.pulsewidth_us(1000 + (200 * 1000) / 90); // servo 2p go to position 2
wait(1);
Position1_2p = 0;
Position2_2p = 1;
Motor = 0;
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
Motor = 1;
counter2p.read();
counter1p.read();
if(counter2p > 0.5){
state = 6;
}
else if((counter1p > 0.5)&&(Position1_1p == 1)){
state = 0;
}
else if((counter1p > 0.5)&&(Position2_1p == 1)){
state = 3;
}
break;
case 6: // state 6 if counter 2p = 1
servo_4.pulsewidth_us(0); // motor stop
Motor = 0;
led4 = 1;
if(SW2p == 1){ // wait SW 2p to go to the initial state
servo_5.pulsewidth_us(1000 + (0 * 1000) / 90);
state = 0;
}
break;
}
}
}
//
//************************************************************************
// Main Program
//
int main() {
init_sys();
Reset = 0;
FOREVER {
timersensor.attach(&sensor, 0.02); //function sensor is reading all the 20 ms
counter1p.read();
counter2p.read();
timerstatemachine.attach(&state_machine, 0.1); // function state machine is readinf all the 100 ms
clk = !clk;
wait(0.001);
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->cls(); lcd->locate(0,0); lcd->printf("W3C"); 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);
}
}