example addd, some renaming and minor changes

This commit is contained in:
mes 2021-04-10 12:51:20 +02:00
parent 4f1e5c8de9
commit b7097f0894
7 changed files with 662 additions and 1 deletions

111
README.md
View File

@ -1,2 +1,111 @@
# IBS-Sensor-Library
Hella IBS 200A Battery Sensor via LIN-Bus
Hella IBS 200X Lead-Battery Sensor (Gen 1) via LIN-Bus
A IBS 200X sensors overserves the charge and health state of a Lead-Battery. Data can be read out via Lin interface, and this can easily be done with this library.
You can provide a LIN-Interface object to the IBS-Sensor object, wich is used to read and write on the bus. Therefore you can plug additional physical sensors on the Lin line and accordingly link additional devices on the software side to the Lin-Interface.
# dependencies
The Lin Interface utilizes a Hardware Serial (UART) of an ESP32. To make the code reusable, I provided a separate Library: https://github.com/mestrode/Lin-Interface-Library
I've used a TJA1020 Transceiver on HW side. The chip contains a statemachine, which needs to be controlled before you will be able to write or receive data. To keep thinks easy, I created a derived class which consider the statemachine every time using the bus: https://github.com/mestrode/Lin-Transceiver-Library
# example
This small example utilizes a hardware serial (UART) no 2 of an ESP32.
```cpp
// LIN Bus Interface provided viy TJA1020
#include "TJA1020.hpp"
// IBS Batterie Sensor
#include "IBS_Sensor.hpp"
#define LIN_SERIAL_SPEED LIN_BAUDRATE_IBS_SENSOR /* Required by IBS Sensor */
#define lin_NSLP_Pin 32
// utilize the TJA1020 by using UART2 for writing and reading Frames
Lin_TJA1020 LinBus(2, LIN_SERIAL_SPEED, lin_NSLP_Pin); // UART_nr, Baudrate, /SLP
// Hella IBS 200x "Sensor 2"
IBS_Sensor BatSensor(2);
void setup()
{
// tell the BatSensor object which LinBus to be used
BatSensor.LinBus = &LinBus;
}
void showSensorData() {
// read data from sensor (method request data by using several
// Lin-Frames)
BatSensor.readFrames();
// may you using a Bus-Transceiver which should go to sleep after
// transmission (depends on your HW)
LinBus.setMode(LinBus.Sleep);
// use received data
Serial.printf("Calibration done: %d &\n",
BatSensor.CalibrationDone);
Serial.printf("Voltage: %.3f Volt\n", BatSensor.Ubat);
Serial.printf("Current: %.3f Ampere\n", BatSensor.Ibat);
Serial.printf("State of Charge: %.1f %\n", BatSensor.SOC);
Serial.printf("State of Health: %.1f &\n", BatSensor.SOH);
Serial.printf("Available Capacity: %.1f &\n", BatSensor.Cap_Available);
}
```
There are mode data provided by the sensor, than shown in this small example.
# limitations
The manufacturer says the sensor will need aperiod of ~3h without current goint in or out of the battery to be calibratet (see CalibrationDone flag).
Not all Bytes and Frames are known to be interpreted, yet. But it's enough to use the sensor in an unrestricted way.
E.g. the main panel writes a configuration frame whose function is not known. But I decided to do configuration thinks like the mfg does.
Consider the Cap_Available tells you the theoretical available capacity. But the technology of lead batterys is limited, so you can use only ~50% of the labled capacity. Deeper discharge will damage the battery further.
# configuration of sensor
May you want to configure the sensor **once** to your specific battery.
Do not configure your sensor on every startup. This is also not needed, cause the data is stored in the sensor.
Actually you will only need to configure the sensor once, until you changed your battery physically (with different properties).
// configure sensor and provide Battery Type (AGM) and labeled capacity in Ah
BatSensor.writeConfiguration(BatSensor.BAT_TYPE_AGM, 180);
This will write three configuration Frames. The function for two of them is known. Anyway, I decided to write also the third, unknown frame since the original panel does this, too.
# hardware
## Productside of manufacturer
https://www.hella.com/microsite-electronics/en/Intelligent-battery-sensors-154.html
https://www.hella.com/microsite-electronics/en/Intelligent-battery-sensor-200X-491.html
In the meanwhile there is a second generation available.
https://www.hella.com/caravan/en/Intelligent-battery-sensor-1564.html
## Pinning of connector
Pin 1 = 12V (TBC)
Pin 2 = Lin (TBC)
## Connector Housing (2 pin MCON-1.2 LL type)
Connector is has coding A
If available, try the mirrored version, if not available, try a cutter.
872-858-565 (Hirschmann)
? (Tyco)
## Single crimp pin
7-1452671-1 (Tyco, MCON-1.2 LL, single wire seal)
### Single wire seal
2098582-1 (Tyco, will be ok for small wires)
# safety
follow the users manual of the manufacturer and inclde a fuse between battery plus pole and the 12V pin of the sensor
# see also
This library was created by using additional information form several sides. Thank you to the contributors!
* discussion in a german forum, contains the bus log (see folder "etc" of this project)
https://www.kastenwagenforum.de/forum/threads/diy-hella-ibs-batteriecomputer.31724/
* HW-Project fom Frank Schöniger on Github
https://github.com/frankschoeniger/LIN_Interface

View File

@ -0,0 +1,18 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:esp32doit-devkit-v1]
platform = espressif32
board = esp32doit-devkit-v1
framework = arduino
lib_deps =
https://github.com/mestrode/Lin-Interface-Library
https://github.com/mestrode/Lin-Transceiver-Library
https://github.com/mestrode/IBS-Sensor-Library

View File

@ -0,0 +1,52 @@
#include <Arduino.h>
// LIN Bus Interface provided viy TJA1020
#include <TJA1020.hpp>
// IBS Batterie Sensor
#include <IBS_Sensor.hpp>
#define LIN_SERIAL_SPEED LIN_BAUDRATE_IBS_SENSOR /* Required by IBS Sensor */
#define PIN_NSLP 23
// utilize the TJA1020 by using UART2 for writing and reading Frames
Lin_TJA1020 LinBus(2, LIN_SERIAL_SPEED, PIN_NSLP); // UART_nr, Baudrate, /SLP
// Hella IBS 200x "Sensor 2"
IBS_Sensor BatSensor(2);
void setup()
{
// Serial represents Serial(0)
Serial.begin(115200);
// configure slope rate
Serial.print("configure low slope rate of TJA1020\n");
LinBus.setSlope(LinBus.LowSlope);
// tell the BatSensor object which LinBus to be used
BatSensor.LinBus = &LinBus;
}
void showSensorData() {
// read data from sensor (method request data by using several
// Lin-Frames)
BatSensor.readFrames();
// may you using a Bus-Transceiver which should go to sleep after
// transmission (depends on your HW)
LinBus.setMode(LinBus.Sleep);
// use received data
Serial.printf("Calibration done: %d &\n", BatSensor.CalibrationDone);
Serial.printf("Voltage: %.3f Volt\n", BatSensor.Ubat);
Serial.printf("Current: %.3f Ampere\n", BatSensor.Ibat);
Serial.printf("State of Charge: %.1f %%\n", BatSensor.SOC);
Serial.printf("State of Health: %.1f %%\n", BatSensor.SOH);
Serial.printf("Available Capacity: %.1f &\n", BatSensor.Cap_Available);
}
void loop()
{
showSensorData();
delay(5000);
}

31
library.json Normal file
View File

@ -0,0 +1,31 @@
{
"name": "Hella IBS-200X Battery Sensor",
"version": "0.0.1",
"description": "Interface to a Hella IBS-200X Lead-Battery Sensor via LIN-Bus",
"keywords": [
"Hella",
"IBS",
"IBS 200X",
"Inteligent Battery Sensor",
"Battery Sensor",
"LIN",
"Lin-Bus"
],
"repository": {
"type": "git",
"url": "https://github.com/mestrode/IBS-Sensor-Library"
},
"authors": [
{
"name": "mestrode",
"maintainer": true
}
],
"license": "GPL-2.0-only",
"dependencies": [
{
"name": "LIN-Interface",
"version": "https://github.com/mestrode/LIN-Interface-Library.git"
}
]
}

10
library.properties Normal file
View File

@ -0,0 +1,10 @@
name=Hella IBS-200X Battery Sensor
version=0.0.1
author=mestrode <ardlib@mestro.de>
maintainer=mestrode <ardlib@mestro.de>
sentence=Interface to a Hella IBS-200X Battery Sensor via LIN-Bus
paragraph=handles the LIN Frames for interfacing the IBS Battery Sensor
category=sensors
url=https://github.com/mestrode/IBS-Sensor-Library
depends=Lin-Interface
license=GPL-2.0-only

343
src/IBS_Sensor.cpp Normal file
View File

@ -0,0 +1,343 @@
// IBS_Sensor.cpp
// Interfaces a Hella IBS-200X Battery Sensor via Lin-BUS
// Provides voltage, curret, State of Charge, etc.
//
// Copyright mestrode <ardlib@mestro.de>
// Original Source: https://github.com/mestrode/IBS-Sensor-Library
//
// Requires class Lin_Interface: https://github.com/mestrode/Lin-Interface-Library
//
// Includes informations provided by breezer
// https://www.kastenwagenforum.de/forum/threads/diy-hella-ibs-batteriecomputer.31724/page-2
// Includes informations from the code created by Frank Schöniger
// https://github.com/frankschoeniger/LIN_Interface
#include "IBS_Sensor.hpp"
//-----------------------------------------------------------------------------
// LIN Specification said abaout FrameIDs:
// 0-50 (0x00-0x3B) are used for normal Signal/data carrying frames.
// 60 (0x3C) and 61 (0x3D) are used to carry diagnostic and configuration data.
// 62 (0x3E) and 63 (0x3F) are reserved for future protocol enhancements.
//-----------------------------------------------------------------------------
// Frame IDs depends on SensorNo ("Sensor 1" or "Sensor 2" is marked on the label)
#define IBS_FRM_STA 0 /* 0x27 */
#define IBS_FRM_CUR 1 /* 0x28 */
#define IBS_FRM_ERR 2 /* 0x29 */
#define IBS_FRM_tb3 3 /* 0x2A */
#define IBS_FRM_SOx 4 /* 0x2B */
#define IBS_FRM_CAP 5 /* 0x2C */
// 0 1 2 3 4 5
// STA CUR ERR tb3 SOx CAP
const uint8_t IBS_FrameID[2][6] = {{0x21, 0x22, 0x23, 0x24, 0x25, 0x26}, // "Sensor 1"
{0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C}}; // "Sensor 2"
//-----------------------------------------------------------------------------
// There are additional Frames, the Sensor is responding to
// If you send one of those Frames to "Sensor 2", it will response:
// ID 34h - Resonse: 20:4E:20:4E:00:00:00:00
// ID 35h - Resonse: 00:00:00:00:00:00:00:00
// ID 36h - Resonse: 00:00:08:00:F8:FF
// ID 37h - Resonse: F4:2E:2D:00:00:00:00:00
// What does it mean?
//-----------------------------------------------------------------------------
// constructor
// constructor of class IBS_Sensor
IBS_Sensor::IBS_Sensor(int SensorNo) {
// "Sensor 1" = 1 => _SensorNo = 0;
// "Sensor 2" = 2 => _SensorNo = 1;
_SensorNo = SensorNo-1;
};
//-----------------------------------------------------------------------------
// Request current valus form sensor
/// Read current sensor data (at least all usefull frames)
/// @returns success of _all_ operations
bool IBS_Sensor::readFrames()
{
//ensure not work with received data (in case of a chksum error at the first run)
StatusReady = false;
//Read max 3 times sensor status / wait for valid data
for (int i=3; i>=0; i--) {
// StatusReady Flag is included in Frame "Status"
readFrameStatus();
if (StatusReady)
break;
}
if (!StatusReady) {
return false;
}
bool success = readFrameCurrent();
success = success && readFrameSOx();
success = success && readFrameCapacity();
// Dont know that to do with the results of Frame Error and TB3
// success = success && readFrameError();
// success = success && readFrameTB3();
return success;
}
// Request Frame "Status": only Ready Flag is asumed
/// @returns checksum of frame is valid, data accepted
bool IBS_Sensor::readFrameStatus()
{
// FrameID "Sensor 1" = 21h
// "Sensor 2" = 27h
// ID 27h - STA - D1 = identification, Bereitschaft des Sensors?
// LL = Statusbyte
// 01 = Sensor ready, data available flag ?
// Sends usually data like 192 194 208=linked to Cap_Max?
bool chkSumValid = LinBus->readFrame(IBS_FrameID[_SensorNo][IBS_FRM_STA]);
if (chkSumValid)
{
StatusByte = LinBus->LinMessage[0];
// Bit 0 seemed to be a kind of Data Ready Flag
StatusReady = LinBus->LinMessage[0] & 0x01;
}
return chkSumValid;
}
/// Request Frame CUR: Ubat, Ibat, Tbat and unknown1
/// @returns checksum of frame is valid, data accepted
bool IBS_Sensor::readFrameCurrent()
{
// FrameID "Sensor 1" = 22h
// "Sensor 2" = 28h
// ID 28h - CUR - AB:84:1E:F4:2E:84:7A
// IL IM IH = Ibat (x-2000000)/1000 Ampere, positive Werte = Batterie laden
// UL UH = Ubat x/1000 Volt
// TT = Tbat x/2-40 °C
// ?? = 0x7A and 0c7C observed, changes with event on unknown6?
bool chkSumValid = LinBus->readFrame(IBS_FrameID[_SensorNo][IBS_FRM_CUR]);
if (chkSumValid)
{
Ibat = (float((long(LinBus->LinMessage[2]) << 16) + (long(LinBus->LinMessage[1]) << 8) + long(LinBus->LinMessage[0]) - 2000000L)) / 1000.0;
Ubat = (float((LinBus->LinMessage[4] << 8) + LinBus->LinMessage[3])) / 1000.0;
Tbat = float(LinBus->LinMessage[5]) / 2 - 40;
unknown1 = LinBus->LinMessage[6];
}
return chkSumValid;
}
/// Request Frame "Error": only one Byte maybe with some Error Flags
/// @returns checksum of frame is valid, data accepted
bool IBS_Sensor::readFrameError()
{
// FrameID "Sensor 1" = 23h
// "Sensor 2" = 29h
// ID 29h - ERR - 00
// LL = Error flags or code
bool chkSumValid = LinBus->readFrame(IBS_FrameID[_SensorNo][IBS_FRM_ERR]);
if (chkSumValid)
{
ErrorByte = LinBus->LinMessage[0]; // IBS_Error bit code?
}
return chkSumValid;
}
/// Request Frame tb3: 4 bytes, but unknown content
/// @returns checksum of frame is valid, data accepted
bool IBS_Sensor::readFrameTB3()
{
// FrameID "Sensor 1" = 24h
// "Sensor 2" = 2Ah
// ID 2Ah - tb3 - 00:00:00:00
// HH LL = unknown2
// HH LL = unknown3
bool chkSumValid = LinBus->readFrame(IBS_FrameID[_SensorNo][IBS_FRM_tb3]);
if (chkSumValid)
{
unknown2 = (LinBus->LinMessage[1] << 8) + LinBus->LinMessage[0];
unknown3 = (LinBus->LinMessage[3] << 8) + LinBus->LinMessage[2];
}
return chkSumValid;
}
/// Request Frame SOH: SOH, SOC and 2 unknown Bytes and a unknown Word
/// @returns checksum of frame is valid, data accepted
bool IBS_Sensor::readFrameSOx()
{
// FrameID "Sensor 1" = 25h
// "Sensor 2" = 2Bh
// ID 2Bh - SOx - 2D:C8:FF:BB:00:00
// HH = State Of Charge x/2 in Prozent
// CC = State Of Health x/2 in Prozent
// ?? = unknown4 / has correlation to Cap_Available or SOC?
// ?? = unknown5 / no direkt link to unkown 4?
// H?:L? = unknown6 / maybe some corelation to Cap_Available or SOC?
bool chkSumValid = LinBus->readFrame(IBS_FrameID[_SensorNo][IBS_FRM_SOx]);
if (chkSumValid)
{
SOC = float(LinBus->LinMessage[0]) / 2; // state of health
SOH = float(LinBus->LinMessage[1]) / 2; // state of charge
unknown4 = LinBus->LinMessage[2]; // seemed to be a byte value
unknown5 = LinBus->LinMessage[3]; // seemed to be a byte value
unknown6 = (LinBus->LinMessage[5] << 8) + LinBus->LinMessage[4]; // word or 2 bytes, not verified
}
return chkSumValid;
}
/// Request Frame "Capacity": max seen, available and configured Capacity, Calibration
/// @returns checksum of frame is valid, data accepted
bool IBS_Sensor::readFrameCapacity()
{
// FrameID "Sensor 1" = 26h
// "Sensor 2" = 2Ch
// ID 2Ch - CAP - 20:03:B4:00:50:FE
// HH LL = Max seen Capacity x/10 Ah (=SOH ?)
// AL AH = Available Capacity x/10 Ah (=SOC)
// AH = Configured Capacity
// FF = CalibByte, maybe filled with stuffing bits?
// 01 = CalibrationDone flag, 1=ok, 0=uncalibrated
bool chkSumValid = LinBus->readFrame(IBS_FrameID[_SensorNo][IBS_FRM_CAP]);
if (chkSumValid)
{
Cap_Max = (float((LinBus->LinMessage[1] << 8) + LinBus->LinMessage[0])) / 10; // max. seen available Cap
Cap_Available = (float((LinBus->LinMessage[3] << 8) + LinBus->LinMessage[2])) / 10; // Available Capacity
Cap_Configured = LinBus->LinMessage[4]; // configured Cap
CalibByte = LinBus->LinMessage[5]; // eigentlich ist nur das Bit0 wichtig?
CalibrationDone = bitRead(LinBus->LinMessage[5], 0); // 1=calibration done 0=not finished yet
}
return chkSumValid;
}
//-----------------------------------------------------------------------------
// configuration of Sensor - only needed once: data will be stored in sensor
/// Configure BatSensor by sending 3 Configuration-Frames
void IBS_Sensor::writeConfiguration(IBS_BatteryTypes BatType, uint8_t BatCapacity)
{
writeUnknownParam(); // Not sure why
writeBatCapacity(BatCapacity); // nominal capacity (Ah)
writeBatType(BatType); // battery type (AGM, GEL or STARTER)
}
/// Write configuration Parameter "Unknown"
/// Parameter will be written by the configuration procedure used by the main panel
/// so I don't want to break tradition...
/// @returns no verification of success!!!
void IBS_Sensor::writeUnknownParam()
{
// Function of ths configuration Frame is unknown!
// Frame is send in configuration procedure by control panel, so why miss this out?
// guess this frame does
// - general Reset of the sensor?
// - configure initial battery status? (0x7F = 50% charge state)
// Request for configuration by main panel
// 00005.731 3c 02 06 b2 3a ff 7f ff ff 8b ERR
// ^^
// Response of sensor
// 00005.780 7d 02 02 f2 0a ff ff ff ff fe ERR
// ^^ guess this was not successful
LinBus->LinMessage[0] = 0x01 + _SensorNo; // Sensor No
LinBus->LinMessage[0] = 0x02; // Sensor No
LinBus->LinMessage[1] = 0x06; // Data Len
LinBus->LinMessage[2] = 0xB2; // CMD Config Read
LinBus->LinMessage[3] = 0x3A; // Config Type
LinBus->LinMessage[4] = 0xFF; // the unknown message = reset configuration?
LinBus->LinMessage[5] = 0x7F; // obviously not the first but the second byte will be written
LinBus->LinMessage[6] = 0xFF;
LinBus->LinMessage[7] = 0xFF;
LinBus->writeFrame(0x3C, 8);
LinBus->readFrame(0x3D);
}
/// Write configuration Parameter "Capacity" = Value of Ah of the Battery, default factory value = "80"Ah
/// @param BatCapacity labeled capacity (in Ah) of the lead battery
/// @returns no verification of success!!!
void IBS_Sensor::writeBatCapacity(uint8_t BatCapacity)
{
// Configuration (Of Sensor Type 1)
// Battery capacity can be read back on 0x2C Byte 4
// ID 3Ch - Capacity 02:03:B5:39: BatCap :FF:FF:FF - BatCap in Ah
LinBus->LinMessage[0] = 0x01 + _SensorNo; // Sensor No
LinBus->LinMessage[1] = 0x03; // Data Len
LinBus->LinMessage[2] = 0xB5; // CMD Config Read
LinBus->LinMessage[3] = 0x39; // Config Type
LinBus->LinMessage[4] = BatCapacity; // e.g. 70 Ah
LinBus->LinMessage[5] = 0xFF; // filling bytes
LinBus->LinMessage[6] = 0xFF;
LinBus->LinMessage[7] = 0xFF;
LinBus->writeFrame(0x3C, 8);
LinBus->readFrame(0x3D);
}
/// Write configuration Parameter "Battery Type" and read answer back (not judged)
/// @param BatType
/// @returns no verification of success!!!
void IBS_Sensor::writeBatType(IBS_BatteryTypes BatType)
{
// Battery Type can not be verified by using another Frame, since no Frame includes this data
// But recalibration is obviously needed, so CalibrationDone Flag should be an indicator for success
/* Procedure
00012.919 ec bc 02 dc 01 46 FF 30 CAP Sensor 2, is calibrated (FF)
00012.935 3c 02 03 b5 3a 1e ff ff ff ec ERR Config Sensor 2 Len 3 Conf =B5 Type 3a Data 1e
^^ = AGM parameter to be written
00012.988 7d 02 03 f5 3a 1e ff ff ff ac ERR Answer Sensor 2 Len 3 Conf+40=F5 Type 3a Data 1e
^^ = AGM readback --> confirmation of parameter from device
^^ = len+40 --> valid
00013.115 ec bc 02 dc 01 46 FE 31 CAP Sensor 2, is not calibrated (FE)
^ need to calibrate
*/
// ID 3Ch - STARTER Bat 02:03:B5:3A: 0A :FF:FF:FF|01
// GEL Bat 02:03:B5:3A: 14 :FF:FF:FF|F6
// AGM Bat 02:03:B5:3A: 1E :FF:FF:FF|EC
LinBus->LinMessage[0] = 0x01 + _SensorNo; // Sensor No
LinBus->LinMessage[1] = 0x03; // Data Len
LinBus->LinMessage[2] = 0xB5; // CMD Config Read
LinBus->LinMessage[3] = 0x3A; // Config Type
LinBus->LinMessage[5] = 0xFF; // filling bytes
LinBus->LinMessage[6] = 0xFF;
LinBus->LinMessage[7] = 0xFF;
switch (BatType)
{
case BAT_TYPE_STARTER:
LinBus->LinMessage[4] = 0x0a; // Starter Battery
break;
case BAT_TYPE_GEL:
LinBus->LinMessage[4] = 0x14; // GEL Battery
break;
case BAT_TYPE_AGM:
LinBus->LinMessage[4] = 0x1e; // AGM Battery
break;
}
LinBus->writeFrame(0x3C, 8);
LinBus->readFrame(0x3D);
}

98
src/IBS_Sensor.hpp Normal file
View File

@ -0,0 +1,98 @@
// IBS_Sensor.hpp
// Interfaces a Hella IBS-200X Battery Sensor via Lin-BUS
// Provides voltage, curret, State of Charge, etc.
//
// Copyright mestrode <ardlib@mestro.de>
// Original Source: "https://github.com/mestrode/IBS-Sensor-Library"
//
// Requires class Lin_Interface: https://github.com/mestrode/Lin-Interface-Library
//
// Includes informations provided by breezer
// https://www.kastenwagenforum.de/forum/threads/diy-hella-ibs-batteriecomputer.31724/page-2
// Includes informations from the code created by Frank Schöniger
// https://github.com/frankschoeniger/LIN_Interface
#pragma once
//#include <Arduino.h>
//This device needs a lin interface to read and write on
#include <Lin_Interface.hpp>
#define LIN_BAUDRATE_IBS_SENSOR 19200
class IBS_Sensor {
public:
// Batery types
enum IBS_BatteryTypes {
BAT_TYPE_STARTER,
BAT_TYPE_GEL,
BAT_TYPE_AGM
};
// constructor
IBS_Sensor(int SensorNo);
// Lin Interface will be used to send and request frames
Lin_Interface *LinBus;
// Frame "Status"
bool StatusReady = false; // ready for Data Request?
uint8_t StatusByte = 0x00; // provides at least a StatusReady flag, but the is more encoded
// Frame "Current"
float Ibat = 0.0; // Current in Ampere
float Ubat = 0.0; // Battery Voltage in Volt
float Tbat = 0.0; // Battery Temperature in Celsius
uint8_t unknown1 = 0x00;
// Frame "Error", flags / code unknown
uint8_t ErrorByte = 0x00; // Error code/flags?
// Frame "tb3", data unknown
uint16_t unknown2;
uint16_t unknown3;
// Frame "SOx", mayby includes State of Functon?
float SOH = -1.0; // procides State of Healt in percent
float SOC = -1.0; // procides State of Charge in percent
uint8_t unknown4;
uint8_t unknown5;
uint16_t unknown6;
// Frame "Capacity"
float Cap_Max = 0.0; // max seen capacity
float Cap_Available = 0.0; // max available capacity, means charge level
uint8_t Cap_Configured = 0; // configured battery capacity
bool CalibrationDone = false; // data may plausible, but sensor has still some doubts
uint8_t CalibByte = 0x00; // Capacity flag byte, may only contains CalibrationDone flag
//-----------------------------------------------------------------------------
// Request current valus form sensor
// regular read
bool readFrames();
// specific read of Frame
bool readFrameStatus();
bool readFrameCurrent();
bool readFrameError();
bool readFrameSOx();
bool readFrameCapacity();
bool readFrameTB3();
//-----------------------------------------------------------------------------
// configuration of Sensor - only needed once: data will be stored in sensor
//configuration of sensor
void writeConfiguration(IBS_BatteryTypes BatType, uint8_t BatCapacity);
// all known configuraton Frames, used by original Panel
void writeUnknownParam();
void writeBatCapacity(uint8_t BatCapacity);
void writeBatType(IBS_BatteryTypes BatType);
private:
// SensorNo = 0 --> Hella IBS 200 labeled "Sensor 1"
// SensorNo = 1 --> Hella IBS 200 labeled "Sensor 2"
int _SensorNo;
};