Final Blog | Qimeng Liu

 The demo vedio

In this project, We create a sweep bin bot with RTOS and station machine. There are two distance sensors in front of the bot to measure distance of a box. If the bot find this bot, the bot chase the box.

There are some testing vedios.
The vedio shows that we test the bot on the ground, and it chase to the box successfully. Even we can not stop it, is always try to chase a soft or wall.
 

This vedio shows that we test the state machine with different box positions. The vedio shows all the the station machine show correct, and it also work on the ground.


The state machine

The one of the most important part is the state machine, it make sure the sweep bin bot doing the right thing with different ADC value from distance sensors.

The state machine code depend on the state machine diagram which from the project objectivity. So in this project, the state machine diagram is shown below:





    
The state machine code includes if( ) or else if( ) with different condition. Like the first state machine is the 
Each if or else if include input and output. The input represent the last stage and which way should the state go. The output in the if or else if and go forward to the next state and get some outcomes.

This is the a part of the state machine, this mean the last state is CHASE_RIGHT and if BOX_GONE and then go these output and go to state RADAR.


Thus, in the state machine code, every if or else if represent a arrow in state machine diagram. The arrow point to the next state.

Thank you Jason for your help. I am really enjoy in your class. I learnt a lot and I think can do better in the future.

The is the whole code of this project:
/////////////////////////////////////////////////////////////////////////
//// ex_rtos_demo_9_basic_kernal.C ////
//// ////
//// This file demonstrates how to create a basic command line ////
//// using the serial port without having to stop the RTOS ////
//// operation. This can also be considered a semi kernal for ////
//// the RTOS. ////
//// ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////

#include <16f877a.h>
#device *=16 ADC=8
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS,DISABLE_INTS)
#use rtos(timer=1,minor_cycle=100ms,)

#include <stdio.h>
#include <stdlib.h>
#include "BENGLCD420.C"
//#include <stdint.h>

#define RED PIN_B5
#define GREEN PIN_A5

#include <string.h>

// this character array will be used to take input from the prompt
char input [10];
// this will hold the current position in the array
int index;
// this will signal to the kernal that input is ready to be processed
int8 input_ready;

int8 task1_toggle=0;
int8 task2_toggle=0;
int8 task3_toggle=0;
int8 task4_toggle=0;
int8 task5_toggle=0;

//input pin pressed
int8 pressed =0;

//pwm signals for motors
int16 pwm1 = 1500; //1500us 1.5ms pwm pinb3
int16 pwm2 = 1500; //1500us 1.5ms pwm pinb4

//inputs
//!#define INPUT_1_ON 1
//!#define BOX 2
//!#define BOX_GONE 3
//!#define BOX_LEFT 4
//!#define BOX_RIGHT 5

//#define INPUT_1_ON      1
//#define INPUT_2_ADC_GREATER_THAN_100 2

//states
#define START 0
#define RADAR 1
#define CHASE 2
#define CHASE_LEFT 3
#define CHASE_RIGHT 4
//!#define STATE_5 5

#define BOX_GONE 0
#define BOX 1
#define BOX_LEFT 2
#define BOX_RIGHT 3

//#define STATE_1 1state machine input
unsigned int8 state_machine_input1 = 0;
//unsigned int8 state_machine_input2 = 0;

//state machine state variable
unsigned int8 state = START;

unsigned int8 input_task2 = 0;
int ctrl = 0;
int8 adc_value1 = 0;
int8 adc_value2 = 0;



//#task(rate=200ms,max=100ms)
//void input1_rtos_task ( );

#task(rate=200ms,max=100ms)
void input2_rtos_task ( );

#task(rate=200ms,max=100ms,queue=2)
void output1_rtos_task ( );

#task(rate=200ms,max=100ms,queue=2)
void output2_rtos_task ( );

#task(rate=100ms,max=100ms,queue=2)
void state_machine_rtos_task ( );


//!void input1_rtos_task ( )
//!{
//!
//!
//!int8 input_task1;
//!
//!while(1)
//!{
//!
//!//send value of switch
//!if( (!input(PIN_A4)) && (pressed == 0) ) // pin is active high low
//!{
//!pressed = 1;
//!
//!input_task1 = INPUT_1_ON;
//!//rtos_msg_send(state_machine_rtos_task,input_task1);
//!
//!}
//!else if(input(PIN_A4))
//!{
//!pressed = 0;
//!}
//!
//!//task debud info on lcd
//!if(task1_toggle == 0)
//!{
//!lcd_gotoxy( 1,1);
//!printf(lcd_putc,"in1 >>%u ",pressed);
//!task1_toggle = 1;
//!}
//!else
//!{
//!lcd_gotoxy( 1,1);
//!printf(lcd_putc,"in1 >>>");
//!task1_toggle = 0;
//!}
//!
//!rtos_yield();
//!}
//!}

void input2_rtos_task ( )
{
//int8 input_task2;
//int8 adc_value1 = 0;
//int8 adc_value2 = 0;
//!int8 box;
//!int8 box_gone1;
//!int8 box_gone2;
//!int8 box_left;
//!int8 box_right;
//!int8 default1;
//!int8 default2;

set_adc_channel(1);
delay_ms(1);

adc_value1 = read_adc();

if(adc_value1 > 120)
{
adc_value1 = 120;
}
if(adc_value1 < 20)
{
adc_value1 = 20;
}

set_adc_channel(2);
delay_ms(1);
adc_value2 = read_adc();

if(adc_value2 > 120)
{
   adc_value2 = 120;
}

if(adc_value2 < 20)
{
   adc_value2 = 20;
}

// Box gone
if (adc_value1 <= 20 && adc_value2 <= 20)
{
   //adc_value1 = 170;
   //adc_value2 = 150;
   //box_gone1 = adc_value1;
   //box_gone2 = adc_value2;
   //rtos_msg_send(state_machine_rtos_task, box_gone1);
   //rtos_msg_send(state_machine_rtos_task, box_gone2);
   rtos_msg_send(state_machine_rtos_task, BOX_GONE);
   printf(" MESSAGE:%u\n\r", BOX_GONE);
}
else if (adc_value1 > 20 && adc_value2 > 20) // change values?
{
   rtos_msg_send(state_machine_rtos_task, BOX);
   printf(" MESSAGE:%u\n\r", BOX);
  //adc_value1 + 80;
  //adc_value2 + 80;
}

else if (adc_value1 > adc_value2 + 20) // change values
{
   rtos_msg_send(state_machine_rtos_task, BOX_LEFT);
   printf(" MESSAGE:%u\n\r", BOX_LEFT);
}

else if (adc_value2 > adc_value1 + 20) // change values
{
   rtos_msg_send(state_machine_rtos_task, BOX_RIGHT);
   printf(" MESSAGE:%u\n\r", BOX_RIGHT);
}

//printf("adc box_gone1: %u\n\r", box_gone1);
//printf("adc box_gone2: %u\n\r", box_gone2);
//printf("adc default1: %u\n\r", default1);
//printf("adc default2: %u\n\r", default2);

// 3. Send processed value
//rtos_msg_send(state_machine_rtos_task, default1);
//rtos_msg_send(state_machine_rtos_task, default2);



// LCD debug unchanged...
}

void output1_rtos_task ()
{
while(1)
{

if(rtos_msg_poll ( )>0)
{
pwm1 = rtos_msg_read ( );
// the function rtos_msg_read, reads the first value in the queue
//printf("messages recieved by out1 : %lu\n\r",pwm1);

pwm1 = pwm1 * 10; // turn 200 into 2000 for us, min should be 100
//printf("messages recieved by out1 : %lu\n\r",pwm1);

// the funciton rtos_msg_send, sends the value given as the
// second parameter to the function given as the first
}


//pwm 1 drive motor 1 on robot pin 36 on pic
output_bit(PIN_B3,1);
delay_us(pwm1);
output_bit(PIN_B3,0);





//task debud info on lcd
////////////////////////
if(task3_toggle == 0)
{
lcd_gotoxy( 1,2);
printf(lcd_putc,"out1 >> ");
task3_toggle = 1;
}
else
{
lcd_gotoxy( 1,2);
printf(lcd_putc,"out1 >>>");
task3_toggle = 0;
}

rtos_yield();
}//end of while 1
}



void output2_rtos_task()
{
unsigned int8 message = 0;

//some reason message ques does not work for another output
// so we will pass to it using a protected variable
while(1)
{
if(rtos_msg_poll ( )>0)
{
pwm2 = rtos_msg_read ( );

// the function rtos_msg_read, reads the first value in the queue
//printf("messages recieved by out2 : %lu\n\r",pwm2);

pwm2 = pwm2 * 10; // turn 200 into 2000 for us, min should be 100
//printf("messages recieved by out1 : %lu\n\r",pwm2);

// the funciton rtos_msg_send, sends the value given as the
// second parameter to the function given as the first
}

//second pwm pin b4 pin 40 on pic
output_bit(PIN_B4,1);
delay_us(pwm2);
output_bit(PIN_B4,0);

//task debud info on lcd
////////////////////////
if(task4_toggle == 0)
{
lcd_gotoxy( 10,2);
printf(lcd_putc,"out2 >> ");
task4_toggle = 1;
}
else
{
lcd_gotoxy( 10,2);
printf(lcd_putc,"out2 >>>");
task4_toggle = 0;
}
rtos_yield();

}//end of while (1)
}

void state_machine_rtos_task()
{
set_adc_channel(1);
delay_ms(1);
adc_value1 = read_adc();
set_adc_channel(2);
delay_ms(1);
adc_value2 = read_adc();

if(rtos_msg_poll ( )>1){

state_machine_input1 = rtos_msg_read ( );
//state_machine_input2 = rtos_msg_read ( );

// the function rtos_msg_read, reads the first value in the queue
//printf("messages recieved by state_mc : %u\n\r",state_machine_input);
// the funciton rtos_msg_send, sends the value given as the
// second parameter to the function given as the first




//state machine here
if((state == START))
   {
   //startup outputs
   adc_value1 = 140;
   adc_value2 = 160;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
   
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"RADAR");
   
   state = RADAR;
   }

else if ((state == RADAR)&& state_machine_input1 == BOX)
   {
   //outputs
   adc_value1 = 100;
   adc_value2 = 100;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
   
   lcd_putc('\f');
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"CHASE");
   
   state = CHASE;

}
else if((state == CHASE)&& (state_machine_input1 == BOX_LEFT))
   {
   //outputs
   adc_value1 = 140;
   adc_value2 = 160;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
   
   lcd_putc('\f');
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"CHASE LEFT");
   
   state = CHASE_LEFT;
   }
   
else if((state == CHASE)&& (state_machine_input1 == BOX_RIGHT))
   {
   //outputs
   adc_value1 = 160;
   adc_value2 = 140;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
   
   lcd_putc('\f');
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"CHASE RIGHT");
   
   state = CHASE_RIGHT;
   }
   
else if((state == CHASE_LEFT)&& (state_machine_input1 == BOX))
   {
   //outputs
   adc_value1 = 100;
   adc_value2 = 100;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
   
   lcd_putc('\f');
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"CHASE (L)");
   
   state = CHASE;
   }
   
else if((state == CHASE_RIGHT)&& (state_machine_input1 == BOX))
   {
   //outputs
   adc_value1 = 100;
   adc_value2 = 100;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
   
   lcd_putc('\f');
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"CHASE (R)");
   
   state = CHASE;
   }
else if((state == CHASE_LEFT)&& (state_machine_input1 == BOX_GONE))
   {
   //outputs
   adc_value1 = 140;
   adc_value2 = 160;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
   
   lcd_putc('\f');
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"RADAR (L)");
   
   state = RADAR;
   }
else if((state == CHASE_RIGHT)&& (state_machine_input1 == BOX_GONE))
   {
   //outputs
   adc_value1 = 160;
   adc_value2 = 140;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
                                                                  
   lcd_putc('\f');
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"RADAR (R)");
   
   state = RADAR;
   }
else if((state == CHASE)&& (state_machine_input1 == BOX_GONE))
   {
   //outputs
   adc_value1 = 160;
   adc_value2 = 140;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
   
   lcd_putc('\f');
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"RADAR (CHASE)");
   
   state = RADAR;
   }
else if((state == CHASE_LEFT)&& (state_machine_input1 == BOX_GONE))
   {
   //outputs
   adc_value1 = 160;
   adc_value2 = 140;
   
   rtos_msg_send(output2_rtos_task,adc_value1);
   rtos_msg_send(output1_rtos_task,adc_value2);
   
   lcd_putc('\f');
   lcd_gotoxy( 1,4);
   printf(lcd_putc,"RADAR (L)");
   
   state = RADAR;
   }
 }
}
   
//!//task debud info on lcd
//!if(task5_toggle == 0){
//!{
//!lcd_gotoxy( 1,3);
//!printf(lcd_putc,"state_mc >> ");
//!task5_toggle = 1;
//!}
//!else
//!{
//!lcd_gotoxy( 1,3);
//!printf(lcd_putc,"state_mc >>> ");
//!task5_toggle = 0;
//!}
//!}

void main ( ) {

// initialize input variables
index=0;
input_ready=FALSE;

//initialise portb to be outputs
SET_TRIS_B( 0x00 );

//initialse pin a4 to be an input
SET_TRIS_a( 0xdf ); // 11011111

//initialise pin a0 as analog input and select ad channel 0
setup_adc(ADC_CLOCK_INTERNAL );
setup_adc_ports( AN0 );
set_adc_channel(0);

// initialize interrupts
enable_interrupts(int_rda);
enable_interrupts(global);


//init lcd
lcd_init();
lcd_putc('\f');
printf ( "starting..rtos" );
lcd_gotoxy( 1,4);
printf (lcd_putc, "starting..rtos" );
delay_ms(1000);
lcd_putc('\f');


rtos_run();
}




Comments

Popular posts from this blog

Blog 1 - Igor Kapusniak

Blog 5 - Bin Bot Project - Davin Barron