I have made a water dispenser with three different modes for filling a glass, 2 different bottles.
The order is...
bottle
school bottle
glass
The sensor works fine when i press it the first time to change the mode to "bottle". But then it triggers twice and skips to "glass" instead of "School Bottle". Pls help me with this.
#include <HX711_ADC.h>
#include <LiquidCrystal_I2C.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif
LiquidCrystal_I2C lcd(0x27,16,2);
//pins:
const int HX711_dout = 4; //mcu > HX711 dout pin
const int HX711_sck = 5; //mcu > HX711 sck pin
int mode;
int x=2,y=0;
int touch;
float i;
//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
const int calVal_eepromAdress = 0;
unsigned long t = 0;
void setup() {
lcd.init();
lcd.backlight();
Serial.begin(57600); delay(10);
Serial.println();
Serial.println("Starting...");
lcd.print("Starting");
pinMode(7,INPUT);
pinMode(8,OUTPUT);
pinMode(9,OUTPUT);
pinMode(13,OUTPUT);
pinMode(12,OUTPUT);
digitalWrite(8,LOW);
LoadCell.begin();
LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
float calibrationValue; // calibration value (see example file "Calibration.ino")
calibrationValue = EEPROM.read(0); // uncomment this if you want to set the calibration value in the sketch
#if defined(ESP8266)|| defined(ESP32)
//EEPROM.begin(512); // uncomment this if you use ESP8266/ESP32 and want to fetch the calibration value from eeprom
#endif
//EEPROM.get(calVal_eepromAdress, calibrationValue); // uncomment this if you want to fetch the calibration value from eeprom
unsigned long stabilizingtime = 2000; // preciscion right after power-up can be improved by adding a few seconds of stabilizing time
boolean _tare = true; //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);
Serial.println("Startup is complete");
}
}
void loop() {
static boolean newDataReady = 0;
const int serialPrintInterval = 0; //increase value to slow down serial print activity
// check for new data/start next conversion:
if (LoadCell.update()) newDataReady = true;
// get smoothed value from the dataset:
if (newDataReady) {
if (millis() > t + serialPrintInterval) {
i = LoadCell.getData();
Serial.print("Load_cell output val: ");
Serial.println(i);
lcd.setCursor(0,1);
lcd.print(i);
newDataReady = 0;
t = millis();
}
}
// receive command from serial terminal, send 't' to initiate tare operation:
if (Serial.available() > 0) {
char inByte = Serial.read();
if (inByte == 't') LoadCell.tareNoDelay();
}
// check if last tare operation is complete:
if (LoadCell.getTareStatus() == true) {
Serial.println("Tare complete");
}
touch=digitalRead(7);
Serial.println(touch);
if (touch==HIGH&&x==1){
Serial.println("glass");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Glass");
lcd.setCursor(0,1);
lcd.print(i);
x=2;
y=1;
}
else if (touch==HIGH&&x==2){
Serial.println("bottle");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Bottle");
lcd.setCursor(0,1);
lcd.print(i);
x=3;
y=2;
}
else if (touch==HIGH&&x==3){
Serial.println("School Bottle");
lcd.clear();
lcd.setCursor(0,0);
lcd.print("School Bottle");
lcd.setCursor(0,1);
lcd.print(i);
x=1;
y=0;
}
if (x==3){
if (i>436&&i<2476){
digitalWrite(8,HIGH);
}
else {
digitalWrite(8,LOW);
}
}
if (x==2){
if (i>237&i<906){
digitalWrite(8,HIGH);
}
else {
digitalWrite(8,LOW);
}
}
if (x==1){
if (i>383&i<2580){
digitalWrite(8,HIGH);
}
else {
digitalWrite(8,LOW);
}
}
if (y==1){
y=0;
motordown();
delay(600);
motorstop();
}
if (y==2){
y=0;
motorup();
delay(600);
motorstop();
}
}
void motorup(){
digitalWrite(12,HIGH);
digitalWrite(13,LOW);
}
void motordown(){
digitalWrite(13,HIGH);
digitalWrite(12,LOW);
}
void motorstop(){
digitalWrite(13,LOW);
digitalWrite(12,LOW);
}
Thanks for the clean up, it's very helpful. It's very likely that the problem you mention is because you have no state change detection on the sensor input. In other words, detecting when it becomes HIGH, not when it only is HIGH. You can do that by storing its value and seeing if the current value has changed.
Did you mean
static boolean newDataReady = false;
Boolean variables really don't have integer values. It's only an implementation detail that false happens to be 0.
Why did you declare it as a static local variable instead of a global? Is this your own code?
Any progress from your research on State Change Detection?
Also you need to re-examine your entire code base to ensure it complies with proper C usage. Here you have used bitwise 'and' instead of boolean 'and':
if (weight > 383 & weight < 2580) {
There may be more... try:
if (weight > 383 and weight < 2580) {
Why do you name only two pins out of about 8 that you use?
One of the problems I showed you is a critical error. It can't work that way. So unless you fix that, I'm not willing to help you any further. If you're really confident that you know where the problem is, you can fix it.
If you have made any changes to your code, please post it again.
Also, any progress from your research on State Change Detection?