Load cell code without WiFi/MQTT works, same code with WiFi/MQTT unstable

Hello,

I have put together an D1 mini pro with HX711 and 4 load cells and when I run the code from HX711_ADC (Olav Kallhovd) the weight stabilize at 0 and I jump on the bed and the weight increases and drop when I exit it, it works for hours.

Then I used the code I found here GitHub - newAM/LoadCellOccupany: Home automation occupancy sensor using load cells and the weight start jump up and down many hundred kg so I thought it was something wrong with the weight code from newAM so I took out the WiFi and MQTT part and added it too HX711_ADC (Olav Kallhovd) code but the problem is the same...

This code the weight is stable and I can jump on the bed and get my weight, works for hours but doesn't output the weight to MQTT only on serial monitor.

/*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   Settling time (number of samples) and data filtering can be adjusted in the config.h file
   For calibration and storing the calibration value in eeprom, see example file "Calibration.ino"

   The update() function checks for new data and starts the next conversion. In order to acheive maximum effective
   sample rate, update() should be called at least as often as the HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS.
   If you have other time consuming code running (i.e. a graphical LCD), consider calling update() from an interrupt routine,
   see example file "Read_1x_load_cell_interrupt_driven.ino".

   This is an example sketch on how to use this library
*/

#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif

//pins:
const int HX711_dout = D0; //mcu > HX711 dout pin
const int HX711_sck = D2; //mcu > HX711 sck pin

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);

const int calVal_eepromAdress = 0;
unsigned long t = 0;

void setup() {
  Serial.begin(57600); delay(10);
  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  calibrationValue = -7818.58; // 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()) {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }
}

void loop() {
  static boolean newDataReady = 0;
  const int serialPrintInterval = 2000; //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) {
      float i = LoadCell.getData();
      
      Serial.print("Load_cell output val: ");
      Serial.println(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");
  }

}

Load_cell output val: -0.01
Load_cell output val: -0.03
Load_cell output val: -0.03
Load_cell output val: -0.07
Load_cell output val: -0.08
Load_cell output val: -0.04
Load_cell output val: -0.04
Load_cell output val: -0.11
Load_cell output val: -0.10
Load_cell output val: -0.09
Load_cell output val: -0.08

Same code as over but added WiFi and MQTT, weight unstable and can't be used for anything.

/*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   Settling time (number of samples) and data filtering can be adjusted in the config.h file
   For calibration and storing the calibration value in eeprom, see example file "Calibration.ino"

   The update() function checks for new data and starts the next conversion. In order to acheive maximum effective
   sample rate, update() should be called at least as often as the HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS.
   If you have other time consuming code running (i.e. a graphical LCD), consider calling update() from an interrupt routine,
   see example file "Read_1x_load_cell_interrupt_driven.ino".

   This is an example sketch on how to use this library
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <HX711_ADC.h>
#if defined(ESP8266) || defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif

//pins:
const int HX711_dout = D0;  //mcu > HX711 dout pin
const int HX711_sck = D2;   //mcu > HX711 sck pin

// connection settings
#define TIMEOUT 5000               // connection failure timeout in ms
#define MQTT_PORT 1883             // MQTT broker port
#define MQTT_CLIENT_ID "loadcell"  // device client ID

// Wifi settings
#define WIFI_CLIENT_ID "LOADCELL1"
#define SSID_NAME "IoT"           // SSID network wifi name to connect to
#define SSID_PASSWORD "12345678"  // Wifi password

// MQTT topics
#define TOPIC_BASE "loadcell/sensor/main-bedroom"  // base topic
#define TOPIC_LOAD TOPIC_BASE "/load"              // topic to publish samples on
#define TOPIC_TARE TOPIC_BASE "/tare"              // topic to receive tare commands on
#define MQTT_USER ""                               // MQTT username
#define MQTT_PASS ""                               // MQTT password
#define MQTT_HOST IPAddress(192, 168, 1, 2)        // MQTT broker ip

WiFiEventHandler gotIpEventHandler, disconnectedEventHandler;

WiFiClient scaleClient;
PubSubClient mqttClient(scaleClient);

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);

// reconnects to the MQTT broker
void reconnect() {
  // loop while disconnected
  while (!mqttClient.connected() && WiFi.isConnected()) {
    // attempt to connect
    Serial.println("Attempting to establish connection to MQTT broker...");
    if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS)) {
      // print connection messaged for debug
      Serial.println("Connection established to MQTT broker");
      mqttClient.publish(TOPIC_BASE, "connected");

      // subscribe to control topic
      mqttClient.subscribe(TOPIC_TARE);
    } else {
      Serial.print("Failed to connect: ");

      // print client state
      switch (mqttClient.state()) {
        case MQTT_CONNECTION_TIMEOUT:
          Serial.println("MQTT_CONNECTION_TIMEOUT");
          break;
        case MQTT_CONNECTION_LOST:
          Serial.println("MQTT_CONNECTION_LOST");
          break;
        case MQTT_CONNECT_FAILED:
          Serial.println("MQTT_CONNECT_FAILED");
          break;
        case MQTT_DISCONNECTED:
          Serial.println("MQTT_DISCONNECTED");
          break;
        case MQTT_CONNECTED:
          Serial.println("MQTT_CONNECTED");
          break;
        case MQTT_CONNECT_BAD_PROTOCOL:
          Serial.println("MQTT_CONNECT_BAD_PROTOCOL");
          break;
        case MQTT_CONNECT_BAD_CLIENT_ID:
          Serial.println("MQTT_CONNECT_BAD_CLIENT_ID");
          break;
        case MQTT_CONNECT_UNAVAILABLE:
          Serial.println("MQTT_CONNECT_UNAVAILABLE");
          break;
        case MQTT_CONNECT_BAD_CREDENTIALS:
          Serial.println("MQTT_CONNECT_BAD_CREDENTIALS");
          break;
        case MQTT_CONNECT_UNAUTHORIZED:
          Serial.println("MQTT_CONNECT_UNAUTHORIZED");
          break;
        default:
          Serial.println("MQTT_STATE_UNKNOWN");
          break;
      }

      // delay before next attempt
      delay(TIMEOUT);
    }
  }
}

const int calVal_eepromAdress = 0;
unsigned long t = 0;

// callback function for handling new messages on subscribed topics
void callback(char* topic, byte* payload, unsigned int length) {
  // zero out scale offset
  if (!strcmp(topic, TOPIC_TARE)) {
    LoadCell.tareNoDelay();
  }
}

void setup() {

  IPAddress mqttBroker(MQTT_HOST);

  Serial.begin(57600);
  delay(10);

  gotIpEventHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP& event) {
    Serial.print("Station connected, IP: ");
    Serial.println(WiFi.localIP());
  });

  disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected& event) {
    Serial.println("Station disconnected, will reconnect or still trying");
  });
  // connect with DHCP
  WiFi.hostname(WIFI_CLIENT_ID);
  Serial.printf("Connecting to %s ...\n", SSID_NAME);
  WiFi.begin(SSID_NAME, SSID_PASSWORD);

  // configure MQTT broker
  mqttClient.setServer(mqttBroker, MQTT_PORT);

  // set callback function
  mqttClient.setCallback(callback);

  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  float calibrationValue;       // calibration value (see example file "Calibration.ino")
  calibrationValue = -7818.58;  // 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()) {
    LoadCell.setCalFactor(calibrationValue);  // set calibration value (float)
    Serial.println("Startup is complete");
  } else {
    LoadCell.setCalFactor(calibrationValue);  // set calibration value (float)
    Serial.println("Startup is complete");
  }
}

void loop() {
  static boolean newDataReady = 0;
  const int serialPrintInterval = 2000;  //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) {

      float weight = LoadCell.getData();

      Serial.print("Load_cell output val: ");
      Serial.println(weight);
      mqttClient.publish(TOPIC_LOAD, String(weight).c_str(), true);
      newDataReady = 0;
      t = millis();

      weight = 0;

    }
  }

  // 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");
  }

  // connect if disconnected
  if (!mqttClient.connected()) {
    if (WiFi.isConnected()) {
      reconnect();
    }
  }

  // maintain connection
  mqttClient.loop();
}

Load_cell output val: -389.72
Load_cell output val: -209.98
Load_cell output val: 244.82
Load_cell output val: 249.28
Load_cell output val: -80.30
Load_cell output val: -382.72
Load_cell output val: -334.44
Load_cell output val: -221.93
Load_cell output val: -260.50
Load_cell output val: -146.83
Load_cell output val: -194.87
Load_cell output val: -264.98
Load_cell output val: -305.49
Load_cell output val: 14.79
Load_cell output val: 111.23
Load_cell output val: 238.00

Any help is appreciated :slight_smile:

Just try it with only sending mqtt data, does it work?

/*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   Settling time (number of samples) and data filtering can be adjusted in the config.h file
   For calibration and storing the calibration value in eeprom, see example file "Calibration.ino"

   The update() function checks for new data and starts the next conversion. In order to acheive maximum effective
   sample rate, update() should be called at least as often as the HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS.
   If you have other time consuming code running (i.e. a graphical LCD), consider calling update() from an interrupt routine,
   see example file "Read_1x_load_cell_interrupt_driven.ino".

   This is an example sketch on how to use this library
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <HX711_ADC.h>
#if defined(ESP8266) || defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif

//pins:
const int HX711_dout = D0;  //mcu > HX711 dout pin
const int HX711_sck = D2;   //mcu > HX711 sck pin

// connection settings
#define TIMEOUT 5000               // connection failure timeout in ms
#define MQTT_PORT 1883             // MQTT broker port
#define MQTT_CLIENT_ID "loadcell"  // device client ID

// Wifi settings
#define WIFI_CLIENT_ID "LOADCELL1"
#define SSID_NAME "IoT"           // SSID network wifi name to connect to
#define SSID_PASSWORD "12345678"  // Wifi password

// MQTT topics
#define TOPIC_BASE "loadcell/sensor/main-bedroom"  // base topic
#define TOPIC_LOAD TOPIC_BASE "/load"              // topic to publish samples on
#define TOPIC_TARE TOPIC_BASE "/tare"              // topic to receive tare commands on
#define MQTT_USER ""                               // MQTT username
#define MQTT_PASS ""                               // MQTT password
#define MQTT_HOST IPAddress(192, 168, 1, 2)        // MQTT broker ip

WiFiEventHandler gotIpEventHandler, disconnectedEventHandler;

WiFiClient scaleClient;
PubSubClient mqttClient(scaleClient);

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);

// reconnects to the MQTT broker
void reconnect() {
  // loop while disconnected
  while (!mqttClient.connected() && WiFi.isConnected()) {
    // attempt to connect
    Serial.println("Attempting to establish connection to MQTT broker...");
    if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS)) {
      // print connection messaged for debug
      Serial.println("Connection established to MQTT broker");
      mqttClient.publish(TOPIC_BASE, "connected");

      // subscribe to control topic
      mqttClient.subscribe(TOPIC_TARE);
    } else {
      Serial.print("Failed to connect: ");

      // print client state
      switch (mqttClient.state()) {
        case MQTT_CONNECTION_TIMEOUT:
          Serial.println("MQTT_CONNECTION_TIMEOUT");
          break;
        case MQTT_CONNECTION_LOST:
          Serial.println("MQTT_CONNECTION_LOST");
          break;
        case MQTT_CONNECT_FAILED:
          Serial.println("MQTT_CONNECT_FAILED");
          break;
        case MQTT_DISCONNECTED:
          Serial.println("MQTT_DISCONNECTED");
          break;
        case MQTT_CONNECTED:
          Serial.println("MQTT_CONNECTED");
          break;
        case MQTT_CONNECT_BAD_PROTOCOL:
          Serial.println("MQTT_CONNECT_BAD_PROTOCOL");
          break;
        case MQTT_CONNECT_BAD_CLIENT_ID:
          Serial.println("MQTT_CONNECT_BAD_CLIENT_ID");
          break;
        case MQTT_CONNECT_UNAVAILABLE:
          Serial.println("MQTT_CONNECT_UNAVAILABLE");
          break;
        case MQTT_CONNECT_BAD_CREDENTIALS:
          Serial.println("MQTT_CONNECT_BAD_CREDENTIALS");
          break;
        case MQTT_CONNECT_UNAUTHORIZED:
          Serial.println("MQTT_CONNECT_UNAUTHORIZED");
          break;
        default:
          Serial.println("MQTT_STATE_UNKNOWN");
          break;
      }

      // delay before next attempt
      delay(TIMEOUT);
    }
  }
}

const int calVal_eepromAdress = 0;
unsigned long t = 0;

// callback function for handling new messages on subscribed topics
void callback(char* topic, byte* payload, unsigned int length) {
  // zero out scale offset
  if (!strcmp(topic, TOPIC_TARE)) {
    LoadCell.tareNoDelay();
  }
}

void setup() {

  IPAddress mqttBroker(MQTT_HOST);

  Serial.begin(57600);
  delay(10);

  gotIpEventHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP & event) {
    Serial.print("Station connected, IP: ");
    Serial.println(WiFi.localIP());
  });

  disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected & event) {
    Serial.println("Station disconnected, will reconnect or still trying");
  });
  // connect with DHCP
  WiFi.hostname(WIFI_CLIENT_ID);
  Serial.printf("Connecting to %s ...\n", SSID_NAME);
  WiFi.begin(SSID_NAME, SSID_PASSWORD);

  // configure MQTT broker
  mqttClient.setServer(mqttBroker, MQTT_PORT);

  // set callback function
  mqttClient.setCallback(callback);

  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  float calibrationValue;       // calibration value (see example file "Calibration.ino")
  calibrationValue = -7818.58;  // 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()) {
    LoadCell.setCalFactor(calibrationValue);  // set calibration value (float)
    Serial.println("Startup is complete");
  } else {
    LoadCell.setCalFactor(calibrationValue);  // set calibration value (float)
    Serial.println("Startup is complete");
  }
}
unsigned long TimeToPublish = 1000;
unsigned long pastTime  = millis();
void loop() {
  static boolean newDataReady = 0;
  const int serialPrintInterval = 2000;  //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) {

        float weight = LoadCell.getData();

        Serial.print("Load_cell output val: ");
        Serial.println(weight);
        mqttClient.publish(TOPIC_LOAD, String(weight).c_str(), true);
        newDataReady = 0;
        t = millis();

        weight = 0;

      }
    }

    // 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");
    }
  */

  if (WiFi.isConnected())
  {
    if ( mqttClient.connected() )
    {
      mqttClient.loop();
      if ( (millis() - pastTime) >= TimeToPublish )
      {
        mqttClient.publish(TOPIC_LOAD, String(100).c_str(), true);
        pastTime = millis();
      }
    }
  } else
  {
WiFi.hostname(WIFI_CLIENT_ID);
  Serial.printf("Connecting to %s ...\n", SSID_NAME);
  WiFi.begin(SSID_NAME, SSID_PASSWORD);
    WiFi.hostname(WIFI_CLIENT_ID); ///need to reconnect with WiFI then connect to MQT
    reconnect();
  }

  // maintain connection

}

Your reconnect does not account for a WiFI disconnect.

My MQTT keep alive task might give a few hints or not.

/*
  Important to not set vTaskDelay/vTaskDelayUntil to less then 10. Errors begin to develop with the MQTT and network connection.
  makes the initial wifi/mqtt connection and works to keeps those connections open.
*/
void MQTTkeepalive( void *pvParameters )
{
  sema_MQTT_KeepAlive   = xSemaphoreCreateBinary();
  xSemaphoreGive( sema_MQTT_KeepAlive ); // found keep alive can mess with a publish, stop keep alive during publish
  MQTTclient.setKeepAlive( 90 ); // setting keep alive to 90 seconds makes for a very reliable connection, must be set before the 1st connection is made.
  TickType_t xLastWakeTime = xTaskGetTickCount();
  const TickType_t xFrequency = 250; //delay for ms
  for (;;)
  {
    //check for a is-connected and if the WiFi 'thinks' its connected, found checking on both is more realible than just a single check
    if ( (wifiClient.connected()) && (WiFi.status() == WL_CONNECTED) )
    {
      xSemaphoreTake( sema_MQTT_KeepAlive, portMAX_DELAY ); // whiles MQTTlient.loop() is running no other mqtt operations should be in process
      MQTTclient.loop();
      xSemaphoreGive( sema_MQTT_KeepAlive );
    }
    else {
      log_i( "MQTT keep alive found MQTT status % s WiFi status % s", String(wifiClient.connected()), String(WiFi.status()) );
      if ( !(wifiClient.connected()) || !(WiFi.status() == WL_CONNECTED) )
      {
        connectToWiFi();
      }
      connectToMQTT();
    }
    //log_i( " high watermark % d",  uxTaskGetStackHighWaterMark( NULL ) );
    xLastWakeTime = xTaskGetTickCount();
    vTaskDelayUntil( &xLastWakeTime, xFrequency );
  }
  vTaskDelete ( NULL );
}

connect to WiFi

void connectToWiFi()
{
  int TryCount = 0;
  while ( WiFi.status() != WL_CONNECTED )
  {
    TryCount++;
    WiFi.disconnect();
    WiFi.begin( SSID, PASSWORD );
    vTaskDelay( 4000 );
    if ( TryCount == 10 )
    {
      ESP.restart();
    }
  }
  WiFi.onEvent( WiFiEvent );
}

connect to mqtt broker

void connectToMQTT()
{
  byte mac[5]; // create client ID from mac address
  WiFi.macAddress(mac); // get mac address
  String clientID = String(mac[0]) + String(mac[4]) ; // use mac address to create clientID
  while ( !MQTTclient.connected() )
  {
    MQTTclient.connect( clientID.c_str(), mqtt_username, mqtt_password );
    vTaskDelay( 250 );
  }
  MQTTclient.setCallback ( mqttCallback );
  MQTTclient.subscribe   ( topicOK );
  MQTTclient.subscribe   ( topicRemainingMoisture_0 );
  MQTTclient.subscribe   ( topicWindSpeed );
  MQTTclient.subscribe   ( topicWindDirection );
  MQTTclient.subscribe   ( topicDPnWI );
  MQTTclient.subscribe   ( topicOutsideTemperature );
  MQTTclient.subscribe   ( topicOutsideHumidity );
  MQTTclient.subscribe   ( topicOutsidePressure );
  MQTTclient.subscribe   ( topicRainfall );
  //MQTTclient.subscribe   ( topicWSVolts );
  MQTTclient.subscribe   ( topicPower );
} //void connectToMQTT()

I tried your code but not sure if I understand as this is all it gives out

Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...
Connecting to IoT ...

The WiFi/MQTT part in the code I use works but it also makes the weight unstable somehow...

Thanks for the WiFi/MQTT code, I'll look into it if I can get a stable output on the WiFi/MQTT I have now :slight_smile:

It could be related to:

OFF TOPIC: I'm just laughing thinking in a possible usage for this project. :metal: :rofl:

That is an older version from the same guy I got my code from and it doesn't work.

Your code is not the same at all because I can't see this part on code above.

He got one for WiFi

So where's this part in your code?

Like I said in my first post, with his code the load cell was unstable with hundreds of Kg up and down so I took his WiFi/MQTT code and added it to another code where the load cell was stable but when I did that the load cell also got unstable...

But the "average" part is important.

Not when the weight goes from -389 to 249 Kg when it should be 0 Kg...

Look what you are saying.

so I thought it was something wrong with the weight code from newAM so I took out the WiFi and MQTT part and added it too HX711_ADC (Olav Kallhovd) code but the problem is the same...

The reading was unstable with AM code and it also unstable with your code. So the problem should something else.

Arithmetic average is always a good way to get consistent values because you could discard bad readings.

It could have something like this:

float value = scale.get_units();

if((value > worstLowValue) && (value < worstHighValue))
{
   avg += value;
   samples++;
}

if (samples >= NUM_SAMPLES)
{
  avg /= samples;

  mqttClient.publish(TOPIC_LOAD, String(avg).c_str(), true);
}


But the HX711_ADC (Olav Kallhovd) code by itself without the WiFi/MQTT is fine and stable, it gives out 0 Kg with nothing on the bed and if lie down it shows ~80Kg stable. You are right that average is probably always good but putting average on a value that goes up and down +/- 500 Kg when it should be 0 Kg is not going to fix my problem.

The strange thing is that I haven't done anything with the code that get the weight result, just added WiFi and MQTT and the weight result goes bananas...

I appreciate your help tho :slight_smile:

It was the WiFi that interfered with the analog signal so after putting in some delay in the "void loop()" as red_car suggested here the weigh is stable :slight_smile:

/*
   -------------------------------------------------------------------------------------
   HX711_ADC
   Arduino library for HX711 24-Bit Analog-to-Digital Converter for Weight Scales
   Olav Kallhovd sept2017
   -------------------------------------------------------------------------------------
*/

/*
   Settling time (number of samples) and data filtering can be adjusted in the config.h file
   For calibration and storing the calibration value in eeprom, see example file "Calibration.ino"

   The update() function checks for new data and starts the next conversion. In order to acheive maximum effective
   sample rate, update() should be called at least as often as the HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS.
   If you have other time consuming code running (i.e. a graphical LCD), consider calling update() from an interrupt routine,
   see example file "Read_1x_load_cell_interrupt_driven.ino".

   This is an example sketch on how to use this library
*/

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <HX711_ADC.h>
#if defined(ESP8266)|| defined(ESP32) || defined(AVR)
#include <EEPROM.h>
#endif

//pins:
const int HX711_dout = D1; //mcu > HX711 dout pin
const int HX711_sck = D2; //mcu > HX711 sck pin

// connection settings
#define TIMEOUT   5000 // connection failure timeout in ms
#define MQTT_PORT 1883 // MQTT broker port
#define MQTT_CLIENT_ID "loadcell" // device client ID

// Wifi settings
#define WIFI_CLIENT_ID "LOADCELL1"
#define SSID_NAME "IoT" // SSID network wifi name to connect to
#define SSID_PASSWORD "12345678" // Wifi password

// MQTT topics
#define TOPIC_BASE "loadcell/sensor/main-bedroom" // base topic
#define TOPIC_LOAD TOPIC_BASE "/load"  // topic to publish samples on
#define TOPIC_TARE TOPIC_BASE "/tare"  // topic to receive tare commands on
#define MQTT_USER "" // MQTT username
#define MQTT_PASS "" // MQTT password
#define MQTT_HOST IPAddress(192, 168, 1, 2) // MQTT broker ip

WiFiEventHandler gotIpEventHandler, disconnectedEventHandler;

WiFiClient scaleClient;
PubSubClient mqttClient(scaleClient);

//HX711 constructor:
HX711_ADC LoadCell(HX711_dout, HX711_sck);

// reconnects to the MQTT broker
void reconnect()
{
    // loop while disconnected
    while (!mqttClient.connected() && WiFi.isConnected())
    {
        // attempt to connect
        Serial.println("Attempting to establish connection to MQTT broker...");
        if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASS))
        {
            // print connection messaged for debug
            Serial.println("Connection established to MQTT broker");
            mqttClient.publish(TOPIC_BASE, "connected");

            // subscribe to control topic
            mqttClient.subscribe(TOPIC_TARE);
        }
        else
        {
            Serial.print("Failed to connect: ");

            // print client state
            switch (mqttClient.state())
            {
                case MQTT_CONNECTION_TIMEOUT:
                    Serial.println("MQTT_CONNECTION_TIMEOUT");
                    break;
                case MQTT_CONNECTION_LOST:
                    Serial.println("MQTT_CONNECTION_LOST");
                    break;
                case MQTT_CONNECT_FAILED:
                    Serial.println("MQTT_CONNECT_FAILED");
                    break;
                case MQTT_DISCONNECTED:
                    Serial.println("MQTT_DISCONNECTED");
                    break;           
                case MQTT_CONNECTED:
                    Serial.println("MQTT_CONNECTED");
                    break;
                case MQTT_CONNECT_BAD_PROTOCOL:
                    Serial.println("MQTT_CONNECT_BAD_PROTOCOL");
                    break;
                case MQTT_CONNECT_BAD_CLIENT_ID:
                    Serial.println("MQTT_CONNECT_BAD_CLIENT_ID");
                    break;
                case MQTT_CONNECT_UNAVAILABLE:
                    Serial.println("MQTT_CONNECT_UNAVAILABLE");
                    break;
                case MQTT_CONNECT_BAD_CREDENTIALS:
                    Serial.println("MQTT_CONNECT_BAD_CREDENTIALS");
                    break;
                case MQTT_CONNECT_UNAUTHORIZED:
                    Serial.println("MQTT_CONNECT_UNAUTHORIZED");
                    break;
                default:
                    Serial.println("MQTT_STATE_UNKNOWN");
                    break;
            }

            // delay before next attempt
            delay(TIMEOUT);
        } 
    }
}

const int calVal_eepromAdress = 0;
unsigned long t = 500;

// callback function for handling new messages on subscribed topics
void callback(char* topic, byte* payload, unsigned int length)
{
    // zero out scale offset
    if (!strcmp(topic, TOPIC_TARE))
    {
      LoadCell.tareNoDelay();
    }
}

void setup() {
  
  IPAddress mqttBroker(MQTT_HOST);
  
  Serial.begin(57600); delay(10);

  gotIpEventHandler = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP& event)
  {
    Serial.print("Station connected, IP: ");
    Serial.println(WiFi.localIP());
  });

  disconnectedEventHandler = WiFi.onStationModeDisconnected([](const WiFiEventStationModeDisconnected& event)
  {
    Serial.println("Station disconnected, will reconnect or still trying");
  });
  // connect with DHCP
  WiFi.hostname(WIFI_CLIENT_ID);
  Serial.printf("Connecting to %s ...\n", SSID_NAME);
  WiFi.begin(SSID_NAME, SSID_PASSWORD);

  // configure MQTT broker
  mqttClient.setServer(mqttBroker, MQTT_PORT);

  // set callback function
  mqttClient.setCallback(callback);

  Serial.println();
  Serial.println("Starting...");

  LoadCell.begin();
  //LoadCell.setReverseOutput(); //uncomment to turn a negative output value to positive
  float calibrationValue; // calibration value (see example file "Calibration.ino")
  calibrationValue = -7818.58; // 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()) {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }
  else {
    LoadCell.setCalFactor(calibrationValue); // set calibration value (float)
    Serial.println("Startup is complete");
  }
}

void loop() {
  delay(2000);
  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) {

      float i = LoadCell.getData();
      weight = LoadCell.getData();

      Serial.print("Load_cell output val: ");
      Serial.println(i);
      mqttClient.publish(TOPIC_LOAD, String(weight).c_str(), true);
      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");
  }

  // connect if disconnected
  if (!mqttClient.connected())
  {
      if (WiFi.isConnected()) {
        reconnect();
      }
  }

  // maintain connection
  mqttClient.loop();
}

Output

Load_cell output val: -0.00
Load_cell output val: -0.00
Load_cell output val: -0.01
Load_cell output val: -0.01
Load_cell output val: -0.01
Load_cell output val: -0.01
Load_cell output val: -0.01
Load_cell output val: -0.01
Load_cell output val: -0.01
Load_cell output val: -0.01
Load_cell output val: -0.01
Load_cell output val: -0.00

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.