Go Down

Topic: [SOLVED] SMBus and I²C-Wire-Library (Read 6984 times) previous topic - next topic

toonlumberjack

May 21, 2013, 12:03 pm Last Edit: May 22, 2013, 12:36 pm by toonlumberjack Reason: 1
Hi,

working on a Smart Battery. Want to read all the interesting data like voltage, innertemperatur, current,Capacity....

All these are done in seperated sketches. Now I want to put it in one big sketch and there I get problems I can't explain (see comments). It seems that the values are switched: Getting voltage-values during reading for temperature and vice versa.

Here is the code for the first attempt (getting voltage and temperature in one sketch):

Code: [Select]
#include "Wire.h"
#define bl03_address 0x0B

void setup()
{
Wire.begin();
Serial.begin(9600);


}

void getvoltage()
{
Wire.beginTransmission(bl03_address);
Wire.write(0x09);
byte one,second;
Wire.requestFrom(bl03_address, 2);
one= Wire.read();//should get 74; got 97
second=Wire.read();//should get 30; got B
Serial.println(one,HEX);
Serial.println(second,HEX);
double c= (second*256) + one;
Serial.println("Spannunng der BL03");
Serial.println(((c/3)*10/1000),2);
byte errorcode = Wire.endTransmission(bl03_address);
Serial.print("Errorcode=");Serial.println(errorcode);
}

void gettemperature()
{
Wire.beginTransmission(bl03_address);
Wire.write(0x08);
byte one=0,second=0;
Wire.requestFrom(bl03_address, 2);
one= Wire.read();//should get 97; got 74
second=Wire.read();//should get B; got 30
Serial.println(one,HEX);
Serial.println(second,HEX);
int c= (second*256) + one;
Serial.println("Temperatur der BL03");
Serial.println(((c/10)-273.15),2);
int errorcode = Wire.endTransmission(bl03_address);
Serial.print("Errorcode=");Serial.println(errorcode);
}

void loop()
{
 getvoltage();
gettemperature();
delay(5000);
}



Would totally appreciate replies.

pylon

Would help if you provided a link to the datasheet of that BL03, whatever that is.

toonlumberjack

Sorry for the lack of information. BL03 is a LiIon battery with Battery Managment System. It's like a black box for me. There is no datasheet available. So after reverse engineering I found out thats a SMBus Communciation to read out relevant data like Capacity, Current, Voltage,.....

So after spending a few hours searching in the forum, I found that a few guys have a similar problem. The SMBus protocol requires 2 Startbits and then one Stopbit. Something like this:

Startbit
WriteaddressBattery
Registeraddress (where the data is stored)
Startbit
ReadAddressBattery
Number of Bytes to write
Stopbit

Well, for one value like temperature, there is no problem. But putting two values in one programm the wire library seems not to be able to handle it correctly.

At the moment i have switched to the i2cmaster-Library from http://homepage.hispeed.ch/peterfleury/avr-software.html . But I'm would be totally happy to keep the Wire-Library.

toonlumberjack

graynomad

I haven't used either I2C or SMBus but my understanding is that they are both essentially the same, the differences being small and relating to clock speeds and voltage levels. Also SMBus has an ALERT signal.

In either case there are no start "bits", there is a single start "condition" and two acknowledge bits.

SMBus is very well documented, have you searched for the spec and other documentation?

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

toonlumberjack

Yeah i have the complete SMBus Documents.

What i have found for the Wire-Library was on

http://arduino.cc/en/Main/ReleaseNotes

Code: [Select]

ARDUINO 1.0.1 - 2012.05.21
...
* Added ability to generate repeated starts in the Wire library (in
  master mode).  Extra boolean parameters to endTransmission() and
  requestFrom() control whether or not to send a stop (or a repeated
  start instead).  (Todd Krein)
  http://code.google.com/p/arduino/issues/detail?id=663
...



So it seems to work. Will study http://code.google.com/p/arduino/issues/detail?id=663 now.

Thanks for reply
toonlumberjack

pylon

Quote
The SMBus protocol requires 2 Startbits and then one Stopbit.


I cannot find such a definition in the SMBus description on Wikipedia:

http://en.wikipedia.org/wiki/System_Management_Bus

I also used some SMBus devices which also didn't follow your description. Maybe your device is very special in this regard and introduced something special or you misinterpreted the start and stop condition to be start and stop bits (that are not bits because the clock line is not alternated). In any case, multiple start conditions are device specific and not part of the SMBus specification (to my knowledge).

Quote
Well, for one value like temperature, there is no problem. But putting two values in one programm the wire library seems not to be able to handle it correctly.


Please describe how this is meant. What does "one program" mean in this context?

Quote
At the moment i have switched to the i2cmaster-Library from http://homepage.hispeed.ch/peterfleury/avr-software.html .


i2cmaster is a software emulation of the I2C bus while twimaster does it in hardware like the Wire library.

toonlumberjack

Quote
I cannot find such a definition in the SMBus description on Wikipedia:


A Smart Battery IC needs the following and above mentioned transmission (pseudocode) without a stopbit between the startbits. And by the way: Wikipedia is not almighty ;-)

Quote

I also used some SMBus devices which also didn't follow your description

Yeah, totally right.

Quote

Maybe your device is very special in this regard and introduced something special or you misinterpreted the start and stop condition to be start and stop bits (that are not bits because the clock line is not alternated). In any case, multiple start conditions are device specific and not part of the SMBus specification (to my knowledge).


Well, I started with a white paper. After sniffing the data between a analyzing device, whose software is not open and which i could only use for a few hours, I decided to go that way. But I don't want to ignore that I could misinterpreted something.

Quote
Quote
Well, for one value like temperature, there is no problem. But putting two values in one programm the wire library seems not to be able to handle it correctly.


Please describe how this is meant. What does "one program" mean in this context?


Sorry. I'm not a native speaker. So what i meant was:
Reading one value in one sketch (in the loop() ) was no problem at all. But reading two values in one sketch got me the problem.

Quote
Quote
At the moment i have switched to the i2cmaster-Library from http://homepage.hispeed.ch/peterfleury/avr-software.html .


i2cmaster is a software emulation of the I2C bus while twimaster does it in hardware like the Wire library.


Well, it worked for me. So the issue is SOLVED for me.

Here the change in the code:

Code: [Select]
#include <i2cmaster.h>

int dev = 0x0B<<1;
int data_low = 0;
int data_high = 0;
int pec = 0;

void setup()
{
Serial.begin(9600);
i2c_init(); //Initialise the i2c bus
}

void getvoltage()
{
  i2c_start_wait(dev+I2C_WRITE);
  i2c_write(0x09);
  i2c_rep_start(dev+I2C_READ);
  data_low = i2c_readAck(); //Read 1 byte and then send ack
  data_high = i2c_readAck(); //Read 1 byte and then send ack
  pec = i2c_readNak();
  i2c_stop();

  double tempDataVoltage = 0x0000;
  tempDataVoltage = (data_high) *256 + data_low;
  double voltage = tempDataVoltage/3*10;
  //Serial.print("Spannung=");Serial.println(tempDataVolatge,HEX);
  Serial.print("Spannung in mV =");Serial.println(voltage,0);
}

void gettemperature()
{
  i2c_start_wait(dev+I2C_WRITE);
  i2c_write(0x08);
  i2c_rep_start(dev+I2C_READ);
  data_low = i2c_readAck(); //Read 1 byte and then send ack
  data_high = i2c_readAck(); //Read 1 byte and then send ack
  pec = i2c_readNak();
  i2c_stop();

  double tempDataTemperature = 0x0000;
  tempDataTemperature = (data_high) *256 + data_low;
  //Serial.print("Temperatur=");Serial.println(tempDataTemperature,HEX);
  double temperature=((tempDataTemperature/10)-273.15);
  Serial.print("Temperatur in Grad Celsius=");Serial.println(temperature,2);
}

void loop()
{

getvoltage();
gettemperature();
Serial.println("--------------------------------------------");
}


Go Up