Calibfreq with SERVO and the 08M

nfk

Senior Member
Hi,

I am using the SERVO command with an 08M and would like the pulse width to be correct. I have noticed that as a default, if I use the command...

Code:
servo 1,150
...then I get a pulse width of around 1.69 ms instead of 1.5 ms. I figured that I could use SETFREQ to fix this so I tried various values and obtained the following rather odd (and non-linear) results...

-31=1.68
-15=1.92
-10=1.84
0=1.69
10=1.57
12=1.54
14=1.52
15=1.51
16=1.94

If you look at the series (knowing that I was aiming for a result of 1.50) You might guess that as I got to a SETFREQ value of 15 I thought "Aha! Almost there!" but when I tried the next value (i.e. 16) the result was 1.94 and I was completely baffled.

Any ideas why this is happening?

Cheers,
Nigel
 
Last edited:

hippy

Ex-Staff (retired)
The internal register which adjusts frequency is a 5-bit two's complement number from -16 to +15. Outside that range the numbers are truncated to something within range, ie -31 is actually +1 and +16 is -16.

Code:
xxx1 0001 -15
xxx1 0000 -16
xxx0 1111 15
xxx0 1110 14
xxx0 1101 13
xxx0 1100 12
xxx0 1011 11
xxx0 1010 10
xxx0 1001 9
xxx0 1000 8
xxx0 0111 7
xxx0 0110 6
xxx0 0101 5
xxx0 0100 4
xxx0 0011 3
xxx0 0010 2
xxx0 0001 1
xxx0 0000 0
xxx1 1111 -1
xxx1 1110 -2 
xxx1 1101 -3
xxx1 1100 -4
xxx1 1011 -5
xxx1 1010 -6
xxx1 1001 -7
xxx1 1000 -8
xxx1 0111 -9
xxx1 0110 -10
xxx1 0101 -11
xxx1 0100 -12
xxx1 0011 -13
xxx1 0010 -14
xxx1 0001 -15
xxx1 0000 -16
xxx0 1111 15
xxx0 1110 14
Manual 2 does say "CALIBFREQ {-} factor : factor is a constant/variable containing the value -31 to 31" -- That's an error as best I can tell.
 
Last edited:

nfk

Senior Member
Ah ha! That makes much more sense, thanks! Yes, I think the manual could be a little clearer.

Nigel
 

nfk

Senior Member
I'm hoping Technical will have a look at this because it seems to me there is an issue with the way servo pulses are generated in the PICAXE chips (well the 08M at least).

As discussed previously, the CALIBFREQ command operates in a slightly odd way. For the record, I have given below the results of a test that I did where I used SERVOPOS 150 to generate pulses and CALIBFREQ to try to get out the correct value. The first column shows the CALIBFREQ value used, column 2 is the pulse width of the output signal and the 'X' denotes values that required a hard reset to reprogram the chip owing to the altered speed.

My problem is this...on every 08M I have bought (probably about 30 or 40 by now) the servo command has always been inaccurate and always by about the same margin. SERVOPOS 1,150 for example will nearly always yield a pulsewidth of about 168. It's almost as if it is programmed incorrectly.

As if to confirm this, if I get it close to the correct value by using CALIBFREQ 15 (on the chips I have anyway) the chip is moved into the 'reset required' zone and has to have a hard reset for reprogramming. Surely if the 08M was programmed correctly, when the servo output signal was correct then the serial programming would work too.

Another very frustrating thing is that although I can get tantalisingly close to the correct pulsewidth with CALIBFREQ 15 which gives a 'centre servo position' of 152 I am still a little way off my target of 150. As soon as I go to CALIBFREQ 16 (as the table below shows) it jumps back to 193. Looking at is as a graph as shown here, I would have expected the corrective effect of CALIBFREQ to be centred around an error of zero but the value you get from the servo-related commands is always too large.



Isn't this an error? Surely one should be able to achieve the pulsewidth one is asking for, even if some tuning of CALIBFREQ is required.

Cheers,
Nigel

31 171
30 172
29 173
28 175 X
27 176 X
26 178 X
25 179 X
24 180 X
23 182 X
22 184 X
21 185 X
20 187 X
19 188 X
18 190 X
17 191 X
16 193 X
15 152 X
14 153 X
13 154 X
12 155 X
11 156 X
10 157 X
9 158 X
8 159
7 160
6 162
5 163
4 164
3 165
2 166
1 168
0 169
-1 171
-2 172
-3 173
-4 175
-5 176 X
-6 178 X
-7 179 X
-8 180 X
-9 182 X
-10 184 X
-11 185 X
-12 187 X
-13 188 X
-14 190 X
-15 191 X
-16 193 X
-17 152 X
-18 153 X
-19 154 X
-20 155 X
-21 156 X
-22 157 X
-23 158
-24 159
-25 160
-26 162
-27 163
-28 164
-29 165
-30 166
-31 168
 
Last edited:

BCJKiwi

Senior Member
Can a fixed (known) correction factor be applied to the 150 instead of fiddling with the frequency?

From your comments it appears the correction required would be the same for all chips.

Appreciate this does not address the error but may be a simpler solution and avoids the issues of running the 08Ms with an 'off-spec" clock.
 

nfk

Senior Member
I'm not sure - I'd be interested in hearing what Technical thinks. It would be very handy to be able to apply a fixed correction so long as a) it was always the same and b) that it allowed the programming to work without a hard reset.

Cheers,
Nigel
 

BCJKiwi

Senior Member
You have the setup to determine this.
Run through the range and produce a table of set point and actual.

Any pattern / factor will hopefully be obvious. We know there is a fixed? offset of 18+ at a set point of 150 - just need a bunch more data points!
 

hippy

Ex-Staff (retired)
I agree with BCJKiwi; start with a graph of what should be coming out and what is coming out. To get what's desired you may have to apply a function along the lines of "y=mx+c"; the m comes from the CALIBFREQ but there's no c being applied.

It would be interesting to see what the graph of result against desired was for a PICAXE with an external crystal.
 

nfk

Senior Member
I understand what you're saying about the '+C' part but I don't see why that should be necessary. If I was just writing one programme I'd stick in a constant and be done with it. However, I'm sure that this shouldn't be necessary except to fine-tune individual chips. Here's my logic...

The manual says that servo-related commands create a pulse-width of the value x0.01ms. THIS IS NOT ACCURATE. Now I know I'm being picky, and I know that individual chips may vary, and if the output was within one or two percent I might be happy. BUT, being consistently around 10% out is unacceptable and I think it is 'built-in'.

Now, we are provided with the CALIBFREQ command which enables us to tune the frequency of the chip. Fine, except that the code for this tuning provides results which cannot bring the chip into calibration, i.e. produce the results that are given in the manual. Another interesting point about this is that if I use CALIBFREQ to get it nearly correct, it knocks out the timing for the serial interface which then won't work (except with a hard reset of course).

Here's the thing...if the internal PICAXE code is correct, if I use CALIBFREQ to get the SERVO commands working, why does this mess up the serial port??? Surely they are 'locked together' by the code in the chip and if one is correct the other should be too.

This is why I believe there is an error in the servo code and that the pulsewidth that the servo commands generate need to be reduced by about 10%.

Cheers,
Nigel
 
Last edited:

hippy

Ex-Staff (retired)
Maybe the internal PICAXE code isn't correct, maybe it is but not when used with the PICAXE's with internal oscillators, maybe it's just an artefact of the way the servo control has to be done within the interpreter. Maybe it's a +/-N offset error or artefact or it may be more complex than that. Maybe it's something Rev-Ed are already aware of or perhaps it's the first they know of any problem. Only Technical can give us the full low-down on that.

In the meantime, if there is a consistent 10% error it may be better to adjust for that by changing the value used in SERVO by 10% rather than tweaking CALIBFREQ, or to apply some adjustment and tweak CALIBFREQ less. Other than that it will mean waiting for Technical to investigate, give a reply, and for Rev-Ed to make any changes if they intend to.

It may be worth making a new post high-lighting the problem of servo timing in Software Feedback.
 
Last edited:

Technical

Technical Support
Staff member
This is something we will look into.

The length of the pulse operates by an internal timer 'interrupt' which activates every 100us or so. It then decrements the servo value (e.g. 150), and when it gets to 0 switches off the pin.

However the length of the code processing the interrupt varies and does depend on several different factors, for instance, how many servos are currently active. This can add an overhead which in turn increases the pulse length.

As initially designed, the servo command was intended for simple educational student projects on low-grade servos where they may simply want to open/shut a window for instance, and so these small differences were not considered that relevant - the servo value could be easily tweaked to 149 or 151!

However in your helicopter / high grade digital servo situation we appreciate these differences are much more important. At present the best solution for your project is to simply add a scaling factor as already suggested , do not use calibfreq. Or use a board specifically designed for accurate servo control, such as the 21 channel AXE031.
 
Top