Picaxe servopos vs pulsin - why different?

For various reasons, I am trying to emulate the function of a servo control board, insofar as the application will be only for motor speed and direction control via one pin and a pwm input- essentially, I'm trying to make a tiny motor driver compatible with inputs via a picaxe servopos command.

(I think there's lot of other potential applications here, but this is where I'm at for now).

 

 

For my test setup,I have the servopos commands (after a "servo" init) issued by a separate picaxe 18X. The servo command is input into a picaxe 08M which reads the pulse via a pulsin command.

The code for the 18X is straightforward:

;------------------18X CONTROL
servo 0,75
main:
servopos 0,254
pause 1000
goto main

 

The code for the 08M is also basic:

;------------------08M CONTROL

symbol pwmval = w0

checkservo:
input sigpin
pulsin sigpin,1,pwmval
;debug pwmval
goto checkservo

 

My understanding of the servopos command: e.g. servopos,0,150 is that a pulse of 1.500 ms width is sent to pin 0, and repeated every 20ms.

my understanding of the pulsin command: e.g. pulsin 3,1,w0 is that a pulse is measured, triggered by the rising (or falling) edge, and the duration is returned in w0, in 10us units.

This means that if I read a servpos,0,150 output with a pulsin 3,1,w0 (connecting output 0 on the output picaxe, to input 3 on the input picaxe), then w0 should contain the value 150.

 

 

Great. except it doesn't. Hence the forum.

Here's a list of the issued pwm command and the resulting (reproducable) read, w0 value with a 08M reading the servpos command from a 18X:

servopos (18X) w0(08M)
260                  9
255                  5
254                 283
250                 279
247                 275
245                 273
240                 267
200                 223
150                 169
120                 136
100                 114
90                  103
85                  97
80                  92
70                  81
60                  70
50                  59
30                  37
10                  15

 

Now, I can understand why the w0 goes lower for servopos>255, no problem. These data are just included for interest.

What I can't understand is why the W0 values are always higher than the servopos command AND seems to be a function of the servopos value (if it's useful, the fractional discrepancy seems to be asymptotic towards 10-11% for high servopos values). If there were strangenesses with the shape of the pulse, and the point at which the trigger started, then that also would result in a constant offset, not one dependent on the servopos value, all the other processes I can guess at would seem to me to produce a constant offset, or at least, a factor - but not a variable one.

Does anyone have any thoughts?

 

 

Let’s start with the easy

Let’s start with the easy questions =)

What’s your clock/crystal/resonator setup for each PICAXE?

its not the freq

I found a similar thing on the 28X1. By replacing the servo(pos) commands with pulsout commands everything kept working except that the servos would go to slightly different positions.

This was the same program on the same frequency setting on the same processor.

I dont know why, but I have a feeling the servo commands are inaccurate and the pulse commands are. I guess if I had a scope I could find out.

Confirmed

Your feeling seems to be correct. I just did some tests with 08M and 28x2 and here’s what I “scoped” out:

Servo

08M

28X2

10

0,152

0,110

30

0,370

0,310

50

0,590

0,510

60

0,700

0,612

70

0,808

0,712

80

0,920

0,812

85

0,974

0,860

90

1,028

0,908

100

1,140

1,008

120

1,360

1,208

150

1,688

1,504

200

2,240

2,008

240

2,680

2,400

245

2,720

2,460

247

2,750

2,480

250

2,780

2,500

254

2,820

2,540

255

0,052

2,560

260

0,086

0,050

The first column has servo command’s value, the second one has pulse width from 08M and last one has pulse width from 28x2. Pulse widths are in milliseconds.

08M pulses seem to correspond emuller’s findings pretty accurately. Interestingly 28x2 gives a bit different results and its pulse widths seem to correspond to servo command quite nicely. Maybe it’s because it has 8MHz frequency instead of 4MHz or maybe the whole command is implemented differently on 28x2, dunno. Most interesting is the “servo 255” row: 08M gives 0,052ms and 28X2 gives 2,56ms (and maybe gives some support for my guess of servo command being implemented differently).

 

Nice

Do you have the pulse width values using the pulsout command to compare with?

My guess is that the error in the pulse widths comes from a short delay in the timer interrupt that the servo command uses to keep pulsing in the background.

The frequency factor between the 08M and the 28X2 does not account for that big a difference in measurements so I think you’re right in saying the 28X2 has a different implementation of either the servo command or the timed interupt.

 

I do now

Here they are:

Pulsout

08M

 

Pulsout

28X2

10

0,100

 

20

0,102

30

0,299

 

60

0,302

50

0,498

 

100

0,502

60

0,598

 

120

0,600

70

0,698

 

140

0,700

80

0,796

 

160

0,800

85

0,848

 

170

0,852

90

0,896

 

180

0,900

100

0,996

 

200

1,000

120

1,196

 

240

1,200

150

1,496

 

300

1,500

200

1,992

 

400

2,000

240

2,390

 

480

2,400

245

2,440

 

490

2,440

247

2,460

 

494

2,460

250

2,490

 

500

2,500

254

2,530

 

508

2,540

255

2,540

 

510

2,540

260

2,590

 

520

2,600

Some notes about those values: 08M was on 08 Proto board and 28x2 on 28 Project board. Accuracy of readings might differ between different pulsout (and servo in previous post) values because I used different time/div setting to read them. I used the smallest time/div setting I could so that the whole pulse fit into my scope’s screen. 08M and 28x2 had different values for pulsout because of their different clock frequency.

For those interested here’s the code I used to test pulsout (copy-paste screwed up data lines, sorry):

’ 4MHz:

'data 0,(0,10,0,30,0,50,0,60,0,70,0,80,0,85,0,90,0,100,0,120,0,150,0,200,0,240,0,245,0,247,0,250,0,254,0,255,1,4)

’ 8MHz:

data 0,(0,20,0,60,0,100,0,120,0,140,0,160,0,170,0,180,0,200,0,240,1,44,1,144,1,224,1,234,1,238,1,244,1,252,1,254,2,8)

 

symbol pulse_width = w0

symbol i = b2

symbol j = b3

 

main:

  for i = 0 to 18 ’ 18 Word values

    j = i*2

    read j, b1 ’ pulse_width MSB

    j = j + 1

    read j, b0 ’ pulse_width LSB

pulse_loop:

    for j = 0 to 255

      pulsout 1, pulse_width

      pause 5

    next

    if pinC.3 = 0 then pulse_loop ’ (in 08M it’s pin3)

  next

  goto main

 

 

Thanx

That is pretty amazing. I mean: the values for the 08M are very close to the mark even though its clock is supposed to be “not very accurate”.

Also amazing that the servo positions are so much off. I will definitely rewrite the code for my 08M servo driver to use pulsout instead of servo after this.

Thanks for clearing that up!

No problem

I’m not familiar with “insides” of PICs but looking quickly at PIC12F683 datasheet (http://ww1.microchip.com/downloads/en/devicedoc/41211d_.pdf) I found that frequency tolerance of that chip is ±2% in 0°C ≤ Ta ≤ +85°C and when 2.5V ≤ VDD ≤ 5.5V (chapter 15.8, table 15-2). I’m just thinking that maybe the frequency is highly temperature and operating voltage dependent (and my 21-22°C room temperature is “perfect”). Or maybe I just got lucky and got a good one.

Hmm… Testing if the temperature affects pulsout with 08M could be interesting. Where are you my 08M? Freezer calls! :wink: