Make hour counter to count running hours engine

Hi everybody,

I would like to make a hour counter for my motorcylce engine.

So when my engine is running an input is made high en while this input is high counting has te be done.
How the time is displayed doesn't mather for the moment. I think i will use serial for now.

I would like to use the millis() function or time lib...

So afger 24hourd are passee counting has to continue till 999hour

I also woul like to display hours in following form: for example nine and a half hours become 9.5 hours

I'm programming for just 2 month and anderstand all common basics but time, delay, millis() and so on is a problem for me so does anyone has some kind of hints, sketches for me to start?

Best regards

Jazzy gerard

The one big thing to avoid is storing the time as a millis value, as this will quickly get very large and overflow and essentially go back to 0 or a large negative number depending on the data type used. To avoid this, use one counter that counts millis up to 0.1 hours, then reset that counter and increment an hour counter by 0.1.

I don't know if you have thought about how you are going to sense the motor run time yet or not, but I would recommend an accelerometer. Even if you are sitting still the motor should easily vibrate enough to detect. The only times it would be wrong is if you regularly cruse with the motor off or take a lot of ferry rides. You may also be able to put the Arduino into a sleep mode when no vibration is detected to save your battery.

Then again, if you can power the Arduino with power that is only on when the ignition is, then you only need to make a program that counts when it has power and saves the data regularly in case it looses power.

The one big thing to avoid is storing the time as a millis value

A 32 bit unsigned integer counting milliseconds takes 49 days to overflow.
A 64 bit unsigned integer counting milliseconds takes 561 million years to overflow.

jroorda:
The one big thing to avoid is storing the time as a millis value, as this will quickly get very large and overflow and essentially go back to 0 or a large negative number depending on the data type used. To avoid this, use one counter that counts millis up to 0.1 hours, then reset that counter and increment an hour counter by 0.1.

I don't know if you have thought about how you are going to sense the motor run time yet or not, but I would recommend an accelerometer. Even if you are sitting still the motor should easily vibrate enough to detect. The only times it would be wrong is if you regularly cruse with the motor off or take a lot of ferry rides. You may also be able to put the Arduino into a sleep mode when no vibration is detected to save your battery.

Then again, if you can power the Arduino with power that is only on when the ignition is, then you only need to make a program that counts when it has power and saves the data regularly in case it looses power.

Great idea about counting in steps from 0.1hour. Did not tought about that!
I use a delay(1) in my sketch so i can make a counter which count til 6 min and then increase an other counter till 10 for every hour and so on and so on!

About the signal to see when my engine runs. I figured that out already. My engine produces 12v when running with some small dc concersion and a voltage divider a can put in on a ditital input.

Now to store the data while power is off i just saw something about an arduino rtc module with real time clock and eeprom. I now nothing about this but think it can be usefull what you guys think?

Best regards

Jazzy g

jazzygerard:
How the time is displayed doesn't mather for the moment.

I also woul like to display hours in following form: for example nine and a half hours become 9.5 hours

Well that was a quick moment.

Now to store the data while power is off i just saw something about an arduino rtc module with real time clock and eeprom. I now nothing about this but think it can be usefull what you guys think?

The RTC isn't going to help you store the data while the device is off, that's what the EEPROM does. The RTC helps keep track of the date and the time of day. Whether that is usefull to you depends on if knowing the date/time is important in your project. It can also provide better accuracy than the Arduino's clock, but gives less precision.

The EEPROM is built right in to the Arduino. Don't write to it every millisecond or you will wear it out -- write to it every minute or so.

The delay(1) you mention will make your hour meter a bit inaccurate, because each loop through your code takes several microseconds that aren't "counted". Using code similar to the "Blink without delay" example will be more accurate. An RTC will be even more accurate, but in my option the accuracy of an RTC is probably not necessary in this case (unless you really want one of course :wink: ).

Arrch:

jazzygerard:
How the time is displayed doesn't mather for the moment.

I also woul like to display hours in following form: for example nine and a half hours become 9.5 hours

Well that was a quick moment.[/quote]

No i ment were it would be displayed on lcd, tft, 7seg .... :slight_smile:

tylernt:
The EEPROM is built right in to the Arduino. Don't write to it every millisecond or you will wear it out -- write to it every minute or so.

The delay(1) you mention will make your hour meter a bit inaccurate, because each loop through your code takes several microseconds that aren't "counted". Using code similar to the "Blink without delay" example will be more accurate. An RTC will be even more accurate, but in my option the accuracy of an RTC is probably not necessary in this case (unless you really want one of course :wink: ).

So what you are saying is that i dont need the extra module but just can write to the arduino's eeprom?

And what to you mean with" don't write to it every millisecond"?

Like you mentioned i dont need the accuracy from the rtc but i tought the module would be useful for
1 the rtc then i can implement date and time in my project
2 i have an eeprom to write my running hours to.

Best regards

Jazzy Gérard

jazzygerard:
So what you are saying is that i dont need the extra module but just can write to the arduino's eeprom?

That is correct. Your Arduino has 1,024 bytes of EEPROM inside of it, just waiting to be used.

And what to you mean with" don't write to it every millisecond"?

Each byte of EEPROM can only be written to about 100,000 times before it fails. Writing every millisecond would wear out a byte of EEPROM in 100 seconds. So, only write to it occasionally.

Like you mentioned i dont need the accuracy from the rtc but i tought the module would be useful for
1 the rtc then i can implement date and time in my project

Sure.

2 i have an eeprom to write my running hours to.

You don't need to use the RTC's EEPROM. You can, if you want to, but why bother? It's easier to just use the EEPROM already built into your Arduino.

Oke thanks tylernt,

And wich line of code do i need to write to my eeprom and use the stored value to continue counting after a power switch of?

Regards jazzy

jazzygerard:
And wich line of code do i need to write to my eeprom and use the stored value to continue counting after a power switch of?

Look at the EEPROM examples; they are extremely simple.

This page has read and write examples:

http://playground.arduino.cc/Code/EEPROMWriteAnything

AWOL:

The one big thing to avoid is storing the time as a millis value

A 32 bit unsigned integer counting milliseconds takes 49 days to overflow.
A 64 bit unsigned integer counting milliseconds takes 561 million years to overflow.

Alternatively, store the time as the number of seconds, in a 32-bit (unsigned long) variable. It will take ~136 years of running to overflow.

It's also quite easy to sense the impending loss of power and write to the EEPROM only when power is about to be lost. Power the Arduino from the +12V supply via a series diode and low value series resistor (e.g. 10 ohms), and add a large capacitor between the Arduino power input and ground. The capacitor will power the Arduino for several milliseconds when power is lost, giving you time to write to the EEPROM. To detect imminent loss of power, either make analogRead calls at regular intervals, or use the analog comparator to generate an interrupt.

jazzygerard:
About the signal to see when my engine runs. I figured that out already. My engine produces 12v when running with some small dc concersion and a voltage divider a can put in on a ditital input.

Be very careful with this, if you get any spike it will definately blow your digital input or the entire microcontroller.
Use optocouplers to keep the Arduino safe. maybe this helps you, it was where i learned some little tricks like using zener diodes to clearly detect when there is voltage and when there isnt.
http://forum.arduino.cc/index.php?topic=126646.msg1323154#msg1323154

Sergegsx:

jazzygerard:
About the signal to see when my engine runs. I figured that out already. My engine produces 12v when running with some small dc concersion and a voltage divider a can put in on a ditital input.

Be very careful with this, if you get any spike it will definately blow your digital input or the entire microcontroller.
Use optocouplers to keep the Arduino safe. maybe this helps you, it was where i learned some little tricks like using zener diodes to clearly detect when there is voltage and when there isnt.
Arduino digital input, 80Vdc - #29 by TomGeorge - General Electronics - Arduino Forum

Yes,

what you say is true. like you said i have to design a very safe module to convert these 12V without bringing ma arduino in danger.

tylernt:
This page has read and write examples:

Arduino Playground - HomePage

Hi again, i took a look to your link and found this the most interesting "simple" code to use.

2012-07-30, Thijs Elenbaas
Using the EEPROMex library, the code would simplify to the following:
#include <EEPROMex.h>

// ID of the settings block
#define CONFIG_VERSION "ls1"

// Tell it where to store your config data in EEPROM
#define memoryBase 32

bool ok = true;
int configAdress=0;

// Example settings structure
struct StoreStruct {
char version[4]; // This is for mere detection if they are your settings
int a, b; // The variables of your settings
char c;
long d;
float e[6];
} storage = {
CONFIG_VERSION,
220, 1884,
'c',
10000,
{4.5, 5.5, 7, 8.5, 10, 12}
};

void setup() {
EEPROM.setMemPool(memoryBase, EEPROMSizeUno); //Set memorypool base to 32, assume Arduino Uno board
configAdress = EEPROM.getAddress(sizeof(StoreStruct)); // Size of config object
ok = loadConfig();
}

void loop() {
// [...]
int i = storage.c - 'a';
// [...]
storage.c = 'a';
if (ok)
saveConfig();
// [...]
}

bool loadConfig() {
EEPROM.readBlock(configAdress, storage);
return (storage.version == CONFIG_VERSION);
}

void saveConfig() {
EEPROM.writeBlock(configAdress, storage);
}

now, i really cant read this code and the explanation from the commands used in this lib is quite minimal. I already made my hour counter with success. the hours are stored in a value "Counter 1" does anybody knows what i have to do to use this code example to write the value of my "counter 1" to my adruino's eeprom and use it for further hour counting after a power switch off?

for the people who are interested my hour counter is build op as followed:

//hour counter

if (millis() - lastup == 360000){
lastup = millis();
Counter_01 = Counter_01 + 0.1;
Serial.print("Running hours: ");
Serial.println(Counter_01);
}

thank everybody for all the help so far. if we can just finish this last part i would be so happy!!

best regards

Hi, sorry wakeup this post so late and sorry my bad english! But this post help-me very well and I will try collaborate. This is my code (dummy) but I think work.

#include "LiquidCrystal_I2C.h"
#include "EEPROM.h"

LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);

int ledPin = 13; //Ligado ao backgroudlight do LCD
unsigned long millis_guardado;
unsigned long millis_anterior_conta_hora = 0;
unsigned long millis_anterior_grava_hora = 0;
unsigned long millis_corrente;

int sessentaMinutos = 0;
int sessentaMinutosGuardado = 0;

const long IntervaloGravaEEPROM = 180000; //3 Minutos
const long IntervaloHora = 3600000; // Uma hora
int EnderecoEEPROM = 0;

void setup() {
  pinMode(ledPin, OUTPUT);
  digitalWrite(ledPin, HIGH);

  lcd.begin (16,2); 
  lcd.clear();
  
  while (!eeprom_is_ready());
  sessentaMinutosGuardado = eeprom_read_word((uint16_t*)EnderecoEEPROM)/256; 
  sessentaMinutos = sessentaMinutos + sessentaMinutosGuardado;
  
}

void loop() {
  millis_corrente = millis();
  while (!eeprom_is_ready());
  
  if (millis_corrente - millis_anterior_conta_hora > IntervaloHora){
    millis_anterior_conta_hora = millis_corrente;
    sessentaMinutos++;
  }
  if (millis_corrente - millis_anterior_grava_hora > IntervaloGravaEEPROM){
    millis_anterior_grava_hora = millis_corrente;
    sessentaMinutosGuardado = sessentaMinutos;
    eeprom_write_word((uint16_t*)EnderecoEEPROM, sessentaMinutosGuardado*256);    
  }
    
  lcd.setCursor(0,0);
  lcd.print("HORIMETRO"); 
  lcd.setCursor(10,0);
  lcd.print(sessentaMinutos); 
  
}

My great concern about this whole thread was the aspect of expensively re-inventing the wheel - again! :astonished: