Cessna 172 cockpit otthon

Építsünk szimulátort

Építsünk szimulátort

Radio/Nav panel #1

2019. november 03. - C172Peti

Belekezdtem a rádió/navigáció műszer paneljának tervezésébe, egyelőre még csak nagyon alap szinten.

radio_nav_panel_front.jpg

Beledobáltam a 3D tervbe mindent, amire első körben gondoltam. 

A felső kijelző sor képes megjeleníteni a rádiós és navigációs készenléti és aktív frekvenciákat, A második sorba egyelőre csak a rádió csatornaválasztó kijelzőjét tettem bele.

radio_nav_panel_exploded.jpg

Belekerült kettő darab a házikészítésű dupla encoderemből. Bár az FSX nem tudja a 8.33-as rádiót kezelni, a kapcsolója bekerül. Talán az FSX 2020 tudja majd és talán tudok majd ahhoz is programmal csatlakozni. A többdigites LED kijelzőkről korábban már meséltem. Nyolc darabra van szükségem 3 digitesből a frekvenciákhoz, bár jelenleg csak két tizedes lesz használva a három helyett. Egy darab két digites is bekerül a csatornaválasztó megjelenítéséhez.

radio_nav_panel_back.jpg

A nyomógombokra (frekvencia aktiválás, csatorna választás) olyan mikrokapcsolókat használok, amiből jelenleg van itthon pár darab. Itt azért még lehet futok egy kört, hátha találok pont olyan méretűt és formájút, ami oda illik. Jobb híján egyelőre maradnak a mikrokapcsolók és tervezek rájuk majd egy gombot.

A műszer bekapcsolásához, hangerőszabályzáshoz, illetve a NAV állítócsavarjához egy egyszerű potmétert terveztem most bele. Bár ezzel kimarad a feeling, hogy bekapcsoljuk a rádiót, később nézek majd erre is egy olyan potit, ami kapcsolóval kezdődik. Őszintén szólva most túl nagy hangsúlyt ebbe a részbe nem fektetek, mivel a szimulátorban ez nem igazán lesz kihasználva (egyelőre legalábbis nem látom a fontosságát).

Összegezve, ez még korántsem egy kész terv, csupán az alkatrészek valamilyen rendezett formában összepakolva. Most jön az a rész, hogyan is rögzítsem a nyomógombokat, kijelzőket, állító csavarokat, magát a műszerdobozt.

 Mindez összefoglalva egy kis videóban is:

NAV1 - COM1 adatok a szimulátorból

LED kijelző koncepciója már megvan, következő lépésként a navigációs blokkhoz szükséges adatokat igyekszem kinyerni a szimulátorból.

Az FSUIPC doksija szerint (FSUIPC4 Offsets Status.pdf) a 034E címen található a COM1 frekvencia. Itt a frekvenciából 4 számjegyet tárol BCD formátumban, ami annyit tesz, hogy 2 byte helyet foglal.

Őszintén szólva itt egy picit szomorú lettem, mert ez annyit jelent, hogy 8.33 -as frekvenciákat ezek szerint az FSX nem képes tárolni. Tekintve, hogy 2018 év végétől már kötelező itthon is a 8.33-as rádió a gépekbe és gyakorlatilag az összes kisebb reptér frekvenciáját a 25kHz-esről 8.33-as elhatárolás szerinti frekikkel látták el ( pl. LHMC 132.200 -> 132.215 ), kezdünk távol kerülni az aktuális valóságtól. No de hátha a Flight Simulator 2020 majd ad erre megoldást :)

Hagyom ezt a 8.33 és 25kHz problémát, ha van rá érdeklődés szívesen összefoglalom egy külön bejegyzésben hogyan is működnek ezek és mik az alapvető különbségek.

Visszatérve a jelenlegi állapothoz: 4 számjegy van tárolva. Egész pontosan a 4 középső számjegy. 132.200 esetén ez 3220-at jelent. Belegondolva logikus döntés ez, a vezető '1' -est teljesen felesleges tárolni, az nem változhat, 25kHz bontás esetén pedig az utolsó sázmjegyet a legtöbb (ha nem minden) 25kHz-es rádió lespórolja. Ez amúgy szabványosan is elfogadott. Pl. a 132.225-ös frekvencia 25kHz-es elhatárolásnál, 132.22 -ként jelenik meg az 5 digites rádión. Nem magyarázom ezt tovább, viszont egyre jobban érik a gondolat bennem, hogy ezt külön részletezzem a 8.33-as felbontással együtt :)

com1_data.jpg

Nézzük inkább a lényeget, hogy lesz a BCD-ből megjeleníthető szám. A fenti képen legalul van az a két byte (binárisan), amit tárol a szimulátor. A feleadat egyszerű: 4 bit határoz meg egy számot, daraboljuk fel a 16 bit adatot 4 bitesekre és már meg is vagyunk. 

Mivel a számokat majd az arduino-ra akarom küldeni, ezért nekem célszerű egy byte tömböt generálni belőle, amivel már az arduinónak nem kell számolgatnia, csak "bután" megjeleníteni.

Ezt az alábbi kóddal oldottam meg a szerver oldalon:

public static byte[] BCDtoByteArray(byte bcd) {       

    byte[] retVal = new byte[2];

    retVal[0] = (byte) (bcd & 0xf0);       

    retVal[0] >>>= (byte) 4;

    retVal[0] = (byte) (retVal[0] & 0x0f);       

    retVal[1] = (byte) (bcd & 0x0f);

    return retVal;

}

 

Ez a kód annyit csinál, hogy a bemenetként kapott byte-ot ketté vágja és egy byte tömbben visszaadja a két értéket a BCD-nek megfelelően.

Ezt a byte-sorozatot már "csak" oda kell dobni az arduinónak, hogy megjelenítse. Megnéztem a standby és a navigációs frekvenciákat, mindegyik ugyanígy működik, csak más-más címről kell beolvasni őket az alábbiak szerint:

COM1 034E
COM1 STBY 311A
NAV1 0350
NAV1 STBY 311E
COM2 3118
COM2 STBY 311C
NAV2 0352
NAV2 STBY 3120

 

 

 

LED vezérlés: MAX7221 + Arduino

Az épülő szimulátornál jópár számjegyet kell megjeleníteni 7 szegmenses LED kijelzővel. Próbálkoztam korábban arduinóval vezérelni őket, majd kaptam a tippet, hogy miért is nem használok MAX7221 IC-ket hozzá?

max7221.jpg

Gyorsan kiderült, hogy közös anódos kijelzőim vannak, ami a MAX7221-el nem, vagy csak igen körülményes úton vezérelhetőek. Elmélyedve a témában, simán megérte a zsáknyi közös anódos kijelzőimet félrerakni és rendelni közös katódosokat belőle. A MAX7221 által nyújtott kényelem és teljesítmény kárpótol mindenért.

Röviden pár szó az IC-ről. 8 darab 7 (+1) szegmenses kijelzőt képes vezérelni egy IC. Az adatokat SPI-n tolhatjuk bele (soros kommunikáció), az IC pedig cserébe multiplexeli a szegmensek között. Vezérlés szempontjából teljesen mindegy, hogy több darab egy digites, vagy több digites kijelzőt használunk. Érdemes megjegyezni, hogy ez a remek tulajdonsága, hogy 8 digitet tud egyszerre kezelni, kényelmes lehetőséget biztosít arra, hogy egyetlen IC-vel akár egy 8x8-as LED mátrixot is vezérljünk, amire az adatlapján példát is találunk.

max7221_pin_configuration.jpg

A lábkiosztás és az alap áramköri séma egyszerű, könnyen értelmezhető/össze rakható. Igazából egy dologra érdemes figyelni: az áramkorlátozó ellenállásra, ami a fenti ábrán 9.53kOhm. Az adatlap szerint ez a minimális érték, a tapasztalat nekem azt mutatta, hogy 22k ellenállással működött rendesen. Ennél kisebbnél néha lezárt az IC és nem volt hajlandó tovább működni (tönkre nem ment ugyan, de áramtalanításra volt szükség, hogy újra végezze a dolgát).

Van még egy rendkívül hasznos tulajdonsága ennek az IC-nek: sorba köthetőek. Így gyorsan kitágul a világ és néhány IC-t sorbakötve néhányszor nyolc digit válik vezérelhetővé.

Gondoltam ki is próbálom, 11 digit kijelzésére az alábbi áramkört raktam össze

max7221_schematic.jpg

Itt két MAX7221 IC-t látunk sorbakötve, az első 8 a második 3 digitet vezérel. Az arduino boardról 3 lábat használok, a CLK, LOAD(CS) és DataInput-hoz.

A vezérléshez a LedControl arduino könyvtárat használtam, megtalálod itt: http://wayoda.github.io/LedControl/index.html

Nem csak az API leírása pazar, hanem részletes útmutatást ad az áramkör felépítéséhez is. Van pár példaprogram LED mátrix és 8 szegmenses LED kijelzők vezérléséhez is. Érdemes megjegyezni, hogy az itt található áramkörökben a zajok szűrésére használ két kondenzátort. Én ezt nem pakoltam bele az áramköreimbe, nem észleltem problémát, pedig egyszerű breadboardokon pakoltam össze mindent, ami nem a stabil kontaktról híres. Valószínűleg ha az arduino board messzebb van az IC-ktől, akkor hosszabb kábelek már összeszedhetnek annyi zajt, ami gondot okozhat az üzemelésben és megéri a kondikat berakni az áramkörbe.

Röviden a teszt programom, amit használtam a lenti videóban:

#include "LedControl.h"
/* Now we need a LedControl to work with. 

***** These pin numbers will probably not work with your hardware ***** 

pin 2 is connected to the DataIn  

pin 3 is connected to the CLK  

pin 4 is connected to LOAD  

we have two MAX7221 */

LedControl lc=LedControl(2,3,4,2);

A LedControl inicializálásához 4 paraméter kell megadni. Ezek rendre: DataIn, CLK, LOAD lábak (digitális outputként lesznek használva). Negyedik paraméterként pedig meg kell mondanunk, hogy hány IC van sorbakötve. A könyvtár 8 IC-t kezel egy sorban. Ha ennél többet szeretnénk vezérelni egy boardról, az is megtehető, ekkor viszont "indítanunk kell egy új sort", azaz inicializálunk egy másik változót és újabb 3 arduino lábat jelölünk ki a vezérléshez.

void setup() {
  /*
  The MAX72XX is in power-saving mode on startup,
  we have to do a wakeup call
  */
  lc.shutdown(0,false);
  lc.shutdown(1,false);
  /* Set the brightness to a medium values */
  lc.setIntensity(0,1);
  lc.setIntensity(1,1);
  /* and clear the display */
  lc.clearDisplay(0);
  lc.clearDisplay(1);
}

Amikor az IC-k feszültés alá kerülnek, energiatakarékos módban vannak. A shutdown(0, false) utasítással ébreszthetjük fel, ahol az első paraméter az IC sorszáma a sorban, a második pedig, false esetén felébreszti, true esetén energiatakarékos módba küldi az IC-t. Ha több IC-nk van, mindegyiket "ébreszzük" fel itt.

A setIntensity(0,1) szolgál az a LEDek intenzitásának megadására, itt is az IC sorszáma az első paraméter, majd maga az intenzitás.

Az alábbi writeArduinoOn7Segment 11 digiten a következőt jeleníti meg: ArduinoArdu.  Ez voltaképp egy minta, miként lehet karaktereket megjeleníteni. Gyakorlatilag mindegyik utasításnál igaz, hogy az első paraméter az IC sorszáma, míg a második paraméter az adott IC-n a megjelenítendő digit sorszáma. Harmadik paraméterként jön a megjelenítendő karakter, míg az utolsó paraméter jelöli, hogy a pontot meg akarjuk-e jeleníteni.

void writeArduinoOn7Segment() { 

lc.setChar(0,0,'a',false);  delay(delaytime); 

lc.setRow(0,1,0x05); 

delay(delaytime); 

lc.setChar(0,2,'d',false); 

delay(delaytime); 

lc.setRow(0,3,0x1c); 

delay(delaytime); 

lc.setRow(0,4,B00010000); 

delay(delaytime); 

lc.setRow(0,5,0x15); 

delay(delaytime); 

lc.setRow(0,6,0x1D); 

delay(delaytime); 

lc.setChar(0,7,'a',false); 

delay(delaytime); 

lc.setRow(1,0,0x05); 

delay(delaytime); 

lc.setChar(1,1,'d',false); 

delay(delaytime); 

lc.setRow(1,2,0x1c); 

delay(delaytime);  

A szegmensek külön-külön megjelenítéséhez szerintem a setRow használható legjobban, itt megadhatjuk bináris számokkal, hogy mely szegmens világítson (1 byte = 8 bit = 8 szegmens). A fenti példában a B00010000 egyetlen szegmenst jelenít meg, ami a kiírt szövegünkben az "i" betű lesz.

Számok megjelenítéséhez a setDigit a legkényelmesebb, ahol 0-15 közötti számot adhatunk meg és értelemszerűen 0-9, A-F -ig jeleníti meg a számokat.

Így a végére egy kis videó, hogyan is működik mindez:

 

 

 

 

 

 

Dupla encoder #3

a végleges megoldás

A dupla tekerőgombos-kapcsolós megoldás végéhez értem, szerelhető, működőképes és már néz is ki valahogy.

doubleencoderfinal.jpg

A működéséről és szerelhetőségéről egy rövid videó:

Most pedig megyek tovább a rádió/navigációs panel kijelzőjével, immár MX7221 IC-vel vezérelve a 7 szegmenses kijelzőket.

 

 

süti beállítások módosítása