Need help with programming logic

Greetings, Hope everyone is doing well.

I'm working on a project which is supposed to be basically a fuel quality checking device.
I'm attaching the code I'm using

//this code includes sending data to esp01 on serial and GPS readings
#include <HX711_ADC.h>
#include <EEPROM.h>
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

//pins:8386427
char *DeviceID = "Device1";
int RXPin = 2;
int TXPin = 3;
int GPSBaud = 9600;

const int HX711_dout = A4; //mcu > HX711 dout pin
const int HX711_sck = A5; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
TinyGPSPlus gps;
SoftwareSerial gpsSerial(RXPin, TXPin);

static boolean newDataReady = 0;
long t;

const int serialPrintInterval = 500; //increase value to slow down serial print activity
static unsigned long lastSerialTime;

float calibrationValue = 432.54;//436.01; // uncomment this if you want to set the calibration value in the sketch327.49
long TareOffset = 8398661;//9532802;//8344838//8344747//8345467//8345516

#include <LiquidCrystal.h>
LiquidCrystal lcd (10,9,8,7,6,5);

#define BtnA 4
#define BtnB A1
#define BtnC A2
#define BtnD A3

int page = 0;
int weight;
float f_weight;
float units;
float mass1;
float mass2;
float mass3;
float kgs;
float new_factor_Weight;
float new_weight2;
float previous_weight;
float new_weight;
float new_volume;
float previous_volume;

int petrol = 0;
int diesel = 0;

int A_ButtonState = 0;
int B_ButtonState = 0;
int C_ButtonState = 0;
int D_ButtonState = 0;

int last_A_ButtonState = 0;
int last_B_ButtonState = 0;
int last_C_ButtonState = 0;
int last_D_ButtonState = 0;

volatile boolean SwA = false;
volatile boolean SwB = false;
volatile boolean SwC = false;
volatile boolean SwD = false;

unsigned long previousMillis = 0;
const long interval = 60000;
unsigned long currentMillis;

unsigned long previousMillis1 = 0;
const long interval1 = 5000;
unsigned long currentMillis1;

int Long;
int Lat;

//-----------------------------------------

  void checkIf_A_ButtonIsPressed()
  {
    if (A_ButtonState != last_A_ButtonState) 
  {
    if (A_ButtonState == 0) 
    {
      SwA = true;
    }
    delay(50);
  }
   last_A_ButtonState = A_ButtonState;
  }

//---------------------------------------------
void checkIf_B_ButtonIsPressed()
{
  if (B_ButtonState != last_B_ButtonState) 
  {
    if (B_ButtonState == 0) 
    {
      SwB = true;
      
    }
    delay(50);
  }
   last_B_ButtonState = B_ButtonState;
}

//----------------------------------------------------

void checkIf_C_ButtonIsPressed()
{
   if (C_ButtonState != last_C_ButtonState) 
  {
    if (C_ButtonState == 0)
    {
      SwC = true;
      
    }
    delay(50);
  }
   last_C_ButtonState = C_ButtonState;
}

//----------------------------------------------------
void checkIf_D_ButtonIsPressed()
{
   if (D_ButtonState != last_D_ButtonState) 
  {
    if (D_ButtonState == 0)
    {
      SwD = true;
      
    }
    delay(50);
  }
   last_D_ButtonState = D_ButtonState;
}
//---------------------------------------------------------------------------------------------------------------------------------
void DisplayFuel()
{
  if (petrol == 1)
  {
    lcd.setCursor(19,3);
    lcd.print("P");
  }
  else if (diesel == 1)
  {
    lcd.setCursor(19,3);
    lcd.print("D");
  }
  else
  {
    lcd.setCursor(19,3);
    lcd.print("?");
  }
}
//---------------------------------------------------------------------------------------------------------------------------------
 void makeDecision()
{
  lcd.setCursor(0,1);
 if(petrol)
 {
  if(f_weight > 710 && f_weight < 775)
  {
    lcd.print("Good"); 
  }
  else
  {
    lcd.print("Bad");
  }
 }
  else if(diesel)
  {
    if(f_weight > 810 && f_weight < 880)
    {
      lcd.print("Good");
    }
    else
    {
      lcd.print("Bad");
    }
  }
 }
//---------------------------------------------------------------------------------------------------------------------------------
void checkFuelQuality()
{
   chkWeight();
   makeDecision();
 }
//---------------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------------------------------------------------------------------------------------------
void chkWeight()
{
  // check for new data/start next conversion:
  if (LoadCell.update()) newDataReady = true;

  // get smoothed value from the dataset:
  if (newDataReady) 
  {
     if (millis() - lastSerialTime >= serialPrintInterval)  
    {
     weight = LoadCell.getData();
     f_weight = weight;
     Serial.print("Load cell output value:");
     Serial.println(f_weight);
     newDataReady = 0;
     lastSerialTime = millis();
    }
   }
 }
//---------------------------------------------------------------------------------------------------------------------------------
void unit_factor()
{
  if(new_weight2 > 49)
  {
  units = 1000.0/new_weight2;
  Serial.print("Units division:");
  Serial.println(units);
  }
}
//---------------------------------------------------------------------------------------------------------------------------------
void setup() 
{
  Serial.begin(115200);
  LoadCell.begin();
  gpsSerial.begin(GPSBaud);
     
  long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
  boolean _tare = false; //set this to false if you don't want tare to be performed in the next step
  LoadCell.start(stabilizingtime, _tare);
  
  if (LoadCell.getTareTimeoutFlag())
  {
    Serial.println("Timeout, check MCU>HX711 wiring and pin designations");
    while (1);
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    LoadCell.setTareOffset(TareOffset);
    Serial.println("Startup is complete");
  }

  pinMode(4, INPUT_PULLUP);
  pinMode(A1, INPUT_PULLUP);
  pinMode(A2, INPUT_PULLUP);
  pinMode(A3, INPUT_PULLUP);
  
  lcd.begin(20,4);
  
  lcd.setCursor(5,0);
  lcd.print("Welcome to");
  lcd.setCursor(2,1);
  lcd.print("Ready Automotive");
  lcd.setCursor(0,3);
  lcd.print("Technology Solutions");
  
  delay(3000);
  lcd.clear(); 
}

void loop() 
{
 //while (gpsSerial.available() > 0)
 //{
// gps.encode(gpsSerial.read());
  //if (gps.location.isUpdated())
  //  {
      
  //    }  
// }

  drawMenu();
  A_ButtonState = digitalRead(BtnA);
  B_ButtonState = digitalRead(BtnB);
  C_ButtonState = digitalRead(BtnC);
  D_ButtonState = digitalRead(BtnD);

  checkIf_A_ButtonIsPressed();
  checkIf_B_ButtonIsPressed();
  checkIf_C_ButtonIsPressed();
  checkIf_D_ButtonIsPressed();
  
  if (SwA && page == 0)
  {
    SwA = false;
    if(petrol == 1 || diesel == 1)
    {
    page = 2;
    }
    else
    {
     page = 5;
    }
  }
  else if (SwA && page == 1) 
  {
    SwA = false;
    lcd.setCursor(0,3);
    lcd.print("Petrol Selected");
    delay(1000);
    page = 2;
    petrol = 1;
    diesel = 0;
   }
  else if (SwA && page == 2)
  {
    SwA = false;
    previous_volume = mass1;
    //previous_weight = f_weight;
    unit_factor();
    page = 3;
    
  }
  else if (SwA && page == 3)
  {
    SwA = false;
    page = 4;
  }

   if (SwB && page == 1)
  {
    SwB = false;
    lcd.setCursor(0,3);
    lcd.print("Diesel Selected");
    delay(1000);
    page = 2;
    diesel = 1;
    petrol = 0;
  }
  else if (SwB && page == 3)
  {
    SwB = false;
    page = 0;
    lcd.clear();
  }
  else if (SwB && page == 4)
  {
    SwB = false;
    page = 0;
    lcd.clear();
   }

  if (SwD && page == 0)
  {
    SwD = false;
    page = 1;
  }
  else if(SwD && page == 5)
  {
    SwD = false;
    page = 1;
  }
}

void drawMenu()
{
  delay(150);
  switch (page)
  {
    case 0:
     HomePage();
    break;

    case 1:
     lcd.clear();
     lcd.print("Select Fuel");
     lcd.setCursor(0,1);
     lcd.print("Press:");
     lcd.setCursor(0,2);
     lcd.print("A: Petrol  B: Diesel");
    break;

    case 2:
     lcd.clear();
     lcd.print("Please fill");
     lcd.setCursor(0,1);
     lcd.print("1000ml Fuel");
     lcd.setCursor(15,1);
     chkWeight();
     Serial.print("New total Weight:");
     Serial.println(weight);
     Serial.print("Previous weight:");
     Serial.println(previous_weight);
     new_weight2 = weight - previous_weight;
     Serial.print("New sample weight:");
     Serial.println(new_weight2);
     lcd.print(new_weight2);
     lcd.setCursor(0,2);
     lcd.print("Press A");
     lcd.setCursor(0,3);
     lcd.print("when done");
     DisplayFuel();
    break;

    case 3:
     lcd.clear();
     lcd.print("Fuel Quality is:");
     checkFuelQuality();
     lcd.setCursor(0,2);
     lcd.print("A -> Yes");
     lcd.setCursor(12,2);
     lcd.print("B -> NO");
     DisplayFuel();
    break;

    case 4:
     lcd.clear();
     lcd.print("Tank being filled");
     lcd.setCursor(0,1);
     lcd.print("Please wait...");
     lcd.setCursor(0,2);
     chkWeight();
     new_weight = weight - previous_weight;
     new_volume = new_weight * units;
     lcd.print(new_volume);
     lcd.setCursor(0,3);
     lcd.print("Press B to exit");
     DisplayFuel();
    break;

    case 5:
     lcd.clear();
     lcd.print("Please Select Fuel");
     lcd.setCursor(0,1);
     lcd.print("Press D");
     lcd.setCursor(0,2);
     lcd.print("to select Fuel");
    break;
  }
}

void HomePage()
{
  delay(500);
  Serial.println();
  Serial.println();
  Serial.println("*HOME PAGE*");
  
  chkWeight();
  Serial.print("Previous Weight:");
  Serial.println(previous_weight);

  Serial.print("Current Weight:");
  Serial.println(f_weight);
  if (f_weight != previous_weight)//current weight is not equal to previous weight
  {
  mass2 = f_weight - previous_weight;
  Serial.print("New Weight:");
  Serial.println(mass2);
  }
  Serial.print("Unit factor being used:");
  Serial.println(units);
  mass3 = mass2 * units;
  Serial.print("New Volume:");
  Serial.println(mass3);
  
  Serial.print("previous Volume:");
  Serial.println(previous_volume);
  mass1 = previous_volume + mass3;
  Serial.print("Total Volume:");
  Serial.println(mass1);

  previous_weight = f_weight;

  lcd.setCursor(3,1);
  lcd.print("Fuel Quantity:");
  lcd.setCursor(5,2);
  if(mass1 >= 1000)
  {
   kgs = mass1/1000.0;
   lcd.print(kgs);
   lcd.print("Ltrs");
   Send_to_ESP(kgs);
  }
  else
  {
    lcd.print(mass1);
    lcd.print("Ltrs");
    Send_to_ESP(mass1);
  }
  Serial.print("final volume");
  Serial.println(mass1);
  Serial.println();
  //if (previous_weight != mass2)
  //{
  
}
//-------------------------------------------------------------------------------------------------------------------------------------------

void Send_to_ESP(float Weight)
{
      chkWeight();
      Serial.print("<");
      //Serial.print(DeviceID);
      //Serial.print(",");
      Serial.print(gps.location.lat(), 6);
      Serial.print(","); 
      Serial.print(gps.location.lng(), 6);
      Serial.print(",");
      Serial.print(Weight);
      Serial.print(",");
      Serial.print(f_weight);
      Serial.print(",");
      Serial.print(new_weight2);
      Serial.println(">");
}

The code is messy but it works for most of the parts but only with two issues which I'm not able to fix.

  1. Whenever I gradually reduce the weight from loadcell the relevant reduction is not displayed on the screen.
  2. After a lil while the system output gets messed up on its own even though I do not change any weight on load cell

The issue #1 is becoz of the line

if (f_weight != previous_weight)//current weight is not equal to previous weight
  {
  mass2 = f_weight - previous_weight;
  Serial.print("New Weight:");
  Serial.println(mass2);
  }

in the function homepage() but if I remove that if loop my mass2 value becomes 0 and no matter what I put on load cell it gives me zero output.

Any help is much appreciated

Thanks in advance

if (f_weight != previous_weight)//current weight is not equal to previous weight
{
mass2 = f_weight - previous_weight;
Serial.print("New Weight:");
Serial.println(mass2);
}
This portion of code displays the change in weight. If you want to display the new weight then print f_weight instead of, or as well as, mass2

Thanks for your reply UKHeliBob and thanks for joining here

What I see on the serial monitor is really not that important, but okay I can make f_weight to appear on the serial monitor as well. But still my issue remains unsolved.

Your potential helpers should not be forced to go through your code line by line to understand what the program and the device does.

You should post a detailed description of what the devices purpose is.

And you should post a detailed description what the device should do and what you can watch what is happening instead.

best regards Stefan

I'm not sure if its a technically fit thing to implement but it sounds lil crazy. I'll try to explain the expected working with an example:

but first lets see how the system is supposed to work:

  1. The system shows total fuel volume in liters on the home page.

  2. Then the user selects the type of fuel: Petrol or Diesel

  3. After the fuel type is selected the system asks user to fill 100ml of selected fuel.

  4. once the 1000ml fuel is filled the system calculates what we can call it as volume by dividing the 1000 by the weight of 1000ml fuel. lets call the output of this division as Unit1

  5. As the user proceed to next step, the system checks the quality of fuel from the Unit1 value as shows user if the fuel he's about to fill is good or bad and asks user if he wants to proceed to fill the fuel or not.

  6. If user prefers to fill the fuel, the system asks to fill the fuel.

  7. Once the user fills the fuel, the system multiplies the weight of the newly filled fuel with the unit1 value and shows it on the home page. Lets call this as volume1

  8. Lets say that now user gets to another fuel station and reinitiates the entire process again, The system asks to fill 1000ml fuel again, once the 1000ml fuel is poured the system divides 1000 by its weight and the result of this division is now Unit2

  9. System checks the quality of fuel and asks the user if he wants to proceed with the tank filling or not, user selects to fill the tank.

  10. Now, the system multiplies the weight of incoming fuel (just the weight of the fuel that is being newly filled excluding the previous one) with Unit2 this time and not with unit1

  11. lets call the result of this multiplication as volume2. Now on the display the system should show total value of fuel as Volume1 + Volume2

and the process repeats. each time a fuel is filled a new unit factor is calculated, the newly filled fuel weight is multiplied by new unit factor the result is added into previous result and is shown on the screen.
To sum it up in formulation we can state it as follows:

For example,
Iteration 1:
weight of 1000ml fuel: 200gms (just an example for showing)
Unit factor: 1000/weight of 1000ml fuel in this case it would be 1000/200 = 5
Weight of the fuel filled in tank: 800 gms (for example)
Volume showed on screen: Unit factor X weight of the fuel filled in tank including the 1000ml fuel we filled for calculating the unit factor so it gives us:
800 X 5 = 4000 ml i.e 4 ltrs

Iteration 2:
as soon as the iteration 2 begins we store the previous values as follows:
previous weight: 800 gms
previous volume: 4000

New weight of 1000ml fuel: 500gms (again just for an example)
New unit factor: 1000/500 = 2
New weight of fuel filled in tank: 900
New volume: 900 X 2 = 1800

Total volume displayed on screen: Previous Volume + new Volume = 4000 + 1800 = 5800 ml i.e. 5.8 Ltrs

  1. The problem is when we start reducing the fuel, after a certain point the total volume doesn't reduce even if the total fuel content of the tank reduces to zero.

  2. The above procedure is executed correctly only upto three iterations then the calculations get messed up

hm ..... have to re-read this several times noticing numbers on my own trying to understand what is going on. Needs some time later.....

best regards Stefan

1 Like