Precise output pulse: Any suggestions

CircuitPython on hardware including Adafruit's boards, and CircuitPython libraries using Blinka on host computers.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
SeattleDavid
 
Posts: 100
Joined: Wed Sep 18, 2019 2:26 am

Precise output pulse: Any suggestions

Post by SeattleDavid »

I have a need to generate an output pulse on a Raspberry RP2040 Pico on one of the GPIO pins that needs to be...

1) between 10us (0.00001 seconds) up to 10ms (0.01 seconds) in duration.

2) starting 0 to 10ms (0.01 seconds with 0.1ms increments) from a trigger event.

So it might be like this: Every time the trigger event happens, wait 2.5 milliseconds, and then generate a pulse that is 250 microseconds in duration. However, depending upon the machine being controlled, the pulse width and the delay before pulsing will be variable. I need to be able to handle any delay and pulse width.

Is there a Circuit Python library that can assist with doing this type of thing? Or, is there hardware that can do this?

I have heard the RP2040 PIO is very flexible and it seems that it may be able to do this type of thing. But the learning curve also seems rather steep. So I was hoping for a simpler approach, perhaps some CP library function.

-----

User avatar
mikeysklar
 
Posts: 13824
Joined: Mon Aug 01, 2016 8:10 pm

Re: Precise output pulse: Any suggestions

Post by mikeysklar »

Have you experimented with pulseio.Pulseout? There is some example code to get you going here:

https://docs.circuitpython.org/en/lates ... index.html

User avatar
SeattleDavid
 
Posts: 100
Joined: Wed Sep 18, 2019 2:26 am

Re: Precise output pulse: Any suggestions

Post by SeattleDavid »

The documentation for PulseOut probably makes sense only to the person that wrote it. At least, to me it makes no sense whatsoever.
Pulse PWM “carrier” output on and off. This is commonly used in infrared remotes. The pulsed signal consists of timed on and off periods. Unlike PWM, there is no set duration for on and off pairs.
This appears to have been designed with one specific purpose in mind: IR remote controls. But it is very unclear quite what the parameters actually do:

The example clearly does something, but what? It would be nice if the author had spent just a moment of their time to document what a "carrier" is, and how the "duty cycle" relates to the pulse chain specified by the "sent" method.

This might do what I need, but really the functionality of this is quite unclear. Why would somebody spend hours crafting a function and less than a minute documenting it?

User avatar
mikeysklar
 
Posts: 13824
Joined: Mon Aug 01, 2016 8:10 pm

Re: Precise output pulse: Any suggestions

Post by mikeysklar »

Here is example code using PulseOut that should produce a 10ms pulse which can experiment with and adjust to faster frequencies:

Code: Select all

import array
import board
import time
import pulseio

pulseOut = pulseio.PulseOut(board.A0, frequency=10000, duty_cycle=0xFFFF)

pulses = array.array('H', [10000])

while(True):
    pulseOut.send(pulses)
    time.sleep(5)

User avatar
SeattleDavid
 
Posts: 100
Joined: Wed Sep 18, 2019 2:26 am

Re: Precise output pulse: Any suggestions

Post by SeattleDavid »

Possibly helpful, but again, it probably makes sense only to somebody that already understands how the function works. I don't doubt that it does what you say...but as the documentation lacks really any detailed description nohow the function works, it is hard to understand your example.

It seems to set up a frequency of 10,000Hz, which is 100μS. But it's unclear how you get from 100μS to 10mS. What's the magic that glues 100μS and 10mS together?

User avatar
sj_remington
 
Posts: 994
Joined: Mon Jul 27, 2020 4:51 pm

Re: Precise output pulse: Any suggestions

Post by sj_remington »

What's the magic that glues 100μS and 10mS together?
It seems reasonable to assume is that this, which appears to set frequency to 10000Hz (1/100us):

Code: Select all

frequency=10000
could be changed to this, to set the frequency to 100Hz (1/10ms):

Code: Select all

frequency=100
Try it and let me know if my wild guess is correct.

User avatar
SeattleDavid
 
Posts: 100
Joined: Wed Sep 18, 2019 2:26 am

Re: Precise output pulse: Any suggestions

Post by SeattleDavid »

I am still struggling to understand at all what is going on here. You really have a lot of implied contextual background going on that I don't have.

The PulseOut method takes three parameters:
1) The first is the GPIO pin and that is clear.

2) The second is a frequency. Why a frequency? How is this used? Does this generate some type of waveform? How does specifying a frequency have anything to do with anything other than a square wave output? What is the purpose of "frequency"?

3) The third is the duty cycle, which normally specifies the percentage of on-time of a square wave. In this case it is a constant, not a percentage. But what is the maximum (undocumented and implied value)? 65535? So is 65535 always on and is 0 always off and 32767 a 50% duty cycle?

Next is the send method. This seems to take an array of values. But why? What do the elements in the array represent? It almost seems like the array MAY represent on and off durations, but how do those durations relate to the "frequency" and "duty cycle"?

I appreciate the example, and yes, the output GPIO pin does blink (as seen on an oscilloscope.) But what is being blinked remains a complete mystery to me.

Please help.

User avatar
SeattleDavid
 
Posts: 100
Joined: Wed Sep 18, 2019 2:26 am

Re: Precise output pulse: Any suggestions

Post by SeattleDavid »

OK, I finally (elsewhere) got an explanation...

PulseOut is mis-named and is a highly specialized special-purpose function designed primarily for driving IR remotes. Because of two (simple to fix) design flaws it is unsuitable for generating a pulse chain.

The array consists of a strong of ON and OFF times (in microseconds) for the pulses. You can have any number of them to create whatever pulsing pattern you desire.

However, there is this concept of "frequency" built into PulseOut which is confusing and unfortunate for general pulse output applications. It works like this: when the output is on, it will be modulated against the "frequency" and its corresponding "duty_cycle" so that what you get is not an ON, but a chopped up ON signal. (Chopped up by the "Frequency". This is needed in IR remotes and, well, pretty much nowhere else.

A better name for the function would have been "IROut".

-----

There are two (pretty minor) changes that would make this a useful and general purpose function:

1) if "frequency=0" could be set to disable the frequency modulation, then the output pulses would be exactly what is specified in the array. This would make outputting a set of pulses for any general purpose very straightforward. Basically, setting frequency to 0 would disable the modulation. (Currently, setting frequency=0 results in an error.) This would be a simple, backwards compatible change.

2) Pulse ON and OFF durations are limited to a maximum of 65535 microseconds, or the equivalent of 0.065 seconds. This is too short for many applications. One solution is to allow longer (more than double byte) lengths to be specified in the Array. An alternative is to add a duration multiplier parameter in PulseOut that would multiple durations by something such as 1000. This could be as simple as and option that specifies if durations are in uS or mS (duration='mS' or duration='uS').

I would add that three additional features would be quite nice:

3) The ability for this to operate non-blocking (in the background) so that the pulse pattern could continue while the program ran.

4) The ability to have multiple GPIO all starting at the same instant. Each GPIO might have a different pulse pattern via their own non-blocking PulseOut command, but a parameter that indicates to wait for a trigger method to be issued, which would release all channels.

-----

I interface a lot of older equipment, and the ability to generate various pulse patterns is important. This can also be true for control panels with warning lights. The ability to have a PulseOut that can generate human-readable pulse patterns would be generally useful.

Locked
Please be positive and constructive with your questions and comments.

Return to “Adafruit CircuitPython”