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.
-----
Precise output pulse: Any suggestions
Moderators: adafruit_support_bill, adafruit
Please be positive and constructive with your questions and comments.
- mikeysklar
- Posts: 13824
- Joined: Mon Aug 01, 2016 8:10 pm
Re: Precise output pulse: Any suggestions
Have you experimented with pulseio.Pulseout? There is some example code to get you going here:
https://docs.circuitpython.org/en/lates ... index.html
https://docs.circuitpython.org/en/lates ... index.html
- SeattleDavid
- Posts: 100
- Joined: Wed Sep 18, 2019 2:26 am
Re: Precise output pulse: Any suggestions
The documentation for PulseOut probably makes sense only to the person that wrote it. At least, to me it makes no sense whatsoever.
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?
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: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.
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?
- mikeysklar
- Posts: 13824
- Joined: Mon Aug 01, 2016 8:10 pm
Re: Precise output pulse: Any suggestions
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)
- SeattleDavid
- Posts: 100
- Joined: Wed Sep 18, 2019 2:26 am
Re: Precise output pulse: Any suggestions
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?
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?
- sj_remington
- Posts: 994
- Joined: Mon Jul 27, 2020 4:51 pm
Re: Precise output pulse: Any suggestions
It seems reasonable to assume is that this, which appears to set frequency to 10000Hz (1/100us):What's the magic that glues 100μS and 10mS together?
Code: Select all
frequency=10000
Code: Select all
frequency=100
- SeattleDavid
- Posts: 100
- Joined: Wed Sep 18, 2019 2:26 am
Re: Precise output pulse: Any suggestions
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.
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.
- SeattleDavid
- Posts: 100
- Joined: Wed Sep 18, 2019 2:26 am
Re: Precise output pulse: Any suggestions
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.
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.
Please be positive and constructive with your questions and comments.