Using Arduino and PMBUS to change the output voltage of a buck converter

Hi everyone,
I am trying to monitor and control the output of a buck converter with PMBus protocol in Arduino Uno.

I read different post and article, and used some codes in Arduino FORUM, but almost all does not work.
Finally, I tried to remove errors in a code, but still there is an error ''undefined reference to linear16(unsigned char, unsigned char)'.'' and ''undefined reference to linear11(unsigned char, unsigned char)'.''
I put the whole code here.
Please help me.
Thanks in advance.

#include <Wire.h>`Preformatted text`
#include <float.h>`Preformatted text`

/* Address */
const byte VCCINT     = 0x38`Preformatted text`;


/* Command */
const byte VIN = 0x88;
const byte VOUT = 0x8B;
const byte IOUT = 0x8C;
const byte PW = 0x96;

/* Register values */
double Vo = 0;
double Vi = 0;
double Io = 0;
double P = 0;


/* Function Prototype */

double ByteRequest(byte DeviceAddr, byte Command, int format); // format : 0 linear11, 1 linear16
double linear11(byte msb, byte lsb);
double linear16(byte msb, byte lsb);





void setup() {
Serial.begin(9600);
Wire.begin();
Wire.setClock(100000L);
}

void loop() {
Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Vo = ByteRequest(VCCINT, VIN, 0);
Serial.print("Vin = ");
Serial.print(Vo);
Serial.println(" V");

Vi = ByteRequest(VCCINT, VOUT, 1);
Serial.print("Vout = ");
Serial.print(Vi);
Serial.println(" V");

Io = ByteRequest(VCCINT, IOUT, 0);
Serial.print("Iout = ");
Serial.print(Io);
Serial.println(" A");

P = ByteRequest(VCCINT, PW, 0);
Serial.print("Power = ");
Serial.print(P);
Serial.println(" W");

delay(2000);
}

// convert a LinearFloat5_11 formatted word into a floating point value
float linear11ToFloat(uint16_t wordValue)
{
int8_t exponent = wordValue>>11; // extract exponent as MS 5 b its
int16_t mantissa = wordValue & 0x7ff; // extract mantissa as LS 11 bits
if ( exponent > 0x0F ) exponent |= 0xE0; // sign extend exponent
if ( mantissa > 0x03FF ) mantissa |= 0xF800; // sign extend mantissa
return mantissa * pow(2,exponent); // compute value as
// mantissa * 2^(exponent)
}
// convert a LinearFloat5_11 formatted word into a floating point value
float linear16ToFloat(uint8_t exp,uint16_t wordValue)
{
int8_t exponent = exp; // extract exponent as MS 5 b its
int16_t mantissa = wordValue; // extract mantissa as LS 11 bits

if ( exponent > 0x0F ) exponent |= 0xE0;    // sign extend exponent  
if ( mantissa > 0x03FF ) mantissa |= 0xF800;  // sign extend mantissa
return mantissa * pow(2,exponent);         // compute value as
                                           // mantissa * 2^(exponent) 

}

double ByteRequest(byte DeviceAddr, byte Command, int format){
byte ReceiveData = 0x00;
int wen = 0;
byte msb = 0;
byte lsb = 0;
double res = 0;

Wire.beginTransmission(DeviceAddr);
Wire.write(Command);
wen = Wire.endTransmission((uint8_t) false);

if (wen != 0) {
Serial.print("endTransmission error ");
Serial.println(wen);
}

Wire.requestFrom((uint8_t) DeviceAddr, (uint8_t) 2, (uint8_t) true);

if (Wire.available()) {
lsb = Wire.read();
msb = Wire.read();
} else {
Serial.println("No data on bus\r\n");
}

if(format==1)
res = linear16(msb,lsb);
else
res = linear11(msb,lsb);

Wire.beginTransmission(DeviceAddr);
Wire.write(Command);
wen = Wire.endTransmission((uint8_t) true);

return res;
}

code in code tags.

#include <Wire.h>`Preformatted text`
#include <float.h>`Preformatted text`

/* Address */
const byte VCCINT     = 0x38`Preformatted text`;


/* Command */
const byte VIN = 0x88;
const byte VOUT = 0x8B;
const byte IOUT = 0x8C;
const byte PW = 0x96;

/* Register values */
double Vo = 0;
double Vi = 0;
double Io = 0;
double P = 0;

/* Function Prototype */

double ByteRequest(byte DeviceAddr, byte Command, int format); // format : 0 linear11, 1 linear16
double linear11(byte msb, byte lsb);
double linear16(byte msb, byte lsb);

void setup() {
Serial.begin(9600);
Wire.begin();
Wire.setClock(100000L);
}

void loop() {
Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
Vo = ByteRequest(VCCINT, VIN, 0);
Serial.print("Vin = ");
Serial.print(Vo);
Serial.println(" V");

Io = ByteRequest(VCCINT, IOUT, 0);
Serial.print("Iout = ");
Serial.print(Io);
Serial.println(" A");

P = ByteRequest(VCCINT, PW, 0);
Serial.print("Power = ");
Serial.print(P);
Serial.println(" W");

delay(2000);
}

// convert a LinearFloat5_11 formatted word into a floating point value
float linear11ToFloat(uint16_t wordValue)
{
int8_t exponent = wordValue>>11; // extract exponent as MS 5 b its
int16_t mantissa = wordValue & 0x7ff; // extract mantissa as LS 11 bits
if ( exponent > 0x0F ) exponent |= 0xE0; // sign extend exponent
if ( mantissa > 0x03FF ) mantissa |= 0xF800; // sign extend mantissa
return mantissa * pow(2,exponent); // compute value as
// mantissa * 2^(exponent)
}
// convert a LinearFloat5_11 formatted word into a floating point value
float linear16ToFloat(uint8_t exp,uint16_t wordValue)
{
int8_t exponent = exp; // extract exponent as MS 5 b its
int16_t mantissa = wordValue; // extract mantissa as LS 11 bits

if ( exponent > 0x0F ) exponent |= 0xE0;    // sign extend exponent  
if ( mantissa > 0x03FF ) mantissa |= 0xF800;  // sign extend mantissa
return mantissa * pow(2,exponent);         // compute value as
                                           // mantissa * 2^(exponent) 
}

double ByteRequest(byte DeviceAddr, byte Command, int format){
byte ReceiveData = 0x00;
int wen = 0;
byte msb = 0;
byte lsb = 0;
double res = 0;
Wire.beginTransmission(DeviceAddr);
Wire.write(Command);
wen = Wire.endTransmission((uint8_t) false);

if (wen != 0) {
Serial.print("endTransmission error ");
Serial.println(wen);
}

Wire.requestFrom((uint8_t) DeviceAddr, (uint8_t) 2, (uint8_t) true);

if (Wire.available()) {
lsb = Wire.read();
msb = Wire.read();
} else {
Serial.println("No data on bus\r\n");
}

if(format==1)
res = linear16(msb,lsb);
else
res = linear11(msb,lsb);

Wire.beginTransmission(DeviceAddr);
Wire.write(Command);
wen = Wire.endTransmission((uint8_t) true);

return res;
}

hopefully someone else can help you with solving the other issues.

Thank you very much for your help.
I modified the code, and now there is no error, but the data is incorrect.

#include <Wire.h>

/* Address */
#define I2C_SLAVE_ADDR 0x38 
//const byte VCCINT     = 0x38;

/* Command */
const byte VIN        = 0x88;
const byte VOUT       = 0x8B;
const byte IOUT       = 0x8C;
const byte PW         = 0x01;

/* Register values */
double Vo        = 0;
double Vi        = 0;
double Io        = 0;
double P         = 0;

/* Function Prototype */
double ByteRequest(byte DeviceAddr, byte Command, int format); // format : 0 linear11, 1 linear16
float linear11(int8_t msb, uint16_t lsb);
float linear16(uint8_t msb, uint16_t lsb);

// convert a LinearFloat5_11 formatted word into a floating point value 
float linear11(int8_t msb, uint16_t lsb ) // msb :exponent  , lsb: mantisa 
{   
    int8_t exponent = msb>>11;       // extract exponent as MS 5 b its
    int16_t mantissa = lsb&0x7ff;  // extract mantissa as LS 11 bits    
    if ( exponent > 0x0F ) exponent |= 0xE0;    // sign extend exponent   
    if ( mantissa > 0x03FF ) mantissa |= 0xF800;  // sign extend mantissa
    return mantissa * pow(2,exponent);         // compute value as
                                               // mantissa * 2^(exponent) 
}
// convert a LinearFloat5_11 formatted word into a floating point value 
float linear16(uint8_t msb,uint16_t lsb) 
{   
    int8_t exponent = msb;       // extract exponent as MS 5 b its
    int16_t mantissa = lsb; // extract mantissa as LS 11 bits 
       
    if ( exponent > 0x0F ) exponent |= 0xE0;    // sign extend exponent  
    if ( mantissa > 0x03FF ) mantissa |= 0xF800;  // sign extend mantissa
    return mantissa * pow(2,exponent);         // compute value as
                                               // mantissa * 2^(exponent) 
}
 

void setup() {
  Serial.begin(9600);
  Wire.begin();
  Wire.setClock(100000L);
}

void loop() {
  Serial.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
  Vo = ByteRequest(I2C_SLAVE_ADDR, VIN, 0);
  Serial.print("Vin = ");
  Serial.print(Vo);
  Serial.println(" V");

  Vi = ByteRequest(I2C_SLAVE_ADDR, VOUT, 1);
  Serial.print("Vout = ");
  Serial.print(Vi);
  Serial.println(" V");

  Io = ByteRequest(I2C_SLAVE_ADDR, IOUT, 0);
  Serial.print("Iout = ");
  Serial.print(Io);
  Serial.println(" A");

  P  = ByteRequest(I2C_SLAVE_ADDR, PW, 0);
  Serial.print("Power = ");
  Serial.print(P);
  Serial.println(" W");

  delay(2000);
}


double ByteRequest(byte DeviceAddr, byte Command, int format){
  byte ReceiveData = 0x00;
  int wen = 0;
  byte msb = 0;
  byte lsb = 0;
  double res = 0;

  Wire.beginTransmission(DeviceAddr);
  Wire.write(Command);
  wen = Wire.endTransmission((uint8_t) false);

  if (wen != 0) {
    Serial.print("endTransmission error ");
    Serial.println(wen);
  }

  Wire.requestFrom((uint8_t) DeviceAddr, (uint8_t) 2, (uint8_t) true);

  if (Wire.available()) {
    lsb = Wire.read();
    msb = Wire.read();
  } else {
    Serial.println("No data on bus\r\n");
  }


  if(format==1)
    res = linear16(msb,lsb); // msb :exponent  , lsb: mantisa 
  else
    res = linear11(msb,lsb);

  Wire.beginTransmission(DeviceAddr);
  Wire.write(Command);
  wen = Wire.endTransmission((uint8_t) true);
  
  return res;
}

The result is as follows.

Vin = 62.50 V
Vout = 0.00 V
Iout = 0.00 A
Power = 128.00 W

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.