Program for my project

Hi, Jim,
I do not really know what analog servo is. It seems even cheaper than digital servo. I have some servo, like HS-322HD, T Pro MG996R and EXI S1123, are they analog servos?
Thanks.
Yongxin

"All servos receive the same signal which is PPM. The difference is how the signal is processed in the servo and how the servo motor is controlled.

In an analog servo the signal is compared to the current potentiometer position using an analog comparator and then the resulting signal is amplified and sent to the motor, so the servo position is updated as often as a PPM is received or in other words with the frequency of the PPM pulse train which is approximately 50 times per second. In between these 50 times per second the motor is at idle so in general the servo can move.

In a digital servo all the processing is done by a CPU running a specific program (which in some cases can be upgraded). The frequency the motor is driven is not in relation with the incoming PPM signal and is much higher - usually 200-300 times per second. As a result a digital servo has better holding torque.

As far as comparing analog and digital servos by speed, torque, accuracy and power usage - it depends which servos are being compared - a high end coreless analog servo will outperform a low end digital servo in most if not all areas. If everything else is the same - motor, geartrain, bearings, the digital version of the servo will slightly outperform the analog version in speed and torque but will use more power when it does it. For example you can compare Hitec HS-625BB (analog) to HS-5625BB (digital), HS-645BB (ana) to HS-5646BB (dig), HS-635HB (ana) to HS-6635 (dig), HS-475HB (ana) to HS-5475HB (dig) and so on." - RCGroup.

Thank you, Jonny.
It helps me alot.
Yongxin

Q :frowning: :
1.Does Bot Borad II and Basic Atom/Pro have the function that allows me to monitor the servo’s moving status on my PC screen?
2.If I want the my 2nd sevo starts 2 minutes after the first one starts, how can I change the codes?
Thank you.
Yongxin

In all questions like this what have you tried? You can do a simple serout S_OUT to output anything you want which can be displayed in a terminal window on the PC, or you can write code for both sides that uses whatever predefined interface you wish to create, which can be bi-directional…

  1. You issue an HSERVO command to the 2nd servo at the appropriate time. From the adding 1 or 2 things to your list of wants, I can not tell if you are simply experimenting or if you have some specific goals in mind. Also can not tell if it is hobby type thing or, school type project or work related. If work related and your requirements are at all complex you may want to consider hiring a programmer to help out.

From your last comment can not tell what you want the 2nd servo to do, does it swing back and forth like the first 1? does it have the same period? Does it stop for an hour like the first one? At the same time or after some different number of iterations? My guess is you are going to need to setup something like a state machine, or at least emulate it, with maybe keeping, which step you are in the iteration of a servo (Moving left, Moving Right…) the count of how many iterations have been done, time to next step… Then instead of simply sleeping (pause, delay…), you need to figure out which of the servos will need to be serviced next and either loop until that time or calculate a sleep time…

Likewise you need to figure out what your PC interaction will be. If through the standard serial port and you wish for the PC to be able to influence the program, than you need to understand that the BAP will only receive data on that serial port, when the program is in a SERIN for S_IN. There are tricks you can use to have the PC get the BAPS attention (using an interrupt on IRQ0…), but it takes some experimenting to get to work. You can use the Hardware serial port on the BAP to send and receive data asynchronously and have it buffered, but this is not connected to the DB9 connector on the BB2/BAP28 (One is on the Arc32). But on the BAP you can(as I do) hook up something like an XBEE to the hardware serial port (P14/P15) and hook up a 2nd on your PC though maybe a USB adapter… So again you have many options.

So again if you know what it is you wish to do, you should try to write it down as concisely as you can. Then see if you can break each of those requirements down into smaller chunks… Until you can solve each of them…

Kurt

Hi, Kurt,
Thank you very much for your reply.
I would like to tell you my story first. I am a biologist (immunologist exactly) in medical field, so I knew nothing about servo until several months ago and just got a little knowledge about the codes from you guys recently.
I have a private issue that have bothered me for near 20 years. I used to use a device with some common motors and timers to resolve my problem. My freind told me the servo motor has many advantages like smaller, programmable, less noise and so on. I bought some servos, programmers and controllers from Servocity, but its products could not meet my requirements. My freind further suggested me to contact Lynxmotion and so called Jim. Jim told he can help me with Lynxmotion’s products. At first I thought I could get all things done by following the product instruction but I quickly found it is far from that. You already know all remaining things from the conversation in this forum. The current codes you and Jim made have met my bisic needs :smiley: , so I placed some more orders for your products (I assume you are working for Lynxmotion). The reason for me to order more Bot Borad II and Basic Atom/Pro this time is based on my stupid thought in which I can use my old time to control these Bot Borad II and Basic Atom/Pro, and then get each Bot Borad II and Basic Atom/Pro to further control each servo, respectively.
I am now thinking if one contoller can control many (3 different motion types) servos as it is supposed, I can buy less controllers for the “back up” and I may not need to use my old timer.
My all servos are going to do the similar work, like go forth to 180 degrees—pause—back to 0 degree— pause----and repeat but they start at different time with 2-10 minutes intervals. The differences for the servo working status only are the length of travel time and the pause time. I feel I have learnt how to adjust the time in the program you made for me. I wish I can learn how to add one more servo in the same program, in which the relationship of different servo starting times will be fixed and reliable. Such as, 2 minites after servo 1 starts, the servo 2 starts, and 4 minute later, the servo 3 starts…
My old device has a function (meter) which allows me to know (read) the motor rotation speed (roughly). Therefore, if I have a way to know how the servo work by watching my PC screen instead of keeping my eyes on those servos, it would be very convenient for me.
I am not very rich person, so I can not hire people for my project. However, I am willing to pay a certain amount for the service (if it is not too expensive) since I did not realize these two needs when I talked to Jim.
Again, I appreciate all of your help very much and I got a lot fun from the servo and its controller system in addition to their usage. I feel it is becoming my hobby.
Expecting to get more help from you, no matter it is paid or not.
Yongxin

Actually I am a customer and don’t work for Lynxmotion. I do try to help out on the boards and have fun doing so. I am not personally looking to be hired, but only suggested that if your project is complex enough you may want to seek out someone…

If I get a chance I may try to give a few crude version that may get you limping along… But I think it may be easier for you to understand than trying to set up some form of state machine… Not sure of timing of this as I have several other projects I am currently playing with.

Kurt

Hi, Kurt,
When I learnt you are also a customer, I am more grateful for your help. I am in Dallas and can I know where you are? You looks like a computer expert.
It is great enough for me to hear "If I get a chance I may try to give a few crude version that may get you limping along… "
Those two questions might be the last critical two for my current project. In future, I may do something with servo just for fun…
Thanks again.
Yongxin

Here is a Little more complicated program that should be able to handle multiple servos… Not sure if I covered everything here, but should give you a few more hints…

[code]; Program to sweep different servos back and forth over a given time…
NUMSERVOS con 2
; variables and constants associated with system timer
lTimerCnt var long
lCurrentTime var long
WTIMERTICSPERMSMUL con 64 ; BAP28 is 16mhz need a multiplyer and divider to make the conversion with /8192
WTIMERTICSPERMSDIV con 125 ;

STATE_START_CYCLE con 0
STATE_SWEEP_1 con 1
STATE_SWEEP_2 con 2
STATE_LONG_WAIT con 3

ServoState var byte(NUMSERVOS)
ServoTimeNext var long(NUMSERVOS)
ServoLoopCnt var byte(NUMSERVOS)

iServo var byte

SERVO_TABLE bytetable P4, P5
POSITION1_TABLE swordtable -9000, -9000 ; What position to use for each servo for position 1
POSITION2_TABLE swordtable 9000, 9000 ; … Position 2
MOVETIME1_TABLE wordtable 500, 500 ; how much time to go to position 1 in ms
MOVETIME2_TABLE wordtable 500, 500 ; how much time to go to position 2 in ms

; Note the following tables are stored in Timer units. The timer is init to increment every 8192 clock cycles
; so to convert from Clock Cycles(CS) to Milliseconds(ms) we have ms = (cs * 8192)1000/16000000 reduced to cs64/125
; but table is in cs to convert ms to cs we have cs=ms125/64
; note below using defines from other programs as if you run on Arc32 it runs at 20mhz so constants change
INIT_WAIT_TABLE longtable 0, (5000
WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL ; how many ms to delay each servo from starting
TIME1_TABLE longtable (2000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL, (2000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL ; how long the time 1 should be
TIME2_TABLE longtable (2000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL, (2000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL ; likewise for time 2…
LONGWAIT_TABLE longtable (601000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL, (601000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL ; setup long wait time… for me minute…

NUMCYCLES_TABLE bytetable 5, 5

for iServo = 0 to NumServos-1
ServoState(iServo) = STATE_START_CYCLE
ServoTimeNext(iServo) = INIT_WAIT_TABLE(iServo)
ServoLoopCnt(iServo) = 0;
next

; Init our system timer
gosub InitTimer

Loop:
; check to see if any of our servos need handling
gosub GetCurrentTime ; this sets lCurrentTime
for iServo = 0 to NUMSERVOS-1
if lCurrentTime > ServoTimeNext(iServo) then
if ServoState(iServo) = STATE_START_CYCLE then
ServoState(iServo) = STATE_SWEEP_1 ; set up new state
gosub MoveServo[Servo_Table(iServo), POSITION1_TABLE(iServo), MOVETIME1_TABLE(iServo)]
ServoTimeNext(iServo) = ServoTimeNext(iServo) + TIME1_TABLE(iServo) ; set up for when the next time for something to happen

		elseif ServoState(iServo) = STATE_SWEEP_1
			ServoState(iServo) = STATE_SWEEP_2		; set up new state
			gosub MoveServo[Servo_Table(iServo), POSITION2_TABLE(iServo), MOVETIME2_TABLE(iServo)]
			ServoTimeNext(iServo) = ServoTimeNext(iServo) + TIME2_TABLE(iServo)	; set up for when the next time for something to happen

		elseif ServoState(iServo) = STATE_SWEEP_2
			; We completed a complete cycle, lets increment our count of iterations.  If we reach max count we will go into long
			; wait else we will start the next cycle...
			ServoLoopCnt(iServo) = ServoLoopCnt(iServo) + 1
			if ServoLoopCnt(iServo) >= NUMCYCLES_TABLE(iServo) then 
				; set up for the long wait
				ServoTimeNext(iServo) = ServoTimeNext(iServo) + LONGWAIT_TABLE(iServo)	; set up for when the next time for something to happen
				ServoLoopCnt(iServo) = 0 ; reset counter
				HSERVO[Servo_Table(iServo)\-24000\0]	; special number to tell analog servos to power down (send no more signals). 
			endif
			ServoState(iServo) = STATE_START_CYCLE
		endif
	
	endif	

next

goto loop

_MS_Servo var byte
_MS_Pos var sword
_MS_Time var long
MoveServo[_MS_Servo, _MS_Pos, _MS_Time]:
HServo [_MS_Servo_MS_Pos(ABS(_MS_Pos - (HServoPos _MS_Servo))*20)/_MS_Time]
; HServoWait[_MS_Servo]
return

;========================================================================================================
; Note the code below is used to setup a system timer that we use to time maintain the timings in the program
;====================================================================
;--------------------------------------------------------------------
;[TIMER INTERRUPT INIT]
TIMERINT con TIMERAINT
ONASMINTERRUPT TIMERAINT, HANDLE_TIMERA_ASM
InitTimer:
;Timer
; Timer A init, used for timing of messages and some times for timing code…
TIMERINT con TIMERAINT

WTIMERTICSPERMSMUL con 64 ; BAP28 is 16mhz need a multiplyer and divider to make the conversion with /8192
WTIMERTICSPERMSDIV con 125 ;
TMA = 0 ; clock / 8192 ; Low resolution clock - used for timeouts…
lTimerCnt = 0 ; initialize our timer to 0
ENABLE TIMERINT

return

;==============================================================================
;[Handle_Timer_asm] - Handle timer A overflow in assembly language. Currently only
;used for timings for debugging the speed of the code
;Now used to time how long since we received a message from the remote.
;this is important when we are in the NEW message mode, as we could be hung
;out with the robot walking and no new commands coming in.
;==============================================================================
BEGINASMSUB
HANDLE_TIMERA_ASM
push.l er1 ; first save away ER1 as we will mess with it.
bclr #6,@IRR1:8 ; clear the corresponding bit in the interrupt pending mask
mov.l @LTIMERCNT:16,er1 ; Add 256 to our counter
add.l #256,er1
mov.l er1, @LTIMERCNT:16
pop.l er1
rte
ENDASMSUB

;-------------------------------------------------------------------------------------
;==============================================================================
;[GetCurrentTime] - Gets the Timer value from our overflow counter as well as the TCA counter. It
; makes sure of consistency. That is it is very possible that
; after we grabbed the timers value it overflows, before we grab the other part
; so we check to make sure it is correct and if necessary regrab things.
;==============================================================================
GetCurrentTime:
lCurrentTime = lTimerCnt + TCA

; handle wrap
if lTimerCnt <> (lCurrentTime & 0xffffff00) then
lCurrentTime = lTimerCnt + TCA
endif

return lCurrentTime
[/code]

I set it up for 2 servos, but you simply need to change the define for how many servos and add entries to the different tables for additional servos.

Kurt
movenservos.bas (6.38 KB)

Thank you so much, kurt.
I am going to try. For me, This one is much more complicated than previous ones. I got very excited.
Yongxin

hi, Kurt,
Your codes worked great! I made some changes and tested them—so far so good :slight_smile: . I am going to test more modifications and try adding one more servo tomorrow if my third servo comes.
Thank you again.
Yongxin

You are welcome,

FYI - there are some issues with the code.

I am using creating/using a 32 bit timer counter. If my quick calculations are correct, that the 16mhz timer divided by 8192 will overflow the counter in something like 25+ days. For me that is no issue as I never run a program for more than a few minutes, but… If needed there are ways to fix. Could change interrupt code to generate a 64 bit clock, or could add code in that checks the minimum time till the next event and at some point when that is large enough maybe decrement some amount from the timer, plus the wake up times…

Also the code never sleeps… That is it is always spinning waiting for the next event, it does try to free up the servos from using the power of the pulses. So it would not be the most battery efficient code. If that is important, you can update the code that if the minimum time till next event exceeds some threshold, you disable interrupts and then put the processor in some sleep mode for most of that time, then wake up and update your counter/event times and enable interrupts…

Kurt

Kurt,
Thanks.
I found the “pause” is better than “sleep”. During the pause, the servo does not move, but during sleep, the servo keeps frequently vibrating (once/3 seconds). I am using rechargable betteries or AC-DC adaptor, so the power efficiency would not be a big issure.
I do not quite understand “…will overflow the counter in something like 25+ days”. What is going to happen if I keep the servo running over 25 days? automatically stop? or…(this might be a very stupid question, I am afraid of). If it can keep running 60 days, that woud be great. You suggested several ways to fix it, which one is easier? Actually, I have no idea at all for these options.
So, I still need your help.
Yongxin

Quick note: As mentioned in previous posts by Robot Dude, Digital servos can not be easily turned off, there are some exceptions, but… The code I last posted did tell the system to stop generating servo pulses for the servos, when they go into their long sleeps. So in theory you should be able to do sleeps. Not sure however how the HSERVO subsystem works with sleeps. It may still be causing interrupts which will wake up the processor… But if pause works for you…

With the current code, the timer will overflow after about 25+ days. What this means is the variables are 32 bits in length and as such have a maximum value that they can hold, which in this case is: 4,294,967,295
When you add 1 to this value the result will be: 0
Which in the code was cause it to be less than the other values, which will cause their conditions to test properly. After the other values wrap around as well than they will work again. There are some changes that can be done, some simpler than others.

  1. Change precision of the clock. Right now I am keeping timings accurate to about: .512 milliseconds which in your case is probably overkill. So for example if I divide the clock by 4 and make it accurate to about 2.048ms it could run for about 100+ days which is more than your 60. Probably will go this route…

  2. Reset timers at some specific time. This is also somewhat easy. For example in the code that puts the servo to sleep, could add a test to say if this is the last servo in your list, reset the timer value to zero and subtract the current timer from all of the wake up times. This would also be easy to do and keep the current accuracy…

  3. Maintain a timer with more bits than 32, like 64 bits. Not hard, but would require doing some simple 64 bit math, which is not hard, but I would probably do that in assembly language, which makes it less readable to others…

Kurt

Edit: Here is a version of the code using 1) above:

[code]; Program to sweep different servos back and forth over a given time…
NUMSERVOS con 2
; variables and constants associated with system timer
lTimerCnt var long
lCurrentTime var long

; Warning on the timings I am going to further divide the clock value by 4, which will give us a precision of about 2ms,
;but will keep our clock from overflowing for over 100 days…
;This requires changes in, our multiplier below, plus in the timer interrupt and in our GetCurrentTime function.
WTIMERTICSPERMSMUL con 64*4 ; BAP28 is 16mhz need a multiplyer and divider to make the conversion with /8192
WTIMERTICSPERMSDIV con 125 ;

STATE_START_CYCLE con 0
STATE_SWEEP_1 con 1
STATE_SWEEP_2 con 2
STATE_LONG_WAIT con 3

ServoState var byte(NUMSERVOS)
ServoTimeNext var long(NUMSERVOS)
ServoLoopCnt var byte(NUMSERVOS)

iServo var byte

SERVO_TABLE bytetable P4, P5
POSITION1_TABLE swordtable -9000, -9000 ; What position to use for each servo for position 1
POSITION2_TABLE swordtable 9000, 9000 ; … Position 2
MOVETIME1_TABLE wordtable 500, 500 ; how much time to go to position 1 in ms
MOVETIME2_TABLE wordtable 500, 500 ; how much time to go to position 2 in ms

; Note the following tables are stored in Timer units. The timer is init to increment every 8192 clock cycles
; so to convert from Clock Cycles(CS) to Milliseconds(ms) we have ms = (cs * 8192)1000/16000000 reduced to cs64/125
; but table is in cs to convert ms to cs we have cs=ms125/64
; note below using defines from other programs as if you run on Arc32 it runs at 20mhz so constants change
INIT_WAIT_TABLE longtable 0, (5000
WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL ; how many ms to delay each servo from starting
TIME1_TABLE longtable (2000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL, (2000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL ; how long the time 1 should be
TIME2_TABLE longtable (2000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL, (2000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL ; likewise for time 2…
LONGWAIT_TABLE longtable (601000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL, (601000WTIMERTICSPERMSDIV)/WTIMERTICSPERMSMUL ; setup long wait time… for me minute…

NUMCYCLES_TABLE bytetable 5, 5

for iServo = 0 to NumServos-1
ServoState(iServo) = STATE_START_CYCLE
ServoTimeNext(iServo) = INIT_WAIT_TABLE(iServo)
ServoLoopCnt(iServo) = 0;
next

; Init our system timer
gosub InitTimer

Loop:
; check to see if any of our servos need handling
gosub GetCurrentTime ; this sets lCurrentTime
for iServo = 0 to NUMSERVOS-1
if lCurrentTime > ServoTimeNext(iServo) then
if ServoState(iServo) = STATE_START_CYCLE then
ServoState(iServo) = STATE_SWEEP_1 ; set up new state
gosub MoveServo[Servo_Table(iServo), POSITION1_TABLE(iServo), MOVETIME1_TABLE(iServo)]
ServoTimeNext(iServo) = ServoTimeNext(iServo) + TIME1_TABLE(iServo) ; set up for when the next time for something to happen

		elseif ServoState(iServo) = STATE_SWEEP_1
			ServoState(iServo) = STATE_SWEEP_2		; set up new state
			gosub MoveServo[Servo_Table(iServo), POSITION2_TABLE(iServo), MOVETIME2_TABLE(iServo)]
			ServoTimeNext(iServo) = ServoTimeNext(iServo) + TIME2_TABLE(iServo)	; set up for when the next time for something to happen

		elseif ServoState(iServo) = STATE_SWEEP_2
			; We completed a complete cycle, lets increment our count of iterations.  If we reach max count we will go into long
			; wait else we will start the next cycle...
			ServoLoopCnt(iServo) = ServoLoopCnt(iServo) + 1
			if ServoLoopCnt(iServo) >= NUMCYCLES_TABLE(iServo) then 
				; set up for the long wait
				ServoTimeNext(iServo) = ServoTimeNext(iServo) + LONGWAIT_TABLE(iServo)	; set up for when the next time for something to happen
				ServoLoopCnt(iServo) = 0 ; reset counter
				HSERVO[Servo_Table(iServo)\-24000\0]	; special number to tell analog servos to power down (send no more signals). 
			endif
			ServoState(iServo) = STATE_START_CYCLE
		endif
	
	endif	

next

goto loop

_MS_Servo var byte
_MS_Pos var sword
_MS_Time var long
MoveServo[_MS_Servo, _MS_Pos, _MS_Time]:
HServo [_MS_Servo_MS_Pos(ABS(_MS_Pos - (HServoPos _MS_Servo))*20)/_MS_Time]
; HServoWait[_MS_Servo]
return

;========================================================================================================
; Note the code below is used to setup a system timer that we use to time maintain the timings in the program
;====================================================================
;--------------------------------------------------------------------
;[TIMER INTERRUPT INIT]
TIMERINT con TIMERAINT
ONASMINTERRUPT TIMERAINT, HANDLE_TIMERA_ASM
InitTimer:
;Timer
; Timer A init, used for timing of messages and some times for timing code…
TIMERINT con TIMERAINT

WTIMERTICSPERMSMUL con 64 ; BAP28 is 16mhz need a multiplyer and divider to make the conversion with /8192
WTIMERTICSPERMSDIV con 125 ;
TMA = 0 ; clock / 8192 ; Low resolution clock - used for timeouts…
lTimerCnt = 0 ; initialize our timer to 0
ENABLE TIMERINT

return

;==============================================================================
;[Handle_Timer_asm] - Handle timer A overflow in assembly language. Currently only
;used for timings for debuging the speed of the code
;Now used to time how long since we received a message from the remote.
;this is important when we are in the NEW message mode, as we could be hung
;out with the robot walking and no new commands coming in.
;==============================================================================
BEGINASMSUB
HANDLE_TIMERA_ASM
push.l er1 ; first save away ER1 as we will mess with it.
bclr #6,@IRR1:8 ; clear the cooresponding bit in the interrupt pending mask
mov.l @LTIMERCNT:16,er1 ; Add 256 to our counter - Note changed to 64 as we are changing the clock to overflow
add.l #64,er1 ; only after about 100 days instead of 25
mov.l er1, @LTIMERCNT:16
pop.l er1
rte
ENDASMSUB

;-------------------------------------------------------------------------------------
;==============================================================================
;[GetCurrentTime] - Gets the Timer value from our overflow counter as well as the TCA counter. It
; makes sure of consistancy. That is it is very posible that
; after we grabed the timers value it overflows, before we grab the other part
; so we check to make sure it is correct and if necesary regrab things.
; Warning: Changed function to divide clock by 4 to allow a slower overflow…
;==============================================================================
GetCurrentTime:
lCurrentTime = lTimerCnt + TCA/4

; handle wrap
if lTimerCnt <> (lCurrentTime & 0xffffffC0) then ’ Had to modify mask as well as only updating lower 6 bits…
lCurrentTime = lTimerCnt + TCA/4
endif

return lCurrentTime
[/code]

Hi, Kurt,

  1. is great! 2 ms is still very accurate for me. I now have 100 days that is more than 3 months. It is really wonderful. I learnt a lot from you.
    Thank you so much.
    Yongxin

Hi,
One thing is bothering me a lot right now: Every time when I start to run my servo with Bot Board II (for 180 degree moving), the the servo always quickly rotates to 0 degree first, then start its normal program. How can I get rid of the first quick move? I wish all moves are very slow as I programed.
Thank you.
Yongxin

The problem is that when you first turn on your system. The system knows nothing about where the servo is, so it jumps to your first location. One work around is if you know where your servos resting point, tell it go there first and then tell it to move where you want it…

Kurt

Hi, Kurt,
Thank you very much for your reply. So glad hearing from you.

Actually, no matter where I want it go, it always rapidly goes back to 0 degree levels and then start from 0 degree to where I want, except that it is originally at 0 degree.

For example, its position is at +90 degree, I set it starts at +90 degree, and after I switch it on, the servo moves back to 0 degree first, then moves to +90 degree and keeps running normally. Even I set up a “pause” at beginning, after I turn it on, the servo is still running back to 0 degree first, then starts the “pause”.

Do we have a way to fix it? It will be OK as long as we can get rid of the fast move. I do not care where it starts very much.

Thanks again.

Yongxin

It will depend on what you are using. If you are using the SSC32/BotBoard/AtomPro28 then the SSC32 has a startup sequence programmed into. You can change this sequence in the SSC32. If you are using the ARC32 then I’ll need to see your code to see what is causing it.

Thank you, Nathan.
Actually, I do not know what I have is SSC32 or ARC32. Neither is labeled on the boards (cards) I have. Jim recommanded them to me, he must know. All codes I am using could be found in this topic. They were developed by either Jim or Curt and they all cause abrupt move when the servo gets start. Following is an example:

MYSERVO con P4
hsPosition var sword
Position1 con -9000 'about -90 degrees (adjust to desired angle)
Position2 con 9000 'about +90 degrees
Time1 con 5000 '5 second pause value (adjust)
Time2 con 5000 '5 second pause value
HSSpeed con ((Position1-Position2)*20)/3000 ’ This calculates the speed value. 3000 is in ms adjust…
sound 9, [100\880, 100\988, 100\1046, 100\1175]
low 0
HSERVOENABLE ’ I don’t think this is needed any more
hservo[MYSERVO\hsPosition]
start:
toggle P12
hsPosition = Position1
hservo[MYSERVO\hsPosition\HSSpeed]
hservowait[MYSERVO]
pause Time1
toggle P13
hsPosition = Position2
hservo[MYSERVO\hsPosition\HSSpeed]
hservowait[MYSERVO]
pause Time2
toggle p14
goto start

This problem bother me a lot. If you can further help me to get it resolved, I’ll appreciatr it very much.
Yongxin