[TotalNoob] Interpret Engine RPM, output Color based on RPM

To preface, I have had an arduino uno for all of an hour so I am still learning. I did some research on reading engine RPM but without anyone stating that they had done it.
My plan:
Read engine RPM via induction coil.
Have an LED reflect the engine speed by color using an RGB LED. As the engine gets faster, the led fades to different colors.
Example:
800 rpm = Purple
1500 rpm = Blue
3000 rpm = Green
4000 = Yellow
5000 = Orange
6000 = Red

I want the colors to fade into each other smoothly.

Currently this is planned for a motorcycle.
So, that's the plan...now the questions. Will i be able to interpret an induction coil to read the RPM. Will i risk damage to the arduino if the input spikes at all. What type of protection could I add to prevent damage.

Any recommendations on where to start would be great.

You will need an external circuit to convert the pulse from the ignition coil into a 0-5V signal.

If your LEDs draw 20mA or less then you could power them directly from the Arduino - if they need more than that, you would need to drive them via a transistor.

Other than those I/O electrical design issues, the logic you describe would be simple to code.

I'll have to run a multimeter on the induction coil. It may already be less than 5v. Ill go check that out right now.

I was going to use an LED strip designed for arduino from radio shack if they are bright enough. If they arent, i was going to get one of those underbody kits for cars and motorcycles and use that, but i'd have to remove the chip from the pcb it comes with somehow so i can take control of it.

EDIT: So the induction coil idea didnt work, it's not outputting any signal. So i took voltage off what I think are the coils. It read .22 volts at idle and .35 volts at full throttle so i dont see any indication that there will be any sort of massive spike that could damage the arduino. The only funky part is, i cant be sure thats a pulsing source without hooking up a oscilloscope which i dont have. I assume the pulse is so fast that the multimeter doesnt read it properly.

nastyninjabear:
I'll have to run a multimeter on the induction coil. It may already be less than 5v. Ill go check that out right now.

It won't be. It'll almost certainly be 12V with substantial inductive spikes, and not safe to connect to your Arduino. You need to use an op-amp or similar circuit to convert this noisy signal to a clean 0-5V signal that your Arduino can deal with.

Ok, I am looking into which wire brings the signal to the actual Tachometer. I assume that signal has to be clean for the tach to work properly. If it is, cant i just resist it down to 5v?

EDIT: Of course I can, i can use the PCB off a usb car charger to change it from 12v to 5v EASILY.

So im working through learning to code, wondering if anyone would be willing to help me sort this out a bit.

nastyninjabear:
Ok, I am looking into which wire brings the signal to the actual Tachometer. I assume that signal has to be clean for the tach to work properly. If it is, cant i just resist it down to 5v?

The signal from the coil LT circuit will be a nominal 12V square wave but has big spikes on it from the inductive noise from the coil. Tachos designed to be driven from the coil must be designed to tolerate these spikes - in fact some tachos rely on them and don't work reliably when feed with a 'clean' 12V pulse.

Because of the spikes you can't use a simple voltage divider to convert the 12V square wave down to a clean 5V signal. You need to use a transistor or op-amp circuit which will be controlled by the signal from the coil and produce a clean 5V output which is safe to connect to the Arduino.

So i decided this project would be easier on a car than a motorcycle. So instead of tapping into the coils, i can tap into the Tachometer signal wire where it meets the ECU. Im trying to determine if that is 12v or 5v. I dont have an oscilloscope so its hard to determine, i could use the arduino but....no lol.
I assume that is MUST be a clean signal if its going into the ecu.

nastyninjabear:
I assume that is MUST be a clean signal if its going into the ecu.

That's not a valid assumption.

If the coil is switched by the ECU then the connection to the coil is an output, and is definitely not clean.

If the coil is switched by a distributor or some other controller outside of the ECU then the connection from the coil to the ECU is an input, and is definitely not clean.

If you have a bit of wire that is connected electrically to the coil LT then there will be a lot of noise on it which you will need to protect the Arduino from. There's really no getting away from it, I'm afraid.

Ok then. I need some sort of circuit that splits the voltage and regulates it at 5v cleanly. I've heard the term op amp used a few times so i looked it up.....and im lost lol. It seems that an op amp does the opposite of what i want? It amplifies voltage?

Any way someone can point me in the right direction here?

Ok, disregard this entire post :slight_smile:

Turns out they make something called a CAN bus shield. It plugs directly into the OBDII sensor in your car, and gives you every bit of info you need INCLUDING the rpms. I'll just use that!

nastyninjabear:
Ok, disregard this entire post :slight_smile:

Turns out they make something called a CAN bus shield. It plugs directly into the OBDII sensor in your car, and gives you every bit of info you need INCLUDING the rpms. I'll just use that!

I was about to tell you exactly that when you moved from a Motorcyle to a car - as long as you have a car newer than around 1998 (it varies by manufacturer and country) then it will have an ODB-II port.

Now some of the really newer cars have weird connectors but most cars are standard.

You will also find there is a nice clean 5v (and also typically 12v) output that can be sourced from this connector also.

Look up obduino and away you go

Craig

Thanx a ton! I'm going to probably need help with the coding but ill start a new thread when I get the Canbus shield.

nastyninjabear:
engine speed by color using an RGB LED. As the engine gets faster, the led fades to different colors.
Example:
800 rpm = Purple
1500 rpm = Blue
3000 rpm = Green
4000 = Yellow
5000 = Orange
6000 = Red

I want the colors to fade into each other smoothly.

anyone could help with the code ??
or give any tips how to do it ??

signal
1000RPM - 5,2V
7000RPM - 1V

gentlemen any suggestion
how to get started ??

nastyninjabear:
<...>
So instead of tapping into the coils, i can tap into the Tachometer signal wire where it meets the ECU.
<...>

Please do not do this...
2 reasons:

  • one, you could damage the ECU which has a large replacement/repair cost
  • same as above!

Seriously, messing with the ECU or a CAN bus directly can create circumstances that could cause the car to stall in traffic. Not good.

Honestly, the best way to do something like this is with an inductive pickup ... remember the 1960, 1970 Neon timing lights from K-Mart and others? I'm old, I remember. But it was just a small inductor with a winding. You can build your own using a small split-ferrite inductor with a few turns of wire... use a 5V Zener diode to condition the signal and a 1K to 10K series resistor to the Arduino digital input. Then take a look of some of the frequency code on the forum.

Ray

I thought you had CANBUS output that was going to give you digital info?
If you're sticking with analog voltages, then you can make a 'map' of RPM to PWM on 3 pins for the color you want.
Divide the RPMs by 100, so you have 10 to 70. Call it 0 to 70 even.
Make a table with 70 entries
0 RedValue GreenValue BlueValue
1 RedValue GreenValue BlueValue
2 RedValue GreenValue BlueValue
:
:
60 RedValue GreenValue BlueValue
70 RedValue GreenValue BlueValue

Fill in the values.
Now when you read an RPM in, you read out the PWM values and send them out.
analogWrite (redPin, rpmRedMap[value]);
analogWrite (bluePin, rpmBlueMap[value]);
analogWrite (greenPin, rpmGreenMap[value]);
You can do the same mapping for analog values, multiplying the number so its a whole number and using that for the table
52 RedValue GreenValue BlueValue
51 RedValue GreenValue BlueValue
50 RedValue GreenValue BlueValue
:
:
1 RedValue GreenValue BlueValue
0 RedValue GreenValue BlueValue

value = analogRead(rpmSensor); // yields 0 to 1023
value = value/20; // yields 0 to 51, corresponding to full RPM (0) to slowest (52)
analogWrite (redPin, voltageRedMap[value]);
analogWrite (bluePin, voltageBlueMap[value]);
analogWrite (greenPin, voltageGreenMap[value]);

So your code might look like:

// set up pin definitions
byte redPin = 3; // PWM pin
byte greenPin = 5; // PWM pin
byte bluePin = 6; // PWM pin
byte voltageRedMap [] = {
255,254,252, ...4,2,0,}; // these are the 51 or 52 value for red
byte voltageBlueMap [] = {
255,254,252, ...4,2,0,}; // these are the 51 or 52 value for blue
byte voltageGreenMap [] = {
255,254,252, ...4,2,0,}; // these are the 51 or 52 value for green
int value;
void setup(){
pinMode (redPin, OUTPUT);
pinMode (bluePin, OUTPUT);
pinMode (greenPin, OUTPUT);
//  nothing needed for analog input
}
void loop(){
value = analogRead(A0); // yields 0 to 1023
value = value/20; // yields 0 to 51, corresponding to full RPM (0) to slowest (52)
analogWrite (redPin, voltageRedMap[value]);
analogWrite (bluePin, voltageBlueMap[value]);
analogWrite (greenPin, voltageGreenMap[value]);
delay(50); // pause so colors are only updated ~20 times a second
}

How you fill out the 3 arrays will determine the colors you get. You don't say where the voltage is coming from, hopefully you have protection in place to prevent it from exceeding 5.5V so it doesn't damage the analog input (assuming a 5V power level for the Arduino chip)