AXE171 board and 2 servos

Garahbara

New Member
Hi all,
I've tried and tried and tried to get this to work. But it's time to ask.

Running the AXE171 project board with the SPE035 sound module. (Picaxe 14M2 processsor)

I need to operate 2 servos concurrently to open/close railway gates either side of the track.

The board provides for Pins B1 and B3 for servo operation.

One servo, on either pin works fine. Try to run both pins, alternating SERVOPOS commands between pins results in either servo to judder/jolt to another position then immediately returning to the correct position. The judder/jolt seems to be randon, and occurs every 5, 10, 20 seconds, or so.

If I use a high ranges of servopos (say 180 thru 220) the judder/jolt occurs more often. If I use a lower range of servopos (say 75 thru 120) the judder/jolt is far less frequent. Placing a "pause" ( 20 - 50 ms) inbeteen each servopos also reduces the frequecy of the judder/jolt as the pause period increases. But I'm unable to eliminate the judder/jolt when running both servo pins. Any higher on the "pause" here and the gates operate too slowly.

If I code for just using either pin (not both at the same time) there is no judder/jolt at all, ever, even with both servos plugged in.

The codes is in a loop.

While servopos_ctr < x
Servopos_ctr = servopos_ctr + 1
Servopos B.1, Servopos_ctr
Pause
Servopos B3, Servopos_ctr
Pause
endloop


Yes, I do a "servo pin, initial position" to set them up.
Yes, I know....... But I'm running both servos off the 3 pins on the AXE171 board for B1 & B3. ( pins for "pin", V+, V0)

The manual tells me the servopos and servo command will continually pulse the servo pins every 20ms with the the pulse length according to the position needed.

My question...... Will the Picaxe14M2 operate correctly and schedule and execute correctly and concurrently TWO, servo pin's pulses? Or is it limited to reliably operating and pulsing continually, just 1 servo pin at a time?

Should I turn one servo pin "OFF" before using the other? (and use servo, rather than servopos, of course)

i.e.

While servopos_ctr < x
Servopos_ctr = servopos_ctr + 1
Servo B.1, Servopos_ctr
Servo B1, OFF
Pause
Servo B3, Servopos_ctr
Servo B3, OFF
Pause
endloop


Any assistance much appreciated.

Thanks,

Alan.

TOOT!
 

lbenson

Senior Member
I don't know if it is your problem, but many have encountered judder with servopos, and have cured it by using pulsout. Here's my code for adjusting a pan and tilt camera--working for the last 12 years:
Code:
servoOut:  ' smoothly move from lastSpot
  b2 = activeSpot - lastSpot
  b3 = 1
  if activeSpot < lastSpot then
    b2 = lastSpot - activeSpot
    b3 = $FF   ' minus one
  endif
  sertxd("Servo: ",#activeServo," pos: ",#activeSpot, cr,lf)
'  serout 0,N2400,(#b2, " ", #b3, " ", #lastSpot, " ", #activeSpot,10,13)
  activeSpot = lastSpot
  for b4 = 1 to b2       ' move smoothly to new activeSpot
    activeSpot = activeSpot + b3
'  serout 0,N2400,(#b4, " ", #b3, " ", #b2, " ", #activeSpot,10,13)
      pulsout activeServo,activeSpot
      pause 20
      pulsout activeServo,activeSpot  ' twice seems to make it work
      pause 20
  next b4
  lastSpot = activeSpot
  return
This code is ancient, so has some clunkiness (e.g., I wouldn't now use the raw variable names b2,b3,b4). The code which calls this routine keeps track of the two servos and sets activeServo, activeSpot, and lastSpot as desired before calling the routine. One possible issue is that the code does not send a continuous pulse. This has worked fine for my servos, but apparently some do not hold the last position set if there is not a continuous train.

I found that I had to send the pulsout twice to get the servo to respond. You may need to insert a pause before "next b4" to adjust the speed at which you move the servo.
 

Eng460

Well-known member
As I understand it, you can only run one servo at a time. Apparently there is only one timer in the chip. While both servo commands occur at slightly different times there is no problem, but if both operate at the same time, every now and then the pulses to each will occur at the same time and this will upset the pulse length and cause that very puzzling jitter.

The pulse to a servo is normally repeated about every 20 mS to maintain position, the gap not being terribly critical, (only the actual pulse length is critical), so using the pulsout required alternately to each servo in a loop is a possible solution. Other routines to detect the trains could be included in the loop so long as you allow for the timing to not extend the time between servo pulses too much. Hippy explained this very well in response to my recent query about timing issues with an 08M2+, where use of Pulsin in the same program caused similar issues. Apparently the larger chips also have this single timer limitation. The solution in my case was to use a separate 08M2+ to operate as a servo driver, using hserin to receive the required pulse length from the main board. The servo driver uses pulsout and pauseus commands to send a pulse every 20 mS.

Alternatively for railway gates, it might be possible to operate all the gates at a single crossing from one servo, using bell crank’s and wire links under the board if they are accessible.

(The exact title of my thread was “Timing conflicts with servo and serout on 08M2+”, easily found with the find threads tab. It turned out that the serout was not the problem, but that is a separate issue.)

Eng460
 
Last edited:

goom

Senior Member
Maybe I'm missing something, but would it not make sense to send the servo command pulses to each servo from a single Picaxe output pin? Assuming that the 2 servos are identical, and have the same linkage geometry, then they should move both crossing gates in synchrony.
 

AllyCat

Senior Member
Hi,

Personally I've never used two servos at the same time so can't give a definitive answer and certainly the topic of servo "twitches" is quite common on this forum. However, I would expect it to be possible to avoid them by one method or another, and NOT to switch the Servo Pulses OFF.

Firstly, if starting with a "blank sheet of paper", I would allocate the servos to pins b.2 and b.4. They are two of the PWM (hardware) outputs, which could potentially give absolutely "rock solid" pulses, albeit with a few minor configuration restrictions. But let's assume we must use b.1 and b.3......

Next, I would design my software "polling" loop to repeat approximately (or exactly) every 20 ms. That would allow the use of a pair of PULSOUT commands to drive the two servos, a method which has often been described to be a solution to the issue. But IMHO the "best" solution is to make the "intended" commands work correctly! So I set up a simple test using the famous DPScope. ;) Note in particular the "persistence" option and the "CH1" trigger on the earlier of the two pulses.

The test code is shown below, and the first thing that the 'scope shows is that the two pulses are generated consecutively, with about a 96us delay between them (note the two vertical green cursors show the earliest end of the first pulse and the start of the second pulse). I've commented out an intermediate pulse which can demonstrate how the pulses are sequenced. The program is arranged so that the two pulses are complementary, thus the second pulse should always terminate at exactly the same time after the first starts (i.e from the 'scope trigger signal). Usually that happens, but very occasionally (with my test setup) the falling edge becomes "doubled", for perhaps one pulse each minute. That suggests a small timing error which might be clue, but you would need to see if there is any correlation between it, and any twitch on either of the servos.

Code:
#picaxe 14m2
#no_data
#terminal 4800
symbol tempw = w1
symbol tempb = b4                   ; Temporary byte variable
symbol index = b5
symbol TMR1H = $17               ; SFR Timer 1 High byte (~256 us units)

pause 1000
call showVdd
do  
    for b0 = 75 to 225 step 5           ; Step avoids traces merging
        b1 = 300 - b0
        servo b.3 , b0
;        servo b.4 , 75                         ; Optional
        servo b.5 , b1
        pause 500
;        peeksfr TMR1H,tempb        ; Present value in Timer1
;          do                                      ; Synchronise loop to Timer 1
;            index = tempb
;            peeksfr TMR1H,tempb
;         loop while tempb > index    ; Loop until timer overflows
;        pause 10                                ; Wait for the Servo pulses to be generated
    next
loop

symbol Vdd = s_w2                                 ; Measured Supply voltage (normally in mV)
symbol CALVDD18 = 58254                    ; Trim value to calibrate Vdd, nominally 1024 * 1024 / 18 = 58254
showVdd:                                         ; A Standard header for testing
    calibadc10 tempw  
    Vdd = tempw / 2 + CALVDD18 / tempw            ; Round up numerator by adding divisor / 2
    calibadc10 tempw                                        ; Measure FVR1024 relative to Vdd again
    Vdd = CALVDD18 / tempw + Vdd * 9           ; Merge the Vdds to mV
    sertxd("Vdd= ",#Vdd," mV",cr,lf)
  return
As a further test, I introduced some additional code to synchronise the polling loop to "Timer 1" which generates the internal interrupt that triggers the Servo pulses. The synchronisation code is commented out above, but I used and described the method in a recent Code Snippet. It's not conclusive, but with that code included, I haven't seen a "doubled" edge in many (tens) of minutes repeating the test. That could suggest that updating a SERVO value exactly whilst it is being executed (in the background) is causing the issue. Alternatively, the 'scope might reveal some other feature is causing the twitching.

TwoServos.png

Of course, using a single servo "pulse" to drive both gates would be a solution, but IMHO places heavy constraints on the mechanical construction of the gates (which can often be obviated by making minor adjustments to a few simple constants or variables within the program). Finally, going back to an earlier comment, I would expect to be able to also control the "Red flashing lights" within the same polling loop, maybe using some "creative" allocation of the 14M2's pinning. ;)

Cheers, Alan.
 
Last edited:

Garahbara

New Member
and have the same linkage geometry,
This is the issue. I'd need to make each linkage point to the raising/lower boom gate extremely accurate from the pivot point of the boom gate, if I'm to drive both servos exactly the same. The scale models of the lights, gates and signs etc, do not provide the linkage point on the boom. Where I "drill" the linkage point, is up to me. And I'd like the linkage as close to the pivot point as possible. The closer to the pivot point I put the linkage point, the greater exageration of movement difference, should I make just a small error in the placement of that linkage point.
 

Garahbara

New Member
As I understand it, you can only run one servo at a time. Apparently there is only one timer in the chip. While both servo commands occur at slightly different times there is no problem, but if both operate at the same time, every now and then the pulses to each will occur at the same time and this will upset the pulse length and cause that very puzzling jitter.
hmmmm...... My understanding of the SERVOPOS (not the SERVO) command, is that the pulses must already be occuring every 20ms regardless. (started by the SERVO command). All the SERVOPOS command does is ALTER the pulse length, Not initiate or start the pulsing. I get the jitter whether SERVOPOS commands are being processed or not.

SERVOPOS does nothing, unless you've done a SERVO command, which begins the pusling every 20ms. SERVOPOS just alters the pulse length. SERVO OFF stops the pulsing, and any subsequent SERVOPOS commands do nothing. (well, a SERVOPOS might do something, like alter the length of pulses that are no longer being sent, of course.)

To get the "jitter", the servo motor must be recieving a pulse, and the jitter is caused by an "errant" pulse length, that does not match what it is supposed to be.

Have I got this bit right?

Alan.

TOOT!
 

Garahbara

New Member
But let's assume we must use b.1 and b.3......
I don't have any choice. I'm working with the AXE171 board. eg. B4 is hardwired on the board as the TX to the player.
The test code is shown below,
I note you are using the SERVO command, not SERVOPOS. SERVO resets the timer each time and restarts pulsing. Should you be using SERVO outside the loop first, then SERVOPOS within the loop?

As a further test, I introduced some additional code to synchronise the polling loop to "Timer 1"
hmmmm... I'll do some reading on that one......

I'm trying to keep it all within Blockly, but that is getting inceasingly difficult, as I"m aready manually changing a few things each time I "convert" (cause Blockly is a bit limited in some of it's options)

Of course, using a single servo "pulse" to drive both gates would be a solution, but IMHO places heavy constraints on the mechanical construction of the gates (which can often be obviated by making minor adjustments to a few simple constants or variables within the program)
Exactly, as explained in a previous post. Although putting a "U" in the linkage wire can help make minor adjustments by closing/widening the "U" bend.

But IMHO the "best" solution is to make the "intended" commands work correctly!
Yes. This one. Make the intended command work correctly! :eek: 😵

What we need to know is whether the 14M2 does this pulsing synchronously. ie, the pulses being sent to two different pins should overlap, if they occur close enough together. And not have the pulse to the alternate pin clobber (truncate) the pulse that may be being sent to the first pin.

The AXE171 board comes with TWO pins configured as "Serial LCD or Servo", with 3 pin connections (B1/B3, +ve and 0V). Now, if the SERVO & SERVOPOS commands don't work properly if using BOTH provided SERVO pins, then why did they build it into the board???? (albeit B3 on the board does say LCD)

Hope I've given you all some interesting reading on a lazy Saturday afternoon, in these Covid lockdown times.

Alan.

TOOT!
 
Last edited:

AllyCat

Senior Member
Hi,

It's still (kind of) Friday night here, so just a quick reply. The following two comments are slightly contradictory, or indicate that there are (at least) two different causes:
If I use a high ranges of servopos (say 180 thru 220) the judder/jolt occurs more often. If I use a lower range of servopos (say 75 thru 120) the judder/jolt is far less frequent.
I get the jitter whether SERVOPOS commands are being processed or not.
Yes, you are correct that I (probably) should have used the SERVOPOS command. The PCBScope triggering will ignore the counter resetting (if it does). However, I think the waveforms (which were taken with a 14M2) conclusively show (if the "persistence" mode is disabled) that the pulses do not overlap, so that shouldn't be the cause of the issue. Personally, I wouldn't attempt to use Blockly; IMHO it's not as "bad" as the flowcharting software, but still introduces coding restrictions that may reduce the chances of finding a satisfactory solution.

Cheers, Alan.
 

Garahbara

New Member
The following two comments are slightly contradictory
I see what you mean. However, If I'm using longer pulse length on the SERVOPOS, these longer length pulses will continue on BOTH pins regardless of whether I issue further SERVOPOS commands or not. With shorter pulse lengths occuring repeatedly, there may be less chance of "collision" (or overlap) of the pulses to both pins, hence less jitter? :geek: 😵

Just some observation I've made, and that is just watching the servo motors, the jitter of the motor always seems to be in the direction of a "shorter" pulse. ie Perhaps the pulses are getting "truncated" by the next pulse to the other pin occuring too close the previous one.

I know other processors allow you to alter the timing of the pulses from the default 20ms. I think that would help (if "collision" is occuring) maybe to double that, but the 14M2 doesn't support that.

Time to get the sillyscope out again methinks.
 
Last edited:

Garahbara

New Member
OK guys,

I think I can cross my theory about collision or overlap off the list and bin that one. I've tried with the sillyscope, and nup. No evidence. One pulse immediately follows the other, and it is extremely accurate. Exactly every 20ms between the pulses, and exact length of SERVPOS 200. Check the Pos Width.

If someone could give me a hint with the sillyscope on how to trap a "pos width" that shouldn't be, much appeciated. I think I've visually seen them as they wizz past but they are few and far between.

This was done without the servo motors connected.

24135
 

AllyCat

Senior Member
Hi,
how to trap a "pos width" that shouldn't be
Generally, tick the "Persist(ance)" option. You may also need to use a faster sweep speed (0.2ms is as fast as the PCBScope can work in "real time"), and also the CH1 or EXT trigger mode. I don't know how much the "Waveform Measurements" panel interferes with the "normal" operation of the 'scope, but I'd be inclined to turn that off (at least as a check) unless the measurements are actually needed.

Cheers, Alan.
 

roho

Member
Presumably these are the Tower Pro SG90 servos that you mentioned on a previous thread? I too had problems with these servos glitching (not identical from your description but not too dissimilar either) when controlled by a 14M2 using the SERVO command. The solution was to use the PULSOUT command instead, as described by Ibenson above. This thread may contain useful information for you.

Note that I'm describing a single servo, not two. However, I do have two other projects that each use two servos, although pinout requirements here mean that I use an 18M2 in each case. The basic technique is to generate a fixedish time loop of 20 ms (it seems that the loop period is not critical), split this into two halves of approximately 10 ms, and then send a PULSOUT command to each servo alternately. This cured all the glitching across all three projects.

Hope that this helps you,

Roger.
 

Garahbara

New Member
Presumably these are the Tower Pro SG90 servos that you mentioned on a previous thread?
Yep.

controlled by a 14M2 using the SERVO command
I've sillyscoped the life outa the things using SERVO and SERVOPOS, and the 14M2 produces errant pulse lengths when using frequent SERVOPOS commands. Maybe 1, 2 or 3 every few thousand or so. Plugged the servos motors on, and when they "glitched" the pulse length from the 14M2 was different from what it was supposed to be. (Pos Width on the silly scope).Just a single "SERVO" command to get the pulsing going, and nothing after that, did not produce the glitch, and got perfect pulses every time. Introduce SERVOPOS commands (which you need to do frequently if you are going to move the things) and you get clitches. Even with a single servo motor.

So I give up.

The solution was to use the PULSOUT command instead, as described by Ibenson above.
I've now reluctantlly done that, and have not had a glitch since. The servo motors have been going forward and backwards for over an hour now, and not a glitch on the silly scope. 20ms between pulses running two servo motors. 180 degree rotation.

NOTE to all. Do NOT use "Pulse ouput" in Blockly to do this. It generates a "toggle on" -> "pause" in "ms" -> "toggle off" for the specified pin. See attachments.

Alan.

TOOT!
 

Attachments

AllyCat

Senior Member
Hi,

Yes, in my earlier post I did prefix my suggestions with a "Plan B" (using PULSOUTs) and even a "Plan C" (PWM outputs), since there can be "issues" with some PICaxe commands. Note that there are two other PWM output pins, on Port C (to make the total of 4 on most M2s). There are also some commands that are well-known (and documented) to glitch the servos, such as SERIN, SEROUT, SERTXD and DEBUG, etc., (I'm not sure about PULSIN and PULSOUT).

When I am using an "unfamiliar" command, I often do a syntax check with and without the command "commented out", to see how many (program) bytes it uses. Some are actually generic "System Macros" (i.e. "normal" code created by the Program Editor) which can sometimes be written more efficiently by the User/Programmer (and may run faster if there are fewer bytes to execute). Examples are BINTOASCII, SWAP and PWMDUTY. So here, I compared the byte counts of SERVO and SERVOPOS and was surprised to see that the counts are identical (and small). Furthermore, they contain exactly the same parameters and it does NOT appear to be necessary to use a SERVO command before a SERVOPOS. So the question arises: What does SERVOPOS do? (compared with SERVO). Maybe there is something "hard coded" into the PICaxes, but I don't believe that it ever "resets" the timer (unlike the PWMOUT command compared with PWMDUTY), because the timer is also used for the "time" variable in M2s. Sometime, I might compare the exact execution times of the two commands, to see if SERVOPOS actually is doing something "different"

If it really is the execution of the SERVOPOS (or SERVO) command which corrupts the timing of the pulses, then I would see if synchronising them away from the pulse generation period (as I described above, by testing the Timer 1 value) solves the problem. Otherwise, you are committed to maintaining a continuous 20ms polling loop, although that shouldn't be a major burden in this particular case.

Cheers, Alan.
 

lbenson

Senior Member
Otherwise, you are committed to maintaining a continuous 20ms polling loop
I did not find this to be the case with the servos I used. The program moved them in response to a command (from a browser page via a small linux device), and there might be minutes, hours, days, weeks between commands with no continuing pulse train needed to keep the servo holding the position it had been moved to. This is for a pan and tilt camera, and both the pan and tilt servos maintain position after movement, despite different weights on the servos (though I did try to balance the weight).
 

Garahbara

New Member
it does NOT appear to be necessary to use a SERVO command before a SERVOPOS
I just tested this again. And yes. You must issue a SERVO first (to get the 20ms pulses going), otherwise SERVPOS does nothing. SERVOPOS may very well alter the length of the pulses, but if the pulses ain't happening (because no SERVO was done first) then nothing happens.

but I don't believe that it ever "resets" the timer

The Holy Book of Picaxe says : The servo command initialises the pin for servo operation and starts the timer and It is recommended to use the servopos command to adjust position. This prevents resetting of the timer, which could cause 'jitter'

which can sometimes be written more efficiently by the User/Programmer (and may run faster if there are fewer bytes to execute).
I too, look at this aspect of things, and I've done a lot of comparision between SERVO/SERVOPOS and PULSOUT. Curiosity will kill my cat one of thse days. :eek: :geek:

SERVO/SERVOPOS uses 20ms beetween pulses. The pulses are issued every 20ms regardless of pulse length, or whether a SERVOPOS has been issued or not. The pulses are issued every 20ms, and sequentially, (within the 20ms) if using more than one SERVO pin. This also implies that you could "fill up" the 20ms period between pulses, with pulses to multiple servo motors. I note in higher processors, you can set the pulse interval for SERVO, but the 14M2 does not support this.

With SERVOPOS you can get a constant rate/speed of movement of the servo motor, regardless of the pulse length. (say for raising/lowering boom gates)

With PULSOUT, with, say a 20ms pause, the pulses are issued at the rate of 20ms + pulse length.

eg. Positioning the servo motor at "60", gives a period between pulses of 20ms + the 60 for positioning. Positioning the servo at 240, give a period between pulses of 20ms + the 240 for positioning.

I've tested this: (rotate servo motor through 180 degrees).

nn = 60
Loop
PUSLOUT pin, nn
Pause 20ms
nn = nn +1
endloop


The servo motor noticebly slows as nn gets higher. (minimally, but noticeable) due the the greater length of the PULSOUT. The code does not progress until the PULSEOUT is complete.

I've sillyscoped the above logic, and yes, the period between pulses increased with the above logic as "nn" got higher. Substitue a SERVOPOS for the PUSLOUT in the above logic, and the period between pulses does not budge from 20ms.

Someone should not have recommed I get that sillyscope. :geek:😵:eek:😁 How anyone could be bored with nothing to do in these Covid lockdown times, is beyond me. 😉

Alan.

TOOT!
 
Last edited:

Garahbara

New Member
I did not find this to be the case with the servos I used. The program moved them in response to a command (from a browser page via a small linux device), and there might be minutes, hours, days, weeks between commands with no continuing pulse train needed to keep the servo holding the position it had been moved to.
I found this too. Even with SERVOPOS.

When testing the boom gates raising/lowering logic, I put in a SERVO OFF (which stops the pulses), if the gates were up and no trains around. Was fine, next time a train arrived, I'd do a SERVO and get the pulses going again, then SERVOPOS to move the gates.

Also with PULSOUT. Only use it while the gates are in operation (moving up or down). No need for gate movement? No need to PULSOUT. All worked fine.😁

Alan.

TOOT!
 
Top