Reliable pulse output delays after interrupts?
Reliable pulse output delays after interrupts?
My program's goal is to await an external edge, and on receipt, generate a single pulse X microseconds later. This seems like it should be simple, but I can't seem to find a way to reliably output this pulse.
I looked at using either a timer, interrupt or if statement, but nothing seemed to work well. The if works best, but it has downsides. Am I missing something?
1) Timer: It looks like the timers are made for repetitive outputs. I want a delay to a pulse edge with a defined pulsewidth.
2) Interrupt: I could never get it to work. It seems like the docs say since the callback enacts two or three delays, the interrupt cannot be used.
3) Monitor the input line with an if statement, i.e. the input line is always monitored (blocking situation). Two related timing errors arise on this method: A) repetitive lengthening of the time to output. The output timing error grows to 1 ms over about 3 seconds, then either snaps back to the correct delay, or B) gets an extra 2 ms added on to the delay time. I guessed that garbage collection may be part of the problem, so I tried just disabling or disabling/enabling. It still had the lengthening problem, but the 2 ms jump was never observed prior to shutdown a few seconds later due to max garbage.
Thanks for any help, Bill
I looked at using either a timer, interrupt or if statement, but nothing seemed to work well. The if works best, but it has downsides. Am I missing something?
1) Timer: It looks like the timers are made for repetitive outputs. I want a delay to a pulse edge with a defined pulsewidth.
2) Interrupt: I could never get it to work. It seems like the docs say since the callback enacts two or three delays, the interrupt cannot be used.
3) Monitor the input line with an if statement, i.e. the input line is always monitored (blocking situation). Two related timing errors arise on this method: A) repetitive lengthening of the time to output. The output timing error grows to 1 ms over about 3 seconds, then either snaps back to the correct delay, or B) gets an extra 2 ms added on to the delay time. I guessed that garbage collection may be part of the problem, so I tried just disabling or disabling/enabling. It still had the lengthening problem, but the 2 ms jump was never observed prior to shutdown a few seconds later due to max garbage.
Thanks for any help, Bill
Re: Reliable pulse output delays after interrupts?
There is a way to do that entirely in hardware I think.
It isn't exposed, but the Timer has what's known as a one-shot mode and my recollection is that you can set it up so that one timer is triggered from another.
II think that solution is the only solution that will give you consistent pulse widths. Anything involving an interrupt can have your interrupt delayed (unless you happen to have the highest priority interrupt and nobody disables interrupts).
It isn't exposed, but the Timer has what's known as a one-shot mode and my recollection is that you can set it up so that one timer is triggered from another.
II think that solution is the only solution that will give you consistent pulse widths. Anything involving an interrupt can have your interrupt delayed (unless you happen to have the highest priority interrupt and nobody disables interrupts).
Re: Reliable pulse output delays after interrupts?
What might be delaying the interrupt? I was guessing garbage collection, but my attempts at manually doing GC failed in one manner or another. I thought that I once read that the collection only took a few microseconds, but I could not find that thread. If it only takes a few microseconds then I can enable during a noncritical period. I'm seeing delay variations between 50 and 2,000 microseconds (which seems like a lot). Thanks.
Re: Reliable pulse output delays after interrupts?
Interrupts being disabled for various reasons.
One is while other interrupt handlers (of higher priority) are running.
Currently, interrupts are disabled while reading and writing blocks to the sdcard (until the transfers can be done using DMA). That would be my guess for the 2msec delays.
Dave Hylands
One is while other interrupt handlers (of higher priority) are running.
Currently, interrupts are disabled while reading and writing blocks to the sdcard (until the transfers can be done using DMA). That would be my guess for the 2msec delays.
Dave Hylands
Re: Reliable pulse output delays after interrupts?
I'm pretty sure that a gc cycle takes about 2 milliseconds, not microseconds.
As for the pulse generation, I had the same idea as Dave - the way to get reliable short pulses is to make the timer hardware do it for you and keep the software out of the process.
I found this description in the programmer's reference manual (RM0090, DM00031020.pdf):
The stm module isn't very well documented yet (maybe I should try to help with that…) but if you are interested in trying this I can offer some pointers.
-Bryan
As for the pulse generation, I had the same idea as Dave - the way to get reliable short pulses is to make the timer hardware do it for you and keep the software out of the process.
I found this description in the programmer's reference manual (RM0090, DM00031020.pdf):
As Dave said, this isn't exposed in the Timer Class on uPy, but with some patience it may be possible to configure the registers to do it directly using the stm module, which allows you to read and write to the configuration registers directly via stm.mem32[address]17.3.15 One-pulse mode
One-pulse mode (OPM) is a particular case of the previous modes. It allows the counter to be started in response to a stimulus and to generate a pulse with a programmable length after a programmable delay.
Starting the counter can be controlled through the slave mode controller. Generating the waveform can be done in output compare mode or PWM mode. You select One-pulse mode by setting the OPM bit in the TIMx_CR1 register. This makes the counter stop automatically at the next update event UEV.
The stm module isn't very well documented yet (maybe I should try to help with that…) but if you are interested in trying this I can offer some pointers.
-Bryan
Re: Reliable pulse output delays after interrupts?
Thanks, Dave and Bryan. I'll look into your suggestions by mid next week (other fires to put out at the moment). Bill.
Re: Reliable pulse output delays after interrupts?
One thought: TIM2 looks like it can be triggered by an external input and be setup for one-pulse operation (from https://github.com/micropython/micropyt ... PWM-Timers). Maybe I could take an external input and trigger Tim2. I am unable to find out further documentation on the external input/trigger details as well as the one-pulse operation. Any thoughts? I assume that the timers will not have jitter caused by internal interrupt processing.
Thanks, Bill
Thanks, Bill
Re: Reliable pulse output delays after interrupts?
The information on on-pulse mode is on page 326 (Section 13.3.10) of the RM0090 Reference Manual Document.
You can find the RM0090 document here: http://www.st.com/web/en/resource/techn ... 031020.pdf
Warning - It's 835 pages long.
You can find the RM0090 document here: http://www.st.com/web/en/resource/techn ... 031020.pdf
Warning - It's 835 pages long.
Re: Reliable pulse output delays after interrupts?
I'm not sure that I understand this correctly. Does it mean that I can not use the pyboard for a fuel injection system that triggers a timer each revolution of the crankshaft and the pulsewidth is for how much fuel to be injected?
Re: Reliable pulse output delays after interrupts?
Do you mean is there an example that shows you exactly what to do to accomplish that? If so then the answer is currently no.
Is the pyboard processor capable of doing that? Yes
Does micropython have an easy way to make that happen right now? No
Is the pyboard processor capable of doing that? Yes
Does micropython have an easy way to make that happen right now? No