MAX9611 Current reading failure

Hi, i have a problem with the MAX9611, and i hope someone here can help me.
The problem is as follows:

I2C Communication with MEGA2560 board and 9 Slaves (5* MAX9611), Nextion Display, and some hardware Stuff around.
The Temperature and Voltage values are fine, but the Current is not in the near of realistic. Tested are codes from adafruit, from an other post in the forum and self written parts, with all I have the same issue - 100th of A without any load and Voltage, is the Voltage connected the Current jumps to 15,xxxA. In this Case I can’t measure the Current, the Value is stiff. My sense Resistor is a Shunt with 60mV/600A (0.0001Ohm).

my used code (snipped)

void MAX9611_read(int adress, int counter)
{
  MAX9611_voltage[counter] = 0.000;
  MAX9611_current[counter] = 0.000;

  Wire.begin();                      // READ VOLTAGE
  Wire.beginTransmission (adress); // I2C address
  Wire.write(0x0A);              // Select Control register 1
  Wire.write(0x07);              // 111 Read all channels in fast-read mode, sequentially every 2ms. Uses last gain setting.
  Wire.endTransmission();
  Wire.beginTransmission(adress);  // I2C address
  Wire.write(0x02);              // RS+ DATA BYTE 1 (MSB) this returns the volatge
  Wire.endTransmission();
  delay(.010);
  Wire.requestFrom(adress, 2);
  msb = Wire.read();
  lsb = Wire.read();
  Wire.endTransmission();
  MAX9611_voltage[counter] = ((msb) << 4) + (lsb >> 4);
  MAX9611_voltage[counter] = (MAX9611_voltage[counter] * multiplier);

  // new current
  Wire.begin();
  Wire.beginTransmission(adress); // Begin transmission on I2C Address (E0)
  Wire.write(0x00);             // CSA DATA BYTE 1 (MSBs) reg address (hex) 0X00
  Wire.endTransmission();

  Wire.requestFrom(adress, 2);    // read csa msb and lsb bytes
  msb = Wire.read();
  lsb = Wire.read();
  Wire.endTransmission();
  MAX9611_current[counter] = ((msb) << 4) + (lsb >> 4);
  MAX9611_current[counter] = (((.440 / 4096) * MAX9611_current[counter]) / MAX9611_rsense); //Current = ((IFULLSCALE/4096) ×
  //MAX9611_Current)/Sense Resistor (.05)

  // new temp
  Wire.begin();
  Wire.beginTransmission(adress); // Begin transmission on I2C Address (E0)
  Wire.write(0x08);             // TEMP DATA BYTE 1 (MSBs)
  Wire.endTransmission();
  Wire.requestFrom(adress, 2);    // read csa msb and lsb bytes
  msb = Wire.read();
  lsb = Wire.read();
  Wire.endTransmission();
  myInt[counter] = (((msb << 8) | lsb) >> 7);

  // 2's compliment check
  if (myInt[counter] > 255) {
    // do something condition TRUE
    myInt[counter] = myInt[counter] - 512;
  } else {
    // do something condition FALSE
  }
}

I think this code is from somewhere in the net… my code is not there anymore, because the same results are represented.

It may be, that there are some offset errors or timing problems?

All timings are done with this part

curtimed = millis();

  if (abs(curtimed - timed) >= 250)
  {
    clock_read();
    digitalWrite(13, !digitalRead(13));
    Serial.println("CLK Read");
    tmra++;
  }

  if (tmra >= 3)
  {
    // read_temperature_boards(162);
    // temperature_controler_set(162, 31, 0b00000000);
    MAX9611_read(MAX_adress[0], 0);
    tmra = 0;
  }
#ifdef DEBUG_HEATR
  //i2c_scan_devices();

  if (tmra >= 3)
  {
    
    read_temperature_boards(162);
    temperature_controler_set(162, 31, 0b00000000);
    tmra = 0;
  }

#endif

I have no ISR’s or Timers except the " millis(); ".

Thanks a lot and best regards,
Denis

  delay(.010);

RTFM. Delaying for 1/100th of a millisecond is NOT possible.

  MAX9611_voltage[counter] = ((msb) << 4) + (lsb >> 4);

What type is the MAX9611_voltage array?

You need to post a link to the datasheet of the device you are reading. Storing one byte of data in two different bytes does not pass the sniff test.

  Wire.endTransmission();
  delay(.010);
  Wire.requestFrom(adress, 2);
  msb = Wire.read();
  lsb = Wire.read();
  Wire.endTransmission();

beginTransmission() needs a matching endTransmission(). requestFrom() does NOT.

The Wire library needs to have begin() called ONCE, not every time you want to use a Wire function.

You will probably have better luck with your snippets at http://snippets-r-us.com.

Hi, thanks for the fast response.
The Datasheet can be found here: https://datasheets.maximintegrated.com/en/ds/MAX9611-MAX9612.pdf

The wire.begin() 's are deleted, this leavings was from some subroutines copyed and were forget :-/.

But it looks still the same.

No Voltage connected:

VOLTAGE = 0.000 V
CURRENT = 135.352 A
TEMP    = 25.44 C

LiIon Cell connected:

VOLTAGE = 3.598 V
CURRENT = 4.297 A
TEMP    = 25.44 C

In both cases no current is flowing.

Best regards

Is there any reason you won't post the complete code?

Hi,
Welcome to the forum.

Please read the first post in any forum entitled how to use this forum.
http://forum.arduino.cc/index.php/topic,148850.0.html then look down to item #7 about how to post your code.
It will be formatted in a scrolling window that makes it easier to read.

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

Hi,

in the attached picture is the schematic from the MAX9611 board.
Some company rules are in the way of showing the whole code :-/

But for now, i have tried some other ways.

  • Setting the CSA Gain factor
  • Setting fast-read mode
  • Read the whole register bank

same result.

no connection:

VOLTAGE = 0.000 V
CURRENT = 133.740 A
TEMP    = 26.40 C

LiIon Cell connected:

VOLTAGE = 3.598 V
CURRENT = 4.834 A
TEMP    = 26.40 C
void MAX9611_read(int adress, int counter)
{
  byte I2C_read[10];
  MAX9611_voltage[counter] = 0.000;
  MAX9611_current[counter] = 0.000;
  Wire.beginTransmission (adress); // I2C address
  Wire.write(0x0A);              // Select Control register 1
  Wire.write(0x01);              // 0x01 gain setting x4.
  Wire.endTransmission();
  Wire.beginTransmission (adress); // I2C address
  Wire.write(0x0A);              // Select Control register 1
  Wire.write(0x07);              // 0x07 Read all channels in fast-read mode, sequentially every 2ms. Uses last gain setting.
  Wire.endTransmission();
  delay(1);
  Wire.beginTransmission(adress); // Begin transmission on I2C Address (E0)
  Wire.write(0x00);             // CSA DATA BYTE 1 (MSBs) reg address (hex) 0X00
  Wire.endTransmission();
  Wire.requestFrom(adress, 10);
  for (int i = 0; i < 10; i++)
  {
    I2C_read[i] = Wire.read();
  }
  Wire.endTransmission();

  MAX9611_current[counter] = ((I2C_read[0]) << 4) + (I2C_read[1] >> 4);
  MAX9611_current[counter] = (((.110 / 4096) * MAX9611_current[counter]) / MAX9611_rsense); //Current = ((IFULLSCALE/4096) ×
  //MAX9611_Current)/Sense Resistor (.05)

  MAX9611_voltage[counter] = ((I2C_read[2]) << 4) + (I2C_read[3] >> 4);
  MAX9611_voltage[counter] = (MAX9611_voltage[counter] * multiplier);

  myInt[counter] = (((I2C_read[8] << 8) | I2C_read[9]) >> 7);

  // 2's compliment check
  if (myInt[counter] > 255) {
    // do something condition TRUE
    myInt[counter] = myInt[counter] - 512;
  } else {
    // do something condition FALSE
  }
 MAX9611_temperature[counter] = myInt[counter] * .48;

#ifdef DEBUG_MAX9611

  Serial.print("VOLTAGE = ");
  Serial.print(MAX9611_voltage[counter], 3);
  Serial.println(" V");

    Serial.print("CURRENT = ");
  Serial.print(MAX9611_current[counter], 3);
  Serial.println(" A");
  
  Serial.print("TEMP    = ");
  Serial.print(MAX9611_temperature[counter]);
  Serial.println(" C");
#endif
 
}

Thanks a lot

Atlas85:
Some company rules are in the way of showing the whole code :-/

This is an open-source support forum. I’m sure there are plenty of resources available to help with proprietary code. You simply have to pay for the assistance.

EDIT:
For help here you must at least post code that will compile.

Hi,

If you disconnect the 9611 inputs and short H1 to H2, so the current is shorted , but not connection to the shunt, what does the display show?

You do have the shunt in the high side of the load?

Can you please post a copy of your circuit around the load and shunt and 9611, in CAD or a picture of a hand drawn circuit in jpg, png?

You have got gnd of the 9611 connected to gnd of the load supply?
9611.jpg

Tom... :slight_smile:

9611.jpg

Hi,
the Shunt is like a short with 0.0001Ohm. The complete test setup is on an isolated board with a LiIon 18650 Cell.
Negative from the cell is on GND of the board, Positive from cell goes to RS+ on the board. The board is screwed with spacers to the Shunt and the shunt is mounted on isolators on a large heatsink. (Not for cooling the Shunt :slight_smile: , there where some MOSFets, too, but not connected at this state of test)
The picture shows the layout of the schematic from my last post.
Shorting H1 & H2 is done with an other board on the fly with the same result.

This Code is what I have, is Free and compile:

#define DEBUG_MAX9611

#include <Wire.h>

long tmra = 0;

//MAXIM MAX9611 Variablen
float MAX9611_voltage[5];
float MAX9611_current[5];
float MAX9611_temperature[5];
byte max9611_addr;
float MAX9611_rsense = 0.06 / 600; //Shunt Werte in Volt und Ampere
int myInt[5];
float multiplier = 0.014; //voltage sense LSB
unsigned long timed;
unsigned long curtimed;
byte MAX_adress[5] = {112, 113, 114, 115, 116};



void MAX9611_read(int adress, int counter)
{
  byte I2C_read[10];
  MAX9611_voltage[counter] = 0.000;
  MAX9611_current[counter] = 0.000;
  Wire.beginTransmission (adress); // I2C address
  Wire.write(0x0A);              // Select Control register 1
  Wire.write(0x01);              // 0x01 gain setting x4.
  Wire.endTransmission();
  Wire.beginTransmission (adress); // I2C address
  Wire.write(0x0A);              // Select Control register 1
  Wire.write(0x07);              // 0x07 Read all channels in fast-read mode, sequentially every 2ms. Uses last gain setting.
  Wire.endTransmission();
  delay(1);
  Wire.beginTransmission(adress); // Begin transmission on I2C Address (E0)
  Wire.write(0x00);             // CSA DATA BYTE 1 (MSBs) reg address (hex) 0X00
  Wire.endTransmission();
  Wire.requestFrom(adress, 10);
  for (int i = 0; i < 10; i++)
  {
    I2C_read[i] = Wire.read();
  }
  Wire.endTransmission();

  MAX9611_current[counter] = ((I2C_read[0]) << 4) + (I2C_read[1] >> 4);
  MAX9611_current[counter] = (((.110 / 4096) * MAX9611_current[counter]) / MAX9611_rsense); //Current = ((IFULLSCALE/4096) ×
  //MAX9611_Current)/Sense Resistor (.05)

  MAX9611_voltage[counter] = ((I2C_read[2]) << 4) + (I2C_read[3] >> 4);
  MAX9611_voltage[counter] = (MAX9611_voltage[counter] * multiplier);

  myInt[counter] = (((I2C_read[8] << 8) | I2C_read[9]) >> 7);

  // 2's compliment check
  if (myInt[counter] > 255) {
    // do something condition TRUE
    myInt[counter] = myInt[counter] - 512;
  } else {
    // do something condition FALSE
  }
  MAX9611_temperature[counter] = myInt[counter] * .48;

#ifdef DEBUG_MAX9611

  Serial.print("VOLTAGE = ");
  Serial.print(MAX9611_voltage[counter], 3);
  Serial.println(" V");

  Serial.print("CURRENT = ");
  Serial.print(MAX9611_current[counter], 3);
  Serial.println(" A");

  Serial.print("TEMP    = ");
  Serial.print(MAX9611_temperature[counter]);
  Serial.println(" C");
#endif

}


void setup()
{
  Wire.begin();        // join i2c bus (address optional for master)
  Serial.begin(9600);

  pinMode(13, OUTPUT); // alive LED
  timed = millis();
}


void loop()
{
  curtimed = millis();

  if (abs(curtimed - timed) >= 250)
  {

    digitalWrite(13, !digitalRead(13));
    tmra++;
    timed = millis();

  }

  if (tmra >= 3)
  {

    MAX9611_read(MAX_adress[0], 0);
    tmra = 0;
  }


}

Thanks and best regards

and a little stupid question, how i get the picture in the post?

Atlas85:
and a little stupid question, how i get the picture in the post?

"Read the directions, and directly you'll be directed in the right direction."

  • The Cheshire Cat in Alice in Wonderland

Hi,
What if you short H1 and H2 at C3 with nothing connected to H1 and H2.

Also try with NO LOAD but the load supply applied.

What is the load?

Nice PCB too.

Thanks… Tom… :slight_smile:

Hi,

H1 and H2 shorted or on Shunt mounted makes no difference, H1&2 open let the Values float. It is no load connected yet, this will be build up later with resistors and MOS-Fets (~80mOhm).

With my last try i have found, that the registers are confusing. If i try to read the wrong register e.g. 0x01-0x02 instead of 0x00 - 0x01 the fault is the same with other values. can it be, that the registers are overlapping and that i should shift this seperate?
The datasheet is in this thing not a large help :frowning:

The attached pictures show the hardware :slight_smile:




thanks

And on top i have shorted the SET Pin to GND for testing … No changes in this problem.

Best regards

Hi,
Have you run this bit of code to check the I2C address?

https://playground.arduino.cc/Main/I2cScanner

Tom... :slight_smile:

For shure. with this i have tested the devices for I2C function :slight_smile:

Denis :slight_smile:

So on... I have Tested the MAX9611 on a piece of breadboard with some braided wire. it works...
i have assambled a nother PCB with only the MAX9611, and the connectors - voltage ok, temperature ok, current is out of reality.

if i heat up a little the MAX on the breadboard, the failure is there, too.

It is time to say goodbye to this little chip.
I take a nother one from my scrap box... The MCP 3426 - i change the design to measure the current in the lowside and so on it will work.

best regards