this is the most recent code i have been using
#include <HX711.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <AccelStepper.h>
// --- PIN ASSIGNMENTS ---
#define HX711_DT A0
#define HX711_SCK A2
#define STEP_PIN 13
#define DIR_PIN A3
#define EN_PIN 12
// --- KEYPAD CONFIG ---
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'}
};
byte rowPins[ROWS] = {11, 10, 9, 8};
byte colPins[COLS] = {7, 6, 5, 4};
// --- OBJECT INITIALIZATION ---
HX711 scale;
LiquidCrystal_I2C lcd(0x27, 16, 2);
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
AccelStepper auger(AccelStepper::DRIVER, STEP_PIN, DIR_PIN);
// --- GLOBAL VARIABLES ---
float targetWeight = 0;
String inputString = "";
float calibration_factor = 420.0;
void setup() {
Serial.begin(9600);
pinMode(EN_PIN, OUTPUT);
digitalWrite(EN_PIN, HIGH);
lcd.init();
lcd.backlight();
lcd.print("System Ready");
scale.begin(HX711_DT, HX711_SCK);
if (scale.wait_ready_timeout(1500)) {
scale.set_scale(calibration_factor);
scale.tare();
}
auger.setMaxSpeed(4000);
auger.setAcceleration(2000);
delay(1000);
lcd.clear();
}
void loop() {
char key = keypad.getKey();
if (key >= '0' && key <= '9') { inputString += key; targetWeight = inputString.toFloat(); }
else if (key == '*') { inputString += "."; }
else if (key == '#') { inputString = ""; targetWeight = 0; scale.tare(); }
else if (key == 'A' && targetWeight > 0) { runDispenser(); }
static unsigned long lastIdle = 0;
if (millis() - lastIdle > 400) {
lcd.setCursor(0, 0); lcd.print("Set: "); lcd.print(targetWeight, 1); lcd.print("g ");
lcd.setCursor(0, 1); lcd.print("Wt : "); if(scale.is_ready()) lcd.print(scale.get_units(1), 1); lcd.print("g ");
lastIdle = millis();
}
}
void runDispenser() {
lcd.clear();
digitalWrite(EN_PIN, LOW); // ENABLE MOTOR
float current = 0;
unsigned long lastLcdUpdate = 0;
unsigned long lastScaleRead = 0;
while (true) {
// 1. STABILIZED SCALE READING (Median-style average of 3)
if (millis() - lastScaleRead > 100) {
if (scale.is_ready()) {
current = scale.get_units(3);
}
lastScaleRead = millis();
}
float remaining = targetWeight - current;
// 2. STOP CONDITION
if (remaining <= 0.0) break;
// 3. ADAPTIVE SPEED (Fast, then Mid, then Trickle)
if (remaining > 5.0) {
auger.setSpeed(2000);
} else if (remaining > 1.0) {
auger.setSpeed(600);
} else {
auger.setSpeed(150);
}
auger.runSpeed();
// 4. LCD UPDATE
if (millis() - lastLcdUpdate > 400) {
lcd.setCursor(0, 0); lcd.print("POUR: "); lcd.print(current, 1); lcd.print("g ");
lastLcdUpdate = millis();
}
if (keypad.getKey() == 'B') break;
}
// --- SHUTDOWN & SETTLE ---
auger.setSpeed(0);
digitalWrite(EN_PIN, HIGH);
lcd.clear();
lcd.print("Finalizing...");
delay(1500); // Important for noise to die down
float final = scale.get_units(10);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("FINAL: "); lcd.print(final, 2);
lcd.setCursor(0,1);
lcd.print("DONE!");
delay(3000);
inputString = "";
lcd.clear();
}