Servers by jDrones

Smart Battery via Arduino

Hello,
I tried to implement my own smart battery via I2C and based on the Maxell Battery.
Everything runs on an Arduino.
I managed to send data from the Arduino to the Pixhawk, but the values are strange.
For the single cell voltages I performed some tests:

  • Value on the Arduino / Value in Mission Planner:
  • 0 / 65,28
  • 1 / 65,281
  • 65125 / 65,381
  • 65534 / 65,534
  • 65535 / 0

For the other values the results are similar…
Since it’s always something with 65… I’m guessing it has something to do with the uint_8_max value…

Any idea what I should do to send appropriate voltages?

Thanks in advance
Vabe

Hello ,
Did you wrote the SBS protocol to send the data from arduino to Pixhawk ?
Did you set-up the flight controller to use SMBus Maxwell ?
The read voltage/Current use mV , any data will be divide / 1000.0f

 // read voltage (V)
    if (read_word(BATTMONITOR_SMBUS_VOLTAGE, data)) {
        _state.voltage = (float)data / 1000.0f;
        _state.last_time_micros = tnow;
        _state.healthy = true;
    }
BATTMONITOR_SMBUS_VOLTAGE=9

Check if the word is in the correct order (buff[1] high buff[0] low)

/ read word from register
// returns true if read was successful, false if failed
bool AP_BattMonitor_SMBus::read_word(uint8_t reg, uint16_t& data) const
{
// buffer to hold results (1 extra byte returned holding PEC)
const uint8_t read_size = 2 + (_pec_supported ? 1 : 0);
uint8_t buff[read_size];    // buffer to hold results

// read the appropriate register from the device
if (!_dev->read_registers(reg, buff, sizeof(buff))) {
    return false;
}

// check PEC
if (_pec_supported) {
    const uint8_t pec = get_PEC(AP_BATTMONITOR_SMBUS_I2C_ADDR, reg, true, buff, 2);
    if (pec != buff[2]) {
        return false;
    }
}

// convert buffer to word
data = (uint16_t)buff[1]<<8 | (uint16_t)buff[0];
// return success
return true;
}

Not really, I just looked which registers got called and searched their meaning in the ardupilot code, I didn’t even know about the full protocol.

Yes, I guess if there was a mistake there, i wouldn’t see a change in the single cell voltages, since they method is different for every battery.

I just use Wire.write(value), where I send a number:

uint16_t overall_voltage = 32400;

case 0x09: //overall voltage request
Wire.write(overall_voltage);
break;

I also tried setting a specification_info where pec is not available, since in there there is something changed with the values, but also this didn’t result in the expected numbers…

I’m developing a backend driver for smart battery Battgo by ISDT , the device use a serial to comunicate with the flight controller . In this case I can use a serial port to debug in SITL mode…
I tried to force a value as data=65535 ,the _state.voltage work as expected 65.535…


Sorry , i’m not i2c expert , but could be a problem with speed data ? a sort of data corrupt ?
I think the support for smart battery in ardupilot is not tested very wel. I didn’t find any smart battery in the market . In my opinino only ISDT battery could be a DIY solution .
If you are interested i wrote some informations in Github

IT WORKS!!!
I decided to investigate a bit more into highByte/lowByte and compared it to @ppoirier’s TFMINI to I2C, and in there I found highByte and lowByte, that was the only thing missing.

Now I can create a diy smart battery with an arduino…

I’ve already checked out BattGo, but I’m not really a fan of it, I would love to tinker with ALL values myself.

2 Likes

I finally found the time to assemble the prototype and it works, kinda.

Temperature is still messed up somehow, current isn’t calibrated etc, but as of now, all sensors are detected and shown in Mission Planner, now it’s time to code😀

1 Like
Servers by jDrones