MCP9808 is a digital temperature sensor that converts temperatures between -20°C and +100°C to a digital word with ±0.25°C/±0.5°C (typical/maximum) accuracy. The MCP9808 comes with user-programmable registers that provide flexibility for temperature sensing applications. The registers allow user-selectable settings such as Shutdown or Low-Power modes and the specification of temperature Alert window limits and critical output limits.
Contents of the TutorialThe tutorial is split into the following pages:
- MCP9808 overview :- An overview of the sensor MCP9808, its features and capablities.
- Hardware Requirements :- All the requirements that are necessary for the project.
- Connections :- Step by step description on how to connect various discrete components and hook them together.
- Example code :- An arduino code to interface MCP9808 with arduino nano
- Applications :- An insight into the applications of the sensor.
The MCP9808 is perhaps one of the most accurate temperature sensors we have seen. This device offers an incredible ±0.25 of accuracy over an extended temperature range of -40°C to +125°C.This sensor has an industry standard 400 kHz, 2-wire, SMBus/I2C compatible serial interface, allowing up to eight to be controlled with a single serial bus.
These features make the MCP9808 ideal for sophisticated, multi-zone, temperature-monitoring applications including industrial freezers and refrigerators, food processing, personal computers and servers, consumer electronics and handheld/portable devices. The data sheet for the MCP9808 can be found at Here .
The pin diagram of MCP9808 is :-
The respective function for each pin is :-
Here is the demonstration with an Arduino code.
Hardware Requirements- Arduino Nano
Specification :-
• Accuracy:
±0.25 (typical) from -40°C to +125°C
- ±0.5°C (maximum) from -20°C to 100°C
- ±1°C (maximum) from -40°C to +125°C
• User-Selectable Measurement Resolution:
- +0.5°C, +0.25°C, +0.125°C, +0.0625°C
This I²C Shield for Arduino Nano makes it easy to plug any of our devices directly into your Nano for easy operation and fast development. Open the possibilities of sensors, relay controller, digital I/O, analog to digital conversion and much more with a simplified 4-pin plug interface made for your Arduino Nano.
Connections :-Let's hook up the components. First gather all of the above mentioned components.
Take an I2C shield for arduino nano generally known as "ANYI2C shield", and put the arduino nano onto it. Press gently to complete the connection.
Then at one end of the I2C connecting cable connect the sensor i.e MCP9808. The other end of the I2C cable is to be inserted into the ANYI2C shield.
All is set, now to run up the system power up the arduino nano using a Mini-B usb cable.
The stage is set now, lets see the example code for our project
Example CodeThe arduino code for MCP9808 can be found on github.com and can be downloaded from our repository :- controleverythincommunity
For our arduino code the first and the foremost software that we require is an IDE(integrated development environment) where we can write and modify our arduino codes. The arduino IDE can be download from Here.
The code can be copied from here also. just copy the entire code, go to arduino IDE you just downloaded in case you didn't have it earlier, paste the code, compile and run it. The output will be visible on the serial monitor.
// Distributed with a free-will license.
// Use it any way you want, profit or free, provided it fits in the licenses of its associated works.
// MCP9808
// This code is designed to work with the MCP9808_I2CS I2C Mini Module available from ControlEverything.com.
// https://www.controleverything.com/content/Temperature?sku=MCP9808_I2CS#tabs-0-product_tabset-2
#include
// MCP9808 I2C address is 0x18(24)
#define Addr 0x18
void setup()
{
// Initialise I2C communication as MASTER
Wire.begin();
// Initialise Serial Communication, set baud rate = 9600
Serial.begin(9600);
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select configuration register
Wire.write(0x01);
// Continuous conversion mode, Power-up default
Wire.write(0x00);
Wire.write(0x00);
// Stop I2C Transmission
Wire.endTransmission();
// Start I2C Transmission
Wire.beginTransmission(Addr);
// Select resolution rgister
Wire.write(0x08);
// Resolution = +0.0625 / C
Wire.write(0x03);
// Stop I2C Transmission
Wire.endTransmission();
}
void loop()
{
unsigned int data[2];
// Starts I2C communication
Wire.beginTransmission(Addr);
// Select data register
Wire.write(0x05);
// Stop I2C transmission
Wire.endTransmission();
// Request 2 bytes of data
Wire.requestFrom(Addr, 2);
// Read 2 bytes of data
// temp MSB, temp LSB
if(Wire.available() == 2)
{
data[0] = Wire.read();
data[1] = Wire.read();
}
// Convert the data to 13-bits
int temp = ((data[0] & 0x1F) * 256 + data[1]);
if(temp > 4095)
{
temp -= 8192;
}
float cTemp = temp * 0.0625;
float fTemp = cTemp * 1.8 + 32;
// Output data to screen
Serial.print("Temperature in Celsius : ");
Serial.println(cTemp);
Serial.println(" C");
Serial.print("Temperature in Fahrenheit : ");
Serial.println(fTemp);
Serial.println(" F");
delay(500);
}
The code is fairly simple and easy to understand. The various components of the code are :-
#include
This line is a header which is to be included for our I2C communication. For more information on the this header file, you can go to arduino.cc .
#define Addr 0x18
It defines the I2C address of the sensor MCP9808.
Wire.begin();
Serial.begin(9600);
Wire.begin() :-Initiate the Wire library and join the I2C bus as a master or slave. This should normally be called only once.
Serial.begin(9600) :-Sets the data rate in bits per second (baud) for serial data transmission. For communicating with the computer, use one of these rates: 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 57600, or 11520 .
Wire.beginTransmission(Addr);
Begin a transmission to the I2C slave device with the given address. Subsequently, queue bytes for transmission with the write() function and transmit them by calling endTransmission() .
Wire.write(0x01);
Writes data from a slave device in response to a request from a master, or queues bytes for transmission from a master to slave device (in-between calls to beginTransmission() and endTransmission()).
The MCP9808 has a 16-bit Configuration register (CONFIG) that allows the user to set various functions for a robust temperature monitoring system. Bits 10 through 0 are used to select the temperature alert output hysteresis, device shutdown or Low-Power mode, temperature boundary and critical temperature lock, and temperature Alert output enable/disable.
Wire.write(0x00);
Wire.write(0x00);
Configure MCP9808 to work in Continuous conversion mode, and have a Power-up default functionality.
Wire.endTransmission();
Ends a transmission to a slave device that was begun by beginTransmission() and transmits the bytes that were queued by write().
Wire.write(0x08);
Select resolution register. This register allows the user to change the sensor resolution. The POR default resolution is +0.0625°C. The selected resolution is also reflected in the Capability register.
bit 7-2 Unimplemented: Read as ‘0’
bit 1-0 Resolution bits
00 = +0.5°C (tCONV = 30 ms typical)
01 = +0.25°C (tCONV = 65 ms typical)
10 = +0.125°C (tCONV = 130 ms typical)
11 = +0.0625°C (power-up default, tCONV = 250 ms typical)
Wire.write(0x05);
Select the data address from where the digital data is present. The digital word is loaded to a 16-bit read-only Ambient Temperature register (TA) that contains 13-bit temperature data in two’s complement format.
Wire.requestFrom(Addr, 2);
Wire.requestFrom() is Used by the master to request bytes from a slave device. The bytes may then be retrieved with the available() and read() functions. Here 2 bytes of data is requested from MCP9808.
if(Wire.available() == 2)
The function Returns the number of bytes available for retrieval with read(). This should be called on a master device after a call to requestFrom() or on a slave inside the onReceive() handler. In this case as we have requested for 2 bytes, if only the sensor transmits 2 bytes of data the program flow will continue else it will stop.
Wire.read();
The function is used to Reads a byte that was transmitted from a slave device to a master after a call to requestFrom() or was transmitted from a master to a slave.
// Convert the data to 13-bits
int temp = ((data[0] & 0x1F) * 256 + data[1]);
if(temp > 4095)
{
temp -= 8192;
}
float cTemp = temp * 0.0625;
float fTemp = cTemp * 1.8 + 32;
The data is of 13-bit resolution i.e the data is available only from bit 0 to bit 12.
Serial.print("Temperature in Celsius : ");
Serial.println(cTemp);
Serial.println(" C");
Serial.print("Temperature in Fahrenheit : ");
Serial.println(fTemp);
Serial.println(" F");
The result is displayed on the serial monitor of the arduino IDE.
Applications :-MCP9808 finds many applications like :-
- General Purpose
- Industrial Applications
- Industrial Freezers and Refrigerators
- Food Processing
- Personal Computers and Servers
- PC Peripherals
- Consumer Electronics
- Handheld/Portable Devices








Comments