Anladığım kadarıyla kendi sorumu cevaplama özgürlüğünü alıyorum ve bu, bulgularımı paylaşmanın iyi bir yolu. Bana başlamak için bir yer ve denemek için bazı fikirler verdiğim için Olin Lathrop'a teşekkürlerim, ama sonuçta protokol Olin'in tahminden oldukça farklı çıktı, bu yüzden bu cevabı gönderiyorum.
Güncelleme: Son 8 bit ile ilgili tam olarak anlamadığım bir soru gönderdim ve Dave Tweed bunu anladı . Ayrıntıları buraya ekleyeceğim, bu nedenle bu cevap tam protokol spesifikasyonu olarak çalışabilir, ancak Dave'in cevabını kontrol edin.
Bunu anlamak için farklı şeyler denemek zorundaydım, ama anladığımdan oldukça eminim. İşin garibi, başka bir yerde bu protokole benzeyen bir şey bulamadım, ama henüz bilmediğim ortak bir protokol olabilir.
Her neyse, bulduğum şey:
Protokol / kodlama
Verileri kodlamak için hem darbeler hem de aralarındaki boşluklar kullanılır. Uzun bir darbe / boşluk ikili bir (1) ve kısa bir darbe / boşluk ikili sıfırdır (0). Darbeler,% 50 görev döngüsünde standart tüketici kızılötesi 38kHz modülasyonu kullanılarak gönderilir.
Nabız / boşluk zamanlamaları orijinal soruda, ancak burada tamlık için tekrarlayacağım:
Bit Pulse Space
-----+---------+---------
0 | 275µs | 285µs
1 | 855µs | 795µs
Tüm ± 10µs maks., ± 5µs tip. Bu, 16MHz'de bir mantık analizörü ile yakalanan örneklere dayanmaktadır; Bir osiloskopum yok, bu yüzden tam profili bilmiyorum (yani yükselme / düşme süreleri).
Kontrol girişleri uygulandığı sürece paketler tekrarlanır ve en az 100 ms aralıkla yerleştirilmiş gibi görünür.
Paket iletimi, verilerin bir parçası olmayan ve sabit olan bir "darbe 1" önsözüyle başlar. Aşağıdaki boşluk paketin ilk veri bitini kodlar ve son darbe son biti kodlar.
Her paket 32 bit uzunluğundadır ve uzaktan kumandanın sağlayabileceği her girişi içerir. Değerler az endian, yani MSB olarak okunur.
Veri yapısı
Aşağıda bireysel paketlerin temel yapısı verilmiştir. Son 8 bit beni karıştırdı, ama şimdi anlaşıldı (aşağıya bakınız).
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2
--+---------------------------+-----------+---+-------+-----------
P| Yaw | Throttle | Pitch | T | Chan. | Check
P: Preamble (always a pulse-1), T: Trim, Chan.: Channel
Bit Length Description (see note below)
-----------------------------------------------
0 1 Preamble. High 1
1-6 6 Yaw. Range 0-36 for left-right, 17 being neutral
7-14 8 Throttle. Range 0-134
15-20 6 Pitch. Range 0-38 for forward-back, 17 being neutral
21-22 2 Trim. Left = 1, right = 2, no trim = 0
23-26 4 Channel. A = 5, B = 2, C = 8
27-32 6 Check bits
Not: Aralıkları aldığım en yüksek değerleri temel alır. Protokol daha büyük aralıklar kapasitesine sahiptir - gaz kelebeği için 255'e, eğim / sapma için 63'e kadar - ancak bunun yaklaşık yarısında sınırlıdır.
Adım değerinin 14-21 (dahil) arasında bir ölü bant olduğu görülmektedir; sadece yukarıdaki veya altındaki değerler helikopterin tepki vermesini sağlar. Sapma için aynı olup olmadığını bilmiyorum (helikopter zaten kararsız olduğu için ve kendi başına biraz dönebilir).
Burada grafik terimlerdedir (orijinal sorudaki grafikle karşılaştırın)
6 kontrol biti, önceki değerlerin tümü XOR'lanarak hesaplanır. Her değer 6 bit olarak değerlendirilir. Bu, 8-bit gaz kelebeği değerinin 2 MSB'sinin göz ardı edildiği anlamına gelir. yani
check = yaw ^ (throttle & 0x3F) ^ pitch ^ trim ^ channel
Pratik notlar
Sinyal zamanlamaları ve modülasyonunun süper hassas olması gerekmez. Arduino'nun hiç doğru olmayan zamanlaması bile, tehlikeli modülasyona ve gerçek uzaktan kumandaya kıyasla nabız / uzay sürelerinde biraz isabet ve özlemeye rağmen iyi çalışıyor.
Helikopterin bulduğu ilk sinyalin kanala bağlanacağına inanıyorum - ancak test etmedim. Çok uzun bir süre sinyalsiz kalırsa (birkaç saniye), tekrar sinyal alana kadar "arama" moduna geri döner.
Gaz kelebeği sıfırsa, helikopter hatve ve yalpalama değerlerini göz ardı edecektir.
Trim komutları, uzaktan kumandadaki her düğmeye basıldığında yalnızca bir kez gönderilir. Muhtemelen trim değeri, helikopterin kendi kontrolöründeki bir değeri arttırır / azaltır; uzaktan kumandanın izlediği bir şey değil. Bu nedenle, bunun herhangi bir uygulaması muhtemelen bu şemaya bağlı kalmalı ve sadece ara sıra sol / sağ değerini göndermeli, aksi takdirde varsayılan olarak paketlerdeki sıfır trim değerine gönderilmelidir.
Gaz kelebeğini sıfıra ayarlayan bir kill anahtarına sahip olmanızı öneririm. Bu, helikopterin gökyüzünden düşmesine neden olacaktır, ancak motorlarını döndürmediği zaman daha az hasar görecektir. Dolayısıyla, bir şeye çarpmak veya vurmak üzereyseniz, dişlileri sıyırmak veya bıçakları kırmamak için kill anahtarına basın.
Orijinal uzaktan kumandanın IR LED'leri 900nm'den büyük bir dalga boyuna sahip gibi görünüyor, ancak ~ 850nm LED'i kullanırken sorun yaşamıyorum.
Helikopterin IR alıcısı tamam, ama süper duyarlı değil, bu nedenle IR kaynağınız ne kadar parlaksa, o kadar iyi. Uzaktan kumanda, mantık tarafından kullanılan 5V ray yerine 9V ray üzerinde oturan 3 LED seri kullanır. Mevcut çekilişini çok hassas bir şekilde kontrol etmedim, ama 50mA bahse girerim.
Örnek veri
İşte bir sürü paket, ilgilenen herkes için (evet, bir kod çözücü yazdım; tüm bunları elle çözmedim). A kanalı paketleri orijinal sorudaki grafiklerle aynı yakalamalardan gelir.
Channel A
Yaw Throttle Pitch Tr Chan Check Description
-----------------------------------------------------------
000100 10000100 000000 00 0101 000101 Left Mid + Throttle
000000 10000110 010001 00 0101 010010 Left Max + Throttle
100001 10000110 000000 00 0101 100010 Right Mid + Throttle
100100 10000100 010001 00 0101 110100 Right Max + Throttle
010001 00000000 001011 00 0101 011111 Forward Min
010001 00000000 000000 00 0101 010100 Forward Max
010001 00000000 011000 00 0101 001100 Back Min
010001 00000000 100101 00 0101 110001 Back Max
010001 00000000 010001 01 0101 010101 Left Trim
010001 00000000 010001 10 0101 100101 Right Trim
010001 00000011 010001 00 0101 000110 Throttle 01 (min)
010001 00010110 010001 00 0101 010011 Throttle 02
010001 00011111 010001 00 0101 011010 Throttle 03
010001 00101111 010001 00 0101 101010 Throttle 04
010001 00111110 010001 00 0101 111011 Throttle 05
010001 01010101 010001 00 0101 010000 Throttle 06
010001 01011111 010001 00 0101 011010 Throttle 07
010001 01101100 010001 00 0101 101001 Throttle 08
010001 01111010 010001 00 0101 111111 Throttle 09
010001 10000101 010001 00 0101 000000 Throttle 10 (max)
Channel B
Yaw Throttle Pitch Tr Chan Check Description
-----------------------------------------------------------
000000 10000110 010001 00 0010 010101 Left Max + Throttle
100100 10000110 010001 00 0010 110001 Right Max + Throttle
010001 00000000 001001 00 0010 011010 Forward Min
010001 00000000 000000 00 0010 010011 Forward Max
010001 00000000 010111 00 0010 000100 Back Min
010001 00000000 100110 00 0010 110101 Back Max
010001 00000000 010001 01 0010 010010 Left Trim
010001 00000000 010001 10 0010 100010 Right Trim
010001 00000001 010001 00 0010 000011 Throttle Min
010001 00110100 010001 00 0010 110110 Throttle Mid
010001 01100111 010001 00 0010 100101 Throttle High
010001 10001111 010001 00 0010 001101 Throttle Max
Channel C
Yaw Throttle Pitch Tr Chan Check Description
-----------------------------------------------------------
000000 10000101 010001 00 1000 011100 Left Max + Throttle
100100 10000101 010001 00 1000 111000 Right Max + Throttle
010001 00000000 001010 00 1000 010011 Forward Min
010001 00000000 000000 00 1000 011001 Forward Max
010001 00000000 010111 00 1000 001110 Back Min
010001 00000000 100110 00 1000 111111 Back Max
010001 00000000 010001 01 1000 011000 Left Trim
010001 00000000 010001 10 1000 101000 Right Trim
010001 00000001 010001 00 1000 001001 Throttle Min
010001 00110100 010001 00 1000 111100 Throttle Mid
010001 01100110 010001 00 1000 101110 Throttle High
010001 10000101 010001 00 1000 001101 Throttle Max
Yukarıda belirtildiği gibi, son 8 bit anlaşıldı, ancak sadece gelecek nesiller için, burada orijinal düşüncelerim var. Tahminlerimde neredeyse yanlış olduğum için bunu tamamen göz ardı etmekten çekinmeyin.
Son 8 bit
Paketin son 8 biti hala biraz gizem.
23-26 bit arasındaki 4 bitin tamamı, uzaktan kumandanın kanal ayarıyla tamamen belirlenmiş gibi görünmektedir. Uzaktan kumandadaki kanalın değiştirilmesi protokolü veya modülasyonu hiçbir şekilde değiştirmez; sadece bu 4 biti değiştirir.
Ancak 4 bit, kanal ayarını kodlamak için gerçekten gerekli olanın iki katıdır; sadece üç kanal var, bu yüzden 2 bit bol. Bu nedenle, yukarıdaki yapı açıklamasında, yalnızca ilk 2 biti "Kanal" olarak etiketledim ve diğer ikisini "X" olarak etiketledim, ancak bu bir tahmin.
Aşağıda her kanal ayarı için ilgili bitlerin bir örneği verilmiştir.
Chan. Bits 23-26
-----+-------------
A | 0 1 0 1
B | 0 0 1 0
C | 1 0 0 0
Temel olarak, kanal ayarını iletmek için gerekenden 2 bit daha fazladır. Belki de protokol daha sonra daha fazla kanal izin vermek için bir kenara 4 bit vardır, ya da protokol tamamen farklı oyuncaklarda kullanılabilir, ama sadece bilmiyorum. Daha büyük değerler için, protokol dışarıda bırakılabilen ekstra bitler kullanır (yaw / gaz kelebeği / perde her biri biraz daha az ile geçebilir), ancak 3 duruma sahip trim için sadece 2 bit kullanılır. Böylece, kanalın sadece 2 bit olduğundan şüphelenilebilir, ancak bu sonraki 2'yi hesaba katmaz.
Diğer olasılık ise paketin sağlama toplamının "bit" ile başlayarak 8 bit uzunluğunda olması ve - sağlama toplamı sihrinden - kanal ayarını her zaman bir şekilde yansıtmalarıdır. Ama yine de: Bilmiyorum.
Ve bahsetmişken: Bu kontrol bitlerinin nasıl oluştuğu hakkında hiçbir fikrim yok. Onların, demek olan herhangi bir tek kontrol girişine karşılık gelmez, çünkü kontrol bitleri ve onlarla keman eğer helikopter yanıt verdiklerini görünmüyor. Sanırım bu bir çeşit CRC, ama anlayamadım. Çek, "X bitlerini" nasıl yorumladığınıza bağlı olarak 6-8 bit uzunluğundadır, bu nedenle bir araya getirilebilecek birçok yol vardır.