Go Down

Topic: Please help with Current Sense Amplifiers conversion algorythm (Read 1 time)previous topic - next topic

combib Jan 07, 2013, 01:25 am
I need help converting data from a MAX9611 with a 0.05 ohm sense resistor. I have the following:

MAX9611_voltage = ((msb)<<4)+(lsb>>4);
MAX9611_voltage = ((MAX9611_voltage/4096)*57.3);

result = (msb<<4)+(lsb>>4);
MAX9611_current = ((result*multiplier)/0.05);

The voltage is a little low and the current reads 0.0043 with no load attached

My complete code is as follows:
Code: [Select]

/*********************************************************************
* FileName: MAX9611.h
* Dependencies: None
* Overview: Defines function prototypes, I2C address, global
* variables.
********************************************************************/

// ***************** User-configurable parameters ********************

// main voltage range
#define voltage_max 56.3
#define main_voltage_min 1.0

// main current range
#define current_max 10000
#define current_min 0

//From function The address comes from the function, which allows many different //address MAX9611 to be used

// Sense resistor values
#define sense_resistor 0.05

// *******************************************************************
// Function prototypes

double get_MAX9611_current(int address, int gain);

Code: [Select]

/*********************************************************************
* FileName: MAX9611.cpp
* Dependencies: MAX9611.h (include here and in main)
* Wire.h (include here and in main)
********************************************************************/

/*********************************************************************
* Function:        void get_MAX9611_voltage (void),
* void get_MAX9611_current (void)
* PreCondition:    None.
* Input:            None.
* Output:          None.
* Side Effects:    None.
* Overview:        Function for obtaining MAX9611 voltage via I2C
* bus.
*
********************************************************************/

#include "MAX9611.h"
#include "Wire.h"

double MAX9611_voltage;
double MAX9611_current;
int gain;
int result;

int multiplier;

int msb;
int lsb;

Wire.write(0x0A);
Wire.write(0x03);
Wire.endTransmission();

Wire.write(0x02);
Wire.endTransmission();

Wire.endTransmission();

result = ((msb)+(lsb));
MAX9611_voltage = ((56.3/4096)*(result));

return MAX9611_voltage;
}

double get_MAX9611_current(int address, int gain){
int msb;
int lsb;
float multiplier; //calculation multiplier

switch (gain) {

case 1: //gain of 1
multiplier = 0.0001075;
break;

case 4: //gain of 4
multiplier = 0.00002688;
break;

case 8: //gain of 8
multiplier = 0.000055;
break;

default: //gain of 1
multiplier = 0.0001075;
}
Wire.write(0x0A);
Wire.endTransmission();

Wire.write(0x00);
Wire.endTransmission();

Wire.endTransmission();

result = (msb<<4)+(lsb>>4);
MAX9611_current = ((result*multiplier)/0.05);

return MAX9611_current;
}

Code: [Select]

#include <MAX9611.h>
#include <Wire.h>
/*
Analog pins 4 (SDA),5(SCL)
*/

int msb;
int lsb;
byte i;

void setup()
{
lcd.begin(16, 2);
Serial.begin(9600);
delay(1); //wait for serial bus to settle
}

void loop()
{
double volts;
double current;
byte i;
int g;

lcd.setCursor(0,1);
while (1) {

Wire.begin();
for (i = 0x70; i < 0x7F; i++) //scan I2c bus for potential MAX9611 devices
{
Wire.beginTransmission (i);
if (Wire.endTransmission () == 0)
{
volts = get_MAX9611_voltage(i);//get the voltage for this device the parameter is the address

lcd.setCursor(9,0);
lcd.print(volts, 2); //print the current with 2 decimal places
lcd.print(" V");

g = 1;

current = get_MAX9611_current(i, g); //get the current for this device (the first parameter is the address and the second{future} is the gain)

lcd.setCursor(0,0);
lcd.print(current, 4); //print the current with 4 decimal places
lcd.print(" A");

lcd.setCursor(2,1);
lcd.print((current * volts)); //calculate watts
lcd.print(" Watts");

Serial.print ("Address "); Serial.print((i<<1), HEX); //print the actual hex address (Arduino uses the actual hex address divided by 2)
Serial.print ("   "); Serial.print (volts); Serial.print (" Volts");
Serial.print ("   "); Serial.print (current); Serial.print (" Amps");
Serial.print ("   "); Serial.print (current * volts); Serial.print (" Watts");
Serial.print ("\n");
}
}
delay (1);  // maybe unneeded?
} // end of good response
} // end of for loop

PeterH #1
Jan 07, 2013, 02:06 am

The voltage is a little low and the current reads 0.0043 with no load attached

Low compared to what?

What input values do you expect to get from the MAX9611 and what values do you actually get?

What output voltage and current values do you expect to calculate for those input values, and what do you actually get?

combib #2
Jan 07, 2013, 02:48 am
The voltage should display 8.87 Volts but displays 8.79 volts

I get current reading of 0.0043 with no load attached, I expect it to be zero

Magician #3
Jan 07, 2013, 02:59 am
Code: [Select]
result = ((msb)+(lsb)); It's not right, use your formula. Other option would be:
Code: [Select]
result = ((msb << 8)+(lsb));  //   (1)
Regarding current, your formula round results to 8-bit instead of 12, this probably a reason.
Try (1) for current also, and you may need to tweak your gain coefficient down to 16 (divide by). Calibration may be necessary after all

PeterH #4
Jan 07, 2013, 03:04 am

The voltage should display 8.87 Volts but displays 8.79 volts

I get current reading of 0.0043 with no load attached, I expect it to be zero

What input values do you expect to get from the MAX9611 and what values do you actually get?

dhenry #5
Jan 07, 2013, 03:06 am
Quote
the current reads 0.0043 with no load attached

That could be due to floating point math.

You should really use fixed point math.

Go Up