I am into making a multiple data monitoring system for my motorcycle.
I am using a 16x2 LCD to display all the data..
The data are as follows
1. Engine RPM
2. Engine Temperature
3. Battery Voltage
4. Speedometer
5. Odometer
6. 4 Trip meters
I am using this circuit to pickup capacitive pulses from the spark-plug of the engine and feeding it to the interrupt pin 2 of arduino to determine RPM. As mine is a single cylinder engine, so every spark means one rotation.
I will be using LM 35 to measure the Engine temperature..
Now the codes which I have is for Volt, RPM, and Odometer..
Code for Volt and RPM combined with millis
#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.begin(16,2);
lcd.setCursor(3, 0);
lcd.print("Royal");
lcd.setCursor(7, 1);
lcd.print("Enfield");
delay(3000);
lcd.clear();
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 * ((R1 + R2)/R2); //voltage to display
lcd.setCursor(0,0);
lcd.print(vin, 1); //Print float "vin" with 1 decimal
lcd.print("V ");
}
/****************THIS PART IS FOR RPM*************************/
unsigned long RPMcurrentMillis = millis();
if(RPMcurrentMillis - RPMpreviousMillis > RPMinterval) {
RPMpreviousMillis = RPMcurrentMillis;
noInterrupts();
unsigned long rpmToDisplay = rpm; // take a copy with interrupts disabled in case it changes
interrupts();
if (rpmToDisplay >= 1000)
{
lcd.setCursor(7, 0);
lcd.print("RPM");
lcd.print(rpmToDisplay/1000);
lcd.print(',');
lcd.print((char)(((rpmToDisplay/100) % 10) + '0'));
lcd.print((char)(((rpmToDisplay/10) % 10) + '0'));
lcd.print((char)((rpmToDisplay %10) + '0'));
}
else
{
lcd.setCursor(7, 0);
lcd.print("RPM");
lcd.print(rpmToDisplay);
lcd.print(" ");
}
}
}
The odometer code
#include <EEPROM.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 9, 8);
const int odometerPin = 3;
const int odometerInterrupt = 1;
const int odometerEepromLocation = 0; // address of the first of 4 bytes in which the total wheel revs is stored
const int powerPin = A0; // analog pin used to sense impending loss of power
const float wheelCircumference = 0.002035; // wheel circumference in km
const int minPowerOkReading = 700; // minimum reading on the power sense analog input that indicates good power
const int minPowerRestoredReading = 750; // minimum reading on the power sense analog input that indicates we have powered back up
volatile unsigned long wheelRevs; // total wheel revolutions counted, will overflow after 85 million km
unsigned long lastDisplayedMs = 0UL; // time when we last refreshed the display
void setup()
{
lcd.begin(16,2);
// Initialise wheel revs from value stored in EEPROM
wheelRevs = 0UL;
for (int i = odometerEepromLocation + 3; i >= odometerEepromLocation; --i)
{
wheelRevs <<= 8;
wheelRevs |= (unsigned long)EEPROM.read(i);
}
if (wheelRevs == 0xFFFFFFFFUL)
{
// must be the first time we have run
wheelRevs = 0UL;
}
// Set up the odometer sensor pin and interrupt
pinMode(odometerPin, INPUT);
attachInterrupt(odometerInterrupt, odometerIsr, FALLING);
}
void odometerIsr()
{
++wheelRevs;
}
void loop()
{
// Capture the wheel revs with interrupts disabled in case it changes while we read it
noInterrupts();
unsigned long savedWheelRevs = wheelRevs;
interrupts();
if (analogRead(powerPin) < minPowerOkReading)
{
// Looks like power is going down, so write wheel revs to EEPROM (takes 13.2ms to write 4 bytes)
for (int i = odometerEepromLocation; i < odometerEepromLocation + 4; ++i)
{
EEPROM.write(i, (unsigned char)savedWheelRevs);
savedWheelRevs >>= 8;
}
// wait until either we die or the power comes back up
while (analogRead(powerPin) < minPowerRestoredReading)
{
delay(200);
}
}
else
{
unsigned long now = millis();
if (now - lastDisplayedMs >= 200) // update display every 200ms
{
lastDisplayedMs = now;
float km = wheelCircumference * savedWheelRevs;
lcd.setCursor(0, 0);
lcd.print(km, 1);
lcd.print("Km");
}
delay(5); // repeat after 5ms so that we check for power down often enough
}
}