Go Down

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

combib

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

// I2C addresses
//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_voltage(int address);
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 address;
int gain;
int result;

int multiplier;

double get_MAX9611_voltage(int address){
int msb;
int lsb;


    Wire.beginTransmission(address);
    Wire.write(0x0A);
    Wire.write(0x03);
    Wire.endTransmission();
   
    Wire.beginTransmission(address);
    Wire.write(0x02);
    Wire.endTransmission();

    Wire.requestFrom(address,2);
    msb = Wire.read();
    lsb = Wire.read();
    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
int reg_add; //register address

  switch (gain) {

    case 1: //gain of 1
reg_add = 0x00;
multiplier = 0.0001075;
      break;

case 4: //gain of 4
reg_add = 0x01;
multiplier = 0.00002688;
      break;

    case 8: //gain of 8
reg_add = 0x02;
multiplier = 0.000055;
    break;

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

    Wire.requestFrom(address,2);
    msb = Wire.read();
    lsb = Wire.read();
    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)
*/
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

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


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?
I only provide help via the forum - please do not contact me for private consultancy.

combib

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

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


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?
I only provide help via the forum - please do not contact me for private consultancy.

dhenry

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