kedd, október 13, 2015

Ford Bluetooth Audio - HU, HU, itt CDC(9GFO)

Szóval elvárások voltak, neki is láttam, bekábeleztem a kis breadboard-ot a leírás alapján.


Utána jött a kód értelmezése. A kód eredetileg a Yammp3/USB eszköz kódja volt és az lett átírva az Arduino-ra, Ezután egy másik fejlesztő még belenyúlt, és volt egy harmadik aki a Bluetooth modult illesztgette a rendszerhez és ez a kódon is nyomott hagyott, ugyanis a három fejlesztő három különböző gondolkodásmóddal, casing-el, változótípus deklarációval fejlesztett és most itt vagyok én szintén a saját elképzeléseimmel.
Elhatároztam, hogy semmi nem sürgős, nem kell kapkodni, bőven van idő és lehetőség kísérletezni, ezért nekiláttam, hogy beüzemeljem a kódot és kísérletezzek vele. Kitűztem egy útvonalat mérföldkövekkel ami nagyjából így épült fel:


---[ ACP kommunikáció a Nano hardware UART-ján ]-------------------------------

Ez volt talán a legnehezebb. A kódból kiiktattam az összes Bluetooth vezérlést, állapotkezeléseket és mindent ami nem szükséges közvetlenül ahhoz, hogy a fejegység úgy vegye, hogy egy CD-váltó van rákötve.

Az ACP (Ford Audio Control Protocol) egy RS485-ön 9600 baud-al, 9 bites adatokkal dolgozó protokoll. A problémák ott kezdődtek, hogy az arduino (pontosabban az ATmega328P) hardware uart-ja képes a 9 bites üzemmódra, de azt csak mindenféle regiszter bindzsizésekkel lehet beüzemelni, mert az alap rutinkönyvtárak nem támogatják. Először "megijedtem" tőle, de ahogy kicsit beleástam magam egyre érthetőbb lett és végül is tényleg csak pár plusz sor kellett ahhoz, hogy működjön.

És már itt előjött a műszerhiány. Mert persze az ember megnézi a kódot, megérti a kódot, aztán feltölti a kódot és a kód fut. Naja. Ha működik akkor szuper, mert mondjuk a rádió nem azt írja ki, hogy "CD ERROR" hanem azt, hogy "CD 1-01" ... de erre várnom kellett, mivel nem történt semmi.
Rengeteg hiba lehet: A kódban alapból van valami hiba; A fejegységem kicsit másképp akar kommunikálni; a Nano nem elég "erős" hozzá, hogy a feladatot elvégezze; vagy csak szimplán valami kábelezési gond.
De hogy derítse ki az ember ha nagyjából semmilyen műszere nincs. Ha lett volna egy oszcilloszkópom akkor valószínűleg egy fél napot eltöltök jelforma elemzéssel, dekódolással, hogy rájöjjek, hogy hol van a kutya elásva. De ehelyett egy sokkal egyszerűbb módot választottam: A LED mágikus erejét. Igen, egy darab fénypont.
Ehhez a kódot kellett úgy módosítani, hogy bizonyos pontokon kigyulladjon a led. PL: "jött adat a fejegységtől" (ez is mekkora mázli, hogy a kommunikáció úgy kezdődik, hogy előbb a fejegység küld adatot, így ha már azt tudjuk helyesen fogadni akkor túl nagy baj nem lehet), vagy ha az adatcsomagokban található ellenőrzőkód helyes.
Itt derült ki, hogy simán felcseréltem az A-B érpárt amin a kommunikáció megy, így konkrétan az adatok inverzét kaptam. Miután visszacseréltem őket a fejegység életre kelt és én nem lehettem boldogabb. Rögtön rá is kötöttem a számítógép hangkimenetét és az már a fejegységen keresztül szólt.

Végül is itt már van egy olyan eszközöm amivel már simán egy audio kábellel rá tudom vezetni a fejre a hangot, nagy baj nem lehet.

Szintén a nyomozás részeként "jobb híján" bevetettem a mobiltelefonom "lassított felvétel" funkcióját, hogy ellenőrizzem, hogy előbb kap-e adatot a fejegységtől az Arduino, vagy fordítva:



---[ ACP kommunikáció Software Serial-al ]-----------------------------

Elmentettem a működő verziót és nekiláttam a feketelevesnek.
Már előre tudtam, hogy ha a Bluetooth használni akarom akkor a kényelmes hardware uart-ot nem használhatom az ACP-hez, mivel csak az tudja azt a sebességet (115k2 baud) amivel a BT modul kommunikálni akar. Elkezdtem túrni a netet, olyan software-serial megoldások után ami tudja a 9 bites üzemmódot, de sajnos nem találtam ilyet, úgyhogy a standard 8 bites SWSerial rutinkönyvtárat átalakítottam és így be tudtam üzemelni ezt is.
Ekkor jött el az idő, hogy megrendeljem a bluetooth modult, hiszen most már közel 100%, hogy működni fog.


---[ ACP SWSerial + 115k2-es kommunikáció a HW UART-on ]------------------

Visszanyúltam az eredeti kódhoz és elkezdtem visszaemelgetni azokat a részeket amik az ACP adatforgalmából kiveszi azt, hogy épp milyen gomb lett megnyomva a fejegységen és ezt átalakítja olyan üzenetekké amit majd a BT modul meg fog érteni.
Itt jött elő, hogy az ACP protokoll egy hisztis kis picsa. Vagyis ha nem elég gyors a válasz a fejegység kérésére akkor máris kiírja, hogy "CD ERROR" és máris az antenna nélkül bekötött fm rádió sistergését lehet hallgatni.

Az Arduino Mega valószínűleg annyira gyorsan ki tudta szolgálni ezeket az eszközöket, hogy nem akasztotta meg a kommunikációt az, hogy "sorosan" futott a feldolgozás, vagyis a fejegységtől jött az üzenet aminek a hatására jelezte a rendszer a bluetooth modulnak, hogy "kérem a következő számot", majd az visszaszólt és még pont időben tudott válaszolni a rendszer a fejegységnek, hogy "OK".
Ezért átalakítottam (mivel nem feltétlen szükséges ez a működés) úgy a kódot, hogy a fejegységtől érkező üzenetre rögtön válaszolok valamit, majd ezután kezelem le a Bluetooth modult és ha valami olyasmi változott ami miatt a fejegységnek jelezni kellene akkor azt egy "status report" üzenettel elküldöm külön a fejnek.


---[ ACP SWSerial + 115k2 HW UART + "TX only" debug kimenet. ]-----------------------------

Írtam még egy kis lib-et az Arduino-hoz ami egy teljesen egyszerű "Tx-only" vagyis csak írni tudó software serial cucc, amivel ha szükséges akkor szöveges üzeneteket tudok kiírni úgy a nano-ból, hogy közben ez nem zavar bele sem az ACP-be, sem a Bluetooth kommunikációba.

Az első képen egy mobil-on fut a "debug", a másikon pedig egyszerre nézem, hogy mit küld(ene) a rendszer a Bluetooth felé (mivel még nincs meg a modul ezért a számítógép lett a virtuális modul) és hogy a debug kimeneten milyen infók vannak. A harmadig pedig az aktuális állapot :)


---[ CDC emulátor és Bluetooth modul kezelés ]------------------

Amikor már minden stabilan ment, eljött az az ideje egy komolyabb ráncfelvarrásnak. Az eredeti kódban szépen elásva volt maga az emulált CD-váltó (CDC) ezért úgy gondoltam kiszabadítom Willy-t. Külön file-ba került minden ami az ACP-től, Bluetooth-tól függetlenül csak arról szól, hogy egy CD váltó az hogyan is működik. Alap dolgok: bekapcsol, kikapcsol, következő számot kérnek tőle, vagy épp azt, hogy tekerjen bele az aktuálisan futó zenébe. 
Ez azért jó, mert ha az ACP protokollal épp az jön, hogy jöhet a következő szám, akkor nem közvetlenül kiszól a Bluetooth-nak, hanem közlöm a CDC emulátorral, hogy jöjjön a következő. Az pedig számon tartja az aktuális track azonosítóját, ezt visszaküldi a fejegységnek és szól a Bluetooth-nak, hogy jöhet a következő nóta. Így könnyebb hibát keresni és egyáltalán átlátni a működést.
Ugyan ez lett magával a Bluetooth (pontosabban az OVC6830 alapú eszköz) kezelésével is. Az eredeti kódban előre beégetett utasítások voltak mint a sokat mondó BT_Send(135), ezeket is lecseréltem jól nevesített függvényekre, OVC_NetxtTrack(),  rendes állapotkezelésre, stb. 
Így pl már azt is tudja a rendszer, hogy ha nincs a telefonnal összepárosodva akkor a fejegységen a "NO DISK" szerepel (ilyenkor marad cd-váltó üzemmódban a fejegység, nem vált vissza rádióba), párosodás alatt pedig "CHECK DISK" látszódik. Apró dolgok, de ez a maximum amit a visszajelzésekből ki lehet hozni.

1 megjegyzés:

  1. Nagyon ugyes vagy! Gratula! En a multheten kezdtem foglalkozni a dologgal, de nagyon nem tunt egyszerunek a kommunikacio.

    VálaszTörlés