What Smart Shelf has been created for
The data about goods' availability and shelf stocks is one of the most important indicators for a successful and well-structured business. The information about the number of products in the stores is essential to streamline purchasing and logistics processes. This information also helps create a better customer experience. Just ask yourself, which cafe would you prefer: the one that always has in place your favorite latte with coconut milk or another one which can offer only the latte with cow’s milk because the coconut milk ran out yesterday and the team has not received the new shipment. The question is not hard to plumb.
How does Smart Shelf work
This IoT project for smart management of the office space implies 4 load cell sensors to the NodeMCU ESP8266 using the HX711 load cell amplifier module. ESP8266 receives normalized values from HX711, after processing, these values with some other information (such as a shelf id, etc.) will be sent to Salesforce CRM. On the Salesforce side, we make calculations about free space usage and placement of the items on the shelf, after that, we display those calculations on a rounded gauge.
The last step in that chain is an email notification, sent when an item is almost completely or fully ran out.
Let's start with the Hardware part
Sensors:
Load Cells - 40kg. These load cells operate at minute voltage changes and they need an amplifier board to hook them up to a microcontroller like an Arduino

Pic.1 Measurements of the load cell
Amplifier:
HX711 - This Load Cell Amplifier is a small breakout board for the HX711 IC that allows you to easily read load cell weight measures. By connecting the amplifier to the microcontroller you can read the changes in the resistance of the load cell, and with some calibration, you’ll be able to get very accurate weight measurements. #include "HX711.h" library used to work with boards.

Pic.2 HX711
Specification:
- Differential input voltage: ±40mV(Full-scale differential input voltage is ± 40mV)
- Data accuracy: 24 bit (24 bit A / D converter chip.)
- Refresh frequency: 80 Hz
- Operating Voltage : 5V DC
- Operating current : <10 mA
- Size:38mm*21mm*10mm
Body:
3D printed body. The used material is ABS polymer

Pic.3 Dimensions of the main frame
Pic.4 Dimensions of the top cap
Pic.5 Dimensions of the board-holding console
Pic.6 Dimensions of the sensor holder
Power:
Power is provided via a USB-b cable and a 220v adaptor.
Data-transmission:
Data transmission is setup with usage of the WiFi module in the esp8266 board. Software libraries for that:
#include<ESP8266WiFi.h>
#include<ESP8266WiFiMulti.h>
#include<ESP8266HTTPClient.h>
Software part:
Embedded software
#include<Arduino.h>
#include<ESP8266WiFi.h>
#include<ESP8266WiFiMulti.h>
#include<ESP8266HTTPClient.h>
#include <HX711_ADC.h>
#include <EEPROM.h>
#include <cmath>
const String id = "000000001";
const int doutPin = 2; //mcu > HX711 dout pin, must be external interrupt capable D4
const int sckPin = 5; //mcu > HX711 sck pin D1
const float calValue = -22500.0;; // calibration value, correct this value using any etalon weight to get the etalon weight correct value on the screen!!!!
const int eepromAdress = 0;
float currentWeight;
float oldWeight = 0;
float temperature;
long t;
HX711_ADC LoadCell(doutPin, sckPin);
ESP8266WiFiMulti WiFiMulti;
void setup() {
Serial.begin(115200);
loadCellBegin();
wifiBegin();
}
void loop() {
scale();
}
void loadCellBegin() {
Serial.println("Starting...");
LoadCell.begin();
long stabilisingtime = 3000; // tare preciscion can be improved by adding a few seconds of stabilising time
LoadCell.start(stabilisingtime);
if (LoadCell.getTareTimeoutFlag()) {
Serial.println("Tare timeout, check MCU>HX711 wiring and pin designations");
}
else {
LoadCell.setCalFactor(calValue); // set calibration value (float)
Serial.println("Startup + tare is complete");
}
attachInterrupt(doutPin, ISR, FALLING);
}
void wifiBegin() {
for (uint8_t t = 4; t > 0; t--) {
Serial.printf("[SETUP] WAIT %d...\n", t);
Serial.flush();
delay(1000);
}
WiFi.mode(WIFI_STA);
// Login and Password From your WIFI AP
WiFiMulti.addAP("JBTOWER-0801", "JETBI.wifi-0801");
}
void ISR() {
LoadCell.update();
}
void scale() {
//get smoothed value from data set
if (millis() > t + 250) {
currentWeight = LoadCell.getData();
Serial.print("Load_cell output val: ");
Serial.print("currentWeight ");
Serial.println(currentWeight);
Serial.print("currentWeight*10 ");
Serial.println(round(currentWeight * 10));
Serial.print("oldWeight*10 ");
Serial.println(round(oldWeight * 10));
t = millis();
}
//if ((round(currentWeight 10) - round(oldWeight 10) > 1) || round(oldWeight 10) - round(currentWeight 10) > 1)
if ((round(currentWeight 10) - round(oldWeight 10) > 1) || round(oldWeight 10) - round(currentWeight 10) > 1) {
delay(3000);
//to avoid invalid scale
currentWeight = LoadCell.getData();
String body = "{\"weight\":\"" + String(currentWeight, 2) + "\",\"id\":\"" + id + "\",\"temperature\":\"" + String(temperature, 3) + "\"}";
doPost(body);
oldWeight = currentWeight;
}
}
void doPost(String body) {
if ((WiFiMulti.run() == WL_CONNECTED)) {
HTTPClient https;
Serial.print("[HTTPS] begin...\n");
//put your REST Service URL here and fingerprint (Info how to get fingerprint is under this topic).
if (https.begin("https://hrdevnew-jet-bi.cs89.force.com/smartshelf/services/apexrest/inbound", "67:67:D9:27:78:6C:A1:54:A4:DB:4D:0D:94:ED:D1:18:8B:BE:F3:76")) {
Serial.print("[HTTPS] POST...\n");
int httpCode = https.POST(body);
if (httpCode > 0) {
Serial.printf("[HTTPS] POST... code: %d\n", httpCode);
oldWeight = currentWeight;
} else {
Serial.printf("[HTTPS] POST... failed, error: %s\n", https.errorToString(httpCode).c_str());
}
https.end();
} else {
Serial.printf("[HTTPS] Unable to connect\n");
}
}
}
Inbound channel service:
Pic.7 Postman test request
Demo materials


Pic.8-9 Ready to use shelf in the kitchen
Summary
The first stage of the project has been brought to its logical end. There is a fully working prototype of the shelf which satisfies the objectives set.
In the nearest future, we plan to improve the security setting of the solution. Also, other body sizes and types will be implemented. Future development will be focused on making the shelf thinner (ideally 3-5 mm), adding the power unit for the autonomous work.
References
Link to controller documentation
Link to amplifier specification
Link to load cells