CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

servo and photocells

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
IceMetal



Joined: 20 Nov 2008
Posts: 79
Location: white Plains, NY

View user's profile Send private message Yahoo Messenger

servo and photocells
PostPosted: Fri Feb 27, 2009 1:49 pm     Reply with quote

I'm trying to make the servo follow the light with a couple of photocells
I'm using the pickit2 and the photocells are connected to RA1 and RA2
and the servo is connected on RD0.
The max voltage from the photocell is 5V when there is light and when
there is no light is 0V, so I have to make the both photocells to read 5V
so the sensor will stop moving and will align with the light. I modified a
code PCM programmer did but still not even close Sad
help please
Code:

#include <16F887.h>

#FUSES NOWDT               
#FUSES NOMCLR
#FUSES NOCPD
#FUSES NOBROWNOUT            
#FUSES XT 
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
/////////////////////////////////////////////////////////////////////////////////

#define LEFT_SERVO_PIN   PIN_D0
#define RIGHT_SERVO_PIN  PIN_D1

#include <servos.c>

//=========================================

void main()
{
int sensor_left, sensor_right;

setup_adc_ports( san1 | san2 );
setup_adc(ADC_CLOCK_DIV_32);

init_servos(); 


while(1)
  {
   set_adc_channel(1);
   delay_us(50);
   sensor_left = read_adc();    
   sensor_left = (sensor_left / 16.2);                     // Get value in 0 to 4 range

   set_adc_channel(2);
   delay_us(50);
   sensor_right = read_adc();    
   sensor_right = (sensor_right / 16.2);                  // Get value in 0 to 4 range


   if(sensor_left >= 4)set_servo(LEFT,  FORWARD, sensor_left);        // Go left
     else set_servo(LEFT, BACKWARD, sensor_right);                    // Go right


   printf("%2x ", sensor_left);
   printf("%2x\r", sensor_right);
delay_ms(500);
  }

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 27, 2009 2:19 pm     Reply with quote

Quote:

sensor_right = read_adc();
sensor_right = (sensor_right / 16.2);

Here you are dividing the ADC value of 0 to 255, by 16.2.
The result can be from 0 to 15. (Also for the left sensor).


Quote:
if(sensor_left >= 4)set_servo(LEFT, FORWARD, sensor_left);
else set_servo(LEFT, BACKWARD, sensor_right);

Here, you use the sensor value (from 0 to 15) as the speed parameter
for the set_servo() function.


But in the servos.c file, shown below, it gives a definition of the function
parameters for the set_servo() function. The speed can be only 0 to 4.
Not 0 to 15.
Quote:
//// void set_servo(int1 side, int1 direction, int8 speed) ////
//// Call to set the speed and direction of a servo ////
//// Inputs: ////
//// 1) LEFT or RIGHT ////
//// 2) FORWARD or BACKWARD ////
//// 3) 0-4 for a speed. 0 is halt in either direction. /


Here is the function. Notice they do a range check on the 'speed'
parameter. If the parameter is greater than 4, the function just
returns. It doesn't do anything. So for most of your speed values
(0 to 15 range), you won't get any result. Not even a warning.
Code:
void set_servo(int1 side, int1 direction, int8 speed)
{
   if(speed < sizeof(servo_speeds)/2)
   {
      if(side)
      {
       .....
      }
      else
      {
       '''''
      }
   }
}
IceMetal



Joined: 20 Nov 2008
Posts: 79
Location: white Plains, NY

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Feb 27, 2009 3:16 pm     Reply with quote

thank you, I will try to write the program this way, maybe is not 5 volts, because when I was reading output I was getting results from 0 to 4.
IceMetal



Joined: 20 Nov 2008
Posts: 79
Location: white Plains, NY

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Feb 27, 2009 4:52 pm     Reply with quote

hi I was trying to do that way, just didnt work, I did the code again, and now when is dark it stops, I'm trying to make it stop when both sensors read 4 but stops when both sensors read 0

Code:

#include <16F887.h>

#FUSES NOWDT               
#FUSES NOMCLR
#FUSES NOCPD
#FUSES NOBROWNOUT            
#FUSES XT 
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
/////////////////////////////////////////////////////////////////////////////////

#define LEFT_SERVO_PIN   PIN_D0
#define RIGHT_SERVO_PIN  PIN_D1

#include <servos.c>

//=========================================

void main()
{
int sensor_left, sensor_right;

setup_adc_ports( san1 | san2 );
setup_adc(ADC_CLOCK_DIV_32);

init_servos(); 

while(1)
  {
   set_adc_channel(1);
   delay_us(50);
   sensor_left = read_adc();    
   sensor_left = (sensor_left / 28.4);                     // Get value in 0 to 4 range

   set_adc_channel(2);
   delay_us(50);
   sensor_right = read_adc();    
   sensor_right = (sensor_right / 28.4);                  // Get value in 0 to 4 range

   if(sensor_right <= 4)set_servo(LEFT,  FORWARD, sensor_right);        // Go left
    if(sensor_left <= 4)set_servo(LEFT, BACKWARD, sensor_left);        // Go right


   printf("%2x ", sensor_left);
   printf("%2x\r", sensor_right);
delay_ms(500);
  }

PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 27, 2009 5:00 pm     Reply with quote

Quote:
sensor_left = read_adc();
sensor_left = (sensor_left / 28.4); // Get value in 0 to 4 range

The value read from the ADC will be from 0 to 255.
Code:

255
----- = 8.97
28.4

This is truncated to 8. So your result will be from 0 to 8.

You are not really getting a value from 0 to 4.
IceMetal



Joined: 20 Nov 2008
Posts: 79
Location: white Plains, NY

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Feb 27, 2009 5:04 pm     Reply with quote

PCM programmer wrote:
Quote:
sensor_left = read_adc();
sensor_left = (sensor_left / 28.4); // Get value in 0 to 4 range

The value read from the ADC will be from 0 to 255.
Code:

255
----- = 8.97
28.4

This is truncated to 8. So your result will be from 0 to 8.

You are not really getting a value from 0 to 4.



PCM Programmer it was my mistake before the sensor with full light they dont get up to 5 volts, so I never get anything over 4 I'm looking at the output with full light now and is 4 and if I cover the light is 0
IceMetal



Joined: 20 Nov 2008
Posts: 79
Location: white Plains, NY

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Feb 27, 2009 5:18 pm     Reply with quote

sorry to keep posting but I'm so close now ,, right now it follows the light from right to center but it doesnt go from center to left
whats wrong????? :(



Code:
while(1)
  {
   set_adc_channel(1);
   delay_us(50);
   sensor_left = read_adc();    
   sensor_left = (sensor_left / 28.4);                     // Get value in 0 to 4 range

   set_adc_channel(2);
   delay_us(50);
   sensor_right = read_adc();    
   sensor_right = (sensor_right / 28.4);                  // Get value in 0 to 4 range

   if(sensor_right <= 4)set_servo(LEFT, BACKWARD , sensor_left);        // Go left
    if(sensor_left <= 4)set_servo(LEFT, FORWARD, sensor_right);        // Go right


   printf("%2x ", sensor_left);
   printf("%2x\r", sensor_right);
delay_ms(500);
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 27, 2009 5:31 pm     Reply with quote

Quote:
I'm trying to make it stop when both sensors read 4 but stops when both sensors read 0

I'm still working on this request.

Quote:
sensor_left = (sensor_left / 28.4);

if(sensor_left > 4) // Limit upper value to 4
sensor_left = 4;


To guarantee that you never give the set_servo() function an illegal
speed value (greater than 4), you should add the test shown in bold
above.


Quote:
sensor_left = 4 - sensor_left; // Invert the values

Then, to invert the values, you can add the code above. This will give
a value of 4, when the initial value is 0. When the input value is 1, you
will get a value of 3, etc.
Quote:

0 4
1 3
2 2
3 1
4 0

You said you wanted it to stop when both sensors read 4. Since the
set_servo() function stops when it gets a speed of 0, the line of code
above will change the order of the speed values to do this.
IceMetal



Joined: 20 Nov 2008
Posts: 79
Location: white Plains, NY

View user's profile Send private message Yahoo Messenger

PostPosted: Fri Feb 27, 2009 8:23 pm     Reply with quote

thank you so much this is the line of code I was looking for and I couldnt figure out, thank you!!!!!!!!!


Code:
sensor_left = 4 - sensor_left; // Invert the values
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group