Hey guys. I'm working on making a fuel gauge for my motorcycle. I have the basic concept working and I've added some averaging so that the gauge isn't going nuts while you're going down the road. Here's the current code:
/*
*LED Fuel Gauge for Honda SuperHawk 16L Tank
*http://www.superhawkforum.com
*Code by Will Lyon 9/23/2015. Contact: will.lyon12584@gmail.com
*5V to fuel sensor Grn/Blk
*Fuel sensor Gry/Blk to Analog 0 with 10k resistor to GND
*220 ohm resistor to each led and GND
*/
const int sensorPin = A0; // the pin that the potentiometer is attached to
const int ledCount = 10; // the number of LEDs in the bar graph
const int numReadings = 30; // use this value to determine the size of the readings array
int ledPins[] = {
2, 3, 4, 5, 6, 7,8,9,10,11 }; // an array of pin numbers to which LEDs are attached
int readings[numReadings]; // the readings from teh fuel level gauge
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
void setup() {
for (int thisLed = 0; thisLed < ledCount; thisLed++) { // loop over the pin array and set them all to output:
pinMode(ledPins[thisLed], OUTPUT);
}
for (int thisReading = 0; thisReading < numReadings; // initialize all readings to zero
thisReading++) {
readings[thisReading] = 0;
}
}
void loop() {
total = total - readings[readIndex]; // subtract the last reading
readings[readIndex] = analogRead(sensorPin);// read from the sensor
total = total + readings[readIndex]; // add the reading to the total
readIndex = readIndex + 1; // advance to the next position in the array
if (readIndex >= numReadings) { // if we're at the end of the array
readIndex = 0; // wrap around to the beginning
}
average = total / numReadings; // calculate the average
delay(1000); // delay in between readings for stability
average = map(average, 580, 913, 0, ledCount); // map the result to a range from 0 to the number of LEDs:
// loop over the LED array:
for (int thisLed = 0; thisLed < ledCount; thisLed++) {
// if the array element's index is less than ledLevel,
// turn the pin for this element on:
if (thisLed == average-1) {
digitalWrite(ledPins[thisLed], HIGH);
}
// turn off all pins higher than the ledLevel:
else {
digitalWrite(ledPins[thisLed], LOW);
}
}
delay(100);
}
Now the problem I have is that when you first power it up (or turn the bike on) it takes about 5-10 seconds to gather enough readings to get the average high enough to get the gauge working. I tried implementing code that would read whether or not the neural light is on and only run the averaging if it was off and display real-time readings when it is on. The problem with this though is that when it switches from real-time to the average it starts at zero and works its way back up.
I'd like it to ideally use real readings for about 10 seconds after power up while at the same time accumulating readings for the average. Then after 10 seconds it would switch to using the average but it would have already accumulated enough readings to get the gauge to stay steady. Most cars do this - when in Park the gauge reads all over the place (if the car is moving and fuel is sloshing in the tank) but once you put it into gear the gauge implements some kind of smoothing or averaging, but it doesn't start from zero and then work its way up.
A member over on the Arduino forums suggested this:
Use millis() and a 'flag'.
When the flag = 0, use the initial value you get from wherever.
When millis() is > your startTime - add startTime = millis(); at the end of setup() - then make the flag = 1 and start using real numbers.
The only problem is I've got no idea how to implement that in my code. I've searched for examples using millis() but all I can find is basic timer and/or stopwatch code and I don't know how to modify/adapt that to work with my situation. Thanks in advance!