MCP3221 Digital I2C 12bit ADC. 0v - 5v @ 1mV Library.

Digital I2C 12bit ADC.

Hello World

Import programMCP3221_TEST

MCP3221_Test Program.


Import libraryMCP3221

A library for the MCP3221 12BIT I2C ADC. (2.7 - 5.0v)


This library was written because I needed to an analogIn accurately in the range 2.5v to 5.0v, at a resolution of 20mV.

If you use an external ADC then these give a reading referenced to the supply voltage. So, if you use an ADC such as an MCP3221, and supply it with 5.0v, then the ain can swing between 0 and 5.0v.

The chosen IC is an I2C device, and at 12BIT, it has a resolution of 4096 "steps" between Vss (usually GND) and Vdd (Supply voltage).

This means that if it is supplied with 5.0v, it has a resolution of approx 1mV.

Notes on Addressing

This library is for the default part : MCP3221A5T-I/OT

The "A5" in the part number denotes the specific address of this part. This ADC is available with different addresses (different part codes) so that you can have more than 1 on the I2C bus.

Studying the datasheet showed that it is not a completely standard I2C part. You cannot write to an MCP3221, it has no writable registers. You open a conversation with it by sending it a byte terminating in a "1" bit, these bytes are usually "reads" in the I2C architecture.

MCP3221 also requires an ACKnowledge between each byte it sends, before it will send the next byte. So we need to be a bit manual with how we talk to it.

It also needs an (NOT) ACKnowledge after the second byte or it will keep sending bytes (continuous sampling)(You can continuous sample from it if you want, but this library does not support that) This is a simple, "set it up and read from it, getting a value back as a voltage" library.

to communicate with it you must..

  • Send 8 bit device/ part address to open conversation. (See .h file for part explanation)
  • read a byte (with ACK)
  • read a byte (with NAK)
  • I2C.STOP
  • Convert the 2 byte value to something meaningful by referencing the supply voltage


There seems to be a typo copied across multiple datasheets. The part code is 1001, so the initial "open conversation byte" is 10011011, not as described in the text of the datasheet. The pictures on the datasheets have it correct.


Instantiate with, SDA, SCL, and the supply voltage it is running on. then "read()" returns a float of the voltage on the ain pin. No further processing of the return value is required.

#include "mbed.h"
#include "MCP3221.h"

DigitalOut myled(LED1);

Serial pc(USBTX, USBRX); // tx, rx
AnalogIn ain(p20);
MCP3221 adc(p9, p10, 5.0); //sda, scl, supplyVoltage

int main() {

    while (1) {
        pc.printf("ain: %f :: ",*3.3);
        pc.printf("adc: %f \r\n",;



The pullups govern the speed it can run at.

  • Use 10k for 100kHz
  • Use 2k for 400kHz

Further notes can be found at

You need to log in to post a discussion