#include <EEPROM.h>
#include <LiquidCrystal.h>
#include "HX711.h"
HX711 scale;
LiquidCrystal lcd(12, 11, 7, 6, 5, 4);
#define Offset_eeprom_Adress 100
#define calibratation_eeprom_Adress 200
const int LOADCELL_DOUT_PIN = 2;
const int LOADCELL_SCK_PIN = 3;
const int CMD_PIN = 9;
long offset = 1;
long mesure = 1;
long delay_time = 0;
long calibration_value = 1;
int buttons[] = {A1, A2, A0, 10};
enum {UP, DOWN, ENTER, BACK};
char* menu[] = {"1-TARGET", "2-CALIBRATION", "3-REST", "4-hen"};
int targetWeightTens = 0;
int targetWeightOnes = 0;
int targetWeightDecimals = 0;
int calibrationTens = 0;
int calibrationOnes = 0;
int calibrationDecimals = 0;
int currentAdjusting = 0;
bool inTargetWeightMenu = false;
bool inCalibrationMenu = false;
bool inMainMenu = true;
int menuIndex = 0;
float currentWeight = 0.0;
float target = 0.0;
int button_up_clicked = 0; // only perform action when button is clicked, and wait until another press
int button_select_clicked = 0; // same as above
int button_down_clicked = 0; // same as above
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
pinMode(CMD_PIN, OUTPUT);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale.set_gain(128); // Adjusted for typical gain for HX711
EEPROM.put(calibratation_eeprom_Adress, calibration_value);
EEPROM.put(Offset_eeprom_Adress, offset);
Serial.println("Tarring the scale ...wait please");
delay(1000);
offset = tare_scale();
Serial.println("Do you need a new calibration");
delay(5000);
if (read_from_serial() == "yes") {
Serial.println("Make 1 kg on the scale");
delay(1000);
calibration_value = read_calibration();
Serial.println("Scale calibrated");
delay(1000);
} else {
calibration_value = read_calibration();
}
for (int i = 0; i < 4; i++) pinMode(buttons[i], INPUT_PULLUP);
showHomeScreen();
}
void loop() {
double FFF = get_weight();
currentWeight = (float)FFF ; // قراءة الوزن الحالي
double GGG = targetWeightTens*10 + targetWeightOnes + targetWeightDecimals * 0.1 ;
target = (float)GGG ;
Serial.print(currentWeight);Serial.print("...."); Serial.println(target);
// showHomeScreen();
if (inMainMenu) {
showHomeScreen(); // Ensure the home screen is updated with the current weight
if (!digitalRead(buttons[ENTER])) {
inMainMenu = false;
showMainMenu();
delay(50);
}
} else {
if (!digitalRead(buttons[UP])&& (button_up_clicked == 0)) {
if (inTargetWeightMenu || inCalibrationMenu) {
adjustValues(true);
button_up_clicked == 1;
} else {
menuIndex = (menuIndex - 1 + 4) % 4;
button_up_clicked == 1;
updateDisplay();
}
delay(50);
} else if (!digitalRead(buttons[DOWN]) && (button_down_clicked == 0)) {
if (inTargetWeightMenu || inCalibrationMenu) {
adjustValues(false);
button_down_clicked == 1;
} else {
menuIndex = (menuIndex + 1) % 4;
button_down_clicked == 1;
updateDisplay();
}
delay(50);
} else if (!digitalRead(buttons[ENTER])) {
if (inTargetWeightMenu || inCalibrationMenu) {
currentAdjusting = (currentAdjusting + 1) % 3;
updateDisplay();
} else {
switch (menuIndex) {
case 0:
inTargetWeightMenu = true;
break;
case 1:
inCalibrationMenu = true;
break;
// Add other cases as needed
}
currentAdjusting = 0;
updateDisplay();
}
delay(50);
} else if (!digitalRead(buttons[BACK])) {
if (inTargetWeightMenu || inCalibrationMenu) {
inTargetWeightMenu = false;
inCalibrationMenu = false;
updateDisplay();
} else {
inMainMenu = true;
showHomeScreen();
}
delay(50);
}
}
}
void adjustValues(bool increase) {
int* value = inTargetWeightMenu ? (currentAdjusting == 0 ? &targetWeightTens : currentAdjusting == 1 ? &targetWeightOnes : &targetWeightDecimals) : (currentAdjusting == 0 ? &calibrationTens : currentAdjusting == 1 ? &calibrationOnes : &calibrationDecimals);
if (increase) {
(*value)++;
if (*value > 9) *value = 0;
} else {
(*value)--;
if (*value < 0) *value = 9;
}
updateDisplay();
}
void showHomeScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Weight:");
lcd.setCursor(8, 0);
lcd.print(currentWeight, 2);
lcd.setCursor(0, 1);
lcd.print("Target:");
lcd.setCursor(8, 1);
lcd.print(target);
delay(1);
}
void showMainMenu() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Main Menu: ");
lcd.setCursor(0, 1);
lcd.print(menu[menuIndex]);
}
void updateDisplay() {
lcd.clear();
if (inTargetWeightMenu) {
lcd.setCursor(0, 0);
lcd.print("Set Target Wt:");
lcd.setCursor(0, 1);
// Display the target weight with a blinking cursor over the adjusting value
lcd.print(targetWeightTens);
lcd.print(targetWeightOnes);
lcd.print(".");
lcd.print(targetWeightDecimals);
// Set the cursor to the adjusting value
if (currentAdjusting == 0) {
lcd.setCursor(0, 1);
} else if (currentAdjusting == 1) {
lcd.setCursor(1, 1);
} else {
lcd.setCursor(3, 1);
}
lcd.blink(); // Start blinking on the adjusting value
} else if (inCalibrationMenu) {
lcd.setCursor(0, 0);
lcd.print("Calibration:");
lcd.setCursor(0, 1);
// Similar logic for calibration menu
lcd.print(calibrationTens);
lcd.print(calibrationOnes);
lcd.print(".");
lcd.print(calibrationDecimals);
// Set the cursor to the adjusting value
if (currentAdjusting == 0) {
lcd.setCursor(0, 1);
} else if (currentAdjusting == 1) {
lcd.setCursor(1, 1);
} else {
lcd.setCursor(3, 1);
}
lcd.blink(); // Start blinking on the adjusting value
} else {
lcd.noBlink(); // Ensure to turn off blinking when not adjusting values
// Add logic for other menus as needed
showMainMenu();
}
}
//======================================================================================================
String read_from_serial() {
char incomingByte = 0;//int
String gh;
int ind;
while (Serial.available() > 0) {
incomingByte = Serial.read();
gh += (String)(incomingByte);
ind = 1;
}
return gh;
}
//======================================================================================================
long Calibrate_scale(long calibrated_weight) {
double reading = (double)get_mean_val(10) ;
double calibratation = reading / calibrated_weight;
EEPROM.put(calibratation_eeprom_Adress, calibratation);//write_offset_in_eeprom();//write_calibration_in_eeprom();
return calibratation;
}
//======================================================================================================
//======================================================================================================
long read_calibration() {
long calibration ;
EEPROM.get(calibratation_eeprom_Adress, calibration);//write_offset_in_eeprom();
return calibration;
}
//======================================================================================================
//======================================================================================================
double get_weight() {
double poid;
poid = (double)get_val(); //get_one_val_and_power_down()
poid = poid - (double)offset;
poid = poid / (double)calibration_value;
return poid;
}
//======================================================================================================
long get_val() {
delay(100);
long reading ;
if (scale.is_ready()) {
reading = scale.read();
}
else {
Serial.println("HX711 not found.");
}
return reading;
}
//======================================================================================================
long get_mean_val(int nbr) {
double moy = 0;
for (int j = 0; j < nbr; j++) {
moy = moy + (double)get_val(); //get_one_val_and_power_down()
}
moy = moy / nbr;
return moy;
}
//======================================================================================================
long tare_scale() {
long offset = get_mean_val(10) ;
EEPROM.put(Offset_eeprom_Adress, offset);//write_offset_in_eeprom();
return offset;
}
//======================================================================================================
//======================================================================================================
long Read_offset() {
long offset;
EEPROM.get(Offset_eeprom_Adress, offset);
return offset;
}
//======================================================================================================
//======================================================================================================
long get_one_val_and_power_down() {
long reading ;
digitalWrite(LOADCELL_SCK_PIN, LOW);
delayMicroseconds(100);
delay_time = millis();
while ((!scale.is_ready()))
{
delay_time = millis() - delay_time;
if (delay_time > 200) {
Serial.println("HX711 not found.");
}
else {
reading = scale.read();
digitalWrite(LOADCELL_SCK_PIN, HIGH);
delay_time = millis();
delay(1);
}
}
//delay_time= 0;
return reading;
}