DIY Hyundai Ioniq 28 kWh -akun kuormitustesteri

Rakensin Hyundai Ioniq Electric 28 kWh:lle oman pienen BMS-testerin, jonka tarkoituksena on seurata ajoakun kennoryhmien käyttäytymistä oikean ajon aikana.

Ajatus on yksinkertainen: pelkkä paikallaan mitattu kennon jännite ei välttämättä paljasta heikentynyttä kennoryhmää. Kun akkua kuormitetaan kunnolla, heikomman ryhmän jännite voi pudota muita enemmän.

Laite lukee Ioniqin BMS:ää suoraan auton CAN-väylästä OBD-liittimen kautta ja tallentaa mittaukset microSD-kortille myöhempää analysointia varten.

Ensimmäisessä kunnollisessa testissä pääsin noin 94 kW purkutehoon, ja suurin havaittu kennoryhmien välinen ero oli vain 40 mV. Eli ainakin tämän testin perusteella 170 000 km ajetun Ioniqin akku näyttää erittäin tasaiselta.

Tarvittavat osat

  • ESP32-S3
  • SN65HVD230 CAN-transceiver tai vastaava 3,3 V CAN-moduuli
  • LM2596 step-down -muunnin
  • microSD SPI -moduuli
  • microSD-kortti, FAT32
  • OBD-liitin/OBD-jatkojohto
  • hetkellinen painonappi
  • johtoja, kotelo ym.

Kytkennät tässä projektissa:


CAN:
ESP32 GPIO 5  -> CAN TXD
ESP32 GPIO 6  <- CAN RXD

OBD pin 6  -> CAN-H
OBD pin 14 -> CAN-L
OBD pin 5  -> GND

Virransyöttö:
OBD pin 16 (+12 V) -> LM2596 IN+
OBD pin 4 (GND)    -> LM2596 IN-

LM2596 säädetty 5,0 volttiin:
OUT+ -> ESP32 5V/VIN
OUT- -> ESP32 GND

microSD:
GPIO 10 -> CS
GPIO 11 -> MOSI
GPIO 12 -> SCK
GPIO 13 -> MISO
5V      -> VCC
GND     -> GND

Testin nollausnappi:
GPIO 7 -> painonappi -> GND

HUOM! Auton OBD-liittimen 12 volttia EI saa kytkeä suoraan ESP32:een. Käytän välissä LM2596:ta, jonka ulostulo on säädetty yleismittarilla 5,0 volttiin.

Auton CAN-väylään ei myöskään lisätä omaa 120 ohmin terminointivastusta.

Miten Ioniqin BMS:ää luetaan?

Ioniq 28 kWh:n akussa on 96 sarjaan kytkettyä kennoryhmää. BMS:n diagnostiikkatietoja voidaan kysyä CAN-väylän kautta.

Tässä käytetyt ryhmät:


0x2101 = BMS:n perustiedot
0x2102 = kennoryhmät 1–32
0x2103 = kennoryhmät 33–64
0x2104 = kennoryhmät 65–96

BMS:n pyyntö lähetetään CAN ID:lle:


0x7E4

ja BMS vastaa ID:llä:


0x7EC

Kennon jännite saadaan raakadatasta:


cell_voltage = raw / 50.0

Eli esimerkiksi raakadata 199 tarkoittaa:


199 / 50 = 3,98 V

Vastaukset ovat ISO-TP-monikehyksisiä, joten First Framen jälkeen ESP32 lähettää BMS:lle flow-control-kehyksen.

Mitä ohjelma mittaa?

Nopeasta BMS-datasta tallennetaan mm.:


SOC
akun kokonaisjännite
akun virta
purku-/latausteho
alin kennoryhmä
ylin kennoryhmä
kennojen välinen delta
suurin testin aikana havaittu delta
heikoin kennoryhmä peak-hetkellä
teho peak-hetkellä

Lisäksi kaikki 96 kennoryhmää tallennetaan erilliseen tiedostoon.

SD-kortille syntyy:


ioniq_fast.csv
ioniq_cells.csv

ioniq_fast.csv sisältää nopean ajonaikaisen datan ja ioniq_cells.csv kaikkien 96 kennoryhmän jännitteet.

Arduino/ESP32-koodin perusidea

CAN alustetaan ESP32:n TWAI-ajurilla 500 kbit/s nopeudelle:


#define CAN_TX GPIO_NUM_5
#define CAN_RX GPIO_NUM_6

twai_general_config_t g_config =
    TWAI_GENERAL_CONFIG_DEFAULT(CAN_TX, CAN_RX, TWAI_MODE_NORMAL);

twai_timing_config_t t_config =
    TWAI_TIMING_CONFIG_500KBITS();

twai_filter_config_t f_config =
    TWAI_FILTER_CONFIG_ACCEPT_ALL();

twai_driver_install(&g_config, &t_config, &f_config);
twai_start();

BMS-ryhmän kysely tehdään esimerkiksi näin:


void requestBMS(uint8_t group) {
    twai_message_t msg = {};
    msg.identifier = 0x7E4;
    msg.data_length_code = 8;

    msg.data[0] = 0x02;
    msg.data[1] = 0x21;
    msg.data[2] = group;

    twai_transmit(&msg, pdMS_TO_TICKS(100));
}

Esimerkiksi:


requestBMS(0x01);  // 2101
requestBMS(0x02);  // 2102
requestBMS(0x03);  // 2103
requestBMS(0x04);  // 2104

ISO-TP First Framen jälkeen BMS:lle pitää lähettää Flow Control:


void sendFlowControl() {
    twai_message_t fc = {};
    fc.identifier = 0x7E4;
    fc.data_length_code = 8;

    fc.data[0] = 0x30;
    fc.data[1] = 0x00;
    fc.data[2] = 0x00;

    twai_transmit(&fc, pdMS_TO_TICKS(100));
}

Varsinaisessa ohjelmassa vastaukset kerätään ISO-TP:stä yhdeksi payloadiksi ja sen jälkeen puretaan tarvittavat arvot.

Esimerkki 2101-datan purkamisesta

Omassa toteutuksessani 2101-payloadista luetaan mm.:


float soc = payload[6] / 2.0;

int16_t rawCurrent =
    (int16_t)((payload[12] << 8) | payload[13]);

float currentA = rawCurrent / 10.0;

uint16_t rawVoltage =
    (payload[14] << 8) | payload[15];

float packVoltage = rawVoltage / 10.0;

float powerKW =
    (packVoltage * currentA) / 1000.0;

float maxCellV = payload[25] / 50.0;
uint8_t maxCell = payload[26];

float minCellV = payload[27] / 50.0;
uint8_t minCell = payload[28];

int deltaMV =
    round((maxCellV - minCellV) * 1000.0);

Testin nollausnappi

GPIO 7:n nappi aloittaa uuden testin nollaamalla peak-arvot.

Esimerkiksi:


pinMode(7, INPUT_PULLUP);

Painalluksen yhteydessä:


peakDeltaMV = 0;
peakPowerKW = 0;
weakCell = 0;

Serial.println("*** NEW BATTERY TEST ***");

Näin vanhan koeajon suurin delta ei jää seuraavan testin tuloksiin.

Tulosten analysointi

Tein lisäksi Python-ohjelman, joka lukee SD-kortin kaksi CSV-tiedostoa ja tekee niistä automaattisen HTML-raportin.

Raportissa näkyvät esimerkiksi:


Testin kesto
SOC alussa/lopussa
Suurin purkuteho
Suurin regen/latausteho
Suurin kennodelta
SOC ja teho suurimman deltan hetkellä
MIN/MAX kennoryhmä
useimmin alimmaksi mitattu kennoryhmä
teho ajan funktiona
kennodelta ajan funktiona
kaikkien 96 kennoryhmän poikkeamat
kiinnostavimmat kennoryhmät

Omassa testissä tulokseksi tuli:


SOC alussa:          84,5 %
SOC lopussa:         82,5 %
Suurin purkuteho:    94,0 kW
Suurin regen:       -38,6 kW
Suurin kennodelta:   40 mV
Delta @ SOC:          84,0 %
Delta @ teho:         92,5 kW
MIN kennoryhmä:       #10
MAX kennoryhmä:       #77

Tässä tapauksessa siis lähes täydellä, noin 92,5 kW kuormalla kennoryhmien suurin ero oli vain 40 mV.

Seuraavaksi tarkoitus on tehdä sama testi alemmalla SOC:lla, koska mahdollinen heikompi kennoryhmä tulee yleensä paremmin esille akun varaustason laskiessa.

Huomio tulosten tulkinnasta

Tällä laitteella ei mitata suoraan akun todellista kapasiteettia tai absoluuttista SOH-arvoa.

Tämä on ennen kaikkea kuormitustesteri kennoryhmien keskinäisten erojen löytämiseen.

Kennodeltaan vaikuttavat esimerkiksi:


SOC
kuormitus
akun lämpötila
mittaushetki
BMS:n mittausresoluutio

Siksi esimerkiksi 40 mV ei yksinään kerro akun kuntoa. Olennaisempaa on seurata, kasvaako ero voimakkaasti kuormituksen kasvaessa ja putoaako sama kennoryhmä toistuvasti muita alemmas.

Tässä projektissa käytetty luokittelu on tarkoituksella vain suuntaa-antava.

Ja tietenkin: CAN-väylällä touhutaan omalla vastuulla. Tämä ohjelma on tarkoitettu BMS-datan lukemiseen, ei auton ohjainlaitteiden muuttamiseen tai kirjoittamiseen.

CAN_akku_espi_aug25a.zip (6,0 Kt)

2 tykkäystä

Mielenkiintoinen projeckti

1 tykkäys

Kyllä on hieno seurata, miten voidaan

toimia. Ajankohtainen aihe :+1:

2 tykkäystä