This Arduino project shows how to build a simple temperature measurement station with DS1631 digital temperature sensor where temperature values (in degrees Celsius and degrees Fahrenheit) are printed on 1602 LCD screen.
About the DS1631 Temperature Sensor (from datasheet):
The DS1631 digital thermometer and thermostat by Analog Devices (Maxim Integrated) provide 9, 10, 11, or 12-bit temperature readings over a -55 °C to +12 °C range. The DS1631 thermometer accuracy is ±0.5 °C from 0 °C to +70 °C with 3.0V ≤ VDD ≤ 5.5V. The thermostat on DS1631 provides custom hysteresis with user-defined trip points (TH and TL). The TH and TL registers and thermometer configuration settings are stored in NV EEPROM so they can be programmed prior to installation.
Benefits and features:
- Operating temperature range: -55 °C to +125 °C (-67 °F to +257 °F).
- ±0.5 °C Accuracy over 0 °C to +70 °C range.
- User-Selectable output resolution from 9 bits to 12 bits.
- Reduce cost with no external components.
- Up to eight devices can operate on a 2-wire bus.
- Flexible and nonvolatile user-defined thermostatic modes with custom hysteresis.
- Available in 8-Pin μSOP, SO and DIP packages.
Hardware Required:
- Arduino UNO board —> Board details —> ATmega328P datasheet
- 1602 LCD screen
- DS1631 temperature sensor —-> datasheet
- 2 x 4.7k ohm resistor
- 330 ohm resistor
- 10k ohm variable resistor or potentiometer
- Breadboard
- Jumper wires
Arduino with DS1631 Temperature Sensor and 1602 LCD Circuit:
Project circuit diagram is shown below.
The 1602 LCD screen (2 rows and 16 columns) is used to display temperature values in degrees Celsius and degrees Fahrenheit where:
RS —> Arduino digital pin 2
E —> Arduino digital pin 3
D4 —> Arduino digital pin 4
D5 —> Arduino digital pin 5
D6 —> Arduino digital pin 6
D7 —> Arduino digital pin 7
VSS, RW, D0, D1, D2, D3 and K are connected to Arduino GND,
VEE to the 10k ohm variable resistor (or potentiometer) output,
VDD to Arduino 5V and A to Arduino 5V through 330 ohm resistor.
VEE pin is used to control the contrast of the LCD. A (anode) and K (cathode) are the back light LED pins.
The DS1631 temperature sensor SDA (serial data) and SCL (serial clock) pins are respectively connected to Arduino A4 and A5 pins (ATmega328P hardware I2C module pins). The DS1631 is supplied with 5V from the Arduino board.
The three pins: A0, A1 and A2 are slave address select pins which are connected to ground, therefore the DS1631 takes an address of 0x48 (1001+A2+A1+A0).
Arduino with DS1631 Temperature Sensor and 1602 LCD Code:
Hints:
Since the address pins of the DS1631 (A2, A1 and A0) are connected to Arduino GND, its I2C slave address is 0x48 which is defined in the code as shown below:
1 2 3 | // define DS1631 I2C slave address (1001+A2+A1+A0) // A2, A1 & A0 connected to GND --> 1001000 = 0x48 #define DS1631_ADDRESS 0x48 |
In the Arduino code below there is a function named ds1631_temperature(), it is used to read temperature values from the DS1631 sensor.
The previous function returns a signed 2-byte number which is actual temperature value (in °C) multiplied by 16 (why 16? —> because we’re working with 12-bit resolution).
For example if the returned value equals to 209 means actual temperature is equal to 209/16 = 13.0625 °C.
To get the value of temperature in degrees Fahrenheit (°F), I used the function below:
1 | int32_t f_temp = (int32_t)c_temp * 90/5 + 5120; // 5120 = 32 x 16 x 10 |
This function is just from the common one: °F = °C x 9/5 + 32.
Since the temperature in °C is multiplied by 16 the 32 also needs to be multiplied by 16.
To get the °F temperature with no floating number, I multiplied every thing by 10.
This function gives the actual value of the temperature in °F multiplied by 160 (actual °F = f_temp/160).
Since the DS1631 is used with 12-bit resolution, we get the temperature in °C as shown below (example):
1 | sprintf(c_buffer, " %02u.%04u%cC", c_temp/16, (c_temp & 0x0F) * 625, 223); |
Again, why 16 and 625? —> Because we are working with 12-bit resolution (increment step = 0.0625).
The resolution of this thermometer is 0.0625°C (0.1125°F).
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 Arduino with DS1631 digital temperature sensor. * Temperature values are printed on 16x2 LCD screen. * This is a free software with NO WARRANTY. * https://simple-circuit.com/ * ***********************************************************************/ #include <Wire.h> // include Arduino Wire library (required for I2C devices) #include <LiquidCrystal.h> // include Arduino LCD library // LCD module connections (RS, E, D4, D5, D6, D7) LiquidCrystal lcd(2, 3, 4, 5, 6, 7); // define DS1631 I2C slave address (1001+A2+A1+A0) // A2, A1 & A0 connected to GND --> 1001000 = 0x48 #define DS1631_ADDRESS 0x48 void setup(void) { lcd.begin(16, 2); // set up the LCD's number of columns and rows lcd.setCursor(0, 0); // move cursor to column 0, row 0 [position (0, 0)] lcd.print("Temp ="); Wire.begin(); // join i2c bus // initialize DS1631 sensor Wire.beginTransmission(DS1631_ADDRESS); // connect to DS1631 (send DS1631 address) Wire.write(0xAC); // send configuration register address (Access Config) Wire.write(0x0C); // perform continuous conversion with 12-bit resolution Wire.beginTransmission(DS1631_ADDRESS); // send repeated start condition Wire.write(0x51); // send start temperature conversion command Wire.endTransmission(); // stop transmission and release the I2C bus } // variables char c_buffer[11], f_buffer[11]; // main loop void loop() { delay(1000); // wait a second // get temperature in °C ( actual temperature in °C = c_temp/16) int16_t c_temp = ds1631_temperature(); // calculate temperature in °F (actual temperature in °F = f_temp/160) // °F = °C x 9/5 + 32 int32_t f_temp = (int32_t)c_temp * 90/5 + 5120; // 5120 = 32 x 16 x 10 if(c_temp < 0) { // if temperature < 0 °C c_temp = abs(c_temp); // absolute value sprintf(c_buffer, "-%02u.%04u%cC", c_temp/16, (c_temp & 0x0F) * 625, 223); } else { if (c_temp/16 >= 100) // if temperature >= 100.0 °C sprintf(c_buffer, "%03u.%04u%cC", c_temp/16, (c_temp & 0x0F) * 625, 223); else sprintf(c_buffer, " %02u.%04u%cC", c_temp/16, (c_temp & 0x0F) * 625, 223); } if(f_temp < 0) { // if temperature < 0 °F f_temp = abs(f_temp); // absolute value sprintf(f_buffer, "-%02u.%04u%cF", (uint16_t)f_temp/160, (uint16_t)(f_temp*1000/16 % 10000), 223); } else { if (f_temp/160 >= 100) // if temperature >= 100.0 °F sprintf(f_buffer, "%03u.%04u%cF", (uint16_t)f_temp/160, (uint16_t)(f_temp*1000/16 % 10000), 223); else sprintf(f_buffer, " %02u.%04u%cF", (uint16_t)f_temp/160, (uint16_t)(f_temp*1000/16 % 10000), 223); } lcd.setCursor(6, 0); // move cursor to position (6, 0) lcd.print(c_buffer); // print c_buffer (temperature in °C) lcd.setCursor(6, 1); // move cursor to position (6, 1) lcd.print(f_buffer); // print f_buffer (temperature in °F) } int16_t ds1631_temperature() { Wire.beginTransmission(DS1631_ADDRESS); // connect to DS1631 (send DS1631 address) Wire.write(0xAA); // read temperature command Wire.endTransmission(false); // send repeated start condition Wire.requestFrom(DS1631_ADDRESS, 2); // request 2 bytes from DS1631 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 << 8 | t_lsb; raw_t >>= 4; return raw_t; } // end of code. |
Arduino with DS1631 Sensor and 1602 LCD Proteus Simulation Video:
The following video shows Proteus simulation result of this project.
Proteus simulation file download link is below:
Arduino + DS1631 + LCD
Related Project:
Interfacing Arduino with DS1621 Temperature Sensor
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.