HX711 ESP-01 8266 Load Cell Arduino IOT Sketch .ino

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>

/* Open network, no pass, free 4 all. */
const char *ssid = "TIMBANGAN ONLEN";

ESP8266WebServer server(80);

// esp-01 wiring pinout
const int LOADCELL_DOUT_PIN = 2;
const int LOADCELL_SCK_PIN = 0;

// set pulse for select channel gain
// Channel A, gain factor 128. PULSE = 1
// Channel A, gain factor 64. PULSE = 3
// Channel B, gain factor 32. PULSE = 2
const byte PULSE = 1; //channel A, 128

unsigned long rawadc, startMillis, currentMillis;

unsigned long averageraw(byte samples = 5){
  unsigned long sum;
  for(byte s = 0; s < samples; s++){
    sum += ReadCount();
    delayMicroseconds(5);
  }
  return sum / samples;
}

unsigned long ReadCount(void){ 
  unsigned long Count; 
  unsigned char i; 
  digitalWrite(LOADCELL_DOUT_PIN, HIGH);  //  LOADCELL_DOUT_PIN set to high as output data is not ready for retrieval         
  digitalWrite(LOADCELL_SCK_PIN, LOW); // LOADCELL_SCK_PIN set to low as output data is not ready for retrieval
  Count = 0; 
  while(digitalRead(LOADCELL_DOUT_PIN)); // When LOADCELL_DOUT_PIN goes to low, it indicates data is ready for retrieval.
  for (i = 0; i < 24; i++){ // 24 bits are shifted out
    digitalWrite(LOADCELL_SCK_PIN, HIGH); 
    Count = Count << 1; 
    digitalWrite(LOADCELL_SCK_PIN, LOW);
    if(digitalRead(LOADCELL_DOUT_PIN)) Count++; 
  } 
  // set default channel A gain 128, PULSE = 1
  digitalWrite(LOADCELL_SCK_PIN, HIGH); 
  Count = Count ^ 0x800000;  
  digitalWrite(LOADCELL_SCK_PIN, LOW);
  //optional, 3 & 2 pulses for channel A gain 64 & channel B gain 32
  if(PULSE > 1){
    for(byte n = 1; n < PULSE; n++){
      digitalWrite(LOADCELL_SCK_PIN, HIGH); 
      digitalWrite(LOADCELL_SCK_PIN, LOW);      
    }
  }
  return Count; 
}

static const char HOME[] PROGMEM = R"Ganteng_Permanen(
<!DOCTYPE html>
<html>
  <head>
    <title>TIMBANGAN ONLEN</title>
    <meta name="author" content="Ganteng Permanen">
    <style>
.gauge{position:relative;background:var(--gauge-bg);border:.05em solid #222;border-radius:50%;min-width:550px;min-height:550px;font-weight:700;font-size:70px}.gauge .ticks{position:absolute;width:100%;height:100%;top:0;left:0}.gauge .ticks .min{background:#000;position:relative;left:0;top:50%;width:100%;height:1%;margin-bottom:-1%;background:linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 4%,#000 4%,#000 15%,rgba(0,0,0,0) 15%);transform:rotate(-45deg)}.gauge .ticks .mid{background:#000;position:relative;left:0;top:50%;width:100%;height:1%;margin-bottom:-1%;background:linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 4%,#000 4%,#000 15%,rgba(0,0,0,0) 15%);transform:rotate(90deg)}.gauge .ticks .max{background:#000;position:relative;left:0;top:50%;width:100%;height:1%;margin-bottom:-1%;background:linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 4%,#000 4%,#000 15%,rgba(0,0,0,0) 15%);transform:rotate(225deg)}.gauge .ticks .tithe{transform:rotate(calc(27deg * var(--gauge-tithe-tick) - 45deg));background:#000;position:relative;left:0;top:50%;width:100%;height:1%;margin-bottom:-1%;background:linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 10%,#000 10%,#000 15%,rgba(0,0,0,0) 15%)}.gauge .tick-circle{position:absolute;top:15%;left:15%;width:calc(70% - .1em);height:calc(70% - .1em);border-left:.1em solid;border-top:.1em solid;border-right:.1em solid;border-bottom:.1em solid transparent;border-radius:50%}.gauge .needle{transform:rotate(calc(270deg * calc(var(--gauge-value,0deg)/ 100) - 45deg));background:#000;position:relative;left:0;top:49%;width:100%;height:4%;margin-bottom:-4%;background:linear-gradient(90deg,rgba(2,0,36,0) 0,rgba(0,0,0,0) 24%,#000 24%,#000 30%,rgba(0,0,0,0) 50%)}.gauge .needle .needle-head{position:relative;top:15%;left:22.5%;width:2.7%;height:70%;background-color:#000;transform:rotate(-45deg)}.gauge .labels{position:absolute;width:100%;height:100%}.gauge .labels .value-label{position:relative;top:77%;text-align:center}.guide-x,.guide-y{background-color:orange;visibility:visible;position:absolute;left:50%;top:0;width:1px;height:100%}.guide-y{left:0;top:50%;width:100%;height:1px}

        .gauge {
            margin: auto;
        }

      .center {
        position: absolute;
        margin-left: auto;
        margin-right: auto;
        left: 0;
        right: 0;
        text-align: center;
        top: 9vw;
      }     
      span {
        animation: efek .6s infinite;
        font-size: 22vw;
        font-weight: bold;
        color: pink; 
        text-shadow: 2px 2px red, -2px -2px red, 0 0 18px red;
      }
      code {
        color: pink; 
        opacity: 0.6; 
        text-shadow: 2px 2px blue;
      }
      @keyframes efek {
        50% {text-shadow: 5px 5px 10px blue;}
      }
      
      .tab {
        overflow: hidden;
            margin-top: 7vw;
            text-align: center;
        border: 1px solid #ccc;
        background-color: #f1f1f1;
      }
      .tab button {
        background-color: inherit;
        border: none;
        outline: none;
        cursor: pointer;
        padding: 14px 16px;
        transition: 0.3s;
      }
      .tab button:hover {
        background-color: #ddd;
      }
      .tab button.active {
        background-color: #ccc;
      }
      .tabcontent {
        display: none;
        padding: 6px 12px;
        border: 1px solid #ccc;
        border-top: none;
      }   
    </style>
  </head>
  <body onload="init()">
    <div class="center">
      <span id="bobot">333</span>
      <code>grams</code>
            <div id="demoGauge" class="gauge" style="
                --gauge-value:0;
                width:200px;
                height:200px;">

                <div class="ticks">
                    <div class="tithe" style="--gauge-tithe-tick:1;"></div>
                    <div class="tithe" style="--gauge-tithe-tick:2;"></div>
                    <div class="tithe" style="--gauge-tithe-tick:3;"></div>
                    <div class="tithe" style="--gauge-tithe-tick:4;"></div>
                    <div class="tithe" style="--gauge-tithe-tick:6;"></div>
                    <div class="tithe" style="--gauge-tithe-tick:7;"></div>
                    <div class="tithe" style="--gauge-tithe-tick:8;"></div>
                    <div class="tithe" style="--gauge-tithe-tick:9;"></div>
                    <div class="min"></div>
                    <div class="mid"></div>
                    <div class="max"></div>
                </div>
                <div class="tick-circle"></div>

                <div class="needle">
                    <div class="needle-head"></div>
                </div>
                <div class="labels">
                    <div class="value-label"></div>
          <code id="unig" style="position:relative;top:68%;font-weight:77;font-size:14px;color:navy;">grams</code>
                </div>
            </div>
      <div class="tab">
        <button class="tablinks" onclick="setingan(event, 'tare')">Tare</button>
        <button class="tablinks" onclick="setingan(event, 'calib')">Calibrate</button>
        <button class="tablinks" onclick="setingan(event, 'manu')">Tuning</button>
        <button class="tablinks" onclick="setingan(event, 'mode')">Mode</button>
        <button class="tablinks" onclick="setingan(event, 'etc')">Bonus</button>
        <button class="tablinks" onclick="setingan(event, 'noti')">Hint</button>
      </div>      
      <div id="tare" class="tabcontent">
        <label>Current Offset:</label> <b class="offsetnum"> </b>
        <p>Clear the scale. Remove anything on it. Are you Ready? Hit the button now.</p>
        <button type="button" id="setoffset" onclick="setup(this);">Set Offset Now!</button>
      </div>
      <div id="calib" class="tabcontent">
        <label>Current Scale/Calibration Factor:</label> <b class="scalenum"> </b>
        <p>Place a known weight on the loadcell. Next.. insert a known weight value, & hit the button.</p>
        <label>Known weight <small>(grams)</small>:</label> <input type="number" id="antim" min="1" max="1000" value="50"> <button type="button" id="setscale" onclick="setup(this);">Set Scale Now!</button>
      </div>
      <div id="manu" class="tabcontent">
        <label>Set Offset:</label> <input type="number" value="9999" class="offsetnum">
        <p><label>Set Scale:</label> <input type="number" step="0.05" value="99.99" class="scalenum"></p>
        <button type="button" id="setboth" onclick="setup(this);">Tweak Now!</button>
      </div>
      <div id="etc" class="tabcontent">
        <label>Font color:</label> <input type="color" id="fontcolor" value="#ff0000" oninput="bonus(this)">&nbsp; &nbsp; 
        &nbsp;<label>Font shadow:</label> <input type="color" id="fontshadow" value="#ff0000" oninput="bonus(this)">
        <p><label>Speed/Duration <small>(ms)</small>:</label> <input type="number" step="50" min="500" max="2000" value="777" id="speed" oninput="bonus(this)"></p>
        <label>Delay <small>(ms)</small>:</label> <input type="number" step="100" min="500" max="3000" value="1500" id="delay" oninput="bonus(this)">
      </div>
      <div id="noti" class="tabcontent">
        <label>Average Raw ADC Value:</label> <b id="adc"> </b>
        <p>All settings are saved on browser localStorage, so.. each browser have their own saved settings.</p>
        Settings will be cleared in a "private browsing" or "incognito" mode.
      </div>
      <div id="mode" class="tabcontent">
        <input type="radio" name="modecek" id="normal" onclick="setmode(this)"> <label for="normal">Normal</label> &nbsp; &nbsp; 
        <input type="radio" name="modecek" id="filler" onclick="setmode(this)"> <label for="filler">Filler</label><br><br>
        <div id="normalval" style="display:block;"><input type="checkbox" id="sgg" onchange="setmode(this)"> <label for="sgg">Show Gauge</label></div>
        <div id="thresholdval" style="display:none;"><i id="curthres"></i><br><br><label>Threshold <small>(Max 1000 grams)</small>:</label> 
        <input type="number" value="500" min="1" max="1000" id="maxthreshold"> <button type="button" id="setthreshold" onclick="setup(this);">Set Threshold Now!</button></div>
      </div>
    </div>
    <small>Maks beban = 1kg</small>   
    <script>
      const Storageprefix = "test1-";
      const scaleStorageitemname = Storageprefix + "scale";
      const offsetStorageitemname = Storageprefix + "offset";
      const durasiStorageitemname = Storageprefix + "durasi";
      const rehatStorageitemname = Storageprefix + "rehat";
      const colorStorageitemname = Storageprefix + "color";
      const shadowStorageitemname = Storageprefix + "shadow";
      const modeStorageitemname = Storageprefix + "mode";
      const thresholdStorageitemname = Storageprefix + "threshold";
      const showgaugeStorageitemname = Storageprefix + "showgauge";
      var durasi = 777; // animation counting duration
      var rehat = 1500; // delay for next animation counter
      var x = 33; // total steps
      var i = 0; // step
      var newres = 0; // new value
      var oldres = 0; // old value
      var margin = 0; // absolute value
      var step = 0; // step value
      var rawvalue; //raw reading
      var offset = "0";  // 
      var rawunit; // rawvalue - offset
      var unitval; // rawunit / scale
      var scale = "1"; // rawunit / bobot
      var fontkolor = "#FF1493", fontsado = "#FF0000";
      var mode = "normal";  // 
      var threshold = 500;  // 
      var showgauge = false;
      //get saved settings on localStorage
      function init() {
        (localStorage.getItem(offsetStorageitemname) == null) ? localStorage.setItem(offsetStorageitemname, offset) : offset = localStorage.getItem(offsetStorageitemname);
        document.getElementsByClassName("offsetnum")[0].innerHTML = offset;
        document.getElementsByClassName("offsetnum")[1].value = offset;
        (localStorage.getItem(scaleStorageitemname) == null) ? localStorage.setItem(scaleStorageitemname, scale) : scale = localStorage.getItem(scaleStorageitemname);
        document.getElementsByClassName("scalenum")[0].innerHTML = scale;
        document.getElementsByClassName("scalenum")[1].value = scale; 
        (localStorage.getItem(colorStorageitemname) == null) ? localStorage.setItem(colorStorageitemname, fontkolor) : fontkolor = localStorage.getItem(colorStorageitemname);
        document.getElementsByTagName("span")[0].style.color = fontkolor;
        document.getElementById("fontcolor").value = fontkolor;
        (localStorage.getItem(shadowStorageitemname) == null) ? localStorage.setItem(shadowStorageitemname, fontsado) : fontsado = localStorage.getItem(shadowStorageitemname);
        document.getElementsByTagName("span")[0].style.textShadow = "2px 2px " +fontsado+ ", -2px -2px " +fontsado+ ", 0 0 18px " + fontsado;
        document.getElementById("fontshadow").value = fontsado; 
        (localStorage.getItem(durasiStorageitemname) == null) ? localStorage.setItem(durasiStorageitemname, durasi) : durasi = localStorage.getItem(durasiStorageitemname);
        document.getElementById("speed").value = durasi;
        (localStorage.getItem(rehatStorageitemname) == null) ? localStorage.setItem(rehatStorageitemname, rehat) : rehat = localStorage.getItem(rehatStorageitemname);
        document.getElementById("delay").value = rehat;
        (localStorage.getItem(modeStorageitemname) == null) ? localStorage.setItem(modeStorageitemname, mode) : mode = localStorage.getItem(modeStorageitemname);
        document.getElementById(mode).checked = true;
        displaythreshold(mode);
        (localStorage.getItem(thresholdStorageitemname) == null) ? localStorage.setItem(thresholdStorageitemname, threshold) : threshold = localStorage.getItem(thresholdStorageitemname);
        document.getElementById("maxthreshold").value = threshold;
        document.getElementById("curthres").innerHTML = "Current Max. Threshold:<mark> " + threshold + " </mark>grams";
        (localStorage.getItem(showgaugeStorageitemname) == null) ? localStorage.setItem(showgaugeStorageitemname, showgauge) : showgauge = localStorage.getItem(showgaugeStorageitemname);
        document.getElementById("sgg").checked = (showgauge === "true") ? true : false;
        gaugeon(document.getElementById("sgg").checked);
        document.getElementsByClassName("tab")[0].style.marginTop = (showgauge === "true") ? "1vw" : "7vw";       
      }
      var intervalKonter = setInterval(Konter, durasi / x);
      function Konter() {
        i += 1;
        if(i == 1) {
          margin = Math.abs(newres.toFixed(2) - oldres);
          x = margin < 3 ? 12 : 33;
          step = margin / x;
          document.getElementsByTagName("span")[0].style.animationPlayState = "paused";
        }
        newres > oldres ? oldres += step : oldres -= step;
        if(oldres < 0) oldres = 0;
        //document.getElementById("bobot").innerHTML = oldres.toFixed(2);
        document.getElementById("bobot").innerHTML = (mode == "filler") ? (oldres/(threshold/100)).toFixed(1) : oldres.toFixed(2) ;
        document.getElementsByClassName("value-label")[0].innerHTML = oldres.toFixed(2);
        var jarum = Math.floor((oldres / 1000) * 100);
        document.getElementById("demoGauge").style.setProperty('--gauge-value', jarum);
        
        if(i == x) {
          oldres = newres;
          document.getElementsByTagName("span")[0].style.animationPlayState = "running";
          //rawvalue = 1000 * Math.random(); // simulate sensor weight value, replace w/ xhr
          //rawvalue = Math.floor(Math.random() * 999999);  // simulate sensor raw adc value
          fetch("hx").then(hasil => hasil.text()).then(bait => rawvalue = parseInt(bait));
          rawunit = rawvalue - offset;
          if(rawunit < 0) rawunit = 0;
          newres = rawunit / scale;
          document.getElementById("adc").innerHTML = rawvalue;
          
          clearInterval(intervalKonter);
          i = 0;
          setTimeout (function() {intervalKonter = setInterval(Konter, durasi / x);}, rehat);
        }
      }
      
      function gaugeon(ok) {
        if(ok === true){
          document.getElementById("bobot").style.display = "none";
          document.getElementsByTagName("code")[0].style.display = "none";
          document.getElementById("demoGauge").style.display = "block";
          document.getElementsByClassName("center")[0].style.top = "5px";
        }else{
          document.getElementById("bobot").style.display = "initial";
          document.getElementsByTagName("code")[0].style.display = "initial";
          document.getElementById("demoGauge").style.display = "none";
          document.getElementsByClassName("center")[0].style.top = "7vw";
        }
        localStorage.setItem(showgaugeStorageitemname, ok);
      }
      
      function displaythreshold(id) {
        if(id == "filler"){
          document.getElementById("normalval").style.display = "none";
          document.getElementById("thresholdval").style.display = "block";
          document.getElementsByTagName("code")[0].innerHTML = "%";
          document.getElementsByTagName("code")[0].style.fontSize = "5vw";
          gaugeon(false);
          document.getElementById("sgg").checked = false;
        }else{
          document.getElementById("normalval").style.display = "block";
          document.getElementById("thresholdval").style.display = "none";
          document.getElementsByTagName("code")[0].innerHTML = "grams";
          document.getElementsByTagName("code")[0].style.fontSize = "initial";
        }   
      }
      
      function setmode(radio) {
        mode = radio.id;
        if(mode === "sgg"){
          gaugeon(radio.checked);
        }else{
          displaythreshold(mode);
          localStorage.setItem(modeStorageitemname, mode);
        }
      }
      
      function setup(tombol) {
        if(tombol.id == "setthreshold"){
          threshold = document.getElementById("maxthreshold").value;
          localStorage.setItem(thresholdStorageitemname, threshold);
          document.getElementById("curthres").innerHTML = "Current Max. Threshold:<mark> " + threshold + " </mark>grams";
        }else{
          offset = document.getElementsByClassName("offsetnum")[1].value;
          scale = document.getElementsByClassName("scalenum")[1].value;
          if(tombol.id === "setoffset" || tombol.id === "setboth"){
            if(tombol.id === "setoffset") offset = rawvalue;
            localStorage.setItem(offsetStorageitemname, offset);
            document.getElementsByClassName("offsetnum")[0].innerHTML = offset;
            document.getElementsByClassName("offsetnum")[1].value = offset;
          }
          if(tombol.id === "setscale" || tombol.id === "setboth"){
            if(tombol.id === "setscale") scale = rawunit / document.getElementById("antim").value;
            localStorage.setItem(scaleStorageitemname, scale);
            document.getElementsByClassName("scalenum")[0].innerHTML = scale;
            document.getElementsByClassName("scalenum")[1].value = scale;
          }
        }
      }

      function setingan(evt, opsi) {
        var u, tabcontent, tablinks, bol;
        if(document.getElementById(opsi).style.display == "block") {
          bol = 1;  
          if(document.getElementById("bobot").style.display !== "none"){
            document.getElementsByClassName("tab")[0].style.marginTop = "7vw";
            document.getElementsByClassName("center")[0].style.top = "9vw";
          }else{
            document.getElementsByClassName("gauge")[0].style.minWidth = "550px";
            document.getElementsByClassName("gauge")[0].style.minHeight = "550px";
            document.getElementsByClassName("gauge")[0].style.fontSize = "70px";
            document.getElementById("unig").style.fontSize = "14px";
            document.getElementsByClassName("tab")[0].style.marginTop = "1vw";
          }
        }
        tabcontent = document.getElementsByClassName("tabcontent");
        for (u = 0; u < tabcontent.length; u++) {
          tabcontent[u].style.display = "none";
        }
        tablinks = document.getElementsByClassName("tablinks");
        for (u = 0; u < tablinks.length; u++) {
          tablinks[u].className = tablinks[u].className.replace(" active", "");
        }
        if(bol !== 1){
          if(document.getElementById("bobot").style.display !== "none"){
            document.getElementsByClassName("center")[0].style.top = "7vw";
            document.getElementsByClassName("tab")[0].style.marginTop = "1vw";
          }else{
            document.getElementsByClassName("gauge")[0].style.minWidth = "463px";
            document.getElementsByClassName("gauge")[0].style.minHeight = "463px";
            document.getElementsByClassName("gauge")[0].style.fontSize = "45px";
            document.getElementById("unig").style.fontSize = "10px";
            document.getElementsByClassName("tab")[0].style.marginTop = "1vw";
          }
          document.getElementById(opsi).style.display = "block";
          evt.currentTarget.className += " active";
        }
      }
            
      function bonus(selek) {
        switch(selek.id) {
          case "speed":
            durasi = selek.value;
            if(selek.value < 500) durasi = 500;
            if(selek.value > 2000) durasi = 2000;
            localStorage.setItem(durasiStorageitemname, durasi)
          break;
          case "delay":
            rehat = selek.value;
            if(selek.value < 500) rehat = 500;
            if(selek.value > 3000) rehat = 3000;
            localStorage.setItem(rehatStorageitemname, rehat)
          break;
          case "fontcolor":
            document.getElementsByTagName("span")[0].style.color = selek.value; 
            localStorage.setItem(colorStorageitemname, selek.value);
          break;
          case "fontshadow":
            document.getElementsByTagName("span")[0].style.textShadow = "2px 2px " +selek.value+ ", -2px -2px " +selek.value+ ", 0 0 18px " + selek.value;
            localStorage.setItem(shadowStorageitemname, selek.value);
          break;
        }
      }
    
    </script>
  </body>
</html>
)Ganteng_Permanen";

/* go to http://192.168.4.1 via web browser */
void handleRoot() {
  server.send_P(200, "text/html", HOME);
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  WiFi.softAP(ssid);
  pinMode(LOADCELL_DOUT_PIN, INPUT);
  pinMode(LOADCELL_SCK_PIN, OUTPUT);
  
  while(digitalRead(LOADCELL_DOUT_PIN));  // wait tobe ready
  //initial reading
  rawadc = ReadCount();

  server.on("/", handleRoot);
  server.on("/hx", []() {
    //300ms & up for next sensor reading 
    currentMillis = millis();
    if (currentMillis - startMillis >= 300) {
      rawadc = averageraw(4);
      digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
      startMillis = currentMillis;
    }
    delay(2);
    server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
    server.sendHeader("Pragma", "no-cache");
    server.sendHeader("Expires", "-1");
    server.send(200, "text/plain", String(rawadc)); // let the browser to calculate & measuring the weight
  });
  server.begin();
}

void loop() {
  server.handleClient();
}


///////////////////////////////////////////////
//                  ©2022                    //
// https://www.youtube.com/c/GantengPermanen //
//            USE @ YOUR OWN RISK            //
///////////////////////////////////////////////

Design a site like this with WordPress.com
Get started