I'm working on an arduino universal fuel gauge. I've gathered and mishmashed some code together from a lot of places. I am pretty happy with how it runs except for one issue. After running for an hour or so the display seems to freeze up. It needs a manual reset or to open a serial monitor window if its enabled in the code (i assume it resets when starting serial stream because it always starts at 1 in the serial stream) and seems to work again, for a while.
I researched this and found people were having issues with I2C with if when statements. Found that reinitializing the display keeps it going. It may be code, hardware, or a funky library issue, I'm not sure.
I'm using a nano soldered to the back of a 7 segment I2C Adafruit backpack, Its going to be a fuel gauge in a car eventually. It should work with anything with a fuel level sender. I haven't tested it yet.
In an attempt to fix the freezing I have moved matrix.begin into the same if statement that triggers at the end of a read cycle to print to the display to keep the display scrolling too fast. It seems to have solved the freezing issue. The old one that was "allowing" freezing is commented out up top. Problem is the display initializes at full brightness then very quickly dims the next line of code (It does this about every 2 seconds or so.) This flicker will drive me nuts.
A nice benefit of initializing the display after a read cycle means the fuel gauge doesn't display an incorrect value at startup because it has taken a cycle of reads.
Code probably isn't super clean, I'm still new to coding. I'm not sure if I did something stupid or what. Im not sure what to do to fix it, any ideas are appreciated. I'm using IDE 1.6.7
// Use link
// https://docs.google.com/spreadsheets/d/1U6xyKBzcwL-aZyKyFAhQMOxg_XEEtUO7daMy8ZZFt00/edit?usp=sharing
// to calculate voltage divider resistor. Watch for overloading the fuel sender, keep wattage as low as
// possible.
//use serial monitor (set debug to 1 below) to view a/d # for empty and full tank to calibrate fullAD # and emptyAD # below.
// set lowFuelLed to arduino output # for low fuel warning. Watch max load, use a npn transistor / mosfet to drive your
// drive led or light.
// set lowFuelLev to turn low fuel light on below __% (0 for off)
// set lowFuelBlink to blink display below __% (0 for off)
#include "Adafruit_LEDBackpack.h"
#include "Adafruit_GFX.h"
Adafruit_7segment matrix = Adafruit_7segment();
const int numReadings = 32; // # of smoothing readings, seems 32 is max
float cap = 17.9; // enter tank capacity _ _ . _ liters, gallons, unit of measure doesnt matter
int readings[numReadings]; // the readings from the analog input
int readIndex = 0; // the index of the current reading
int total = 0; // the running total
unsigned int average = 0; // the average
int inputPin = A1; // fuel level input pin
int emptyAD = 150; // A/D # for empty (set debug below to 1 to find a/d in serial monitor)
int fullAD = 800; // A/D # for full (set debug below to 1 to find a/d in serial monitor)
int AD = 0; // for serial monitor A/D display for E\|/F calibration
int lowFuel = 0; // for serial monitor low fuel light 1 / 0
const int lowFuelLed = 13; // output for low fuel light
int lowFuelLev = 200; // toggles low fuel led on/off & blink display (range is 0-1000)
int lowFuelBlink = 100; // blink display below this (range is 0-1000, eg. 200 = 20%)
int debug = 1; // 1 for serial output on, 0 for off (normally 0)
void setup()
{
// initialize serial communication with computer:
if (debug == 1)
{
Serial.begin(9600);
}
//matrix.begin(0x70);
//matrix.setBrightness(00);
// initialize all the readings to 0:
for (int thisReading = 0; thisReading < numReadings; thisReading++) {
readings[thisReading] = 0;
}
}
void loop()
{
total = total - readings[readIndex]; // subtract the last reading:
readings[readIndex] = analogRead(inputPin); // 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:
average = constrain(average, emptyAD, fullAD); // Constrains range to keep in range window
average = map(average, emptyAD, fullAD, 1, 1000); // map the result A/D to a 0 - 1000 set empty and full
if (debug == 1) // set int debug to 1 for serial monitor on, 0 for off
{
AD = analogRead(inputPin);
Serial.print("avg ");
Serial.print(average);
Serial.print("\t");
Serial.print("readindex ");
Serial.print(readIndex);
Serial.print("\t");
Serial.print("lowFuel ");
Serial.print(lowFuel);
Serial.print("\t");
Serial.print("A / D ");
Serial.print(AD);
Serial.println();
}
delay(100); // delay in between reads for stability and to keep display from bouncing too much
if (readIndex >= (numReadings - 1)) //at the end of a reading cycle
{ matrix.begin(0x70); // to help I2C not freeze up
matrix.setBrightness(00);
matrix.print ((average*cap)/1000); //display % * tank capacity
matrix.writeDisplay(); // request display to write
delay(3);
if (average <= lowFuelLev)
{ // if average fuel% is = or below _%
(lowFuel = 1); // turn on the low fuel LED
digitalWrite(lowFuelLed, HIGH); // turn on the low fuel warning LED on
}
if (average > lowFuelLev)
{
(lowFuel = 0);
digitalWrite(lowFuelLed, LOW); // turn the low fuel LED off
}
}
if (average <= lowFuelBlink) // blink display if < lowFuelBlink(another low fuel warnning)
{
matrix.blinkRate(03); // blink display
}
else
{
matrix.blinkRate(00); //revert back to not blinking display above LowFuelBlink %
}
}
Thanks for any ideas on how to fix it.