Battery Management System (SMBUS,I2CBus)

Hallo zusammen,
ich habe eine smart intelligent Battery und ich will aus dieser diverse Daten auslesen.
Auf der kleinen Platine im inneren dieser Battery befindet sich der µ-Controller PIC14000. Die adresse des I2C busses habe ich bereits herausgefunden ! Und zwar ist dies 0x0b.

Leider stehe ich jetzt vor einer Wand und weis nicht weiter.
Wie bekomme ich jetzt aus diessem µ-Controller die nötigen Informationen (Spannung, Strom ...Serialnummer, Baujahr etc) heraus.

Ich bin dankbar um jede Hilfe die ich bekommen könnte !

MFG

Was für eine Battery ist es denn? Hersteller, Model?

Leider ist kein Hersteller bekannt. Das ganze ist ein Techniker Projekt.

Ich habe nur das akkupacket nackt bekommen d.h. mit Platine und Zellen !

Ohne Herstellerinformationen wirst du an keine Batterieinformationen kommen. Du brauchst ja irgendwelche Steuerbefehle auf die das System antworten muss.

Danke für deine Hilfe.

Ich habe nochmals nachgefragt also der Hersteller wäre Inspired energy.
Und da kommt für mich nur ein Akku in frage (12V,3,85Ah)
http://inspiredenergy.com/Standard_Products/NJ1020/NJ1020.htm

Wie kitzel ich jetzt die Informationen aus diesem µ-controller heraus.

Schau mal unter folgendem Link

http://sbs-forum.org/specs/sbdat110.pdf

Danke dir für deine schnelle Hilfe. Jetzt mus ich einmal schauen wie ich das bewerkstellige :slight_smile:

Hallo,

ich habe da einen Code im Netz gefunden aber irgendwie komme ich damit nicht zurrecht !

Könnte mir der ein odere andere evtl. einen Denkanstoss verpassen ?!

MFG

#include <Wire.h>
 

// include userdefined headers
#include "variables_constants.h"      // list of commands
#include "struct.h"                   // struct of Akku
#include "functions.h"                // functions

Server server(80);                    // define port of webserver

void setup()
{ 
  Serial.begin(19200);
  Serial.println("Begin I2C as Master ...");
  
  Wire.begin(); //Join I2C-Bus as Master
   
  
    }
  }
  
 
  
   
  Serial.println("Setup finished.");
}

Akku Akkupack; // create struct of datatype Akku
Akku *pAkkupack = &Akkupack; // create pointer on Akkupack, needed as parameter for functions

// --- Verfügbare Funktionen ---
  int log2(int);                                // calculates log2
  word ReadWord(byte);                          // read Word from I2C-interface
  byte ReadAkkupack(byte, Akku*);               // read data from all accupacks
  void PrintAllSerial(Akku*);                   // prints all data to com-port
   


void loop()
{
   
  
  if (Serial.read() ==0x52)
  {    // refresh Akku Parameters if "R" is send
        
        channel = 1;
        for(byte channel_count=1; channel_count <= 8; channel_count++)
        {
          byte choosed_channel = ReadAkkupack(channel, pAkkupack);         // read data from all accupacks
          Serial.print("Einlesen von Mux-Kanal: ");                        // print channel to com-port
          Serial.println(log2(choosed_channel));                           // Kanal = log2(choosedChannel)
          PrintAllSerial(pAkkupack);                                       // print all data to serial
         
          channel = channel << 1;                   // switch channel by shifting left, fill with zeros   
        }   
      
   }
  
   delay(2000);
  
}
#ifndef _functions_
#define _functions_

#include "struct.h";
//functions.h
/*
  Arduino doesn't support the function log2() by his own.
  The logarithm of any base other than the natural is the
  natural logarithm divided by the natural logarithm of the base.
  So, we get l2(x) by dividing ln(x) by ln(2).
*/
int log2(int x)
{
 return(log(x)/log(2)); 
}


/*
    reads an return 2 bytes (word)
    "command" is the command in order to commands.h, see datasheet BQ2060.
    word ReadWord(command);
*/
word ReadWord(byte command)    // read word
{
  byte RecLowbyte = 0;         // received highbyte
  byte RecHighbyte = 0;        // received lowbyte  
  Wire.beginTransmission(BMS); // begin transmission to adress of BQ2060
  Wire.send(command);          // send command as byte
  Wire.endTransmission();      // finish send
  
  //there are two options, first: answer is 2 bytes long, second: answer is 1 byte long.
  switch (int(command)) {
    case  int(0x01)     :
    case  int(0x02)     :
    case  int(0x03)     :
    case  int(0x04)     :
    case  int(0x05)     :
    case  int(0x06)	:
    case  int(0x08)	:
    case  int(0x09)	:
    case  int(0x0a)	:
    case  int(0x0b)	:
    case  int(0x0c)	:
    case  int(0x0d)	:
    case  int(0x0e)	:
    case  int(0x0f)	:
    case  int(0x10)	:
    case  int(0x11)	:
    case  int(0x12)	:
    case  int(0x13)	:
    case  int(0x14)	:
    case  int(0x15)	:
    case  int(0x16)	:
    case  int(0x17)	:
    case  int(0x18)	:
    case  int(0x19)	:
    case  int(0x1a)	:
    case  int(0x1b)	:
    case  int(0x1c)	:
    case  int(0x2f)	:
    case  int(0x3c)	:
    case  int(0x3d)	:
    case  int(0x3e)	:
    case  int(0x3f)	:
          Wire.requestFrom(BMS, 2);    // request 2 bytes from slave device
          RecLowbyte = Wire.receive();
          RecHighbyte = Wire.receive();
          break;
    case  int(0x07)	:
          Wire.requestFrom(BMS, 1);    // request 1 bytes from slave device
          RecLowbyte = Wire.receive();
          RecHighbyte = 0;
          break;
    default: break;                    //nothing 
  }
  
  return(word(RecHighbyte, RecLowbyte)); 

}

/*
    read data from all accupacks.
    void ReadAkkupack(channel of multiplexer, pointer on Akkupack);
*/
byte ReadAkkupack(byte channel, Akku* Akkumodul)
{
  Wire.beginTransmission(Mux);           // begin transmission to adress of multiplexer (mux)
  Wire.send(channel);                    // choose mux-channel
  Wire.endTransmission();                // finsh transmission to adress of mux
  
  Wire.requestFrom(BMS, 1);              // request 1 bytes from slave device
  byte choosed_channel = Wire.receive();  // save the ChannelSelectionBits (see datasheet PCA9548)
  
  // --- Read Word ---
  Akkumodul->RemainingCapacityAlarm = ReadWord(RemainingCapacityAlarm);
  Akkumodul->RemainingTimeAlarm = ReadWord(RemainingTimeAlarm);
  Akkumodul->BatteryMode = ReadWord(BatteryMode);
  Akkumodul->AtRate = ReadWord(AtRate);
  Akkumodul->AtRateTimeToFull = ReadWord(AtRateTimeToFull);
  Akkumodul->AtRateTimeToEmpty = ReadWord(AtRateTimeToEmpty);
  Akkumodul->AtRateOK = ReadWord(AtRateOK);
  Akkumodul->Temperature = ReadWord(Temperature);
  Akkumodul->Voltage = ReadWord(Voltage);
  Akkumodul->Current = ReadWord(Current);
  Akkumodul->AverageCurrent = ReadWord(AverageCurrent);
  Akkumodul->MaxError = ReadWord(MaxError);
  Akkumodul->RelativeStateOfCharge = ReadWord(RelativeStateOfCharge);
  Akkumodul->AbsoluteStateOfCharge = ReadWord(AbsoluteStateOfCharge);
  Akkumodul->RemainingCapacity = ReadWord(RemainingCapacity);
  Akkumodul->FullChargeCapacity = ReadWord(FullChargeCapacity);
  Akkumodul->RunTimeToEmpty = ReadWord(RunTimeToEmpty);
  Akkumodul->AverageTimeToEmpty = ReadWord(AverageTimeToEmpty);
  Akkumodul->AverageTimeToFull = ReadWord(AverageTimeToFull);
  Akkumodul->ChargingCurrent = ReadWord(ChargingCurrent);
  Akkumodul->ChargingVoltage = ReadWord(ChargingVoltage);
  Akkumodul->BatteryStatus = ReadWord(BatteryStatus);
  Akkumodul->CycleCount = ReadWord(CycleCount);
  Akkumodul->DesignCapacity = ReadWord(DesignCapacity);
  Akkumodul->DesignVoltage = ReadWord(DesignVoltage);
  Akkumodul->SpecificationInfo = ReadWord(SpecificationInfo);
  Akkumodul->ManufactureDate = ReadWord(ManufactureDate);
  Akkumodul->SerialNumber = ReadWord(SerialNumber);
  Akkumodul->PackConfigurationAndStatus = ReadWord(PackConfigurationAndStatus);
  Akkumodul->VCELL4 = ReadWord(VCELL4);
  Akkumodul->VCELL3 = ReadWord(VCELL3);
  Akkumodul->VCELL2 = ReadWord(VCELL2);
  Akkumodul->VCELL1 = ReadWord(VCELL1);
  
  return choosed_channel;                // return the ChannelSelectionBits (see datasheet PCA9548)
  
}

/*
    prints all data to com-port.
    void PrintAllSerial(pointer to Akkupack);
*/
void PrintAllSerial(Akku* Akkumodul)
{
  Serial.print("RemainingCapacityAlarm: ");
  Serial.print(Akkumodul->RemainingCapacityAlarm);
  Serial.println(" mAh, 10mWh");
  
  Serial.print("RemainingTimeAlarm: ");
  Serial.print(Akkumodul->RemainingTimeAlarm);
  Serial.println(" min");
  
  Serial.print("BatteryMode: ");
  Serial.print(Akkumodul->BatteryMode);
  Serial.println(" BIN");
  
   Serial.print("AtRate: ");
  Serial.print(Akkumodul->AtRate);
  Serial.println(" mA, 10mW");
  
  Serial.print("AtRateTimeToFull: ");
  Serial.print(Akkumodul->AtRateTimeToFull);
  Serial.println(" min");
  
  Serial.print("AtRateTimeToEmpty: ");
  Serial.print(Akkumodul->AtRateTimeToEmpty);
  Serial.println(" min");
  
  Serial.print("AtRateOK: ");
  Serial.print(Akkumodul->AtRateOK, BIN);
  Serial.println(" BIN");
  
  Serial.print("Temperature: ");
  Serial.print(Akkumodul->Temperature);
  Serial.println(" 0.1K");
    
  Serial.print("Voltage: ");
  Serial.print(Akkumodul->Voltage);
  Serial.println(" mV");
    
  Serial.print("Current: ");
  Serial.print(Akkumodul->Current);
  Serial.println(" mA");
  
  Serial.print("AverageCurrent: ");
  Serial.print(Akkumodul->AverageCurrent);
  Serial.println(" mA");
  
  Serial.print("AtRateTimeToEmpty: ");
  Serial.print(Akkumodul->AtRateTimeToEmpty);
  Serial.println(" min");
    
  Serial.print("MaxError: ");
  Serial.print(Akkumodul->MaxError);
  Serial.println(" %");
   
  Serial.print("RelativeStateOfCharge: ");
  Serial.print(Akkumodul->RelativeStateOfCharge);
  Serial.println(" %");
  
  Serial.print("AbsoluteStateOfCharge: ");
  Serial.print(Akkumodul->AbsoluteStateOfCharge);
  Serial.println(" %");
    
  Serial.print("RemainingCapacity: ");
  Serial.print(Akkumodul->RemainingCapacity);
  Serial.println(" mAh, 10mWh");
    
  Serial.print("FullChargeCapacity: ");
  Serial.print(Akkumodul->FullChargeCapacity);
  Serial.println(" mAh, 10mWh");
    
  Serial.print("RunTimeToEmpty: ");
  Serial.print(Akkumodul->RunTimeToEmpty);
  Serial.println(" min");
    
  Serial.print("AverageTimeToEmpty: ");
  Serial.print(Akkumodul->AverageTimeToEmpty);
  Serial.println(" min");
    
  Serial.print("AverageTimeToFull: ");
  Serial.print(Akkumodul->AverageTimeToFull);
  Serial.println(" min");
    
  Serial.print("ChargingCurrent: ");
  Serial.print(Akkumodul->ChargingCurrent);
  Serial.println(" mA");
    
  Serial.print("ChargingVoltage: ");
  Serial.print(Akkumodul->ChargingVoltage);
  Serial.println(" mV");
    
  Serial.print("BatteryStatus: ");
  Serial.print(Akkumodul->BatteryStatus, BIN);
  Serial.println(" BIN");
    
  Serial.print("CycleCount: ");
  Serial.print(Akkumodul->CycleCount);
  Serial.println(" cycles");
    
  Serial.print("DesignCapacity: ");
  Serial.print(Akkumodul->DesignCapacity);
  Serial.println(" mAh, 10mWh");
    
  Serial.print("DesignVoltage: ");
  Serial.print(Akkumodul->DesignVoltage);
  Serial.println(" mV");
  
  Serial.print("SpecificationInfo: ");
  Serial.print(Akkumodul->SpecificationInfo, BIN);
  Serial.println(" BIN");
  
  Serial.print("ManufactureDate: ");
  Serial.print(Akkumodul->ManufactureDate);
  Serial.println(" (year -1980)* 512 + month *32 + day");
  
  Serial.print("SerialNumber: ");
  Serial.print(Akkumodul->SerialNumber);
  Serial.println("");
  
  Serial.print("PackConfigurationAndStatus: ");
  Serial.print(Akkumodul->PackConfigurationAndStatus, BIN);
  Serial.println(" BIN");
  
  Serial.print("VCELL4: ");
  Serial.print(Akkumodul->VCELL4);
  Serial.println(" mV");
  
  Serial.print("VCELL3: ");
  Serial.print(Akkumodul->VCELL3);
  Serial.println(" mV");
  
  Serial.print("VCELL2: ");
  Serial.print(Akkumodul->VCELL2);
  Serial.println(" mV");
  
  Serial.print("VCELL1: ");
  Serial.print(Akkumodul->VCELL1);
  Serial.println(" mV");
  
  Serial.println(""); 
  Serial.println(""); 

}
#ifndef _struct_
#define _struct_
//struct.h
/*
  The datatype Akku is used to store all readable parameters
*/

typedef struct{
  unsigned int RemainingCapacityAlarm; //UNIT: mAh, 10mWh
  unsigned int RemainingTimeAlarm; //UNIT: minutes
  unsigned int BatteryMode; //UNIT: BIN
  int AtRate;  //UNIT: mA, 10mW 0021
  unsigned int AtRateTimeToFull ; //UNIT: minutes
  unsigned int AtRateTimeToEmpty ; //UNIT: minutes
  boolean AtRateOK ; //UNIT: Boolean
  unsigned int Temperature ; //UNIT: 0.1°K
  unsigned int Voltage ; //UNIT: mV
  int Current ; //UNIT: mA
  int AverageCurrent ; //UNIT: mA
  unsigned int MaxError ; //UNIT: percent
  unsigned int RelativeStateOfCharge ; //UNIT: percent
  unsigned int AbsoluteStateOfCharge ; //UNIT: percent
  unsigned int RemainingCapacity ; //UNIT: mAh, 10mWh
  unsigned int FullChargeCapacity ; //UNIT: mAh, 10mWh
  unsigned int RunTimeToEmpty ; //UNIT: minutes
  unsigned int AverageTimeToEmpty ; //UNIT: minutes
  unsigned int AverageTimeToFull ; //UNIT: minutes
  unsigned int ChargingCurrent ; //UNIT: mA
  unsigned int ChargingVoltage ; //UNIT: mV
  word BatteryStatus ; //UNIT: BIN
  unsigned int CycleCount ; //UNIT: cycles
  unsigned int DesignCapacity ; //UNIT: mAh, 10mWh
  unsigned int DesignVoltage ; //UNIT: mV
  unsigned int SpecificationInfo ; //UNIT: n/a
  unsigned int ManufactureDate ; //UNIT: n/a
  unsigned int SerialNumber ; //UNIT: integer
  word PackConfigurationAndStatus;  //UNIT: BIN
  unsigned int VCELL4; //UNIT: mV
  unsigned int VCELL3; //UNIT: mV
  unsigned int VCELL2; //UNIT: mV
  unsigned int VCELL1; //UNIT: mV
} Akku;


#endif
#ifndef _var_and_const_
#define _var_and_const_
//Variables.h
// --- I2C-adresses ---
const int BMS = B0001011;    //Adresse PIC 14000 0x16
 

 

// --- I2C-commands for BQ2060 ----
const byte  RemainingCapacityAlarm = 0x01; // SMBus ACCESS: read , UNIT: mAh, 10mWh
const byte  RemainingTimeAlarm = 0x02; // SMBus ACCESS: read , UNIT: minutes
const byte  BatteryMode = 0x03; // SMBus ACCESS: read , UNIT: BIN bit mapped
const byte  AtRate = 0x04; // SMBus ACCESS: read , UNIT: mA, 10mW

const byte AtRateTimeToFull = 0x05 ; // SMBus ACCESS: read , UNIT: minutes
const byte AtRateTimeToEmpty = 0x06 ; // SMBus ACCESS: read , UNIT: minutes
const byte AtRateOK = 0x07 ; // SMBus ACCESS: read , UNIT: Boolean
const byte Temperature = 0x08 ; // SMBus ACCESS: read , UNIT: 0.1°K
const byte Voltage = 0x09 ; // SMBus ACCESS: read , UNIT: mV
const byte Current = 0x0a ; // SMBus ACCESS: read , UNIT: mA
const byte AverageCurrent = 0x0b ; // SMBus ACCESS: read , UNIT: mA
const byte MaxError = 0x0c ; // SMBus ACCESS: read , UNIT: percent
const byte RelativeStateOfCharge = 0x0d ; // SMBus ACCESS: read , UNIT: percent
const byte AbsoluteStateOfCharge = 0x0e ; // SMBus ACCESS: read , UNIT: percent
const byte RemainingCapacity = 0x0f ; // SMBus ACCESS: read , UNIT: mAh, 10mWh
const byte FullChargeCapacity = 0x10 ; // SMBus ACCESS: read , UNIT: mAh, 10mWh
const byte RunTimeToEmpty = 0x11 ; // SMBus ACCESS: read , UNIT: minutes
const byte AverageTimeToEmpty = 0x12 ; // SMBus ACCESS: read , UNIT: minutes
const byte AverageTimeToFull = 0x13 ; // SMBus ACCESS: read , UNIT: minutes
const byte ChargingCurrent = 0x14 ; // SMBus ACCESS: read , UNIT: mA
const byte ChargingVoltage = 0x15 ; // SMBus ACCESS: read , UNIT: mV
const byte BatteryStatus = 0x16 ; // SMBus ACCESS: read , UNIT: BIN bit mapped
const byte CycleCount = 0x17 ; // SMBus ACCESS: read , UNIT: cycles
const byte DesignCapacity = 0x18 ; // SMBus ACCESS: read , UNIT: mAh, 10mWh
const byte DesignVoltage = 0x19 ; // SMBus ACCESS: read , UNIT: mV
const byte SpecificationInfo = 0x1a ; // SMBus ACCESS: read , UNIT: bit mapped
const byte ManufactureDate = 0x1b ; // SMBus ACCESS: read , UNIT: n/a
const byte SerialNumber = 0x1c ; // SMBus ACCESS: read , UNIT: integer
const byte PackConfigurationAndStatus = 0x2f; // SMBus ACCESS: read , UNIT: BIN bit mapped
const byte VCELL4 = 0x3c; // SMBus ACCESS: read , UNIT: mV
const byte VCELL3 = 0x3d; // SMBus ACCESS: read , UNIT: mV
const byte VCELL2 = 0x3e; // SMBus ACCESS: read , UNIT: mV
const byte VCELL1 = 0x3f; // SMBus ACCESS: read , UNIT: mV

#endif