Society of Robots - Robot Forum

Software => Software => Topic started by: otai92 on January 27, 2013, 03:35:48 AM

Title: wall following robot using analog distance sharp sensor
Post by: otai92 on January 27, 2013, 03:35:48 AM
hello, I m try to make wall following robot using analog distance sharp sensor and I use PIC 18F452 for the compiler I use MIKROC . I Have trouble in  programming , I cannot set the distance for the sensor
this my code

#define suis1 PORTB.F0
///////output////////////
#define led1 PORTB.F6
#define led2 PORTB.F7
#define motold PORTC.F4
#define motolb PORTC.F5
#define motord PORTC.F6
#define motorb PORTC.F7
#define speedr                        CCPR1L
#define speedl                        CCPR2L
// Lcd pinout settings
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
// Pin direction
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
///////////define funtion///////////
void mula();
void adc0_display ();
void adc2_display ();
void forward(int l,int r);
void right(int l,int r);
void left(int l,int r);
void wallfollow();
void stop();
//////intial variable///////
int ADC_Value0,ADC_VaLue2,ad1,ad2,ad3,ad4;
int ad5,ad6,ad7,ad8;
void main()
{
  mula();
  Lcd_Init();                     // Initialize LCD
  Lcd_cmd(_LCD_CURSOR_OFF);
  lcd_out(1,1,"miroc");
  delay_ms(1000);
  Lcd_Cmd(_LCD_CLEAR);
  lcd_out(1,1,"ad1=");
  lcd_out(2,1,"ad2=");
  while(1) //infinate loop
  {
    adc0_display ();
    adc2_display ();
    if(suis1==0)
    {
      while(1)
      {
         wallfollow();
      }

    }


  }

}
void mula()
{
  TRISA=0b000000111; // define input or output
  TRISB=0b000000001;
  TRISC=0b000000000;
  TRISD=0b000000000;
  TRISE=0b000000000;
  ADCON1=0b000000000; // set input PORTA become become analog
  PR2=255;
  CCP1CON = 0b00001100;                //to generate PWM @ ccp1 and ccp2
  CCP2CON = 0b00001100;
  T2CON   = 0b00000110;                //on timer 2 to power up PWM
  speedl=speedr=0;
  motord=0;
  motorb=0;
  motold=0;
  motolb=0;
  led1=led2=0;
}
void adc0_display ()
{
    ADC_Value0= ADC_Read(0);
    ad1=ADC_value0/1000 +48;
    lcd_chr(1,5,ad1);
    ADC_value0%=1000;
    ad2=ADC_value0/100 +48;
    lcd_chr(1,6,ad2);
    ADC_Value0%=100;
    ad3=ADC_value0/10 +48;
    lcd_chr(1,7,ad3);
}

void adc2_display ()
{
    ADC_Value2= ADC_Read(2);
    ad5=ADC_value2/1000 +48;
    lcd_chr(2,5,ad5);
    ADC_value2%=1000;
    ad6=ADC_value2/100 +48;
    lcd_chr(2,6,ad6);
    ADC_Value2%=100;
    ad7=ADC_value2/10 +48;
    lcd_chr(2,7,ad7);
}
void forward(int l,int r)
{
  motord=1;
  motorb=0;
  speedr=r;

  motold=1;
  motolb=0;
  speedl=l;
}
void right(int l,int r)
{
  motorb=1;
  motord=0;
  speedr=r;

  motold=1;
  motolb=0;
  speedl=l;
}
void left(int l,int r)
{
   motord=1;
   motorb=0;
   speedr=r;

   motolb=1;
   motold=0;
   speedl=l;
}
void stop ()
{
   motord=0;
   motolb=0;
   speedl=0;
   speedr=0;
}
void wallfollow()
{

     adc0_display ();
     adc2_display ();
     if(ADC_Read(0)==ADC_Read(2))
      {
       while(ADC_Read(0)==ADC_Read(2))
        {
        led1=led2=1;
        forward(255,230);
        }
      }
      else if((ADC_Read(0)>ADC_Read(2))&&(ADC_Read(0)>40)&&((ADC_Read(2)>40)))
      {
       while((ADC_Read(0)>ADC_Read(2))&&(ADC_Read(0)>40)&&((ADC_Read(2)>40)))
        {
        led1=led2=1;
        forward(255,235);
        }
      }
      else if((ADC_Read(0)<ADC_Read(2))&&(ADC_Read(0)>40)&&((ADC_Read(2)>40)))
      {
       while((ADC_Read(0)<ADC_Read(2))&&(ADC_Read(0)>40)&&((ADC_Read(2)>40)))
        {
        led1=led2=1;
        foward(255,235);
        }
      }
     else if ((ADC_Read(0)>40)&&(ADC_Read(2)<40))
      {
        while ((ADC_Read(0)>40)&&(ADC_Read(2)<40))
        {
          led1=1;
          left(170,220);
        }
      }
     else if ((ADC_Read(0)<40)&&(ADC_Read(2)>40))
      {
         while ((ADC_Read(0)<40)&&(ADC_Read(2)>40))
         {
           led2=1;
           right(220,170);
         }
      }
      else
       {
          led1=led2=0;
          foward(255,235);
       }
}


I Hope any body can help me urgent , tq :)
Title: Re: wall following robot using analog distance sharp sensor
Post by: waltr on January 27, 2013, 12:15:16 PM
I use PICs but not MIKROC. You need to debug your code and hardware. To do this break it down into functional sections.

1- Is the Sharp distance sensor working properly? Measure its output with a Voltmeter and ensure that the output Volt changes with distance. Is the Sharp's output Voltage in a proper range for the PIC (0 to 5V)?

2- Is the ADC setup and working correctly? Connect a 10k pot across Vdd to Vss with the wiper to the ADC input. Read the ADC and output the upper 8-bits to a Port (you can connect to Port to LEDs or measure the Voltage of each pin to determine to 8-bit value). Is the correct value output? Does the value change when the pot is turned?
These are the two common problem areas for beginners.

Does MIKROC have any debugging capability? Either a Simulator or in-circuit?
I use Microchip's MPLAB IDE, HiTech C and a PICKit2. With these I can run the code in a Simulator to catch coding errors then run the PIC with the PICKit 2 as an in-circuit debugger.
Title: Re: wall following robot using analog distance sharp sensor
Post by: otai92 on January 27, 2013, 08:49:07 PM
tq for your advise , my sensor can work properly, I can get voltage value change with distance  from that sensor. For the ADC setup , before this I use the variable resistor .The adc value can change from 0 to 1023. The problem is I m try to set my robot only can detect wall when the sensor detect let say distance between robot and wall around 3 inch but I cannot set that distance for my robot. I only can set above 3 inch. I don't know how to set the shorter distance between robot and wall. I want my robot only detect wall near with it. hope you can help me tq  :).
Title: Re: wall following robot using analog distance sharp sensor
Post by: jkerns on January 28, 2013, 09:16:44 AM
Those sensors do not tend to behave well when you get too close to the wall: http://www.sparkfun.com/datasheets/Components/GP2Y0A21YK.pdf (http://www.sparkfun.com/datasheets/Components/GP2Y0A21YK.pdf) see figure 5.

Do you know exactly how the sensor behaves at the distances you want to measure? If you cross the peak output then your algorithm may work backwards in terms of which direction you turn in response to the votlage being too high or too low. But, the problem is that it is not easy to know which side of the curve you are on.
Title: Re: wall following robot using analog distance sharp sensor
Post by: waltr on January 28, 2013, 09:51:54 PM
And which of the Sharp sensors are you using?
As jkerns pointed out to look at the graph in the Sharp data sheet for the minimum distance for the Sharp sensor you have.

You may want to output the RAW ADC values from the Sharp sensor to your LCD. Then you can get a good idea of the values as the Bot approaches a wall.

I do not follow the 'wallfollow' function. Maybe it is too complicated. Could you start with a simpler function?
Title: Re: wall following robot using analog distance sharp sensor
Post by: otai92 on January 28, 2013, 10:56:31 PM
tq  :) . I know the sensor have range of detection, if out from the range,  sensor cant work properly. I think my problem is my programming .
this is simple programming i give

#define suis1 PORTB.F0
///////output////////////
#define led1 PORTB.F6
#define led2 PORTB.F7
#define motold PORTC.F4
#define motolb PORTC.F5
#define motord PORTC.F6
#define motorb PORTC.F7
#define speedr                        CCPR1L
#define speedl                        CCPR2L
// Lcd pinout settings
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
// Pin direction
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
///////////define funtion///////////
void mula();
void adc0_display ();
void adc2_display ();
void depan(int l,int r);
void kanan(int l,int r);
void kiri(int l,int r);
//void pusing_kiri();
//void pusing_kanan();
void wallfollow();
void stop();
//////intial variable///////
int ADC_Value0,ADC_VaLue2,ad1,ad2,ad3,ad4;
int ad5,ad6,ad7,ad8;
void main()
{
  mula();
  Lcd_Init();                     // Initialize LCD
  Lcd_cmd(_LCD_CURSOR_OFF);
  lcd_out(1,1,"miroc");
  delay_ms(1000);
  Lcd_Cmd(_LCD_CLEAR);
  lcd_out(1,1,"ad1=");
  lcd_out(2,1,"ad2=");
  while(1) //infinate loop
  {
    adc0_display ();
    adc2_display ();
    if(suis1==0)
    {
      while(1)
      {
         
     if(ADC_Read(0)==ADC_Read(2))
      {
       while(ADC_Read(0)==ADC_Read(2))
        {
        led1=led2=1;
        forward(250,230);
        }
      }
     else  if((ADC_Read(0)>40)&&(ADC_Read(2)<40))
      {
        while((ADC_Read(0)>40)&&(ADC_Read(2)<40))
        {
          led1=1;
          left(180,200);

        }
      }
     else if ((ADC_Read(0)<40)&&(ADC_Read(2)>40))
      {
         while ((ADC_Read(0)<40)&&(ADC_Read(2)>40))
         {
           led2=1;
           right(200,180);

         }
      }


      else
       {
          led1=led2=1;
          foward(250,230);
       }
      }

    }


  }

}
void mula()
{
  TRISA=0b000000111; // define input or output
  TRISB=0b000000001;
  TRISC=0b000000000;
  TRISD=0b000000000;
  TRISE=0b000000000;
  ADCON1=0b000000000; // set input PORTA become become analog
  PR2=255;
  CCP1CON = 0b00001100;                //to generate PWM @ ccp1 and ccp2
  CCP2CON = 0b00001100;
  T2CON   = 0b00000110;                //on timer 2 to power up PWM
  speedl=speedr=0;
  motord=0;
  motorb=0;
  motold=0;
  motolb=0;
  led1=led2=0;
}
void adc0_display ()
{
    ADC_Value0= ADC_Read(0);
    ad1=ADC_value0/1000 +48;
    lcd_chr(1,5,ad1);
    ADC_value0%=1000;
    ad2=ADC_value0/100 +48;
    lcd_chr(1,6,ad2);
    ADC_Value0%=100;
    ad3=ADC_value0/10 +48;
    lcd_chr(1,7,ad3);
}

void adc2_display ()
{
    ADC_Value2= ADC_Read(2);
    ad5=ADC_value2/1000 +48;
    lcd_chr(2,5,ad5);
    ADC_value2%=1000;
    ad6=ADC_value2/100 +48;
    lcd_chr(2,6,ad6);
    ADC_Value2%=100;
    ad7=ADC_value2/10 +48;
    lcd_chr(2,7,ad7);
}
void foward(int l,int r)
{
  motord=1;
  motorb=0;
  speedr=r;

  motold=1;
  motolb=0;
  speedl=l;
}
void right(int l,int r)
{
  motorb=1;
  motord=0;
  speedr=r;

  motold=1;
  motolb=0;
  speedl=l;
}
void left(int l,int r)
{
   motord=1;
   motorb=0;
   speedr=r;

   motolb=1;
   motold=0;
   speedl=l;
}
void stop ()
{
   motord=0;
   motolb=0;
   speedl=0;
   speedr=0;
}

can you all give me simple coding that you did it for wall follow robot using that sensor or give me the best link/website for wall follow robot programming . Thank you again to waltr and jkerns because your relpy :) .