Skip to content

Release v0.11

Release process: 19/09/2025 - 29/10/2025

BMS Analog

  • DaisyChain Logic in Charger
  • Cell Balancing of Set (not only own pack)

BMS LED display & Error handling

  • Overvoltage in charger not shown as error on LEDs
  • Error detection of Set (not only own pack)
  • Error detection of undervoltage (charger only) and non-disableable latches
  • SoC with fine granular mapping (still base on voltage measurement)
  • SoC LED flickering remove
  • SoC LED operat in Set (not only own pack)

BMS Others

  • Cyphal Node ID static in Copter
  • Cyphal Publish of fast complete data struct (starcopter.highdra.bms.BMSData.0.1)
  • Usage Statistic for temperature, current, voltage, state, ... (Flash file)

Cyphal Library

  • Cyphal TimeSync
  • Cyphal File Access
  • Cyphal custom LED commands (200)
  • Cyphal Identify command

CLI Integration Aspects

Notes for Update Steps v0.10 -> v0.11

  • Check current version (GetInfo + Registry/Hardware, Software Versions)
  • Save current registry content (Read and memorize all registers)
  • Perform a DFU to new v0.11
  • Check version (GetInfo)
  • ! No reboot / power off for 10s (MCUBoot Image is verified after 10s)
  • Apply changes to the Registry (see table below)
  • Set the RTC time (y cmd <node> 101 <date --rfc-3339=seconds>)
  • Calibrate the Analog Sensing
    • maybe activate the pack in 6 pack parallel Charger
    • wait until all voltages are constant (pack wide balancing)
    • measure and apply the calibration to all packs

v0.10 -> v0.11 Update Relevant Features

  • BMS are handled now in Sets (Set_ID & Set_Index required).
  • For DaisyChain (and pack balance), external calibration is recommended.
  • Cyphal Node ID in Copter is set static to BMS location/position (v0.10: PnP in Copter).
  • New Cyphal struct for BMS Data is published with v0.11.
  • Flash now holds statistic files (Initial in v0.11, Struct may change lateron -> update data within from now on).

v0.10 -> v0.11 Register Changes

Name Type Value Flags Required Change?
bms.board.hardware.bms_id string '2032315255325016005D004300000000' M P -
bms.board.hardware.flash_date string '2025-08-18 15:12:55+02:00' M P update date to flashing date
bms.board.hardware.pack_sn natural32[1] 0 M P is required now
bms.board.hardware.set_id natural16[1] 555 M P is required now
bms.board.hardware.set_index natural8[1] 5 M P is required now
bms.board.hardware.version natural8[2] [4, 1]   P -
bms.board.software.version natural8[2] [0, 11]   P 0.10 -> 0.11
bms.cell_balance.threshold real32[1] 0.01 M P -
bms.measurement.ibat.offset real32[1] 0.0 M P external calibration!
bms.measurement.vbat.gain real32[1] 1.0 M P external calibration!
bms.measurement.vpack.gain real32[1] 1.0 M P external calibration!
log.can.active natural8[1] 1 M P -
log.can.severity natural8[1] 2 M P -
uavcan.node.description string 'Starcopter Highdra BMS' M P -
uavcan.node.id natural16[1] 72 M -
uavcan.pub.bms_data.dt_ms natural16[1] 100 M P - (new, default is fine)
uavcan.pub.bms_data.id natural16[1] 6064 M P - (new, default is fine)
uavcan.pub.bms_data.type string 'starcopter.highdra.bms.BMSData.0.1'   P - (new, default is fine)
uavcan.pub.energy_source.dt_ms natural16[1] 100 M P -
uavcan.pub.energy_source.id natural16[1] 6063 M P -
uavcan.pub.energy_source.type string 'reg.udral.physics.electricity.Power.0.1'   P -
uavcan.pub.power_data.dt_ms natural16[1] 2000 M P -
uavcan.pub.power_data.id natural16[1] 6060 M P -
uavcan.pub.power_data.type string 'starcopter.highdra.bms.PowerData.0.2'   P -
uavcan.pub.state.dt_ms natural16[1] 2500 M P -
uavcan.pub.state.id natural16[1] 6062 M P -
uavcan.pub.state.type string 'starcopter.highdra.bms.State.0.2'   P -
uavcan.pub.temp_data.dt_ms natural16[1] 2000 M P -
uavcan.pub.temp_data.id natural16[1] 6061 M P -
uavcan.pub.temp_data.type string 'starcopter.highdra.bms.TempData.0.1'   P -

v0.11 New Flash Files

Filename: cell_capacity_monitor.dat

struct cell_data_s {
 uint16_t struct_version = 1;
 uint16_t struct_size = sizeof(cell_data_s);
 uint32_t magic = 0xA5F0C3B2; // Magic number for data integrity check
 time_t save_timestamp = 0;
 float capacity_max = 0.0f;
 float current_cell_capacity = 0.0f;
 time_t last_full_timestamp = 0; // The last time the cell was fully charged
 float charge_change_amount_since_last_full = 0.0f;                   // The amount of charge lost since the last full charge
 float full_idle_voltage = 0.0f; // The voltage of the cell when it was last fully charged
 time_t last_empty_timestamp = 0; // The last time the cell was fully discharged
 float charge_change_amount_since_last_empty = 0.0f; // The amount of charge gained since the last full discharge
 float empty_idle_voltage = 0.0f; // The voltage of the cell when it was last fully discharged
 time_t next_capacity_max_update = 0;
 float capacity_max_filtered = NOMINAL_CELL_CAPACITY_WH;
};

Filename: cell_usage_monitor.dat

struct cell_use_statistic_s {
 float full_charge_energy{0.0f};    // in Ws
 float full_discharge_energy{0.0f}; // in Ws
};

Filename: pack_operation_range.dat

struct pack_operation_range_s {
 uint16_t struct_version = 1;
 uint16_t struct_size = sizeof(pack_operation_range_s);
 uint32_t magic = 0xA5F0C3B2; // Magic number for data integrity check
 time_t save_timestamp = 0;
    // Current intervals: -10000, -1000, 0, 1000, 10000, 999000
    // Voltage intervals: 16200, 21000, 22200, 24600, 999000
 int64_t operation_count_ms[6][5]{0}; // operation is <= limit V/A at interval
    // Temperature interval: -20000, ...<linear divided, 40x>..., 100000
 int64_t temperature_count_ms[42]{0}; // temp <= 0, ..., > last
 // FSM state
 int64_t fsm_state_count_ms[(int)BMS_FSM_STATE::END];
 // Error states:
 int32_t error_count_10s[(int)ERROR_TYPE::END];
 // startup count
 int32_t startup_count{0};
 // life time
 float average_active_time{0.f};
 uint32_t average_active_count{0};
 int64_t life_time_active_ms{0};
};