Impedancia mérés Raspberry Pi-vel Pythonban

Ennek a kis python kódnak az elődjét eredetileg jelfeldolgozási algoritmusok kipróbálgatására-fejlesztgetgetésére szántam, melynek célja egy esetleges későbbi mikrovezérlős kézi T/S-mérő fejlesztésében egyfajta előre dolgozás lett volna. Végül oda fejlődött a kis kódocska, hogy már önállóan kezelte a hangkártyát, azaz algoritmus szimuláció helyett már igazi méréseket tudott végezni. Kipróbálva a python kódot Raspberry Pi 4-esen, azon is probléma nélkül futott és tette a dolgát, az USB-n rácsatlakoztatott E-MU 0202 és a Steinberg UR22 hangkártyákkal is! Ezzel a korábbi mikrokontrolleres ötletet akár fel is válthatja egy R-Pi-s megvalósítás. Némi kódtisztítás, kommentbeszúrás után kvázi "kiadható" formát kapott a programkód.

kép

Amire jelenleg szerényen ugyan, de képes: Lekalibrálja a mérőrendszert, megméri a bekötött hangszóró (vagy egyéb dolog, pl. váltóalkatrész) impedanciamenetét a beállított frekvenciasávban és beállított felbontásban, menti a kapott eredményt egy ZMA fileba, valamint fel is rajzolja azt egy grafikonba, hogy azért valamit lássunk is belőle.

Ami a lehetséges jövőjét illeti: ebből is lehet dobozolható impedancia és T/S paraméter mérőt készíteni, sőt mivel sokkal erősebb hardver, mint egy sima 32 bites mikrokontroller, így akár egy teljes komplett mérőrendszert is lehetne készíteni, 3D nyomtatt házban, reflexiómentesen beépített mikrofonnal (hangnyomás-mérőkhöz hasonlóan a mikrofonnál elkeskenyedő ház) akár az akusztikai méréseket is tudhatná. Saját kijelzés és kezelőszervekkel nem kellene monitor és billentyűzet hozzá, de akár hálózaton is el lehetne érni egy webalapú kezelőfelületen pl. egy tablettel vagy mobiltelefonnal az R-Pi-be feltelepített Apache szerver jóvoltából wifi hálózaton keresztül. A lehetőségeknek mint látható, csak a képzelet szab határt!

Miért is kell nekünk ez a Python alapú fapados mérőprogram, mikor ott vannak a jó kis bevált szoftvereink? (Atra, LspLAB, stb.)

Hát, lássunk pár érvet:

  • Látjuk hogyan működik, hogyan végzi a jelfeldolgozást, hogyan számol, tehát tanulni tudunk belőle!
  • Bele is tudunk nyúlni, átírni, megnézni úgy mi történik, azaz tanulni tudunk belőle!
  • Beleírhatunk egyedi perverziókat is, azaz 100%-ban testreszabható a mérési mód
  • A Python platformfüggetlen nyelv, és a választott kiegészítők is (beleértve a hangkártya kezelését is) platformfüggetlenek, gyakorlatilag a kódnak tök mindegy, hogy Windowson, vagy Linuxon indítod-e el (olyannyira, hogy módosítás nélkül viheted át egyikről a másikra!)
  • A kód tesztelten működik Raspbery Pi 4-esen, mely megnyitja a lehetőséget egy hasonló projekt előtt, mint amit a bevezetőben említettem, azaz kicsi, kompakt, hordozható, saját kijelző és kezelőfelülettel rendelkező T/S kéziműszer irányába. Az R-Pi-n vannak GPIO lábak, tudnak vezérelni dolgokat (LED-eket, reléket, nyomógombokat leolvasni), van SPI, I2C busz, amin tud kezelni kijelzőt, és van I2S busza, amivel tud kezelni audio DAC és ADC chipeket! Bár én USB hangkártyát kötöttem rá (EMU 0202, Steinberg UR22), de lehet venni illetve készíteni saját DAC/ADC modult is hozzá. Vagy még az is játszhat, hogy csak ADC-t kap, és a DAC helyett egy DDS függvénygenerátorral állítunk elő mérőjelet, ugyanis SPI buszon képes lehet egy ilyen IC-t vezérelni.

Mérési módszerek

A kód az un. stepped sine, azaz lépcsőzetes szinuszjeles mérést alkalmazza. Azonban pár mondatban összefoglalnám, milyen egyéb mérési módok jöhetnének még számításba. A stepped sine még a szimulációs cél miatt lett elsősorban választva, mivel a mikrokontrolleres eszközben egyedül ezt lehet reálisan megvalósítani a gyakorlatilag zéró memóriaigénye és a szintén közel zéró számításigénye végett. A lehetséges alternatívák amúgy a következők:

  • Stepped (lépcsőzetes) szinusz

    Lépcsőzetesen növekvő szinusz csomagok, lényegében diszkrét jelcsomagokkal végigmérjük a frekvenciasávot adott nagyságú ugrásokkal. A mérési idő több perc is lehet (tipikusan kb 3-5, de akár 10-20 perc, vagy még több is, ha nagyon feltoljuk a felbontást, azaz nagyon kicsiket lépkedünk, vagy nagyon alacsony frekvenciáról (pl. 1-2Hz) indítjuk a mérést) A feldolgozás szinusz és koszinusz jellel történő korreláción alapul. Ezzel csak harmonikussal gerjesztünk, és a visszamért jelben csak az alapharmonikust mérjük, így eliminálja a felharmonikusokat és zaj nagy részét, ezért nem hamisítja a zaj és torzítás (nemlineáris viselkedés) meg a mérést. Továbbá a harmonikus gerjesztés miatt csak a harmonikus torzítást hozza ki a mérendő rendszerből, a többi torzításfajtát nem, de ezt is eliminálja. Nagyon pontos, nem igényel előre bufferelést, az adatok akár röptében is feldolgozhatók, minimális számítási kapacitást igényel.
  • Hosszú szinusz sweep- (folyamatosan és lassan (akár percekben mérhető) változó szinuszjel.

    Feldolgozása itt is korreláció alapú, FFT-hez túl nagy adatmennyiséget jelentene. Pontossága és számítási igénye megegyezik az előbbivel. Precíz "lejátszás/felvétel" együttfutást (gyakorlatilag zéró latency-t igényel a hangkártyától) Emiatt PC-n hangkártyával nem egyszerű eset.
  • Rövid szélessávó jelek (zaj, gyors szinusz sweep, multitone, multisweep stb.)

    Kifejezetten FFT alapú mérés, rövid szélessávú jellel (kvázi minden frekvencia benne van). Maga a jel lehet ilyen-olyan zaj, gyors szinusz sweep, különféle un. multitone, multisweep stb. Sweep esetén korreláció nem alkalmazható, ahhoz túl gyorsan változik a frekvencia. A mérés felbontása a jel hosszától függ, az FFT miatt nyers mivoltában lineáris felbontást eredményez. Pl. 1sec hosszú mérőjel 1Hz frekenciafelbontást tesz lehetővé, 1Hz az első spektrumvonal, és ennek egész számú többszörösein jön a többi. Ez a felbontás a 10-100Hz tartományban (ami a T/S paraméterek számításához is kell) nem mindig elég, ellenben meg a 10kHz környékén meg már irreálisan sok. A kapott nyers FFT rettenesen ronda szokott lenni, sok-sok jelfeldolgozási "kozmetikázás" kell neki, hogy jól is nézzen ki (FFT ablakolás, frekvencia-tartományban simító szűrések (átlagoló, medián stb))

Én személy szerint a T/S paraméterek mérésekhez jobban favorizálom a stepped szinusz módot, alacsony frekvenciákon jobb felbontást ad, mint az FFT-s, nem kell félni, hogy a kozmetikázás hamisít a mért értékeken (bár az ismert mérőprogramok igen jól használják ezeket a dolgokat, hogy ne legyen hamis az eredmény), ill a periódikus gerjesztés nem hoz ki a mérendő rendszerből intermodulációs (IM) és tranziens intermodulációs (TIM) torzításokat, amiket aztán az FFT nem tud eliminálni a THD-val egyetemben. Itt csak a THD torzítást és zaj játszik, amit viszont a korreláció eliminál (mivel csak az alapharmonikussal számol, azt korreláltatja ki a jelből).

Mérési elrendezés

A mérési séma a úgy néz ki, hogy PC vagy R-Pi, arra USB-n keresztül van csatlakoztatva egy hangkártya. A hangkártya bal kimenetét bekötjük egy egyszerű, alacsony és lehetőleg szimmetrikus tápfeszről táplált végfokozatra. Hi-fi erősítők alkalmazásával nagyon kell vigyázni, mivel azokban 30-50V tápfesz is lehet, és kb ugyanekkora csúcsjel jelenhet meg annak kimenetén, ami a hangkártya LINE bemenetén már károsodást okozhat! Sok egyszerű végfok vásárolható KIT-ben, ezek közül is a TDA2030 IC-vel rendekezőket tudom javasolni, mivel ennek az IC-nek (ha nem is egy HIFI világbajnok) de 140kHz a sávszélessége, vagyis a 192kHz hangkártyák kb 80-90kHz felső tartományát is gond nélkül átviszi.

kép

A mérőkapcsolás a hangszóró és azzal sorbakötött -jelen esetben 15 Ohm- mérőellenállás. (nevezhetjük még soros ellenállásnak vagy sense ellenállásnak) Ez egy feszültségosztót képez, a mérés pedig az osztó bemenetét, és az osztási csomópontot érinti. Előbbi a referencia jel, és ez a jobb csatornába megy, másik a mért jel, ami a bal csatolnába megy vissza a hangkártyába. Ezeket a jeleket GND nélkül csak a melegpontra kell bekötni, vagy ha használunk árnyékolt kábelt is, akkor az árnyékoló harisnyát csak a hangkártya felöl kössük be! Ne csináljunk földhorkot, pláne hogy nagyáramú földhurok jönne létre, ha a hangszóró föld felöli (végfok kimeneti GND) csomópontjához kötnénk! Ezeket a földeket külön PGND-nek jelölöm, hogy ezek teljesítmény földek (azaz nagyáramú). A felüsztség kivezérlés lényeges, alapszabálynak tekinthető, hogy legalább akkora jel kerüljön a hangszóróra, hogy annak membránja alacsony frekvencián szemmel láthatóan mozgásba jöjjön (legalább 1-2mm), de ne legyen olyan nagy, hogy a tekercs kimenjen a homogén mágneses térből, azaz a hangszóró Xlin tartományán belül maradjon. Hangszórón mérve kb 200-300mVeff ideális, ami a végfokon 1Veff kivezérlés mellett kb meg is valósul egy 8 Ohmos hangszórón.

A környezet telepítése

Mielőtt futtatod a kódot, elő kell készíteni neki a terepet! Én ezt most a R-Pi estére mutatom be, de pl. egy Windows alapú PC-n se lesz ez nagyon más. R-Pi esetén először is telepíteni kell egy Raspbian OS-t egy SD kártyára. Ezt nem részletezem, találsz róla infót, vagy úgy veszel R-Pi-t, hogy kérsz hozzá egy előtelepített SD kártyát is. A Raspbianba előre fel van telepítve a Python3, így azzal nincs teendőnk, ill. gyakorlatilag minden ismert Linux rendszerrel ugyanez a helyzet. Windows esetében telepíteni kell a Python3-at, ami szintén nem nagy kihívás egy általános PC használó számára. Itt talán annyi megjegyzést tennék, hogy a telepítő ablakon lesz egy checkbox, ami azt kérdezi, hogy a rendszer path útvonalakhoz adja-e hozzá a python program útvonalát, ezt mindenképpen be kell jelölni! Következő lépés, hogy néhány Python plugint telepíteni kell. R-Pi-n nyissunk egy terminált (pl. a Ctrl + Alt + T billentyűkombó) és szépen egymás után írjuk be ezeket a parancsokat:


sudo apt install python3-scipy


sudo apt install python3-matplotlib


sudo apt install python3-soundfile


sudo apt install python3-pyaudio


pip3 install sounddevice

Windowson a fenti összetevők konzolos ablakba beírt pip-el is települtek, a példa legutolsó sora szerint. A sorrendre vigyázni kell, mert függőségi viszonyok is vannak köztük! (pl. a sounddevice csak akkor települ, ha van pyaudio)

A program paraméterezése

A program elején változókba van minden szükséges paraméter megadva. Ezeket a kódban kell átírni, rámenteni, majd lehet újra futtatni a kódot. A R-Pi-ben én a Geany programot használom editornak, ez elő van telepítve a Raspbianban. Ennek van egy papírrepülő gombja, amit megnyomva ráment a filera és futtatja terminálablakban.

Egy gyors megjegyzés: Bár Raspbianban nem volt probléma, de más asztali Linuxnál tapasztaltam olyat, hogy a a Geany futtatáskor Python 2-vel akarta futtatni a kódot. A Python 2 és Python 3 nem teljesen kompatibilis egymással, és az összetevőket is külön telepíti a két rendszernek. Ilyen esetben a Geany programban állítsuk be a python3-at alapértelmezett Python interpreternek a következőképpen: Menüben elnavigálunk a Build vagy Összeállítás / a Build- vagy Összeállítási parancsok megadása menüpontba. A felugró ablakban a Python parancsok rész Compile és a Futtatási parancsok / Execute részben is a python szót cseréljük le python3-ra! Ilyen esetben, amikor Python 2 és Python 3 is van a gépen, a pip-et is célszerű pip3-nak írni, hogy biztosan a Python 3-hoz telepítse a kívánt összetevőt a rendszer!

kép

A program elején az import szekció után struktúráltan sorakoznak a paraméteres konstansok:

CALIB_MODE

True=kalibrálunk, False=mérünk

START_FREQUENCY

ettől a frekvenciától...

END_FREQUENCY

...eddig a frekvenciáig mérünk

FREQ_STEP_PER_OCT

frekvencia felbontás (ennyi mérési érték oktávonként)

MIN_SIGNAL_PERIODS

legalább ennyi periódisból álljon egy jel (alacsony frekvenciákon hosszú mérőjeleket eredményes, egy 2Hz-es mérőjel esetén, aminek 0.5s a periódisideje és egy 10-es értékkel pl. ez 5 szekundum!

MIN_SIGNAL_TIME

legalább ennyi idejű egy mérőjel. Szekundumban van, a 0.4-es érték 400msec-nek felel meg!

MIN_SILENCE_PERIODS

A jel előtt és mögött csend szakaszt szúrunk be, hogy a hangeszköz különféle késései, valamint a jel mögötti esetleges tranziens is benne legyen a felvételben. Ez a paraméter azt jelenti, hogy legalább ennyi periódusideig legyen ez a csend.

MIN_SILENCE_TIME

Mint az előbbi, csak minimum időben. Itt is, alacsony frekvenciákon a megadott periódusszám, magas frekvenciákon a megadott idő számít.

TIME_OFFSET

Amennyiben ez az érték 0, úgy a mérőjel és a két csend szakasz szimmetrikus. 0-tól eltérő értékkel a jel tologatható eőre hátra a csend-el határolt részeken. (A -0.04s (40msec) pl. nagyjából kompenzálja a Steinberg UR22 hangkártya késését.)

VOLUME

A kimenőjel digitális nagysága 1 esetében "full scale" azaz teljes nagyságú. ]0...1] intervallumban lehet megadni, 0.1 alá (ez -20dB-nek felel meg) ne menjünk!

R_SENSE

A mérőkör soros (érzékelő, sense) ellenállásának pontos mért értéke (Ezt neked kell beálítanod, a kódban az enyém szerepel!)

USE_WINDOWING

Ablakolás alkalmazása. Ablakfüggvényt leginkább FFT és FIR szűrőknél használunk. Az ablakfüggvény tulajdonképpen egy burkológörbét ad a feldolgozandó jelnek, amivel mintegy felkeveri és lekeveri azt, a szélein lehalkítja. Itt nem a már felvett és feldolgozás előtt álló jelet ablakoljuk meg, hanem a kimenőjelet. Ezzel elkerülhetű, hogy a hangszórón pattogások legyenek, ill. a jel indítási/befejezési tranziensek is kisebbek lesznek.

USE_CALIB_VALUE

Kalibrálás üzemmódban a programkód kalibrál, majd azt lementi egy calibrate.npy file-na. Mérés üzemmódban ha ez a változó True, akkor betölti ezt a file-t és alkalmazza a kalibrációs értékeket.

USE_SAVE_WAV

Mérőjelek (generált és visszamért) wav file-ba mentése egy py_records nevű alkönyvtárba. Debug célokat szolgál, az össze freknecián, amin csak mérünk kimenti wav-ba a jeleket. Időzítések beállítása, tranziensek megfigyelése, hanghibák (pl. ha azt halljuk, hogy pattog vagy ciripel a hang mérés alatt)

USE_REPLAY

Szintén debug célból, visszajátszik minden felvett jelet

DEVICE_NAME

Itt van pár kikommentelt is, a hangeszköz nevének megadása, ez alapján próbálja kiválasztani a program a hangkártyát.

FS

Sampling frekvency, avgy samle rate, ahogy tetszik. Hardveres és szoftveres mintavételi frekvencia. Célszerűen a hangkártya maximális képességeire legyen beállítva.

Első körben egy kalibrációt csináljunk, illetve itt állítsuk be a mérési frekvencia tartományt és lépésközt! Fontos, hogy a kalibráció mindig az itt beírt freki beállításoknak felel csak meg, ha más beállítás kell, akkor ahhoz új kalibrációt kell csinálni! Nyilván ezt lehetne javítani, de itt most a faék egyszerűség a fontosabb, de aki kicsit tud programozni, könnyen beleírhat egy jobb, de értelemszerűen bonyolultabb megoldást. Kezdő frekinek 1Hz alatti értéket nem érdemes beírni, itt már maga az ADC vág, van bennük DC mentesítő felülátereszteő szűrő. Felső frekvenciának a mintavételezési freki felénél kisebb érték legyen megadva, különben alias spektrumtartományba menyünk! Alacsony frekvenciákon (beállítástól függően) egy csomag időtartama több másodperc is lehet, így a kb 50Hz alatti frekvenciák mérése nagyon lassacskán megy, a túl alacsony alsó határ nagyon elhúzhatja a teljes mérés időtartamát, nálam volt, hogy egy alkalommal 23 percig kalibrált, majd szintán 23 percig mért! A túl finom felbontás (pl. 1/48,1/64 stb) szintén rendkívül hosszúra nyúltja a mérési időt. Ezekkel a beállításokkal játszadozni kell.

A kalibráció hardveres beállítása abból áll, hogy nyitva hagyjuk a mérőkapcsolat. Néhol ilyenkor egy kapcsolóval direkbe átkapcsolnak, azaz áthidalják a soros mérőellenállást, de ez nem helyes mód, ugyanis ilyenkor a hangkártya bemeneti impadanciáján nem történik feszültségesés. Fontos, hogy ne hidaljuk át a mérőellenállást, csakis ekkor kalibrálunk végtelenre! Nyilván, ez csak akkor számottevő, ha kicsi, pl. csak 10kOhm a bemeneti impedancia a hangkártyán.

Ezután be kell még állítani, hogy melyik hangkártyát használja a rendszer, ehhez előbb inítsuk el a progamot:

kép

Nyilván itt még hiára kiáll, mert nem találta meg a beállított kártyát. Úgy van megírva a kód, hogy minden esetben végiglistázza a hangeszközöket. Ez lehet hogy csak 3 elemű, de a Win 10-nél pl. ki se fért a képernyőn, vissza kellett görgetni. Copyzzuk le a képernyőről a szöveges részt, és írjuk be a kód DEVICE_NAME sztringjébe. Előfordul, hogy később más hw számon látja majd ugyanezt a Linux, akkor át kell javítani csak azt az egy számot, vagy ismét arra tudok buzdítani, hogy programozzuk le, hogy ezt a karaktert ne nézze! Ezekután el kell indulnia a kódnak, és végig kell mennie a frekvenciuákon:

kép

Látni fogjuk a képenyőn, hogy az egyes frekvenciákon mekkora eltérést mér a két csatorna között dB-ben és fázisban. A végén ezt lementi a calibrate.npy fileba, majd amikor visszaállítjuk a CALIB_MODE-ot Falsra, vagy nem kalibrációban indítjuk a programot, akkor ebből a fileból fogja visszatölteni a kalibrációs értékeket. A filbe csak a mért értékeket menti, frekenvia értéket nem! (egyszerűség miatt) Ezért fontos, hogy ne változzon a frekvencia-kiosztás a kalibráció és azt azt követő mérések között.

A következő lépés, hogy bekötünk valamilyen mérendő hangszórót a méricske mérőpontjaiba. Elindítjuk a programot, és szépen végigmér, majd a végén felmutat nekünk egy mérési grafikont:

kép

A programkód letöltése

A programkódot feltettem a Letöltések menübe, ill. erről a linkről is letöltheted!

A teljes programkód:

Kép betöltése…
Bezár