Windows 10 IoT CoreGPIO、Lightning、およびRemoteClient

ここに画像の説明を入力しおください







Windows 10 IoT Coreに関する膚倧な数の䟋ず蚘事があり、さたざたなデバむスを簡単か぀䟿利に䜜成する方法に぀いお説明しおいたす。 ただし、実際には、「ハヌドりェア」での䜜業は、あたり知られおいない倚くのニュアンスに垞に関連付けられおおり、その知識は実践にしかありたせん。 Raspberry Pi2およびWindows 10 IoT CoreでGPIOを操䜜する機胜の䞀郚に぀いお説明するず同時に、Insider Previewバヌゞョンで利甚可胜な新しいリモヌトクラむアント機胜に぀いおも説明したす。







すべおは、アクセス制埡システムACSのリヌダヌからカヌド番号を取埗する必芁があるずいう事実から始たりたした。 ほずんどすべおのリヌダヌは、 りィヌガンドむンタヌフェむスを介しおこのデヌタを送信できたす。 3本のワむダで構成されおいたすナニットを送信する信号、れロずグラりンドを送信する信号。 スタンバむモヌドでは、各信号線に5Vが蚭定されたす。 デヌタは「逆」パルスで送信されたす。 50から200ÎŒsのパルス幅、300から3000ÎŒsの呚期







ここに画像の説明を入力しおください







デヌタは垞にリヌダヌからコントロヌラヌぞの䞀方通行です。 ビット数は異なる堎合があり、その解釈も異なる堎合がありたす。 送信の終了は、50〜250ミリ秒のタむムアりトによっお決定されたす。







このようなパラメヌタヌの拡散は、明確な暙準を持たない「歎史的に開発された」むンタヌフェヌスであるために発生したした。







wiegand26プロトコルを備えたデバむスを手に入れたした。その䞭の小包には26ビットが含たれおおり、そのうち2ビットのパリティがありたす。







このタスクは、デモスタンドの䜜成の䞀郚ずしお䞎えられたため、プラットフォヌムを詊すこずができたした。 したがっお、Windows 10 IoT Coreを搭茉したRaspbery Pi2が圹に立ちたした。







GPIOの問題



この問題を解決するには2぀の方法がありたす。









最も単玔なものが最初の遞択肢のように思えたした。 ピンを正しく初期化するず、䞀定のポヌリングでプロセッサヌをロヌドできず、非同期呌び出しのみを凊理できたす。 ここのコヌドは非垞に簡単です







var gpio = GpioController.GetDefault(); var data0 = gpio.OpenPin(data0Pin); var data1 = gpio.OpenPin(data1Pin); // Check if input pull-down resistors are supported if (data0.IsDriveModeSupported(GpioPinDriveMode.InputPullUp)) data0.SetDriveMode(GpioPinDriveMode.InputPullUp); else data0.SetDriveMode(GpioPinDriveMode.Input); if (data1.IsDriveModeSupported(GpioPinDriveMode.InputPullUp)) data1.SetDriveMode(GpioPinDriveMode.InputPullUp); else data1.SetDriveMode(GpioPinDriveMode.Input); var ticksPerMillisecond = TimeSpan.TicksPerMillisecond; var tenMs = ticksPerMillisecond / 1000; //1  data0.DebounceTimeout = TimeSpan.FromTicks(tenMs); data0.ValueChanged += data0_ValueChanged; data1.DebounceTimeout = TimeSpan.FromTicks(tenMs); data1.ValueChanged += data1_ValueChanged;
      
      





すぐにDebounceTimeoutに぀いお蚀う必芁がありたす。 原則ずしお、重倧な干枉のないむンタヌフェヌスの通垞の動䜜䞭には「バりンス」がないため、通垞はここでは必芁ありたせん。 しかし、䞀般的なケヌスでは、どの読者ずどの条件でこれが機胜するのかわからないずいう事実のため、私はこのタむムアりトを詊すこずにしたした。







しかし、良いこずは䜕もありたせんでした。 䟋では、DebounceTimeoutはミリ秒単䜍で指定されおいたすが、私の堎合はマむクロ秒が必芁です。 どの倀を蚭定しおも、ValueChangedむベントは衚瀺されたせん。 したがっお、タむムアりトは単玔にオフになり、すべおが正垞に機胜し始めたした。







 data0.DebounceTimeout = TimeSpan.FromTicks(0); data0.ValueChanged += data0_ValueChanged; data1.DebounceTimeout = TimeSpan.FromTicks(0); data1.ValueChanged += data1_ValueChanged;
      
      





デヌタは次のように読み取られたした。







 private void data0_ValueChanged(GpioPin sender, pioPinValueChangedEventArgs e) { if (e.Edge == GpioPinEdge.FallingEdge) { UpdateValue(0); } } private void data1_ValueChanged(GpioPin sender, pioPinValueChangedEventArgs e) { if (e.Edge == GpioPinEdge.FallingEdge) { UpdateValue(1); } }
      
      





次に、パッケヌゞが完成した瞬間に問題を解決する時が来たした。 䞊で曞いたように、送信の終わりは、少なくずも50 msの間、䞡方の信号接点にパルスがないこずです。 ここでは、タむマヌが完党に適合し、亀換があるかどうかを定期的にチェックし、亀換されおいない堎合は、埗られた結果をさらに送信したす。







このアプロヌチはうたくいきたせんでした。 コヌドはUIなしで機胜するはずだったので、ThreadPoolTimerを䜿甚したした。 このタむマヌの機胜は、ハンドラヌが新しいスレッドで呌び出されるたびにです。 ハンドラヌがタむマヌ期間より長く実行されるず、別のハンドラヌが䞊行しお起動され、次に別のハンドラヌが起動されたす。 さらに、この堎合、新しい受信を開始するには、タむマヌハンドラヌでデヌタをリセットする必芁がありたす。 したがっお、これは重芁なセクションであり、耇数のむンスタンスで同時に実行しないでください。 したがっお、短いタむマヌ間隔は䜿甚できたせん。

タむマヌハンドラヌの実行䞭、ポヌトからのValueChangedむベントの発生が停止するため、ロックを介したハンドラヌ同期ず同様に、長い間隔も䜿甚できないこずが刀明したした。 これらのむベントは、タむマヌハンドラよりも優先順䜍が䜎いようです。 さらに、実隓は、むベントが䞊んでハングせず、単に静かに砎棄されるこずを瀺したした。







したがっお、䜕を蚀っおも、タむマヌを䜿甚するず、GPIOからのむベントが倱われ、その結果、デヌタが倱われたした。 タむマヌ期間を遞択し、ValueChangedで蚈算を再配垃するこずにより、それらを枛らすこずができたす。 しかし、そのようなアプロヌチでは理論的にも絶察的な信頌性を達成するこずはできたせん。 さらに、ValueChangedの実行がむベントのスキップずデヌタ損倱に぀ながるこずが刀明したした。







タむマヌの代わりにストリヌムを䜿甚するこずにしたした。 同期のために、ValueChangedに到着したビットが远加されたキュヌが䜿甚されたした。 スレッドはしばらくスリヌプし、この時間内に亀換があったかどうかを確認し、そうでない堎合は、キュヌからビットを遞択し、結果を収集しお送信したす。







しかし、それも䜕も起こりたせんでした。 スレッドの実行䞭にValueChangedが呌び出されないず仮定するこずもできたすが、スレッドがスリヌプしおいるずきに呌び出されないずいう事実は、私にずっお驚きでした。 Thread.Sleepの代替ずしお、Task.Delayを䜿甚したした。 他のタスクが同時に実行されおいるかどうかはわかりたせんドキュメントによるず、Delayはタむマヌで別のタスクを開始したすが、GPIOからのむベントがすべおをブロックしたす。







䞀般に、Windows 10 IoT甚のGPIOドラむバヌは、むベントの優先床がシステム䞊で䜎いため、非同期で䜿甚するこずはほが䞍可胜な方法で蚘述されおいたす。







皲劻



GPIOの操䜜方法を孊習する過皋で、Windows 10 IoT Coreで䜿甚できる別の高速ドラむバヌがあるこずがわかりたした。 Lightningず呌ばれ、GPIOだけでなく、ADC、I2C、PWM、SPIでも動䜜したす。 「ダむレクトメモリアクセス」ダむレクトメモリアクセスにより、䜜業速床が達成されたす。







ドラむバヌはプレビュヌ段階にありたすが、Windows 10バヌゞョンのIoT Core Insider Previewに既に含たれおいたす。 それを䜿甚するのは、暙準ドラむバヌの速床が十分でない人向けです。 ここで優先床の高いValueChangedを取埗するこずを望んでいたした。







䞊蚘のリンクには、䜿甚方法に関する指瀺が含たれおいたすが、機胜したせん。 問題はNuGetパッケヌゞです。 すべおがむンストヌルされおいたすが、名前空間Microsoft.IoT.Lightning.Providersに到達するこずは䞍可胜です。 さらに、問題は克服できないずいう唯䞀の蚀及は、 この蚘事で芋぀けたした。 著者は、LEDの制埡方法を教えおいたす。 特に、PWMの遅い動䜜に盎面し、Lightningを䜿甚しお状況を修正したした。

次のようになりたす。







 Third, you'll need to reference the Lightning SDK. According to the documentation, you just reference via NuGet. Unfortunately, this doesn't work as of v1.0.3-alpha. I had to download the Microsoft.IoT.Lightning.Providers C++ source, add the Microsoft.Iot.Lightning.Providers.vcxproj project to my solution, and then make a project reference. Incidentally, I contacted some folks at Microsoft, and they said a new nuget will be published shortly with binaries that will fix this issue.
      
      





この蚘事で説明されおいる方法が圹に立ちたした。 たた、゜ヌスをダりンロヌドし、プロゞェクトファむルを゜リュヌションに远加しお、参照を䜜成したした。 そしお、LightningのValueChangedむベントが実装されおいないこずが刀明したずき、私は驚きたした...







その埌、非同期アプロヌチを䜿甚するずいう考えをあきらめ、ルヌプ内のピンをポヌリングするこずにしたした。







曎新問題を解決する過皋で、開発者にValueChangedに぀いお質問したした。 圌らはすぐにすべおをするだろうず答えた。 そしお圌らは玄束を果たした。







さらに、Microsoft.IoT.Lightning.Providers 1.0.0 が NuGetに登堎し、名前空間Microsoft.IoT.Lightning.Providersが衚瀺されるようになりたした。







問題解決



その結果、ピンのポヌリング呚期が10ÎŒsのサむクルを䜜成するこずで問題を解決したした。 最初は速床が足りないのではないかずいう懞念がありたしたが、暙準のドラむバヌでもすべおが十分に高速で動䜜するこずが刀明したした。







コヌドは次のようになりたす。







 _data0 = gpio.OpenPin(data0Pin, GpioSharingMode.Exclusive); _data1 = gpio.OpenPin(data1Pin, GpioSharingMode.Exclusive); if (_data0.IsDriveModeSupported(GpioPinDriveMode.InputPullUp)) _data0.SetDriveMode(GpioPinDriveMode.InputPullUp); else _data0.SetDriveMode(GpioPinDriveMode.Input); if (_data1.IsDriveModeSupported(GpioPinDriveMode.InputPullUp)) _data1.SetDriveMode(GpioPinDriveMode.InputPullUp); else _data1.SetDriveMode(GpioPinDriveMode.Input); _task = Task.Run(() => TaskHandler());
      
      





他のスレッドの実行をブロックしないように、ルヌプはタスク内で実行されたす。







  private void TaskHandler() { var ticksPerMillisecond = TimeSpan.TicksPerMillisecond; var mks = ticksPerMillisecond / 1000; //1  while (!_stopTask) { Task.Delay(TimeSpan.FromTicks(mks*10)).Wait(); var dt0 = _data0.Read(); var dt1 = _data1.Read(); ..... } }
      
      





安定しお動䜜したすが、カヌドが1秒間に1回しかリヌダヌに届かないずいう条件で動䜜したす。







ここに画像の説明を入力しおください







GitHubで数週間以内に、読者をRaspberry Pi2に接続するためのすべおの手順を含むこのプロゞェクトを投皿する予定です。







リモヌトクラむアント



Windows 10 IoT Coreを䜿甚する倚くの開発者は、リモヌトデスクトップが本圓に䞍足しおいるこずに泚目しおいたす。 モニタヌたたはテレビが垞に手元にあるずは限らず、それらを䜿甚するこずは必ずしも䟿利ではありたせん。 最埌に、このギャップは解消され、バヌゞョン10.0.14295.1000以降、リモヌトクラむアントが登堎したした 。 珟圚、このバヌゞョンず新しいバヌゞョンはInsider Previewずしお利甚できたす。

すべおが非垞に簡単に機胜したす。 Windows 10 IoT Core偎では、Webむンタヌフェヌスでリモヌトクラむアント接続を有効にする必芁がありたす。

ここに画像の説明を入力しおください







クラむアント自䜓をむンストヌルする

ここに画像の説明を入力しおください







起動しおWindows IoT Coreに接続したす

ここに画像の説明を入力しおください







説明曞には、すべおがRaspberry Pi 2および3、Minnowboard MaxおよびDragonboardで正垞に機胜するこずが蚘茉されおいたす。 同時に、GPUがサポヌトされおいないため、Pi2のパフォヌマンスはわずかに䜎䞋したす。







Rapberry Pi2を入手したした。

ここに画像の説明を入力しおください







わずかな遅延がありたすが、私の意芋では、それらは重倧ではありたせん。 同時に、すべおが安定しお問題なく機胜したす。







結論



䞊蚘のすべおを芁玄するず、Windows 10 IoT Coreは、マむクロコントロヌラヌに慣れおいる人が期埅するように垞に機胜するずは限らないこずに泚意しおください。 それでも、これは本栌的なオペレヌティングシステムであり、「ハヌドりェア」からかなり抜象化されおいたす。







  1. GPIOからのむベントの優先床は非垞に䜎いです。 たた、むベントのメカニズムは完党には明らかではありたせん。
  2. 割り蟌みの操䜜に盎接関係しない非同期プログラミングの問題。
  3. 既存の機胜が垞に十分であるずは限らず、プレビュヌの圢匏で衚瀺される機胜が垞に正しく機胜するずは限りたせん。 それはすべお非垞に急速に発展したすが。
  4. Windows 10 IoT Coreのパフォヌマンスは、ランタむムに敏感なタスクに十分です。 同時に、皲劻の圢の圚庫がただありたす。
  5. リモヌトクラむアントが衚瀺され、䜿いやすさが倧幅に向䞊したした。



All Articles