Blog 6 - Final Blog
Blog 6 | Final Specification and Blog
In this blog this steps towards getting the state machine functional will be dicussed along with the current state of the state machine and sweeper bot. Also discussed will be a proposal on what could be done to the bot in the future as we have a few ideas.
Sensors
Since the start of the sprint we needed to get the sensors to operate correctly since the beginning of the project. We have sinced traced back the wires and got readings from them. Reading the values and having the state machine do something with the readings was the next task. As we already know we need to send 100ms for backwards, 150ms for backwards and 200ms for forward. Once we got the readings we needed to set some thresholds due to the nature of the sensors not reading perfectly. We did the following:
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;
}
We found that setting a threshold for the values made the sweeper bot operate better in this range as it stopped any noisey signals from coming in. After this we were then able to sort out the motors using the ADC values.
State Machine
How does the state machine operate?
On start up or when the sweeper bot is automatically started on Radar mode so it can look for the box straight away. In Radar mode it spins around on its axis to search for a box. It will only jump to Chase mode when both sensors are equal or within a small range of each other to which it goes full forward to the box. As you can see in the state machine diagram the values are inverted since the sensors we are using are mouted opposite to the motors. So we do the opposite forward is 100 and backwards is 200.
When in Chase, if the box disappears when turning left/right it will stay turning left/right in a hunt radar mode so whichever way it was turning when it got lost by the sensors it will stay turning in that direction until both sensors pick up a value to then it will go back to Chase mode. And also if in Chase Left or Right it will go to Chase (full forward) when the sensors both pick up the values.
This state machine allows for all possibilities that we tested when we first implemented the state machine into the code which was very basic and we found out quickly and implemented into the code quite quickly that if we didnt have the feedback or additional states it would get stuck in a state or just not do what we wanted it to do.
Videos:
Code
The code I liked doing the most as I felt I code learn a lot from the state machine and it helped me to underatand it better. From the original code I had I didn't have it acting as a state machine, more running off an IF statement which was used to send messages to the already functioning code. This worked but wasn't what we wanted. So we then improved the code and sat down with Jason to go over how it should be done together. This helped my understanding of the operation of it much better and overall of how state machines work.
Thank you:
Just want to say thank you to everyone involved in this project I had so much fun doing this project with everyone involved I learned a lot academically but also learned more about team work which is an important skill to learn.
Thank you to Jakub, Yoma, Sean, Jiaju, Qimeng and Tao.
And of course a massive thank you to Jason the best lecturer :)
Code:
#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
Post a Comment