Wait for pin to be high for a certain amount of time
ryfitzger227
Posts: 99
I'm jumping into another part of my timing project and I came across something that I absolutely don't know how to do accurately and by not taking up any extra cogs. What I need to do is pause the system for 500ms while a pin is high. But if the pin doesn't stay high in those 500ms, then it needs to wait for the pin to become high again and then again wait for 500ms. Here's a "step-by-step" diagram of what I want done.
How would I do this in Spin accurately? If you have anymore questions, just ask.
Thanks,
- Ryan
- wait for the pin to become high (for ex: [B]waitpeq(|< 25, |< 25, 0) [/B]) - keep monitoring that pin to make sure it stays high for 500ms - if the pin did not stay high for 500ms, return to line #1. - if the pin did stay high for 500ms continue.....
How would I do this in Spin accurately? If you have anymore questions, just ask.
Thanks,
- Ryan
Comments
If you need a few hundred nanoseconds, You'll either need a second cog to use as a watchdog for a waitpeq, or you'll need to do it PASM.
If you can get by with something like a few milliseconds, you may be able to use a loop with "if cnt - earlierTime > TIME_LIMIT" type of comparison.
At least that's all I can think of. I'm curious to see what others come up with.
One way to do this is use an extra pin that the watchdog changes, then you use WAITPNE as the instruction, which will respond
to either pin changing.
Or the watchdog can just coginit the waiting cog (but this has approx 8k cycle overhead), but no extra pin needed.
Or you can set a counter going gated on that pin (POS mode), and another that counts negative edges on that pin (NEGEDGE), and just
poll the counter phase registers? Not perfect as you can read or clear the phase registers in perfect synchrony.
-Phil
What I'm trying to do is use a sensor (like an ir sensor) to tell me if something is there. But for example I don't want the timer to start until something has been there for 500ms. This prevents the timer from starting by somebody just walking through the sensor. So the minimum time could be as little as a blink of the eye. A turn around of a ms or so will be okay for a circumstance like that. The only thing I need accurate is the 500ms that the pin needs to be high. I also want to keep away from PASM, since the rest of my project is in Spin.
There really isn't a maximum time. After the pin has been high for 500ms, I need it to move on to start the timer, etc (so it would no longer even be monitoring that pin).
Could somebody explain to me a little more of what a watchdog is? (I've never heard of that before with a programming language). If it runs in another cog, I can't use it but it's good to have that knowledge.
Any more questions, just ask.
Thanks.
- Ryan
And here's a variation that let's you set the target pin state (1 for high, 0 for low):
It uses a counter that counts only when the chosen pin is high. The counter is present with 500 ms and counts down. If the counter rolls under zero while the pin remains high, the timer routine will be called.
-Phil
Choices are :
a) IP drives counter by edge :
First edge loads Counter, Starts 500ms, Read Counter after 500ms. If no change, have no edges inside last 500ms
b) IP gates the counter
First edge starts the counter, Starts 500ms, Read counter after 500ms, if Counter = 100% of expected value, IP was never low.
One method gives how many edges were in the 500ms, and the other gives the % of time the signal was high.
-Phil
Correct, that is why I said "If you can tolerate a slightly relaxed spec" - the op seems more interested in noise removal, than total minimum decision times, so a relaxed spec may be ok.
-Phil
But if you hard wait 500ms and and a signal was 20ms high + 20ms low + 500ms high
You would miss the start of the last correct signal as 460ms in to it you stopped, checked the psha and it is 480 (=failed the test)
And now you start a new test but that will wait for next low to high, so as Phil said you missed it.
Phil,
Thanks for this code. It works great. I added another feature. Is there anyway I can set this to monitor 2 pins? I'm looking at pins 1 and 3. So same concept as before, but now it waits for both pins to be high instead of just 1. I played around with your code, but couldn't get two pins to work.
Thanks,
- Ryan
After the first edge, subsequent tests do not need to edge re-start.
From the OPs comments, this sounds like a long de-bounce.
There is a relaxed solution that exits when the signal is Hi > 500ms, but as you & Phil mention, it can take up to 2x that to deliver the pass tick.
It uses the counter's logic function to count only on the AND of both pins.
BTW, I wasn't sure if you wanted to wait until one pin went low to start looking for coincident highs, or just one of them, so I included options for both.
-Phil