Go Down

Topic: Please help with algorithms to convert MAX9611 data (Read 776 times) previous topic - next topic

combib

I am having difficulty with the algorithm to convert the data from a max9611. With the following code, I get 0.55V on a 9V battery.

Code: [Select]

#include <MAX9611.h>
#include <Wire.h>
/*
Analog pins 4 (SDA),5(SCL)
*/
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>
// The LCD and DS3132 use the I2C SCL on analog pin 5 and SDA on analog pin 4.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();

int msb;
int lsb;
double tempresolution = 0.48;

void setup()
{
  lcd.begin(16, 2);
  Serial.begin(9600);
  Wire.begin();
}

void loop()
{
  double volts;
  double current;
 
  lcd.setCursor(0,1);
  while (1) {
   
    volts = get_MAX9611_voltage();
    current = get_MAX9611_current();

  lcd.setCursor(0,0);
  lcd.print(current);
  lcd.print(" A");
 
  lcd.setCursor(9,0);
  lcd.print(volts);
  lcd.print(" V");
 
  lcd.setCursor(2,1);
  lcd.print(current * volts);
  lcd.print(" Watts");
  }
}


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.0
#define main_voltage_min 1.0

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



// I2C addresses
#define MAX9611_address 0x70 //0x70 is the Arduino MAX9611 address actual address is 0xE0

// Sense resistor values

// *******************************************************************



extern double MAX9611_voltage;
extern double MAX9611_current;


// Function prototypes

double get_MAX9611_voltage();
double get_MAX9611_current();

void init_MAX9611 ();



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;
double MAX9611_rsense;

double get_MAX9611_voltage (void){
unsigned char msb;
unsigned char lsb;

    Wire.beginTransmission(0x70); // Read average voltage of RS+
  // (input common-mode voltage) from ADC
    Wire.write(0x0A);
    Wire.write(0x03);
    Wire.endTransmission();
   
    Wire.beginTransmission(0x70); // read from RS+ register
    Wire.write(0x02);
    Wire.endTransmission();

    Wire.requestFrom(0x70,2); // read RS+ msb and lsb bytes
    msb = Wire.read();
    lsb = Wire.read();
    Wire.endTransmission();

    MAX9611_voltage = (((msb | (lsb>>4)) & 0xFF));
    MAX9611_voltage = ((57.3/4096)*MAX9611_voltage); //Voltage = (VFULLSCALE/4096) ×
//MAX9611_voltage
return MAX9611_voltage;
}

double get_MAX9611_current (void){
unsigned char msb;
unsigned char lsb;

    Wire.beginTransmission(0x70);// Read current-sense amplifier
// output from ADC, gain = 1x
    Wire.write(0x0A);
    Wire.write(0x00);
    Wire.endTransmission();
   
    Wire.beginTransmission(0x70); // read from csa register
    Wire.write(0x00);
    Wire.endTransmission();

    Wire.requestFrom(0x70,2); // read csa msb and lsb bytes
    msb = Wire.read();
    lsb = Wire.read();
    Wire.endTransmission();

    MAX9611_current = (((msb | (lsb>>4)) & 0xFF));
    MAX9611_current = (((.440/4096)*MAX9611_voltage)/.05); //Current = ((IFULLSCALE/4096) ×
//MAX9611_Current)/Sense Resistor (.05)

    return MAX9611_current;
}

robtillaart


if you print raw values of msb and lsb

Code: [Select]
    MAX9611_voltage = (((msb | (lsb>>4)) & 0xFF));
    MAX9611_voltage = ((57.3/4096)*MAX9611_voltage);


I expect the error is in 
Code: [Select]
MAX9611_voltage = (((msb | (lsb>>4)) & 0xFF));
as the next line divides by 4096 but the above line only produces values up 0..255 => so it misses a factor 16

0.55 x 16 = 8.8 so almost 9 volts ...

so rewrite these 2 lines to
Code: [Select]
int volts = (lsb >>4) * 256;
volts = volts + msb;
MAX9611_voltage = (57.3/4096) * volts;



furthermore you define (in the lib)
Code: [Select]
#define voltage_max 56.0
and uses 57.3 in the formula ...
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Go Up