Good day all,
Going to start this off with the classic "I am new to Arduino", so there is still a lot to learn for me. To thus far I've managed to correct a lot of errors by working through numerous threads on this forum as well as others but I am currently baffled.
I am busy building a milligram scale with the end goal of measuring to 0.005g reliably. For the interface I am using a Nextion display to display the current weight rating. Once the unit is powered on the scale calibrates itself with a predefined calibration value and then tares the scale to zero. See below for the circuit construction.
I have also added a TARE button to the interface to manually zero the scale when required. The problem I am having is as CODE 1 is currently written, the TARE button only works when the button is pressed between the loop iterations, requiring me to continuously press the button until the timing is correct and it finally registers and zeros the scale. Am I correct in my statement about the press event only registering between loops?
CODE 1:
Below is the code I am currently using where the button must be pressed repeatedly until it finally registers:
// LIBRARIES REQUIRED:
#include <HX711_ADC.h> //INCLUDE HX711_ADC LIBRARY FOR LOAD CELL
#include <EEPROM.h> //INCLUDE EEPROM LIBRARY TO STORE DATA TO EEPROM
#include <Nextion.h> //INCLUDE NEXTION LIBRARY TO WRITE DATA FROM ARDUINO > NEXTON
// PINS TO BE USED:
const int HX711_dout = 3; //UNO > HX711 DATA PIN
const int HX711_sck = 2; //UNO > HX711 CLK PIN
bool _tare = false;
//DEFINE OBJECTS TO BE USED ON NEXTION SCREEN
NexText textNumber = NexText(0,2,"textNumber"); // NexText(page number, object number, "object name")
NexButton buttonTare = NexButton(0,1,"buttonTare");
char buffer[10] = {0}; //CREATES A BUFFER TO HOLD THE TEXT
//REGISTER OBJECTS FOR NEXTION DISPLAY
NexTouch *nex_listen_list[] =
{
&textNumber,
&buttonTare,
NULL
};
//HX711 CONSTRUCTOR:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
const int calVal_eepromAdress = 0;
unsigned long t = 0;
void buttonTarePushCallback(void *ptr){
LoadCell.tareNoDelay();
}//END OF TARE BUTTON FUNCTION
void setup() {
nexInit();
Serial.begin(9600);
delay(10);
LoadCell.begin();
float calibrationValue; // calibration value (see example file "Calibration.ino")
calibrationValue = 6533.93; // 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); // set calibration value (float)
//Serial.println("Startup is complete");
}
buttonTare.attachPush(buttonTarePushCallback);
} //END SETUP
void loop() {
nexLoop(nex_listen_list);
static boolean newDataReady = 0;
const int serialPrintInterval = 0; //INCREASE VALUE TO REDUCE SCREEN PRINT INTERVALS
// check for new data/start next conversion:
if (LoadCell.update()) newDataReady = true;
// get smoothed value from the dataset:
if (newDataReady) {
if (millis() > t + serialPrintInterval) {
float i = LoadCell.getData();
float i_rounded =((round(i*200)+0.005)/200); //ROUNDS VALUE TO NEAREST 0.005
//Serial.print("Load_cell output val: "); // FOR DEBUGGING, IF USED COMMENT OUT textNumber.setText(buffer)
//Serial.println(i_rounded); // FOR DEBUGGING, IF USED COMMENT OUT textNumber.setText(buffer)
newDataReady = 0;
t = millis();
memset(buffer,i_rounded , sizeof(buffer)); //CLEARS BUFFER
dtostrf(i_rounded, 8, 3, buffer); // ALLOWS FOR DECIMAL VALUES TO BE DISPLAYED ON THE NEXTION dtostrf(variable, ???, number decimals, buffer)
textNumber.setText(buffer);
} //END IF (MILLIS()....)
} //END IF (NEWDATAREADY)
}// END LOOP
I would like to be able to press the TARE button at any time with the scale then zeroing and afterwards continuing with the readings. I've tried incorporating the buttonTarePushCallback into an IF statement in CODE 2 however this does not seem to do anything once the button is pushed. Any idea why the button is not zeroing the scale when pressed?
CODE 2:
The following code has the IF statement incorporated into the void loop():
// LIBRARIES REQUIRED:
#include <HX711_ADC.h> //INCLUDE HX711_ADC LIBRARY FOR LOAD CELL
#include <EEPROM.h> //INCLUDE EEPROM LIBRARY TO STORE DATA TO EEPROM
#include <Nextion.h> //INCLUDE NEXTION LIBRARY TO WRITE DATA FROM ARDUINO > NEXTON
// PINS TO BE USED:
const int HX711_dout = 4; //UNO > HX711 DATA PIN
const int HX711_sck = 5; //UNO > HX711 CLK PIN
bool _tare = false;
//DEFINE OBJECTS TO BE USED ON NEXTION SCREEN
NexText textNumber = NexText(0,2,"textNumber"); // NexText(page number, object number, "object name")
NexButton buttonTare = NexButton(0,1,"buttonTare");
char buffer[10] = {0}; //CREATES A BUFFER TO HOLD THE TEXT
//REGISTER OBJECTS FOR NEXTION DISPLAY
NexTouch *nex_listen_list[] =
{
&textNumber,
&buttonTare,
NULL
};
//HX711 CONSTRUCTOR:
HX711_ADC LoadCell(HX711_dout, HX711_sck);
const int calVal_eepromAdress = 0;
unsigned long t = 0;
void buttonTarePushCallback(void *ptr){
}//END OF TARE BUTTON FUNCTION
void setup() {
nexInit();
Serial.begin(9600);
delay(10);
LoadCell.begin();
float calibrationValue; // calibration value (see example file "Calibration.ino")
calibrationValue = 6533.93; // 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); // set calibration value (float)
//Serial.println("Startup is complete");
}
} //END SETUP
void loop() {
nexLoop(nex_listen_list);
if (buttonTarePushCallback){
LoadCell.tareNoDelay();
static boolean newDataReady = 0;
const int serialPrintInterval = 0; //INCREASE VALUE TO REDUCE SCREEN PRINT INTERVALS
// check for new data/start next conversion:
if (LoadCell.update()) newDataReady = true;
// get smoothed value from the dataset:
if (newDataReady) {
if (millis() > t + serialPrintInterval) {
float i = LoadCell.getData();
float i_rounded =((round(i*200)+0.005)/200); //ROUNDS VALUE TO NEAREST 0.005
//Serial.print("Load_cell output val: "); // FOR DEBUGGING, IF USED COMMENT OUT textNumber.setText(buffer)
//Serial.println(i_rounded); // FOR DEBUGGING, IF USED COMMENT OUT textNumber.setText(buffer)
newDataReady = 0;
t = millis();
memset(buffer,i_rounded , sizeof(buffer)); //CLEARS BUFFER
dtostrf(i_rounded, 8, 3, buffer); // ALLOWS FOR DECIMAL VALUES TO BE DISPLAYED ON THE NEXTION dtostrf(variable, ???, number decimals, buffer)
textNumber.setText(buffer);
}
} //END IF (MILLIS()....)
} //END IF (NEWDATAREADY)
}// END LOOP
*My code is a modified version of example "Read_1x_load_cell" within the HX711_ADC library.
Kind Regards,
Stefaans5111
