beaglebone で、コマンドラインからデジタルとアナログ入出力

beagleboneで、arduinoみたいなことをやってみようということでいろいろ調べています。
よく、付属のLEDの点灯の記事を見かけるのですが、そんなのではなくて、arduinoみたいに外部のLEDをピカピカさせたいのです。
また、beaglebone付属のIDEを使って、webからやるのではなくて、せっかくlinuxが入っているのですから、コマンドラインやプログラムから、ピカピカさせたいものです。



beagleboneは名刺入れサイズの大きさのPCです。
中身はふつーのlinuxです。
gccやg++も最初から入っていますので、いろいろ遊べます。
boostなども入れることができます。(コンパイルに数時間かかりますけど)


また、beagleboneのCPU Cortex-A8には、NEONというSIMD命令が搭載しています。
gccのオプションを設定すれば、高速に浮動小数点演算ができます。

gcc -march=armv7-a -mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mabi=aapcs-linux -fforce-addr -fomit-frame-pointer -fstrength-reduce main.c


これらを使って、フィジカルコンピューティングは楽しそうです。

初心者に優しくまとめてあるサイトがなかったので作ってみましたよ。
#無保証です。これをやって壊れたり悲惨な目にあっても知りません。自己責任でやってください。
#ハードウェアは初心者なんでへんてこりんなことしているかもしれません。間違っていたら教えてあげてくださいw

お買い物

beaglebone本体。
http://gamegadget.ocnk.net/product/53

他にも探すとあると思います。googleします。アダプター別売。初心者なんでセットで買った。ハマりたくないしね。OSはディフォルトでlinuxが入っているのでそのままでOK。



LED , ブレッドボード,ケーブル,温度センサーなどの部品

LED
http://akizukidenshi.com/catalog/g/gI-00626/
(たぶんこれでいいと思う。今回は、 arduino付属の物を使った)


ブレッドボード
http://akizukidenshi.com/catalog/g/gP-05157/
(たぶんこれでいいと思う。今回は、 arduino付属の物を使った)


ケーブル
http://akizukidenshi.com/catalog/g/gC-05159/
(たぶんこれでいいと思う。今回は、 arduino付属の物を使った)


温度センサー LM35DZ
http://akizukidenshi.com/catalog/g/gI-00116/

arduino関係のお買い物

買わなくても別にいいけど、比較対象として、載せてます。

Arduinoをはじめようキット
Arduinoをはじめようキット

prototyping Lab
Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ (Make:PROJECTS)

beagleboneとの接続

USBでつなぐと、コンソールログインできます。

ドライバはこちらからダウンロードできます。

・64bit
http://beagleboard.org/static/beaglebone/a3/Drivers/Windows/BONE_D64.exe
・32bit
http://beagleboard.org/static/beaglebone/a3/Drivers/Windows/BONE_DRV.exe



ただし、日本語環境だと、実行時にエラーになってしまうので、工夫が必要です。

---------------------------
デバイス ドライバのインストール ウィザード
---------------------------
現在の言語では、デバイス ドライバのインストール ウィザードはサポートされません。



このパッケージを提供した製造元に問い合わせてください。
---------------------------
OK   
---------------------------

1.ダウンロードしたインストーラー BONE_D64.exe の拡張子を BONE_D64.exe.zip とかにします。


2.zip解凍します。


3.解凍してできた dpinst.xml を書き換えます。

前 <language code="0x0409">
↓
後 <language code="0x0411">


4.dpinst.exeを実行します。 これでインストールできます。




このやりかたは、こちらのブログに書いてあった方法です。
とても助かりました。
http://d.hatena.ne.jp/JiaLu/20120312/1331552415



さて、ドライバをインストールしたら、 PC と beaglebone をUSBで接続します。
USBで接続した beagleboneにアクセスするには、ターミナルソフトを使います。
今回は、おなじみ teraterm を使います。
#PuTTY?なんですかそれw食えるんですか (アンチPuTTY)


接続をシリアルポートを選択します。


beaglebone とつながっているCOMポートを選択します。
たいていの人はCOMポートは1つか2つしかないと思います。番号が大きいCOMポートを選択するとたいてい大丈夫です。
windowsバイスマネージャから番号も調べることもできますが、長くなるので、割愛。


シリアルポートで接続しました。
が、何も表示されません。



プロトコルが一致していないためです。
teratermの「設定」メニューから、「シリアルポート」を選択してください。



いろいろでてきますが、通信速度を 115200bps にして繋げばログインプロンプトが表示されます。
ボー・レートのところを 115200bps にしてください。
他は変更しないでください。変更しちゃったよという人は、このとおりの設定に直してください。


設定を変えて、エンターキーをガシガシたたくと、ログインプロンプトが出現します。


rootのノンパスでログインできます。

root@beaglebone:~#ls -la 

drwxr-xr-x  6 root root   1024 May 31 13:08 .
drwxr-sr-x  4 root root   1024 Apr 16 07:21 ..
-rw-------  1 root root  14766 May 31 03:33 .bash_history
drwxr-xr-x  2 root root   1024 May 28 21:13 .mplayer
-rw-------  1 root root     47 May 31 12:51 .python-history
drwx------  2 root root   1024 Apr 15 09:46 .ssh
-rw-------  1 root root  17535 May 31 13:08 .viminfo

root@beaglebone:~# pwd

/home/root


root@beaglebone:~# cat /proc/cpuinfo
Processor       : ARMv7 Processor rev 2 (v7l)
BogoMIPS        : 498.89
Features        : swp half thumb fastmult vfp edsp thumbee neon vfpv3 tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant     : 0x3
CPU part        : 0xc08
CPU revision    : 2

Hardware        : am335xevm
Revision        : 0000
Serial          : 0000000000000000



root@beaglebone:~#gcc

gcc: no input files


root@beaglebone:~#g++

g++: no input files

中身はふつーのlinuxです。
g++ とかも最初から入っています。
これは面白そうですね。


プログラムで遊ぶといいと思います。
ただ、今回は、フィジカルコンピューティングで遊びたいのです。
LEDをぴかぴかさせたいのです。

位置の特定

beaglebone を写真のような向きにもって、 右側に位置する 黒いバスが、port8 です。
逆際に位置するのが、 port9 です。


基盤をよーく眺めると、 P8 とか P9 とか書いてあります。
で、このバスを上から、pin1 pin2 〜 pin43 pin44 となっています。
これも、基盤をよーくみると、書いてあります。


それぞれのバスの役割は以下の通りです。
(https://github.com/CircuitCo/BeagleBone-RevA5/blob/master/BeagleBone_revA5_SRM.pdf?raw=true)

デジタル出力

デジタル出力をやってます。
今回は、LEDを光らせてみます。
LED をbeagleboneに取り付けます。
LEDを以下のように刺してみます。


LEDの足の短い方が GNDなので、 そっちを port8 pin1 に刺します。
もう片側を port8 pin3 にさします。

port8 pin1 とかそれってどこじゃいって話ですね。
図で説明するとこの位置です。ここにさします。


注意
今回は、わかりやすいように直接しています。
ちゃんとやりたきゃ抵抗入れるべきですね。
今回使う 3V程度だととりあえず動きます。
長時間光らせとくとヤバイかもしれません。終わったら抜きましょう。


ブレッドボードで指す場合こんな感じです。


LEDの「足が短い方」が GND で黒いケーブル、 LEDの「足の長い」が赤いケーブルです。
黒いケーブルは、GRD(port8 pin1)に接続し、赤いケーブルは、port8 pin3 に接続します。

ぴかぴかー

少しメンドイのですが、以下のコマンドを入れます。

つけて消します

echo 7 > /sys/kernel/debug/omap_mux/gpmc_ad6
echo 38 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio38/direction

#light on
echo 1 > /sys/class/gpio/gpio38/value

sleep 2

#light off
echo 0 > /sys/class/gpio/gpio38/value


echo 38 > /sys/class/gpio/unexport

面白いですね。
今回は、port8 pin3 でしたが、となりの port8 pin4 でも同じことができます。
やってみましょう。


port8 pin4に繋ぎ変えます。

前回は 38 でしたが、繋ぎ変えたので、 39 になります。

echo 7 > /sys/kernel/debug/omap_mux/gpmc_ad7
echo 39 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio39/direction
echo 1 > /sys/class/gpio/gpio39/value
sleep 2
echo 39 > /sys/class/gpio/unexport

どんなふうになっているのでしょうか?
まず、先程値を出力した gpio38 という gpio39 デバイスファイルですが、ふつーはこれらのファイルはありません。
echo 39 > /sys/class/gpio/export することで作成されます。

ls -la /sys/class/gpio/gpio39/

ls: cannot access /sys/class/gpio/gpio39/: No such file or directory



#export すると出現します。
echo 39 > /sys/class/gpio/export
ls -la /sys/class/gpio/gpio39/

drwxr-xr-x 3 root root    0 May 31 12:05 .
drwxr-xr-x 7 root root    0 Jan  2  2000 ..
-rw-r--r-- 1 root root 4096 May 31 12:05 active_low
-rw-r--r-- 1 root root 4096 May 31 12:05 direction
-rw-r--r-- 1 root root 4096 May 31 12:05 edge
drwxr-xr-x 2 root root    0 May 31 12:05 power
lrwxrwxrwx 1 root root    0 May 31 12:05 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 May 31 12:05 uevent
-rw-r--r-- 1 root root 4096 May 31 12:05 value


使い終わったら、 echo 39 > /sys/class/gpio/unexport で消します。

ls -la /sys/class/gpio/gpio39/

drwxr-xr-x 3 root root    0 May 31 12:05 .
drwxr-xr-x 7 root root    0 Jan  2  2000 ..
-rw-r--r-- 1 root root 4096 May 31 12:05 active_low
-rw-r--r-- 1 root root 4096 May 31 12:05 direction
-rw-r--r-- 1 root root 4096 May 31 12:05 edge
drwxr-xr-x 2 root root    0 May 31 12:05 power
lrwxrwxrwx 1 root root    0 May 31 12:05 subsystem -> ../../../../class/gpio
-rw-r--r-- 1 root root 4096 May 31 12:05 uevent
-rw-r--r-- 1 root root 4096 May 31 12:05 value



#unexport すると消えます。
echo 39 > /sys/class/gpio/unexport
ls -la /sys/class/gpio/gpio39/

ls: cannot access /sys/class/gpio/gpio39/: No such file or directory

次に、 39 とか 38 とかの数字と、 gpmc_ad7 とか gpmc_ad6 についてです。
pinの場所との対応表は以下のようになるみたいです。

pin 名前 番号     pin 名前 番号
Port8_pin1 -- --     Port8_pin2 -- --
Port8_pin3 gpmc_ad6 38     Port8_pin4 gpmc_ad7 39
Port8_pin5 gpmc_ad2 34     Port8_pin6 gpmc_ad3 35
Port8_pin7 gpmc_advn_ale(使っていいの?) 67     Port8_pin8 gpmc_oen_ren(使っていいの?) 66
Port8_pin9 gpmc_ben0_cle(使っていいの?) 69     Port8_pin10 gpmc_wen(使っていいの?) 68
Port8_pin11 gpmc_ad13 45     Port8_pin12 gpmc_ad12 44
Port8_pin13 gpmc_ad9 23     Port8_pin14 gpmc_ad10 26

以下略
定義一覧は、beaglepins.h にあります。(これについてはあとで説明)


実際に、見ましょう。
たとえば、一つしたのport8 pin5 につないだ場合は、 gpmc_ad2 と 34 ですから、以下のようになります。

echo 7 > /sys/kernel/debug/omap_mux/gpmc_ad2
echo 34 > /sys/class/gpio/export
echo out > /sys/class/gpio/gpio34/direction
echo 1 > /sys/class/gpio/gpio34/value
sleep 2
echo 34 > /sys/class/gpio/unexport
arduinoだとこんな感じ

さっきのデジタル出力をarduino でやる場合にはこんな感じにつなぐと思います。

そして、こんなスケッチを書くと思います。

const int ledPin = 13;

void setup() {
  pinMode(ledPin,OUTPUT);
}

void loop() {
  digitalWrite(ledPin,HIGH);
  
  delay(1000);
  
  digitalWrite(ledPin,LOW);
}

デジタル入力

beagleboneでデジタル入力する方法についてです。
実はあまりよくわかっていません。

一応、それっぽいことはできなくもないのですが・・・

echo 37 > /sys/kernel/debug/omap_mux/gpmc_ad6
echo 38 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio38/direction

cat /sys/class/gpio/gpio38/value
#1 が表示される。


#使い終わったら消す.
echo 38 > /sys/class/gpio/unexport

gpmc_ad6 なので、 Port8 pin3 と GND をつかいます。


ブレッドボードを別の用途に使ってしまったので、手で持っていますw

注意:
つなぎっぱにしないでください。
数分ぐらい放置しておくと、危ないです。

あまのじゃく

動作を見ていきます。
まずは、gpioの確保だけを行います
まだ、 Port8 pin3 と GND 間をいまはつながないでください。
つないでいれば離してください。

echo 37 > /sys/kernel/debug/omap_mux/gpmc_ad6
echo 38 > /sys/class/gpio/export
echo in > /sys/class/gpio/gpio38/direction

次に、 pinの状態を読み込みます。

cat /sys/class/gpio/gpio38/value

1


1が表示されました。



次に、 Port8 pin3 と GND をつなぎます。

cat /sys/class/gpio/gpio38/value

0

0が表示されました。



Port8 pin3 と GNDを外します。

cat /sys/class/gpio/gpio38/value

1

1が表示されました。

つながない 1
つなぐ 0

そうなんですね、、 つながっている時に0 が、つながっていなときに1 が表示されてしまうんです。
ふつーは逆、つながっている時が 1 で、つながっている時が 0 だと思います。
それが、逆になっています。

なんで、こうなっているか、ふつーの動作に変えるオプションはあるのか?よくわかりません。
よくわかんないんですが、とりあえず、これで動作します。
結果を !bool でもすれば、 0 と 1 になりますし、まーこれでいいかなーって思います。

27だとうまくいかない。

デジタル入力で 37 ではなくて、27にしているサイトもありますが、
27だとうまく動作しませんでした。 37だと0と1が入れ替わるあまのじゃくですが、動作しました。

#動く
echo 37 > /sys/kernel/debug/omap_mux/gpmc_ad6
↓
#動かない
echo 27 > /sys/kernel/debug/omap_mux/gpmc_ad6

27で動いたという方は教えてください。

アナログ入力

アナログ入力ということで、温度を測ってみたいと思います。
arduino用に買ってきていた LM35DZ 温度センサーを使ってみます。


今回は指す場所が3箇所あり、離れているので、ブレッドボードを使います。

LM35と書いてある平らな面から見て、右がGRD(黒ケーブル GNDにつなぐ)、 真ん中が温度情報(緑ケーブル AIN0につなぐ)、 左が5Vの電極(赤ケーブル)、につなぎます。


先程、LEDをさしたバスが port8 で、それの反対側にあるのが、 port9 です。
こいつが アナログ入出力ができるらしいです。


port9 は pin1 ,pin2 が GND です。
pin6 pin7 が 5Vらしいです。

また、beagleboneでは、アナログ入出力は、 AIN0〜AIN6を利用します。
AIN0は、 pin39です。


早速刺してみましょう。
さっきも書きましたが、黒が GND。 赤が 5V。 緑が AIN0 です。

beaglebonで値を取得する

beaglebone上では、 AIN0 が /sys/devices/platform/tsc/ain1 に、 AIN1 が /sys/devices/platform/tsc/ain2 と一つずれた名前でマップされています。
わかりづらいですが、そーゆーものらしいです。

名前 マップ先
AIN0 /sys/devices/platform/tsc/ain1
AIN1 /sys/devices/platform/tsc/ain2
AIN2 /sys/devices/platform/tsc/ain3
AIN3 /sys/devices/platform/tsc/ain4
AIN4 /sys/devices/platform/tsc/ain5
AIN5 /sys/devices/platform/tsc/ain6


今回は、 AIN0(port9 pin39) にさしたので、 /sys/devices/platform/tsc/ain1 を見てみます。
(beagleboneの アナログ入出力は12bitの値が取れるそうで、 0 〜 4096(2^12) の値になります。)

cat /sys/devices/platform/tsc/ain1

562

何か値が表示されました。
この数字を以下の計算式で使って変形する必要があります。

まずボルトに変換します。

value * ( 1.8V / 4096 ) = V


値を入れてみると、、
562   * ( 1.8V / 4096 ) = 0.246972656V


0.246972656Vだということがわかりました。
1Vは 1000mV です。
今回の温度計 LM35DZは、1度ごとに10mV変化するそうです。
と、いうことは、0.246972656Vは何度なんでしょうか?

0.246972656V * 1000 = 246.972656mV
246.972656mV / 10 = 24.6度

現在の温度が 24.6度ということがわかりました。
ちょっと寒い。

別のポートから値をとったらどうなるか?

さて、先ほどのコマンドで、 /sys/devices/platform/tsc/ain1 としましたが、これは、 AIN0(port9 pin39) のことです。
今度は、となりの AIN1(port9 pin40)にさしてみます。

cat /sys/devices/platform/tsc/ain2

551

さっきと似たような値がちゃんと値が取れました。
温度計 LM35DZなので、数字は完全に一致にならず多少ぶれます。



ちなみに、今は指していないポートから値をとると、変な値が取れるみたいです。

cat /sys/devices/platform/tsc/ain3

2548
arduinoだとこんな感じ

これをarduinoでやるとすると、こんなふうにつなぎと思います。


そして、こんなスケッチを書くと思います。

const int sensorPin = 0;

void setup() {
  Serial.begin(9600); 
}

void loop() {
  int native = analogRead(sensorPin);
  
  int temperature = map(native , 0 , 205 , 0 ,100);
  
  Serial.print("Native: ");
  Serial.println(native);
  Serial.print("Temperature: ");
  Serial.println(temperature);
  
  delay(1000);
}

動作させると、 COMに値が表示されます。
温度は nativeは LEDが返してきた値で、 temperatureはそれをスケールさせて人間が理解できる温度表記に変えたものです。

ライブラリは?

cat と echo でやりましたが、もっと簡単に取れるライブラリがほしい時もあります。
すでに作られているようで、 beagleboneIOというライブラリがあります。
https://github.com/justjoheinz/beagleboneIO/


早速使ってみましょう。

wget "http://github.com/justjoheinz/beagleboneIO/zipball/master"
unzip justjoheinz-beagleboneIO-*.zip
cd  justjoheinz-beagleboneIO-*
./configure
make

cd src

実行ファイルは src のなかにできます。
src/digitalWrite や src/analogRead を使って遊びます。
今回は、make install はしません。やりたい人はどうぞ。

beagleboneIOでデジタル出力

port8 pin3 ledをつないでやってみましょう。


./digitalWrite --pin P8_3 --value 1

sleep 2

./digitalWrite --pin P8_3 --value 0


となりの port8 pin4 につないだとしたら、こんなふうにやります。

./digitalWrite --pin P8_4 --value 1

sleep 2

./digitalWrite --pin P8_4 --value 0

簡単ですね。

beagleboneIOでアナログ入力

AIN0(port9 pin39) に温度計 LM35DZをつなぎます。

さっそく、値を取得してみましょう。

./analogRead --pin 0

562


値が取れました。
cat で取得したのと似た数字です。
(温度計なので、必ず同じ値になるとは限りません)

cat /sys/devices/platform/tsc/ain1

564


あれ? ain1 と思った人は、 beaglebone では、 AIN0 が /sys/devices/platform/tsc/ain1 、 AIN1 が /sys/devices/platform/tsc/ain2 と、一つずれたところにマップされるのを思い出してください。


この562とか564の数字を前に使った変換式に入れてあげると、温度がわかります。

562   * (1.8V / 4096 )  = 0.246972656V

0.246972656V * 1000 = 246.972656mV

246.972656mV / 10 = 24.6度

まとめ

beagleboneを利用すると、 linuxを利用して デジタル・アナログ入出力ができるみたいです。
linuxであるから、g++や boostなどの高度なライブラリがたくさん利用できます。
boostを利用してのフィジカルコンピューティングは面白いのではないんでしょうか?

参考

Beaglebone Coding 101: Blinking an LED
http://www.gigamegablog.com/2012/01/05/beaglebone-coding-101-blinking-an-led/

Beaglebone Coding 101: Buttons and PWM
http://www.gigamegablog.com/2012/03/16/beaglebone-coding-101-buttons-and-pwm/

beagleboneIO
https://github.com/justjoheinz/beagleboneIO

prototyping Lab
Prototyping Lab ―「作りながら考える」ためのArduino実践レシピ (Make:PROJECTS)

A/D変換のテスト OpenCVで遊ぼう!
http://playwithopencv.blogspot.jp/2012/05/ad.html

beaglebone
http://gamegadget.ocnk.net/product/53
(他にも探すとあるよ。アダプター別売。セットで買うとはまらないでいいと思う。OSはディフォルトでlinuxが入っているのでそのまま)

Arduinoをはじめようキット
Arduinoをはじめようキット

WindowsにBeagleBoneシリアル接続ドライバのインストール
http://d.hatena.ne.jp/JiaLu/20120312/1331552415

零からの電子工作
http://dic.nicovideo.jp/a/%E9%9B%B6%E3%81%8B%E3%82%89%E3%81%AE%E9%9B%BB%E5%AD%90%E5%B7%A5%E4%BD%9C
(勉強させてもらっています・・・・)

ついたく

試行錯誤している時に、間違って5Vをそれも逆に流してしまって、燃えてしまったLEDに敬礼。
LEDから煙がモクモクでました。あわててケーブルを引っこ抜きました。
逝ってしまわれた。円環の理に導かれて・・・・

LEDは犠牲になったのだ。