Table of Contents
Today, we are going to work with an extremely accurate temperature sensor, the TMP117 by Texas Instruments. This medical-grade digital sensor is capable of resolving temperatures to within ±0.1 °C. Adafruit has packaged this sensor in a low-cost breakout module that is easy to use with any microcontroller.
Introduction
Temperature measurement is one of the most common tasks in electronics projects. Whether you’re monitoring the environment, building a weather station, or controlling a heating system, you’ll need a reliable temperature sensor.
Today we’ll be looking at the TMP117, a high-accuracy digital temperature sensor from Texas Instruments. Adafruit produces a convenient module for this device, making it easy to connect to your favorite microcontroller.

We’ll start by learning about the TMP117 and the Adafruit module, then hook it up to an ESP32-S3 board and write some Arduino code. After that, we’ll compare it against several other popular temperature sensors. Finally, we’ll build a WiFi thermometer project using the TMP117, an ESP32-C6, and a small OLED display – and we’ll construct it without using any wires!
TMP117
The TMP117 is a digital I²C temperature sensor designed by Texas Instruments. It offers exceptional accuracy and stability, making it ideal for applications where precise temperature readings are critical. In fact, it meets the ASTM E1112 and ISO 80601-2-56 standards for electronic patient thermometers.
Key specifications:
- Accuracy: ±0.1 °C (from –20 °C to +50 °C)
- Measurement range: –55 °C to +150 °C
- Resolution: 0.0078 °C (16-bit output)
- Low power consumption
- I²C interface (up to 400 kHz)
- 4 selectable I²C addresses
- Programmable alert limits
- Operating voltage: 1.8 V to 5.5 V
The TMP117 also has programmable Temperature Alerts. You can set high and low temperature thresholds and generate an interrupt on the module’s INT pin.
We’ll be using a module from Adafruit in our experiments. The module includes voltage regulation and level-shifting circuitry, so you can safely use it with both 3.3V and 5V microcontrollers. It also features STEMMA QT / Qwiic connectors, allowing for solderless, plug-and-play connections with compatible boards.
Sparkfun also makes a similar module, and you can use that one in these experiments as well.
Using the TMP117
The TMP117 module is very easy to use. As an I²C device, hookup is simple, either via the module pins or using the Qwiic connector. Both Adafruit and Sparkfun have provided libraries that can be used with their modules.
TMP117 Pinout
Here is the pinout of the Adafruit TMP117 module:

The sensor is positioned on a thermal isolation island to reduce heat transfer from other board components. It has a default I²C address of 0x48, which can be changed using the ADDR pin.
TMP117 Hookup
We’ll be testing the sensor with a microcontroller; I’m using a Seeeduino XIAO ESP32-S3 board, but any microcontroller (3.3 or 5 volts) will work pretty well.
Thanks to the I²C interface, wiring is simple. You only need four wires: power, ground, clock (SCL), and data (SDA).
Here is the hookup for the Seeeduino XIAO:

Of course, if your microcontroller has a Qwiic connector, you may use that instead. If you do, be aware that on many microcontrollers, the Qwiic connector is on a secondary I²C bus. Check your documentation if you are unsure of this, or just use the wires.
TMP117 Code
To read from the sensor, we’ll use the Adafruit TMP117 library. You can install it from the Arduino IDE Library Manager by searching for “Adafruit TMP117“. You’ll also need the “Adafruit BusIO” and “Adafruit Unified Sensor” libraries; the IDE should offer to install them for you when you select the TMP117 library.
Once we have installed the library, we can test out the sensor using the “basic_test” sketch packaged with the Adafruit library.
|
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 |
/** * @file basic_test.ino * @author Bryan Siepert for Adafruit Industries * @brief Shows how to specify a * @date 2020-11-10 * * @copyright Copyright (c) 2020 * */ #include <Wire.h> #include <Adafruit_TMP117.h> #include <Adafruit_Sensor.h> Adafruit_TMP117 tmp117; void setup(void) { Serial.begin(115200); while (!Serial) delay(10); // will pause Zero, Leonardo, etc until serial console opens Serial.println("Adafruit TMP117 test!"); // Try to initialize! if (!tmp117.begin()) { Serial.println("Failed to find TMP117 chip"); while (1) { delay(10); } } Serial.println("TMP117 Found!"); } void loop() { sensors_event_t temp; // create an empty event to be filled tmp117.getEvent(&temp); //fill the empty event object with the current measurements Serial.print("Temperature "); Serial.print(temp.temperature);Serial.println(" degrees C"); Serial.println(""); delay(1000); } |
You’ll find this sketch under the Adafruit_TMP117 folder in the example sketches section of your Arduino IDE.
The sketch is pretty straightforward. It begins by including the required libraries, the Wire Library for I²C and two Adafruit libraries, the TMP117 and the Universal Sensor library.
In Setup(), we start the serial monitor and the TMP117.
In the Loop(), we create an event named “temp” and populate it with the current temperature measurement. This is then printed to the serial monitor. A one-second delay is applied, and then we restart the Loop().

Load the sketch to your microcontroller and observe through the serial monitor. You should see the temperature in Celsius, with two decimal places of accuracy.
Comparing TMP117 to Other Sensors
The TMP117 is undoubtedly easy to use, and the Adafruit (and SparkFun) module is well supported. But it is also more expensive than other temperature sensors, some of which also sense humidity or other environmental parameters.
To determine if it is worth the extra expense, I have compared its performance to that of several other popular sensors. They are as follows:

DHT11
- A very basic, low-cost digital temperature and humidity sensor.
- Temp Range: 0-50°C
- Temp Accuracy:
- Datasheet
DHT22
- The more capable sibling of the DHT11, with better range and accuracy.
- Temp Range: -40 to 80°C
- Temp Accuracy:
- Datasheet
MCP9808
- A high-accuracy I2C temperature sensor, a direct competitor to the TMP117.
- Temp Range: -40°C to +125°C
- Temp Accuracy: (Typical)
- Datasheet
AHT20
- A popular and affordable I2C temperature and humidity sensor.
- Temp Range: -40 to 85°C
- Temp Accuracy: (Typical)
- Datasheet
AM2320
- An I2C-based digital temperature and humidity sensor.
- Temp Range: -40 to +80°C
- Temp Accuracy:
- Datasheet
LM35
- A classic precision analog temperature sensor. Output voltage is linearly proportional to the Celsius temperature (10mV per degree C).
- Temp Range: -55 to 150°C
- Temp Accuracy: (Typical at 25°C)
- Datasheet
TMP36
- Another popular analog temperature sensor, with a 10 mV/°C scale factor and a 500 mV offset.
- Temp Range: -40°C to +125°C
- Temp Accuracy: (Typical)
- Datasheet
In the case of sensors that also sense humidity, we are only going to read temperature.
| Sensor | Type | Accuracy | Range (°C) | Notes |
|---|---|---|---|---|
| TMP117 | Digital (I²C) | ±0.1 °C | –55 to 150 | Very high accuracy |
| DHT11 | Digital (1-wire) | ±2 °C | 0 to 50 | Low cost, limited range |
| DHT22 (AM2302) | Digital (1-wire) | ±0.5 °C | –40 to 80 | Better accuracy, humidity sensor |
| MCP9808 | Digital (I²C) | ±0.25 °C | –40 to 125 | Stable and accurate |
| AHT20 | Digital (I²C) | ±0.3 °C | –40 to 85 | Humidity + temperature |
| AM2320 | Digital (I²C or 1-wire) | ±0.5 °C | –40 to 80 | Humidity + temperature |
| LM35 | Analog | ±0.5 °C | –55 to 150 | Output 10 mV/°C |
| TMP36 | Analog | ±1 °C | –40 to 125 | Output 10 mV/°C, offset |
The table above compares the temperature sensors.
Running the Test
The two analog sensors I’m using in the comparison require 5 volts. All of the other sensors are digital, either one-wire or I²C, and can operate on either 3.3 or 5 volts.
Because of the 5-volt requirement for the analog sensors, I decided to use an Arduino Uno R4 WiFi board. I made this choice because:
- The Uno R4 is a 5-volt logic device.
- It features a 12-bit Analog-to-Digital Converter for increased accuracy compared to earlier models.
- It has a 3.3-volt Qwiic connector on a secondary I²C channel.
I used the TMP117 and AHT20 with the Qwiic connectors; the other I²C sensors (MCP9808 and AM2320) used pins A4 and A5 for their I²C connection. The two “DHT” sensors utilized digital I/O pins (2 and 3), while the analog sensors employed analog inputs A0 and A1.

It made for quite a packed breadboard!
The results were somewhat surprising.
All of the digital sensors performed well, tracking the TMP117 very closely. The AHT20 (which also measures humidity) was exceptionally impressive.
The two analog sensors were off by several degrees, which could be a result of the 5-volt power supply. Using the Arduino AREF pin with an externally calibrated voltage may have resolved this, although if you are going to such extremes, it might make sense to use one of the digital sensors instead.
Bottom line: the TMP117 was the most accurate, but several of the less-expensive digital I²C sensors performed almost as well.

WiFi Thermometer
Let’s take our TMP117 and build a practical, standalone device – an ESP32-based WiFi thermometer that shows the reading on an OLED display and also broadcasts it on its own web server.
The design is pretty generic, and you could use almost any ESP32 module and OLED display along with the TMP117. However, I have selected a few components that pair exceptionally well with the TMP117, allowing us to create a compact, Wi-Fi 6-capable design that operates on a rechargeable battery.
For the ESP32, I have chosen the SparkFun ESP32-C6 Qwiic Board, a compact development platform built around Espressif’s ESP32-C6 microcontroller. It also includes a USB-C port for programming and power, a 2-pin JST connector with onboard LiPo battery charging circuitry (MCP73831), and Reset and Boot buttons.

The display I have selected is also from SparkFun, the SparkFun Qwiic OLED Display. This is a compact 0.91-inch, 128×32 pixel monochrome screen based on the familiar SSD1306 driver IC. It’s one of many Qwiic OLEDs from Sparkfun. This version features two vertical Qwiic connectors on the back, allowing for easy daisy-chaining with other Qwiic devices while keeping wiring neat inside enclosures. It communicates over I²C at address 0x3C and includes onboard 4.7 kΩ pull-up resistors (which can be disabled via jumpers if needed).
WiFi Thermometer Hookup
If you build the thermometer using the same components I used, then all you need for “hookup” is two short Qwiic cables. Both the TMP117 and the SparkFun Qwiic OLED Display have two Qwiic connectors to allow “daisy-chaining”, so the only hookup instructions are to connect everything to either in the most suitable fashion using the two Qwiic cables!

Otherwise, you can use any ESP32 board, along with an OLED display. The earlier demonstration with the Seeduino XIAO will show you the hookup for the TMP117. Just hook up the I2C OLED in the same fashion, paying attention not to reverse SDA and SCL.
WiFi Thermometer Code
This sketch reads the TMP117, displays it on the OLED, and also provides a web-based interface so you can view the temperature on your phone, tablet, or computer.
|
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 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 |
/* Precision ESP32 Thermometer esp32-precision-thermometer.ino Uses SparkFun ESP32-C6 Qwiic Pocket Development Board Uses Adafruit TMP117 Precision Temperature Sensor Uses SparkFun 128x32 Qwiic OLED Display DroneBot Workshop 2025 https://dronebotworkshop.com */ // Include Required Libraries #include <Wire.h> #include <WiFi.h> #include <WebServer.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #include <Adafruit_TMP117.h> // OLED display configuration #define SCREEN_WIDTH 128 #define SCREEN_HEIGHT 32 #define OLED_RESET -1 // No reset pin on Qwiic version #define SCREEN_ADDRESS 0x3C // Default I2C address for SparkFun 128x32 OLED // WiFi Access Point credentials const char* ssid = "ESP32_Temperature"; const char* password = "temp12345"; // Create objects Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); Adafruit_TMP117 tmp117; WebServer server(80); // Global temperature variables float currentTempC = 0.0; float currentTempF = 0.0; void setup() { // Start Serial Monitor Serial.begin(115200); delay(1000); Serial.println("TMP117 + OLED + Web Temperature Display"); // Initialize I2C Wire.begin(); // Initialize OLED display if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { Serial.println("SSD1306 allocation failed"); while (1); // Halt execution } // Clear the display display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(0, 0); display.println("Initializing..."); display.display(); // Initialize TMP117 temperature sensor if (!tmp117.begin()) { Serial.println("Failed to find TMP117 chip"); display.clearDisplay(); display.setCursor(0, 0); display.println("TMP117 Error!"); display.display(); while (1); // Halt execution } Serial.println("TMP117 found!"); // Setup WiFi Access Point WiFi.mode(WIFI_AP); WiFi.softAP(ssid, password); IPAddress IP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(IP); // Setup web server routes server.on("/", handleRoot); server.on("/temperature", handleTemperature); server.begin(); Serial.println("HTTP server started"); // Show startup message on OLED display.clearDisplay(); display.setTextSize(1); display.setCursor(0, 0); display.println("WiFi AP: ESP32_Temperature"); display.setCursor(0, 10); display.print("IP: "); display.println(IP); display.setCursor(0, 20); display.println("Web interface ready!"); display.display(); delay(3000); } void loop() { // Handle web server requests server.handleClient(); // Read temperature from TMP117 sensors_event_t temp; tmp117.getEvent(&temp); currentTempC = temp.temperature; currentTempF = (currentTempC * 9.0 / 5.0) + 32.0; // Print to serial monitor Serial.print("Temperature: "); Serial.print(currentTempC, 2); Serial.print("°C ("); Serial.print(currentTempF, 2); Serial.println("°F)"); // Clear the display display.clearDisplay(); // Display temperature in Celsius (large text) display.setTextSize(2); display.setCursor(0, 0); display.print(currentTempC, 2); display.print(" C"); // Display temperature in Fahrenheit (small text) display.setTextSize(1); display.setCursor(0, 24); display.print("("); display.print(currentTempF, 2); display.print(" F)"); // Update the display display.display(); // Wait before next reading delay(1000); } void handleRoot() { String html = R"rawliteral( <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ESP32 Temperature Monitor</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: 'Arial', sans-serif; background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%); color: white; min-height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; padding: 20px; } .container { background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border-radius: 20px; padding: 40px; text-align: center; box-shadow: 0 8px 32px rgba(31, 38, 135, 0.37); border: 1px solid rgba(255, 255, 255, 0.18); max-width: 500px; width: 100%; } h1 { font-size: 2.5em; margin-bottom: 30px; color: white; text-shadow: 2px 2px 4px rgba(0,0,0,0.3); } .temp-display { background: rgba(255, 255, 255, 0.9); color: #1e3c72; border-radius: 15px; padding: 30px; margin: 20px 0; box-shadow: 0 4px 15px rgba(0,0,0,0.1); } .temp-value { font-size: 4em; font-weight: bold; margin-bottom: 10px; text-shadow: none; } .temp-unit { font-size: 1.5em; opacity: 0.7; margin-bottom: 20px; } .temp-alt { font-size: 1.3em; color: #2a5298; font-weight: 500; } .refresh-btn { background: linear-gradient(45deg, #2a5298, #1e3c72); color: white; border: none; padding: 15px 30px; border-radius: 25px; font-size: 1.1em; font-weight: bold; cursor: pointer; margin-top: 20px; transition: all 0.3s ease; box-shadow: 0 4px 15px rgba(0,0,0,0.2); } .refresh-btn:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(0,0,0,0.3); } .refresh-btn:active { transform: translateY(0); } .footer { margin-top: 30px; font-size: 0.9em; opacity: 0.8; } @media (max-width: 600px) { .container { padding: 30px 20px; } h1 { font-size: 2em; } .temp-value { font-size: 3em; } } </style> </head> <body> <div class="container"> <h1>🌡️ Temperature Monitor</h1> <div class="temp-display"> <div class="temp-value" id="tempC">--.-</div> <div class="temp-unit">°Celsius</div> <div class="temp-alt" id="tempF">(--.- °Fahrenheit)</div> </div> <button class="refresh-btn" onclick="updateTemperature()"> 🔄 Refresh Temperature </button> <div class="footer"> ESP32-C6 Temperature Sensor<br> Updates automatically every 2 seconds </div> </div> <script> function updateTemperature() { fetch('/temperature') .then(response => response.json()) .then(data => { document.getElementById('tempC').textContent = data.celsius.toFixed(2); document.getElementById('tempF').textContent = '(' + data.fahrenheit.toFixed(2) + ' °Fahrenheit)'; }) .catch(error => { console.error('Error fetching temperature:', error); document.getElementById('tempC').textContent = 'Error'; document.getElementById('tempF').textContent = '(Connection Error)'; }); } // Update temperature on page load updateTemperature(); // Auto-refresh every 2 seconds setInterval(updateTemperature, 2000); </script> </body> </html> )rawliteral"; server.send(200, "text/html", html); } void handleTemperature() { String json = "{"; json += "\"celsius\":" + String(currentTempC, 2) + ","; json += "\"fahrenheit\":" + String(currentTempF, 2); json += "}"; server.send(200, "application/json", json); } |
The sketch may be a bit long, but it is not that hard to understand.
We start by including several libraries to handle the TMP117 and the OLED display. You may need to install some of these libraries using your Library Manager in the Arduino IDE.
We then configure the OLED display and create the Wi-Fi Access Point credentials. You can change these if it suits you better.
After that, we create objects for the sensor, display, and web server. We also make two variables for temperature, one in Celsius and one in Fahrenheit.
In Setup(), we initialize everything and create our Wi-Fi access point. We also define some web server routes.
In the Loop(), we handle the web server requests with the command server.handleClient(). The client requests will be handled by two functions, defined in Setup().
The rest of the Loop() involves reading the sensor, converting the reading to Fahrenheit, and printing to both the serial monitor and OLED display.
The handleRoot() function has all the HTML and CSS. You can personalize the display by editing it if you wish.
And the handleTemperature() function takes care of updating the display on the web page.
Using the WiFi Thermometer
Load the code to the ESP32-C6 and restart the microcontroller. You should see some Wi-Fi connection information displayed on the OLED, followed by the temperature in both scales.
To use the Wi-Fi feature, you will need to connect your device (phone, tablet, or computer) to the Access Point created by the ESP32-C6. The details are shown here:

Once you connect to the web page, you should see the following display:

You’ll note that the temperature on the OLED and the web page match each other, with a slight bit of latency on the web page.
You can use ytis as is, or modify it to become an IoT device. The ESP32-C6 is Wi-Fi-6 compatible, so it is ideal for IoT.
Conclusion
The TMP117 is one of the most precise and reliable temperature sensors available for hobby projects. With ±0.1 °C accuracy, it outperforms most common alternatives like the DHT11 or LM35. Thanks to boards like Adafruit’s Qwiic breakout, it’s also extremely easy to use with both 3.3 V and 5 V microcontrollers.
We’ve seen how to use it with an ESP32-S3, compared it against other sensors, and built a full WiFi thermometer with an ESP32-C6 and an OLED display. Whether you’re experimenting, teaching, or creating a practical project that requires precision temperature measurements, the TMP117 is an excellent sensor to add to your toolkit.
Parts List
Here are some components you might need to complete the experiments in this article. Please note that some of these links may be affiliate links, and the DroneBot Workshop may receive a commission on your purchases. This does not increase the cost to you and is a method of supporting this ad-free website.
TMP117 Adafruit
ESP32-C6 Sparkfun
Resources
Code Samples – All the code used in this article in one easy-to-use ZIP file!
Article PDF – A PDF version of this article in a ZIP file.



I’m having trouble with the libraries for the WiFi thermometer sketch. Which ones did you use for WiFi.h and WebServer.h ?