spin help: wait for pins to be stable
Hi,
I want a process to wait until 2 pins are stable at high and then 5 seconds more.
Any dip on any of the pins during this time should start a new 5 second period wait.
In other words, I want a wait until 5 seconds after the last dip.
Can anyone help me with some codelines for this, please!
Nick
I want a process to wait until 2 pins are stable at high and then 5 seconds more.
Any dip on any of the pins during this time should start a new 5 second period wait.
In other words, I want a wait until 5 seconds after the last dip.
Can anyone help me with some codelines for this, please!
Nick

Comments
PRI WaitForPinHighForFiveSeconds timeout := now + 5 seconds repeat while now < timeout if pin low timeout := now + 5 seconds returnor
PRI WaitForPinHighForFiveSeconds repeat timeout = now + 5 sconds repeat while pin high if now > timeout returnThe only issue there is short period lows on the pin. If they are of shorter duration than you are sampling the pin at you will miss them.
If you need to handle short period pulses you will need a slightly more complicated approach, using an additional cog.
Thanks !
/Nick
I enjouyed writing some democode for this
see attached files
best regards
Stefan
If you can spare an extra pin the code is simple....
1) Read the input pin
2) Make the output pin equal to what was read in #1
1K 10K Actual Input >---/\/\---o---/\/\---< From Output Pin | o----------> To Input Pin▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Post Edited (Beau Schwabe (Parallax)) : 10/3/2008 4:58:49 AM GMT
When using waitcnt, the systemcounter rollover isn't any problem but doing other thing meanwhile, like checking if the pin has changed, makes it a problem. THANKS A LOT for your democode !
Beau: The idea with schmitt trigger using an extra pin is good, I'll add it to my notes, but doesn't solve the problem in this case.
Maybe I should have told the whole story directly: I'm building a speedometer for my model railway. The input pins are connected to two IR-detectors sensing a model train passing. The detectors are mounted between the ties together with two IR-diodes mounted upwards, so the IR-beams are reflected by the bottom of the loco or waggons. The reflection isn't constant so the pin will vary high-low as long as the train passes (eg. due to gaps between waggons)
What I want to achive is waiting for tho whole train to pass and then 5s extra.
Flow:
Idle state: waiting for first trig of one of the detectors
First trig: store counter, wait for the other detector to trig
Other counter triggered: calculate time and speed, show on display, wait until whole train passed both detectors plus 5 s
Reset display, back to idle state
Nick
[noparse][[/noparse]code]
PUB elapsed_time_msec(p_TimeVar)
'can measure up to approximately 53 seconds at 80MHz
· result := ((cnt >> 1) - (p_TimeVar >> 1))&$7FFFFFFF/(clkfreq/500)
[noparse][[/noparse]/code]
Essentially what we're doing here is forcing the propeller to do·31-bit unsigned·arithmetic instead of 32-bit signed arithmetic.·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."
- Bjarne Stroustrup
Post Edited (Ken Peterson) : 10/3/2008 1:31:58 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."
- Bjarne Stroustrup
good ! very short coding
but there was a little bug in it
the new divider for ClkFreq is 2000
as it is the divider of a divider its not the half but the double of the divider before
best regards
Stefan
Post Edited (StefanL38) : 10/3/2008 1:57:24 PM GMT
Still up for a hardware solution?
"...The detectors are mounted between the ties together with two IR-diodes mounted upwards, so the IR-beams are reflected by the bottom of the loco or waggons. The reflection isn't constant so the pin will vary high-low as long as the train passes (eg. due to gaps between waggons)
What I want to achive is waiting for tho whole train to pass and then 5s extra..."
Seems like you need something like a "missing pulse detector".· The circuit below will output a HIGH when there is nothing blocking the sensor, and output a LOW when there is something blocking the sensor.· During brief interruptions where the sensor is not blocked, the output will·still remain LOW.
·
Assuming a 1.4V threshold, an R value of 330k and a C value of 10uF provides about a 1 second delay.· Increasing the C value to 47uF provides about a 5 second delay.
·
Since the threshold of 1.4V could vary from Prop to Prop , or another processor such as a BS1, BS2, or SX, it might be good to use a 1Meg pot in place of the 330k resistor so that you can fine tune the timing yourself.· Once you settle on a value that works, you can substitute a fixed value resistor in its place.
Edit:
If the supply is 3.3V rather than 5V, then an R value of 180k·instead of 330k will give comparable results ... still assuming that the threshold is about 1.4V
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Post Edited (Beau Schwabe (Parallax)) : 10/3/2008 3:19:03 PM GMT
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
·"I have always wished that my computer would be as easy to use as my telephone.· My wish has come true.· I no longer know how to use my telephone."
- Bjarne Stroustrup
@Ken: I would have done the same mistake without testing the code
@Nick: This is a very good example how different solutions can be found if a project is described in DETAIL.
first of all: I'm developing software now for 25 years. The last 5 years especially for
controlling machines. The code below is a result of this experience. So please don't feel
bad if your code is more complicated or less elegant
I guess your code is easier to understand.
Here is a codeversion which I think does what it should to your speedmeasurement.
I think in a quite short way taking care of the train coming from both directions
(it doesn't matter if sensor1 or sensor2 is triggered first)
and takes care of the sensor switching on/off as many times as he likes
and still measure correct.
I added methods that give the absolut time since last rollover to zero of the systemcounter
This code uses the very short and therefore elegant calculating of elapsed_time_msec from Ken
copy &paste this code to the Propeller-IDE to have the comfort of different colors
for comments and PUBs etc.
'Use F11 to store it the EEPROM. If you open the COM-Port 'with a terminalsoftware this may cause a reset and this reset starts new booting 'the content of RAM will be overwritten by the still different content of the EEPROM 'loaded to the RAM by the boot-process CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 c_Input = 0 c_Output = 1 c_Low = 0 c_High = 1 Sensor1_PinNr = 21 '<== IO-Pin number that should be watched to be stable Sensor2_PinNr = 1 '<== IO-Pin number that should be watched to be stable c_WaitPeriod = 5 VAR long heart_stack[noparse][[/noparse] 20] long SS_of_Sensor1 'SnapShot of Systemcounter "cnt" from Sensor1 long SS_of_Sensor2 long Et1 'to store elapsedtime of Sensor1 long Et2 long TimeDiff OBJ 'heart : "heartbeat" little object from the obex that makes an LED blink 'that i can see easily bootphase finished after reset and Prop is running debug : "FullDuplexSerial" PUB Main 'the FIRST PUB-Method inside a spinfile is ALWAYS the startpoint where the program starts to run 'heart.Start(27, 200) debug.start(31, 30, 0, 57600) DIRA[noparse][[/noparse] Sensor1_PinNr] := c_Input ' configure PIN as Input DIRA[noparse][[/noparse] Sensor2_PinNr] := c_Input ' configure PIN as Input SS_of_Sensor1 := 0 SS_of_Sensor2 := 0 repeat 'every mathemathical calculation that results 'in a value <> 0 is a logical TRUE 'so you can use a variable itself as a short kind of "SS_of_Sensor1 <> 0" 'it's similar for negation not(SS_of_Sensor1) is short for "SS_of_Sensor1 == 0) repeat until (SS_of_Sensor1 and SS_of_Sensor2) if (INA[noparse][[/noparse] Sensor1_PinNr]) and not(SS_of_Sensor1) SS_of_Sensor1 := cnt 'make SnapShot 'adding "and not(SS_of_Sensor1)" does the following: 'SS_of_Sensor1 is set to zero before entering the loop 'as long as SS_of_Sensor1 is zero the condition "not(SS_of_Sensor1) is TRUE 'by the first switching of the sensor SS_of_Sensor1 gets a value <> 0 'then the condition "not(SS_of_Sensor1)" is no longer true 'because of this the SnapShot is NOT updated by later switching to high of the sensor 'this means: later switchings of the sensor are ignored {'for debugging purposes if SS_of_Sensor1 debug.str(string(" SS_of_Sensor1=")) debug.dec(SS_of_Sensor1) debug.tx(13) } if (INA[noparse][[/noparse] Sensor2_PinNr]) and not (SS_of_Sensor2) SS_of_Sensor2 := cnt 'make SnapShot { if SS_of_Sensor2 debug.str(string(" SS_of_Sensor2=")) debug.dec(SS_of_Sensor2) debug.tx(13) } Et1 := elapsed_time_msec(SS_of_Sensor1) Et2 := elapsed_time_msec(SS_of_Sensor2) TimeDiff := ||(Et1 - Et2) 'here you add calculating and displaying time and waiting for 5 seconds if (SS_of_Sensor1 and SS_of_Sensor2) debug.str(string(" TimeDiff=")) debug.dec(TimeDiff) debug.tx(13) waitcnt(ClkFreq + cnt) SS_of_Sensor1 := 0 SS_of_Sensor2 := 0 PUB Absolute_microsec : microsecs microsecs := ((cnt >> 1) & $7FFFFFFF / (clkfreq / 2_000_000)) PUB Absolute_msec : millisecs millisecs := Absolute_microsec / 1_000 PUB Absolute_sec : seconds seconds := Absolute_microsec / 1_000_000 PUB elapsed_time_msec(p_TimeVar) 'can measure up to approximately 53.7 seconds at 80MHz 'remove bit 32 which is the sign "+-" by shift bits one to the right by ">> 1" result := ((cnt >> 1) - (p_TimeVar >> 1)) & $7FFFFFFF / (clkfreq / 2000) '80 MHz = _xinfreq = 5_000_000 with _clkmode = xtal1 + pll16x '5_000_000 = 5 MHz x pll16x = 80 MHz 'with lower pll_x-factors than pll16x measuring-range goes up with 'factor 80MHz / ClkFreq = 80Mhz / (_xinfreq * pll_x) 'example: 5 MHz * pll4x = 20 MHz. measuring-range: 53.7 seconds * (80MHz / 20MHz) = '53.7 seconds * 4 = 214.8 secondsbest regards
Stefan