「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -[[戻る>Windows 10 IoT]] * 目次 [#afd73fd3] #contents *概要 [#r83f0bc8] Windows 10 IoT Coreの評価を実施中。 *基本 [#x1829430] **Headモード、Headlessモード [#vb07d84b] ***Headモード [#zb49acc7] -GUI有りモード ***Headlessモード [#e8ef7773] -GUI無しモード -リソース消費を抑えることが出来る。 ***切替方法 [#e24c9190] 以下のコマンドで切り替え可能。 -Headlessモードに変更 setbootoption.exe headless shutdown /r /t 0 -Headlessモードに変更 setbootoption.exe head shutdown /r /t 0 -参考 --Headed/Headless devices | Windows IoT~ https://developer.microsoft.com/en-us/windows/iot/docs/headlessmode **ドライバの種類 [#x7c0a154] ***Inboxドライバ [#tf570855] -プラグ・アンド・プレイに対応した機器をパソコンに接続すると、~ Windowsに同梱されるドライバの中から自動的にドライバが選択され組み込まれる。 -このため、すぐに周辺機器が使えるようになる。 -この、Windowsに同梱されているドライバを、Inboxドライバと呼ぶ。 ***DMAPドライバ [#d07f25ae] -DMAP : Direct Memory Mapped -[[Inboxドライバ>#tf570855]]よりもGPIOパフォーマンスの向上を実現する開発用ドライバ -以下のケースでは、安全にDMAPドライバを使用できる。 --信頼できるアプリケーションのみのマシン上で使用する。 --Lightningプロバイダ(Microsoft.IoT.Lightning.Providers.*)経由でのみ使用する。 --または、「[[Arduino Wiring sketches>https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?Arduino%20Wiring%20sketches]]」のみ使用する。 ---Arduino Wiring for Windows 10 IoT Core | Windows IoT~ https://developer.microsoft.com/en-us/windows/iot/Docs/ArduinoWiring -悪意のあるアプリはH/W、Securityの問題を引き起こす可能性がある。 *準備 [#a112e823] **開発用PC [#p56a97c1] -OSは、Windows 10とする。 -企業内なら、開発用NWへの接続が許可されているもの。 **IoT機器 [#wa4465fe] ***本体 [#i2baa07c] Raspberry Pi 3 MODEL B ***電源 [#x4c3a174] micro USB(Androidと同じ) **周辺機器 [#k9059277] ***ストレージ [#c7bfbb17] -microSDメモリーカード(Raspberry Pi 3に挿す) -microSD から メモリーカード への 変換アダプター(開発用PCに挿す) ***ネットワーク [#i5f96c0d] スイッチとして機能する機器(開発用PCとRaspberry Pi 3を接続する) -有線LANの場合: L2スイッチとLANケーブル -無線LANの場合: プライバシー・セパレータ機能を搭載したWifiルーター ***入出力 [#qe08c680] -モニタとHDMI ケーブル。 -USB マウス, USB キーボード *セットアップ [#a7892242] **Windows 10 IoT Coreのインストール [#d214299e] ***Windows 10 IoT Core Dashboardのダウンロード [#mb138c4c] -Downloads | Windows IoT~ https://developer.microsoft.com/ja-jp/windows/iot/downloads --Get Windows 10 IoT Core Dashboardをクリック --setup.exeがダウンロードされるのでダブルクリックして実行 --Windows 10 IoT Core Dashboardをインストールする。 ***microSDにWindows 10 IoT CoreのOSイメージを書き込む。 [#z083771f] -インストール後、そのままWindows 10 IoT Core Dashboardが起動する。 -「microSD から メモリーカード への 変換アダプター」を開発用PCに挿す。 -[新しいデバイスのセットアップ]で以下の入力を行う。 -[ダウンロードとインストール]をクリックしてmicroSDにOSイメージを書き込む。 --はじめに、Windows 10 IoT Coreがダウンロードされる。 --次に、microSDにOSイメージを書き込まれる(フラッシング)。~ この際、コマンド・プロンプトで進捗表示がされる。 --書き込みが完了すると「SDカードは準備が完了しています」と表示される。 -この画面で表示されている「3.デバイスを検索します」の「自分のデバイス」ボタンを押下し、~ 「Dashboard」と「Raspberry Pi 3」との通信を許可しておく。~ Windows10IoTCoreDashboard.exeのインバウンドが許可される。 ***Raspberry Pi 3へ機器を接続 [#j4cd151e] -電源 --micro USB(Androidと同じ) -周辺機器 --OSイメージを書き込んだ microSD を挿す。 --有線接続の場合、LANケーブルに接続する。 --入出力 ---USB マウス、USB キーボード ---モニタ(HDMI ケーブル) **Windows 10 IoT Coreの初期設定をする。 [#t0d354c2] ***起動時 [#fe32df20] -言語を選択する(日本語を選択)。 -無線LANの場合、 --Wifiを選択可能 --IPアドレスはDHCPで自動配布される。 -有線LANの場合、 --起動前にLANケーブルを接続しておく。 --IPアドレスはAPIPAのアドレスになっている。 ***[[その他、適宜>#bbd556e0]] [#f4416a6f] -コマンド・プロンプト --コマンド・ラインを選択して、 --Administratorのログイン・アカウント情報を入力する。 --コマンド・プロンプトを使用できるようになる。 **Windows 10 IoT Core Dashboardから接続・操作する。 [#bbd556e0] -開発用PC側のIPアドレスの設定 --無線LANの場合、~ DHCPで自動配布されるアドレスで通信可能なので設定は不要。 --有線LANの場合、~ APIPAのアドレスを確認し、開発用PCのアドレスを設定・変更する。 ---IPアドレス : 169.254.x.x ---サブネットマスク : 255.255.0.0 -Windows 10 IoT Core Dashboardを起動する。 -「自分のデバイス」からRaspberry Pi 3を選択、 ***Device Portal [#v88f9fcc] -接続 --右クリック、[Device Portalで開く]を選択する。 --Administratorのログイン・アカウント情報を入力する。 --ログイン後、Device Portalが表示される。 -操作 --Device Portalから操作する。 --HOME:タイムゾーンの変更 --PROCESS: 電源(再起動など) -,etc. ***SMB [#o74961ed] -接続 --右クリック、[ネットワーク共有を開く]を選択する。~ 上手く行かない時は、「\\[Raspberry Pi 3のIPアドレス]\C$」を直打ち。 --Administratorのログイン・アカウント情報を入力する。 --「\\[Raspberry Pi 3のIPアドレス]\C$」が開く。 -操作 --[[イベント・ログ]]のファイルなどを取出し、確認できる。 ***[[PowerShell]] [#z7b42565] -接続 --右クリック、[PowerShellを起動]を選択する。 --Administratorのログイン・アカウント情報を入力する。 -操作 --コマンドやコマンドレットを実行できる。 --[[Headモード、Headlessモードの切換>#vb07d84b]] --IPアドレスの設定(APIPAアドレスなら、必要に応じて変更すると良い) ---設定方法 ipconfig /all netsh interface ip show config netsh interface ip set address "Ethernet" static [IPアドレス] [サブネットマスク] [デフォゲ] ---設定例 netsh interface ip set address "Ethernet" static 192.168.1.2 255.255.255.0 192.168.1.1 ---設定変更後~ PowerShellが切断される。~ Windows 10 IoT Core Dashboardの「自分のデバイス」のIPアドレスが更新される。~ --Administratorのパスワードを設定/変更する。 net user Administrator [パスワード] --ローカルコンピュータの新しい NetBIOS 名を設定 setcomputername [新しいマシン名] **開発用PC側のIPアドレスを設定/変更する。 [#d510bcb1] ***IPアドレス、サブネットマスクなどを変更する。 [#k21bb5c8] Windows 10 IoT Core側の設定に合わせて、~ IPアドレス、サブネットマスクなどを変更する。 netsh interface ip set address "Ethernet" static 192.168.1.1 255.255.255.0 ***モバイルホットスポットでインターネット接続を共有する。 [#k3893f04] Windows 10 IoT Coreとモバイルホットスポット(Wi-Fi)でインターネット接続を共有する。 -Windows 10 Iot Core (Raspberry PI 2)をWifiテザリングで接続する - yoshi1966のガジェット日記~ http://yoshi1966.hateblo.jp/entry/2016/10/15/230447 この設定を行えば、開発用PCと、Windows 10 IoT Coreが、~ 192.168.137.0/24のサブネットで接続できるようになり、インターネット接続も共有可能になる。~ ただし、Windows 10 IoT Core Dashboardから操作するために、有線LAN接続は引き続き必要になる。 *開発環境 [#m85a98cc] **開発用PCの準備 [#b3444611] Windows 10がインストールされた開発用PCを準備する。 **開発環境のセットアップ [#x26cd015] ***[[Visual Studio]] 2017をインストールする。 [#n79e7b25] -ターゲットがCreators Updade対象になっているようで、[[Visual Studio]] 2015ではなく2017が必要。 -インストール時に、ユニバーサル Windowsアプリ開発ツールをインストールすること。 -参考 --VisualStudio 2017がリリース、さっそくインストールしてみた | 純規の暇人趣味ブログ~ https://jyn.jp/visualstudio-2017/ ***開発者モードを有効にする。 [#l04592a7] -[Windows] Windows 10 で開発者モードにする~ https://www.ipentec.com/document/document.aspx?page=windows-windows-10-set-developer-mode ***Windows SDKのインストール [#m891396f] Windows 10 用のWindows SDKをダウンロードしてインストールする。~ -Windows 10 用のWindows SDKをダウンロード --Windows 10 SDK – Windows アプリ開発~ https://developer.microsoft.com/windows/downloads/windows-10-sdk --以下から選択可能だが、ここでは1台だけの構築なのでEXEを選択する。 ---.EXE をダウンロードする ---.ISO をダウンロードする -Windows 10 用のWindows SDKをインストール --winsdksetup.exeをダブルクリックしてインストーラを実行。 --インストーラーが起動したら既定値でインストールする。 -インストールが完了したら、OSを再起動する。 **“Hello World”的にサンプルを実行する準備 [#n996cedb] ***サンプル・プログラムをGitHubからDownloadZIPする。 [#ca16fca5] -ms-iot/samples: Windows 10 IoT Core Samples~ https://github.com/ms-iot/samples -解凍して、HelloWorldとHelloBlinkyを入手する。 ***HelloWorldする。 [#yd263ef0] -HelloWorld.slnをダブルクリックしてVS 2017を起動する。 -[Debug]ボタンのドロップダウンから[リモート コンピューター]を選択。 -以下の入力を行う。 --アドレス: IPアドレスを手打ち(自動検出できなかった場合) --認証モード: ユニバーサル(暗号化されていないプロトコル) --[選択]ボタンを押下する。 -[Debug]ボタンを押下する。 -Hello Worldのメッセージが表示される。 ***HelloBlinkyする。 [#g7e13525] -HelloWorld.slnと同じ手順で、HelloBlinky.slnをDebug実行する。 --(2回目なので、)自動検出されているRaspberry Pi 3を選択する。 --GPIO pinsの初期化が正しく行われた旨のメッセージが表示される。 **サンプル・プログラムをデプロイして起動する。 [#z26ae788] ***デプロイ [#n2a432aa] -[ソリューション構成]を「Release」に変更し、 -[ビルド]から「xxの配置」を選択する。 -[配置が完了しました]・・・の[完全パッケージ名]をメモしておく。 ***スタートアップアプリに指定 [#g120712c] -Windows 10 IoT Core Dashboardから[[PowerShell>#z7b42565]]で接続する。 -以下のコマンドを実行する。 iotstartup list -アプリが配置されていることを確認する。 -以下のコマンドを実行してスタートアップアプリに登録する。 iotstartup add headed 完全パッケージ名の先頭部分 -shutdown /r /t 0で再起動すれば、次回起動時から自作のIoTアプリが起動する。 -元のIoT Coreメイン画面に戻すには、以下でスタートアップアプリを切り替える。 iotstartup add headed IoTCoreDefaultApp *いろいろな処理を実装する。 [#m9b9f8bf] **空のプロジェクトから実装を始める。 [#p73c6d25] ***プロジェクトの新規作成 [#q6a301ad] -[新規作成]-[プロジェクト] -[テンプレート]-[Visual C#] --GUI有りのIoTアプリ~ [Windows ユニバーサル]-[空白のアプリ]を選択 --GUI無しのIoTアプリ~ [Windows IoT Core]-[Background Application (IoT)]を選択 -Background Application (IoT)の利用には以下のインストールが必要。 --Windows IoT Core Project Templates for VS 201x - Visual Studio Marketplace ---https://marketplace.visualstudio.com/items?itemName=MicrosoftIoT.WindowsIoTCoreProjectTemplates ---https://marketplace.visualstudio.com/items?itemName=MicrosoftIoT.WindowsIoTCoreProjectTemplatesforVS15 ***UWP バージョンを選択する [#q1ab8a0d] [ターゲットバージョン]と[最小バージョン]を選択する。 -UWP バージョンの説明 --ターゲットバージョン :一般ユーザー向けのコードを新しく開発する場合、常に最新ビルドの Windows (14393) を使う。 --最小バージョン :エンタープライズ アプリを開発する場合は、最小バージョンで古いバージョンをサポートすることを検討する。 -参考 --UWP バージョンの選択 - UWP app developer | Microsoft Docs~ https://docs.microsoft.com/ja-jp/windows/uwp/updates-and-versions/choose-a-uwp-version ***Debug実行 [#m0aa48fb] -この状態だと、[[選択したUWP バージョン次第で>#q1ab8a0d]]、ローカルでのDebug実行も可能。~ しかし、以降、H/Wに関する処理を実装していくとローカルでのDebug実行はできなくなる。 -[[HelloWorld.sln>#yd263ef0]]、[[HelloBlinky.sln>#g7e13525]]と同じ手順でコレをDebug実行する。 --[ターゲットCPU]を[x86]から[ARM]に変更してから、 --[リモート コンピューター]でDebug実行する。 -空のウィンドウが表示されることを確認する。 ***Writing apps開発の設定を行う [#o7187b4c] -参照設定で[Universal Windows]-[拡張]-[Windows IoT Extension for the UWP]をチェックする。 -NuGetから「Direct Memory Mapped Driver」の「Microsoft.IoT.Lightning」をインストールして参照設定を追加。 -以下の「Direct Memory Mapped Driver」の「Microsoft.IoT.Lightning」を利用するための設定を行う。 --[[[Device Portal>#v88f9fcc]]]からドライバを切替える。 ---[Devices]をクリックしてページを切り替える。 ---[Default Controller Driver]を[Direct Memory Mapped Driver]に設定する。 ---「Warning: This option will reduce Windows security~ in exchange for performance using an in development driver.」と表示される。 ---[Update Driver]をクリックしてドライバ設定を更新する。 ---リブートするかどうかのメッセージが表示されるのでリブートする。 --以下のコードをマニフェストファイル(Package.appxmanifest)に追加。 ---Capabilities要素に以下を追加する。 <Capabilities> <!-- アプリケーションがカスタムデバイスにアクセスできるようにする --> <iot:Capability Name="lowLevelDevices" /> <!-- LightningインターフェースのデバイスGUID ID --> <DeviceCapability Name="109b86ad-f53d-4b76-aa5f-821e2ddf2141"/> </Capabilities> ---package要素に上記のiot名前空間を追加する。 xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10" IgnorableNamespaces="uap mp iot"> --参考 ---Writing apps | Windows IoT~ https://developer.microsoft.com/en-us/windows/iot/docs/buildingappsforiotcore ---Using Microsoft.IoT.Lightning.Providers library and sample code | Windows IoT~ https://developer.microsoft.com/en-us/windows/iot/docs/lightningproviders >Option 2: Referencing the library **Lチカを実装する。 [#g55fff11] ***デバイス [#v03311f0] Apple PiのLEDのGPIO numberについては、下記を参照のこと。 -Yahoo!ブログ > ボクにもわかる電子工作 > 5分で動作確認。~ 本日発売のRaspberry Pi用 IoT拡張ボードApple Pi ( Linux ) ~ https://blogs.yahoo.co.jp/bokunimowakaru/55431206.html >LEDの制御(青色LED1=GPIO 5、白色LED2=GPIO 6) ***MainPage.xaml.cs [#td45f713] using System.Threading.Tasks; using Windows.Devices; using Windows.Devices.Gpio; using Microsoft.IoT.Lightning.Providers; namespace App1 { /// <summary> /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。 /// </summary> public sealed partial class MainPage : Page { /// <summary> /// GpioPin #5は青色 /// GpioPin #6は白色 /// </summary> private readonly int LED_PIN = 6; /// <summary>GpioPin</summary> private GpioPin _gpioPin; /// <summary>Lチカを実装する。</summary> public MainPage() { this.InitializeComponent(); // LightningProviderが利用可能かどうかチェックする。 if (LightningProvider.IsLightningEnabled) { // LowLevelDevicesAggregateProviderを取得 LowLevelDevicesController.DefaultProvider = LightningProvider.GetAggregateProvider(); } // GpioControllerを取得 GpioController gpioCtrl = GpioController.GetDefault(); if (gpioCtrl == null) { return; } // GpioControllerでGpioを取得 this._gpioPin = gpioCtrl.OpenPin(LED_PIN); // GpioPinでGpioPinをコントロール。 this._gpioPin.SetDriveMode(GpioPinDriveMode.Output); this._gpioPin.Write(GpioPinValue.High); this.loop(); } /// <summary> /// UIをハングさせないよう、asyncなloop内でawaitを使用する。 /// System.Threading.Threadが無いので、こうなる。 /// </summary> private async void loop() { while (true) { // GpioPinでGpioPinをコントロール。 await Task.Delay(1000); this._gpioPin.Write(GpioPinValue.Low); await Task.Delay(1000); this._gpioPin.Write(GpioPinValue.High); } } } } **LCDに文字を表示する。 [#t5995e43] ***デバイス [#ec344dc0] -電子工作 - .NET 開発基盤部会 Wiki > 周辺機器 > LCD(液晶ディスプレイ)> I2C LCD AQM0802~ https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C#b226d3e8 ***MainPage.xaml.cs [#f822c91e] using System.Text; using System.Threading.Tasks; using Windows.Devices; using Windows.Devices.I2c; using Microsoft.IoT.Lightning.Providers; // 空白ページの項目テンプレートについては、https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x411 を参照してください namespace App1 { /// <summary> /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。 /// </summary> public sealed partial class MainPage : Page { /// <summary> /// Raspberry Pi 3で GPIO端子の I2C機能を有効化する方法 /// (ラズパイ3の GPIO端子の I2C機能を有効にして各種センサーを繋げる方法まとめ) /// http://www.neko.ne.jp/~freewing/raspberry_pi/raspberry_pi_3_gpio_enable_i2c/ /// </summary> private readonly byte _Lcd_Addr = 0x3e; /// <summary>I2cDevice</summary> private I2cDevice _Lcd; public MainPage() { this.InitializeComponent(); this.Loaded += MainPage_Loaded; } /// <summary>Loaded</summary> /// <param name="sender"></param> /// <param name="e"></param> private async void MainPage_Loaded(object sender, RoutedEventArgs e) { await this.InitLcd(); await this.DisplayLcd(); } /// <summary> /// LCDを初期化する。 /// 電子工作 - .NET 開発基盤部会 Wiki > 周辺機器 > LCD(液晶ディスプレイ)> I2C LCD AQM0802 /// https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C#b226d3e8 /// </summary> private async Task InitLcd() { // LightningProviderが利用可能かどうかチェックする。 if (LightningProvider.IsLightningEnabled) { // LowLevelDevicesAggregateProviderを取得 LowLevelDevicesController.DefaultProvider = LightningProvider.GetAggregateProvider(); } // I2cControllerを取得 I2cController i2cCtrl = await I2cController.GetDefaultAsync(); if (i2cCtrl == null) { return; } // I2cControllerでLCDを取得。 this._Lcd = i2cCtrl.GetDevice(new I2cConnectionSettings(this._Lcd_Addr)); // 初期化 await WriteLcdCmd(0x38, 1); // 行数の設定 await WriteLcdCmd(0x39, 1); // 拡張コマンドの設定開始 await WriteLcdCmd(0x14, 1); // 内部OSC周波設定 await WriteLcdCmd(0x70, 1); // コントラスト設定 await WriteLcdCmd(0x56, 1); // パワー/アイコン コントラスト設定 await WriteLcdCmd(0x6c, 250); // Follower設定 await WriteLcdCmd(0x38, 1); // 拡張コマンドの設定終了 await WriteLcdCmd(0x0c, 1); // ディスプレイ オン await WriteLcdCmd(0x01, 2); // ディスプレイ クリア } /// <summary>LCDに表示する</summary> /// <returns>Task</returns> private async Task DisplayLcd() { await WriteLcdCmd(0x01, 2); // ディスプレイ クリア // 一行目を指定して await WriteLcdCmd(0x80, 1); // Set DDRAM Address await WriteLcdDisplay("RzPi3"); // Write data to RAM // 二行目を指定して await WriteLcdCmd(0xc0, 2); // Set DDRAM Address await WriteLcdDisplay("ApplePi"); // Write data to RAM } /// <summary>LCDにコマンドを送る</summary> /// <param name="cmd">byte</param> /// <param name="waitTime_msec">int</param> /// <returns>Task</returns> private async Task WriteLcdCmd(byte cmd, int waitTime_msec) { // I2cDeviceでLCDをコントロール。 // 10 bit 書くので2 byte で先頭は空なので 0. this._Lcd.Write(new byte[] { 0, cmd }); await Task.Delay(waitTime_msec); } /// <summary>LCDに表示する</summary> /// <param name="msg">string</param> /// <returns>Task</returns> private async Task WriteLcdDisplay(string msg) { byte[] bytesMSG = Encoding.ASCII.GetBytes(msg); // I2cDeviceでLCDをコントロール。 foreach (byte b in bytesMSG) { // 10 bit 書くので2 byte で先頭は・・・ this._Lcd.Write(new byte[] { 0x40, b }); // 先頭0x40は? } await Task.Delay(1); } } } **センサーからデータを取得する。 [#j7e0332f] ***デバイス [#s4471539] -電子工作 - .NET 開発基盤部会 Wiki > 周辺機器 > センサー類 > BME280~ https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C#ca1b88b8 ***MainPage.xaml [#o749592d] <Page x:Class="App1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <TextBlock x:Name="tbkTMP" Text="tbkTMP" HorizontalAlignment="Left" VerticalAlignment="Top" Height="50" Width="400" Margin="200, 140, 0, 0" TextWrapping="Wrap" FontSize="36" /> <TextBlock x:Name="tbkHUM" Text="tbkHUM" HorizontalAlignment="Left" VerticalAlignment="Top" Height="50" Width="400" Margin="200, 210, 0, 0" TextWrapping="Wrap" FontSize="36" /> <TextBlock x:Name="tbkPRE" Text="tbkPRE" HorizontalAlignment="Left" VerticalAlignment="Top" Height="50" Width="400" Margin="200, 280, 0, 0" TextWrapping="Wrap" FontSize="36" /> </Grid> </Page> ***MainPage.xaml.cs [#zdef5dca] -Windows 10 IoT Core用のBME280ライブラリ: Todotaniのはやり物Log~ http://todotani.cocolog-nifty.com/blog/2016/01/windows-10-iot-.html のコードを一部、修正して動かした。 using System.Threading; using System.Diagnostics; // 空白ページの項目テンプレートについては、https://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x411 を参照してください namespace App1 { /// <summary> /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。 /// </summary> public sealed partial class MainPage : Page { /// <summary>ライブラリ</summary> private BME280 bme280; /// <summary>タイマー</summary> private Timer periodicTimer; public MainPage() { this.InitializeComponent(); this.Loaded += MainPage_Loaded; } /// <summary>Loaded</summary> /// <param name="sender">object</param> /// <param name="e">RoutedEventArgs</param> private void MainPage_Loaded(object sender, RoutedEventArgs e) { this.bme280 = new BME280(); this.initBme280(); } /// <summary>初期化</summary> private async void initBme280() { await this.bme280.Initialize(); this.periodicTimer = new Timer(this.TimerCallback, null, 0, 1000); } /// <summary>TimerCallback</summary> /// <param name="state">object</param> private void TimerCallback(object state) { // ココの処理はBackground Threadで動作する。 var temp = bme280.ReadTemperature(); var press = bme280.ReadPreasure() / 100; var humidity = bme280.ReadHumidity(); var alt = bme280.ReadAltitude(1013); // 1013hPa = pressure at 0m Debug.WriteLine( "Temp:{0:F2}℃ Humidity:{1:F2}% Press:{2:F2}hPa Alt:{3:F0}m", temp, humidity, press, alt); // 主スレッドで処理する(以下はUWPでのControl.Invokeの書き方らしい) var task = this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => { this.tbkTMP.Text = temp.ToString("F2") + "℃"; this.tbkHUM.Text = humidity.ToString("F2") + "%"; this.tbkPRE.Text = press.ToString("F2") + "hPa"; }); } } } ***BME280.cs [#m44eb7c7] using System; using System.Threading.Tasks; using System.Diagnostics; using Windows.Devices; using Windows.Devices.I2c; using Microsoft.IoT.Lightning.Providers; namespace App1 { /// <summary>BME280キャリブレーション用</summary> public class BME280_CalibrationData { // BME280 Registers /// <summary></summary> public ushort dig_T1 { get; set; } /// <summary></summary> public short dig_T2 { get; set; } /// <summary></summary> public short dig_T3 { get; set; } /// <summary></summary> public ushort dig_P1 { get; set; } /// <summary></summary> public short dig_P2 { get; set; } /// <summary></summary> public short dig_P3 { get; set; } /// <summary></summary> public short dig_P4 { get; set; } /// <summary></summary> public short dig_P5 { get; set; } /// <summary></summary> public short dig_P6 { get; set; } /// <summary></summary> public short dig_P7 { get; set; } /// <summary></summary> public short dig_P8 { get; set; } /// <summary></summary> public short dig_P9 { get; set; } /// <summary></summary> public byte dig_H1 { get; set; } /// <summary></summary> public short dig_H2 { get; set; } /// <summary></summary> public byte dig_H3 { get; set; } /// <summary></summary> public short dig_H4 { get; set; } /// <summary></summary> public short dig_H5 { get; set; } /// <summary></summary> public sbyte dig_H6 { get; set; } } /// <summary>BME280 本体</summary> public class BME280 { #region 各種列挙型 /// <summary>キャリブレーションデータのレジスタアドレス</summary> enum eCalibrationDataRegistersAddress : byte { BME280_REGISTER_DIG_T1 = 0x88, BME280_REGISTER_DIG_T2 = 0x8A, BME280_REGISTER_DIG_T3 = 0x8C, BME280_REGISTER_DIG_P1 = 0x8E, BME280_REGISTER_DIG_P2 = 0x90, BME280_REGISTER_DIG_P3 = 0x92, BME280_REGISTER_DIG_P4 = 0x94, BME280_REGISTER_DIG_P5 = 0x96, BME280_REGISTER_DIG_P6 = 0x98, BME280_REGISTER_DIG_P7 = 0x9A, BME280_REGISTER_DIG_P8 = 0x9C, BME280_REGISTER_DIG_P9 = 0x9E, BME280_REGISTER_DIG_H1 = 0xA1, BME280_REGISTER_DIG_H2 = 0xE1, BME280_REGISTER_DIG_H3 = 0xE3, BME280_REGISTER_DIG_H4_L = 0xE4, BME280_REGISTER_DIG_H4_H = 0xE5, BME280_REGISTER_DIG_H5_L = 0xE5, BME280_REGISTER_DIG_H5_H = 0xE6, BME280_REGISTER_DIG_H6 = 0xE7, }; /// <summary>測定データのレジスタアドレス</summary> enum eDataRegistersAddress : byte { BME280_REGISTER_PRESSUREDATA_MSB = 0xF7, BME280_REGISTER_PRESSUREDATA_LSB = 0xF8, BME280_REGISTER_PRESSUREDATA_XLSB = 0xF9, // bits <7:4> BME280_REGISTER_TEMPDATA_MSB = 0xFA, BME280_REGISTER_TEMPDATA_LSB = 0xFB, BME280_REGISTER_TEMPDATA_XLSB = 0xFC, // bits <7:4> BME280_REGISTER_HUMIDDATA_MSB = 0xFD, BME280_REGISTER_HUMIDDATA_LSB = 0xFE, }; /// <summary>コマンド</summary> enum eCmd : byte { BME280_REGISTER_CHIPID = 0xD0, BME280_REGISTER_SOFTRESET = 0xE0, BME280_REGISTER_CONTROLHUMID = 0xF2, BME280_REGISTER_STATUS = 0xF3, BME280_REGISTER_CONTROL = 0xF4, BME280_REGISTER_CONFIG = 0xF5, }; /// <summary> /// /// Enables 2-wire I2C interface when set to ‘0’ /// </summary> public enum interface_mode_e : byte { i2c = 0, spi = 1 }; /// <summary> /// スタンバイ時間のオプション /// t_sb standby options /// effectively the gap between automatic measurements when in "normal" mode /// </summary> public enum standbySettings_e : byte { tsb_0p5ms = 0, tsb_62p5ms = 1, tsb_125ms = 2, tsb_250ms = 3, tsb_500ms = 4, tsb_1000ms = 5, tsb_10ms = 6, tsb_20ms = 7 }; /// <summary> /// BME280のモード設定 /// sensor modes, /// it starts off in sleep mode on power on forced is to take a single measurement now normal takes measurements reqularly automatically /// </summary> public enum mode_e : byte { smSleep = 0, smForced = 1, smNormal = 3 }; /// <summary> /// IIRフィルタの有効/無効 /// Filter coefficients /// higher numbers slow down changes, such as slamming doors /// </summary> public enum filterCoefficient_e : byte { fc_off = 0, // OFF fc_2 = 1, fc_4 = 2, fc_8 = 3, fc_16 = 4 }; /// <summary> /// Oversampling options for humidity /// Oversampling reduces the noise from the sensor /// </summary> public enum oversampling_e : byte { osSkipped = 0, os1x = 1, os2x = 2, os4x = 3, os8x = 4, os16x = 5 }; #endregion #region メンバ変数 /// <summary> /// Raspberry Pi 3で GPIO端子の I2C機能を有効化する方法 /// (ラズパイ3の GPIO端子の I2C機能を有効にして各種センサーを繋げる方法まとめ) /// http://www.neko.ne.jp/~freewing/raspberry_pi/raspberry_pi_3_gpio_enable_i2c/ /// </summary> const byte BME280_Address = 0x76; /// <summary> /// BME280 device signature /// </summary> const byte BME280_Signature = 0x60; /// <summary> /// String for the friendly name of the I2C bus /// </summary> private const string I2CControllerName = "I2C1"; /// <summary> /// Create an I2C device /// </summary> private I2cDevice bme280 = null; /// <summary> /// キャリブレーション /// Create new calibration data for the sensor /// </summary> private BME280_CalibrationData CalibrationData; /// <summary>インターフェイスモード</summary> private byte spi3w_en = (byte)interface_mode_e.i2c; /// <summary>スタンバイ時間のオプション</summary> private byte t_sb; /// <summary>BME280のモード設定</summary> private byte mode; /// <summary>IIRフィルタの有効/無効(サンプリング回数)</summary> private byte filter; /// <summary>温度測定の有効(オーバーサンプリング値)/無効</summary> private byte osrs_t; /// <summary>気圧測定の有効(オーバーサンプリング値)/無効</summary> private byte osrs_p; /// <summary>湿度測定の有効(オーバーサンプリング値)/無告</summary> private byte osrs_h; /// <summary>データ校正用変数</summary> private Int32 t_fine; #endregion /// <summary>Constructor</summary> /// <param name="t_sb">スタンバイ時間のオプション</param> /// <param name="mode">BME280のモード設定</param> /// <param name="filter">IIRフィルタの有効/無効(サンプリング回数)</param> /// <param name="osrs_t">温度測定の有効(オーバーサンプリング値)/無効</param> /// <param name="osrs_p">気圧測定の有効(オーバーサンプリング値)/無効</param> /// <param name="osrs_h">湿度測定の有効(オーバーサンプリング値)/無告</param> public BME280(standbySettings_e t_sb = standbySettings_e.tsb_0p5ms, // 0.5msec mode_e mode = mode_e.smNormal, // Normal filterCoefficient_e filter = filterCoefficient_e.fc_16, // サンプリング回数 * 16 oversampling_e osrs_t = oversampling_e.os2x, // オーバーサンプリング * 2 oversampling_e osrs_p = oversampling_e.os16x, // オーバーサンプリング * 16 oversampling_e osrs_h = oversampling_e.os1x) // オーバーサンプリング * 1 { this.t_sb = (byte)t_sb; this.mode = (byte)mode; this.filter = (byte)filter; this.osrs_t = (byte)osrs_t; this.osrs_p = (byte)osrs_p; this.osrs_h = (byte)osrs_h; } #region 初期化 /// <summary> /// Method to initialize the BME280 sensor /// </summary> /// <returns></returns> public async Task Initialize() { Debug.WriteLine("BME280::Initialize"); try { ////Instantiate the I2CConnectionSettings using the device address of the BME280 //I2cConnectionSettings settings = new I2cConnectionSettings(BME280_Address); ////Set the I2C bus speed of connection to fast mode //settings.BusSpeed = I2cBusSpeed.FastMode; ////Use the I2CBus device selector to create an advanced query syntax string //string aqs = I2cDevice.GetDeviceSelector(I2CControllerName); ////Use the Windows.Devices.Enumeration.DeviceInformation class to create a collection using the advanced query syntax string //DeviceInformationCollection dis = await DeviceInformation.FindAllAsync(aqs); ////Instantiate the the BME280 I2C device using the device id of the I2CBus and the I2CConnectionSettings //bme280 = await I2cDevice.FromIdAsync(dis[0].Id, settings); // LightningProviderが利用可能かどうかチェックする。 if (LightningProvider.IsLightningEnabled) { // LowLevelDevicesAggregateProviderを取得 LowLevelDevicesController.DefaultProvider = LightningProvider.GetAggregateProvider(); } // I2cControllerを取得 I2cController i2cCtrl = await I2cController.GetDefaultAsync(); if (i2cCtrl == null) { return; } // I2cControllerでbme280を取得。 this.bme280 = i2cCtrl.GetDevice(new I2cConnectionSettings(BME280.BME280_Address)); //Check if device was found if (this.bme280 == null) { Debug.WriteLine("Device not found"); } } catch (Exception e) { Debug.WriteLine("Exception: " + e.Message + "\n" + e.StackTrace); throw; } byte[] readChipID = new byte[] { (byte)eCmd.BME280_REGISTER_CHIPID }; byte[] ReadBuffer = new byte[] { 0xFF }; // Read the device signature bme280.WriteRead(readChipID, ReadBuffer); Debug.WriteLine("BME280 Signature: " + ReadBuffer[0].ToString()); // Verify the device signature if (ReadBuffer[0] != BME280.BME280_Signature) { Debug.WriteLine("BME280::Begin Signature Mismatch."); return; } // Read the coefficients table // キャリブレーション読み取り this.CalibrationData = this.ReadCoefficeints(); #region レジスタの設定 // Set configuration registers this.WriteConfigRegister(); // configレジスタ this.WriteControlMeasurementRegister(); // ctrl_measレジスタ this.WriteControlRegisterHumidity(); // ctrl_humレジスタ //Set configuration registers again to ensure configuration of humidity this.WriteConfigRegister(); this.WriteControlMeasurementRegister(); this.WriteControlRegisterHumidity(); #endregion //Dummy read temp to setup t_fine this.ReadTemperature(); } #region キャリブレーション読み取り /// <summary> /// BME280キャリブレーション読み取り /// Method to read the caliberation data from the registers /// </summary> /// <returns></returns> private BME280_CalibrationData ReadCoefficeints() { // 16 bit calibration data is stored as Little Endian, the helper method will do the byte swap. this.CalibrationData = new BME280_CalibrationData(); // Read temperature calibration data this.CalibrationData.dig_T1 = this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_T1); this.CalibrationData.dig_T2 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_T2); this.CalibrationData.dig_T3 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_T3); // Read presure calibration data this.CalibrationData.dig_P1 = this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_P1); this.CalibrationData.dig_P2 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_P2); this.CalibrationData.dig_P3 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_P3); this.CalibrationData.dig_P4 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_P4); this.CalibrationData.dig_P5 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_P5); this.CalibrationData.dig_P6 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_P6); this.CalibrationData.dig_P7 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_P7); this.CalibrationData.dig_P8 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_P8); this.CalibrationData.dig_P9 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_P9); // Read humidity calibration data this.CalibrationData.dig_H1 = this.ReadByte((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_H1); this.CalibrationData.dig_H2 = (short)this.ReadUInt16_LittleEndian((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_H2); this.CalibrationData.dig_H3 = this.ReadByte((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_H3); short e4 = this.ReadByte((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_H4_L); // Read 0xE4 short e5 = this.ReadByte((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_H4_H); // Read 0xE5 this.CalibrationData.dig_H4 = (short)((e4 << 4) + (e5 & 0x0F)); short e6 = this.ReadByte((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_H5_H); // Read 0xE6 this.CalibrationData.dig_H5 = (short)((e5 >> 4) + (e6 << 4)); this.CalibrationData.dig_H6 = (sbyte)this.ReadByte((byte)eCalibrationDataRegistersAddress.BME280_REGISTER_DIG_H6); return CalibrationData; } #endregion #region レジスタの設定 /// <summary> /// configレジスタの設定 /// ・t_sb : スタンバイ時間 /// ・filter : IIRフィルタの有効/無効 /// ・spi3w_en : 3 wire SPIの有効/無効 /// ---------- /// Method to write the config register (default 16) /// 000 100 00 /// ↑ ↑ ↑I2C mode /// ↑ ↑Filter coefficient = 16 /// ↑t_sb = 0.5ms /// </summary> private void WriteConfigRegister() { byte value = (byte)((this.t_sb << 5) + (this.filter << 2) + this.spi3w_en); byte[] WriteBuffer = new byte[] { (byte)eCmd.BME280_REGISTER_CONFIG, value }; bme280.Write(WriteBuffer); return; } /// <summary> /// ctrl_measレジスタの設定 /// ・osrs_t : 温度測定の有効(オーバーサンプリング値)/無効 /// ・osrs_p : 気圧測定の有効(オーバーサンプリング値)/無効 /// ・mode : BME280の測定モード設定 /// ---------- /// Method to write the control measurment register (default 87) /// 010 101 11 /// ↑ ↑ ↑ mode /// ↑ ↑ Pressure oversampling /// ↑ Temperature oversampling /// </summary> private void WriteControlMeasurementRegister() { byte value = (byte)((this.osrs_t << 5) + (this.osrs_p << 2) + this.mode); byte[] WriteBuffer = new byte[] { (byte)eCmd.BME280_REGISTER_CONTROL, value }; bme280.Write(WriteBuffer); return; } /// <summary> /// ctrl_humレジスタの設定 /// ・osrs_h : 湿度測定の有効(オーバーサンプリング値)/無告 /// ---------- /// Method to write the humidity control register (default 01) /// </summary> private void WriteControlRegisterHumidity() { byte value = this.osrs_h; byte[] WriteBuffer = new byte[] { (byte)eCmd.BME280_REGISTER_CONTROLHUMID, value }; bme280.Write(WriteBuffer); return; } #endregion #endregion #region センサーを読む /// <summary>気温を読む</summary> /// <returns>float</returns> public float ReadTemperature() { //Read the MSB, LSB and bits 7:4 (XLSB) of the temperature from the BME280 registers byte tmsb = this.ReadByte((byte)eDataRegistersAddress.BME280_REGISTER_TEMPDATA_MSB); byte tlsb = this.ReadByte((byte)eDataRegistersAddress.BME280_REGISTER_TEMPDATA_LSB); byte txlsb = this.ReadByte((byte)eDataRegistersAddress.BME280_REGISTER_TEMPDATA_XLSB); // bits 7:4 //Combine the values into a 32-bit integer int t = (tmsb << 12) + (tlsb << 4) + (txlsb >> 4); //Convert the raw value to the temperature in degC double temp = this.BME280_compensate_T_double(t); //Return the temperature as a float value return (float)temp; } /// <summary>気圧を読む</summary> /// <returns>float</returns> public float ReadPreasure() { //Read the MSB, LSB and bits 7:4 (XLSB) of the pressure from the BME280 registers byte pmsb = this.ReadByte((byte)eDataRegistersAddress.BME280_REGISTER_PRESSUREDATA_MSB); byte plsb = this.ReadByte((byte)eDataRegistersAddress.BME280_REGISTER_PRESSUREDATA_LSB); byte pxlsb = this.ReadByte((byte)eDataRegistersAddress.BME280_REGISTER_PRESSUREDATA_XLSB); // bits 7:4 //Combine the values into a 32-bit integer int p = (pmsb << 12) + (plsb << 4) + (pxlsb >> 4); //Convert the raw value to the pressure in Pa long pres = this.BME280_compensate_P_Int64(p); //Return the pressure as a float value return ((float)pres) / 256; } /// <summary>湿度を読む</summary> /// <returns></returns> public float ReadHumidity() { //Read the MSB and LSB of the humidity from the BME280 registers byte hmsb = this.ReadByte((byte)eDataRegistersAddress.BME280_REGISTER_HUMIDDATA_MSB); byte hlsb = this.ReadByte((byte)eDataRegistersAddress.BME280_REGISTER_HUMIDDATA_LSB); //Combine the values into a 32-bit integer int h = (hmsb << 8) + hlsb; //Convert the raw value to the humidity in % double humidity = this.BME280_compensate_H_double(h); //Return the humidity as a float value return (float)humidity; } #endregion #region 表示用文字列の作成 /// <summary> /// ℃で温度を戻すメソッド /// 分解能は0.01℃。 /// Method to return the temperature in DegC. Resolution is 0.01 DegC. /// Output value of “51.23” equals 51.23 DegC. /// </summary> /// <param name="adc_T"></param> /// <returns></returns> private double BME280_compensate_T_double(int adc_T) { double var1, var2, T; //The temperature is calculated using the compensation formula in the BME280 datasheet var1 = (adc_T / 16384.0 - CalibrationData.dig_T1 / 1024.0) * CalibrationData.dig_T2; var2 = ((adc_T / 131072.0 - CalibrationData.dig_T1 / 8192.0) * (adc_T / 131072.0 - CalibrationData.dig_T1 / 8192.0)) * CalibrationData.dig_T3; this.t_fine = (int)(var1 + var2); T = (var1 + var2) / 5120.0; return T; } /// <summary> /// Q24.8形式(24の整数ビットと8の小数ビット)のPaの圧力を返すメソッド。 /// Method to returns the pressure in Pa, in Q24.8 format (24 integer bits and 8 fractional bits). /// Output value of “24674867” represents 24674867/256 = 96386.2 Pa = 963.862 hPa /// </summary> /// <param name="adc_P">int</param> /// <returns>long</returns> private long BME280_compensate_P_Int64(int adc_P) { long var1, var2, p; //The pressure is calculated using the compensation formula in the BME280 datasheet var1 = (long)this.t_fine - 128000; var2 = var1 * var1 * CalibrationData.dig_P6; var2 = var2 + ((var1 * CalibrationData.dig_P5) << 17); var2 = var2 + ((long)CalibrationData.dig_P4 << 35); var1 = ((var1 * var1 * CalibrationData.dig_P3) >> 8) + ((var1 * CalibrationData.dig_P2) << 12); var1 = (((long)1 << 47) + var1) * CalibrationData.dig_P1 >> 33; if (var1 == 0) { Debug.WriteLine("BME280_compensate_P_Int64 Jump out to avoid / 0"); return 0; //Avoid exception caused by division by zero } //Perform calibration operations as per datasheet: p = 1048576 - adc_P; p = (((p << 31) - var2) * 3125) / var1; var1 = ((long)CalibrationData.dig_P9 * (p >> 13) * (p >> 13)) >> 25; var2 = ((long)CalibrationData.dig_P8 * p) >> 19; p = ((p + var1 + var2) >> 8) + ((long)CalibrationData.dig_P7 << 4); return p; } /// <summary> /// %rHの湿度をdoubleとして返す。 /// Returns humidity in %rH as as double. Output value of “46.332” represents 46.332 %rH /// </summary> /// <param name="adc_H"></param> /// <returns></returns> private double BME280_compensate_H_double(int adc_H) { double var_H; var_H = this.t_fine - 76800.0; var_H = (adc_H - (CalibrationData.dig_H4 * 64.0 + CalibrationData.dig_H5 / 16384.0 * var_H)) * CalibrationData.dig_H2 / 65536.0 * (1.0 + CalibrationData.dig_H6 / 67108864.0 * var_H * (1.0 + CalibrationData.dig_H3 / 67108864.0 * var_H)); var_H = var_H * (1.0 - CalibrationData.dig_H1 * var_H / 524288.0); if (var_H > 100.0) { Debug.WriteLine("BME280_compensate_H_double Jump out to 100%"); var_H = 100.0; } else if (var_H < 0.0) { Debug.WriteLine("BME280_compensate_H_double Jump under 0%"); var_H = 0.0; } return var_H; } /// <summary> /// 気圧から高度を計算するメソッド /// Method to take the sea level pressure in Hectopascals(hPa) as a parameter and calculate the altitude using current pressure. /// </summary> /// <param name="seaLevel">float</param> /// <returns>float</returns> public float ReadAltitude(float seaLevel) { //Read the pressure first float pressure = this.ReadPreasure(); //Convert the pressure to Hectopascals(hPa) pressure /= 100; //Calculate and return the altitude using the international barometric formula return 44330.0f * (1.0f - (float)Math.Pow((pressure / seaLevel), 0.1903f)); } #endregion #region 読み取り /// <summary> /// Method to read an 8-bit value from a register /// </summary> /// <param name="register">byte</param> /// <returns>byte</returns> private byte ReadByte(byte register) { byte value = 0; byte[] writeBuffer = new byte[] { 0x00 }; byte[] readBuffer = new byte[] { 0x00 }; writeBuffer[0] = register; bme280.WriteRead(writeBuffer, readBuffer); value = readBuffer[0]; return value; } /// <summary> /// Method to read a 16-bit value from a register and return it in little endian format /// </summary> /// <param name="register">byte</param> /// <returns>ushort</returns> private ushort ReadUInt16_LittleEndian(byte register) { ushort value = 0; byte[] writeBuffer = new byte[] { 0x00 }; byte[] readBuffer = new byte[] { 0x00, 0x00 }; writeBuffer[0] = register; bme280.WriteRead(writeBuffer, readBuffer); int h = readBuffer[1] << 8; int l = readBuffer[0]; value = (ushort)(h + l); return value; } #endregion } } ***結果 [#e3a6e5fe] #ref(SensorData.jpg,left,nowrap,SensorData,30%) **Twitterにセンサー情報をTweetする。 [#x047c7ac] 上記のセンサー情報をCoreTweetというライブラリを使用してTwitterにTweetする。 -.NET向けのTwitterライブラリ「CoreTweet」の使い方まとめ - 酢ろぐ!~ http://blog.ch3cooh.jp/entry/coretweet --C#とCoreTweetを使って簡単にTwitterへツイートするbotを作る - 酢ろぐ!~ http://blog.ch3cooh.jp/entry/20140808/1407464147 CoreTweetは、Twitter APIのクライアント・ライブラリなので、~ 非常に多機能っぽいが、ここではTweetするAPIを利用するだけ。 Twitterからエラーが返った場合、以下のエラー一覧が参考になる。 -Atsushi's Homepage ~ Twitter API を使ってみる~ http://www.antun.net/tips/api/twitter.html ***Twitter登録 [#sf52910f] +サインアップして、 +サインインする。 +[[Twitterの開発者サイト>https://dev.twitter.com/]]に移動し、 +[[My Appsのリンク>https://apps.twitter.com/]]をクリックする。 +そして、[[Create New App>https://apps.twitter.com/app/new]]ボタンを押下する。 +[Create an application]画面で以下のように入力して、 #ref(Twitter1.png,left,nowrap,Twitter1,30%) +[Create youre Twitter application]ボタンを押下する。 +アプリケーション登録後、登録したアプリケーションの画面に遷移するので、 +そこで、[Keys and Access Tokens Permissions]タブを押下する。 +表示される[Consumer Key (API Key)], [Consumer Secret (API Secret)]をメモ。 #ref(Twitter2.png,left,nowrap,Twitter2,50%) +次に、当該画面の下部にある[Create my access token]ボタンを押下、~ [Access Token], [Access Token Secret]を入手してコレをメモする。 #ref(Twitter3.png,left,nowrap,Twitter3,50%) +この4つのキー[Consumer Key], [Consumer Secret], [Access Token], [Access Token Secret]を使用してTweetを行う。 ***MainPage.xaml.cs [#d16c1be8] -[[前述のコード>#zdef5dca]]にTweet処理を追加する。 -はじめに以下を行う、 --CoreTweetをNugetから入手。 --CoreTweetをusingに追加する。 --そして、UWPからTweet可能にするようにネットワーク・アクセスを許可する。 ---Windows10でVPN接続するとストアアプリが外に出られなくなる - tmytのらくがき~ http://blog.tmyt.jp/entry/2015/11/23/154702 ---以下が、その設定画面(Package.appxmanifestを選択、機能タブに遷移)。~ ここでは、以下の2つのチェック・ボックスにチェックを入れ、機能をオンにしてみた。 #ref(Twitter4.png,left,nowrap,Twitter4,50%) -Tweet用のTimerとCallbackを追加する。 --Timerと言っても色々あるので以下を参考に、DispatcherTimerを選択。~ Tweet元の情報をUWPのUI場の情報から取得する必要があったので。 ---.NET の Timer を考えよう(1) | うめつる開発室~ http://blog.ume108.mobi/?p=188 ---DispatcherTimerを使って定期実行をする « Tech Booster~ http://techbooster.jpn.org/windowsphone7/10690/ ---c# - Comparing Timer with DispatcherTimer - Stack Overflow~ http://stackoverflow.com/questions/1111645/comparing-timer-with-dispatchertimer -以下、[[前述のコード>#zdef5dca]]からの差分。 using System.Threading; using System.Diagnostics; using CoreTweet; ・・・ /// <summary>ライブラリ</summary> private BME280 bme280; /// <summary>SensorのTimer</summary> private Timer periodicTimer; /// <summary>TwitterのTimer</summary> private DispatcherTimer twitterTimer; /// <summary>TwitterのToken</summary> private Tokens tokens; public MainPage() { this.InitializeComponent(); this.Loaded += MainPage_Loaded; } /// <summary>Loaded</summary> /// <param name="sender">object</param> /// <param name="e">RoutedEventArgs</param> private void MainPage_Loaded(object sender, RoutedEventArgs e) { this.bme280 = new BME280(); this.initBme280(); this.initTwitter(); } /// <summary>Twitterの初期化</summary> private void initTwitter() { // 実際の値を入力する。その際、{}は削除する。 this.tokens = Tokens.Create( "{API key}" , "{API secret}" , "{Access token}" , "{Access token secret}"); this.twitterTimer = new DispatcherTimer(); this.twitterTimer.Interval = TimeSpan.FromSeconds(10); // Tweet間隔を調整 this.twitterTimer.Tick += this.TimerCallback; this.twitterTimer.Start(); } /// <summary>Bme280の初期化</summary> private async void initBme280() { await this.bme280.Initialize(); this.periodicTimer = new Timer(this.TimerCallback, null, 0, 1000); } /// <summary>TwitterのTimerCallback</summary> /// <param name="state">object</param> private void TimerCallback(object sender, object e) { string text = this.tbkTMP.Text +"\r\n" + this.tbkHUM.Text + "\r\n" + this.tbkPRE.Text; Debug.WriteLine("Tweet :" + text); this.tweet(text); } /// <summary>tweetする</summary> /// <param name="text">tweetのテキスト</param> private async void tweet(string text) { Status _status = await this.tokens.Statuses.UpdateAsync(status => text); } /// <summary>Bme280のTimerCallback</summary> /// <param name="state">object</param> private void TimerCallback(object state) ・・・ ***結果 [#xcff3626] #ref(SensorTweet.jpg,left,nowrap,SensorTweet,50%) **[[Wio Node>https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C#c4b8bab8]]を使用する。 [#uf5a57d9] ***[[Wio Node>https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C#c4b8bab8]]のデバイスのデータをRESTで取得する。 [#nfef5083] ***[[Wio Node>https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C#c4b8bab8]]のデバイスをRESTで操作する。 [#h620b0f9] **監視カメラを実装する。 [#b7cf89bb] -カメラ・デバイスは、USBの[[Inboxドライバ>#tf570855]]経由で操作する。 -カメラ・デバイスの操作には、Windows.Media.Capture名前空間のAPIを使用する。 -顔の検出には、Windows.Media.FaceAnalysis.FaceDetector名前空間のAPIを使用する。 *参考 [#u312157d] **電子工作 [#k0189bc1] -電子工作 - .NET 開発基盤部会 Wiki~ https://dotnetdevelopmentinfrastructure.osscons.jp/index.php?%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C **Build Insider [#e0e6c4b2] -Raspberry Pi 2電子工作をWindows 10 IoT Coreで始めよう! - Build Insider~ http://www.buildinsider.net/small/windowsiot/01 **Microsoft [#f1df4e4b] ***ms-iot/samples: Windows 10 IoT Core Samples [#m46c22ac] https://github.com/ms-iot/samples ***Windows 10 IoTCore ハンズオントレーニング [#xec2e2c3] -1章 Windows 10 IoTCore 概要~ http://download.microsoft.com/download/F/C/4/FC488185-8F87-4B40-B9EF-0850110A50A2/IoT_Core_1.pdf -2 章 Windows 10 IoT Core のインストール~ http://download.microsoft.com/download/F/C/4/FC488185-8F87-4B40-B9EF-0850110A50A2/IoT_Core_2.pdf -3章 UWP アプリの開発~ http://download.microsoft.com/download/F/C/4/FC488185-8F87-4B40-B9EF-0850110A50A2/IoT_Core_3.pdf -4章 UI をもたないデバイスへのリモートアクセス~ http://download.microsoft.com/download/F/C/4/FC488185-8F87-4B40-B9EF-0850110A50A2/IoT_Core_4.pdf -5 章 センサーデータをクラウドへ集約~ http://download.microsoft.com/download/F/C/4/FC488185-8F87-4B40-B9EF-0850110A50A2/IoT_Core_5.pdf **電子工作(MAKE) [#n1d42516] -ラズベリーパイWindows | 記事~ http://www.denshi.club/make/raspberrypi/ --マイコン・ボードRaspberry Piを使う前に知っておきたいこと (1) - (3)~ http://www.denshi.club/make/2016/01/raspberry-pi1.html --IoTへの挑戦 Raspberry PiでWindows 10 IoT Coreを動かす (1) - (11)~ http://www.denshi.club/make/2016/01/iotrasberry-piwindows10-iot1.html --Raspberry Pi 3 model Bが入手できました (1) - (10)~ http://www.denshi.club/make/2016/04/raspberry-pi-3-model-b1.html --Raspberry PiにI2CインターフェースのLCDモジュールを接続する (1) - (9)~ http://www.denshi.club/make/2016/08/raspberry-pii2clcd1.html --AQMシリーズのI2C接続LCDキャラクタ・ディスプレイを使う (1) - (2)~ http://www.denshi.club/make/2016/10/aqmi2clcd1.html --Raspberry Piを利用してIoTのシステムを構築する (1) - (2)~ http://www.denshi.club/make/2016/12/raspberry-piiot1wi-fi.html --IoTの格納先を考える (1) - (5)~ http://www.denshi.club/make/2017/01/iot1sql-server-express.html ---- Tags: [[:インフラストラクチャ]], [[:Windows]], [[:IoT]]