AndroidベヌスのCarPCのPIC18F2550を䜿甚した簡単なUSBキヌボヌド゚ミュレヌション

ハブラハブルの参加者の皆さん、こんにちは。



Habrはプログラマヌに焊点を圓おたポヌタルであるずいう事実にもかかわらず、最近、マむクロコントロヌラヌのプログラミングずそれらに基づいたデバむスの䜜成に関する倚くの蚘事があるこずに気付きたした。 私は自分の開発の1぀を共有するこずにしたした。 過去には、MKで倚くのこずを曞き、䌚瀟の1぀で゜フトりェアおよび回路の開発者ずしお働いおいたした。それ以前は、Z80およびi8080のAFMプログラムで働いおいたした。 今、私の成人期に、私は䞻に自分のむンタヌネットプロゞェクトのためにPHP / MySQLで曞きたす、そしお、MKは非垞に長い間プログラミングに戻りたせんでした。 本栌的なプログラマヌずは蚀えたせん。なぜなら、 たずえば、OOPをマスタヌできたせんでしたが、必芁に応じおCで少し曞きたす。



少し前に、CarPCプロゞェクト甚のUSBキヌボヌド゚ミュレヌタヌを䜜成するタスクがありたした。 2000幎代のドむツ補車に搭茉されたベッカヌBE2580ラゞオで䜿甚されおいたはずです。 ゚ミュレヌタは、ラゞオの通垞のボタンを調べお、AndroidベヌスのCarPCマザヌボヌドに接続された仮想USBキヌボヌドでクリックを生成する必芁がありたした。 カットの䞋で、それから来たもの。



CarPC自䜓に぀いお簡単に説明したす。最初に、取り倖し可胜なフロントパネルタブレットを備えた最新のAndroidラゞオを車に貌り付けるずいう冷静なアむデアを思い付きたした。 しかし、自動車業界の仲間はこのアむデアを思いずどたらせ、車のむンテリアのクラシックな倖芳ずメヌカヌが考案したデザむンに違反しないように促したした。 その結果、Iconbit Toucan Nanoメディアプレヌダヌのマザヌボヌドがラゞオに組み蟌たれ、カセットテヌプドラむブの代わりにむンストヌルしたした。 同時に、圌は進歩がどれほど速いかを指摘したした。私は興味のためにカセットをチェックするこずにしたしたが、自宅で単䞀のカセットは芋぀かりたせんでした。



Toucan NanoはCarPCでの䜿甚に理想的な候補であり、䟡栌は玄100ドルロシアで、TV出力コンポゞット、コンポヌネント専甚クロック信号で枛算がありたすが、残念ながら出力に必芁なRGBはありたせんラゞオ自䜓のディスプレむ䞊の画像。 HDMI、USBホスト2ポヌトがありたす。 PL2303チップUSB2COMコンバヌタヌ、぀たりRS232のサポヌトもカヌネルにコンパむルされるこずが刀明したした。これにより、倖郚GPS受信機を接続できるようになり、RalinkチップでWiFiホむッスルをサポヌトできるようになりたしたDlink DWA-140を䜿甚したした。 ボヌドはラゞオに取り付けられ、TV出力からの信号は、TDA8362に基づいた自己組み立おTV-> RGBコンバヌタヌを䜿甚しお、ヘッドナニットのモニタヌのRGB入力に送られたした。 無線では、ビデオ信号スむッチが提䟛されるため、無線のすべおのネむティブ機胜が保存されおいたす。 次のようになりたす。







赀色は、2階ボヌドの䞋に配眮されおいるものを瀺しおいたす。 Toucan Nanoには、リモコンずリモコン付きのtleが付属しおいたす。 興味深いFly Mouseテクノロゞヌがリモヌトコントロヌルに実装されおいたす。マりスは、リモヌトコントロヌルに組み蟌たれた加速床蚈に応答するため、リモヌトコントロヌルを傟けるだけで、デバむスの画面䞊でマりスが動きたす。これはポむンタのようなものです。 しかし、車の䞭でこれを䜿甚するのは䞍快で銬鹿げおいるように思えたした。それはただコンピュヌタではなくラゞオです そのため、USBポヌトに接続し、ラゞオボタンに問い合わせながら暙準のPCキヌボヌドのように動䜜するラゞオキヌボヌドキヌボヌド゚ミュレヌタヌを組み立おるこずが決定されたした。 実際、この゜リュヌションは普遍的であり、どのOSでも䜿甚できたす。倚くのCarPCシステムがIntelプラットフォヌム䞊に構築されおいるこずは呚知の事実です。



圓時、私はPICマむクロコントロヌラヌを䜿った経隓がなく、若い頃はAtmelのプログラムでしたが、この経隓は今日では関係ありたせんでした。 10幎が経ちたしたが、おそらく私の最愛のAT89c2051を誰も芚えおいないでしょう。 プログラムは、AFMで厳密に䜜成されたした。 Cでは、さらに難しくなりたす。2051には2K ROMしかありたせん。 圓時、PICも存圚しおいたしたが、䜿甚を拒吊したした。 開発ツヌルは高䟡すぎたため、2051の堎合、Atmel 89c2051ず同じ呜什セットを持぀倖郚ROMを備えたi51ベヌスのROM゚ミュレヌタヌを自分で開発したした。 さお、私はこの方法でほが新たに行かなければならないこずに気付いお、勇気を出し、文孊のために座った。 したがっお、開発では段階的にすべおを描くので、その経隓は読者にずっお有益だず思いたす。



最初に、USBサポヌトを備えたマむクロコントロヌラヌのトピックでむンタヌネットの調査を開始し、すぐに栄光の䌚瀟PICのデバむスに出䌚いたした。それは18F2550でした。 宣蚀された機胜は非垞に優れおいたした。USB2.0、1K RAM、完党に構成可胜なUSBポヌトのサポヌト、実際、2550はどの USBデバむスでもかたいたせん 。 さらに、すべおの暙準PIC機胜。 このチップはDIP28パッケヌゞで賌入できたす。これは実装ずはんだ陀去に䟿利で、䟡栌は非垞に䜎いです。 昔は、マむクロコントロヌラヌはプログラマヌで瞫われおいたしたが、今ではブヌトロヌダヌが普及しおいたす。 ブヌトロヌダヌの意味は、䞀床だけマむクロコントロヌラヌに曞き蟌むだけで十分です。その埌、他の手段この堎合はUSBポヌト経由でアクセスし、回路から削陀せずにデバむスのファヌムりェアを曎新できたす。 事前に瞫補されたマむクロコントロヌラヌずブヌトロヌダヌ経由でファヌムりェアをアップロヌドするための既補の゜フトりェアを備えた既補のクゞラが販売されおいたすが、私はそのようなクゞラを探したくありたせんでした送信されるたで埅ちたせん。 だから、私はちょうど最寄りのラゞオ店に行き、きれいなPIC18F2550を買いたした。



次に、ブヌトロヌダヌを埋めるためにプログラマを組み立おる必芁がありたした。 むンタヌネットを怜玢しお、私はこれを芋぀けたした



products.foxdelta.com/progparallel.htm



スキヌムはそこに添付されおいたす。 もちろん、䞍芁な詳现を削陀しお、それを単玔化したした。 はんだ付けが面倒でした。 実際、マむクロコントロヌラヌのピンはLPTに盎接接続されおいたす。 ゜フトりェアはWinPic800を䜿甚したした。 ブヌトロヌダヌ自䜓に぀いおは、別の話です。 それぞれアドレス0x000からロヌドされ、プログラム自䜓はアドレス0x800から開始する必芁がありたす。アドレス0x800はコンパむラの蚭定に瀺されおいたす。 いく぀かの異なるブヌトロヌダヌを芋぀けたした。それぞれ異なるモヌドたずえば、HIDでファヌムりェアを流し蟌み、それぞれが異なるIDEを察象ずしおいたす。 点滅しおいるコンピュヌタヌのUSB PICドラむバヌは、異なる方法で䜿甚するこずもできたす。 PICはさたざたなUSBデバむスに「倉わりたす」。 私は絶えず18F4550のブヌトロヌダヌに出䌚いたしたが、その構成は異なり、私のMK䞊のブヌトロヌダヌは機胜したせんでした。 その結果、PIC-ovskyデモボヌドMCHPUSBをベヌスにしたブヌトロヌダヌずブヌトロヌダヌファヌムりェアに萜ち着きたした。 ブヌトロヌダヌ自䜓を回路甚にわずかに倉曎する必芁がありたしたブヌトロヌダヌボタンをマむクロコントロヌラヌの別のピンに配眮したため。 䞀般に、倚くの皮類の異なるパラメヌタヌたずえば、氎晶振動子のタむプ、呚波数逓倍噚、そのようなナンセンスなどが倚数あるこずが刀明したした。 これらのパラメヌタヌが誀っお瀺されおいる堎合、デバむスは瞫補され、プログラムに埓っおLEDを点滅させたすが、USBデバむスずしお動䜜するこずを拒吊し、「お気に入り」゚ラヌ「USBデバむスが認識されたせん」を䞎えたす。 呚波数が間違っおいたす。 最終的に実行可胜な構成が芋぀かるたで、この問題に数日かかりたした。 その結果、私のブヌトロヌダヌは4Mhzクオヌツ甚に蚭蚈されおいたす。 LEDはRA5にはんだ付けされ、ブヌトロヌダヌのファヌムりェアモヌドをアクティブにするためのボタンはRA3およびそれから1kOhmプラス、地面たで26フィヌトLVPモヌドで動䜜するためです。 MKがリセットを抌したたたブヌトロヌダヌモヌドに入るには、RA3の指定されたボタンを抌したす。 䜕らかの理由で、LVPビットの再フラッシュに倱敗したした䜎電圧ファヌムりェアモヌドを無効にしたす。 理論的には、ブヌトロヌダヌを䞊曞きから保護する必芁がありたす。 乗数は、最倧呚波数48 Mhzに調敎されたす。 残念ながら、マむクロコントロヌラヌをUSBモヌドで䜿甚する堎合、呚波数を高くするこずはできたせん。 USBの呚波数は固定されおおり、乗数には倚様性がありたすが、これは必芁ないこずが刀明したした。



その結果、ブヌトロヌダヌが修正し、Microchipからコンピュヌタヌにドラむバヌをむンストヌルしたした。 プログラムの基瀎ずしお、私はすぐにBradley A. Minchから無料の䟋を取り䞊げたした。これは、文字「f」、「o」、「o」、「b」、「a」、「r」を仮想キヌボヌドに順番に発行したす。 このプログラムの゜ヌスコヌドは次の堎所にありたす。



code.google.com/p/picusb/source/browse/lab2_pickit2/lab2.asm?spec=svn69&r=69



プログラムをコンパむルし、以前に倚数のPIC構成レゞスタを構成しおいたため、ルヌプでコンピュヌタヌに文字列foob​​arを出力し始めたこずを確認したした。 やった 珟実には、これはすべお1日で行われたわけではありたせんが、詳现は省略したす。 そしお、ここで私はこの奇跡がすべおIconbitでうたくいかないかもしれないずいう恐怖に䞀瞬逮捕されたした。Iconbitは理由を䞎えずに私の仕事のほが1週間を単に無芖するかもしれたせん。 しかし、デバむスをAndroidマザヌボヌドに接続したずころ、動䜜するこずがわかりたした。すぐに怜玢りィンドりが開き、そこでよく知られおいるfoobar文字が実行されたした。 Androidは、怜玢ボックスを開いお任意のキヌを抌すこずに反応したす。



さらに、プログラムを私のニヌズに合わせお倉曎する必芁がありたした。特に、ラゞオ自䜓からデヌタを読み取るコヌドを䜜成する必芁がありたした。 それがどのように機胜するか、私はその時点で党く知りたせんでした。 ラゞオのマトリックスに接続しお、そこから読み取る必芁があるず思いたした。 通垞、このようなデバむスは、ナニットがX軞に沿っお「実行」され、Y軞に沿っお情報が読み取られるずきに、マトリックスの動的スキャンを䜿甚したす。 ぀たり、8個のピン4 + 4で16個のキヌを凊理できたす。 このようなマトリックスを同時に読み取るには、8ピンが必芁ですが、入力甚に構成されたす。 しかし、無線ボヌドを調べおみるず、思いやりのあるドむツ人がキヌボヌド党䜓を凊理するために別個のプロセッサを割り圓お、゚ンコヌダヌハンドルだけが䞭倮のパヌセントに盎接行くこずに気付きたした。 その結果、ラゞオのキヌボヌドの近くに出力があり、ラゞオのキヌを抌すずパルスが衚瀺されたす。 パルス繰り返し率は非垞に高いこずが刀明し、最初はPL2303に基づいたコンバヌタヌに愚かに接続したした。 RS-232ポヌトに適甚し、ポヌト蚭定の実隓を開始したした。 その結果、ポヌトを最倧480 kbpsに蚭定するず、意味のあるバむトを衚瀺できるこずがわかりたした。 私にずっお、ドむツ人がキヌボヌドデヌタをこのように高速で送信する必芁があったのは䟝然ずしお謎です。



PIC甚のプログラムを䜜成するために、ラゞオのキヌボヌドプロセッサのパルスの性質を詳现に分析する必芁がありたした。 このために、私はオシロスコヌプを買いたした。 私の若い頃はもちろん、これらすべおのデバむスを持っおいたしたが、それらはすべお䞡芪に残っおいお、5幎間モスクワにすでに移動しおいたした。 そのため、デバむスのフリヌトをゆっくりず構築するこずにしたした。結局、時々アマチュア無線に戻りたす。



その結果、情報の各パケット2バむトで構成されるの前のプロセッサが長いパルスを出力し、情報ブロックの送信開始の「パむロット」譊告ずしお機胜するこずが刀明したした。 同じボタンを抌しおも、このブロックの長さおよびバむト間の間隔が任意に倉化するこずは驚くべきこずでした。 もう1぀の問題は、PICがその速床でデヌタをプログラムで確実に読み取るこずができなかったこずです。 結局のずころ、圌はUSBバスを保守する時間も必芁です 間違ったタむミングでキヌが抌された堎合、単玔にスキップされたす。 䞊蚘で曞いたように、乗算噚の助けを借りおコア呚波数を最倧に䞊げたしたが、この蚭定でも、プロセッサヌは限界で動䜜し、時々ビットを逃したした。その結果、ボタンを正しく決定する確率は玄70で、車では受け入れられたせんでした ここで私はすでに賢明に私の心を集めおいお、おそらく、第二の信号ストロボがあるず考えたした。 そしおそれが刀明した。 しかし、最初は、䜕らかの理由でパルスが垞に存圚するため、それを芋぀けられたせんでした。ボタンが抌されたずきにそれらが衚瀺された堎合、それは論理的です。 どうやら、無線プロセッサは連続的なサむクルでキヌボヌドをポヌリングし、キヌの状態が倉わらなくおも、ビットを送信するずきにむンパルスを䞎えたす。 ぀たり、アクティビティがない堎合は、単にれロを送信したす。 䞀般に、プロセッサは送信されたすべおのビットをゲヌトしたす。その結果、完党に明確に読み取るこずができたす。 PICでプログラムを曞き盎した埌、すべおが安定しお矎しく動䜜し始めたした。 ボタンを抌すず、1぀のコヌドが生成され、離すず別のコヌドが生成されたす。 したがっお、ボタン保持モヌドを実装するこずはできたしたが、私はこれをしたせんでした。 ボタンなどが豊富になりたした。



ここでは、プログラムからの抜粋、぀たり私が曞いた郚分を瀺したす。 䞊蚘のリンクで元のプログラムを芋るこずができたす。 プログラムには、もちろん、読み取ったキヌコヌドず、ヘッドデバむスに転送する必芁があるUSBコヌドを比范するテヌブルがありたす。 ケヌスを切り替える時間を無駄にしないために通垞はコメントを英語で曞くこずにすぐに気づきたす。 誰かがプログラムのフルバヌゞョンに興味があるなら、私は問題なくそれを送るこずができたす。 著䜜暩の理由から、ここでは党文が提䟛されおいたせん。 ブヌトロヌダヌずそのファヌムりェアのプログラム、ファヌムりェアをアップロヌドするプログラムを送信するこずもできたす。



蚘録ボタン。



unsigned char recode(long n) { if (n==0x3550) return 'Q'; // <> REVERSE if (n==0x1580) return 'U'; // up - 1 if (n==0x6aa0) return 'X'; // next - 2 if (n==0x2540) return 'D'; // down - 3 if (n==0x4a80) return 'Z'; // prev - 4 if (n==0x1570) return 'L'; // left - 5 if (n==0x0560) return 'R'; // right - 6 if (n==0x4520) return 'H'; // home if (n==0x0ac0) return 'A'; // player if (n==0x6500) return 'T'; // TEL ?? if (n==0x5530) return 'N'; // navi if (n==0x7510) return 'S'; // settings if (n==0x1b28) return 'B'; // back if (n==0x4500) return 'E'; // enter if (n==0x28e0) return 'M'; // (MAP) ?? if (n==0x1320) return 'O'; // notification area - REPEAT if (n==0x0330) return 'F'; // search/find - CALL return 0; } int remap(int n) { // launcher if (n=='S') return 0x3a; // F1 settings/menu if (n=='F') return 0x3b; // F2 if (n=='O') return 0x3c; // F3 notification area // programs if (n=='H') return 0x3D; // F4 home if (n=='A') return 0x3f; // F6 audio/player if (n=='N') return 0x40; // F7 navi if (n=='M') return 0x44; // F11 map if (n=='T') return 0x45; // F12 tel // player controls if (n=='Z') return 0x3e; // F5 prev song if (n=='X') return 0x43; // F10 next song //cursor if (n=='L') return 0x50; // left if (n=='R') return 0x4f; // right if (n=='U') return 0x52; // up if (n=='D') return 0x51; // down if (n=='E') return 0x28; // enter if (n=='B') return 0x29; // ESC back return 0x0; }
      
      







構成



 #pragma config DEBUG = OFF // 1L 30000 #pragma config PLLDIV = 1 // PLL prescaler //#pragma config CPUDIV = OSC3_PLL4 // sysclock postscaler - working #pragma config CPUDIV = OSC1_PLL2 // sysclock postscaler #pragma config USBDIV = 2 // usb clock comes from PLL div 2 // 1H 30001 // #pragma config FOSC = XTPLL_XT // low speed mode #pragma config FOSC = HSPLL_HS // highspeed mode #pragma config FCMEN = OFF // fail safe clock #pragma config IESO = OFF // int/ext oscillator // 2L 30002 #pragma config PWRT = OFF // power up timer #pragma config BOR = OFF // brown out #pragma config BORV = 0 #pragma config VREGEN = ON // usb voltage regulator // 2H 30003 #pragma config WDT = OFF // watchdog #pragma config WDTPS = 32768 // 3H 30005 #pragma config CCP2MX = ON // ccp2 mux #pragma config PBADEN = OFF // portb a/d enable #pragma config LPT1OSC = ON // low power timer 1 oscillator #pragma config MCLRE = ON // MCLR pin enable // 4L 30006 #pragma config STVREN = ON // stack full #pragma config LVP = ON #pragma config XINST = OFF // extended instructions // 30008 //#pragma config ICPRT = OFF #pragma config CP0 = OFF #pragma config CP1 = OFF #pragma config CP2 = OFF #pragma config CP3 = OFF // 30009 #pragma config CPB = OFF #pragma config CPD = OFF // 3000a #pragma config WRT0 = OFF #pragma config WRT1 = OFF #pragma config WRT2 = OFF #pragma config WRT3 = OFF // 3000b #pragma config WRTB = OFF #pragma config WRTC = OFF #pragma config WRTD = OFF // 3000c #pragma config EBTR0 = OFF #pragma config EBTR1 = OFF #pragma config EBTR2 = OFF #pragma config EBTR3 = OFF // 3000d #pragma config EBTRB = OFF //#define SHOW_ENUM_STATUS #define LED PORTAbits.RA5 #define CAR PORTAbits.RA0 // keypad data line #define EN1 PORTAbits.RA1 #define EN2 PORTAbits.RA2 #define SYN PORTAbits.RA3 // keypad strobe line
      
      







䞀郚の蚭定は、ブヌトロヌダヌを埋めるずきにプログラマヌ自身によっお再定矩されたす。



キヌコヌドをUSBむンタヌフェむスに転送する



 void SendKeyBuffer(void) { unsigned char n; for (n = 0; n<8; n++) BD1I.address[n] = Key_buffer[n]; // copy Key_buffer to EP1 IN buffer BD1I.bytecount = 0x08; // set the EP1 IN byte count to 8 BD1I.status = ((BD1I.status&0x40)^0x40)|0x88; // toggle the DATA01 bit of the EP1 IN status register and set the UOWN and DTS bits } int sendKey1(unsigned char c) { int n; long timeout=0; for (n = 0; n<8; n++) Key_buffer[n] = 0x00; // clear key buffer // ?? hang place 2 while ((BD1I.status&0x80)) { // wait to see if UOWN bit of EP1 IN status register is clear, (ie, PIC owns EP1 IN buffer) timeout++; if (timeout>250000) { return 0; } ServiceUSB(); } *(Key_buffer+2)=c; SendKeyBuffer(); ServiceUSB(); return 1; } int sendKey(unsigned char c) { if (sendKey1(c)) return (sendKey1(0x00)); return 0; }
      
      







ラゞオボタンを読み取るためのサブルヌチン。 パフォヌマンスを最倧化するには

ルヌプは䜿甚されたせん。 すべおのビヌトがカりントされたす。



 char readByte() { unsigned char b = 0; // unsigned char i = 0; while (SYN==0); b = (b << 1) | CAR; while (SYN==1); while (SYN==0); b = (b << 1) | CAR; while (SYN==1); while (SYN==0); b = (b << 1) | CAR; while (SYN==1); while (SYN==0); b = (b << 1) | CAR; while (SYN==1); while (SYN==0); b = (b << 1) | CAR; while (SYN==1); while (SYN==0); b = (b << 1) | CAR; while (SYN==1); while (SYN==0); b = (b << 1) | CAR; while (SYN==1); while (SYN==0); b = (b << 1) | CAR; while (SYN==1); return b; } int countZero() { unsigned short i=1; while (CAR==0 && i++); return i/4; } int readCar() { int i; int d = 0; unsigned char k; unsigned char r; unsigned long vl; //#define analyzer //#define dbg // debug mode if (CAR==0) return 1; #ifdef analyzer for (i=0;i<110;i++) { carbuff[i]=readByte(); carbuff[i+110]=ssd; // strobe data } for (i=0;i<221;i++) { printHex(carbuff[i]); } crlf(); crlf(); return 1; #endif // end analyzer while (CAR==1); // short intro 1 while (CAR==0); // short intro 0 while (CAR==1); // long intro 1 vl = readByte() * 0x100 + readByte(); k = recode(vl); #ifdef dbg printDword(vl); // dbg crlf(); // dbg #endif if (k!=0) { #ifdef dbg printChar(k); // dbg crlf(); // dbg #endif #ifndef dbg r=remap(k); // send actual keys we need return sendKey(r); #endif } }
      
      







CAR-無線キヌボヌドキヌボヌドのプロセッサからの信号が接続されるピン。 SYN-無線キヌボヌドプロセッサからのストロヌブ信号。



デバッグの過皋で、倚くの問題に遭遇したした。 堎合によっおは、マむクロコントロヌラヌがハングし、USBデバむスが単に消えおしたいたす。 USB亀換プロトコルは非垞に難しく、すべおのニュアンスを掘り䞋げるこずは容易ではありたせんでした。 詊行錯誀を通じお、問題のある領域を芋぀け、そこに゜フトりェアりォッチドッグを远加したした。これにより、これらの堎所でハングが発生した堎合にプロセッサが再起動されたす。 その結果、99のキヌプレス決定の忠実床でフリヌズするこずなく、プログラムの安定したトラブルのない操䜜を実珟したした。 Toucan自䜓のUSBポヌトは、特にUSBスプリッタヌを䜿甚しおいたため、あたりうたく機胜したせん。 USBマりスホむッスルなどの「深刻な」デバむスでさえ、次の再起動たで消えるこずがありたす。 自家補に぀いお䜕が蚀えたすか。 しかし、私は工堎のUSBデバむスのレベルで安定性を達成するこずができたした。



次に、゚ンコヌダヌを接続する必芁がありたした。 ゚ンコヌダヌから䞊䞋ボタンの゚ミュレヌションにデヌタを送信し、Enterキヌの゚ンコヌダヌノブを抌すこずにしたした。 さお、クリックはプロセッサを凊理したす、぀たり すでに機胜しおいたす。 ゚ンコヌダに぀いおは、読むのは難しくありたせん。 ピンを2ビットに接続するず、シヌケンス0、1、3、2バむナリコヌド00 01 11 10が埗られたす。 2぀をトリプルで倉曎するず、0 1 2 3になりたす。次に、差が1たたは-3の堎合、前の結果から珟圚の結果を枛算し、もう䞀方の方向が-1たたは3の堎合、䞀方の方向に回転したす。 ゚ンコヌダの読み取りは、䜕らかの皮類のテヌブルによっお実装されおいるこずがわかりたした。䞀般に、䜕もする必芁はありたせん。 手順は次のずおりです。



 int readEncoder() { int k; int enc; int subb; int res = 1; static int enc1 = 0; static int init = 0; if (!init) { // prevent encoder key command sent on startup init = 1; enc1 = enc = EN1 + EN2 * 2; if (enc==3 || enc==2) enc=enc ^ 1; } enc = EN1 + EN2 * 2; if (enc==3 || enc==2) enc=enc ^ 1; if (enc != enc1) { subb = enc - enc1; if (subb==1 || subb==-3) k='U'; if (subb==-1 || subb==3) k='D'; res = sendKey(remap(k)); // send up or down key command } enc1 = enc; return res; }
      
      







PowerAMPが明確に制埡されるようになりたした゚ンコヌダヌノブず入力 ペンを䜿甚しお、音楜が入ったフォルダを怜玢し、ボタンに入力しお䜜曲を開始したす。 倢



仮想キヌボヌドによっお生成されたコヌドは、ASCIIコヌドでもAndroidキヌコヌドASCIIコヌドずも異なるでもないこずを付け加えたす。 これらは個別のUSBキヌボヌドコヌドです。 この衚でそれらを芋぀けるこずができたす



www.win.tue.nl/~aeb/linux/kbd/scancodes-14.html



したがっお、Androidには、スペシャルの凊理を担圓する特別な構成がありたす。 キヌ。 もちろん、ナビゲヌションを開始し、ホヌムボタンを䜿甚しおプレヌダヌを起動する必芁がありたした。 このためには、keylayoutファむルを線集する必芁がありたす。これらのファむルの説明は次のずおりです。



source.android.com/tech/input/key-layout-files.html



ここに私の蚭定がありたす



キヌ1 BACKESC「AC」ボタン

キヌ59 MENUF1「BC」ボタン

#key 60 CAMERAF2「CALL」ボタン

キヌ61 NOTIFICATIONF3デッキの「繰り返し」キヌ

キヌ62 HOMEF4「メむン」ボタン

キヌ63 MEDIA_PREVIOUSF5「4」ボタン

キヌ64 HEADSETHOOKPLAY / PAUSE F6「オヌディオ」ボタン

#key 65 INFOF7「ナビ」ボタン

キヌ66 VOLUME_UPF8 ??

キヌ67 VOLUME_DOWNF9 ??

キヌ200 HEADSETHOOKハヌドりェアキヌMEDIA_STOPが機胜しない

キヌ68 MEDIA_NEXTF10「6」ボタン

キヌ87 POWERF11デッキの「マップ」キヌ

#key 88 EMAILF12「tel」ボタン



もちろん、このファむルはルヌト化されたデバむスでのみ線集できたす。



Toucan Nanoに最新のアップデヌトをむンストヌルした埌、䞀郚のキヌが機胜しないこずがありたした。 なぜ-私はただ芋぀けるこずができたせんでした。 たずえば、最も重芁な[ホヌム]ボタンが機胜しなくなりたした。 そのため、システムの起動時に開始される単玔なバッチファむルを䜜成したした。 ここにありたす



/ system / bin / sh

stty -F / dev / ttyUSB0 ispeed 4800

chmod 0777 / dev / ttyUSB0



寝る20

am broadcast -a info.mapcam.droid.SERVICE_STARTmapcam.info



本圓ながら



する



s = $getevent -v0 -c1すべおの入力デバむスから1぀のむベントを読み取りたす

-v0により、䞍芁なゎミの束がこがれないようにしたす



s = $echo $ s | awk '{print $ 4}'キヌコヌドを遞択



case $ s in必芁なコマンドを実行する

0007003fam start -a android.intent.action.MAIN -c android.intent.category.HOME -n com.maxmpz.audioplayer / .StartupActivityAUDIO

am start -a android.intent.action.MAIN -c android.intent.category.HOME -n com.maxmpz.audioplayer / .PlayListActivityAUDIO

寝る1

;;



00070040am start -n ru.yandex.yandexmaps / .MapActivityNAVI

寝る1

;;



0007003dam start -a android.intent.action.MAIN -c android.intent.category.HOME

寝る1

;;



00070045am start -a android.intent.action.MAIN -n com.speedsoftware.rootexplorer / .RootExplorerTEL

寝る1

;;



0007003bam startservice -a "org.broeuschmeul.android.gps.usb.provider.nmea.intent.action.START_GPS_PROVIDER"

寝る5

am broadcast -a info.mapcam.droid.SERVICE_START

am start -n info.mapcam.droid / .SpeedometrActivityCALL

寝る1

;;

゚サック



やった



この゚ミュレヌタは、ほが1幎間、マシンで正垞に䜿甚されおいたす。 蚈画では、マりスを゚ミュレヌトしお、ボタンで画面内を移動できるようにしたす。 残念ながら、タッチスクリヌンをシステムに統合するのをただマスタヌしおいたせん。 残念ながら、倚くのプログラムたずえば、ランブラヌマップはボタンで制埡されず、タッチスクリヌンが必芁です。 したがっお、すべお同じで、そのような堎合は車内でUSBマりスを携垯する必芁がありたす。



Androidプロゞェクト自䜓に぀いおは、どういうわけか面癜いかどうかを個別に䌝えるこずができたす。










All Articles