Off-The-Shelf Hacker: Feel Force with a Load Sensor

When developing and building physical computing gadgets we frequently have the need to measure things. One past article discussed reading temperatures with a thermocouple. The “dial caliper” story, a few weeks back talked about capturing lengths so we could accurately model a part in a CAD program. We also introduced the beam-style load cell and its basic operation, last April.
This time I’ll hack a load cell/amplifier combo onto a NodeMCU board, so I can do remote wireless force sensing. We can use this capability for building portable digital scales, sensing objects and providing actionable feedback from mechanisms. We’ll get the basics going using the NodeMCU board as an Arduino Nano today and stream the data over USB. Adding the wireless code and networking logistics for remote sensing will appear in an upcoming article.
Load Cell + NodeMCU = Tons of Fun

10 kg load cell
The previous load cell article did a decent job of describing what they are and how they work.
They’re typically a small rectangular block of aluminum with a cavity drilled cross-ways through the center, along with strain gauges (thin-film resistors) glued onto the top and bottom. The resistors are wired to an amplifier that analyzes their values and sends the measured force value to a NodeMCU or Arduino Nano board.
One cool thing about these load sensors is that you can buy them individually in 1, 10, 20, 50, 200 and 1000 kg sizes. My 10 kg version cost $8.50 from Amazon and included the amplifier board. There’s even a 5000 kg model that goes for about $124. You could measure an 11,000 lbs. pull with that monster.
All the load cells work with the same tiny HX711 amplifier board.

Load cell amplifier soldered above the NodeMCU board
The completed NodeMCU/amplifier package turned out to be pretty compact. I used 20-gauge solid-core wire to “float” the amplifier board above the NodeMCU board. A couple of pieces of Scotch tape on the bottom of the amp board prevented shorts. As the design evolves we’ll look at an enclosure and maybe some plugs and sockets for switching to different load cells.
Wiring the load cell and amp to the NodeMCU board required minimal soldering. Here are the connections.
Load cell to the HX711 amplifier board.
Load Cell | HX711 board |
---|---|
Red | E+ |
Black | E- |
White | A- |
Green | A+ |
Amplifier board to the NodeMCU microcontroller.
HX711 amplifier | NodeMCU board pin |
---|---|
GND | GND |
DT | D1 |
SCK | D2 |
VCC | Vin |
Running Arduino Code on an ESP8266
The NodeMCU board was a good choice in place of the Nano because it has a built-in ESP8266 Wi-Fi radio. I’m developing the load sensor to be easily portable and be able to be applied in a variety of non-notebook or Raspberry Pi-connected situations. The NodeMCU will connect to my network and stream the data over wifi.
NodeMCUs (ESP8266s) are easily programmed with the Arduino IDE using a USB cable. Just change the board type during compilation and uploading and you’re good to go. This first-cut at the code sends the data over USB and the results are viewed using the Arduino IDE serial terminal.
Getting a NodeMCU or Nano board talking to the HX711 amplifier board requires a library. I installed the HX711_ADC by Olav Kallhovd version 1.1.5 library in the Arduino IDE. Start the Arduino IDE, go to the Tools menu and select Manage Libraries. Search for “HX711” and hit the “Install” button when the above-mentioned library appears in the list. This will also put sample code files under the Files -> Examples menu. They’re listed as HX711_ADC.
For this project, I just pulled in the Read_1x_load_cell example and made a few modifications.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
//------------------------------------------------------------------------------------- // HX711_ADC.h // Arduino master library for HX711 24-Bit Analog-to-Digital Converter for Weigh Scales // Olav Kallhovd sept2017 // Tested with : HX711 asian module on channel A and YZC-133 3kg load cell // Tested with MCU : Arduino Nano, ESP8266 //------------------------------------------------------------------------------------- // This is an example sketch on how to use this library // Settling time (number of samples) and data filtering can be adjusted in the config.h file #include <HX711_ADC.h> #include <EEPROM.hh> //HX711 constructor (dout pin, sck pin): HX711_ADC LoadCell(5,4); const int eepromAdress = 0; long t; void setup() { float calValue; // calibration value // calValue = 696.0; // uncomment this if you want to set this value in the sketch calValue = 245.0; // uncomment this if you want to set this value in the sketch #if defined(ESP8266) //EEPROM.begin(512); // uncomment this if you use ESP8266 and want to fetch the value from eeprom #endif //EEPROM.get(eepromAdress, calValue); // uncomment this if you want to fetch the value from eeprom Serial.begin(115200); delay(10); Serial.println(); Serial.println("Starting..."); LoadCell.begin(); long stabilisingtime = 2000; // 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"); } } void loop() { //update() should be called at least as often as HX711 sample rate; >10Hz@10SPS, >80Hz@80SPS //use of delay in sketch will reduce effective sample rate (be carefull with use of delay() in the loop) LoadCell.update(); //get smoothed value from data set if (millis() > t + 250) { float i = LoadCell.getData(); Serial.print("Load_cell output val: "); Serial.print(i); Serial.print(", oz= "); Serial.println(i * 0.035274); t = millis(); } //receive from serial terminal if (Serial.available() > 0) { float i; char inByte = Serial.read(); if (inByte == 't') LoadCell.tareNoDelay(); } //check if last tare operation is complete if (LoadCell.getTareStatus() == true) { Serial.println("Tare complete"); } } |
In the first mod, I changed the HX711_ADC LoadCell(4,5); values to 5,4. I had inadvertently reversed the data out and s-clock connections from the amplifier board to the NodeMCU. Instead of hauling out the soldering iron and making things consistent with the example code, I just changed the pins in the code. It’s easy to fix certain hardware issues, in code. Be aware that this practice can quickly get out of hand if you aren’t careful and organized, particularly in anything near-production code.
Another change was to add a print statement toward the bottom that displays the measured force in ounces, in addition to kilograms.
Lastly, I changed the calibration value. The example code specified that the author used a 3 kg load cell for his application. I used a 10 kg cell. I arrived at my calibration value by trial and error. The next section quickly runs through the process.
Bending the Beam
To get accurate readings of force, the system needs to be calibrated. Calibrating the sensor with a known weight is pretty straightforward. For today’s discussion will assume the sensor value goes up linearly with the load. Of course, you’ll want to map the values out from the low-end (0) to the high-end (10 kg) to account for any variation, if you need very precise measurements.
For the test setup, I clamped one end of the sensor to my desk, so the drilled gap hung over the edge. I then used a piece of rope to hang a 5-pound exercise weight freely on the other end of the sensor, over the floor. Five pounds is about 2.27 kilograms or 2270 grams.

Load cell readings displayed on Arduino IDE serial terminal window.
My method was a bit brute-force. I changed the calibration value in the code, then compiled and re-uploaded the firmware to the NodeMCU until the right value appeared on the Arduino IDE serial terminal readout. Be sure to unhook the weight, each time you upload the firmware, otherwise, you’ll effectively “zero out” the sensor at 5 pounds. We want the sensor to read zero with no load. Also, if you get negative readings, just turn the sensor over and re-clamp. The strain gauges are arranged such that you get positive and negative readings. This capability might come in handy. Any ideas?
Anyway, calibration was a little tedious although it worked fine in the end. An upgrade might be to add a small potentiometer and some code to let you make the calibration adjustment by turning a knob or screwdriver.
Going Further
It was easy to read the force values right off of the Arduino IDE serial terminal. You could also send them in a Linux terminal with the cat command or even over to a Processing analog gauge program. We’ve talked about these topics in the past articles.
The next step for the project is to add Wi-Fi capability. In an upcoming story, I’ll show you the code and how we might use a remote load sensor connected to the network. Sending the force values to an MQTT broker might be useful as well.
Catch Dr. Torq’s Off-The-Shelf Hacker column, each Saturday, only on The New Stack! Contact him for consultation, speaking appearances and commissioned projects at doc@drtorq.com or 407-718-3274.