2016年10月21日金曜日

Raspberry PiのGPIOを用いてPICマイコンに書き込みをしてみた

はじめに

Raspberry Pi上のScratchでアナログ入力を利用してみた」というエントリにて、PICマイコンを用いると、Raspberry Pi上のScratchにて簡単かつ安価にアナログセンサを取り扱えることを紹介しました。

ただし、PICマイコンには自作プログラムを書き込まなければならず、その書き込み用のツールPICkit3が6千円程度することがややネックでした。

しかし今回、PICkit3を必要とせず、Raspberry PiのGPIOからPICのプログラムを書き込む方法が分かったので紹介します。Raspberry Piをお使いの方ならば、数百円でPICマイコンにプログラムを書き込むことができるようになります。

この方法により、Raspberry Pi上のScratchでアナログセンサを取り扱うことがさらに身近になります。もちろん、それ以外の用途への応用も可能です。

用意するもの

今回、PICマイコンへプログラムを書き込むために用意するものは下記の通りです。
  • 3.3Vで動作するPICマイコン。本ページではAD変換とシリアル通信を取り扱うことのできるPIC12F1822PIC16F1823を用いました。5V以上でしか動作しないPICマイコンでも原理的に書き込み可能だと思いますが、3.3V←→5Vのレベル変換がさらに必要になるので、回路がやや複雑になるでしょう。
  • 9Vの角形電池1つ
  • 9Vの角形電池用スナップ1つ
  • MOSFET 2N7000を1つ:3.3V←→9Vのレベル変換に用います
  • 10kΩの抵抗2つ
  • ブレッドボード、ジャンパワイヤ:適宜


ソフトウェアの準備

まず、Raspberry Piにpickleというソフトウェアをインストールする必要があります。

pickleのページの「Installation」という項目に pickle-4.0d.tar.gz と書かれたリンクがあるのでクリックし、ファイルをダウンロードします。

Raspberry Piのブラウザでは、通常「Downloads」または「ダウンロード」ディレクトリに保存されますので、ファイルマネージャでそれをユーザーpiのホームに移動しておきます。

そして、ターミナルソフトウェアLXTerminalを起動し、下記のコマンド順にを実行し、pickleをインストールします。
$ tar zxf pickle-4.0d.tar.gz
$ cd pickle
$ make
$ sudo make install
以上で必要なソフトウェアのインストールが終わりました。そのターミナルを終了せず、そのまま下記のコマンドを実行します。pickleを用いるための設定ファイルを適切な位置にコピーしています。
$ mkdir /home/pi/.pickle
$ cp src/dotconf/gpio-RPI /home/pi/.pickle/config
次に、コピーした設定ファイルを変更します。ターミナルで下記のコマンドを実行し、設定ファイルをテキストエディタleafpadで開きます。
$ leafpad /home/pi/.pickle/config
開いたファイルの中で、下記の部分を見つけます。これはRaspberry Pi Model B+を用いる設定になっています。
DEVICE=RPI
#DEVICE=RPI2
そのため、Raspberry Pi 2やRaspberry Pi 3を用いている場合、上記の部分を下記のように編集します。

「DEVICE=RPI」の先頭に「#」を記して無効化し、「DEVICE=RPI2」の前の「#」を削除して有効化しているわけです。 Raspberry Pi 3を用いている場合でも「RPI2」のままで構いませんのでご注意ください。
#DEVICE=RPI
DEVICE=RPI2
次に、同じくleafpad上で下記の部分を見つけます。
# RPi OR GPIO BIT-BANG (single PGD DATA I/O)
#                  = CHIPKIT PI =
# !MCLR/VPP        - RPi-Connect 18
VPP=9
# PGM              - RPi-Connect 12
PGM=22
# PGC CLOCK        - RPi-Connect 16
PGC=10
# PGD DATA_I/O     - RPi-Connect 20
PGD=11
これはデフォルトの書き込み設定になっているのですが、今回には該当しないので、「#」のついていない4行に「#」を記して無効化します。すなわち、下記のようになります。
# RPi OR GPIO BIT-BANG (single PGD DATA I/O)
#                  = CHIPKIT PI =
# !MCLR/VPP        - RPi-Connect 18
#VPP=9
# PGM              - RPi-Connect 12
#PGM=22
# PGC CLOCK        - RPi-Connect 16
#PGC=10
# PGD DATA_I/O     - RPi-Connect 20
#PGD=11
次に、そのすぐ下にある以下の行を見つけます。
# RPi OR GPIO BIT-BANG (single PGD DATA I/O)
#                  = CHIPKIT PI PIC32 ICSP =
# !MCLR/VPP        - /RESET
#VPP=4
# PGM              - N/A
#PGM=65535
# PGC CLOCK        - PGC1 RX2
#PGC=14
# PGD DATA_I/O     - PGD1 TX2
#PGD=15
これを以下のように編集します。
# RPi OR GPIO BIT-BANG (single PGD DATA I/O)
#                  = CHIPKIT PI PIC32 ICSP =
# !MCLR/VPP        - /RESET
VPP=4
# PGM              - N/A
PGM=65535
# PGC CLOCK        - PGC1 RX2
PGC=17
# PGD DATA_I/O     - PGD1 TX2
PGD=27
変更のポイントは以下の2つです。
  • 「VPP」、「PGM」、「PGC」、「PGD」のピン番号を記した4行の「#」を削除して有効化すること
  • 「PGC」を「17」に、「PGD」を「27」に変更(もともとのGPIO14とGPIO15はRaspberry Pi上でシリアル通信用に既に使われており、それと干渉しないように)
以上の変更を行ったら、上書き保存してleafpadを閉じてください。以上でpickleを用いる準備は完了です。

なお、編集後の/home/pi/.pickle/configからコメントを表す「#」を含む行を削除した状態は下記のようになっていますので、こちらを丸ごとコピーして保存しても良いです。ただし、「DEVICE」が「RPI2」となっていますのでRaspberry Pi 2およびRaspberry Pi 3用の設定ファイルであることには注意してください。
DEVICE=RPI2
SLEEP=1
BITRULES=0x1000
BUSY=0
VPP=4
PGM=65535
PGC=17
PGD=27
MCP=0x20
FWSLEEP=30
DEBUG=1

回路の準備

次に、PICマイコンに書き込みを行うための回路を準備します。そのために、利用するPICマイコンのピン配置をあらかじめ調べておく必要があります。

PICマイコンへプログラムを書き込むにはいくつかの方法がありますが、今回用いるのは「High voltage programming」という手法です。一般に、マイコンにプログラムを書き込むことを「プログラミング(programming)」と呼ぶことにも注意しておきましょう。

この手法には「VDD」、「VSS(GND)」、「ISCPDAT」、「ISCPCLK」、「~MCLR」という5つのピンを用いますので、そのピンの位置を事前に調べておきます。

今回用いるPIC12F1822およびPIC16F1823の仕様書は英語版日本語版がありますが、それらによると、該当するピンは下記のように配置されていることがわかります。


High voltage programmingでは、~MCLRピンにPICマイコンの動作電圧より高い電圧(ここでは9V)の信号を与える必要があります。

Raspberry PiのGPIOから出力される信号は3.3Vなので、これを9Vに変換する必要があります。そのために、本ページではNチャネルMOSFETを用いた下記のようなレベル変換回路を利用します。

これは、「ロジックレベル双方向変換モジュールBOB-12009」で用いられている回路と同等なものです。


以上をまとめると、PIC12F1822を用いるときに構成すべき回路は下図のようになります。

この回路を構成する場合、9V電池の取り扱いには十分注意してください。9Vの部分をRaspberry Piに接触させると、Raspberry Piが壊れる可能性があります。同様に、回路の接続が正しいことのチェックも重要です。


ほぼ同じですが、PIC16F1823の場合は下図のようになります。


書き込み

最後に、書き込みを行いましょう。

書き込むプログラムをビルドしてできるHEXファイルを用意する必要がありますが、ここでは冒頭で紹介した「Raspberry Pi上のScratchでアナログ入力を利用してみた」というエントリで用いるファイルを書き込んでみます。

HEXファイルはPIC12F1822用とPIC16F1823用の2つしか用意しておりませんのでご注意ください。

まず、LXTerminalを新たに開き、下記のコマンドでファイルをダウンロードし、そのディレクトリに移動します。
$ git clone https://github.com/neuralassembly/TinyPicoBoard
$ cd TinyPicoBoard
pickleというソフトウェアをインストールした際、p12、p14、p16、p24、p32、などといったコマンドがインストールされ、用いるPICマイコンの種類によって使い分けるのですが、本ページではp14コマンドを用います。 まず、Raspberry Piに接続されているPICマイコンの情報を取得するには、下記のコマンドを実行します。
$ p14 id
その結果、下図のように、PICマイコンの情報が表示されます。PIC12F1822が認識されていることが見て取れますね。


TinyPicoBoardディレクトリにある「12f1822.hex」というファイルをPIC12F1822に書き込むには、下記のコマンドを実行します。上図にその様子が示されていますね。
$ p14 program 12f1822.hex
同様に、「16f1823.hex」というファイルをPIC16F1823に書き込むには、下記のコマンドを実行します。
$ p14 program 16f1823.hex
なお、PICに書き込まれているプログラムを消すためのコマンドとしては下記が使えます。消すことの確認を英語で求められたら、「y」をタイプしてEnterします。
$ p14 blank
書き込みが終わったPICは、「Raspberry Pi上のScratchでアナログ入力を利用してみた」に基づいて使用することができます。

終わりに

以上です。~MCLRピンに接続する信号を9Vにレベル変換する必要があることに気づくまで時間がかかってしまいました。

なお、本ページでは3.3Vで動作するPIC12F1822やPIC16F1823を対象としました。4V以上でないと動作しないPICマイコンの場合、恐らく下記のようにする必要があるでしょう(試していません)。
  • VPPピン:Raspberry PiのGPIOから5Vを与える
  • ISCPDAT、ISCPCLKピン:Raspberry Piの17ピン、27ピンと接続する際、3.3V←→5Vのレベル変換回路を介する必要がある


「カラー図解 最新 Raspberry Piで学ぶ電子工作」、「実例で学ぶRaspberry Pi電子工作」を執筆しました。

2016年6月27日月曜日

Raspberry Pi上のScratchでアナログ入力を利用してみた

-1. はじめにのはじめに

本ページの内容は、NOOBS 1.9.2およびNOOBS 2.1.0で動作確認しています。その間のリリース、すなわちNOOBS 1.9.3およびNOOBS 2.0.0ではScratchのバグにより動作しませんのでご注意ください。

NOOBS 2.1.0以降のご利用をお勧めしますが、NOOBS1.9.3およびNOOBS 2.0.0で本ページの内容を試したい場合、ターミナルソフトウェアLXTerminalを起動し、下記の2つのコマンドを順に実行することでScratchが最新になり、本ページの内容が動作するようになります。入力ミスを避ける意味で、コマンドをそれぞれコピーして実行することを推奨します(先頭の「$」はコピーする必要がありません)。
$ wget https://raw.githubusercontent.com/raspberrypi/scratch/master/NuScratch20161021.tgz
$ sudo tar zxf NuScratch20161021.tgz  -C /


0. はじめに

中学生を対象とした電子工作関連のセミナーを担当するにあたり、Scratchによる電子工作で何ができるかを調査しました。

前回のエントリ「Raspberry Pi上のScratchでDCモーターを制御してみた」でRaspberry Pi上のScratchを試してみたところ、と、デフォルトで
  • デジタル(0/1)の入出力
  • ソフトウェアPWM出力
が取り扱えることがわかりました。

ここまでできるのならアナログ入力も取り扱えるようにしよう、というのが今回のエントリです。

結論から言うと、PicoBoardというボードの通信仕様をそのまま用いることで、アナログ入力を利用できることがわかりました。

下図は、前回取り扱ったDCモーター搭載のキャタピラ式模型の前面に距離センサを取り付け、障害物までの距離を一定に保つというデモの様子です。


その様子を示した動画がこちらです。


1. 方針

まずは方針について解説します。

PicoBoardというボードを用いると、Raspberry Piに限らず、WindowsやOS X上のScratchでセンサ入力を取り扱えるようになります。しかし、セミナなどで使うために複数購入するには、価格がやや高いのが難点です。

PicoBoardはシリアル通信でScratchにデータを送るのですが、その仕様は公開されています。これを自分で実装すれば良さそうです。

一番簡単なのは、「Scratching with Arduino」に基づいて、Arduinoで「AD変換+シリアル通信」の機能を実現することでしょう。しかし、この方法もやはり一つあたり数千円かかるので、低価格で複数用意したい、という今回の目的を満たしません。

なお、本ページではArduinoによる実現については解説しませんが、Arduino UnoではRaspberry Pi上のScratchから認識されないので注意が必要です(/dev/ttyACM0 が使われるため)。「FTDI USBシリアル変換アダプター(5V/3.3V切り替え機能付き)」などのように、/dev/ttyUSB0 が使われるデバイスを介する必要があります。

さて、「AD変換+シリアル通信」をなるべく低価格で実現するため、本ページでは「PIC12F1822」または「PIC16F1823」用いることにしました。

PIC12F1822では3個の入力、PIC16F1823では8個の入力を取り扱うことができます。学習目的ならば入力3個のPIC12F1822で十分かな、と個人的には思います。PIC12F1822の方がピン数が少なくて中学生には取り扱いが容易、というのも理由の一つです

なお、シリアル通信はUSB経由ではなく、Raspberry Piのピン番号8, 10のGPIOを用います。

2. Raspberry Piでシリアルコンソールを無効に

さて、上述のようにRaspberry Piのピン番号8, 10のGPIOをPICとのシリアル通信で用いるため、Raspberry Piでシリアルコンソールを無効にする必要があります。

まず、/boot/cmdline.txtを管理者権限のテキストエディタで編集します。
sudo leafpad /boot/cmdline.txt
その中に下記のように「console=serial0,115200」という部分があるので…
dwc_otg.lpm_enable=0 console=tty1 console=serial0,115200 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
これを以下のように削除して保存し、テキストエディタを閉じます。
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p7 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait
さらに、ターミナルを起動し、下記のコマンドを実行してシリアルコンソールを無効にします。
sudo systemctl disable serial-getty@ttyAMA0.service
以上が終わったらRaspberry Piを再起動します。

なお、Raspberry Pi 3ではさらにオンボードのBluetooth機能を無効にしする必要があります。 まず、ターミナルLXTerminalを起動し、下記のコマンドを実行します。
sudo leafpad /boot/config.txt
このコマンドにより、設定ファイル/boot/config.txtが管理者権限のテキストエディタleafpadで開きますので、末尾に下記の1行を追記して保存し、Raspberry Piを再起動します。
dtoverlay=pi3-disable-bt
もし、オンボードのBluetooth機能とシリアル機能を両方使いたい場合、こちらなどを参考にしてください。

3. PICにプログラムを書き込む

Raspberry Piに対してシリアル通信でデータを送るために、PICマイコンにこちらで用意したプログラムをあらかじめ書き込んでおく必要があります。

以前はこれをWindowsやMac OS X上でPICkit3というツールを用いて実現する方法を記していましたが、PICkit3を必要とせずRaspberry Piのみで実現する方法がわかりました。

その方法を別ページの「Raspberry PiのGPIOを用いてPICマイコンに書き込みをしてみた」に記しましたので、そちらを参照して準備を整えてから先に進んでください。

4. 回路を組んで動作させる

プログラムを書き込んだPICの用意ができたら、回路を組んで動作させるだけです。

今回PIC12F1822用に組んだ回路はこちら。前回同様、DCモーター一つを動かすプログラムになっています。



PIC12F1822の「A, B, C」と書かれた3つのピンがアナログセンサを接続できる箇所となっています。

モーター用電源以外は3.3Vで動作する回路としましたので、アナログセンサも3.3Vで動作するものを選択する必要があります。今回は「シャープ測距モジュールGP2Y0E02A」を選んでみました。

なお、ほぼ同じですが、PIC16F1823を用いた回路は下記の様になります。


こちらは、「A, B, C, D, スライダ, 明るさ, 音」と記されたピンにアナログセンサを取り付けられます。「ボタン」と記されたピンにはタクトスイッチからの入力を取り付けることができます。なお、「明るさ」は大小の向きが他と異なること、「音」は大小の変化の仕方が他と異なることに注意してください。これはもともとのPicoBoardの仕様だと思います。

さて、回路が組めたら、Scratchを起動します。

今回組んだプログラムはこちらです。PICから送られるセンサ値は0~100の整数値となっていますので、その値が55~65の場合と30~55の場合とで、モーターの向きを逆にしています。それ以外の値が入力された場合はモーターを止めています。


なお、このプログラムを動作させるためには、あらかじめScratchでセンサを読み取れるようにしておかねばなりません。

下図のように、センサの値を読み取るブロックで右クリックし、「ScratchBoard監視板を表示」を選択します。


すると、下図のようにスプライト表示部に「ScratchBoard監視板」が表示されます。


この「切」の部分で右クリックし、「シリアルかUSBのポートを選択」を選択します。


そこで、ピン番号8と10のGPIOに対応する/dev/ttyAMA0を選択します。


すると、下図のようにセンサからの入力が表示されるようになります。PIC12F1822の場合、値が有効なのは「A、B、C」の三つのみです。


この状態でキャタピラ式模型を動作させたのが冒頭の動画だったというわけです。

5. 終わりに

というわけで、Raspberry Pi上のScratchで下記の入出力が取り扱えることがわかりました。
  • デジタル(0/1)の入出力
  • ソフトウェアPWM出力
  • アナログ入力(0~100の整数値が読まれる)
ここまでできると、LEGOロボットのマインドストームのような教材として十分に使えそうですね。

実際にこの教材を用いて中学校で行なった講義の資料がこちらです。



こちらもどうぞ


「カラー図解 最新 Raspberry Piで学ぶ電子工作」、「実例で学ぶRaspberry Pi電子工作」を執筆しました。

2016年6月17日金曜日

Raspberry Pi上のScratchでDCモーターを制御してみた

0. はじめに

前回のエントリ「NOOBS 1.9.2でインストールしたRaspbian (jessie) 上のScratchで日本語入力を可能にしてみた」にて、Raspberry Pi上のScratchを使えるようになりましたので、本来の目的に戻り、ScratchでGPIOにアクセスしてみました。

目標は、DCモーターを一つ搭載したタンク型模型をScratchから操作することです。タンク型模型は下図のようにタミヤの楽しい工作シリーズで作成しました。


このタンク型模型をスプライトの動きに合わせて左右にコントロールしている様子を示した動画がこちらです。


1. 回路とプログラム

まず、作成した回路はこちら。モータードライバTA7291Pを用いています。GPIO 25と24からソフトウェアPWM信号を出力する回路としています。



そして、この回路に対して作成したプログラムは下図のようになります。

スプライトの動き(「向き」)が反転するたびに、「向き」は-90と90との間を切り替わります。それに応じてモータードライバへの出力を切り替えるプログラムとなっています。

プログラム動作中にスペースキーが押されると、モーターを止め、アプリケーションを終了しています。


2. ソフトウェアPWMについて

プログラム作成には、「Raspberry Piではじめる どきどきプログラミング」および公式のドキュメント「SCRATCH GPIO」を参考にしました。

公式のドキュメントでは、PWMの指定法について「gpio + pin number + pwm + [ 0..1024 ] 」と書いてあったので、0~1024でデューティ比を指定するのかと最初は思いました。

しかし、試してみるとどうも「0~256」程度の範囲がデューティ比0%~100%に対応しているようでした。上記のプログラムでは、デューティ比50%に相当する値128を用いています。

さらに、そのソフトウェアPWM信号の周波数ですが、オシロスコープで波形を見たところ、800Hzでした。100Hz程度だろう、と思っていたので、思いのほか高い周波数で驚きました。

また、下図では値128に対応するデューティ比が確かに50%程度になっていることも観察できます。


3. 終わりに

そのようなわけで、ScratchでGPIOにアクセスしてDCモーターを制御することができました。

これにより、タミヤの楽しい工作シリーズの様々な模型をScratchから操作できます。うまく使うと、小中学生のプログラミングの教材として面白いものができるのではないでしょうか?

こちらもどうぞ


「カラー図解 最新 Raspberry Piで学ぶ電子工作」、「実例で学ぶRaspberry Pi電子工作」を執筆しました。