Nodemcu Based: 3d Printed Indoor Gauge Thermometer

About the project

Created an Arduino/NodeMCU based indoor dial thermometer

Project info

Difficulty: Easy

Platforms: ArduinoNodeMCURaspberry PiPCBWay

Estimated time: 6 hours

License: GNU Lesser General Public License version 3 or later (LGPL3+)

Items used in this project

Hardware components

TM1637 TM1637 x 1
DHT22 Temp/Humidity Sensor DHT22 Temp/Humidity Sensor x 1
NodeMCU v2-Lua based ESP8266 development kit NodeMCU v2-Lua based ESP8266 development kit x 1
28BYJ-48 Stepper Motor 28BYJ-48 Stepper Motor x 1
10K ohm Resistor 1/4 Watt 10K ohm Resistor 1/4 Watt x 1
3d printer 3d printer x 1

Software apps and online services

Arduino Arduino


Had some time this weekend and a desire to create something new and interesting, so went ahead and created an Arduino/NodeMCU based indoor dial thermometer. This device displays the temperature in degree centigrade on a D-Shaped Gauge as well as on a 7-Segment display.

In addition to that, it also saves the temperature and humidity readings in a MySQL DataBase hosted on a home based Raspberry Pi Server. The data is then displayed using the "Our Smart Home" app.

 Components Required

For this project we need:

  • 2 x TM1637 Display Modules
  • 1 x DHT22 or DHT11 Module
  • 1 x NodeMCU Microcontroller
  • 1 x 28BYJ-48 Stepper Motor with ULN2003 Driver Board
  • 1 x 10K Resistor
  • A 3D Printer
  • Copper Wire and Some Nuts & Bolts

Circuit Diagram

The circuit is very simple. Connect the ULN2003 driver board’s IN1, IN2, IN3 and IN4 to the NodeMCUs digital pins D0, D1, D2 and D3.

Then connect the OUT Pin of the DHT22 to the D5 Pin of NodeMCU.
After that connect the 2 x Display Modules to the microcontroller. We are going to use a Common Clock Pin D4 for both modules. Then connect the DIO of one of the modules to D6 (TEMP) and the other one to D7 (HUM) pins on the NodeMCU.
Important: Please avoid using the boot config pins D3, D4, D8 and the RTC pin D0 for the displays.

Now, on the D8 Pin we are going to connect the switch. This switch has a very important role in this circuit.
This switch acts as the 'home' or the 'starting point' of the stepper motor.
When the switch is open Pin D8 is connected to GND through the pull-down resistor and we read a LOW. When the switch is closed, Pin D8 connects to 3.3v pin of NodeMCU and we read a HIGH.
When the 'temperature changes' or the 'device boots up', the pointer starts moving 'counterclockwise'. As soon as the pointer hits the home position, Pin D8 reads HIGH and the logic moves the pointer 'clockwise' to display the temperature on the gauge as read by the DHT22 module.

The Code

The code starts by including all the necessary libraries.
Then it defines all the variables needed for setting up the WiFi connection.
Next, it assigns a static IP address to the ESP8266 (if you want to use DHCP then go ahead and delete these three lines from the code).

After that, it sets up the 2 x URLs that are needed for updating the heartbeat, temperature and humidity.

  1. String URLUpdateStatus = "";
  2. String URLUpdateTemp = "";

Before going ahead let's have a quick look at the 2 php files.
The "UpdateStutus.php" file uses an UPDATE query to update the timestamp of the device sending the request to the current epoch time and hence updating the heartbeat.

  1. <?PHP
  2. try {
  3. $Token = $_GET["Token"];
  4. $Location = $_GET["Location"];
  5. include "ConnectionStringArduino.php"; // Create connection
  6. $sql = 'Update `Status` SET `DateTime`=''.time().'',`State`='1' WHERE `Device`=''.$Location.'' AND `Token` = ''.$Token.'';';
  7. $result = $con->query( $sql ); if($result === FALSE) { die(mysqli_error());}
  8. mysqli_close($con);
  9. } catch (Exception $e) {}
  10. ?>

The "UpdateTemperature.php" uses an INSERT query to add a new row to the database with the current values of Temperature and Humidity. 

  1. <?PHP
  2. try {
  3. $Location = $_GET["Location"];
  4. $TEMP = $_GET["TEMP"];
  5. $HUM = $_GET["HUM"];
  6. include "ConnectionStringArduino.php"; // Create connection
  7. $sql = "INSERT INTO `Weather` (`DateTime`,`Temperature`,`Humidity`,`Location`) VALUES ('".time()."','".$TEMP."','".$HUM."','".$Location."');";
  8. $result = $con->query( $sql ); if($result === FALSE) { die(mysqli_error());}
  9. mysqli_close($con);
  10. } catch (Exception $e) {}
  11. ?>

This is what is written to the database and can be displayed using Google Charts, in my case, I am using the "Our Smart Home" app to display the data using php and JavaScript. Currently I am only displaying the data from the Study room and the Peg Box. To know more about my award winning "Peg Box" project please have a look at my electronics tutorial no. 34 "Peg Box with Temperature and Humidity Monitor using NodeMCU"  (

After that, I am defining all the variables required for reading and storing the value of temperature and humidity.

Next, I am defining all the variables and setting up any additional symbols required for displaying temperature and humidity on the TM1637 Display Module.

After that, I am defining the D8 pin of the NodeMCU as the reset switch pin. We will talk about this in detail in the following sections.

Next, I am setting up the Steps Per Revolution of the stepper motor as 2038 and then initializing the stepper library through pins D0 to D3.

  1. const int stepsPerRevolution = 2038; // Change this to fit the number of steps per revolution of your motor
  2. Stepper myStepper(stepsPerRevolution, D0, D2, D1, D3);// Initialize the stepper library on pins D0 through D3

One thing to note: since I need both clockwise and counterclockwise movements, I have to initialize the pins in the order shown on screen.

Then in the setup() section, first I am setting up the WiFi connection and then sending a heartbeat to the server. Then I am setting up the brightness of the 7-Segments to their max values followed by starting the dht module and finally setting the pin-mode of the switch to INPUT.

  1. void setup() {
  2. Serial.begin(115200); // Initialize the serial port
  3. /*********** Setup a WiFi connection ***********/
  4. if (WiFi.config(local_IP, gateway, subnet)) { Serial.println("Static IP Configured"); }
  5. else { Serial.println("Static IP Configuration Failed"); };
  6. WiFi.mode(WIFI_STA);
  7. WiFi.begin(WIFI_SSID, WIFI_PWD);
  9. while (WiFi.status() != WL_CONNECTED) {
  10. delay(500);
  11. Serial.print(".");
  12. };
  13. Serial.println("nWiFi connected");
  14. Serial.print("IP address: "); Serial.println(WiFi.localIP());
  16. SendIamAlive(); // Send the initial wakeup message to the server
  17. /**********************************************/
  18. display_TMP.setBrightness(7); // Set the display brightness (0-7)
  19. display_HUM.setBrightness(7); // Set the display brightness (0-7)
  20. dht.begin(); // Setup the DHT sensor
  22. pinMode(SWITCH, INPUT); // Declare the switch pin as input
  23. };

Now, in the loop() section I am reading the temperature using the Read_Temp() function and then sending the Temperature and Humidity values every 30 minutes and heartbeat every minute to the home server.

  1. void loop() {
  2. /** Read the temp and humidity info from ther sensor and display it on the 7-segmnet and Gauge **/
  3. Read_Temp();
  4. /** Sending Humidity and temperature every 30 minutes **/
  5. if((millis() - lastTime) > timerDelay){ Serial.println("Sending Temp and Humidity");SendTemperatureAndHumidity(); lastTime = millis(); };
  7. /** Sending I am alive message every minute **/
  8. if((millis() - StatusCounter) > 60000){ Serial.println("Sending Heartbeat"); SendIamAlive(); StatusCounter = millis(); };
  9. };

Next, you see the definition of the SendIamAlive() and SendTemperatureAndHumidity() functions which utilizes the WiFiConnect() function to send the values using the previously discussed URLs.

The Read_Temp() function reads the temperature and humidity and updates the 7-Segment displays and moves the pointer only if there is a change in the values.

The Move_Needle() function first sends the pointer to the home position using the Return_Home() function and then looks through and moves the pointer to the correct position until the stepCout is = STEPS.
The value of STEPS is calculated based on the "stepsPerRevolution" which we previously set it up as 2038.
So, 2038 / 2 (for half circle) = 1019
Now by dividing 1019 by 180 degrees we get the steps required to display each degree centigrade.
Now to display each degree centigrade we need 180/60 = 3 divisions.
Since our gauge starts from -10 and not 0 we also have to add the first 10 blocks which is (5.661 * 10 * 3) to our calculation.

  1. int STEPS = (5.661 * 3 * TEMP) + 169.833; // 5.661 (step resolution) * 3 (steps to display each °C) * TEMP + 169.833 (5.661 * 10 * 3) = since it starts from -10 and not 0)

That's it as easy as that.

3D Designing

Lets have a quick look at the 3D model of the project.
At the front, we have The Pointer, D-Shaped Dial, and the Temperature Scale on the dial.

Down at the bottom we have the Enclosure that will house the microcontroller and all other electronics components in it. The enclosure has a Lid to keep the electronic components safe and sound.

At the back, we have a pocket to hold the DHT22 Module, 3 x holes for the stepper motor, 2 x groves for the TM1637 Display Module and 2 x L-Shaped Brackets to hold the top Dial to the bottom Enclosure.

3D Printing


Once the 3D models were sorted, it was time for me to fire up my 3D printing oven and start printing these 3D models.

I used:
- 1.75mm Cold White PLA Filament, and printed the models with
- 0.2mm
- with 0% infill
- and with support.

As we all know, 3D printing is the process that uses computer-aided design or CAD, to create objects layer by layer.
3D printing is not a new technology, it's been there since the 1980's, when Charles W. Hull invented the process and created the first 3D-printed part. Since then, the field of 3D printing has grown exponentially and holds countless possibilities. The 3D printing process fascinates me a lot and I sometimes love to sit near my printer and watch these layers getting printed.

 The entire printing process took a little over 5 hours to complete and this is the final result.
Alright now, let's start gluing all the printed parts. I first superglued the L-Shaped Brackets to the dial followed by the pocket that will hold the DHT22 module. Then, I went ahead and screwed the bottom enclosure to the top section via the L-Shaped Brackets. 

Breadboard Demo

 Before adding the electronic bits to the 3D printed bits, let's do a quick test to make sure everything works as expected.
So, this 7-Segment display is displaying the temperature and the other one is displaying the humidity.
The needle is currently going round and round in circles as it has no idea where to stop. To stop the needle, and to send it the correct position on the gauge, I need to connect this red jumper cable connected to 3.3v to the D8 Pin of the NodeMCU.
Once I short the cable, the needle changes its direction and moves clockwise to display the temperature value read from the DHT22 module.

The temperature and humidity values are also sent to the 'Home Server' which are then displayed using the "Our Smart Home" app.


Using Acrylic colors, I painted all the 3D printed parts of the project.


Once the coloring is done, its now time for me to put all the electronic components together.
First I screwed the stepper motor to the back of the dial. Then, I gently pushed the DHT22 Module into its pocket at the back of the dial.
 Now the interesting bit. As per our previous discussion, we are going to use a copper wire as a switch that will move the pointer to its correct position. The copper wire will be fed through these two holes from the back and will loop through this small pipe like structure in the front. A small cut will be made on the top exposed side of the copper wire. 

Now on the pointer, we need to add a small piece of copper wire. When this copper bit touches the two copper wires on the pipe, it will complete the circuit and will send a HIGH to the system.

Next, I am hot gluing the two TM1637 7-Segment Display Modules to the back of the dial.
Once done, it's pretty much just a matter of soldering all the sensors to the NodeMCU as per our circuit diagram.

Final Demo

 So, this is how my final setup looks like.
Once the device is turned on, the pointer moves counterclockwise until it touches the copper wires that acts like a switch. Upon touching the wires the pointer moves clockwise to display the temperature value read from the DHT22 module on the D-Shaped Gauge.
The temperature and humidity values are also displayed using 7-Segment Displays.
The values are also sent over WiFi to a Raspberry Pi Home Server and stored in a MySQL database. Using google charts, you can display the data using various different graph options. In my case, I am using the "Our Smart Home" app to display the data using php and JavaScript.

Thanks for watching, please comment and let me know if there are any scopes of improvement.


Thanks again for checking my post. I hope it helps you.
If you want to support me subscribe to my YouTube Channel:

Video: Watch
Full Blog Post: Visit
Thermometer STLs: Download
Peg Box: Watch
How To Wire A Pushbutton: View
Stepper Motor Specs: View 

Support My Work

  • BTC:   1Hrr83W2zu2hmDcmYqZMhgPQ71oLj5b7v5
  • DOGE:  DEU2Wz3TK95119HMNZv2kpU7PkWbGNs9K3
  • ETH:   0xD64fb51C74E0206cB6702aB922C765c68B97dCD4
  • BAT:   0x9D9E77cA360b53cD89cc01dC37A5314C0113FFc3
  • LBC:   bZ8ANEJFsd2MNFfpoxBhtFNPboh7PmD7M2
  • COS:   bnb136ns6lfw4zs5hg4n85vdthaad7hq5m4gtkgf23 Memo: 572187879
  • BNB:   0xD64fb51C74E0206cB6702aB922C765c68B97dCD4
  • MATIC: 0xD64fb51C74E0206cB6702aB922C765c68B97dCD4


Photo of tarantula3


There were 1000+ sperms but I was the fastest one..


Leave your feedback...