2018年4月21日土曜日

Windows 10 IOT Core + TWELITE

 Raspberry Pi 3Bで動いているWindows 10 IOT Core用にアプリを書き始めました。UWPアプリは初めてなうえに、XAMLも初心者の域を出ないので、なかなか捗りません。
 TWELITEでドアの開閉を検出して、予め登録したMACアドレスにWake On LANパケットを送出するのがアプリの主な機能です。同様の仕組みはPython/Raspbianで動作しているのですが、誰でもメンテナンスできるように、UWPアプリとして作り直すことにしました。
  • シリアルポートに流れるTWELTIEの出力を読むバックグラウンドアプリ
  • 設定およびログ表示のためのフォアグラウンドアプリ
という基本構成は固まりました。バックグラウンドとフォアグラウンドの間の通信ができるまでに試行錯誤を繰り返し、BackgroundTaskとAppServiceでやりたいことができるようになるまでかなり時間がかかりましたが、ようやく見通しが立ってきました。



2017年3月7日火曜日

TWE-LITE 2525Aの連続稼働が終了

 TWE-LITE 2525Aの連続稼働が、電池切れにより3月6日の朝で終了しました。11月17日の夜から開始して、およそ3カ月半、108日動き続けました。

 電池切れ間際の電源電圧は約2Vでした。グラフを見ると、2.2Vあたりから電圧低下が早くなっているように見えます。2.1Vから約1週間で終了しました。

 記録された送信回数は25,000以上でした。年末年始にログが取れなかった期間があるので、実際には26,000回を超えていたのではないかと思います。一回のドア開閉で2回の送信が行われるので、一日当たりドア開閉回数はおよそ120回という事になります。

 加速度センサーの消費電流を仮に40μAとすると、一日当たり0.96mAhが消費されます。使用したコイン電池の容量は210mAhですので、加速度センサーとTWE-Liteでだいたい半分ずつ消費していたようです。この計算だと、ドア開閉が多ければ電池切れはさらに早くなりますし、殆どドアを開けなければ半年くらいは持つかもしれません。

 使用した電池は、amazonで買った中国製電池です。星一つのレビュー評価が多いですが、普通に使えました。

2017年2月5日日曜日

PWMとLPFで疑似DA変換

 TWE-Liteのオーディオアプリでは、PWM出力をLPFに通すことで、デューティー比の変化を電圧に変換しています。Analog Discovery 2を買ったので、この様子を視覚的に確認してみました。

 LPFを通す前のPWM出力と、LPFとスピーカーアンプを通った後の音声出力にプローブをつないで、同時に波形を見てみました。
プローブの接続箇所
 波形は、このようになりました。上がPWM波形、下がスピーカー出力の波形です。この時は、テストトーン(正弦波?)を再生していました。
電圧の山では高デューティー比
電圧の谷では低デューティー比

 PWMのデューティー比が高い箇所(約60%)ではスピーカー出力の電圧が高く、デューティー比が低い箇所(約40%)では電圧が低くなっています。
 一見しただけではわかりにくいのですが、Quick Measureでカーソル位置の値を見ると、簡単に理解できます。


2017年1月22日日曜日

TWE-Liteで出力した赤外線リモコン信号の波形

 今までオシロスコープ無しで開発してきましたが、やっぱりあると便利なので、場所を取らないUSBオシロスコープ Analog Discovery 2 を秋月電子で買いました。

 とりあえず、TWE-Liteで作った赤外線リモコン信号の送受信機が正しく動いている事を確認しました。下のスクリーンキャプチャで、水色が赤外線受光モジュールの出力、黄色がTWE-Liteの赤外線リモコン信号出力です。同じタイミングで信号が出ていることが確認できました。

2017年1月20日金曜日

TWE-LITE 2525Aの連続稼働が2カ月を超えました

 11月中旬から動かし始めたTWE-LITE 2525Aは、予想を超えて、まだ動き続けています。


 現在の電源電圧は、2.4V前後です。もう少し、頑張れそうです。

2017年1月14日土曜日

TWE-LiteのInfra-Red Transmitter

 TWE-Liteには赤外線リモコン信号を送信するための機能が用意されているのですが、使用例を見たことが無いので、考え方をメモっておきます。

 副搬送波の周期とデューティー比、データビットを構成する微小ビットの長さ等、タイマーの設定に関係するパラメータは、bAHI_InfraredEnable()で設定します。
bool_t bAHI_InfraredEnable(
uint8 u8Prescale,
uint16 u16Hi,
uint16 u16Lo,
uint16 u16BitPeriodInCarrierPeriods,
bool_t bInvertOutput,
bool_t bInterruptEnable);
  • u8Prescale 赤外線送信で使うTIMER2の分周比を指定します。Users Guideの例では2(=1/4)を指定していますが、16MHzの16ビットタイマーのまま分周しなくても無理なく使えますので、0で良いと思います。
  • u16Hi 副搬送波1周期のうちの非アクティブ時間をタイマーのクロック数で指定します。
  • u16Lo 副搬送波の周期をタイマーのクロック数で指定します。
  • u16BitPeriodInCarrierPeriods データビットを構成する微小ビットの長さを、副搬送波の周期(CarrierPeriod)で割った個数で指定します。
  • bInvertOutput 出力のHi/Loを反転する場合にTRUEを指定します。
  • bInterruptEnable 送信完了割り込みを発生させる場合にTRUEを指定します。
bAHI_InfraredEnable()で設定できる構造は微小ビットまでで、データビットの1/0やリーダーコード等は全て、u16BitPeriodInCarrierPeriodsで指定した個数の副搬送波を単位とする微小ビットの1/0の集まりとして表現します。例えば、下の図に示したNEC方式における'0'データビットは、微小ビットでは'10'という2ビットのデータで表現します。

 赤外線コマンドの送信は、bAHI_InfraredStart()で行います。
bool_t bAHI_InfraredStart(
uint32 *pu32BufferAddress,
uint16 u16TransmissionLengthInBits);
  • pu32BufferAddress 微小ビットの連続で表現したフレーム構造をビッグエンディアンで指定します。
  • u16TransmissionLengthInBits pu32BufferAddressに含まれる有効な微小ビット数を指定します。
pu32BufferAddress の先頭はリーダーコードで始まります。NEC方式では、0xffff0000(の上位24ビット)になります。リーダーコードの後は、データビットの0/1をそれぞれ2進数の'10'および'1000'としてエンコードして、ストップビットの'1'を追加し、最後にフレーム間を'0'で埋めます。

 上の例は、我が家の日立製テレビの電源コマンドで、フォーマットはNEC方式、カスタマーコードは0x50,0xaf, コマンドデータは0x17です(リトルエンディアン)。これを、bAHI_InfraredStart()用にエンコードすると、パラメータは、
pu32BufferAddress = {0xffff00aa, 0x8a28888a, 0x28888a2a, 0xaa288880, 0x00000000, 0x00000000}
u16TransmissionLengthInBits = 192
 となります。
2進数表現にすると、ON/OFFの様子が視覚的にわかります。
 11111111111111110000000010101010
 10001010001010001000100010001010
 00101000100010001000101000101010
 10101010001010001000100010000000
 00000000000000000000000000000000
 00000000000000000000000000000000

 複数のフレームを送信する場合は、
  • pu32BufferAddress に複数のフレームをエンコードして一気に送信する。
  • vAHI_InfraredRegisterCallback()で送信完了ハンドラを指定し、ハンドラの中で次のフレーム送信を行う。
のいずれかの方法になると思います。送信完了ハンドラを使用する場合は、オーバーヘッドを考えてu16TransmissionLengthInBitsを若干減らしたほうが良いかもしれません。

参考資料

TWE-Liteで赤外線リモコン信号を送信

 赤外線リモコン信号の受信だけでなく、送信もできるようになりました。

 送信用のパーツを追加した回路図は、こちらです。
TWE-LiteのGPIOでは赤外線LEDを十分な明るさで点灯させることができないので、余っていたトランジスタを使いました。LEDの電流制限抵抗は、もっと小さくしたほうが良さそうです(50mA位は流したい)。

 赤外線リモコン信号を駆動するTIMER2は、標準アプリでは代替割り当てによってPWM2(or DO0)に割り当てられていますが、NPNトランジスタのベースと一緒にDO0をプルダウンしてしまうとプログラムモードに入れなくなるので、代替割り当てではなくデフォルトのピン割り当てのDO12(標準アプリではDI1)をTIMER2の出力として使っています。
  p-ch FETやPNPトランジスタならば、標準アプリと同様の代替割り当てで問題ありません。その場合は、TIMER2の出力極性を反転する必要があります。

赤外線リモコン信号を送信する手順は、おおまかに以下のようになります。
  1. vAHI_TimerDisable(E_AHI_TIMER_2) でTIMER2を止めておく。
  2. vAHI_InfraredRegisterCallback(cbToCoNet_vHwEvent) で送信完了ハンドラを指定する。
  3. bAHI_InfraredEnable(0, 281, 421, 21, FALSE, TRUE) で副搬送波とエンコード単位波数を指定する。
  4. 送信したい赤外線コマンドのパターンをuint32のバッファにビッグエンディアンで設定する。
  5. bAHI_InfraredStart(pu32BufferAddress,u16TransmissionLengthInBits) で赤外線コマンドを送信する。
  6. 送信完了割り込みが発生したら、次のフレームを送信するために4.または3.の手順に戻る。
上記のbAHI_InfraredEnable()で指定しているパラメータは、NEC方式または家電協方式の場合です。SONY方式では、副搬送波が40kHzになるように指定します。

 赤外線コマンドの1ビットは、bAHI_InfraredEnable()で指定したエンコード単位幅(u16BitPeriodInCarrierPeriods)を複数使って表現します。リーダーコードやフレーム間の無信号部分も同様にしてエンコードに含めるので、1個のコマンドに必要なバッファ長は75-235ビット位になります(長さはフォーマットに依存)。

 送信部分を実装したソースコードも、githubで公開しています。