This tutorial shows how to implement a simple temperature measurement station using ESP8266 NodeMCU board and DS18B20 digital temperature sensor.
The NodeMCU microcontroller (ESP8266EX) reads temperature value from the DS18B20 sensor and prints it (in °C) on Nokia 5110 LCD display (84×48 pixel resolution).
To see how to interface NodeMCU board with Nokia 5110 LCD, visit this post:
Interfacing ESP8266 NodeMCU with Nokia 5110 LCD
The DS18B20 temperature sensor is a 3-pin electronic component (like a simple transistor) from Maxim (formerly Dallas) which uses 1-wire protocol to communicate with master device (microprocessor, microcontroller ….). Each DS18B20 device has a unique 64-bit serial code, which allows multiple DS18B20s to function on the same 1-wire bus and controlled with one master device.
The DS18B20 sensor provides 9-bit to 12-bit Celsius temperature measurement resolution (programmable resolution).
Hardware Required:
- NodeMCU development board
- Nokia 5110 LCD module
- DS18B20 temperature sensor —-> datasheet
- 4.7k ohm resistor
- Micro USB cable (for programming and powering the whole circuit)
- Breadboard
- Jumper wires
NodeMCU with DS18B20 sensor and Nokia 5110 LCD circuit:
The image below shows project circuit diagram.
The DS18B20 sensor has 3 pins (from right to left): VCC (or VDD), data and GND where:
VCC (VDD): sensor power supply pin, connected to NodeMCU 3V3 pin,
data pin: connected to NodeMCU digital pin D5 and
GND: connected to NodeMCU GND pin.
A pull-up resistor of 4.7k ohm is required because the DS18B20 output is open drain.
The Nokia 5110 LCD which is shown in the circuit diagram has 8 pins (from left to right): RST (reset), CE (chip enable), DC (or D/C: data/command), Din (data in), Clk (clock), VCC (3.3V), BL (back light) and Gnd (ground).
The Nokia 5110 LCD is connected to the NodeMCU board as follows:
RST (reset) pin is connected to pin D0 (ESP8266EX GPIO16),
CE (chip enable) pin is connected to pin D1 (ESP8266EX GPIO5),
DC (data/command) pin is connected to pin D2 (ESP8266EX GPIO4),
DIN (data in) pin is connected to pin D3 (ESP8266EX GPIO0),
CLK (clock) pin is connected to pin D4 (ESP8266EX GPIO2),
VCC and BL are connected to pin 3V3,
GND is connected to pin GND.
NodeMCU with DS18B20 sensor and Nokia 5110 LCD code:
The following Arduino code requires 2 libraries from Adafruit Industries:
The first library is a driver for the Nokia 5110 LCD (PCD8544 controller), download link is below:
Adafruit Nokia 5110 LCD library
The 2nd library is Adafruit graphics library which can be downloaded from the following 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.
The previous 2 libraries are included in the main code as follows:
1 2 | #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_PCD8544.h> // include adafruit PCD8544 (Nokia 5110) library |
The DS18B20 sensor data pin is connected to NodeMCU pin D5, it’s defined in the code as:
1 | #define DS18B20_PIN D5 // DS18B20 data pin is connected to NodeMCU pin D5 (GPIO14) |
Functions used in the code:
bool ds18b20_start(): used to know if the DS18B20 sensor is correctly connected to the circuit, returns 1 if OK and 0 if error.
ds18b20_write_bit(bool value): writes (sends) 1 bit to the DS18B20 sensor, the bit is ‘value‘ which may be 1 or 0.
ds18b20_write_byte(byte value): writes 1 byte (8 bits) to the DS18B20 sensor, this function is based on the previous function. This function writes LSB first.
bool ds18b20_read_bit(void): reads 1 bit from the DS18B20 sensor, returns the read value (1 or 0).
byte ds18b20_read_byte(void): reads 1 byte from the DS18B20 sensor, this function is based on the previous function. This function reads LSB first.
bool ds18b20_read(int *raw_temp_value): reads the temperature raw data which is 16-bit long (two 8-bit registers), the data is stored in the variable raw_temp_value, returns 1 if OK and 0 if error.
The value of the temperature in degree Celsius is equal to the raw value divided by 16 (in case of 12-bit resolution). The default resolution of the DS18B20 is 12 bits ( ==> thermometer resolution = 0.0625°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 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 | /************************************************************************** * * Interfacing ESP8266 NodeMCU with Nokia 5110 LCD and DS18B20 digital * temperature sensor. * This is a free software with NO WARRANTY. * http://simple-circuit.com/ * *************************************************************************/ #include <Adafruit_GFX.h> // Core graphics library #include <Adafruit_PCD8544.h> // include adafruit PCD8544 (Nokia 5110) library // Nokia 5110 LCD module connections (CLK, DIN, D/C, CS, RST) Adafruit_PCD8544 display = Adafruit_PCD8544(D4, D3, D2, D1, D0); #define DS18B20_PIN D5 // DS18B20 data pin is connected to NodeMCU pin D5 (GPIO14) void setup(void) { // initialize the display display.begin(); // you can change the contrast around to adapt the display // for the best viewing! display.setContrast(50); display.clearDisplay(); // clear the screen and buffer display.display(); display.setTextSize(1); display.setTextColor(BLACK, WHITE); display.setCursor(15, 4); display.print("NODEMCU +"); display.setCursor(0, 14); display.print("DS18B20 SENSOR"); display.setCursor(7, 27); display.print("TEMPERATURE:"); display.display(); } // main loop void loop() { display.setCursor(9, 37); int raw_temp; if( ds18b20_read(&raw_temp) ) { if(raw_temp & 0x8000) { // if the temperature is negative raw_temp = abs(raw_temp); // absolute value display.printf("-%02u.%04u C", (raw_temp/16) % 100, (raw_temp & 0x0F) * 625); } else { // otherwise (temperature >= 0) if (raw_temp/16 >= 100) // if temperature >= 100 °C display.printf("%03u.%04u C", raw_temp/16, (raw_temp & 0x0F) * 625); else // otherwise ( 0 <= temperature < 100) display.printf(" %02u.%04u C", raw_temp/16, (raw_temp & 0x0F) * 625); } display.drawRect(59, 37, 3, 3, BLACK); // print degree symbol ( ° ) display.display(); } else { display.print(" Error! "); display.display(); } delay(1000); // wait a second } bool ds18b20_start() { bool ret = 0; digitalWrite(DS18B20_PIN, LOW); // send reset pulse to the DS18B20 sensor pinMode(DS18B20_PIN, OUTPUT); delayMicroseconds(500); // wait 500 us pinMode(DS18B20_PIN, INPUT); delayMicroseconds(100); // wait to read the DS18B20 sensor response if (!digitalRead(DS18B20_PIN)) { ret = 1; // DS18B20 sensor is present delayMicroseconds(400); // wait 400 us } return(ret); } void ds18b20_write_bit(bool value) { digitalWrite(DS18B20_PIN, LOW); pinMode(DS18B20_PIN, OUTPUT); delayMicroseconds(2); digitalWrite(DS18B20_PIN, value); delayMicroseconds(80); pinMode(DS18B20_PIN, INPUT); delayMicroseconds(2); } void ds18b20_write_byte(byte value) { byte i; for(i = 0; i < 8; i++) ds18b20_write_bit(bitRead(value, i)); } bool ds18b20_read_bit(void) { bool value; digitalWrite(DS18B20_PIN, LOW); pinMode(DS18B20_PIN, OUTPUT); delayMicroseconds(2); pinMode(DS18B20_PIN, INPUT); delayMicroseconds(5); value = digitalRead(DS18B20_PIN); delayMicroseconds(100); return value; } byte ds18b20_read_byte(void) { byte i, value; for(i = 0; i < 8; i++) bitWrite(value, i, ds18b20_read_bit()); return value; } bool ds18b20_read(int *raw_temp_value) { if (!ds18b20_start()) // send start pulse return(0); ds18b20_write_byte(0xCC); // send skip ROM command ds18b20_write_byte(0x44); // send start conversion command while(ds18b20_read_byte() == 0); // wait for conversion complete if (!ds18b20_start()) // send start pulse return(0); // return 0 if error ds18b20_write_byte(0xCC); // send skip ROM command ds18b20_write_byte(0xBE); // send read command *raw_temp_value = ds18b20_read_byte(); // read temperature LSB byte and store it on raw_temp_value LSB byte *raw_temp_value |= (unsigned int)(ds18b20_read_byte() << 8); // read temperature MSB byte and store it on raw_temp_value MSB byte return(1); // OK --> return 1 } // end of code. |
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.