View previous topic :: View next topic |
Author |
Message |
Jiewy
Joined: 27 Apr 2010 Posts: 8 Location: Penang Malaysia
|
Servo motor reactive to light |
Posted: Sun Sep 26, 2010 11:45 pm |
|
|
Hello guys, I need some help on my project.
I would like to create a motor that is reactive to light. I am placing 3 photo resistor and based on the readings of these three sensors, the motor will rotate to 3 directions.
I can read the readings of the 3 photo resistor but I am having problem figuring out how to make the motor rotate to the 3 directions as in how to set the three directions. I am using servo motor.
Can someone pls help me by giving me some ideas! Thank you. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Mon Sep 27, 2010 4:31 pm |
|
|
First when you say 'servo motor' , do you really mean a the typical hobby RC servo motor?
Second, since you can read the 3 inputs, just cut code that compares them to see who is brightest and then use that data to command the 'servo' where to go.
Again how you control the servo depends upon what TYPE of servo it is. All RC style servos do NOT have any feedback to the program so there's no confirmation as to it's real position relative to the command unlike 'real' servos. |
|
|
kd5uzz
Joined: 28 May 2006 Posts: 56
|
|
Posted: Wed Oct 06, 2010 5:32 pm |
|
|
Most RC style servos expect a pulse to determine what position they rotate to.
This pulse needs to be repeated 20 times a second (1 second = 1000miliseconds, so 1000/20 = 50, so once every 50ms).
Most servos expect this pulse to be between 0.5ms and 2.5ms (500us to 2500us).
A delay of 1.5ms (1500us) is normally about center. The exact value for center depends on the servo.
Code: |
While (TRUE){
output_high(PIN_A1);
delay_us(500);
output_low(PIN_A1);
delay_ms(49);
delay_us(500);
}
|
This should instruct the servo (connected to PIN_A1) to move all the way in one direction.
This is not the best way to do this, and I have not actually tried this code.
Similarly, the code below would instruct the servo to move all the way in the other direction.
Code: |
While (TRUE){
output_high(PIN_A1);
delay_ms(2);
delay_us(500);
output_low(PIN_A1);
delay_ms(47);
delay_us(500);
}
|
Note the delay_ms(47) + delay_us(500) = 4750us = 47.5ms.
Also that delay_ms(2) + delay_us(500) = 250us = 2.5ms.
Then that 47.5ms + 2.5ms = 50ms.
You want the entire loop to take right at 50ms to execute to get the "correct" timing.**
Be aware that most servos have mechanical stops that may prevent them from moving to these positions and that attempting to move too far in either direction could damage the servo.
In my experience a range of 750 to 2250 works well.
I usually use a 3.x compiler and there are problems using a variable to pass large values into a delay_us or delay_ms function. But from what I understand the 4.x compilers do not have the same limits and this may allow you to simply use a call such as:
instead of:
Code: |
delay_ms(2);
delay_ms(500);
|
to get the same delay.
As was stated, there is no feed back, so you can not ever be sure a servo has done what you ask, only that it is 'trying'. Try experimenting with the time it takes to move from 750 to 2250 - I expect it is more than a second or even two.
Good luck!
**While the spec I used to get this working states the pulse should be repeated every 50ms, you can update more often. The more often you update the 'stronger' the servo will try to move to that position. However, if you repeat it too often then the servo will get confused. |
|
|
|