This post shows how to implement a simple temperature measurement station using Arduino UNO board and DS18B20 digital temperature sensor.
The Arduino reads temperature (in °C) from the DS18B20 sensor and print its value on SSD1306 OLED display (128×64 pixel).
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).
To see how to interface Arduino with SSD1306 OLED display, visit the following post:
Interfacing Arduino with SSD1306 OLED display
And to see how to interface Arduino with DS18B20 sensor for the first time, take a look at this post:
Digital thermometer using Arduino and DS18B20 sensor
In this project the SSD1306 OLED is configured to work in I2C mode, make sure that your display is configured to work in I2C mode, some displays need jumper placing or some soldering.
Hardware Required:
- Arduino board
- SSD1306 OLED display
- DS18B20 temperature sensor —-> datasheet
- 4.7k ohm resistor
- Breadboard
- Jumper wires
Arduino with DS18B20 sensor and SSD1306 OLED display 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 Arduino 5V pin,
data pin: connected to Arduino analog pin 0 (A0) and
GND: connected to Arduino GND pin.
A pull-up resistor of 4.7k ohm is required because the DS18B20 output is open drain.
The SSD1306 OLED display is connected to the Arduino UNO board as follows:
SSD1306 OLED GND goes to Arduino GND (ground),
SSD1306 OLED VDD to Arduino 5V,
SSD1306 OLED SDA pin (serial data) to pin A4 (Arduino UNO hardware I2C SDA pin),
SSD1306 OLED SCK pin (serial clock) to pin A5 (Arduino UNO hardware I2C SCL pin),
SSD1306 OLED RES pin (reset) to Arduino pin 4.
The SSD1306 OLED display DC pin is connected to VDD which means I2C slave address of the device is 0x3D. If the DC pin is connected to ground (GND) then the I2C slave address will be 0x3C.
Arduino with DS18B20 sensor and SSD1306 OLED display code:
The Arduino code below doesn’t use any library for the DS18B20 sensor.
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 |
The SSD1306 OLED display reset pin and DS18B20 temperature sensor pin connections are defined in the code as shown below:
1 2 3 4 5 | #define OLED_RESET 4 // define display reset pin Adafruit_SSD1306 display(OLED_RESET); // define DS18B20 data pin connection #define DS18B20_PIN A0 |
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.
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 | /* * Arduino Thermometer using DS18B20 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 OLED_RESET 4 // define display reset pin Adafruit_SSD1306 display(OLED_RESET); // define DS18B20 data pin connection #define DS18B20_PIN A0 void setup(void) { delay(1000); // wait a second // 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(13, 0); // move cursor to position (13, 0) pixel display.print("ARDUINO + DS18B20"); display.setCursor(28, 14); display.print("SSD1306 OLED"); display.setCursor(29, 33); display.print("TEMPERATURE:"); display.display(); // update the display display.setTextSize(2); // text size = 2 } unsigned int ds18b20_temp; char _buffer[11]; void loop() { display.setCursor(1, 50); if(ds18b20_read(&ds18b20_temp)) { if (ds18b20_temp & 0x8000) // if temperature < 0 { ds18b20_temp = ~ds18b20_temp + 1; // change temperature value to positive form sprintf(_buffer, "-%02u.%04u C", (ds18b20_temp/16) % 100, (ds18b20_temp & 0x0F) * 625); } else { // otherwise (temperature >= 0) if (ds18b20_temp/16 > 100) // if temperature >= 100 °C sprintf(_buffer, "%03u.%04u C", ds18b20_temp/16, (ds18b20_temp & 0x0F) * 625); else // otherwise ( 0 <= temperature < 100) sprintf(_buffer, " %02u.%04u C", ds18b20_temp/16, (ds18b20_temp & 0x0F) * 625); } display.print(_buffer); display.drawCircle(103, 52, 2, WHITE); // put degree symbol ( ° ) } 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. |
The following picture shows a protoboard circuit of the project:
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.