dc42:
Is it time to do X yet? If so, do X, and calculate and record when you need to do X again.
Is it time to do Y yet? If so, do Y, and calculate and record when you need to do Y again.
I'd suggest a small change to that. Rather than recording the time you need to do X again, record the time you did X. Deciding whether it's time to do Foo then consists of:
unsigned long currentMillis= millis();
if((currentMillis - lastFooMillis) > fooInterval)
{
lastFooMillis = currentMillis;
// do X ...
}
This way deals with timer overflow without any special logic. (Thanks to the many old hands here who have pointed this technique out.)
I am having a little problem with the RPM part.... When the engine stops the RPM is not returning to 0...The last value read by the RPM circuit is kept displayed.... I know that I have to do some sort of lcd.clear() command.. But the thing is that, I do not want the RPM part to me cleared fully.. I would like to display 0 when the engine is off..
I am posting the full code...
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 9, 8);
const int analoginput = 0;
const int tempPin = 1;
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; // Voltage refresh rate
long Vinterval = 300;
long RPMpreviousMillis = 0; // RPM refresh rate
long RPMinterval = 200;
long TemppreviousMillis = 0; // Temperature refresh rate
long Tempinterval = 200;
long printpreviousMillis = 0; // RPM refresh rate
long printinterval = 400;
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;
value = analogRead(analoginput); // read the value on analog input
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();
unsigned long printcurrentMillis = millis();
if(printcurrentMillis - printpreviousMillis > printinterval) {
printpreviousMillis = printcurrentMillis;
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(" ");
}
}
}
/*************************************************************/
/************** THIS PART IS FOR TEMPERATURE *****************/
/*************************************************************/
unsigned long TempcurrentMillis = millis();
if(TempcurrentMillis - TemppreviousMillis > Tempinterval) {
TemppreviousMillis = TempcurrentMillis;
float temp = analogRead(tempPin);
temp = temp * 0.48828125;
lcd.setCursor(0, 1);
lcd.print(temp, 0);
lcd.print((char)223);
lcd.print("C");
}
}
Now the problem is that I am unable to set the print interval time...
I am attaching the code where you can see that I have commented out the refresh rate code for the RPM print... If I use that code then your modification for the 0 is not working...
which does more or less the same thing? btw the timeout code I suggested relies on that piece of code being there, so that the line "--rpmTimeout;" only gets executed at intervals of RPMinterval. If it gets executed too often, the timeout will happen too quickly
So how will the set the time for the RPM printing refresh rate...??
Surely RPMinterval determines the RPM refresh rate? Unless you are doing something else with the calculated RPM as well as displaying it, you don't need to fetch the RPM more often than you display it.
Joy:
What does this mean 60000000UL...??
That's the constant sixty million, with a note to the compiler ("UL" suffix) that we want it treated as having type "unsigned long".
because now I am trying to work on the Speedometer code...
So i was going through the RPM code as it will me almost the same thing except the RPM is calculated in minuites and the Speed will be calculated in hours...
For the speedo, if you only want the speed rounded down to the nearest km/h, then I suggest you calculate it as (C * 3600UL)/t where C is the wheel circumference in mm and t is the interval between pulses in microseconds.
Joy:
Again there will be a mystery for me... how did you get 3600UL..??
The wheel is rotating at 1000000/t revs per second, where t is the pulse interval in microseconds. So the revs per hour are (60 * 60 * 1000000)/t. The distance travelled per hour is (60 * 60 * 1000000 * C)/t mm per hour. Dividing by 1000000 to convert mm to km gives (3600 * C)/t. We want the calculation done in unsigned long mode, hence the UL suffix.
I would declare 'kmph" as "volatile unsigned int" rather than "int".
You have declared a variable "speed" which is not used.
You will need to implement a timeout mechanism, similar to the one for RPM, to handle the speed dropping to zero.
If then hall sensor has an open-collector output (e.g. US1881), then unless you have an external pullup resistor for the Hall sensor, you will need to digitalWrite a high to that pin in setup() to enable the internal pullup resistor.
Joy:
Another question is
What is this part doing..??
if (interval > 2000)
Doing the calculation every 2000 microseconds...??
That was included in the ISR for the ignition sensor, to allow for possibly getting multiple pulses per ignition instead of just one. You shouldn't need it for the RPM sensor.
That was included in the ISR for the ignition sensor, to allow for possibly getting multiple pulses per ignition instead of just one. You shouldn't need it for the RPM sensor.
Shouldn't need this for RPM sensor or Hall Sensor...??
Some mistakes I found in my code...Please check them and correct them if I am wrong...
const float wheelCircumference = 2035; // wheel circumference in km
Does not have to be a float..
unsigned long now = micros();
I think millis will do the job as wheel revs will not be as high as the RPM
kmph = (wheelCircumference * 3600UL)/interval;
here 2035*3600 is a thirteen digits long, and my friend says UL can hold up to 10 digits...
So he suggested me this