This tutorial shows how to interface ESP8266 NodeMCU development board (ESP12-E module) with LM35 analog temperature sensor and SSD1306 OLED display.
In this project the SSD1306 OLED display (128×64 pixel) is used to display environment temperature in degree Celsius, Kelvin and degree Fahrenheit.
Also, the 3 quantities of the temperature are printed on Arduino IDE serial monitor.
The SSD1306 OLED display used in this project is configured to work in I2C mode, some SSD1306 OLED boards may require a small hardware modifications (to select between SPI mode and I2C mode) such as soldering, placing jumpers …
To see how to interface ESP8266 NodeMCU with SSD1306 OLED display, visit the following post:
ESP8266 NodeMCU interfacing with SSD1306 OLED
About the LM35 sensor:
The LM35 temperature sensor is a three pin device (VCC, OUT and GND) with an output voltage linearly related to Centigrade temperature. Since the LM35 output varies with dependent to the temperature, we need an ADC (Analog-to-Digital Converter) module to measure this voltage. The NodeMCU microcontroller (ESP8266EX) has one ADC module with 10-bit resolution.
The LM35 output has linear +10mV/°C scale factor means the following:
If the output voltage = 10mV —> temperature = 1°C
If the output voltage = 100mV —> temperature = 10°C
If the output voltage = 200mV —> temperature = 20°C
If the output voltage = 370mV —> temperature = 37°C
and so on.
LM35 Futures (from datasheet):
- Calibrated Directly in ° Celsius (Centigrade)
- Linear + 10 mV/°C Scale Factor
- 0.5°C Ensured Accuracy (at +25°C)
- Rated for Full −55°C to +150°C Range
- Suitable for Remote Applications
- Low Cost Due to Wafer-Level Trimming
- Operates from 4 to 30 V
- Less than 60-μA Current Drain
- Low Self-Heating, 0.08°C in Still Air
- Nonlinearity Only ±¼°C Typical
- Low Impedance Output, 0.1 Ω for 1 mA Load
The ADC module converts analog data into digital data. The ESP8266EX MCU has a 10-bit ADC module with one analog channel. Negative and positive references of the ADC module are 0V (GND) and 1.0V respectively. That means a 0V is represented by 0 and 1.0V (or higher but we shouldn’t apply more than that) is represented by 1024.
LoLin version of the NodeMCU board analog input is A0 (or ADC0), it’s connected to the ESP8266EX microcontroller through voltage divider of 2 resistors (220k and 100k ohm) as shown in the image below (red circle).
With the built-in voltage divider, the NodeMCU analog channel supports inputs from 0 to 3.3V.
Also, using the LoLin NodeMCU we can supply the LM35 sensor with 5V that comes from pin 5V (or VUSB).
Hardware Required:
- ESP8266 NodeMCU development board
- SSD1306 OLED display with 128×64 pixel resolution
- LM35 temperature sensor —-> datasheet
- micro USB cable (for programming and powering the circuit)
- 5V source (optional)
- Breadboard
- Jumper wires
Interfacing NodeMCU with LM35 sensor circuit:
Project circuit schematic diagram is shown below.
The LM35 sensor has 3 pins (from left to right):
Pin 1 is power supply pin, connected to external 5V power source positive terminal (don’t forget to connect its negative terminal to any of the NodeMCU ground pins).
The NodeMCU LoLin V3 has a pin that provides 5V, it can be used to supply the LM35 sensor. Otherwise, connect it to any 3.3V pin (not recommended because voltage range is from 4V to 36V).
Pin 2: output pin, connected to pin A0 (ADC0),
Pin 3: GND (ground), connected to NodeMCU GND pin.
The SSD1306 OLED display is connected to the NodeMCU board as follows:
SSD1306 OLED GND goes to NodeMCU GND pin,
SSD1306 OLED VDD to NodeMCU 3V3,
SSD1306 OLED SDA pin (serial data) to NodeMCU pin D2 (GPIO4),
SSD1306 OLED SCK pin (serial clock) to NodeMCU pin D3 (GPIO0),
SSD1306 OLED RES pin (reset) to NodeMCU pin D1 (GPIO5).
The SSD1306 OLED display DC pin is connected to VDD (3.3V) which means I2C slave address of the device is 0x3D. If the DC pin is connected to ground (GND) then the I2C slave address becomes 0x3C.
Interfacing NodeMCU with LM35 sensor circuit:
The following Arduino code requires 2 libraries from Adafruit Industries:
The first library is a driver for the SSD1306 OLED display which can be installed from Arduino IDE library manager (Sketch —> Include Library —> Manage Libraries …, in the search box write “ssd1306” and install the one from Adafruit).
The second library is Adafruit graphics library which can be installed also from Arduino IDE library manager.
The previous 2 libraries can also be installed manually, download links are below:
Adafruit SSD1306 OLED driver —-> direct link
Adafruit graphics library —-> direct link
After the download, go to Arduino IDE —> Sketch —> Include Library —> Add .ZIP Library … and browse for the .zip file (previously downloaded).
The same thing for the other library file.
In the code there are total of 3 libraries, they’re included in the code as follows:
1 2 3 | #include <Wire.h> // include Arduino wire library (required for I2C devices) #include <Adafruit_GFX.h> // include Adafruit graphics library #include <Adafruit_SSD1306.h> // include Adafruit SSD1306 OLED display driver |
Definition of the SSD1306 OLED reset pin (RES) and initialization of its library are as shown below:
1 2 3 4 | // define SSD1306 OLED reset at NodeMCU D1 (GPIO5) #define OLED_RESET D1 // initialize Adafruit display library Adafruit_SSD1306 display(OLED_RESET); |
Reading analog voltage using ADC module gives a number between 0 and 1024 (10-bit resolution), 0V is represented by 0 and 3.3V is represented by 1024. Converting back the ADC digital value is easy, we can use the following equation:
Voltage (in milliVolts) = ADC_reading * 3300 / 1024
This voltage (in milliVolts) represents the temperature value in tenths degree Celsius (output value of “273” equals 27.3 °Celsius).
The temperature in tenths degree Fahrenheit = (tenth °Celsius) x 9/5 +320 (because: °F = °Cx9/5 + 32) and the temperature in tenths Kelvin = (tenth °Celsius) + 2732 (because: K = °C + 273.16).
To get the actual value of each quantity we’ve to divide it by 10. The line below shows an example for temperature in Kelvin:
1 | display.printf("%03u.%1u K", tKelvin / 10, tKelvin % 10); |
We get the first 3 digits by dividing the tenths value by 10, and the tenths number (number after the decimal point) of the actual temperature value is equal to the reminder of that division (tenths value % 10).
The resolution of this thermometer is about 0.3°C.
Full Arduino code:
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 | /************************************************************************************** ESP8266 NodeMCU with LM35 analog temperature sensor and SSD1306 OLED display. This is a free software with NO WARRANTY. http://simple-circuit.com/ ***************************************************************************************/ #include <Wire.h> // include Arduino wire library (required for I2C devices) #include <Adafruit_GFX.h> // include Adafruit graphics library #include <Adafruit_SSD1306.h> // include Adafruit SSD1306 OLED display driver // define SSD1306 OLED reset at NodeMCU D1 (GPIO5) #define OLED_RESET D1 // initialize Adafruit display library Adafruit_SSD1306 display(OLED_RESET); void setup() { Serial.begin(9600); // open serial port delay(1000); // wait a second // set I2C pins [SDA = GPIO4 (D2), SCL = GPIO0 (D3)], default clock is 100kHz Wire.begin(4, 0); // initialize the SSD1306 OLED display with I2C address = 0x3D display.begin(SSD1306_SWITCHCAPVCC, 0x3D); // clear the display buffer. display.clearDisplay(); display.setTextSize(1); // text size = 1 display.setTextColor(WHITE, BLACK); // set text color to white and black background display.setCursor(15, 0); // move cursor to position (15, 0) pixel display.print("LM35 TEMPERATURE:"); display.display(); // update the display display.setTextSize(2); // text size = 2 } int tKelvin, tCelsius, tFahrenheit; // main loop void loop() { // read analog voltage and convert it to tenths °C ( = millivolts) tCelsius = analogRead(A0) * 3300/1024; tKelvin = tCelsius + 2732; // convert tenths °C to tenths Kelvin tFahrenheit = tCelsius * 9/5 + 320 ; // convert tenths °C to tenths °Fahrenheit // print temperature in degree Celsius display.setCursor(23, 10); if (tCelsius >= 1000) { // if temperature >= 100.0 °C display.printf("%03u.%1u C", tCelsius / 10, tCelsius % 10); Serial.printf("Temperature = %03u.%1u°C\r\n", tCelsius / 10, tCelsius % 10); } else { display.printf(" %02u.%1u C", tCelsius / 10, tCelsius % 10); Serial.printf("Temperature = %02u.%1u°C\r\n", tCelsius / 10, tCelsius % 10); } // print temperature in degree Fahrenheit display.setCursor(23, 30); if (tFahrenheit >= 1000) { // if temperature >= 100.0 °F display.printf("%03u.%1u F", tFahrenheit / 10, tFahrenheit % 10); Serial.printf(" = %03u.%1u°F\r\n", tFahrenheit / 10, tFahrenheit % 10); } else { display.printf(" %02u.%1u F", tFahrenheit / 10, tFahrenheit % 10); Serial.printf(" = %2u.%1u°F\r\n", tFahrenheit / 10, tFahrenheit % 10); } // print temperature in Kelvin display.setCursor(23, 50); display.printf("%03u.%1u K", tKelvin / 10, tKelvin % 10); Serial.printf(" = %03u.%1u K\r\n\r\n", tKelvin / 10, tKelvin % 10); // print degree symbols ( ° ) display.drawCircle(88, 12, 2, WHITE); display.drawCircle(88, 32, 2, WHITE); // update the display display.display(); delay(1000); // wait a second } // end of code. |
The following picture shows a protoboard circuit of the project:
Arduino IDE serial monitor result:
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.