前回10月30日に電池交換した気圧計ですが、今日電池がなくなって止まってました。
今日の昼間は稼働していたので、ほぼ25日間の動作ということになります。単三で作れば2ヶ月くらい駆動できるかな?
自作の電池駆動機器で簡単にこれだけの期間連続動作させられるようになるなんてしばらく前には予想できませんでしたね。
秋月に新しいユニバーサル基板が登場
秋月電子のサイトを見ていたら、新しいユニバーサル基板が出ているのを発見。
従来の2.54mmピッチの端子間に表と裏にそれぞれ異なる向きで電源バスを這わせて、交差点の部分にスルーホールを設けた構造みたい。
単一電源の回路であれば電源・GND配線が格段に簡単になる上に、4層基板には届かなくても電源インピーダンスは確実に下がるはずので、いろいろ作りやすくなりそう。
(かといって、沿面距離は何をしても大幅に小さくなってしまうので、高電圧がかかる回路は絶対に避けないといけないですが)
プルアップやプルダウンの抵抗・パスコンも1005のチップ品を使えば電源グリッドのスルーホールから直接接続できそうな感じ。1608ではちょっと苦しいかな(いけたらうれしいのだけど)
寒冷前線のレーダー画像
DIP版18F14K50ボードを作ってみました
余っていたDIP版のPIC18F14K50とユニバーサル基板でテスト用のボードを作ってみました。
このボードを作ってみたのは、部品が余っていたから・・・というのもありますが、秋月の800円PIC18F14K50ボードとブレッドボードの組み合わせでは不便な点があったからです。それは、
- 秋月の800円PIC18F14K50ボードではRA3はPICkit3へ接続するようになっている。
よって、ブレッドボードではこの端子は扱えない。 - USBでいろいろなソフトウェアを作って試すには、ブレッドボードでは持ち運びには不便。
というところからです。双方向でのデータのやりとりを試してみたいので、余っていた気圧センサとI2Cのキャラクタ液晶も載せてあります。気圧センサは液晶の下に置いてあります。(最初の写真は気圧センサから読み取った値を液晶に表示しています)
裏面はこんな感じです。(自分用です。回路図を作っていないのでその代用(^^;。クリックすると特大画像が開きます。)
各部分の説明(自分用です)
- 基板裏面から見て右上の部分
USBのBコネクタで、緑色の部品は100mAの保護用ポリスイッチです。 - 基板裏面から見て真ん中やや上
PIC18F14K50です。GND周りに付いている2個の小さな1608のコンデンサは1uFのチップコンです。VUSBのコンデンサは0.22~0.47uFが推奨だったと思いますが、半端な容量のコンデンサが手持ちになかったので1uFとしています。茶色の2012の大きなコンデンサ2個はクリスタル周りの22pFで、その左の4.7kΩはRA3のプルアップ抵抗、その左の1.2kΩ×2個はLEDの電流制限抵抗、その左の24kΩはタクトスイッチのプルアップ抵抗です。ポートCは内蔵プルアップがないので外付けせざるを得ませんでした。 - 基板裏面から見て左の部分
アナログジョイスティックと3.3VのCMOSレギュレータです。CMOSレギュレータIN/OUTには1uF16Vのチップコンがそれぞれついています。 - 基板裏面から見て左下の部分
2個のタクトスイッチです - 基板裏面から見て右下の部分
LCDモジュールへのコネクタと気圧センサです。4.7kΩ×2個はI2Cバスのプルアップ抵抗です。
ポートアサインは以下の通りとしています。
- RA3 – ブートローダスイッチ(L:ブートローダ起動)
- RB4 – I2CバスSDA
- RB5 – not use
- RB6 – I2CバスSCL
- RB7 – not use
- RC0 – 3.3Vリファレンス電圧入力
- RC1 – アナログジョイスティックY軸入力
- RC2 – アナログジョイスティックX軸入力
- RC3 – LED GREEN(H:点灯)
- RC4 – LED RED(H:点灯)
- RC5 – not use
- RC6 – スイッチ入力左(L:ON)
- RC7 – スイッチ入力右(L:ON)
I2Cバスのアドレスアサインは以下の通りです。
- 0x3E – AQM0802A液晶モジュール
(WRITE : 0x7C) - 0x5C – LPS331AP大気圧センサ
(WRITE : 0xB8 / READ : 0xB9)
ソフトウェアはとりあえず以下の通りです。
- PIC18F14K50側ブートローダ
タクトスイッチとLEDのポートアサインを修正 - PIC18F14K50側アプリケーション
カスタムHIDデバイスのデモプログラムをベースにして、先に作った気圧センサ用のPIC16F1823用のI2C/LPS331/LCDドライバを移植。
さらにTimer0割り込みを使って時間管理(似非マルチタスク処理)ができるように割り込み処理を追加。 - Linuxホスト側ブートローダ
Microchipのサンプルプログラムのまま - Linuxホスト側アプリケーション
昔作ったHIDRAWでデータをやりとりするプログラムを改造し、双方向で希望するデータのやりとりができることを確認
これでLinux環境下でデータのやりとりをUSB経由で好きなようにできそうです。
マウスエミュレータ(?)を作ってみた
例によって Microchip Solutionsの中のサンプルプログラムの中にマウスのデモがあったので、これをベースにアナログジョイスティックで操作するマウスエミュレータを作ってみました。
写真が完成した状態です。アナログジョイスティックでマウスカーソルを上下左右に移動させることができ、その下のタクトスイッチ2つはマウスの左クリック・右クリックに対応します。中央やや上のタクトスイッチはBootloaderの起動スイッチです。押しながらUSBケーブルを挿すことでHID Bootloaderが起動します。
USBバスは様々な要因で電圧が変動するので、USBの5Vから以前作った3.3Vレギュレータ小基板で3.3Vを生成してADCの基準電圧とアナログジョイスティックの入力電圧としています。ADCの基準電圧をRB4(AN4=Vref+)に加えて、X軸方向の出力をRB5(AN5)に、Y軸方向の出力をRB6(AN7)に加えています。左右クリックの代わりのタクトスイッチはRB6とRB7に接続し、内部プルアップを有効にしています。RB4にはLEDを接続、RB5にはBootloader用のタクトスイッチを接続していますが、RB5は外部プルアップを行っています。
XY軸はアナログジョイスティックモジュールを基板に載せるときの結線とXYの正負の関係が合わなかったため、内部で読み替えています。
ソフトウェアは上記のハードウェアに合わせた変更と、LEDやSWなどで評価ボードに載っているものに関する制御を取っ払っているのみです。参考になるかわかりませんが、ソースコードをアップロードしておきます。ライセンスは修正部分を除いてオリジナルに従ってください。修正箇所はご自由にどうぞ。なお当然無保証です。PIC18F14K50以外では余分なソースコードは取り除いていませんが一方でコンパイルすらしていませんので、そのつもりで。(修正したソースコード:mouse.c)
そうそう、USBのベンダID、デバイスIDも設定しているファイルを含んでいない=当然変わりませんので、これまたそのつもりでお願いします。
コンパイルはMPLAB-X v1.90とMPLAB C18の組み合わせで、もちろんLinux上です。
設計において今回苦労したのは、コンパイルして生成されたHEXファイルが1000H番地以降にロードするようにリンクされていない、というものです。
もちろん、見た目では
という感じで rm18f14k50_g.lkr ファイルがプロジェクトに取り込まれていますし、ソースコード自身にも384行目付近からベクタを再配置するためのマクロ定義がされていて問題なさそうにみえるのですが、生成されるHEXファイルは0番地付近から生成されている・・・というものです。
・・・・で、悩んで悩んで・・・・ふとMPLAB-Xを再起動したところ、Linker Filesからrm18f15k50_g.lkrが抜けているではないですか・・・。改めてプロジェクトに取り込ませたところ、無事に1000H番地付近からのオブジェクトが生成されて、HID Bootloaderでダウンロード、実行することができました。
しかし、(Linux版だけかもしれませんが)MPLAB-Xはまだこの手の「再起動すると治る」という不具合がたくさんあります。何とかならないもんですかね。趣味で使う分にはまだ納期もないのでいいですが、プロフェッショナル用途では致命的だと思うのですが。
PIC18F14K50用にブートローダを準備する
PIC18F4550でブートローダが動いたので、次に本来のターゲットであるPIC18F14K50で動かしてみます。
1.ブートローダの準備
PIC18F4550のプロジェクトを開きます(自分の場合にはディレクトリごとコピーしてから開いてリネームしています)。次にProjectのPropertyを開き、PIC18F14K50の設定をActiveにして、PICkit3から電源供給するように設定変更します。
ブートローダ用のSWとLEDは io_cfg.h の131行目付近からに記述がありますので、
/** LED ************************************************************/ // #define mInitAllLEDs() LATC &= 0xFE; TRISC &= 0xFE; // #define mLED_1 LATCbits.LATC0 // #define mLED_1_On() mLED_1 = 1; // #define mLED_1_Off() mLED_1 = 0; // #define mLED_1_Toggle() mLED_1 = !mLED_1; #define mInitAllLEDs() LATBbits.LATB4 = 0; TRISBbits.RB4 = 0; #define mLED_1 LATBbits.LATB4 #define mLED_1_On() mLED_1 = 1; #define mLED_1_Off() mLED_1 = 0; #define mLED_1_Toggle() mLED_1 = !mLED_1; /** SWITCH *********************************************************/ // #define mInitAllSwitches() mInitSwitch2(); // #define mInitSwitch2() {ADCON1 = 0x0F;} // #define sw2 PORTAbits.RA3 // #define mDeInitSwitch2() {ADCON1 = 0x07;} #define mInitAllSwitches() mInitSwitch2(); #define mInitSwitch2() {TRISBbits.RB5 = 1; ANSELHbits.ANS11=0;} #define sw2 PORTBbits.RB5 #define mDeInitSwitch2() {TRISBbits.RB5 = 1; ANSELHbits.ANS11=1;}
という感じで、修正します。ここではLEDはポートC0、SWがポートA3に接続する前提だったのを、LEDはポートB4、SWはポートB5に接続するように修正しています。そして、main.cの325行目にある ENABLE_FLASH_SIGNATURE_VERIFICATION の定義はコメントアウトして、SIGNATUREのチェックはしないようにします。
これでビルドを行い、PIC18F14K50に書き込みを行うと、無事にブートローダアプリから認識されるようになりました。
2.ブートローダでロードするサンプルの準備
サンプルは例によってCDC Basic Demoを使いました。同様にProjectのPropertyを開き、PIC18F14K50の設定をActiveにします。プロジェクトのディレクトリ内に「microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/Firmware – PIC18 Non-J/Linker files for applications」の下にある「rm18f14k50_g.lkr」をコピーして、Projectsの「Linker files」を右クリックして「Add Existing Item…」を選択してプロジェクトに加えます。他にもリンカファイルは存在しますが、今回加えたファイル以外は薄文字になっていることを確認します。
さらに、このままビルドすると「p18f14k50.libが見つからない」というエラーに遭遇します。これはライブラリとして実在するのは「p18F14K50.lib」なのに対して、探しているのが「p18f14k50.lib」と全て小文字のファイル名のためです。ですので、
$ cd /opt/microchip/mplabc18/v3.40/lib /opt/microchip/mplabc18/v3.40/lib $ sudo ln -s p18F14K50.lib p18f14k50.lib
として、大文字でも探せるようシンボリックリンクを張って誤魔化します。(Windowsでは問題にならず、Linuxでは問題になるケース)
これでビルドすると無事に通るようになりました。
ビルドしたアプリケーションは「microchip_solutions_v2013-06-15/USB/Device – CDC – Basic Demo/Firmware/MPLAB.X/dist/LPC_USB_Development_Kit_PIC18F14K50/production」の下に置かれますので、ここにできたHEXファイルをブートローダアプリケーションで指定して書き込んでやると無事にCDC Basic Demoとして動作しました。
PIC18F用のHIDブートローダの調査
PIC18F14K50は割り切って使うにはなかなか便利なデバイスなのですが、MPLAB-X(Linux版)とPICkit3の組み合わせで毎回書き換えて使うには、書き込む度に
- PIC18F14K50側のUSBケーブルを抜いて、
- PICkit3を接続し、
- ダウンロードをして、
- PICkit3側のUSBケーブルを外してから
- PICkit3を外して、
- PIC18F14K50側のUSBケーブルを挿す
- (次回書き込みに備えて)PICkit3側のUSBケーブルを挿す
というなかなか面倒くさい手順が必要です。理由は、
- ICSPの端子とUSBのD+/D-端子を共有している
- MPLAB-XのPICkit3に対する制御がイマイチ
(MPLAB-Xからターゲットへの電源が供給されっぱなしなので、一旦PICkit3を外して電源供給を止める必要がある)
というためです。
そこで調べていたところ、HIDプロトコルによるブートローダがMicrochipから提供されていることがわかりました。これを使うと、
- ブートローダを書き込んであればPICkit3なしでターゲットプログラムを書き換えることができる
- PowerON時のポートの状態に応じてブートローダを起動させたり、ターゲットプログラムを起動させたりするのを切り替えることができる
- ターゲットプログラムのダウンロード用のLinux用のホストプログラムはブートローダに同梱されている(Qtベースっぽい)
- ブートローダは0番地付近の約4KBを占有する模様。割り込みベクタは4KB上のアドレス(1000H~)に移動させる細工がされている。
- アプリケーションプログラムも当然1000Hあたりからに置かれるように細工しなければならない
ということがわかりました。
どこから手をつけるか考えていたところ、CDCクラスのBasic Demoのlkrファイルが「rm18f4550 – HID Bootload.lkr」となっていていかにも対応していそうなファイル名です。中身も、
LIBPATH . FILES c018i.o FILES clib.lib FILES p18F4550.lib CODEPAGE NAME=bootloader START=0x0 END=0xFFF PROTECTED CODEPAGE NAME=vectors START=0x1000 END=0x1029 PROTECTED CODEPAGE NAME=page START=0x102A END=0x7FFF CODEPAGE NAME=idlocs START=0x200000 END=0x200007 PROTECTED CODEPAGE NAME=config START=0x300000 END=0x30000D PROTECTED CODEPAGE NAME=devid START=0x3FFFFE END=0x3FFFFF PROTECTED CODEPAGE NAME=eedata START=0xF00000 END=0xF000FF PROTECTED
102A番地から7FFF番地までに配置されそうな感じです。
そこで、手始めにPIC18F4550(AE-18F4550ボード)でブートローダを動かしてみることにしました。
途中までは順風満帆かと思われたのですが・・・・
ブートローダのプロジェクトは microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/Firmware – PIC18 Non-J/MPLAB.X に収められています。これを開いて、ProjectのPropertyを開いてPIC18F4550の設定をActiveにすることと、PICkit3から電源供給するように設定変更します。
ブートローダ用のSWとLEDは io_cfg.h を見ると68行目付近から記述があり、LEDはPORT D0、SWはPORT B4に接続する前提になっていることがわかります。そこで、ブレッドボード上で適当にLEDとSW(プルアップ抵抗をつけておきます)を配線します。
ビルド自体はこれで難なく通り、書き込みもできました。(コンパイラは例によってMPLABC18です)
18F4550のPORT B4をGNDに落とした状態でUSBポートをホストPCと接続するとLEDがチカチカ点滅します。そして、「microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/Firmware – PIC18 Non-J/HIDBootloader(Linux)」を起動すると「Device Attatched」という表示が出て、無事に認識されました。
次にアプリケーションですが、先に調査した通り、CDC Basic Demoで試してみます。
microchip_solutions_v2013-06-15/USB/Device – CDC – Basic Demo/Firmware/MPLAB.X に格納されたプロジェクトを開いて、ProjectのPropertyを開いてPIC18F4550の設定をActiveにしてビルドします。
ビルドして出来上がったHEXファイルはmicrochip_solutions_v2013-06-15/USB/Device – CDC – Basic Demo/Firmware/MPLAB.X/dist/PICDEM_FSUSB/productionの下に格納されています。これをHIDBootloader(Linux)で File → Import Firmaware Image で読み込ませた後、Program → Erase/Program/Verify Device で書き込みます。書き込み後、PORT B4をHレベルになるようにした後、Program → Reset Device でリセットを掛けます。・・・が、再びBootloaderに認識されてしまいました。
うーん、HID Bootloader上のアプリケーション・・・動きません。
ここからが苦難の道のり・・・(涙)
ブートローダのファームウェア側main.cを見ると、421行目近辺に
DoFlashSignatureCheck: //Check if the application region flash signature is valid #ifdef ENABLE_FLASH_SIGNATURE_VERIFICATION if(*(rom unsigned int*)APP_SIGNATURE_ADDRESS == APP_SIGNATURE_VALUE) { //The flash signature was valid, implying the previous //erase/program/verify operation was a success. //Go ahead and jump out of bootloader mode into the application run mode _asm goto REMAPPED_APPLICATION_RESET_VECTOR _endasm } //else the application image is missing or corrupt. In this case, we //need to stay in the bootloader mode, so the user has the ability to //try (again) to re-program a valid application image into the device. //We should stay in bootloader mode _asm goto BootMain _endasm #else //Ideally we shouldn't get here. It is not recommended for the user to //disable both the I/O pin check and flash signature checking //simultaneously. Doing so would make the application non-recoverable //in the event of a failed bootload attempt (ex: due to power loss). _asm goto REMAPPED_APPLICATION_RESET_VECTOR _endasm #endif
というコードがあって、APP_SIGNATURE_ADDRESS番地にAPP_SIGNATURE_VALUEが書かれていないと、BootMain(ブートローダのMain)に飛んでいくことがわかります。具体的には、0x1006番地が0x600Dでなければなりません。
そこで、MPLAB IPEでROMの内容を吸い出して確認してみたところ、見事に0xFFFFになっていました・・・。ここをMPLAB IPEで0x600Dに変更して書き戻してみたところ、ブートローダプログラムでは「Detached」になり、さらにGtkTermで /dev/ttyACM0 にアクセスしてCDC Basic Demo(入力した文字が1文字ずれてエコーバックされる)の機能を確認することができました。
つまり、SIGNATURE VALUEが書かれていないことが原因であることがわかりました。
では、SIGNATURE VALUEは誰が書くのか?
ソースコードの「BootPIC18NonJ.c」の359行目からのProcessIO()を見ると、532行目付近に
case SIGN_FLASH: SignFlash(); BootState = IDLE; break;
というコードがあって、これはホスト(PC)からのコマンド解析部分のようです。ホストから「SIGN_FLASH」というコマンド(ちなみに値は0x09)が来ると、591行目付近のSignFlash()という関数が呼び出されて、該当領域を読み込んだ後、バッファ内のSIGNATUREの部分を書き換えて、書き込む処理を行うように見えます。
つまり、そもそもこの「SIGN_FLASH」というコマンドが来ていないのではないか、ということになります。
SIGN_FLASHが送られてくるコードになっているのか?
こんどはホスト側のソースコードが格納されている「microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/software_cross_platform/Bootloader」の下を見てみました。
「SIGN_FLASH」を送出するっぽいコードは、Comm.cppの640行目付近にある、「Comm::SignFlash(void)」という関数のようです。送られていれば、それなりのデバッグメッセージを出すコードのようなのですが、残念ながらビルドできる環境がありません。(方法もわかりません)
この部分を呼び出すのはMainWindow.cppの555行目付近のようです。
if(failureDetected == false) { //Successfully verified all regions without error. //If this is a v1.01 or later device, we now need to issue the SIGN_FLASH //command, and then re-verify the first erase page worth of flash memory //(but with the exclusion of the signature WORD address from the verify, //since the bootloader firmware will have changed it to the new/magic //value (probably 0x600D, or "good" in leet speak). if(deviceFirmwareIsAtLeast101 == true) { comm->SignFlash(); //Now re-verify the first erase page of flash memory. if(device->family == Device::PIC18) {
書き込み後にVerifyをする関数の最後の方で、Verifyに問題がなく、なおかつdeviceFirmwareIsAtLeast101がセットされていれば、呼び出されるようです。で、この値はブートローダファームウェアのバージョンが1.01以上であればセットされるようです。
実際にセットしている箇所は、MainWindow.cppの1150行目付近、GetQuery()という関数・・・GetQueryコマンドに対する応答パケットを解析する部分の中で、
for(int i = 0; i < MAX_DATA_REGIONS; i++) { if(bootInfo.memoryRegions[i].type == END_OF_TYPES_LIST) { //Before we quit, check the special versionFlag byte, //to see if the bootloader firmware is at least version 1.01. //If it is, then it will support the extended query command. //If the device is based on v1.00 bootloader firmware, it will have //loaded the versionFlag location with 0x00, which was a pad byte. if(bootInfo.versionFlag == BOOTLOADER_V1_01_OR_NEWER_FLAG) { deviceFirmwareIsAtLeast101 = true; qDebug("Device bootloader firmware is v1.01 or newer and supports Extended Query."); //Now fetch the extended query information packet from the USB firmware. comm->ReadExtendedQueryInfo(&extendedBootInfo); qDebug("Device bootloader firmware version is: " + extendedBootInfo.PIC18.bootloaderVersion); } else { deviceFirmwareIsAtLeast101 = false; } break; }
bootInfo構造体のversionFlagがBOOTLOADER_V1_01_OR_NEWER_FLAG(これはDeviceData.hの中で0xA5として定義されています)となっているかで判別しているようです。そしてこの構造体は、Comm.hというヘッダファイルで、
#pragma pack(1) struct MemoryRegion { unsigned char type; unsigned long int address; unsigned long int size; }; struct BootInfo { unsigned char command; unsigned char bytesPerPacket; unsigned char deviceFamily; MemoryRegion memoryRegions[MAX_DATA_REGIONS]; unsigned char versionFlag; unsigned char pad[7]; };
として宣言されています。BootInfoは受信したパケットそのもののようなので、WiresharkでUSBのパケットキャプチャをしてみました。
0040Hからが受信したデータの部分で、構造体の構造にそって読んでいくと、赤丸の部分がversionFlagで0xa5になっていることがわかります。つまり、ブートローダのファームウェア側からは正しく情報が上がっているようです。
SIGN_FLASHは送出されているのか?
書き込みの処理の部分全体をUSBパケットキャプチャしてみたところ、最後のパケットは、
となっていて、最後のコマンドは0x07で「GET_DATA」でした。遡っていってもずーっと0x07で、その前が0x06(PROGRAM_COMPLETE)が2つ、その前が0x05(PROGRAM_DEVICE)がずっと続きます。先頭から書いていくと、
- 0x04(ERASE_DEVICE)
- 0x02(QUERY_DEVICE)
これに対する応答もきちんとVer1.01以上である0xa5が含まれていました。 - 0x05(PROGRAM_DEVICE)がたくさん
- 0x06(PROGRAM_COMPLETE)が2つ
- 0x07(GET_DEVICE)はたくさん
という感じで、0x09(SIGN_FLASH)は含まれていません。・・・・そりゃあ、ダウンロードしたプログラムが動くわけがありません。
で、ここで気づいたことが・・・・
よくみると、ブートローダアプリケーションに表示される文字列は、ブートローダアプリのソースコードではコメントアウトされているものになっています。つまり、ソースコードはついているけど、それをコンパイルしたアプリケーションがついているわけではないようです。・・・・おいおい。
ちなみに、タイムスタンプをみると、ソースコードのタイムスタンプは2013年6月18日2時37分18秒で、添付されているアプリケーションのタイムスタンプは2013年6月18日2時36分36秒です。・・・・この微妙な逆転、一体何なんでしょうね・・・・。
最終的な対策
Qt5をコンパイルする環境はないので、 処置するとしたらブートローダのファームウェア側で処置するしかありません。
簡単に対策するなら、SIGNATUREのチェックを外す、ということになります。
main.c の317行め付近に、
//Never comment this out. If you do, you won't be able to recover if the user //unplugs the USB cable (or power is lost) during an erase/program sequence, //unless you rely on the I/O pin check entry method. The only reason ever to //comment this out, is if you are trying to use this bootloader firmware with //an old bootloader PC application that does not have knowledge of the v1.01 //and newer command set (with QUERY_EXTENDED_INFO and SIGN_FLASH commands). //However, a better solution in such a case, is to upgrade to use a newer PC //application to do the bootloading. #define ENABLE_FLASH_SIGNATURE_VERIFICATION
というコードがあって、コメントには、「ここはコメントするな!」と書いてありますが、そんなことを言っても仕方ありませんので、ここをコメントアウトしてSIGNATUREチェックをやめさせます。コメントの内容によると、書き換え中に電源を切ったりUSBケーブルを抜いたりすると、復活できなくなる・・・・ということみたいです。
ここをコメントしてビルドしたブートローダを書き込んで、PORT B4をGNDに落としてブートローダを起動、ブートローダアプリケーションでCDC Basic Demoを書き込んでみました。その後、PORT B4をHにしてブートローダアプリの「Reset Device」をクリックしたところ、無事にCDC Basic Demoが動作しました。
疲れてしまったので、PIC18F14K50でのトライはまた今度ということで。
おまけ
HIDブートローダを使う場合の各PICでのリンカスクリプトは「microchip_solutions_v2013-06-15/USB/Device – Bootloaders/HID/Firmware – PIC18 Non-J/Linker files for applications」にあるようです。
RasPiに緊急地震速報を報告させてみました
連続稼働に向けてラックに吊り下げたRaspberryPiですが、こいつに緊急地震速報を報告させてみました。
Pythonのスクリプトとして作ったのですが、処理としては以下のような感じです。表示および音声合成は別スクリプト&別スレッドにすることで、表示処理と音声読上げを同時に起動し、遅れをなるべく少なくするようにしています。
1.RaspberryPiでEEWBOTを監視し、地震速報を取得する
Twitterのアカウントでeewbotというbotアカウントを運営している方がいて、実験的に高度利用者向けの緊急地震速報をcsvで配信されています。
こちらのtweetをストリーミングAPIで受けとります。
2.受信した内容をデコードします。
デコードと言っても、都合のいいように表示用と読上げ用のテキストを生成するだけです。
3.USB接続のLCDに表示させます
生成したテキストをUSB接続のLCDに表示させます。
4.スピーカに音声出力します
RaspberryPiに接続したスピーカに合成音声で出力します。音声合成にはAquesTalk Piを使っています。いわゆる「ゆっくり声」で読み上げます。(笑)
(注:AquestTalk Piは商用利用では有償なので、真似する人はご注意を)
いまのところ、RaspberryPiのスピーカ端子にダイソーの100円スピーカ(ケーブルなし)を挿しているので、音量が小さくて静かな状況でないと聞き取れません。なるべくシンプルかつ小さくアンプを仕込む方法を考えています。
5.動かしてみて
遠めの地震だと地震速報の読上げ&表示後に揺れがきます。比較的近くだと揺れが先か同時くらいですが。音声だけだと読み取れなくても同じ内容がLCDをみれば表示されているので、読上げ完了を待たなくても内容がわかりますし、聞き取れなくてもやはり内容はわかりますので、結構便利です。
ちなみに、日本気象協会の地震情報(tenkijp_jishin)もフォローしていて、その内容もそのまま表示&読上げをしています。こちらは緊急地震速報が落ち着いてしばらくしてからTweetされます。
6.メモ
以降は自分用のメモです。
動かすの使った追加パッケージは以下のとおり。
$ sudo apt-get install python-gd
$ sudo apt-get install ttf-kochi-gothic-naga10 ttf-kochi-mincho-naga10
$ sudo pip install pyserial
「TweetToVoiceLCD.py」を走らせれば動作開始。
気圧計の電池がなくなりました
先に作った気圧計ですが、連続稼働していたら電池がなくなってました。稼働し始めて約9~10日というところですが、もともと何かの電池として使っていたものを持ってきたので、寿命としては怪しいです。
なので、改めて新しい電池(といっても、ダイソーアルカリ乾電池ですが・・・)を入れてみました。
さて、どのくらいの寿命となるでしょうか。
Raspbianにavahi-daemonをインストール
これまでネットワーク上のRaspberryPiにSSHでリモートログインする場合には、事前にIPアドレスを固定で割り振っておいて、
$ ssh pi@192.168.1.41
とかしていました。しかし、これは結構面倒くさいし、スマートじゃない。RasPiの場合はSDカード側にホスト情報が保持されているので、RasPiが複数台あるとIPアドレスがぶつかりそうになります。
で、簡単に済ます方法が avahi です。調べると、BonjourのOSS版っぽいことが書いてあったり、Zeroconfだぁとか書いてあったりしますが、要は固定IPじゃなくても極めて簡単に名前ベースでsshとかrdpとかが使えるようになります。
インストールは、
$ sudo apt-get install avahi-daemon
です。
RaspberryPi側のホスト名(/etc/hostname)が「raspberrypi」だとすると、インストール後には「raspberrypi.local」で名前解決できるようになります。そうすると、
$ ssh pi@raspberrypi.local
でSSHログインできたり、
$ sshfs pi@raspberrypi.local:/ /mountpoint
でsshfsでマウントできたり、
$ rdesktop -u pi raspberrypi.local
でリモートデスクトップ接続ができます。また、
$ avahi-brouse -ar
でローカルネットワーク上の対応しているサービスの一覧を表示させることができます。
SDカードにホスト名を書いておけば、DHCP環境ではIPアドレスがぶつかる心配をすることなく複数のRaspberryPiを動作させることができます。
※別にRasPiでなくてもBeagleBoneでも同じ手順で対応できます。