Go Down

Topic: help in making engine digital RPM meter (Read 11 times) previous topic - next topic


I went through your code several times and then uploaded to the arduino ..The RPM was updating every 0.2 seconds but the voltage was being updated after a lot of time intervals..
I am still going through the code to understand properly and re edit it to solve the problem..

In the meantime I took a complicated way.. But it worked.. :)
I took the way of blink without delay.. :P

Code: [Select]
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 9, 8);
const int analoginput = 0;
float vout = 0.0;
int value = 0;
float R1 = 1000.0;    // !! resistance of R1 !!
float R2 = 470.0;     // !! resistance of R2 !!
float vin = 0.0;
const int ignitionPin = 2;
const int ignitionInterrupt = 0;
const unsigned int pulsesPerRev = 1;

long VpreviousMillis = 0;
long Vinterval = 1400;

long RPMpreviousMillis = 0;
long RPMinterval = 200;

unsigned long lastPulseTime = 0;
unsigned long rpm = 0;

void ignitionIsr()
  unsigned long now = micros();
  unsigned long interval = now - lastPulseTime;
  if (interval > 2000)
     rpm = 60000000UL/(interval * pulsesPerRev);
     lastPulseTime = now;

void setup()
  lcd.setCursor(3, 0);
  lcd.setCursor(7, 1);
  pinMode(analoginput, INPUT);
  pinMode(ignitionPin, INPUT);
  attachInterrupt(ignitionInterrupt, &ignitionIsr, FALLING);

void loop()
  /***************THIS PART IS FOR VOLTAGE*********************/
   unsigned long VcurrentMillis = millis();
   if(VcurrentMillis - VpreviousMillis > Vinterval) {
     VpreviousMillis = VcurrentMillis;
   // read the value on analog input
value = analogRead(analoginput);
vout= (value * 5.0)/1024.0;  //voltage coming out of the voltage divider
vin = vout / (R2/(R1+R2));  //voltage to display

lcd.print(vin, 1);   //Print float "vin" with 1 decimal

/****************THIS PART IS FOR RPM*************************/

    unsigned long RPMcurrentMillis = millis();
   if(RPMcurrentMillis - RPMpreviousMillis > RPMinterval) {
     RPMpreviousMillis = RPMcurrentMillis;
  unsigned long rpmToDisplay = rpm;  // take a copy with interrupts disabled in case it changes
  if (rpmToDisplay >= 1000)
    lcd.setCursor(6, 0);
    lcd.print((char)(((rpmToDisplay/100) % 10) + '0'));
    lcd.print((char)(((rpmToDisplay/10) % 10) + '0'));
    lcd.print((char)((rpmToDisplay %10) + '0'));
    lcd.print(" ");
    lcd.setCursor(6, 0);
    lcd.print("RPM ");
    lcd.print(" ");


In your earlier post, you said you wanted to update the voltage every 1.4 minutes, so that is what I coded. Your sketch updates the voltage every 1.4 seconds.

Your method of checking how long it is since you last did an update to see whether to do a new one is a good solution.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.


with your code the rpm was updating at 0.2 seconds but the voltage was taking more that 5 seconds to update... :(


Now I am adding and odometer to the code..

The challenge is to store the Km traveled when I shut of ignition and pull off the key or disconnect the vehicle battery..

I do not want to use the inbuilt atmega 328 EEPROM as I want to write to the EEPROM evere time there is a change in the Km, so I rather want to use an external EEPROM as it will much cheaper and save the Atmega's life....
Will that be a good idea or I can do something else..??


I suggest using the mcu's own EEPROM using one of the following schemes:

1. You are already monitoring the battery voltage, presumably after the ignition key. Therefore, if you power the Arduino via a diode and a large capacitor, you can detect when the ignition has been switched off some while before the Arduino loses power. You could detect the impending loss of power and write to EEPROM then, so that you only do 1 write to EEPROM each time the ignition is turned off (and only if the number of km has changed since last time).

2. You could write to the EEPROM every km but use a wear-levelling scheme so that you don't write to the same cell every time. This would allow you to do well over 10 million km before you approach the 100,000 cycle write/erase lifetime of the built-in eeprom.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Go Up