jm_freqin question
eagletalontim
Posts: 1,399
Quick question... I am using the jm_freqin function to read RPM values on my vehicle and using the value returned in several other functions. I am displaying the results on my lcd display which everything is working properly 98% of the time. What I have having an issue with is the rpm value seems to glitch every once in awhile and it returns a value well over 100,000. I have the freq() called like this which runs with the LCD cog :
[PHP]
PUB LCDupdate
getrpm.init(15)
lcd.init(24, 9600, 2)
lcd.displayOn
lcd.backLight(TRUE)
waitcnt(2_000_000 + cnt)
lcd.cls
lcd.str(string("Gear: "))
lcd.gotoxy(0,1)
lcd.str(string("RPM : "))
repeat
ReadThrottle
rpm := getrpm.freq * 3
lcd.gotoxy(5,0)
lcd.str(num.dec(gear))
lcd.gotoxy(5,1)
lcd.str(string(" "))
lcd.gotoxy(5,1)
lcd.str(num.dec(rpm))
lcd.gotoxy(10, 0)
lcd.str(string(" "))
lcd.gotoxy(10, 0)
lcd.str(num.dec(throttle)) ' Display
waitcnt(10_000_000 + cnt)[/PHP]
I think it may have something to do with how I have it hooked up. I am using the same circuit as I use on the SX which is probably wrong....
[PHP]
10K
5V Ignition Pulse Signal >
/\/\/\/\/\
0
Prop Pin
|
|
/\/\/\/\/\
>GND
100K
[/PHP]
Is this a common issue with the jm_freqin function or am I doing something wrong?
[PHP]
PUB LCDupdate
getrpm.init(15)
lcd.init(24, 9600, 2)
lcd.displayOn
lcd.backLight(TRUE)
waitcnt(2_000_000 + cnt)
lcd.cls
lcd.str(string("Gear: "))
lcd.gotoxy(0,1)
lcd.str(string("RPM : "))
repeat
ReadThrottle
rpm := getrpm.freq * 3
lcd.gotoxy(5,0)
lcd.str(num.dec(gear))
lcd.gotoxy(5,1)
lcd.str(string(" "))
lcd.gotoxy(5,1)
lcd.str(num.dec(rpm))
lcd.gotoxy(10, 0)
lcd.str(string(" "))
lcd.gotoxy(10, 0)
lcd.str(num.dec(throttle)) ' Display
waitcnt(10_000_000 + cnt)[/PHP]
I think it may have something to do with how I have it hooked up. I am using the same circuit as I use on the SX which is probably wrong....
[PHP]
10K
5V Ignition Pulse Signal >
/\/\/\/\/\
0
Prop Pin
|
|
/\/\/\/\/\
>GND
100K
[/PHP]
Is this a common issue with the jm_freqin function or am I doing something wrong?
Comments
As far as I can remember, you're the first to complain. It's an auto application, right? How do you know the problem is not noise bursts in the system? Have you monitored the input with a 'scope?
Another thought: You don't need to know the period for a tachometer application -- why don't you just write a custom object that uses one of the counters in edge detector (counter) mode in a synchronous loop. You don't even need PASM, you could launch a Spin cog that would report the # of transitions every second; write that to the hub and the multiply by 60 to get RPM. Pretty easy.
Could you explain how I could use Prop to output the duration of the high and low? I am still learning the Prop language and getting better as we go
Okay, here's a hint:
-- set the counter for POS detect mode using your input pin
-- set the FRQ register to 1 (PHS register incremented once per clock)
-- wait for the pin to be low
-- clear the PHS register
-- wait for the pin to go high (PHS being updated now)
-- wait for the pin to go low
-- copy the contents of the PHS register -- this is how many clock ticks the signal stayed high
Andy does a good job with counters in his book. You're going to have to dig in and do a bit of study. Yeah, I know it's a drag, but you'll be happy you did when you stop guessing at code and start designing it.
[PHP]
VAR
LONG rpm
LONG counter[100]
' other variables for rest of code
PUB Main
cognew(CountHigh, @counter)
' main code and loop
PUB CountHigh
ctra[30..26] := %01000 ' Set mode to "POS detector"
ctra[5..0] := 15 ' Set APIN to 17 (P17)
frqa := 1 ' Increment phsa by 1 for each clock tick
dira[15]~ ' Pin to input
repeat
waitpeq(%000000, |< 15, 0) ' Wait for pin to go low
phsa~ ' Clear the phsa register
waitpeq(|< 15, |< 15, 0) ' Wait for pin to go high
waitpeq(%000000, |< 15, 0) ' Wait for pin to go low
rpm := phsa ' - 624[/PHP]
Sound about right? The rpm variable is outputted to the LCD screen with the LCD updating cog.
Readings :
1000 RPM : ~ 129600 to ~130300.
2000 RPM : Same
3000 RPM : Same
4000 RPM : Neighbors came out
Do I need more readings or readings from the pin being low?
Consider with a 4 cylinder there are 4 ignition events in 720 degrees.
At 6000rpm there are 100 revolutions per second, 2 ignition events per rev, 200 ignition events per second.
1000ms / 200 sparks is 5ms per ignition interval
RPM = 120_000 / cylinders / interval in milliseconds
Here is my variable updater code so far :
The problem I am running into is the vspeed variable that is being displayed on the screen is jumping around too much for me to get an accurate reading. The speed sensor is a reed switch which gets 5v from the ECU and outputs X number of times per revolution. I am thinking it is 4 pulses per revolution. What I am trying to find out is how many revolutions per 500ms I get at specific speeds. When I use the code above and drive at 40 mph, the reading stays steady at ~ 744 and then jumps to ~ 1180 for a few seconds, then drops back to ~744. That is way too much of a jump for me to use in a math formula. Is the time of how long it takes to process the code above my issue?
From what I gather, the jm_freqin reads the exact time from the start of a high signal to the end of a low signal and returns that as "period". It is then put into this formula clkfreq * 10 / p where p = period. The output is how many pulses are in a 10 ms time period (0.1Hz)? Is that a constant 10ms all the time or does it fluctuate? Or.... do I have it backwards... The output is the amount of time between each pulse? If that is the case, why are my numbers fluctuating soooo much at a constant speed?
I cannot use the BS2.COUNT on this since if the code starts counting before a pulse goes high, then the next time start counting right before a pulse goes low, the results will be different.
You can debounce using software algorithms or with hardware. The level of difficulty depends on the severity of the noise.
You can try the simple fixes first, like low pass filtering that was described before. Next you can do edge detection and disable the input for a moment, and re-enable it.
You may find that simply not accepting a value smaller than a fixed preset is the best solution; throw away a narrow pulse and don't integrate it into your low pass (you should be doing a low pass to smooth out the data).
I would bet your VSS is either a hall effect or variable reluctance. You really need a scope to tell them apart and make a proper interface circuit or you need a very good wiring diagram with depictions and pinouts of sensors.
I found a diagram that looks close, the sensor has 3 wires and looks like a hall effect sensor. This is the output speed sensor.
http://www.justanswer.com/uploads/al525i/2009-03-19_205426_trans2.gif
Looks like 104 is a 5v pullup input. The other wire is ground, the 3rd is ignition power. Looks like an open collector NPN output. What do you have for a resistor on the input of the prop, going to this sensor? Where are you hooking up to the wiring harness?
EDIT : I just found out that the speed sensor is located in the dash.?.? The speedometer cable runs directly to the dash which connects to a wheel with cutouts which is then converted to give a signal to the gauge.