Pages: [1]   Go Down
Author Topic: Please help with algorithms to convert MAX9611 data  (Read 502 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 15
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
/*********************************************************************
 * 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:
/*********************************************************************
 * 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;
}
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 170
Posts: 12451
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


if you print raw values of msb and lsb

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

I expect the error is in 
Code:
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:
int volts = (lsb >>4) * 256;
volts = volts + msb;
MAX9611_voltage = (57.3/4096) * volts;


furthermore you define (in the lib)
Code:
#define voltage_max 56.0
and uses 57.3 in the formula ...
Logged

Rob Tillaart

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

Pages: [1]   Go Up
Jump to: