Go Down

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

Anguz

Hi
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:

  Serial.begin(9600);                 

  // 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   

      fuelval=0;

 } 

 if (switchstate2 == LOW) {           

      fuelval=28;

 }

 if (switchstate3 == LOW) {         

     fuelval=57;

 } 

if (switchstate4 == LOW) {         

     fuelval=85;

 } 

 if (switchstate5 == LOW) {         

    fuelval=113;

 }

 if (switchstate6 == LOW) {         

     fuelval=141;

 }

 if (switchstate7 == LOW) {       

      fuelval=170;

 }

 if (switchstate8 == LOW) {         

    fuelval=198;

 }

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

     fuelval=226;

 }

 if (switchstate10 == LOW) {         

     fuelval=255;

 }

{

  // WE START DOING THE AVERAGING HERE

  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

   Serial.println(present); 

   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
   Serial.println(present);
   analogWrite(fuel, average );

}

} //The end

wildbill

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

Anguz

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

DVDdoug

#3
Apr 21, 2017, 08:56 pm Last Edit: Apr 21, 2017, 09:00 pm by DVDdoug
Quote
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). 


P.S.   
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
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy