Expanding Arduino ADC inputs with external 10 channel ADC

Many microcontroller projects involve the use of sensors like Accelerometers, Gyroscopes, Temperature, Compass, Barometric, Current, Proximity and others. Some sensors have I2C or SPI interfaces but there are still a great many which produce an analogue output voltage. These are measured with the use of the built-in Analogue to Digital Converters (ADC) included in microcontrollers. However, if you are using many sensors and don’t have enough ADC inputs, or have used those pins for other functions, you either have to upgrade to a larger microcontroller with more inputs or resort to using an external (and sometimes expensive) ADC chip.

With this in mind we have programmed our own microcontroller to provide you with 10 additional ADC inputs available via I2C as a slave device. ADC I2C Slave IC

Here is the pinout for the ADC chip

ADC I2C Chip pinout

Apart from supplying power to the chip, simply connect pin 13 (SDA) to Arduino UNO pin A4 (SDA) and connect pin 11 (SCL) to Arduino UNO pin A5 (SCL). Use pullup resistors on these 2 pins (4K7).

Use the sketch below and try it out.

** Wire Master Reader of Hobbytronics 10 channel ADC
** Created 06 Feb 2010
** This example code is in the public domain.
** www.hobbytronics.co.uk

#include <Wire.h>

const int  adc_address=40;        // I2C Address of ADC Chip
const int  adc_config=B00000011;  // 8-bit data, complementary filter 
                                  // output (see datasheet)

unsigned int adc_data[10];        // Array to store ADC values   

void setup()
  //Send settings to ADC_I2C device (optional)
  Wire.begin();              // join i2c bus (address optional for master)
  Wire.beginTransmission(adc_address); // transmit to device
  Wire.send(adc_config);     // send config options
  Wire.endTransmission();    // stop transmitting  
  //Start Serial port
  Serial.begin(9600);        // start serial for output

void get_adc_8()
  // Get 8-bit ADC data
  // We only want single byte values (0 to 255)
  unsigned char data_values_rcvd=0;     // keep track of how many chars received    
  Wire.requestFrom(adc_address, 10);    // request 10 bytes from slave device 
    if(data_values_rcvd < 10) adc_data[data_values_rcvd] = Wire.receive(); 
    // receive a byte as character

void get_adc_10()
  // Get 10-bit ADC data
  // We want double byte values (0 to 1024)   
  // We will reconstruct an unsigned int from the two bytes received 
  unsigned char hi_lo_byte;
  unsigned char data_values_rcvd=0;     // keep track of how many chars received

  Wire.requestFrom(adc_address, 20);    // request 20 bytes from slave device
  hi_lo_byte=1;                         // First byte will be a high byte
    if(data_values_rcvd < 10) 
        // Its a high byte
        adc_data[data_values_rcvd] = Wire.receive() << 8; 
        // receive high byte and shift left 8   
        hi_lo_byte=0;    // next byte will be a low byte
        adc_data[data_values_rcvd] += Wire.receive(); 
        // receive low byte and add to existing value
        hi_lo_byte=1;    // next byte will be a high byte

void loop()
  unsigned char i;

  if(bitRead(adc_config, 0)) get_adc_8();  // get 8-bit data
  else get_adc_10();                       // get 10-bit data

  // Print out our data
    Serial.print(adc_data[i], DEC);     // print the character
    Serial.print(",");                  // print comma
  Serial.println("");                   // print carriage return  

Shopping Cart
0 items

Free Delivery Orders over £50

UK - £2.40 orders under £50
Airmail from £2.95 (+VAT)
More Details...

 Check out our videos
Follow us on: