0

I'm am completing a project of mine that uses an MCP3424 i2c 18bit ADC and an arduino nano to measure temperature with an NTC thermistor but am having trouble with the arduino wire library. This is my first project using i2c so I'm not very knowledgeable about the subject but I have rigorously read the datasheet of the MCP3424 that can be found at (http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf) and tried many different ways to get it working. Also I'm new to posting on this stackexchange so pardon me if my syntax and what not is not right(I'm doing my best). Here is the code I have so far that is on my arduino.

#include<Wire.h>
//#include<LiquidCrystal.h>
//LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

#define MCP 0x6E //Device will output conversion data (7 bits, device address. 1 bit, Read/Write mode)
#define CH1 0x8c //PGA = 1, SPS = 3.75, One-Shot mode, channel 1, initiate new conversion.
#define CH2 0xac //channel 2
#define CH3 0xcc //channel 3
#define CH4 0xec //channel 4

void setup() {
  Serial.begin(9600);//Initiate Connection to computer
  //lcd.begin(16, 2); not used yet
  Wire.begin();//Initiate Wire library
}

void loop() {
  // Read data from
  int pins[] = {CH1, CH2, CH3, CH4};
  long results[] = {0, 0, 0, 0};
  for (int i = 0; i < 4 ; i++) {
    results[i] = ReadMCP(pins[i]);
    Serial.print(i+1);
    Serial.print(": ");
    Serial.print(ReadMCP(pins[i]));
    Serial.print(" ");
    delay(500);
  }
  Serial.print("\n");


}
long ReadMCP(int channel){
  //conversion takes the three bytes and converts to number between 0 and 131071
  int x, y, z;
  long result = 0;

  Wire.beginTransmission(MCP);//begin transmission with ADC in Write mode
  Wire.write(channel);//configure the ADC with settings found in either CH1, 2, 3 or 4
  Wire.endTransmission();
  //delay(500);
  Wire.requestFrom(MCP, 3);//request 6 Bytes of information from MCP3424
  x = Wire.read();//read bytes
  y = Wire.read();
  z = Wire.read();

  if (x>1) {
    if (x%2){
      result += (1 * 65536L);//x * 65536 = x * 2^16
      result += (y * 256L);//y * 256 = y * 2^8
      result += z;
      result = -131072 + result;
    }else{
      result += (y * 256L);//y * 256 = y * 2^8
      result += z;
      result = -131072 + result;
    }

  } else {
    result += (x * 65536L);//x * 65536 = x * 2^16
    result += (y * 256L);//y * 256 = y * 2^8
    result += z;
  }
  return result;
}

My program reads the measurements from each of the 4 channels of the ADC and prints them in the serial monitor.

The issue I am having is that when this code is run without the "delay(500);" function in the ReadMCP() function my measurements from each channel of the MCP3424 are in the wrong place. It prints the measurement from channel 1 as channel 2, the measurement from channel 4 as channel 1 and etc. However, with the delay between endTransmission() and requestFrom() the values are in the correct place. I have looked all over the datasheet and experimented a lot with the issue but cannot see what is causing it. Does anyone know why?

For reference when I have something to measure attached to channel 2 the output without the delay is

1: 131071 2: 131071 3: 66891 4: 131071

and with the delay is

1: 131071 2: 66843 3: 131071 4: 131071

  • 2
    You have to wait for the conversion to be complete. Check the RDY bit as detailed in the datasheet. – Majenko Oct 24 at 10:45
  • Don't leave the unused channels floating...you may read random values caused by noise or, worse, get crosstalk from adjacent channels. Tie unused channels to ground or some known reference voltage. – Elliot Alderson Oct 24 at 13:54
  • Why do you read MCP a second time Serial.print(ReadMCP(pins[i])); instead of using the the result you received 3 lines above (results[i] = ReadMCP(pins[i]);)? – Peter Paul Kiefer Oct 25 at 13:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.