Buat Roda Trim Tab Analog Kompak untuk FlightGear dengan Arduino Nano
Komponen dan Perlengkapan
Arduino Nano R3
atau papan kompatibel
×
1
Potensiometer rotary (generik)
×
1
Kapasitor 100 µF
×
1
Adafruit SSD1306 0.96 inci OLED
×
1
Kabel jumper (generik)
×
1
Aplikasi dan Layanan Online
Arduino IDE
Anaconda
FlightGear
Tentang Proyek Ini
Menghubungkan Arduino ke FlightGear bukanlah hal baru, tetapi saya menemukan wiki sudah usang dan forum memberikan petunjuk berharga di mana Anda harus mencari jalan keluar.
Ide adalah memiliki perintah analog yang bagus, murah, dan kompak untuk mengontrol roda trim tab elevator pesawat di FlightGear. Wiki berfungsi sampai bagian komunikasi. Secara ketat, Anda tidak dapat langsung menggunakan komunikasi serial untuk mengirim perintah dari Arduino ke FlightGear. Anda harus mencari jalan keluar dengan Python untuk mengirim paket melalui UDP.
Apa itu roda trim? Ini adalah perangkat analog untuk mengontrol defleksi tab trim, yang merupakan perangkat aerodinamis untuk menjaga permukaan kontrol (dalam hal ini elevator yang mengontrol pitch pesawat) pada posisi tertentu tanpa usaha pilot. Dari wikipedia:
Persyaratan tambahan untuk proyek ini: python dengan perpustakaan serial, socket, dan sys terinstal. Asumsi bahwa Anaconda telah diinstal, perpustakaan yang hilang dapat diperoleh dengan Anaconda prompt dengan mengetik:
>>> conda install -c anaconda pyserial
yang sama dengan serial dan socket. Cari di internet paket yang sesuai, biasanya yang paling banyak diunduh untuk platform Anda baik. Setelah Anda memiliki python dengan perpustakaan ini (dan, tentu saja, FlightGear terinstal) Anda dapat beralih ke bagian berikutnya.
Ada tiga skrip kode: sketsa Arduino, skrip eksekusi python, dan skrip XML. Sketsa Arduino harus dimuat ke papan Anda. Skrip python harus dijalankan untuk mengaktifkan komunikasi antara Arduino dan FlightGear. Skrip XML adalah protokol generik FlightGear yang harus dipindahkan ke <FlightGearRoot>/data/protocol sekali untuk semua.
Sketsa Arduino memerlukan perpustakaan U8glib. Seperti yang disebutkan dalam komentar, sesuaikan baris 2 sketsa dengan layar Anda:
Lihat contoh dan dokumentasi U8glib. Sketsa harus bekerja bahkan tanpa layar, jadi Anda dapat bermain tanpa umpan balik visual dari papan Anda.
Jika Anda tidak senang dengan arah rotasi, cukup tukar posisi dua argumen terakhir dalam instruksi map berikut
w = map(p,0,1023,100,-100); m = map(p,0,1023,90,0);
supaya nilai potensiometer berkisar dari -100 hingga 100 dan jarum indikator berkisar dari 0 hingga 90 (ini trik untuk menggambar jarum di posisi yang benar, coba sendiri jika Anda penasaran).
Skrip python mencakup alamat host dan nomor port serial. Host harus "localhost" (jika tidak bekerja, coba dengan 127.0.0.1), port bebas (mungkin lebih baik yang tidak digunakan oleh aplikasi lain, saya tidak tahu), port serial di mana papan Anda terhubung dapat dibaca dari Arduino IDE. Dalam kasus saya, adalah "COM4". Catatan: jika Anda menguji Arduino dengan serial monitor, Anda mungkin harus memutus dan menghubungkan kembali papan Anda sebelum menjalankan skrip python agar berfungsi dengan baik.
host = "localhost" port = 21567 #buf = 1024 addr = (host,port) UDPSock = socket(AF_INET,SOCK_DGRAM) tty="COM4" print("tty is ", tty)
Skrip python dapat diletakkan di mana saja. Anda dapat menjalankannya dari baris perintah sistem operasi Anda. Dalam kasus saya (Windows), saya mengetik di command prompt:
python c:\path\to\file\arduinoElevatorTrim.py
Ini dapat diluncurkan sebelum atau bahkan setelah memulai FlightGear.
Terakhir, seperti yang sebelumnya disebutkan, skrip XML harus dipindahkan sekali untuk semua ke folder protokol instalasi FlightGear Anda. Sekarang Anda siap. Luncurkan FlightGear dengan mode yang Anda sukai (baris perintah atau peluncur) dengan menambahkan perintah berikut (tanpa spasi antara karakter!):
di mana kita memberitahu FlightGear untuk menerapkan protokol generik melalui socket, membaca input 30 kali per detik, pada alamat localhost, port 21567, protokol UDP, instruksi dalam file arduinoElevatorTrim.xml. Nikmati roda trim pribadi Anda!
Kode
arduinoElevatorTrimOLED.ino
arduinoElevatorTrim.py
arduinoElevatorTrim.xml
arduinoElevatorTrimOLED.inoArduino
Kode untuk dimuat ke Arduino Nano. Sesuaikan baris 2 (jenis layar) sesuai kebutuhan.
#include <U8glib.h> U8GLIB_SSD1306_128X64 u8g(U8G_I2C_OPT_NONE|U8G_I2C_OPT_DEV_0); // I2C / TWI int xmax = 128; int ymax = 64; int xcenter = xmax/2; int ycenter = ymax/2+10; int arc = ymax/2; int angle = 0; char* label = "TRIM"; int labelXpos = 53; int p, w, m; u8g_uint_t xx = 0; int const potPin = A6; float potVal; // Customized function void gauge(uint8_t angle) { // draw border of the gauge u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_RIGHT); u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_RIGHT); u8g.drawCircle(xcenter,ycenter,arc+6, U8G_DRAW_UPPER_LEFT); u8g.drawCircle(xcenter,ycenter,arc+4, U8G_DRAW_UPPER_LEFT); // draw the needle float x1 = sin(2*angle*2*3.14/360); float y1 = cos(2*angle*2*3.14/360); u8g.drawLine(xcenter, ycenter, xcenter+arc*x1, ycenter-arc*y1); u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_LEFT); u8g.drawDisc(xcenter, ycenter, 5, U8G_DRAW_UPPER_RIGHT); u8g.setFont(u8g_font_chikita); // show scale labels // u8g.drawStr( 10, 42, "-1.0"); // u8g.drawStr( 19, 14, "-0.5"); // u8g.drawStr( 63, 14, "0"); // u8g.drawStr( 92, 14, "0.5"); // u8g.drawStr( 105, 42, "1.0"); u8g.drawStr( 1, 42, "DOWN"); u8g.drawStr( 52, 17 , "NEUT"); u8g.drawStr( 105, 42, "UP"); // show gauge label u8g.setPrintPos(labelXpos,32); u8g.print(label); // show digital value and align its position u8g.setFont(u8g_font_profont22); if (w >= 99) { u8g.setPrintPos(47,60); } if (w >= 10 && w < 99) { u8g.setPrintPos(54,60); } if (w >= 0 && w < 9) { u8g.setPrintPos(60,60); } if (w >= -9 && w < 0) { u8g.setPrintPos(48,60); } if (w >= -99 && w < -9) { u8g.setPrintPos(42,60); } if (w < -99) { u8g.setPrintPos(35,60); } u8g.print(w); } void setup() { Serial.begin(9600); u8g.setFont(u8g_font_chikita); u8g.setColorIndex(1); // assign default color value if ( u8g.getMode() == U8G_MODE_R3G3B2 ) { u8g.setColorIndex(255); } else if ( u8g.getMode() == U8G_MODE_GRAY2BIT ) { u8g.setColorIndex(3); } else if ( u8g.getMode() == U8G_MODE_BW ) { u8g.setColorIndex(1); } else if ( u8g.getMode() == U8G_MODE_HICOLOR ) { u8g.setHiColorByRGB(255,255,255); } } void loop() { potVal = analogRead(potPin); potVal = (potVal - 512.0)/512.0; Serial.print(potVal); Serial.print("\n"); // p is the same as potVal, but it is an integer p = analogRead(potPin); w = map(p,0,1023,100,-100); m = map(p,0,1023,90,0); // show needle and dial xx = m; if (xx < 45){ xx = xx + 135; } else { xx = xx - 45; } // picture loop { u8g.firstPage(); do { gauge(xx); } while( u8g.nextPage() ); } delay(10); }
arduinoElevatorTrim.pyPython
Skrip untuk dijalankan bersama FlightGear untuk "menterjemahkan" komunikasi serial menjadi paket UDP. Anda memerlukan Python terinstal untuk menjalankan skrip ini. Sesuaikan baris 14 (port USB tempat Arduino terhubung) sesuai kebutuhan.
#!/usr/bin/python import sys import serial from socket import * host = "localhost" port = 21567 #buf = 1024 addr = (host,port) UDPSock = socket(AF_INET,SOCK_DGRAM) tty="COM4" print("tty is ", tty) try: ser = serial.Serial(tty,9600) except: print("Error connecting to ", tty) prevline="" while 1: outline='' line=ser.readline() if line != prevline: #some value changed print(line) outline=line UDPSock.sendto(outline,addr) prevline=line
arduinoElevatorTrim.xmlXML
Skrip untuk ditambahkan ke folder <FlightGearRoot>/data/Protocol. Lakukan ini sekali untuk semua.