ESP8266: Turn a $9 Body Scale into a Smart Scale – Part 1

Do you like this post? Writing posts, developing libraries and programming online font creators is actually hard work. I order most of my electronics from a Chinese website called Banggood. It is save and the items usually arrive in good quality. With every order you do there by following this link you are supporting the blog. Thank you!

In this project I will show you how you can build yourself a fancy Withings-like body scale. I divided the article into two parts: Part 1 describes the hardware hack and Part 2 the software. In this project I used a cheap scale I bought in the local super market for 9 Swiss Francs (which is currently about USD $9.-) and I am optimistic that other digital scales will work for you as well. This project was a lot of fun since I had to do reverse-engineering, soldering, programming and (optionally) even 3D modelling and printing. I hope you will enjoy it as much as did!

Splash Screen of the SmartScale
Splash Screen of the revamped SmartScale

Before we begin

Just a little word of warning: you might  be taking apart a working digital body scale. I cannot guarantee that your retrofitting will actually work and you might end up having just a broken body scale. Because of this I recommend that you are using a cheap or old digital scale rather than an expensive working one…
The other thing I’d like to mention: it took me many hours of my scarce free time to build and document this project. While I am not depending on income from this blog I still very much appreciate teleported beer (donation), you following one of my affiliate links or buying something from my shop. Thank you!
This is a write up of a project I started about a year ago. The project went back onto my “work-in-progress stack” and was waiting for a revival. Back then I also wrote a quick article about it.

What you will need

The components I used in my project set me back between USD $30-40 including the body scale. The following list should give you an idea what components you’ll need and what you should be looking for.

ImageDescriptionWhere to buy
Original Digital Body ScaleDigital Body Scale: It is very practical if you can build your smart scale project on an existing digital scale. From what I can tell modern digital scales all use the same kind of sensor (load cell) but I cannot guarantee itSwitzerland: Coop.
IKEA also has a low-cost scale: IKEA
Wemos D1 MiniThe ESP8266 module is the next important component. It is the brain and mouth of your smart scale. I recommend a small development module like the Wemos D1 Mini: it has enough pins and is smallBanggood
HX711 Amplifier ModuleThe HX711 module is a so called Load Cell Amplifier and will convert the weak analog signal from the weight sensor into bits and bytes the ESP8266 can understand.Banggood
LifePo4BatteriesPower Source - I picked a Lifepo4 AA-type battery since it provides the perfect voltage and has a considerable amount of capacity. The AA packaging (14500) also helps to buy or 3d print a good holder. If you don't own a 3d printer also buy a AA-cell holderAliExpress
SSD1306 0.96" OLED displayThese OLED displays are just wonderful: since the pixels glow by themselves the contrast is very high. You can choose between the 0.96 inch SSD1306 display or the 1.3 inch SH1106 one. The smaller one you can buy in the Squix Shop, the other you'll have to order from AliExpress or similar0.96" Oled Display:
1.3" Oled Display:

Besides these “core” components you will also require wires, solder and solder iron, screw drivers.

Understanding the Body Scale

So here is the plan: you open up your pretty body scale, remove everything you don’t need and keep the load cells (the components which measure the weight) in place. Then you connect the load cells to your HX711 amplifier module and connect the amplifier to your ESP8266. Then you’ll need to attach the OLED display to the ESP8266 as well and bring in some kind of power source with an on-off switch. Easy, isn’t it?

The mini PCB I re-used. Now I just had to connect the four wires to the HX711 (click to zoom)

For me the hardest part was to figure out how the load cells should be connected to the HX711. Luckily the load cells were attached to a mini PCB which in turn was soldered with only a few pins to the main board of the body scale. So I only had to figure out how to connect the four pins of the mini PCB to the HX711 module rather than figuring out how to connect the 12 wires of the load cells (3 wires and 4 load cells). I don’t know how your scale will look like. Maybe you will be lucky as well but it also could be that you have to do some hard core reverse engineering. Maybe the following pictures will help.

Load Cell Wiring (click to zoom)
Load Cell Wiring (click to zoom)

I suggest that you test the setup on a bread board before you take out the soldering iron. This way you can easily switch the wires until everything works. SparkFun has a very good introduction to load cells and the HX711: Sparkfun Load Cell Tutorial


Connecting the load cells and the HX711 Amp

Now that we (hopefully) have figured out how to use the existing load cells we have to connect them to the amplifier and the amplifier to the ESP8266.

The mini PCB that came with the digital scale connected to the HX711
A look to the other side of the boards: mini PCB connected to the HX711. I drew the labels V+, V-, S+ and S- on the mini PCB. Sometimes you see this naming scheme

Again, how you connect the load cells to the HX711 requires a bit of educated guessing. Read through the previous chapter, read the SparkFun tutorial about load cells, use the color codes of the wires. Then connect the HX711 to the ESP8266. The following image is just a zoomed in version of the complete wiring below:

Zoomed in sketch of the HX711 wiring. See full picture below (Click to zoom)
HX711 wiring. See full sketch below (Click to zoom)

Connecting the OLED display

If you are familiar with my WeatherStation project or the ESP8266 based plane spotter then the wiring of the OLED display should be straight forward. Just connect VCC on the display with 3V3 on the ESP8266, GND with GND, SDA on the display with D6 on the ESP and SCL with D7. In theory you can choose any D-pin for SDA and SCL, just make sure that they don’t have special functions. I think D8 is required for programming, others might be used for flash access. Also when you use the pins I suggest here you won’t have to change anything with my code. Please have a look at the complete sketch below for a graphical representation of the setup.

Connecting the power source

Now to my new favourite power source in the ESP8266 world: the LiFePo4 AA battery. After watching the excellent video of my fellow (Swiss) country man Andreas Spiess about ESP8266 battery sources I immediately ordered a few from AliExpress. The beauty is that their voltage range matches the 3V3 operation voltage of the ESP8266 perfectly. You don’t need any linear voltage regulator or boost up/down converter which just turn a considerable part of the battery’s capacity into heat. The discharge characteristic of the LiFePo4 also shows that it keeps providing a ESP8266 compatible voltage over a long time. For simplicity (and due to lack of necessary skills;-)) I decided to use a switch which was already built into the scale as on/off switch. An automatic power-saving circuit would have been nice but that would have complicated the project even more. In the original setup the built-in switch could be used to change between pounds and kilograms, now it will serve as the power switch.

The complete hardware setup

The following diagram shows you how to connect all the components together. As suggested earlier I recommend that you wire everything up on a breadboard first. In the next chapter we will to a first smoke test and also a quick calibration of the sensors. Let me know when you are ready;-).

Smart Scale Setup: HX711 - ESP8266 (Wemos D1 Mini) - SSD1306/ SH1106 - LiFePo4 battery
Smart Scale Setup: HX711 – ESP8266 (Wemos D1 Mini) – SSD1306/ SH1106 – LiFePo4 battery (click to zoom)

Smoke Test and Calibration

While I use the term “smoke test” quite often in my daily software engineering routine I only learned recently that the expression originates from electronics: if you turn the device on and there is no smoke coming from the circuit you passed the first phase.

Let’s do a bit more and use a little program to see if the load cells are responding. While the “real” smart scale project will be using the Platformio environment I decided to use the Arduino IDE for this smoke test. This way you will have a starting ground even if you don’t get adjusted to the Platformio IDE. OK? So let’s get started:

  1. If you haven’t done so, install the latest Arduino IDE. I am currently using 1.6.9
  2. Download this library as zip file: and add the zip to the Arduino IDE by Sketch > Include Library… > Add .ZIP library…
  3. For the testing of the OLED display also make sure you have my OLED library installed: Sketch > Include Library > Manage libraries… Search for “ESP8266 Oled Driver for SSD1306 display” by Daniel Eichhorn and Fabrice Weinberg. At the time of writing the last version is 3.2.6
  4. Compile and upload the following code:
    #include <HX711.h>
    // Scale Settings
    const int SCALE_DOUT_PIN = D2;
    const int SCALE_SCK_PIN = D3;
    void setup() {
      scale.set_scale();// <- set here calibration factor!!!
    void loop() {
      float weight = scale.get_units(1);
      Serial.println(String(weight, 2));
  5. Now check the serial monitor. If you see some non-static numbers then the HX711 is probably setup correctly.
  6. Now to calibration. Basically you have to use a known weight and adjust the values by a certain factor. I used my kitchen scale and two tetra packs of milk which weight 2.120kg. Put the same weight on the body scale, take the readings and use the result of the reading divided by the expected value as factor in set_scale(..). If that was confusing, check out the following pictures. Note: at a later stage you should repeat calibration with bigger weights than just two kilograms, e.g. your own weight. This should increase accuracy…
Uncalibrated output. You have to call the set_scale with the proper factor
Uncalibrated output. You have to call the set_scale with the proper factor (click to zoom)


Kitchen Scale with two tetra packs of 2.12kg as a calibration value
Kitchen Scale with two tetra packs of 2.12kg as a calibration value


Calibrated output. Now the serial monitor shows the correct values in kg
Calibrated output. Now the serial monitor shows the correct values in kg (click to zoom)

And now as a last step of the smoke test let’s use the OLED display to show the weight:

// change if your are using SSD1306
//#include <SSD1306Wire.h>
#include <SH1106Wire.h>
#include <OLEDDisplayFonts.h>
#include <HX711.h>

// Scale Settings
const int SCALE_DOUT_PIN = D2;
const int SCALE_SCK_PIN = D3;

// Display Settings
const int I2C_DISPLAY_ADDRESS = 0x3c;
const int SDA_PIN = D6;
const int SDC_PIN = D7;


// change if your are using SSD1306
SH1106Wire        display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);
//SSD1306Wire      display(I2C_DISPLAY_ADDRESS, SDA_PIN, SDC_PIN);

void setup() {
  scale.set_scale(-47941.0 / 2.122);

void loop() {
  String weight = String(scale.get_units(1), 2);
  display.drawString(0, 0, weight);
Simple weight output on the OLED display. Smoke test successful!
Simple weight output on the OLED display. Smoke test successful!

If you see now a frequently updated number on the OLED display then: congratulations! You have successfully destroyed a working body scale, removed a lot of parts and put new ones in and it works again! (Why did we do this again!?!)

Optional: 3D Printed Parts

There is a saying: when you have a hammer, everything looks like a nail. Well, my current hammer is a Printrbot Play and I am constantly looking for justifications why I spent (only) 400 bucks on a useless machine (my wife thinks so;-)). It so happens that I found two “nails” for 3D printing in this project: The AA battery holder and the foot mounts. The battery holder will accommodate the LiFePo4 battery, while the foot mounts became necessary since there wasn’t enough space beneath the scale for the battery. The battery holder is a wonderful parametric OpenScad project from Thingiverse: Since I only had a single cell I parametrized the print accordingly. The foot mounts I designed myself in OpenScad using the measurements from a digital caliper.

3D printed AA battery holder for a single cell from Thingiverse (click to zoom)
3D printed AA battery holder for a single cell from Thingiverse (click to zoom)


3D printed foot mount
3D printed foot mount


Foot Mount designed in OpenScad
Foot Mount designed in OpenScad


Hot glued battery holder, foot mount and IKEA gliders on the bottom of the scale
Hot glued battery holder, foot mount and IKEA gliders at the bottom of the scale

Summary and Outlook

This was part 1 of the SmartScale write-up which explained you the hardware setup. After working through this article you now have hopefully a working but still pretty dumb body scale. In part 2 I will guide you through the software setup. If you don’t want to miss it please sign up for my Newsletter here. You will only ever receive emails related to my project:

A few features that the SmartScale will have:

  • Over-the-Air Update: Just turn on the body scale in the bathroom and deploy a new version of the software
  • Blynk App Integration: see wonderful historical statistics and live data on your smart phone
  • Change between Kilograms and Pounds through the Blynk App
  • Energy saving mode: turn off the HX711 and the NodeMCU after 5min of inactivity. This will not be perfect but better than burning through the battery as quickly as possible;-)
  • Displaying the Weather Forecast, so that you know which clothes to pick after the shower
  • Do simple settings by using the load cell as input device
Over-The-Air Update
Live and historical data on your Smartphone by using Blynk
Weather ForeCast download from the internet
Choose the user by carefully applying the correct weight on the scale
Posted by squix78


  1. Observation, you could pull the weather icons from the Weatherunderground server rather than host them yourself. I think they do-not apply any read quotas.

    Did embedding the icons in flash prove to be too great an overhead?

    1. Hi David. If I’m not mistaken these icons are from a 3rd party (which reminds me to put their credits up). So I’d have to host it somewhere anyway. I currently also only use uncompressed bmp format and I doubt that any reasonable person still has them around for normal use;-). And then: downloading has the advantage to be easier to change compared to embedding in the firmware… But it was a design decision. Comparing pros and cons…

    1. Hi Stephen. I plan to upgrade the plane spotter project to the color screen, so yes, it’s definitely possible. Just a question of time:-)

  2. Hi,

    I have a working esp8266 weather but the small LCD only.
    im trying this one as i have the exact LCD lying around. i saw the “settings.h” where values need to be changed. (i.e. wundeground API, country, city, etc).. the only one that i was not sure and I did not see any explanation was the ThingSpeak value.

    May i ask what is the purpose of the Thingspeak value? i tried to view it but I think its a private channel.

    Anyway, i uploaded it on NodeMCU and when i inspect the Serial monitor, i can get to the part where it downloads the pictures.
    Here is the last bottom lines on the Serial.
    There is a line that says “connection failed.”…. Im guessing it has something to do with the Thingspeak..or maybe something else..

    …….(lots of downloding lines here…………..)
    Downloading and saving as /moon19.bmp
    Downloading and saving as /moon20.bmp
    Downloading and saving as /moon21.bmp
    Downloading and saving as /moon22.bmp
    connection failed
    connection failed
    connection failed
    connection failed

    Loading image ‘unknown.bmp’
    File not found
    Loading image ‘/mini/unknown.bmp’
    File not found
    Loading image ‘/mini/unknown.bmp’
    File not found
    Loading image ‘/mini/unknown.bmp’
    File not found
    Loading image ‘/moon0.bmp’
    File not foundconnection failed
    connection failed
    connection failed
    connection failed

    1. Hi Glenn,
      The purpose of the Thingspeak channel is to display (say) your own local temperature and humidity. So I have an ESP8266 and BME280 sensor running that reports every 10-mins to thingspeak the current temperature and humidity in my garden. Therefore I provide the keys for my channel and it gets reported on the weather display. Ideally there would be a software (compile time) switch to remove that option.

  3. Please ignore the comment below.
    I was able to solve it. Apparently, the wifimanager didn’t connect successfully to my router, so i had to manually connect and put the static SSID and password.

    So its working now, yey! i can see the pictures and the icons properly.

    im still dumbfounded with the Thingspeak channel in the settings.h.
    May i know if that is really needed?

    1. Hi Glenn, I’m a program newbie and met same message from serial port, but I struggled for long time but cant overcome this issue, do you mind give me some suggestion?


  4. Hi,
    Is there any chance regarding tutorial how to call bitmaps using WiFi connection?
    I want to prepare own set of icons but I don’t know how to use it in your script 🙁
    As well I have a question reagrding screen refreshing, as I see that is the issue when the time is updated and some pixels are not removed?
    Thanks in advance for help.

  5. Very impressive weather station, works great!
    If it could automatically update summer/winter-time, it would be absolutely perfect.
    Have fun with the beer 😉

  6. I was able to get this running, but wanted to mention a small issue I ran into. (Sounds like the same one Mike McRoberts references.) The bitmaps require more than 1M of SPIFFS, so if you were like me and had selected only 1M at compile time, you run out of space to download all of the bitmaps, and many of the moon-phase bitmaps will fail to download, or will be perhaps truncated or corrupted. I went back and changed to 4M (3M SPIFFS) in the IDE and was able to solve this. Still having a bit of overlay issues with the time updates, but as Daniel mentioned, the code may still need a little work.

    Thanks for all the effort on this…now to add some of my own tweaks!

  7. Hi Daniel,
    i tried to flash the script but i will receiving all the time the following error:
    In file included from esp8266-weather-station-color.ino:34:0:
    C:\Users\Jens\Documents\Arduino\libraries\esp8266-weather-station-color-master/WebResource.h:25:31: fatal error: ESP8266HTTPClient.h: No such file or directory
    compilation terminated.
    Fehler beim Kompilieren.
    I added the ESP8266HTTPClient-library to the Arduino 1.6.5 but there is still the same error.
    Do you have any idea what i can make that the script will runing?

  8. Unfortunately are no longer stocking the 2.2 Inch Serial TFT SPI Display ILI9341 display! Can it be obtained from another supplier? Or can an alternative be used?

    I would like a bigger screen for my PlaneSpotter project so that I can enclose everything in a case with the lcd screen acting as a box top : )

  9. Dani, excellent! Built this over the weekend (preparing to teach another IoT class this week) and almost worked flawlessly (2.4″ TFT + Wemos D1 Mini). Couldn’t get the WifiManager to connect, tried a few different things then finally went manual mode. The 199: timeClient.updateTime(); would sometimes hang, changed the .h to use “” instead; didn’t do a lot of troubleshooting, was more in quick-fix mode. Maybe later this month I’ll try incorporating Neptune’s daylight savings code back into this (thanks btw for the link to that). PS will try to get some pictures with the kids doing projects over the session the next two weeks. Regards, Mike

    1. Mike, you stated that you changed the .h to use “”. What is the path/filename to that .h file?

  10. Dani,

    I’ve been adding some of my own enhancements to your original code for several weeks now, and thought I’d share some of my changes in case anyone was interested. I’ve posted these on GitHub if you’re interested… .
    This version includes many enhancements to the displays (see the README on GitHub), along with Neptune’s enhancements for daylight savings time. The code could stand some clean-up, but otherwise seems to work well.

    Let me know what you think…I’ll post some photos of the displays when I get a chance.

    Keith Fowler

    1. Hi Keith

      You put some really nice things into the code! I knew that the WifiManager had this configuration UI feature but never got around to use it in my code. Now with your code I have a very nice example to use it;-). Thank you a lot for sharing! I just posted your fotos on Twitter and linked to your repository, I hope you don’t mind.

      I am working ATM on a 2.4″ display with touch. This would allow to switch screens or similar…


      1. Dani…I don’t mind at all, in fact I’m honored. One thing to note, which I pointed out in the README on the repo, is that I have added a few fields over the past few months that may (or may not) have made it into the Weather Station library for the Weather Underground functions. Not sure how exactly to go about getting those into the master. (You may even be able to spot these on some of the displays.) I did not put those library changes up on the repo.

        I’d also had my eyes on those touch-screens and had similar thoughts on using them to control the screen displays. I’m anxious to see what you end up doing with it. Your projects always give me more ideas to try ;).

    2. keith, can you ples tell me what i need to download in the the IDE program to set this up there are so many files i do not know what one i need ! thansk

      1. Andrew…yes, sorry for not making this more clear in the documentation. I’ve (mostly) just used libraries that others have contributed and were already referenced in Dani’s examples, but you’re right that the list has gotten relatively long and may take some digging to find all the sources. Give me some time today and I will add the links to the documentation on my Github repository.

      2. I have updated the README on my repository with info on the contributed libraries and links to make it easier to find these. Let me know if you have any other questions.

  11. Hey Dani and Keith, I just tried this out a few days ago and love it. Just wanted to confirm that when I tried to use Keiths’ version, it failed to compile due to the changes in the Weather_Station library. I would really like to try out this version if one of you could point me at the correct library.
    This was my first project with an esp8266 and I am really surprised at how powerful and easy it is to use.


    1. Kevin…yes, sorry, I knew that would bite someone. I really wanted to get the changes merged into Dani’s master library rather than start off on another branch. In the interim, I have uploaded the two changed library files for the Weather Underground components to a separate folder on the repo if you want to download those to (temporarily) replace the original ones in the Weather Station library. That should allow it to compile. Let me know if that doesn’t work for you. Hopefully I’ll figure out the right (permanent) solution to address the changes soon.


      1. Thanks for the update Keith,

        I got the new code and everything works great. Now I just have to figure out how to make it work with a bigger screen, maybe 7 inch. My eyes ain’t what they used to be. 🙂


        1. Glad you got it working Kevin…and I know what you mean about the old eyes! I’m right there with you. I’m torn between the compact size and being able to read all the data displayed without my glasses ;). Let me know if you find a bigger option that works well for a reasonable cost.

  12. Dani…just made a pull request on your repository to add some of the changes I had made to your Weather Underground library. Let me know if you have questions or issues.

  13. Dani, I just made another pull request for some new updates to the Weather Underground client library. These include changes to support some additional enhancements I have been working on recently that display weather alerts (as per the WU API call “/alerts”), as well as the addition of probability of precipitation (PoP). I have uploaded a new version to my repository on GitHub that shows these additional enhancements (see the README for further details), along with screenshots.

    As always, let me know if you have any questions or issues, and best wishes for the upcoming holidays!

  14. Hi Daniel. I don’t like the Ardunid IDE because of the lack of debugging with breakpoints. Therefore, I’ve just started with VisualGDB and JLink debugger and ESP8266. I have quite some difficulties.

    Do you have any experiences with VisualGDB?

    By the way: I am situated near Zurich and I like your projects! Great work!

  15. I have been having a lot of fun working through the examples with your weatherstation library. I bought your kit, which was an easy way to get started with the ESP8266.
    I am working through the WeatherStationDemoExtendedDST, for some reason updateData is not firing every 10 minutes. updateDHT is working fine, fires every minute.
    I think this is where the problem is, it isn’t setting readyForWeatherUpdate to true. However, it looks exactly the same as your other examples.
    if (readyForWeatherUpdate && ui.getUiState()->frameState == FIXED) {
    Thanks for any help.

  16. Figured it out. Apparently you can’t attach two events to a single ticker? I created two tickers, and now it works.
    tickerUpdateData.attach(UPDATE_INTERVAL_SECS, setReadyForWeatherUpdate);
    tickerUpdateSensor.attach(60, setReadyForDHTUpdate);

  17. I have problems getting it to run with Arduino 1.8.1, esp8266 2.3.0 board plugin and an SPI display. I have to slow down SPI to 250 kHz, otherwise I get all but pixel trash. But when I set OLEDDISPLAY_REDUCE_MEMORY I get a blank screen.

    Do you know of any problems with given setup? Can you recommend a good working combination of Arduino IDE, ESP plugin and SPI settings?

    1. I am a bit confused: which project are you referring to? The OLED Weather station or the color weather station which uses an TFT? Since you posted this in a Color Weather Station post I assume you are referring to the color code? But why then use the OLEDDISPLAY_REDUCE_MEMORY? Can you share a gist which shows your ino file?

      1. I’m sure, I posted that to “ESP8266: SSD1306 Oled Library Release”. 🙂

        Well, I’m just using your examples for the SSD1306 driver. Using a Wemos D1 mini R2 and “SSD1306Spi display(D0, D2, D8);”

        I had it working some weeke before. In the mean time I updated a lot of software, including IDE and board definitions.

        So, there are few choices left: the software combination I have is broken or D1 or display are broken.

        Can you or anyone else report that Wemos D1 mini R2, Arduino 1.8.1 and esp8266 2.3.0 are working with this SSD1306 library (unmodified)?

        Thank you!

        1. I’m still not sure, if my hardware or software combination is broken. But I finally got it all working. Key was reducing SPI speed. In SSD1306Spi.h we have a SPI.setClockDivider (SPI_CLOCK_DIV2), which means 8 MHz. It seems, the (just my?) display can’t handle that, I get mostly pixel garbage. If I reduce that to SPI_CLOCK_DIV64 (which means 250 kHz), it all works. I can even skip the yields() in SSD1306Spi.h’s display() routine. And I can get some speed back with replacing the SPI.transfer-loop for non-double-buffer cases with “SPI.writeBytes(buffer, sizeof(uint8_t) * DISPLAY_BUFFER_SIZE);”

  18. Thanks for making this template availble in the public domain. It has proven to be very valuable. As an improvemnet, would it be possible to have the NodeMCU pin assignment names on the PCB board, similar to the arduino one.

  19. I am having problems with the Weather Station. First screen (time) works well. Second screen says “N/A C”, Third scrren shows N/As, Fourth screen (temp, humid) works well. I have tried installing the latest github code and it doesnt solved the problem. Any tips?

  20. I have bought the Weather Station on Amazon. It came with a DHT11 in a board with a pull up resitor. I am following the pdf with instructions. When pluging this board, the figure at the pdf looks like inverted. My litthe dht board is (from left to right): data, vcc, gnd. It took me a while to figure out this. Also, by printing the read temp and humid values, I saw half of them come as nan. Any tip for improving this?

Leave a Reply