PDA

View Full Version : Voltage divider to pull-up servo logic line



Thomas Fletcher
06-03-2010, 11:10 PM
I am having trouble getting a servo to work. It responds after about 40 seconds when the control
pin is wired straight to the propeller pin.

I am trying a voltage divider to pull up the signal, but I seem to be getting even less "juice" in. Not
pictured but I placed an led on the control line and it is dimmer with this set-up then wired
directly to the propeller pin.

What am I doing wrong?

I got the resisters a while back at radio shack in a pack. I think they were listed as 1/4w. I am
thinking I am reading the color codes wrong or maybe I am wiring it wrong.

Post Edited (Thomas Fletcher) : 6/3/2010 3:15:11 PM GMT

Mike Green
06-04-2010, 01:01 AM
Most servos should work just fine when wired directly to a Propeller I/O pin. It doesn't make sense that a servo would not respond initially, then respond after around 40 seconds. If it doesn't work with the Propeller's 3.3V logic output, then it should continue to not work. A voltage divider would not help you. If you have to have a 5V signal, you would use a switching transistor as shown in Nuts and Volts Column #6. You'd need to invert the pulses to the switching transistor, but it should be easy to modify whatever code you're using to do that.

hover1
06-04-2010, 01:06 AM
Maybe there is something in your code that is causing a waitcnt to be missed and has to cycle around again, (takes about 50 seconds).

BTW, I never use a resistor or pullups on my servos. I will use a 5K inline with the control signal when using the Propeller Servo Controller Board because of the Voltage Translators.

Thomas Fletcher
06-04-2010, 01:15 AM
I hacked the code together from single servo spin and 3-axis(SPI) Spin demo to make
a camera stabilization platform. The program is suppose to counter rotate the platform
in response to roll angle.

Video
www.facebook.com/profile.php?id=830440549&v=app_2392950137#!/video/video.php?v=451426750549 (http://www.facebook.com/profile.php?id=830440549&v=app_2392950137#!/video/video.php?v=451426750549)

Still can not figure out the start-up delay or why it sometimes just stops working.



CON

_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000

CLKPIN = 7
DATAPIN = 6
CSPIN = 5

X_OFFSETVAL = 28 ' X-Axis offset compensation value
Y_OFFSETVAL = 36 ' Y-Axis offset compensation value
Z_OFFSETVAL = -138 ' Z-Axis offset compensation value

VAR

{ long _X,_Y,_Z,_OldX,_OldY,_OldZ
long Z_Rot_Angle, Old_Z_Rot_Angle
long Y_Rot_Angle, Old_Y_Rot_Angle
long X_Rot_Angle, Old_X_Rot_Angle
}
long Stack[16], x, y, servopos, loaded

OBJ

DEBUG : "Parallax Serial Terminal"
SPI : "MMA7455L_SPI_v2.spin" 'Used to Communicate to the Accelerometer
servo : "Servocontrol"


Pub Init
'Initialize the acceleromter
SPI.start(CLKPIN, DATAPIN, CSPIN)
DEBUG.start(250000)
servo.init

waitcnt(clkfreq/10+cnt) 'Wait for things to settle for a 1/10th of a sec

SPI.write(SPI#MCTL, (%0110 << 4)|(SPI#G_RANGE_2g << 2)|SPI#G_MODE) 'Initialize the Mode Control register

'Write the X, Y, and Z offset compensation values
SPI.write(SPI#XOFFL, X_OFFSETVAL)
SPI.write(SPI#XOFFH, X_OFFSETVAL >> 8)
SPI.write(SPI#YOFFL, Y_OFFSETVAL)
SPI.write(SPI#YOFFH, Y_OFFSETVAL >> 8)
SPI.write(SPI#ZOFFL, Z_OFFSETVAL)
SPI.write(SPI#ZOFFH, Z_OFFSETVAL >> 8)
'loaded := cognew(read8bitdata(@x,@y), @stack)
main
Pub Main
Repeat
Read8BitData
If x < 2 and x > -2
servopos := 137
servo.getposition(servopos)

elseif x < -1
Addtoservoangle
elseif x > 1
Subtractfromservoangle

Showdata

Pub Subtractfromservoangle
if x < 88
servopos := 137 - x
servo.getposition(servopos)
elseif x > 87
servopos := 50
servo.getposition(servopos)

Pub Addtoservoangle
if ~x > - 88
servopos := 137 + ||x
servo.getposition(servopos)
elseif x < - 87
servopos := 225
servo.getposition(servopos)

PUB Read8BitData | count,xtemp,ytemp
count := 1
xtemp := 0
ytemp := 0
repeat until count == 11
count++
xtemp := xtemp + SPI.read(SPI#XOUT8) 'repeat for X-axis
ytemp := ytemp + SPI.read(SPI#YOUT8) 'repeat for Y-axis

x := xtemp / 10
x := ~x

PUB Showdata
DEBUG.Position(20,10)
debug.str(string("X= "))
DEBUG.clearend
debug.dec(x)
DEBUG.Position(20,12)
DEBUG.clearend
debug.str(string("Y= "))
debug.dec(~y)
DEBUG.Position(20,14)
DEBUG.clearend
debug.str(string("servopos= "))
debug.dec(servopos)

Mike Green
06-04-2010, 01:53 AM
What's a "Servocontrol"?

Paul Baker
06-04-2010, 02:18 AM
I believe hover is correct, based on your description of behavior it is likely not enough time is initally added to the timer count value to capture the first event. When this happens the timer must rollover which would account for the initial delay you're experiencing

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Paul Baker (mailto:pbaker@parallax.com)

Thomas Fletcher
06-04-2010, 02:27 AM
Servo control is my changed version of Single Servo Spin



CON
_xinfreq=5_000_000
_clkmode=xtal1+pll16x 'The system clock is set at 80MHz (this is recommended for optimal resolution)

VAR
long position 'The assembly program will read this variable from the main RAM to determine the
' servo signal's high pulse duration
long Stack 'Alot some stack space for the cog running MoveMotor to use


PUB Init
cognew(MoveMotor(1),@Stack) 'Start a new cog and run the MoveMotor method on it that outputs pulses on Pin 7



pub tester
'The new cog that is started above continuously reads the "position" variable as it's changed by the example Spin code below
repeat
position:=50 'Start sending 1ms servo signal high pulses (100 * 10us = 1ms)
waitcnt(clkfreq+cnt) 'Wait for 1 second (1ms high pulses continue to be generated by the other cog)
position:=225 'Start sending 1.38ms servo signal high pulses (Center position)
waitcnt(clkfreq+cnt) 'Wait for 1 second (1.38ms high pulses continue to be generated by the other cog)


PUB getposition(pos)
position:=pos
return

PUB MoveMotor(Pin) 'This method outputs a continuous stream of servo signal pulses on "Pin"
dira[Pin]~~ 'Set the direction of "Pin" to be an output
repeat 'Send out a continous train of pulses
outa[Pin]~~ 'Set "Pin" High
waitcnt((clkfreq/100_000)*position+cnt) 'Wait for the specifed position (units = 10 microseconds)
outa[Pin]~ 'Set "Pin" Low
waitcnt(clkfreq/100+cnt) 'Wait 10ms between pulses

Mike Green
06-04-2010, 02:40 AM
Your listing shows that MoveMotor is being started using a value of 1 for the pin number although the comment says pin 7. The delay you're seeing is because the position variable is initially zero and the waitcnt in MoveMotor will hang up for about 50 seconds per repeat loop until the position variable is changed to some non-zero value. You might initialize it in Init just before you call cognew and that will eliminate the hang up. Alternatively, you could set a minimum position value of maybe 100us which servos will ignore anyway because it's too short. Try this:

waitcnt((clkfreq/100_000)*(position#>10)+cnt)

Thomas Fletcher
06-04-2010, 02:48 AM
That nailed it! Geeez. How do you guys keep all this in your heads?

hover1
06-04-2010, 02:50 AM
"Debug" should be sarted:

PUB start(rxpin, txpin, mode, baudrate)

Your missing you pins and mode.

Jim

Mike Green
06-04-2010, 03:17 AM
Thomas,
It's a matter of learning to think logically, paying attention to details, and trying to forget all those things that we all know have to be a certain way. The most difficult part is the last one.