Technical RPM counter

Currently reading:
Technical RPM counter

Joined
Aug 23, 2007
Messages
551
Points
93
This is not your typical RPM counter question. I'm studying electronics here and i'd love to make a digital rpm counter, but i need some more tech details on the seicento ecu.

I understood that there's some sort of rpm information on pin 23 of the ecu (violet/black wire?). As far as i understood, it gives one +5v pulse for every rotation. Am i right?

If the above is right, the best resolution i'll have is 60 rpm (if i detect 1 pulse in 1 second, that means it's going at 60rpm, 2 pulses in 1 second would be 120 rpm and so on... not very precise). I was thinking of an another way to solve that...

I'm pretty sure that seicento has a crankshaft rotation sensor. And it should have a lot of "teeth", so i could get much higher precision with that (also, shorter sample/update times). What pin does this sensor connect to, and what is its output voltage? How many teeth are there on the crankshaft? (i know there are usually missing teeth, but there aren't enough to make my rpm counts too inaccurate).

If you have any information that could help me, please share it with me, and i'll share the final schematics / MCU software used with you guys :)

I'm planning to use an Atmel 89S8253 microcontroller and four 7-segment displays for the rpm.
 
hmm, you're right this isn't what i expected it to be!

You'd think it'd pulse once for every rotation, but it doesn't. It pulses once for every 2 rotations. (hence why in the FAQs about fitting after market rev counters, it says about using ones intended for 2 pot engines else it'll only read half).

The crankshaft sensor is a VR sensor. I don't know the voltage it produces. The crank wheel has 58 teeth, and a 2 teeth gap. It's a standard Bosch 60:2 wheel.

Code:
11 	Input 		TDC / RPM Sensor Signal Negative
28 	Input 		TDC / RPM Sensor Signal Positive

they are the pins used on the Cinquecento. The SPI (mk1) Seicento should be the same, i don't know about the MPI.
 
Last edited:
What do you mean by studying electronics? At school, university or just personal interest?

+5V pulses, that sounds quite simple (if that's right). An oscilliscope would tell you exactly what's going on. Do you have access to an oscilliscope, and are you able to get one to your car? It may also be useful to know how long the pulse stays up for.

If the above is right, the best resolution i'll have is 60 rpm (if i detect 1 pulse in 1 second, that means it's going at 60rpm, 2 pulses in 1 second would be 120 rpm and so on... not very precise). I was thinking of an another way to solve that...

I'm planning to use an Atmel 89S8253 microcontroller and four 7-segment displays for the rpm.

60rpm resolution? Wouldn't it be a 1rpm resolution? Having said that, you'll probably want to display no more than 3 digits, maybe even just 2. The difference of 1rpm is pretty meaningless.

I haven't used an Atmel, but I would have though almost any microcontroller would do the job. I've used a PIC in the past, which was very cheap (<£1 IIRC), had a built in oscillator and many other things like an A to D converter. I think it would take 5V straight on the input pins too. There is a free IDE (with emulators) can be downloaded from the Microchip website. It is in assembly, but didn't find it too bad. I'm haven't read about the Atmel, it may be better, but you could also look at the PIC.

For the program I suppose you would start a timer and reset it when there's a rev. The value in the timer register before the reset would give you the revs, after applying a bit of maths. Then you've just got to do the displays.
 
What do you mean by studying electronics? At school, university or just personal interest?
University, but this is pretty much just personal interest, unfortunately, we don't do anything practical at uni...

60rpm resolution? Wouldn't it be a 1rpm resolution? Having said that, you'll probably want to display no more than 3 digits, maybe even just 2. The difference of 1rpm is pretty meaningless.
If i choose a sampling time of 1 second, then i'll have the number of revs in that second. If the engine made 1 rev in that second, that is 60*1=60 rpm. That's why i'll probably use the crank shaft sensor instead, if possible.

You'd think it'd pulse once for every rotation, but it doesn't. It pulses once for every 2 rotations.
Ouch, that's even worse, it would give me 120 rpm resolution :( So, that's definitely not an option (but it does seem strange to me that the resolution would be so bad, maybe the stock rpm counters do some kind of averaging to overcome this problem?)

The crankshaft sensor is a VR sensor. I don't know the voltage it produces. The crank wheel has 58 teeth, and a 2 teeth gap. It's a standard Bosch 60:2 wheel.
If it's a VR sensor, then there's no way i'll be looking at +5v pulses, because as far as i could google out, it gives a sine voltage. Shouldn't be much of a problem to amplify the signal, possibly even rectify it to get an ever higher sampling rate, and use some sort of a treshold (schmitt) trigger to give me clean 5v pulses. I should sort the voltage levels out first with an oscilloscope. Since it has a positive and negative signal leads, i suppose it uses ground as a reference for both... I'll need to measure that first and then i'll have some sort of an idea how to solve it all. If i'm able to get 60 pulses per second (i'll ignore the two missing teeth and sort that out in software), that would be IDEAL, because i could have 1rpm precision with that.

I decided to use an Atmel because i have a nice development board/programmer for it, and i don't have the equipment for the PIC. Also, i like its 32 in/out pins :) (need 8+4 for the displays and multiplexing, 1 for the pulse counting and maybe some more for other stuff i might add later on, one idea is a beeper to notify you that you've reached the ideal rpms to upshift and so on ;))

A problem I'm aware of:
- the MCU i want to use is an 8-bit one. The largest integer value it can hold is 255, and rpm can go to around 7200. Not a big problem, i can use BCD or simply disregard the two less significant digits (i probably won't do that, and will try to do some averaging/damping so the value doesn't jump all over the place, since it will use a digital display) and always display them as zeroes, or keep the value in 2 bytes (a pain in the ass sometimes)

Questions i have:
-Where is the best place to tap into the crank sensor signal, if possible without having to cut any wires while measuring levels with an oscilloscope? Where is this sensor located, under or above the crank? Is it easily accessible? Will i have to get under the car to reach it?
-I just remembered that the ECU actually has 2 separate connectors to it. When you say pin 11 or pin 23, which connector am i supposed to look at? Also, is there a diagram or a pinout of those connectors, that would be great.
-Since it will be 4x 7-seg displays, where do i install them in the cockpit so it looks nice? ;) (it's still a long way to go until then ;))

Thanks for all the great info so far! :worship:
 
nmrmak said:
A problem I'm aware of:
- the MCU i want to use is an 8-bit one. The largest integer value it can hold is 255, and rpm can go to around 7200.
Not strictly true, this is in the datasheet:
"Timer 2 is a 16-bit Timer/Counter that can operate as either a timer or an event counter."
You could do it like I said, where the value in the timer register is the rpm's. Although it does make the maths a bit more complicated. I think you're probably thinking of counting the pulses as they come in, and then averaging them out over a period of time?
 
Not strictly true, this is in the datasheet:
"Timer 2 is a 16-bit Timer/Counter that can operate as either a timer or an event counter."
You could do it like I said, where the value in the timer register is the rpm's. Although it does make the maths a bit more complicated. I think you're probably thinking of counting the pulses as they come in, and then averaging them out over a period of time?
Timers are 16 bit. That means that i can count up to 2^16 pulses over a period of 2^16 clocks (which is about 100ms, according to my approximate calculations). I use timer 1 as a 16 bit timer, and when it overflows 10 times, it means a second has passed. Then i take the value out of timer 2, which i use as a counter and do the math (multiply counter by 60), but the result has to be saved in an 8-bit register.

The other approach would be to measure the time between two impulses, but that's impossible if there's one pulse per 2 revs, as someone (arc) said, because the timer overflows in 100ms, and at an idle speed of, say, 600 rpm, you have one pulse every 2.5 seconds. This approach might be possible if i'll be using a crank sensor (60 pulses per revolution (possibly 120 if i can use the negative side of the signal)), that's 60ppr*10rps=600 pps (ppr=pulses per rev, rps=revs per second, pps=pulses per second), so the time between the pulses would be 1/600 ~= 0.001667s, which is okay.

Does my thinking sound reasonable? If you have a better idea, i'd love to hear it, could save me lots of effort.

I'd love to thank every one of you for each reply you make, because you're helping me get a better grasp of how to approach this problem.
 
Timers are 16 bit. That means that i can count up to 2^16 pulses over a period of 2^16 clocks (which is about 100ms, according to my approximate calculations). I use timer 1 as a 16 bit timer, and when it overflows 10 times, it means a second has passed. Then i take the value out of timer 2, which i use as a counter and do the math (multiply counter by 60), but the result has to be saved in an 8-bit register.

The other approach would be to measure the time between two impulses, but that's impossible if there's one pulse per 2 revs, as someone (arc) said, because the timer overflows in 100ms, and at an idle speed of, say, 600 rpm, you have one pulse every 2.5 seconds. This approach might be possible if i'll be using a crank sensor (60 pulses per revolution (possibly 120 if i can use the negative side of the signal)), that's 60ppr*10rps=600 pps (ppr=pulses per rev, rps=revs per second, pps=pulses per second), so the time between the pulses would be 1/600 ~= 0.001667s, which is okay.

With the PICs you can set the internal oscillator, but it doesn't look like you have many choices with this one. One way to get around it would be to add an external oscillator at a slower speed so that it takes longer to overflow, is that possible? From your 100ms I worked the clock out to be 12MHz, so maybe you could use a 6MHz oscillator?
 
One way to get around it would be to add an external oscillator at a slower speed so that it takes longer to overflow, is that possible? From your 100ms I worked the clock out to be 12MHz, so maybe you could use a 6MHz oscillator?
Sure, that would double the maximum rotation period to 200ms, limiting me to 5 pulses per second, which is 10 revs per second, which is 600 rpm.
Can centos idle slower than that? (i could still use a 4Mhz oscillator or something)
I don't think it would be neccesary to measure rpms lower than that, but if the engine would come near stalling, it could fall under 600 rpm and then the timer would overflow, giving the impression that the rpms are sky-high. That could be annoying, but would be a rare problem. Also, the display would fluctuate on every 2 revs (i could of course sort this in software)

I'm still thinking about using the crank sensor instead of the ecu pin 23... what do you think about that? it would take some extra circuitry to get the levels up to 5v, schmitt triggers to give me a clean edge pulse, some capacitors for signal damping and noise reduction, but it would be more precise i think... And i could average it over, say, 1/10 of a second (at 600 rpms, you have 60 pulses on the crank sensor in 0.1s, so i could update the counter every 0.1s or 0.2 or 0.5 with far less software challenges)
 
the crank sensor cable is a twin core sheilded cable, they don't much like being poked / cut.

for using this the VR sensor, have a look into MegaSquirt (it's the ECU i run on my car). It has conditioning circuits on it, which you might be able to use.
 
You could look to fit the sei mpi cam pulley and cover, that way you could utilise the hall effect pickup and trigger pattern that occurs every rotaion of the cam.

It would be elegant but possibly OTT.

The megasquirt project may be worth a look, they have an add on board for a second trigger, that uses am LM1815

http://forums.turbobricks.com/showthread.php?t=95888

could be used to add a second sensor, or split off the crank sensor?


Another option would be an inuctive pickup on a HT lead, or for rougher estimate, the LT side of the coil packs....nice LV DV levels.

So may options, each with their own merits and pitfalls.

Kristian
 
All of those are possible, and to be honest, it would be the easiest thing engineering wise to add my own sensor to the crank (or the flywheel, make some sort of a laser-rpm counter, add another hall effect sensor or something), but my idea is to do this in a way that would be minimally invasive so to speak, and easy for anyone to do, but still precise. As i understand, cutting the crank sensor cable is a no go, but i'm sure i can pick up the signal somewhere else, recondition it (shouldn't be a tough job, nice schematics there) and feed it to my mcu.

If i fail miserably at making the crank sensor to work, i could always fall back to the "one-pulse-per-two-revolutions" idea and use the method that The Ugly Duckling suggested, using a slower oscillator, such as the 6MHz one to get the minimum measurable rpm to 600. I suppose i could go for even slower oscillators, but i'm not sure if i'd have some problems with the displays then.

Now that i'm thinking about it (it's 3am though, so my thinking may be well flawed), maybe timer overflows wouldn't be a problem. I can detect timer overflows (using interrupts for example) and simply make an "overflow counter", that would actually be a good idea. That would allow my circuit to run at 12 MHz (means i don't have to go and buy a new oscillator :D). I have already made a prototype program on the development board using some of my own ideas, but it will show half (or double, can't think right now) the real rpm because i thought it was 1 rev 1 pulse. Maybe i'll mod it tomorrow and write a new one with these fresh ideas. Please keep them coming!

So far, these are the two ideas i've had:

1. time based. Wait for some time (1 second in my example), count the pulses that came in during that time, and then multiply it by 60s/time (since time = 1s in my case, i multiply it with 60) and you'll get your rpm. 1 rotation per second = 60 rpm, 10 rotations per second = 600 rpm and so on
NOTE: this is flawed, because it's one pulse per 2 revs, just an example.
Upsides: easy to implement, no rpm fluctuations
Downsides: Not precise, has a coarse resolution (60 rpm in my case)

2. revolution based. Clear the timer. Start the timer. When a pulse comes in, stop the timer and tell me how much time it took for one rev. Repeat.
Upsides: very precise. Tells you the current rpm
Downsides: Could run into some limitations of the microcontroller i'm using now, the maths could get quite messy as well. The time it takes for each succesive rev to complete will always be off by a little, so you'll see a lot of fluctuations on a digital display. Would be great for analog displays though.

I'll keep you up to date on my project, hope to hear more ideas from you guys. (y) You've already helped me a bunch! :worship:

After i'm done, i'll release the board schematics along with the software in ASM for 8051 and the hex file for the mcu i'm using. You'll be free to use it in your own projects or use it on different mcu architectures (such as PIC as someone suggested)

Oh, and if my text is sometimes confusing, sorry about that. English isn't my native language, and i'm pretty tired at the moment, slips happen. :D
 
you've got me questioning what i put earlier now, starting to wonder if its two pulses per rpm, or one pulse per two rpm on pin23.. anyways..

as kritip suggested - you could use the LT connections. The engine uses wasted spark, so in one rotatation it should fire each plug twice. 1(4) 3(2) 4(1) 2(3). the numbers being what the engine needs to fire, and the one in brackets being the wasted spark.

The coilpacks are triggered using a negative pulse from the ECU - think if you use one of them, optoisolated to prevent it trying to sink the current needed to drive the coil pack through your PCB - that might work out nicely.

Don't worry about your English, it's much better than a lot of what i've seen on here!
 
Last edited:
One main problem with digital displays is with fast changing inputs, Your eyes find it hard to read the display. Analogue are better for this aplication.
 
Many thanks, arc. I am expecting the idle speed to be somewhere between 600 and 800 rpm, so if it shows 400 or 1200 on the oscilloscope i should be able to figure out if it's twice per rpm or once in two. One more question, when you say LT connections on the ecu, what pins are you referring to?

cc1: Yes, that is a problem, but i'd like to focus on making the software for now, analogue displays are an engineering challenge if you want them to be precise. And the displays will only be updated twice a second or so, i'm hoping to avoid fluctuations that would make it unreadable. Besides, digital displays are a lot easier for a hobbyist to get his hands on. At some point, i might provide either a voltage signal (using a DAC) or maybe a pwm or stepper motor signal, but that's not my primary objective right now.
 
the LT connections are pin 1 and pin 19. here is the full pinout for the SPI ECU.

Code:
Number 	Description 	Component / Function Notes
1 	Output 		Ignition Coil 1 Cylinders 1+4
2 	Output 		Idle Control Stepper Motor Phase B
3 	Output 		Idle Control Stepper Motor Phase D
4 	Output 		Central Power Relay (Power-Latch) Power to RAM
5 	Input 		Automatic Gearbox ECU input Only on Version CA
6 	Output 		ECU Warning Lamp Activated on -Vbatt
7 	Input / Output 	Immobilizer (If Present, otherwise NC) Bidirectional
8 	Input 		Air Conditioner Relay on (+) Activated on +Vbatt
9 	NC 		Not Connected Not Connected
10 	Input 		Serial Line L Unidirectional line (FLT->ECU)
11 	Input 		TDC / RPM Sensor Signal Negative
12 	Input 		Lambda Sensor Signal Negative
13 	Input 		Water Temperature Sensor Signal
14 	Output 		Sensor +5v Line 5 volt DC
15 	Output 		Serial Line K Bidirectional line (FLT->ECU)
16 	Power 		Signal Grounds In Wiring Loom
17 	Power 		Primary Ground Engine Ground
18 	Output 		Fuel Injector Controls SPi Unit
19 	Output 		Ignition Coil 2 Cylinders 2+3
20 	Output 		Idle Control Stepper Motor Phase A
21 	Output 		Idle Control Stepper Motor Phase C
22 	Output 		Charcoal Canister Multifunction Valve
23 	Output 		Engine Speed Limiting (Fuel Pump) Relay Fuel Pump / Injector / Canister / Coils / Lambda
24 	Output		Air Conditioner Relay on (-) Activated on Gnd
25 	NC 		Not Connected Not Connected
26 	Input 		Ignition in "On" Position
27 	NC 		Not Connected Not Connected
28 	Input 		TDC / RPM Sensor Signal Positive
29 	Input 		Lambda Sensor Signal Positive
30 	Input 		Throttle Position Sensor Signal
31 	Input 		Air Temperature Sensor Signal
32 	Input 		MAP Sensor Signal
33 	NC 		Not Connected Not Connected
34 	Power 		Secondary Ground Engine Ground
35 	Power 		Positive feed from Main Relay Positive out from ECU Relay / Power-Latch

what model of car is this btw, i am basing all my assumptions on it being a MK1 1108cc Seicento.
 
Last edited:
it is a 2003. seicento, 1108cc.
Is there a picture of these connectors (either the connector or the ecu side) so i can see which pin is which, or are they marked on the inside of the connector? (like parallel and serial cables sometimes are)

Edited to add: if it uses a wasted spark, it might make some sense that it gives one extra pulse per rotation. I will probably have the chance to test this on thursday, with an oscilloscope.
 
Last edited:
ok, that model is MPI and uses a different pinout. kritip is the MPI ECU expert ;)

though to trace which wire is firing the coil packs, pick a coil pack and work back from it - and it'll be the wire that isn't at 12v when the ignition is on!
 
you kind of would be, but you could look at it more intercepting the signal from the ECU to the coil pack.

to fire the coil pack, the ECU grounds one of the LT wires off the coil pack. It'll do that everytime it wants to fire a cylinder.
 
Back
Top