Okos otthon is fókuszban

Arduino kalandok

Arduino kalandok

Autó okosítás - CAN adatok feldogozása - part 4

2019. december 18. - denx

Miután sikeresen inicializáltam a kapcsolatot BT-on keresztül az ELM adapterrel, most jön az, hogy a beérkező számhalmazt megpróbáljuk értelmezni is.

Sorok

Ahogy korábban említettem minden adat érkezése után küld egy soremelést is (pontosabban "kocsi vissza" karaktert) az adapter. Ez mindaddig igaz, amíg meg nem kérjük rá, hogy ne tegyen ilyet: "ATL0" parancs ugyanis erre veszi rá az ELM-et, de nekem erre pont nem volt szükségem, hiszen sokkal könnyebb úgy feldolgozni az adatokat, hogy sorokba van rendezve.

Én úgy szerveztem a kódomat, hogy a loop() függyvényben minden körben megnézem, hogy jött-e új karakter, ha igen, akkor azt elküldöm egy függvénynek. Az a függvény pedig pakolja bele egy puffer változóba a karaktereket, kivéve ha soremelés jött, mert akkor elkezdődik a sor értelmezése:

void processCAN(uint8_t value) {
if (value == 10 || value == 13) {
if (bufEnd > 0) {
processBuf(buf);
for (size_t i = 0; i < BUF_SIZE; i++) {
buf[i] = 0;
}
bufEnd = 0;
}
} else {
if (bufEnd < BUF_SIZE) {
buf[bufEnd++] = value;
} else {
log("### Buffer is full. Line is longer than expected.");
}
}
}

Szerintem eléggé magáért beszél a kód, ami pedig az üzenetek értelmezését illeti, azt egy másik kódrészlet csinálja

Értelmezés

Lássuk hogy is néz ki egy ilyen adatsor:

374 CE D0 31 FE 45 42 55 14

Itt az első 3 karakter a feladó modul címét jelzi (én legalábbis így tudom, de lehet nem pontos a megfogalmazásom). utána kettesével vannak hexa értékek, amiket tudni kell értelmezni. Ebben nagy segítséget jelent, ha már valakinek előtted sikerült ezt megtennie és van rá "recept". Nekem sokat segített az egyik márkaspecifikus fórum, ahol nagyon sok mindent kiokumláltak már. Ez a konkrét üzenet tartalmazza azt, hogy mekkora hatótávot jósol az autó magának a jelenlegi töltöttségből és az utóbbi idők használati statisztikáigól. Ezen felül benne van még az az infó is, hogy hány százalékon áll jelenleg az akksi.

Range

A hatótávot az utolsó 2 karakter mutatja, a konkrét példánál ez 14. Illetve 0x14, azaz 20 km. Hát ez nem volt túl bonyolult!

SOC

(Az SOC annak a rövidítése, hogy state of charge.)

Ez már kicsit trükkösebb, ezt ugyanis úgy kapjuk megy, hogy a második párosból kivonunk 10-et, majd elpsztjuk kettővel. vagyis 0xD0 = 208, ebből vonunk ki 10-et, azaz 198, amit el kell osztani 2-vel, vagyis 99%-on áll a példa szerint az akku. Röviden úgy lehet ezt megfogalmazni, hogy 

soc=(PID[0x374][1]-10)/2

ODO

Az ODO azt jelenti, hogy a kilométerszámláló mit mutat, vagyis összesen hány kilométert tett meg az autó. Ez még jól jöhet később, hosszabb távú statisztikához, illetve fogyasztás-kalkulációhoz ez még fontos lesz.

odo=PID[0x412][2]*65536+PID[0x412][3]*256+PID[0x412][4]

Megjegyzés: itt igazából arról van szó, hogy a 3-4-5. párosokat mint 6 jegyű hea számot kell venni és úgy dekódolni.

Speed

Ugyanebben az üzenetben szokott elrejtve lenni az aktuális sebesség is:

speed=PID[0x412][1]

AC töltés

Amikor az autót lassú töltővel töltjük, akkor egy úgynevezett fedélzeti töltő van használatban. Ez gyakorlatilag speciális csatlakozón keresztül kapja meg a konnektorban megjelenő 230V váltóáramot és annyi ampert, amennyit fel tud venni, illetve amennyi képes jönni a forrásból (pl konnektorból).

Mivel ez egy kicsi autó, kicsi az akksija is, nincs is benne túl nagy teljesítményű fedélzeti töltő. A jelenleg elterjedt szabványok szerint az itthon szabványos 230V akár 3 fázison keresztül is érkezhet a kocsiba, de mivel ez egy limitált képessgű töltő, így ebből ő csak 1 fázist tud használni, onnan is maximum 14A áramerősséget. Ezt gyorsan összeszorozva azt kapjuk, hogy a felvett teljesítmég maximum 3.2 kW.

A töltő megosztja a CAN buszona következő üzeneteket:

389 A4 EB 18 5B 54 4A 2A 00

Ebből amit ki lehet hámozni:

  • Bejövő áramerősség (voltban): ACamp=PID[0x389][6]/10 
    • ez a konkrét példában 4.2 A
  • Bejövő feszltség (amperben): ACvolt=PID[0x389][1]
    • konkrétan 235 V
  • Felvett teljesítmény (10% veszteség belekalkulálva, kilowattban): ACpower=ACamp*ACvolt*0.9/1000
    • példánkban 0.8883 kW

Feldolgozás

Nem fogok minden érték feldolgozását egyesébel publikálni, de nekem egy ilyen primitív kis kódrészletet sikerült összedobno, ami a célnak megfelel:

if (buf[0] == '3' && buf[1] == '7' && buf[2] == '4' && bufEnd > 8) {
uint8_t soc;
char c[3] = {buf[7], buf[8], 0};
char *end;
soc = (strtol(c, &end, 16)-10)/2;
}

 

A bejegyzés trackback címe:

https://ardu.blog.hu/api/trackback/id/tr3615346506

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása