BLYNK
HOME       📲 GETTING STARTED       📗 DOCS       ❓HELP CENTER       👉 SKETCH BUILDER

Wifi scale


#1

I am just getting started with this project. I plan on making this project first and then another weight based project that is a bit more specific to aviation.

In this first test I created a scale that uses the HX711 and 4 load cells connected in a bridge.

It allows the user to:

  1. Setup the scale.
  2. Calibrate the scale
  3. Read the scale.

I expect to add graphing of the captured readings and saving of the calibration data to the SPIFFS in the next iteration.

It works but it is just a simple start. There is also unused junk in the code.



#include <FS.h>                   //this needs to be first, or it all crashes and burns...

#include <ArduinoOTA.h>
#include <ESP8266WiFi.h>          //https://github.com/esp8266/Arduino
#include <BlynkSimpleEsp8266.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager
#include <ArduinoJson.h>          //https://github.com/bblanchon/ArduinoJson
#include "HX711.h"
#include <U8g2lib.h>
//#include <U8x8lib.h>
#include "globals.h"


//create timer instance
BlynkTimer timer;

// Initialize our HX711 interface
HX711 scale;


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  Serial.println();
  
  // these two call get the data from the SPIFFS file and use the data to provision  blynk and wifi
  restoreparameters();
  startmywifi();

  Blynk.config(blynk_token);          // config Blynk

    
// Timed Lambda code
  timer.setInterval(1200L, [] () { // Run every 1.2 seconds
// START timer Function    <--- put code lines here that you want to run repetedly in sync
    Blynk.virtualWrite(V0, millis() / 60000);   // Display the UpTime in Minutes
//    Blynk.virtualWrite(V1, String(eml[j++]));   // Display the name
//    if (j >= count) j = 0;
  });  // END Timer Function

}

void loop() {
  // in most cases you should not put code here
 if (Blynk.connected()){
    Blynk.run();
  } else Blynk.connect(1000l);                // timeout 1 seconds        
  timer.run();
} 
BLYNK_WRITE(V9)
{
  Blynk.virtualWrite(V1, readscale());
}

BLYNK_WRITE(V5)
{
  long pinValue = param.asLong();
  Serial.println(pinValue);
}

BLYNK_WRITE(V6){
  setupscale();
}

BLYNK_WRITE(V7){
  startcalibration();
}

BLYNK_WRITE(V8){
  calibratescale();
}


//  Global data
char modulename[] = "Thin K scale";   //<===== this is the name for the OTA updates using the arduino IDE

#define SDA_PIN     2             // I2C SDA pin
#define SLC_PIN     14            // I2C SCL pin

#define knownweight 50

// Define our data and clock pins for the scale
#define DOUT 4 // D2 maps to GPIO4
#define CLK 5  // D1 maps to GPIO5



//define your default values here, if there are different values in config.json, they are overwritten.
// if you are using BLYNK you may not need the mqtt items
char mqtt_server[40] = "your mqtt server";    // <======= this is the default data 
char mqtt_port[6] = "8080";                   // <========= this also
char blynk_token[34] = "YOUR_BLYNK_TOKEN";    //<======== and this

//flag for saving data
bool shouldSaveConfig = true;

#define getweight       V0
#define docalibration   V1
#define weightpin       V2 

const char*  daystrings[7]  =  {"Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"};
const char*   monthstrings[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
int days[7]; 
int today;

//WidgetRTC rtc; 

void setupscale() {
  // Initialize library with data output pin, clock input pin and gain factor.
  // Channel selection is made by passing the appropriate gain:
  // - With a gain factor of 64 or 128, channel A is selected
  // - With a gain factor of 32, channel B is selected
  // By omitting the gain factor parameter, the library
  // default "128" (Channel A) is used here.
  scale.begin(DOUT, CLK);

  Serial.println(scale.read());      // print a raw reading from the ADC

  Serial.print("read average: \t\t");
  Serial.println(scale.read_average(20));   // print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale.get_value(5));   // print the average of 5 readings from the ADC minus the tare weight (not set yet)

  Serial.print("get units: \t\t");
  Serial.println(scale.get_units(5), 1);  // print the average of 5 readings from the ADC minus tare weight (not set) divided
  // by the SCALE parameter (not set yet)

  scale.set_scale(2280.f);                // this value is obtained by calibrating the scale with known weights; see the README for details
  scale.tare();                           // reset the scale to 0

  Serial.println("After setting up the scale:");

  Serial.print("read: \t\t");
  Serial.println(scale.read());                 // print a raw reading from the ADC

  Serial.print("read average: \t\t");
  Serial.println(scale.read_average(20));       // print the average of 20 readings from the ADC

  Serial.print("get value: \t\t");
  Serial.println(scale.get_value(5));           // print the average of 5 readings from the ADC minus the tare weight, set with tare()

  Serial.print("get units: \t\t");
  Serial.println(scale.get_units(5), 1);        // print the average of 5 readings from the ADC minus tare weight, divided
  // by the SCALE parameter set with set_scale

  Serial.println("Readings:");
}

void startcalibration() {
  scale.set_scale();
  scale.tare();
}

void calibratescale() {
  // Place the known weight on  scale
  // Divide the result by known weight.
  long adjustment = scale.get_units(10) / knownweight;
  scale.set_scale(adjustment);
}

long readscale() {
  long weightreading;
  scale.power_up();
  weightreading = scale.get_units(10);
  scale.power_down();             // put the ADC in sleep mode
  return weightreading;
}
 
 
 //callback notifying us of the need to save config
void saveConfigCallback () {
  shouldSaveConfig = true;
}
 
 void restoreparameters(){

  if (SPIFFS.begin()) {
    if (SPIFFS.exists("/config.json")) {
//file exists, reading and loading
      File configFile = SPIFFS.open("/config.json", "r");
      if (configFile) {
        size_t size = configFile.size();
// Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);
        configFile.readBytes(buf.get(), size);
        DynamicJsonBuffer jsonBuffer;
        JsonObject& json = jsonBuffer.parseObject(buf.get());
//        json.printTo(Serial);
        if (json.success()) {
// json will parse the file for the variable name and load it into the supplied variable
          strcpy(mqtt_server, json["mqtt_server"]);     //get the mqtt_server <== you need one of these for each param
          strcpy(mqtt_port, json["mqtt_port"]);         //get the mqtt port
          strcpy(blynk_token, json["blynk_token"]);     //get the blynk token

        }
        configFile.close();
      }
    }
  } 
  //end read
 }



void startmywifi(){
  //Local intialization. Once its done, there is no need to keep it around
  WiFiManager wifiManager;

  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);

  // The extra parameters to be configured (can be either global or just here)
  // After connecting, parameter.getValue() will get you the configured value
  // id/name placeholder/prompt default length
  WiFiManagerParameter custom_mqtt_server("server", "mqtt server", mqtt_server, 40);
  WiFiManagerParameter custom_mqtt_port("port", "mqtt port", mqtt_port, 6);
  WiFiManagerParameter custom_blynk_token("blynk", "blynk token", blynk_token, 32);
  
//set static ip if you want
//  wifiManager.setSTAStaticIPConfig(IPAddress(10,0,1,99), IPAddress(10,0,1,1), IPAddress(255,255,255,0));
  
//  <============== add all your parameters here
  wifiManager.addParameter(&custom_mqtt_server);
  wifiManager.addParameter(&custom_mqtt_port);
  wifiManager.addParameter(&custom_blynk_token);

  //reset settings - for testing
//    wifiManager.resetSettings();    // <========= once you have this working you can comment out this line

  //set minimu quality of signal so it ignores AP's under that quality
  //defaults to 8%
  //wifiManager.setMinimumSignalQuality();
  
  //sets timeout until configuration portal gets turned off
  //useful to make it all retry or go to sleep
  //in seconds
  //wifiManager.setTimeout(120);

  //fetches ssid and pass and tries to connect
  //if it does not connect it starts an access point with the specified name
  //and goes into a blocking loop awaiting configuration
  if (!wifiManager.autoConnect("AutoConnectAP", "password")) {
    ESP.reset();    //reset and try again
  }

  //if you get here you have connected to the WiFi

  //get the custom parameters here
  strcpy(mqtt_server, custom_mqtt_server.getValue());
  strcpy(mqtt_port, custom_mqtt_port.getValue());
  strcpy(blynk_token, custom_blynk_token.getValue());

  //check the flag to see if we save the custom parameters to FS
  if (shouldSaveConfig) {
    DynamicJsonBuffer jsonBuffer;
    JsonObject& json = jsonBuffer.createObject();

 //set the custom parameters here
    json["mqtt_server"] = mqtt_server;
    json["mqtt_port"] = mqtt_port;
    json["blynk_token"] = blynk_token;

    File configFile = SPIFFS.open("/config.json", "w");
    if (configFile) {
//      json.printTo(Serial);       // dump the data to the serial
      json.printTo(configFile);   //write the custom parameters here
      configFile.close();
    } else Serial.println("failed to open config file for writing");
    //end save
  }
}