PWM Signal Conversion

Flash735

New Member
Hi all,

I’m new to the forum and to PICAXE. I have been doing some reading in the manuals with more to go…

I have a model receiver outputting pulse width varying from 0 to 656usec every 1.020ms. I would like to use PICAXE 08m capabilities to build a converter to read those 0 to 656usec pulses and convert those pulses to 1 to 2 msec at 20msec period, f=50hz.

After studying the manual initially, I am confused about the units (sec, msec, usec ???) in the pwmout, and pwmduty command.

I also tried to place 50hz in the pwmout wizard to automatically calculate the command. The wizard indicated 50hz was outside the calculation range.

Also any clarification or reading guidance on what unit of time should be used in the pwmout and pwmduty would be helpful.

Below is a real rough initial brainstorming draft before I go the wrong direction too far. Anyone have any ideas or some handy commands for this type project I could study further would be great...:D

Tks.


INIT:
pwmout C.2, 20msec, dc ; PWMOUT pin, period, duty cycle initialized at 20msec

STICK:
Pulsin C.1, 1, pulse1 ; Read pulses in usec form from receiver output

If pulse1 =>10usec and <20usec then DC=1.00 msec ;33 segments convert usec to msec pulses
If pulse1= >160usec and <180usec then DC=1.25 msec
If pulse1 =>640usec and <660usec then DC=2.00 msec

Pwmduty C.2, dc ; generate msec pulses
Goto STICK
 
Last edited:

srnet

Senior Member
The wizard indicated 50hz was outside the calculation range.
The lower limit appears to be 61Hz on the 08M.

If this is a RC servo pulse you are outputting, then a repitition rate of 61Hz is likley to work, the pulse width (1 to 2ms) is critical but the repitition rate is usually not.
 
Last edited:

Flash735

New Member
The lower limit appears to be 61Hz on the 08M.

If this is a RC servo pulse you are outputting, then a repitition rate of 61Hz is likley to work, the pulse width (1 to 2ms) is critical but the repitition rate is usually not.

Yes this is RC pulses, looks like the 08M works down to 61 on the wizard, and the servopos I believe will work for the project. What would be some ideas on how to have the present range of 0-656usec pulses at 1.02 usec period converted to what the servopos can read (75-225). This is equivalent to 1 to 2 ms pulse range at 20ms period.

tks.
 

Flash735

New Member
Srnet, I found out I still have a partial problem. The servpos works on the 08m2 when I pulsin 75 - 225 in msec on C.3 and read the output on C.4 I use an oscilloscope to step through the input msec pulses 75-225 on C.3 and read them on C.4 across a servo. I've tried the same with pulsin of 10usec to 660usec. Back to part of the initial problem; What would be some ideas to try on how can I get the pulsin to work with 10usec to 660usec pulse inputs on C.3, in order to have the servopos work in the 75-225 range?
 

srnet

Senior Member
Do the sums and a solution may suggest itself.

Your pulse read will give you a result from 0-66.

You need to convert that into a servpos value from 75 to 225, a range of 150.

2 x 66 = 132
 

Goeytex

Senior Member
The following code will do what you want using the Picaxe "Servo" command.
However pulsin and servo both use the internal timer and will collide from time
to time causing glitches in the servo.

I have found servo and pulsin to be incompatible while running concurrently
on the same Picaxe.

Code:
#Picaxe 08m2
#no_data
#com 1
setfreq M16

servo c.4, 120

do
    Pulsin c.3,  1,  w0       [COLOR=#008000]'(1 unit = 2.5us)[/COLOR]
    w0 = w0 * 10 / 17 + 70    [COLOR=#008000]'scale & ofset for 70 - 220[/COLOR]
    servopos c.4,  w0   
    pause 80        [COLOR=#008000] '20ms[/COLOR]
loop
 

Flash735

New Member
I tried the calculation below for the conversion. Still not working. I'm confused as to what is wrong with my formula. The program works in the simulator. :confused: Could it be the type of variable or constant used in the equation? After the init at B.4, the servo only make a jittering sound.

Init:
servo B.4,150 ; initialize servo on port B.4

Stick:
Pulsin C.3, 1, w1 ; Input pulses 10 to 660usec


w2=w1/66 ;usec Ratio (0-66)
w3=w2*150+75 ; servo range 150 at 75-225


servopos B.4,w3 ; move servo to a (75-225) servo position
pause 200

goto Stick ; loop back to select another stick position
 
Last edited:

Flash735

New Member
Thanks Goeytex, for the info about the servo and pulsin incompatibility. I posted the message at 13:29 above before I noticed your post this morning. If you have some comments about it, great!

Could you provide me some guidance on how to get the 10usec to 660usec at 1msec period converted to 1 to 2 msec at 20msec periods using the pulsin, pwmout, and pwmduty back to my original question. Those commands maybe more reliable in my remote control application. I considered a series of if statements as you can see in my original post, however that may not be the best and effective way to go. Any help will be appreciated.
 

hippy

Ex-Staff (retired)
The program works in the simulator. The output across the servo on B.4 stays at 750usec when I vary 10 to 660usec on B.4. :confused: Could it be the type of variable or constant used in the equation?
If it works in the simulator then there seems no reason it should not work in a PICAXE chip. That suggests you've got the signal into the wrong pin or the signalling isn't giving the correct readings with PULSIN - Perhaps it's a signal polarity issue ?

However; are you sure it works in the simulator ?

w2 = w1 / 66 will give a result of 0 when w1 < 66, eg < 660us
 

Goeytex

Senior Member
First I need to know what Picaxe you are using. First it was 08M in Post #1, then 08M2, then I see Pin B.4. which would mean neither off these.
So what Picaxe is it you want to use?

Any X2 or M2 would be ok. the reason being at higher frequency (32mhz) the resolution is much better so the servo will not be as jerky .
 

Flash735

New Member
It is definitely 08M2 configured and wired to B.4 Output, with Pulsin C.3.

Also from manual 2 info 08M2 should be ok:

servo
Syntax:
SERVO pin,pulse
SERVO [preload],pin,pulse (X2 only)
- Pin is a variable/constant which specifies the i/o pin to use.
- Pulse is variable/constant (75-225) which specifies the servo position
- Preload is an optional timing constant (X2 parts only).
Function:
Pulse an output pin continuously to drive a radio-control style servo.
On M2 and X2 parts the servo commands only function on portB (B.0 to B.7)
 

Goeytex

Senior Member
Still Confused. The 08M2 does not have a B.4 output. Only C.0 - C.5 with C.3 being an input only.
In any case you can sort that out in the manual.

Using servo and Pulsin won't work well because of timer conflicts. PWM will not work well due to having the Picaxe use
such a low frequency (4mhz) that results in poor granularity ( only 66 steps). So we use pulsin and pulsout at 32mhz
to get around servo issue and improve the granularity (resolution). The code below should be commented well enough
to explain how it was done. The output is a servo signal of 1ms to 2 ms as you specified, with a time base of 20ms
provided an input signal of 10us - 660us.

Let me know how this works for you. Be sure to get the pin numbers correct.

Code:
#Picaxe 08m2
#no_data
#com 1

symbol val_1 = w0
symbol on_time = w1
symbol off_time = w2
symbol delay = 15200

Setfreq m32

do
   Pulsin c.3 ,1,val_1             [COLOR=#008000] '(1 unit = 1.25us)[/COLOR]
  
   on_time = val_1 * 33 / 21 + 800   [COLOR=#008000]'Scale & offset [/COLOR]
   off_time = delay  - on_time       [COLOR=#008000] 'compensate for on_time[/COLOR]
   pulsout c.2, on_time               [COLOR=#008000]'servo pulse[/COLOR]
   pauseus off_time                   [COLOR=#008000]'off time[/COLOR]
loop
 

Flash735

New Member
Goeytex, I'll have a chance to give it a try in a few days. I appreciate all your help. :cool:

Referring to the manuals and ports: Take a look at manual 2, page 211-213 including the servo example. Maybe we have run into typos showing B ports. At the same time, manual 1 diagram for 08m2 on page 10 only show C ports. Hope some of this helps others running into the same port problems.
 

srnet

Senior Member
Maybe we have run into typos showing B ports
You do need to ensure that if you copy an 'example' from the manual that it is valid for the particular PICAXE you are using.

Even if the example is valid for the PICAXE you are using, you still need to check that the function is on a pin that matches your circuit.
 

hippy

Ex-Staff (retired)
Maybe we have run into typos showing B ports.
There has indeed been confusion over which PICAXE is being used and inconsistencies in naming of pins.

The 08M2 pins are named to be consistent with other M2 parts using port.pin convention as C.0 through C.5, however these can also be referenced as simply pin number, 0 through 5, and also as B.0 through B.5. This convention has also been back-ported for 08M programs - Ultimately it's for the programmer to be consistent in which they choose to use.

I still suspect the fundamental problem with the original code is that it doesn't do as expected, that within the simulation the values entered to represent PULSIN were not the values that would represent PULSIN when used with actual hardware; 660us would be a PULSIN in reading of 66 as that works in 10us units. If 660 were entered to represent 660us that would give a different result to a 66 result which would be seen with real hardware and a pulse of 660us.

Goytex's code of "w0 = w0 * 10 / 17 + 70" appears to consider that ( I haven't tested it ) but the code you appeared to use "w2=w1/66 : w3=w2*150+75" does not.
 

Flash735

New Member
Goeytex, it works!!!:) Could you tell me a little bit about the numbers in your scale equation and also the delay amount of 15200?
 
Last edited:

Flash735

New Member
Another note:

Just to try it, I substituted B.4 for the pulsout port and it still works in the simulator and on the scope and servo....being new to PICAXE commands, I'm not fully sure how much more capability of being able to use a B.4 and a C.4 on an 0m82 chip would give?
 

Flash735

New Member
Another note:

Just to try it, I substituted B.4 for the pulsout port and it still works in the simulator and on the scope and servo....being new to PICAXE commands, I'm not fully sure how much more capability of being able to use a B.4 and a C.4 on an 0m82 chip would give?


If the 08m2 is using ports C.3 and C.2 performing the pulsin and pulsout conversion, is it possible to have another pulsin and pulsout on the same 08m4 operating on port C.1 and C.4? or on C.1 and B.4 if B.4 were valid? What other Picaxe could do it if 08m2 cannot?
 
Last edited:

Goeytex

Senior Member
I am very bad at explaining the maths. But I'll give it a shot.

Given a 32 mhz clock speed 1 pulsin unit = 1.25 us. Also 1 pulsout unit = 1.25us.
So 1.25us - 1 pulsin unit and 660us = 660 / 1.25 = 528 units
So the range = 0 to 528 in pulsin units

Now figure for pulsout units to equal 1 to 2 ms. 1ms = 1000us and 2ms = 2000us.
1000us / 1.25 = 800 and 2000us / 1.25 = 1600 pulsout units.
So the range is 800 units with an offset of 800 from zero.

Therefore we need to convert 0 to 528 to 0 to 800 and then add the offset of 800.
That can be expressed as 800/528 + 800 ....or pulsout = pulsin / 1.51 + 800 but since the
Picaxe cannot to decimal point math we have to improvise. 1.51 is almost 1.5.
1.5 is the same as 3/2 so to get close we could simply do .. Pulsout = pulsin * 3 / 2 + 800.
That would give a range from 0 - 792 probably close enough. But I tweaked it by using
pulsout = 31 / 21 + 800. This done trial an error using scope to see the actual signal.
=================================================================================

The off_time delay of 15200 is in "pauseus" units which is also 1.25us per unit given a 32mhz clock.
So 15200us * 1.25 = 19ms. If we add the minimum on_time of 1 ms we get a total period of 20ms

To maintain that period accurately over the on_time range of 1 - 2 ms we have to subtract
the on_time from the fixed delay period of 19ms (pauseus 15200), So this is expressed in my code
as off_time = delay - on_time. Remove this line from the code and you will see the time period will
change as the pulsout time changes. Theoretically it should be consistent as with the servo
command.

To tweak the time period to exactly 20ms, hook up your scope and adjust the delay value of 15200 up and down
to get 20ms. It should be very close.

Hope this helps.

Note: If I were you, with the 08M2, I would forget that B.x works at all, All it does is confuse things. You have
C.0 to C.5 to work with. Pulsin will work with any of these except c.0. And pulsout will work with all except C.3. You gain
nothing by using b.4 (except confusion) since it is the same thing as c.4 ( if I understand correctly)
 
Last edited:

hippy

Ex-Staff (retired)
It is possible with an 08M2 to read three PULSIN and generate three PULSOUT. How well two or three works will depend on what the respective timings of the pulses are and how repeatedly consistently you need the time between PULSOUT times to be. It may be easier to simply use multiple PICAXE.
 

Goeytex

Senior Member
If the 08m2 is using ports C.3 and C.2 performing the pulsin and pulsout conversion, is it possible to have another pulsin and pulsout on the same 08m4 operating on port C.1 and C.4? or on C.1 and B.4 if B.4 were valid? What other Picaxe could do it if 08m2 cannot?
It should doable on an 08m2.

You have a 19ms window with 1 pulsin/pulsout combo (ignoring command processing overhead). That means you should easily be
able to fit up to three on on Picaxe 08M2. Your delay value of "pauseus 15200" may need to be tweaked and you will need to
subtract the sum of the three pulsout values to maintain a steady 20 ms period. And the 20us period is not carved in stone, since
most servos will work fine up to 30ms.
 
Last edited:

Flash735

New Member
I am very bad at explaining the maths. But I'll give it a shot.

Given a 32 mhz clock speed 1 pulsin unit = 1.25 us. Also 1 pulsout unit = 1.25us.
So 1.25us - 1 pulsin unit and 660us = 660 / 1.25 = 528 units
So the range = 0 to 528 in pulsin units

Now figure for pulsout units to equal 1 to 2 ms. 1ms = 1000us and 2ms = 2000us.
1000us / 1.25 = 800 and 2000us / 1.25 = 1600 pulsout units.
So the range is 800 units with an offset of 800 from zero.

Therefore we need to convert 0 to 528 to 0 to 800 and then add the offset of 800.
That can be expressed as 800/528 + 800 ....or pulsout = pulsin / 1.51 + 800 but since the
Picaxe cannot to decimal point math we have to improvise. 1.51 is almost 1.5.
1.5 is the same as 3/2 so to get close we could simply do .. Pulsout = pulsin * 3 / 2 + 800.
That would give a range from 0 - 792 probably close enough. But I tweaked it by using
pulsout = 31 / 21 + 800. This done trial an error using scope to see the actual signal.
=================================================================================

The off_time delay of 15200 is in "pauseus" units which is also 1.25us per unit given a 32mhz clock.
So 15200us * 1.25 = 19ms. If we add the minimum on_time of 1 ms we get a total period of 20ms

To maintain that period accurately over the on_time range of 1 - 2 ms we have to subtract
the on_time from the fixed delay period of 19ms (pauseus 15200), So this is expressed in my code
as off_time = delay - on_time. Remove this line from the code and you will see the time period will
change as the pulsout time changes. Theoretically it should be consistent as with the servo
command.

To tweak the time period to exactly 20ms, hook up your scope and adjust the delay value of 15200 up and down
to get 20ms. It should be very close.

Hope this helps.

Note: If I were you, with the 08M2, I would forget that B.x works at all, All it does is confuse things. You have
C.0 to C.5 to work with. Pulsin will work with any of these except c.0. And pulsout will work with all except C.3. You gain
nothing by using b.4 (except confusion) since it is the same thing as c.4 ( if I understand correctly)





Hi, thanks for all the previous help!!

I modified the program since our last post: Input range 10usec to 1000usec being converted to 1msec to 2msec pulses. No problem there.

I'm having a problem avoiding a deadzone at the high end above 1000usec; and lower deadzone below 10usec. The transmitter stick starts in the lower range and ends in the high range.

I've tried different approaches and here I'm trying if statements. Any suggestions will be helpful........



symbol val_1 = w0
symbol on_time = w1
symbol off_time = w2
symbol delay = 15200


Setfreq m32

do

Pulsin c.3 ,1,val_1 '(1 unit@32mhz = 1.25us) ; ( 10usec / 1.25 = 8 units) ; (1000usec/1.25us = 800 units)


if val_1 > 999us then val_1 = 1000us ; dead zone2: scope shows xxx when transmitter stick is at high level over 999usec. Duty cycle stays at 98-99% yet motor speed drops off and stops spin.

; Here I'm trying to allow val_1 to equal 800 units throughtout the high dead zone when the stick is there.


if val_1 < 11us then val_1 = 10us ; dead zone1: scope shows xxx when transmitter stick is in low level zone when val_1 is less than 10usec.

;Allow val_1 to equal 8 units thoroughtout the low dead zone



on_time = val_1 * 1 + 800

off_time = delay - on_time 'compensate for on_time

pulsout c.1, on_time 'servo pulse

pauseus off_time 'off time


loop
 
Last edited:
Top