#include "HX711.h"
#include "Wire.h"
#include "Adafruit_SSD1306.h"
#include "ESP8266WiFi.h"
#include "EEPROM.h"
#include "ESP8266httpUpdate.h"
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 32
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
#define upd_version "1"
#define upd_reboot true
#define upd_server "10.11.12.13"
#define upd_file "/update/scaleupd.php"
const int LOADCELL_DOUT_PIN = D4;
const int LOADCELL_SCK_PIN = D3;
const int TarePin = D5;
const int OverPin = D6;
const int GoodPin = D7;
const int UnderPin = D8;
int CalEepromAdress = 101;
int TarEepromAdress = 111;
float known_mass = 500;
float readValue = 0;
float calValue = 6192.2;// overrided by EEPROM or/and boot calibration
float tareValue = 472; // overrided by EEPROM or/and manual tare
const char* ssid = "myWiFi";
const char* password = "53cr37p4ssw0rd";
HX711 scale;
WiFiClient client;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //oled display uses std wire lib - for nodemcu SCL is D1(4), SDA is D2(5) (see pins_arduino.h)
void setup() {
Serial.begin(115200);
Serial.println("\nStarting...");
display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println("Press to Calibrate");
display.display();
pinMode(TarePin, INPUT_PULLUP);
pinMode(OverPin, OUTPUT);
pinMode(GoodPin, OUTPUT);
pinMode(UnderPin, OUTPUT);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
delay(200);
scale.set_scale();
scale.set_scale(calValue);
scale.tare();
int wificnt = 0;
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED && wificnt < 10) {
Serial.print (".");
wificnt ++;
delay(200);
} //try 20sec to connect to Wifi in order to perform OTA update
ESPhttpUpdate.rebootOnUpdate(upd_reboot);
t_httpUpdate_return ret = ESPhttpUpdate.update(upd_server, 80, upd_file, upd_version);
EEPROM.begin(512);
EEPROM.get(CalEepromAdress, calValue);
EEPROM.get(TarEepromAdress, tareValue);
delay(2000); //Giving two sec to perform calibration at boot
if(digitalRead(TarePin) == LOW){
Serial.println("\nIn Calibration...");
scale.set_scale();
scale.tare();
digitalWrite(UnderPin, HIGH); //turning all leds ON
digitalWrite(OverPin, HIGH);
digitalWrite(GoodPin, HIGH);
display.clearDisplay();
display.setCursor(0,0);
display.print("Calibrate with "); display.println(known_mass);
display.display();
Serial.print("Calibrate with "); Serial.println(known_mass);
delay(2000); //Two more seconds to release the button
while (digitalRead(TarePin) == HIGH){ delay(200); Serial.print("."); } //Wait for the button to be pushed, after putting the calibrated weight on the scale
calValue = (scale.get_units(10)) / known_mass;
EEPROM.put(CalEepromAdress, calValue); //Save the calibration to EEPROM
display.clearDisplay();
display.setCursor(0,0);
display.print("Calibrated to "); display.println(calValue);
display.display();
Serial.print("\nCalibrated to "); Serial.println(calValue);
scale.set_scale(calValue);
delay(1000);
}
tareValue = (scale.get_units(20)); //Perform an initial tare
scale.set_offset(tareValue);
scale.tare();EEPROM.put(TarEepromAdress, tareValue); //Save TARE into EEPROM - not really needed here
EEPROM.end();
}
void loop() {
display.clearDisplay();
if(digitalRead(TarePin) == LOW){ //if button pressed - perform tare
Serial.println("\nTare...");
digitalWrite(UnderPin, HIGH); //turn all leds on
digitalWrite(GoodPin, HIGH);
digitalWrite(OverPin, HIGH);
tareValue = (scale.get_units(20));
scale.set_offset(tareValue);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(0,0);
display.print(" TARE to "); display.println(tareValue);
display.display();
Serial.print("TARE to "); Serial.println(tareValue);
} //end of TARE
readValue = (scale.get_units(10) - tareValue);
//readValue = (scale.read_average(20) - tareValue);
Serial.println(readValue);
display.clearDisplay();
display.setTextSize(4);
display.setCursor(5, 0);
display.print(readValue);
display.setTextSize(2);
display.setCursor(116, 17);
display.println("g");
display.display();
digitalWrite(UnderPin, LOW); //turn all leds off
digitalWrite(GoodPin, LOW);
digitalWrite(OverPin, LOW);
if(readValue < 3.49){
digitalWrite(UnderPin, HIGH); //Red Led - below 3.5g
}
if(readValue > 3.48 && readValue < 3.80){
digitalWrite(GoodPin, HIGH); //Green Led - OK
}
if(readValue > 3.79){
digitalWrite(OverPin, HIGH); //Blue Led - too heavy
}
// delay(100);
}