|
|
View previous topic :: View next topic |
Author |
Message |
IceMetal
Joined: 20 Nov 2008 Posts: 79 Location: white Plains, NY
|
servo and photocells |
Posted: Fri Feb 27, 2009 1:49 pm |
|
|
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
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
|
|
Posted: Fri Feb 27, 2009 2:19 pm |
|
|
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
|
|
Posted: Fri Feb 27, 2009 3:16 pm |
|
|
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
|
|
Posted: Fri Feb 27, 2009 4:52 pm |
|
|
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
|
|
Posted: Fri Feb 27, 2009 5:00 pm |
|
|
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
|
|
Posted: Fri Feb 27, 2009 5:04 pm |
|
|
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
|
|
Posted: Fri Feb 27, 2009 5:18 pm |
|
|
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
|
|
Posted: Fri Feb 27, 2009 5:31 pm |
|
|
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
|
|
Posted: Fri Feb 27, 2009 8:23 pm |
|
|
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 |
|
|
|
|
|
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
|