I'm fairly new to Arduino and know very little about electronics (I know a bit about coding though). This project is well beyond my skill level but I have attempted it nonetheless.
My 2003 Mitsubishi Mirage does not have a tachometer and I'm trying to make one using an Arduino Uno. I did some searching online and found some designs that looked feasible. I have attached a schematic (poorly drawn, and only shows one shift register, sorry). Basically the 12V signal from the engine runs through a voltage divider to pin 4 on the Arduino (the 100nF cap is apparently meant to absorb a voltage spike). The RPM value is then displayed on a strip of 24 LEDs (I've used 2 shift registers to handle this amount). The Arduino is powered by a cigarette lighter power supply that puts out 9V.
I wired up the whole circuit on a breadboard and to my surprise it worked perfectly, so I proceeded to solder it all together. However when pulling the pieces from the breadboard I noticed there was no common ground between the car battery and the Arduino, which I thought would be necessary.
Anyway, It's all been soldered together but it is behaving strangely. I only get a signal reading if I hold the signal cable from the engine (green wire in the schematic) in my hand, and with my other hand, touch the female pin header that the signal wire plugs into on the Arduino (pin 4). I thought it may be because there's no common ground, however if I connect one, I don't get any signal reading.
Obviously I've done something wrongly but as previously mentioned, this is well beyond my ken. I'm just wondering if it could be something simple I can fix, or whether I should abandon this project and come back to it once I've learned more about general electronics.
I haven't included the whole sketch, but below are the main parts. Any advice would be greatly appreciated. Thank you kindly. (apologies if I've left out any pertinent info)
const int SIGNAL_PIN = 4;
const int NUMBER_OF_CYLINDERS = 4;
const int LED_UPDATE_INTERVAL = 100;
//Last LED state update time in milliseconds, used to calculate the time from last update
unsigned long lastUpdateTime = 0;
// Amount of spark fires in a single interval
volatile int sparkFireCount = 0;
// RPM value from last update - Used to average the last 2 RPMs for smoother output
int lastRpmValue = 0;
void incrementRpmCount () {
sparkFireCount++;
}
void ConfigurePins()
{
pinMode(SIGNAL_PIN, INPUT);
attachInterrupt(1, incrementRpmCount, FALLING);
pinMode(LATCH_PIN, OUTPUT);
pinMode(DATA_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
for (int i = 0; i < 8; i++) pinMode(ledArray[i], OUTPUT);
}
void setup () {
ConfigurePins();
Serial.begin(9600);
TestTacho();
}
// 4 stroke engine fires every spark in 2 revolutions, so calculate at what degree interval
// sparks fires and divide 360 by it, to find the number of fires per rotation
const int FIRES_PER_REV = (360 / (720 / NUMBER_OF_CYLINDERS));
void loop() {
Main();
}
void Main()
{
if ((millis() - lastUpdateTime) > LED_UPDATE_INTERVAL) {
/* Multiply the amount the spark fires in 1 interval by number of intervals per second to find the amount in one second. Then multiply the
amount in 1 second by 60, to find the spark fires in 1 minute and divide result by the number of fires per revolution to find the rpm */
int currentRpm = (sparkFireCount * (1000 / LED_UPDATE_INTERVAL) * 60) / FIRES_PER_REV;
// average the current and last rpm for smoother results
int averagedRpm = (currentRpm + lastRpmValue) / 2;
Serial.println(averagedRpm);
UpdateTacho(averagedRpm);
sparkFireCount = 0;
lastUpdateTime = millis();
lastRpmValue = currentRpm;
}
}