Go Down

Topic: car fuel gauge (Read 248 times) previous topic - next topic


i have a fuel gauge that due to the fact the tank is foam filled cannot be a normal 'arm'/resistance type
i have an internal magnetic float that slides up and down a stainless tube with reed switches inside
this was built a few years ago and seems reliable- there are however dead spots between the switches
my friend programmed the arduino side for me
i have since become interested in programming and have slowed the response of the program down, to make it more stable under harsh cornering

how can i make either the delay, or the number of values i average over variable?
 until i hit a bump in the car or corner, and the float moves, its some time before i get a fuel reading.
what i need it to do is speed up the response till it has seen one of the inputs, then drop back to the slower rate


  When a switch goes momentarily low it sets the level sent to a fuel gauge

  0 - 5 volts is the output    0 = empty   5v = full

 ///////////////// Version 3 reads the data into an array and averages the output over a number of readings.

 David Whitty / David Rose. December 2012.


// constants don't change. They're used here to set pin numbers:

const int switch1 = 2;     // Digital pin number of the switch.

const int switch2 = 3;     // 11 switches

const int switch3 = 4;     

const int switch4 = 5;     

const int switch5 = 6;   

const int switch6 = 7;     

const int switch7 = 8;     

const int switch8 = 10; 

const int switch9 = 11;     

const int switch10 = 12;       

int fuel = 9;    // output to meter on pin 9

int fuelval; // 0 - 255. Empty or full.

int switchstate1 = 0; //state of the switches low or high

int switchstate2 = 0;

int switchstate3 = 0;

int switchstate4;

int switchstate5;

int switchstate6;

int switchstate7;

int switchstate8;

int switchstate9;

int switchstate10;

const int numReadings = 250;  //How many readings do we take before averaging

int readings[numReadings];      // the readings from the analog input

int index = 0;                  // the index of the current reading

int total = 0;                  // the running total

int average = 0;                // the average

int present = 0;               // the present reading before averaging

void setup() {


 // pinMode(fuel, OUTPUT);   // initialize the fuel level on pin 9 as output

   pinMode(switch1, INPUT);  // initialize the switches pin as an input:

    pinMode(switch2, INPUT);

     pinMode(switch3, INPUT);

      pinMode(switch4, INPUT);

       pinMode(switch5, INPUT);

        pinMode(switch6, INPUT);

         pinMode(switch7, INPUT);

          pinMode(switch8, INPUT);

           pinMode(switch9, INPUT);   

           pinMode(switch10, INPUT);

        //    pinMode(switch11, INPUT); 


//analogWrite(fuel, 255);//Test the meter I DON'T THINK WE WANT TO DO THIS ON A DIGITAL METER

//delay (3000);                            //IT WILL ONLY LOOK CONFUSING

//analogWrite(fuel, 0);

 // initialize serial communication with computer:


  // initialize all the readings to 0:

  for (int thisReading = 0; thisReading < numReadings; thisReading++)

    readings[thisReading] = 0;         


void loop(){ 

   switchstate1 = digitalRead(switch1);//read the switches

   switchstate2 = digitalRead(switch2);

    switchstate3 = digitalRead(switch3);

     switchstate4 = digitalRead(switch4);

      switchstate5 = digitalRead(switch5);

      switchstate6 = digitalRead(switch6);

       switchstate7 = digitalRead(switch7);

        switchstate8 = digitalRead(switch8);

         switchstate9 = digitalRead(switch9);

          switchstate10 = digitalRead(switch10);


       About the levels. For a digital readout set the output levels to the nearest half a volt

       0 - 255 for 10 switches 255/10 = 25.5 between levels so....

       25 = 0.5v . 51 = 1v . 76 = 1.5v . 102 = 2v . 126 = 2.5v . 153 = 3v . 178 = 3.5v . 204 = 4v . 230 = 4.5v . 255 = 5v


  if (switchstate1 == LOW) {     //switch makes contact which sets fuel level   



 if (switchstate2 == LOW) {           



 if (switchstate3 == LOW) {         



if (switchstate4 == LOW) {         



 if (switchstate5 == LOW) {         



 if (switchstate6 == LOW) {         



 if (switchstate7 == LOW) {       



 if (switchstate8 == LOW) {         



 if (switchstate9 == LOW) {       //Jumps from 4 to 5v here as we must use one of the steps for zero



 if (switchstate10 == LOW) {         





  total= total - readings[index];   // subtract the last reading:

readings[index] = fuelval;    // read the value 

  present = fuelval;


  total= total + readings[index];      // add the reading to the total:


  index = index + 1;          // advance to the next position in the array         

  if (index >= numReadings)     // if we're at the end of the array...         


    index = 0;       // ...wrap around to the beginning:                   

  average = total / numReadings;         // calculate the average:


  Serial.println(average);  // send it to the computer as ASCII digits


   analogWrite(fuel, average );

  delay(1000);        // delay in between reads for stability           
average = total / numReadings;         // calculate the average:
  Serial.print("Average Value= ");        //Title line
  Serial.println(average);  // send it to the computer as ASCII digits
   Serial.print("Present Value= ");        //Tile line
   analogWrite(fuel, average );


} //The end


Set fuelval to an invalid value (-1 perhaps) before you test the switchStates.

If it's still invalid when all the switches are checked, don't do the averaging. That'll avoid the delay & you will immediately go back and try again


but it does not always see a switch sometimes all inputs are high... surely that wont work ?


Apr 21, 2017, 08:56 pm Last Edit: Apr 21, 2017, 09:00 pm by DVDdoug
how can i make either the delay, or the number of values i average over variable?
You probably don't need a variable, but you can change the values.

numReadings is 250 and that should be plenty.

Code: [Select]

delay(1000);        // delay in between reads for stability 

1000 millseconds is 1 second.   If I'm reading the code correctly (and I haven't studied it carefully) it looks like you are reading once per second and updating the display once per second.    It's probably OK to read once per second, but there's no need to update the fuel reading that frequently.   
A MUCH longer delay may improve the results.   

Maybe change the delay to one minute (60000 milliseconds). 

Actually, if you do that you'll need to reduce the number of readings...  You'd need 250 minutes for the readings to "stabilize" and that would be useless.   So, maybe a compromise of fewer readings in the average and a longer delay.   Or, change-around the code to take 250 readings before taking an average and updating the display.


Go Up