As written in the subject I'm trying to simulate the communication of an Smart Battery accu pack which uses the SMBus. I need this for testing the software of a technical device which runs with told accu pack as power source. As we just want to test the software, not the hardware, we're trying to simulate as much as possible, including the communication over the SMBus.
The master device requests every second 38 different values from the accu pack, so we set up the Arduino as slave device which answers the requests with the appropriate data. Or at least it should. The Arduino gets the command, which data should be transfered and (after finally finding the problem) also answers the read-requests, but with the wrong data. It always sends 0x01 as lowByte and 0xFF as high/all other Bytes.
I already tried sending the data in various different ways, simply writing it with "Wire.write(variable)", separating high and low Byte with the according Functions and sending these and there are also some Strings to be send, neither of them worked yet. I could understand it, if the Hex-Integers just have a wrong format or can't be transmitted that way, but why does the transmitting of the Strings fail as well?
I hope you can help me with this problem, I don't really know what to do now.
Following the full programm code. It's quite long because we have such many variables and a bit messed up from the tests with different transmitting methods.
I removed most of the comments, because it exceeded the maximum message length, just if you're wondering. I attached the full programm to this post, if you want to take a look at the comments.
#include <Wire.h>
// The Following variables are write only by the Serial Interface
// and read Only for the I2C Master all other Values for the Smart battery are constants
unsigned int Temperature = 2980;
unsigned int Voltage = 11000;
signed int Current = -300;
unsigned int RelativeStateOfCharge = 100;
unsigned int AbsoluteStateOfCharge = 100;
unsigned int RemainingCapacity = 2700;
unsigned int BatteryStatus = 0x00C0;
unsigned int RunTimeToEmpty = 700;
unsigned int AverageTimeToEmpty = 700;
// The following constants are Smart Battery Values which are constant but still be requested
const unsigned int ManufactureAccess = 0x010A;
const unsigned int RemainingCapacityAlarm = 0x0000;
const unsigned int RemainingTimeToAlarm = 0x0000;
const unsigned int BatteryMode = 0x6001;
const signed int AtRate = 0x0000;
const unsigned int AtRateTimeToFull = 0xFFFF;
const unsigned int AtRateTimeToEmpty = 0xFFFF;
const boolean AtRateOK = 0x0001;
const signed int AverageCurrent = -268;
const unsigned int MaxError = 0x0001;
const unsigned int FullChargeCapacity = 3265;
const unsigned int AverageTimeToFull = 0xFFFF;
const unsigned int CycleCount = 0x00C0;
const unsigned int DesignCapacity = 3350;
const unsigned int DesignVoltage = 10800;
const unsigned int SpecificationInfo = 0x31;
const unsigned int ManufactureDate = 0x42C5;
const unsigned int SerialNumber = 0x0002;
const char ManufacturerName[] = "DREAGER";
const char DeviceName[] = "IP1-3S1p-000000022";
const char DeviceChemistry[] = "LI0N";
const char ManufacturerData[] = "0x0E0001000100010001000C000B0000";
//more constants
const unsigned int ChargingCurrent = 0x0658;
const unsigned int ChargingVoltage = 0x3138;
const char OptionalFunction[] = "0x140000000000000000000000000000000000000000";
const unsigned int VoltageCell1 = 0;
const unsigned int VoltageCell2 = 3500;
const unsigned int VoltageCell3 = 3500;
const unsigned int VoltageCell4 = 3500;
const char ErrorMessage[] = "something";
char adress = ' ';
String value = "";
boolean stringComplete = false;
boolean request = false;
int command = -1;
void setup() {
Wire.begin(11);
Wire.onReceive(receiveEvent);nt
Wire.onRequest(requestEvent);
Serial.begin(9600);
value.reserve(20);
}
void loop() {
if (stringComplete) {
switch(adress) {
case 'a': Temperature = value.toInt(); break;
case 'b': Voltage = value.toInt(); break;
case 'c': Current = value.toInt(); break;
case 'd': RelativeStateOfCharge = value.toInt(); break;
case 'e': AbsoluteStateOfCharge = value.toInt(); break;
case 'f': RemainingCapacity = value.toInt(); break;
case 'g': BatteryStatus = value.toInt(); break;
case 'h': RunTimeToEmpty = value.toInt(); break;
case 'i': AverageTimeToEmpty = value.toInt(); break;
default: break;
}
adress = ' ';
value = "";
stringComplete = false;
}
}
void serialEvent() {
while (Serial.available()) {
char inChar = (char)Serial.read();
if (adress == ' ') {
adress = inChar;
} else {
value += inChar;
}
if (inChar == '\n') {
stringComplete = true;
}
}
}
void receiveEvent(int numOfBytes)
{
command = Wire.read();
}
void requestEvent()
{
switch(command){
case 0:
Wire.write(lowByte(ManufactureAccess));
Wire.write(highByte(ManufactureAccess));
break;
case 1: Wire.write(RemainingCapacityAlarm); break;
case 2: Wire.write(RemainingTimeToAlarm); break;
case 3: Wire.write(BatteryMode); break;
case 4: Wire.write(AtRate); break;
case 5: Wire.write(AtRateTimeToFull); break;
case 6: Wire.write(AtRateTimeToEmpty); break;
case 7: Wire.write(AtRateOK); break;
case 8: Wire.write(Temperature); break;
case 9: Wire.write(Voltage); break;
case 0x0a: Wire.write(Current); break;
case 0x0b: Wire.write(AverageCurrent); break;
case 0x0c: Wire.write(MaxError); break;
case 0x0d: Wire.write(RelativeStateOfCharge); break;
case 0x0e: Wire.write(AbsoluteStateOfCharge); break;
case 0x0f: Wire.write(RemainingCapacity); break;
case 0x10: Wire.write(FullChargeCapacity); break;
case 0x11: Wire.write(RunTimeToEmpty); break;
case 0x12: Wire.write(AverageTimeToEmpty); break;
case 0x13: Wire.write(AverageTimeToFull); break;
case 0x14: Wire.write(ChargingCurrent); break;
case 0x15: Wire.write(ChargingVoltage); break;
case 0x16: Wire.write(BatteryStatus); break;
case 0x17: Wire.write(CycleCount); break;
case 0x18: Wire.write(DesignCapacity); break;
case 0x19: Wire.write(DesignVoltage); break;
case 0x1a: Wire.write(SpecificationInfo); break;
case 0x1b: Wire.write(ManufactureDate); break;
case 0x1c: Wire.write(SerialNumber); break;
case 0x1d: Wire.write("TBD"); break;
case 0x1e: Wire.write("TBD"); break;
case 0x1f: Wire.write("TBD"); break;
case 0x20: Wire.write(ManufacturerName); break;
case 0x21: Wire.write(DeviceName); break;
case 0x22: Wire.write(DeviceChemistry); break;
case 0x23: Wire.write(ManufacturerData); break;
case 0x3c: Wire.write(VoltageCell1); break;
case 0x3d: Wire.write(VoltageCell2); break;
case 0x3e: Wire.write(VoltageCell3); break;
case 0x3f: Wire.write(VoltageCell4); break;
//default: Wire.write(ErrorMessage); break;
}
}
Arduino_changeValue.ino (7.94 KB)