Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 06:25 04 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : Micromite: Measuring the Width of a Pulse

     Page 1 of 2    
Author Message
Goeytex
Regular Member

Joined: 12/05/2014
Location: United States
Posts: 74
Posted: 03:02pm 16 May 2014
Copy link to clipboard 
Print this post

I got my PIC32MXF150 chips today and successfully loaded the firmware. Now I need to write a short program that measures the positive width of an incoming pulse. The pulse width will range from 10us to ~ 100us

However to my dismay there is no "Pulsin" or related command in MMBASIC. I looked through the MMBASIC manual and found nothing related to measuring the width of a pulse.

Certainly there is a way ?

Any help or guidance would be appreciated.

Bill
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 03:31pm 16 May 2014
Copy link to clipboard 
Print this post

Yeah, you can pulse an output pin, but not sure if there is an equivalent pulse-in type command for an input. You are probably right - the most likely is a way - but I am not sure of it. Others will no doubt chime in here...

I am guessing that you could setup an interrupt or other loop thus:


DO
If Pin(1)=1 then
X=1
If X<>1 then Timer=0
Loop until Pin(1)=0
Print Timer


This will measure how long it takes for the input pulse to go low again, and store it in the timer. However, this may not work if the pulse period is shorter then the code's ability to measure it....

If it DID work, you could make expand-and-perfect this sample code, and make it a sub or function.

EDIT: I have bugs in my loop above... I am playing with it now.Edited by Grogster 2014-05-18
Smoke makes things work. When the smoke gets out, it stops!
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 03:35pm 16 May 2014
Copy link to clipboard 
Print this post

OK, try this:


SetPin 1,2
X=0
Start:
DO
If Pin(1)=1 then
If X=0 then Timer=0
X=1
Endif
Loop until Pin(1)=0
X=0
Print Timer
Do:Loop until Pin(1)=1
Goto start


UNTESTED - I will have a go on the MM now with this. This should work, but it depends on how narrow the pulse-width is, and the fact that this code has to run may actually mean that the returned result is meaningless.(because it takes time to run the code, which will probably mean that the returned result won't be EXACTLY right - all speculation. I need to run some tests.)

EDIT: Code edited, and this is working fine for button-press type testing, but again - depending on the pulse period, this idea might not be any use. Kinda depends on how much accuracy you need.

The next test I will do, will be using a MicroMite chip, to pulse the MaxiMite in place of the switch, as I can have a pulsout kind of command of a known length, and then see what the MM comes back with.Edited by Grogster 2014-05-18
Smoke makes things work. When the smoke gets out, it stops!
 
Goeytex
Regular Member

Joined: 12/05/2014
Location: United States
Posts: 74
Posted: 06:14pm 16 May 2014
Copy link to clipboard 
Print this post

Hi Grogster,

I see that with "setpin" that frequency(FIN) and Period(PIN) can be measured, and with (CIN) that pulses can be counted. However, nothing in the manual even suggests a command or function that can read the width of a single pulse like other BASICS that usually include a PULSIN or similar command. And unfortunately the manual only lists the commands and offers little to nothing in the way of code examples for each command.

It seems that using the MMBASIC "timer" for short pulses will be fruitless as the timer resolution is 1ms.

I simply cannot imaging a having really nice 32-Bit Processor operating at 40Mhz and it not being able to measure the width of a pulse from 10us to 100us with a resolution of 1 - 2us. Certainly there is a way that I am missing ?

Even the lowly Picaxe 08M2 "Pulsin" can read the width of a pulse with a resolution of 1.25us.



 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 07:55pm 16 May 2014
Copy link to clipboard 
Print this post

Perhaps Geoff will chime in here....(although, I think he is on holiday at the moment)
Might be something that could be added to the language in the next release?

  Quote  It seems that using the MMBASIC "timer" for short pulses will be fruitless as the timer resolution is 1ms.


Copy that.
Edited by Grogster 2014-05-18
Smoke makes things work. When the smoke gets out, it stops!
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3165
Posted: 02:31am 17 May 2014
Copy link to clipboard 
Print this post

  Grogster said  Might be something that could be added to the language in the next release?

Yes, that sounds like a good idea.

I presume that the PICAXE pauses while it is waiting for the leading edge and is measuring the length of the pulse. On the Micromite/Maximite that would disable interrupts during that time - but other than that I cannot see any issues.

Geoff
Geoff Graham - http://geoffg.net
 
Goeytex
Regular Member

Joined: 12/05/2014
Location: United States
Posts: 74
Posted: 05:13am 17 May 2014
Copy link to clipboard 
Print this post

[quote]I presume that the PICAXE pauses while it is waiting for the leading edge and is measuring the length of the pulse. On the Micromite/Maximite that would disable interrupts during that time - but other than that I cannot see any issues.[/quote]

Yes, it is a blocking command.

A nice feature would be to allow the programmer to define the timeout period to improve program flow and eliminate long waits.

variable = pulsin (pin,state,timeout)

Where state either high (1), or low (0), and timeout is in ms

Example: x = pulsin (11,1,5)

Measure the width of the next high pulse (in microseconds) on Pin 11. If no edge detected within 5ms then return a value of zero and continue.


Thanks

Bill
Edited by Goeytex 2014-05-18
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2794
Posted: 07:21am 17 May 2014
Copy link to clipboard 
Print this post

  Goeytex said   [quote]Example: x = pulsin (11,1,5)

Measure the width of the next high pulse (in microseconds) on Pin 11. If no edge detected within 5ms then return a value of zero and continue.


In your example, how would you see best to deal with a high edge being detected within 5ms but then doesn't drop to low (0) again for a 'long' time? Do you need another timeout?

As a coder I can appreciate that you need to cover all possible scenarios otherwise the firmware could get 'stuck' in an endless loop.

x = PulseIn (11,1,5,100) gets 'messy' but the 100 parameter to mean 100mS timeout once leading edge detected.

WW


For everything Micromite visit micromite.org

Direct Email: whitewizzard@micromite.o
 
Goeytex
Regular Member

Joined: 12/05/2014
Location: United States
Posts: 74
Posted: 08:23am 17 May 2014
Copy link to clipboard 
Print this post


[quote]In your example, how would you see best to deal with a high edge being detected within 5ms but then doesn't drop to low (0) again for a 'long' time? Do you need another timeout?[/quote]

I can tell you how the Picaxe does it.

The timeout is fixed and based upon processor speed. With the default CPU Speed of 4Mhz each pulsin unit is 10us. The timeout is (65535 * 10us = .655 seconds). This same timeout period is used if no edge is detected, or if the timer overflows after the edge is detected (pulse is > .655 seconds). If the CPU speed is increased to 32Mhz each pulsin unit becomes 1.25us and the fixed timeout period is reduced to 1.25us * 65535 or about 82ms.

The timeouts could be:

1. Fixed (as with the Picaxe)
2. A single user definable value for both timeouts
3. Two user definable values as you indicated
4. A user definable value for waiting and a fixed value if the pulse too long.

The problem with a single fixed timeout value as with the Picaxe, Is that if an expected pulse does not come when it is supposed to, the program is halted for up to .655 seconds. For example, reading a servo signal. We know that the frame is ~20ms. If the receiver fails and there is no positive pulse, the program will stop execution for .65 seconds before it returns a fault (value of zero). If a timeout of 30 is used then program execution is not unnecessarily halted and can move on to other tasks.

Ideally I would have the command as:

x = pulsin (pin,state,[t1,t2]) where t1 and t2 are the optional timeouts, and if omitted, a reasonable fixed timeout is automatically implemented. However, this is more complicated to implement in firmware.

In any case, any Pulsin type command/function would be a welcome addition to MMBasic. Not being able to read the width of a pulse with reasonable accuracy & resolution is a deal killer for me, as many of my projects depend upon it.



 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 02:37pm 17 May 2014
Copy link to clipboard 
Print this post

Don't despair! Looks like Geoff will add this to a future MMBasic update so it would seem, although, I am not sure of how long that will take, as Geoff is a busy boy.

I'm surprised, actually, that this pulse-in type of command has not been found and discussed before now....

Generally speaking, if you have a pulse-out command(which MMBasic does have), then usually you have the matching pulse-in, but it obviously just was not thought about or seen as necessary before now.

It's good you came along and wanted it, cos it will then become an extra feature once it is implemented.

For the record, I also like your command syntax with the options idea. It just remains to see how involved those extra options are to implement.
Smoke makes things work. When the smoke gets out, it stops!
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2290
Posted: 12:55am 18 May 2014
Copy link to clipboard 
Print this post

geoff: would it not be possible to make use of one of the 32-bit timers (timer2/3 or timer4/5) with an external gate input for timing pulse lengths? so when pin x is high the counter counts up at a set rate (8MHz perhaps, giving a maximum interval of a little over 2 seconds); while when pin x is low counting is inhibited. this would provide the basic functionality of measuring a pulse width, without making the code too task-specific and closing off other uses.

i am looking at "FIGURE 13-2: TIMER2/3, TIMER4/5 BLOCK DIAGRAM (32-BIT)" on page 156 of the revision F datasheet.

as far as how to implement the code: simply create a procedure thus:

FastCount gate_pin, polarity [,prescaler]

where gate_pin is the number of an input pin (already assigned as a digital input using SETPIN), polarity is either 'H' or 'L' to indicate when counting should be enabled), and prescaler is an optional prescaler for a slower count rate.

allow reading of the counter using the pseudo-variable FastCountX.


using the above scheme, the fast counter could be used across several pins, just not more than one at once, much like the A/D converter is multiplexed. if there is not a free 32-bit timer, the use of FastCount could be made mutually exclusive with other functions that clash. the syntax "FastCount OFF" could be used to restore the previous functions when finished with timing.

such a functionality would also make for a neat way to implement a stopwatch.


rob :-)
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3165
Posted: 02:58am 18 May 2014
Copy link to clipboard 
Print this post

There are no spare timers but the timing would be easy to do using the core timer as a counter. This is how other timing (such as the DISTANCE function) works and the same principal can be used for PULSIN.

Geoff
Geoff Graham - http://geoffg.net
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2290
Posted: 03:10am 18 May 2014
Copy link to clipboard 
Print this post

what functions are the various timers used for at the moment?


rob :-)
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3165
Posted: 07:29am 18 May 2014
Copy link to clipboard 
Print this post

Timers...................................................... .....
TIMER NBR DESCRIPTION INTERRUPT
core Used by the uSec() macro no
1 IR Decoder no
2 Used by PWM channel 1 no
3 Used by PWM channel 2 no
4 MMBasic clocks and timers yes
5 COM2 serial interface yes


Request the source, it is all in there.Edited by Geoffg 2014-05-19
Geoff Graham - http://geoffg.net
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3165
Posted: 11:15pm 18 May 2014
Copy link to clipboard 
Print this post

I experimented with adding the PULSIN command to the Micromite and it was quite simple, so attached is V4.5D Beta 1 which includes the command.

I have to do some more work on the firmware before I can make a general release but I thought that the readers of this thread would appreciate having access to this command before then.
2014-05-19_090008_Micromite_V4.5D_Beta_1.zip

This is identical to V4.5C with the addition of PULSIN.

The manual entry is:
a = PULSIN( pin, polarity [, t1 [, t2]] )

Measures the width of an input pulse from 1uS to 1 second with 0.1uS resolution.

'pin' is the I/O pin to use for the measurement, it must be previously configured as
a digital input. 'polarity' is the type of pulse to measure, if zero the function
will return the width of the next negative pulse, if non zero it will measure the
next positive pulse.

't1' is the timeout applied while waiting for the pulse to arrive, 't2' is the
timeout used while measuring the pulse. Both are in microseconds (uS) and are
optional. If 't2' is omitted the value of 't1' will be used for both timeouts. If
both 't1' and 't2' are omitted then the timeouts will be set at 100000 (ie, 100mS).

This function returns the width of the pulse in microseconds (uS) or -1 if a timeout
has occurred. With a CPU speed of 40MHz the measurement is accurate to +/-0.5% and
+/-0.5uS. At other speeds the measurement is slightly less accurate.

Note that this function will cause the running program to pause while the
measurement is made and interrupts will be ignored during this period.


Thanks @Goeytex for the suggestion, as you can see, I implemented it as you proposed.

Geoff
Geoff Graham - http://geoffg.net
 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 11:25pm 18 May 2014
Copy link to clipboard 
Print this post

Wow - yet AGAIN, Geoff, you amaze us all.......

I bet Goeytex will be happy to read this thread.

Are you still on holiday, or are you back home now?
Smoke makes things work. When the smoke gets out, it stops!
 
Goeytex
Regular Member

Joined: 12/05/2014
Location: United States
Posts: 74
Posted: 12:56am 19 May 2014
Copy link to clipboard 
Print this post


@Geoff

Based upon my experience with other vendors/platforms, I was expecting months or weeks or even nothing at all, instead of a day or two. Your response to this is unexpected and very much appreciated.

Having a Pulsin command allows the Micromite to be used in a multitude of applications where it could not be used before.

For example, with a single hall sensor on a flywheel, the pulse width can be measured and the velocity (RPM) can be determined within < 1 rotation of the flywheel. (Ignition system / rev limiter / PID Control). Another might be a servo mixer. There are many many more.

Having such good resolution/accuracy along with user control of the timeouts makes the MMbasic Pulsin command better than any other out there.

Many thanks,


Bill


 
Grogster

Admin Group

Joined: 31/12/2012
Location: New Zealand
Posts: 9066
Posted: 01:16am 19 May 2014
Copy link to clipboard 
Print this post

Geoff is very proactive - it never ceases to amaze me....(and others, no doubt)
Smoke makes things work. When the smoke gets out, it stops!
 
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2290
Posted: 03:44am 19 May 2014
Copy link to clipboard 
Print this post

good work geoff! any chance this might mark the beginning of a few other small tweaks?

i'd love to see the option to select the internal band-gap reference for analog inputs - easiest bet would be to return the raw A/D value (0..1023) when using the internal reference, with -1 being returned if an overflow, and "OPTION REF 3V3 | INT" to select between reference sources (defaulting to 3V3 on powerup). it would then be up to the programmer to handle scaling and any calibration when using the band-gap.

please, please, please :-) i'm after being able to use the analog inputs in a useful way while running on 2x AA batteries.


rob :-)Edited by robert.rozee 2014-05-20
 
Goeytex
Regular Member

Joined: 12/05/2014
Location: United States
Posts: 74
Posted: 03:54am 19 May 2014
Copy link to clipboard 
Print this post

I loaded the V4.5D Firmware and ran a simple PULSIN test.

A Picaxe was programmed to generate a short positive pulse.

Results:
[code]
$2000 TEK Scope: 13.02us
Saleae Logic: 13.0625us
Micromite Pulsin: 13.3us
[/code]

This is excellent!

The Microcmite code can be easily modified to provide a resolution of 1us which should be adequate for most applications.

Sample Test Code:
[Code]
'=========================
'PULSIN TEST
'=========================

CPU 48
do
a = cint(pulsin(15,1)
print a
pause 1000
loop
[/code]

Bill

 
     Page 1 of 2    
Print this page
© JAQ Software 2024