This project shows how to interface ESP8266 NodeMCU board (ESP-12E) with DS1621 digital temperature sensor where temperature values (in degrees Celsius and degrees Fahrenheit) are printed on 1602 LCD screen.
The 1602 LCD used in this project is connected to PCF8574 I2C I/O expander which allows it to communicate with NodeMCU board via I2C bus, this minimizes number of pins required and also may simplify the circuit.
The I2C bus uses only two pins: SDA (serial data) and SCL (serial clock).
This interfacing should also work with DFRobot I2C LCD displays.
About the DS1621 (from datasheet):
The DS1621 Digital Thermometer and Thermostat from Maxim Integrated provides 9-bit temperature readings, which indicate the temperature of the device. The thermal alarm output, TOUT, is active when the temperature of the device exceeds a user-defined temperature TH. The output remains active until the temperature drops below user defined temperature TL, allowing for any hysteresis necessary.
Benefits and features:
- Measures temperatures from – 55 °C to +125 °C in 0.5 °C increments. Fahrenheit equivalent is -67 °F to 257 °F in 0.9 °F increments.
- Temperature is read as a 9-Bit value (2-byte transfer).
- Converts temperature to digital word in less than 1 second.
- Thermostatic settings are user definable and nonvolatile.
- Power supply range (2.7V to 5.5V).
- Data is read from/written via a 2-wire serial interface (open drain I/O lines).
- Saves space.
- Temperature measurements require no external components.
- 8-pin DIP or SO package (208-mil) packages.
The I2C LCD display and the DS1621 sensor can be connected to the same I2C bus where the NodeMCU board microcontroller can talk with both devices (one at a time).
Hardware Required:
- ESP8266 NodeMCU board (LoLin)
- DS1621 temperature sensor —-> datasheet
- 1602 LCD screen
- PCF8574 I/O expander (or PCF8574A) —-> PCF8574 datasheet
- 3 x 10k ohm resistor
- 2 x 4.7k ohm resistor
- 330 ohm resistor
- 10k ohm variable resistor or potentiometer
- micro USB cable (for programming and powering the circuit)
- Breadboard
- Jumper wires
NodeMCU with I2C LCD and DS1621 sensor circuit:
Project circuit diagram is shown below.
The PCF8574 I/O expander is powered with 3.3V that comes from the NodeMCU board (PCF8574 VDD pin is connected to NodeMCU 3V3 pin and VSS is connected to GND).
SDA and SCL pins of the PCF8574 are respectively connected to NodeMCU pins D1 and D2.
A0, A1 and A2 pins of the PCF8574 are address select pins, they decide the I2C address of the chip. In this example each pin is connected to VDD (3.3V) through a 10k ohm resistor (the 10k resistor is optional, each pin can be connected directly to VDD).
The I2C address of the PCF8574 is: 0x20 | A2 A1 A0
In the circuit above the three pins A2, A1 and A0 are connected to VDD ( each one through 10k resistor). That means the I2C address is equal to 0x20 | 7 = 0x27.
If the PCF8574A is used instead of the PCF8574 then the I2C address is: 0x38 | 7 = 0x3F.
LCD data pins are connected to the PCF8574 where: RS, RW, E, D4, D5, D6 and D7 are respectively connected to P0, P1, P2, P4, P5, P6 and P7.
The 1602 LCD is powered with 5V from the NodeMCU board where its VDD pin is connected to NodeMCU pin VU and VSS is connected to GND.
The 1602 LCD operating voltage range is 4.5V – 5.5V and it may not work with 3.3V. The good thing is it accepts 3.3V on its I/O pins.
Other LCD pins are connected as follows:
VSS, RW, D0, D1, D2, D3 and K are connected to NodeMCU GND pin,
VEE to the 10k ohm variable resistor (or potentiometer) output,
A is connected to NodeMCU VU pin (5V) through 330 ohm resistor.
VEE pin is used to control the contrast of the LCD. A (anode) and K (cathode) are backlight LED pins.
The DS1621 is powered with 3.3V from the NodeMCU board, SDA and SCL pins are respectively connected to NodeMCU pins D1 and D2 (PCF8574 and DS1621 are connected to the same I2C bus).
Pins: A0, A1 and A2 are also address select pins, they are connected to GND, therefore DS1621 salve address is 0x48.
NodeMCU with I2C LCD and DS1621 sensor code:
To be able to compile project code with no error, a library for the I2C LCD display is required, download link is below:
LiquidCrystal_I2C Library —-> direct link
After the download, go to Arduino IDE —> Sketch —> Include Library —> Add .ZIP Library … and browse for library .zip file (previously downloaded).
Hints:
The I2C LCD library is initialized with address of 0x27, 2 rows and 16 columns:
1 2 | // configure LiquidCrystal_I2C library with 0x27 address, 16 columns and 2 rows LiquidCrystal_I2C lcd(0x27, 16, 2); |
Since the address pins of the DS1621 (A2, A1 and A0) are connected to NodeMCU GND, its I2C slave address is 0x48, it’s defined in the code as shown below:
1 2 3 | // define DS1621 I2C slave address (1001+A2+A1+A0) // A2, A1 & A0 connected to GND --> 1001000 = 0x48 #define DS1621_ADDRESS 0x48 |
A function named get_temperature() in the Arduino code is used to read raw temperature values from the DS1621 sensor and convert it to tenths degrees Celsius (output value of “135” equals 13.5 °Celsius).
This functions returns a signed integer number (2 bytes).
The temperature in tenths degrees Fahrenheit = (tenth °Celsius) x 9/5 +320 (because: °F = °Cx9/5 + 32).
To get the actual value of each quantity we’ve to divide it by 10. The line below shows an example for temperature in °C:
1 | lcd.printf(" %02u.%1u%cC", c_temp / 10, c_temp % 10, 223); |
We get the first 2 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 0.5°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 | /************************************************************************** * * Interfacing ESP8266 NodeMCU with DS1621 temperature sensor and 1602 I2C LCD. * This is a free software with NO WARRANTY. * http://simple-circuit.com/ * *************************************************************************/ #include <Wire.h> // include Wire library (required for I2C devices) #include <LiquidCrystal_I2C.h> // include I2C LCD library // configure LiquidCrystal_I2C library with 0x27 address, 16 columns and 2 rows LiquidCrystal_I2C lcd(0x27, 16, 2); // define DS1621 I2C slave address (1001+A2+A1+A0) // A2, A1 & A0 connected to GND --> 1001000 = 0x48 #define DS1621_ADDRESS 0x48 void setup(void) { lcd.begin(D1, D2); // initialize I2C LCD module (SDA = D1, SCL = D2) lcd.backlight(); // turn backlight ON lcd.setCursor(0, 0); // move cursor to column 0, row 0 [position (0, 0)] lcd.print("Temp ="); // initialize DS1621 sensor Wire.beginTransmission(DS1621_ADDRESS); // connect to DS1621 (send DS1621 address) Wire.write(0xAC); // send configuration register address (Access Config) Wire.write(0); // perform continuous conversion Wire.beginTransmission(DS1621_ADDRESS); // send repeated start condition Wire.write(0xEE); // send start temperature conversion command Wire.endTransmission(); // stop transmission and release the I2C bus } // main loop void loop() { delay(1000); // wait a second // get temperature in tenths °C int16_t c_temp = get_temperature(); // convert tenths °C to tenths °F int16_t f_temp = c_temp * 9/5 + 320 ; // print temperature in °C lcd.setCursor(6, 0); // move cursor to position (6, 0) if(c_temp < 0) { // if temperature < 0 °C c_temp = abs(c_temp); // absolute value lcd.printf("-%02u.%1u%cC", c_temp / 10, c_temp % 10, 223); } else { if (c_temp >= 1000) // if temperature >= 100.0 °C lcd.printf("%03u.%1u%cC", c_temp / 10, c_temp % 10, 223); else lcd.printf(" %02u.%1u%cC", c_temp / 10, c_temp % 10, 223); } // print temperature in °F lcd.setCursor(6, 1); // move cursor to position (6, 0) if(f_temp < 0) { // if temperature < 0 °F f_temp = abs(f_temp); // absolute value lcd.printf("-%02u.%1u%cF", f_temp / 10, f_temp % 10, 223); } else { if (f_temp >= 1000) // if temperature >= 100.0 °F lcd.printf("%03u.%1u%cF", f_temp / 10, f_temp % 10, 223); else lcd.printf(" %02u.%1u%cF", f_temp / 10, f_temp % 10, 223); } } int16_t get_temperature() { Wire.beginTransmission(DS1621_ADDRESS); // connect to DS1621 (send DS1621 address) Wire.write(0xAA); // read temperature command Wire.endTransmission(false); // send repeated start condition Wire.requestFrom(DS1621_ADDRESS, 2); // request 2 bytes from DS1621 and release I2C bus at end of reading uint8_t t_msb = Wire.read(); // read temperature MSB register uint8_t t_lsb = Wire.read(); // read temperature LSB register // calculate full temperature (raw value) int16_t raw_t = (int8_t)t_msb << 1 | t_lsb >> 7; // convert raw temperature value to tenths °C raw_t = raw_t * 10/2; return raw_t; } // end of code. |
Related Project:
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.
Dear can you make a project with LoRa and PIC CCS compiler please.?