PDA

View Full Version : RPM - DIV32 Problem



davewanna
- 11th April 2008, 02:57
I am reading a tacho out line from an engine ECU with pulsin, scaling it, then displaying it on an LCD screen. I have had it working with the following code...



PULSIN PORTD.6,1,rlow
PULSIN PORTD.6,0,rhigh
rpm = rhigh + rlow
rpm = rpm / 50
rpm = 60000 / rpm
if rpm = 65535 then
rpm = 0
endif
...
lcdout $fe,$ca,dec rpm,"rpm "


in the higher RPM, the resolution drops, so I figured if I was to change my calculations to be ... rpm = 3000000 / rpm ... then the resolution would increase.

However when I make it ...



PULSIN PORTD.6,1,rlow
PULSIN PORTD.6,0,rhigh
rpm = rhigh + rlow
tbase = 50 * 60000
rpm = div32 rpm
if rpm = 65535 then
rpm = 0
endif


The result is roughly 32370rpm
when the revs are increasing, the displayed rpm decreases, and visa-versa... but when the rpm is steady (at idle, or held steady at any RPM) the displayed rpm settles back to 32370

Is there something I am missing here? I am successfully using DIV32 many more times in my code for other functions.

Also I thought I might be overflowing the DIV32 integer (but according to my manual I am not) so I thought I would try....



PULSIN PORTD.6,1,rlow
PULSIN PORTD.6,0,rhigh
rpm = (rhigh + rlow) / 10
tbase = 500 * 600
rpm = div32 rpm
if rpm = 65535 then
rpm = 0
endif


This results in 0 being displayed all the time.

At idle, rlow, and rhigh (which are identical) read approximately 1400 each, which when I do my maths on paper, (either method I have shown) comes out to approximately 1071rpm which would be correct




Could somebody more intelligent or more observant than I please help me? :)


Also might add I'm using a 16F877A

mister_e
- 11th April 2008, 03:07
Not a fan of pulsin or count... I could do some calc... but i feel lazy... did you measure the frequency range of your signal?

What's the min, and max? From what i remember 1,000 RPM for a 4Cyl signal is ~30 HZ.. but noisy 30Hz, so you must do some signal shaping and some average (samples) of it, unless it's not going to be really accurate...

davewanna
- 11th April 2008, 03:29
mister_e...

It's not a pulsin problem, I am displaying rhigh and rlow on the LCD, and they are great... the number falls when the revs goes up, visa-versa... And in my first example the whole thing works perfectly... it's just that because of the division by 50, the result is a number like 56 at 1000rpm, and lower for higher rpm, and therefore poor resolution... Something like 200+rpm jump over around 4000rpm.

I don't need it to be spectacular, but I will change it when I learn more about timers and interrupts.

The issue I have is that my calculations on paper are right, but in the pic are just not working.

Also if I change the line "rpm = rhigh + rlow" ... to ... "rpm = rhigh * 2" ... or ... "rpm = rlow * 2" ... I get 1rpm when the engine is running, and 0rpm when the engine is not. That doesn't make any sense to me... As the result should be the same.

Also might add I'm using a 16F877A

mister_e
- 11th April 2008, 03:34
Hence why i asked for your frequency range. Knowing this, we can know what happen at idle... there we will find your max value for each Pulsin... which i suspect to be really high, so when you add them it just overflow... or they are already zero because of your possible low frequency (or you use BYTE variable)... then screw everything else...

We also need to know your PIC OSC value.

davewanna
- 11th April 2008, 03:44
I'm not sure exactly why you think it's overflowing, as I'm showing it on the LCD to be 1400, but here goes...

I haven't put a cro on it (would have to take out out to the car) but, with the 4mhz clock, at idle (roughly 1000rpm) rlow, and rhigh show me roughly 1400 each. So the 4mhz clock gives resolution at 10us, so a complete high/low would be 28mS.

davewanna
- 11th April 2008, 04:00
I have just changed my code to:



PULSIN PORTD.6,1,rlow
PULSIN PORTD.6,0,rhigh
rtotal = (rhigh + rlow) / 10
tbase = 500 * 600
rpm = div32 rtotal
if rpm = 65535 then
rpm = 0
endif


and I am displaying rtotal on my LCD, which when rlow and rhigh are at 1400, rtotal is at 280. Exactly what I expect. The problem is in the next 2 lines. 500 * 600 should be 300,000. Which when divided by 280, should give me 1071.

But instead I get 0rpm (obviously caused by the following if statement intended to show me 0rpm if the engine is not running)

mister_e
- 11th April 2008, 04:15
The little problem is that you MUST use variable in your 16x16 bit multiplication, unless it's not going to work.



rlow var word
rhigh var word
rtotal var word
RPM VAR WORD
tbase var word
a var word
b var word
a=500
b=600
'
'
'
rhigh=1400
rlow=1400
rtotal = (rhigh + rlow) /10
tbase = a*b
rpm = div32 rtotal

this return 1071

you should have better resolution with...


rlow var word
rhigh var word
rtotal var word
RPM VAR WORD
tbase var word
a var word
b var word
a=5000
b=600
'
'
'
rhigh=1400
rlow=1400
rtotal = (rhigh + rlow)
tbase = a*b
rpm = div32 rtotal

davewanna
- 11th April 2008, 04:20
ok I have done some more changes... just for debugging purposes... My code now looks like:



PULSIN PORTD.6,1,rlow
PULSIN PORTD.6,0,rhigh
rtotal = (rlow + rhigh) / 10
tbase = 500 * 600
rpm = div32 280
if rpm = 65535 then
rpm = 0
endif


This was to test if putting the variable rtotal after the DIV32 command was in any way incorrect. According to what I understand, it should now just display a fixed 1071rpm on the LCD.

However... when I now start the engine, at any rpm lower than roughly 1100 (probably 1071 to be precise), the display shows 0rpm, but over that, as I rev the engine, it shows RPM in the 32000 + range.

WHAT IS DIV32 DIVIDING BY 280??? Cause it's not 300000...

mister_e
- 11th April 2008, 04:22
seems we post at the same time ;)

davewanna
- 11th April 2008, 04:31
Mister_e you are my hero!!

That was the problem, I wasn't using variables. I originally had it trying to divide by 3,000,000 but thought I might be over-flowing for some reason, and tried it at 300,000.

DIV32 was taking the last calculation using variables (rlow + rhigh /10) and therefore dividing rtotal by itself.. which was giving me a 1 while running, and a 0 while off...

All makes sense now really..

Just for interests sake, code now looks like



a = 50
b = 60000
...
PULSIN PORTD.6,1,rlow
PULSIN PORTD.6,0,rhigh
rtotal = rlow + rhigh
tbase = a * b
rpm = div32 rtotal
if rpm = 65535 then
rpm = 0
endif


Thankyou very much, many hours were wasted over that.

Now that I have it conquered, I will learn more about timers and interrupts.

mister_e
- 11th April 2008, 04:33
I knew there was a "fussy" code writing thing in that. Better explanation at the following link
http://www.picbasic.co.uk/forum/showthread.php?t=6931&

Glad to hear it works.