1

Android版ArduinoFirmataを作った

AndroidのJavaの中で

int sensor = arduino.analogRead(1);
arduino.servoWrite(9, 155);
とか書けて便利です。

ここにチュートリアルとか、すぐ試せる無署名のapkとか置いといたのでどうぞ
ArduinoFirmata on Android

ArduinoFirmata on Android


先週ArduinoとAndroidを接続できたので、Firmataプロトコルの移植はRubyでもやった事だしさくっとAndroid版も作ってみた。



Android OS 3.2以上でUSBホスト機能がある端末とStandard FirmataをインストールしたArduinoを、USBホストケーブルで接続する。
Arduino IDE -> [File] -> [Examples] -> [Firmata] -> [StandardFirmata] でインストールできる。
(Firmataを入れたArduinoは、シリアル通信からの命令で動く操り人形モードになります)

Android用ライブラリはjarファイルにしてArduinoFirmata on Androidに置いてある。
Androidプロジェクトのlibsディレクトリに入れれば使える。


Arduino Duemillanove, UNO, Seeduino v2で動作確認した。
USBホストケーブルはこれこれが使えた。


ご意見ご感想はtwitterやgithubのissueやpull requestなどお待ちしております

11

AndroidのUSBホスト機能でArduinoとシリアル通信する

超便利なライブラリ作ったのでこっち使うといいです → 橋本商会 » Android版ArduinoFirmataを作った

——-以下本文

なんか意外と簡単にできたし、まったくやってる人の情報が無いので書いておく。


Nexus7+Arduino(Seeduino)+サーボモータ を動かした


AndroidにArduino等のシリアルデバイスを直つなぎできる。
ADKやUSBホストシールドやIOIOと違って、むずかしい回路やプログラムはいらないし、電源もAndroid側から供給もできる。
マイコン側は単純にシリアル通信するだけ。Android側もUSBシリアルポートを探して接続するだけ。


Nexus7にはUSBポートとは別に充電ポートがあるのでそっちで充電させつつ、デバイス制御もできそう

必要な物は3つ

1. USBホスト機能に対応したAndroid端末
2. USBホストケーブル
3. Arduino等のUSBシリアルデバイス


USBホスト機能に対応したAndroid端末

Android 3.1(タブレット用)や4以上の端末はUSBホスト機能がある。
2012年夏ごろからの端末が該当していて、USBホストシールドやADKが必要なくなった。

Galaxy NexusやGalaxy S3以降でAndroid4以上の端末はokのはず。
Googleが各ベンダになるべくUSBホスト機能を持たせるように働きかけているってsonyの人が言ってた。
最近Nexus SにもAndroid4が配信されたけど、チップセットにUSBホストの機能が無いので無理。


USBホストケーブル

ようするに「AndroidにUSBキーボードやマウスを接続できる」と書いてあるケーブルのこと。
これをUSBポートに接続すると、AndroidはUSBホストモードになる。

USBケーブルは普通4ピンだ。VCC、GND、D+、D-ピンの4つ。
USB mini/microから、5ピンになった。IDピンが増えた。
USBホストケーブルを作るには、IDピンとGNDピンをショートさせるだけでいい。


これを買った。ぴったりで良い。


なお自作も可能。S2 » USBホストケーブルとUSBケーブルの違い にくわしく書いてある。
市販のUSB-マイクロUSB変換コネクタを分解して、IDピンを短絡させてる。


昔のArduinoと今後のArduino

Arduino UNO以降は、AVRマイコン内蔵のUSBシリアル機能を使うようになっている。
Arduino Duemillanove以前は、FTDI社のFT232というUSBシリアル変換ドライバICを使っている。
それぞれ違うデバイスドライバが必要だけど、両方対応できるようにAndroidアプリを実装可能。

このGoogle製ライブラリを使えばいい。勝手にデバイス判別してくれる。
ボーレートの設定とかも扱いやすい関数が揃ってて便利。
usb-serial-for-android – Android USB serial and Arduino device host support library. – Google Project Hosting

これを使わなくてもandroid.hardware.usb.UsbDeviceクラスを使えば自分で実装できるが、ソース見てみればわかるけどげんなりする処理が多いのでusb-serial-for-android.jarを使うのが良いと思います。

AndroidでArduinoとシリアル通信する


usb-serial-for-androidのDownloadsメニューからusb-serial-for-android-v010.jarをダウンロードして、Androidアプリのlibsディレクトリに入れる


AndroidManifest.xml のinternt-filterの中に追加
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />


さらにintent-filterと同列にmeta-dataを作る
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />


device_filter.xml を取得する。FTDIチップやArduinoのUSBベンダIDが書いてある。
wget http://usb-serial-for-android.googlecode.com/git/UsbSerialExamples/res/xml/device_filter.xml
mkdir res/xml
mv device_filter.xml res/xml/


接続する。
アクティビティ内で
import java.io.*;
import android.hardware.usb.*;
import com.hoho.android.usbserial.driver.*;

public void onCreate(Bundle savedInstanceState) {
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
UsbSerialDriver usb = UsbSerialProber.acquire(manager);
if (usb != null) {
try{
usb.open();
usb.setBaudRate(9600);
start_read_thread(); // シリアル通信を読むスレッドを起動
}
catch(IOException e){
e.printStackTrace();
}
}
}


Arduino → Android
シリアル通信で受信したデータを読む。ArduinoでSerial.println(“文字列”)したデータがAndroid側で読める。
public void start_read_thread(){
new Thread(new Runnable(){
public void run(){
try{
while(true){
byte buf[] = new byte[256];
int num = usb.read(buf, buf.length);
if(num > 0) Log.v("arduino", new String(buf, 0, num)); // Arduinoから受信した値をlogcat出力
Thread.sleep(10);
}
}
catch(IOException e){
e.printStackTrace();
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}


adb logcat | grep arduino
して見てみましょう。受信できているはず。


Android → Arduino
AndroidからArduinoに文字列「o」や「x」送信する。
while(true){
usb.write("o".getBytes("UTF-8"),1);
Thread.sleep(1000);
usb.write("x".getBytes("UTF-8"),1);
Thread.sleep(1000);
}


接続を閉じる。
try{
usb.close();
}
catch(IOException e){
e.printStackTrace();
}


Arduinoにはこんなのを書いておくと、シリアル通信でoとxが来たらLEDを点灯消灯させたりサーボモータを回したりできる。
char led_pin = 13;
char serial_recv;

void setup(){
pinMode(led_pin, OUTPUT);
Serial.begin(9600);
}

void loop(){
Serial.println(analogRead(0)); // アナログセンサの値をAndroidに送る
while(Serial.available() > 0){
serial_recv = Serial.read(); // シリアル通信を受信
switch(serial_recv){
case 'o':
digitalWrite(led_pin, true); // 基板上のLEDを点灯
analogWrite(11, 200); // サーボ回す
break;
case 'x':
digitalWrite(led_pin, false); // 消灯
analogWrite(11, 20); // サーボ回す
break;
}
Serial.println(serial_recv);
}
delay(10);
}


WiFiでAndroidアプリ開発

ArduinoをAndroidに接続しているとUSBケーブルがさせない。MacからWiFi経由でAndroidにプログラムを書くといい。
Nexus7が同じ無線LAN内の192.168.1.121にあるとする。
設定→タブレット情報→端末の状態 にIPアドレスが書いてある。
AndroidをMacにUSB接続してから
adb tcpip 5555
adb connect 192.168.1.121:5555
adb logcat
USBケーブルを抜く。

あとはもう、adb installもEclipseからのDebug Runも、logcatもWiFiでできるようになってる。


元に戻すには、USBケーブルを接続して
adb usb
これで戻る。


その他の作例

こういうのを作ってる人がいて、参考になった

Android USB Host + Arduino: How to communicate without rooting your Android Tablet or Phone | Using Android in Industrial Automation
android.hardware.usb.UsbDeviceを使ってArduino UNOとシリアル通信している

Android Host – Arduino間シリアル通信の実現 – アトリエのどか
FTDIドライバを使ってArduino Duemillanove以前とシリアル通信してる

0

Raspberry PiでRuby/Arduino/Twitter/webcam

Raspberry Piが届いたのでセットアップしてArduinoでサーボモーター動かしたり、CdSで明るさ読んでTweetしたり、webcamでJPEGに撮影したりした。
raspbianというほぼdebianなOSを入れたのでかんたんだった。


購入

RSコンポーネンツをキャンセルしてModMyPiでケース付きのを買った。10日ぐらいで届いた。
Makershedでも売ってる。

RaspberryPi + modmypi case


SDカードにRaspberry Piを書き込む


akiroom情報でRaspbian “wheezy”を使うことに。

Amazonで買った16GBのSDHCカードに入れた。4GBあれば足りると思うけど安かったので16GB。

Amazonベーシック SDHCカード 16GB class10
AmazonBasics
売り上げランキング: 20


http://www.raspberrypi.org/downloadsからzipでダウンロードしてきて、
MacでUSBメモリにUbuntuのインストールディスク作ると同じ手順でSDカードに書き込んだ。
ただし今回はRaspberry Pi用にカスタムされたディスクイメージ(インストールディスクではない)をそのままいれる。


SDカードを抜いた状態と刺した状態でそれぞれ
mount
で増えてるデバイスを見つける。/dev/disk3が増えていた。


zipでダウンロードしてきたディスクイメージをdmgに変換してSDカードに書き込む
unzip 2012-10-28-wheezy-raspbian.zip
hdiutil convert -format UDRW -o 2012-10-28-wheezy-raspbian.dmg 2012-10-28-wheezy-raspbian.img
sudo diskutil umountDisk /dev/disk3
sudo dd if=2012-10-28-wheezy-raspbian.dmg of=/dev/rdisk3 bs=1m
sudo diskutil eject /dev/disk3


Raspberry Pi起動

SDカード、LANケーブル、USBキーボード、そしてHDMIをモニタに刺して、最後にMicroUSBで電源を刺して起動。
SSHを有効にするかとかlocaleとかの設定が出る。
基本的に全部ja-JP.UTF-8にしてSSHは有効のまま起動。

Raspberry Pi boot
CUIでログインできた。


あとはもう普通のdebianなので、普通に設定する。
Raspberry Piの日本語化 – ナントカ嬢とかを参考に。


パスワード変える

誰でもpi:raspberry でログインできてしまうので、
passwd
で変える。


電源を切る

sudo halt

再度電源入れたらなかなか起動しなくてあせったが、なんかSDカードに書き込んでた。
2回目の起動からはGUIが立ち上がった。ふつーにpython gamesでオセロとかやってたら時間経ってた。
Raspberry Pi boot


ユーザ名

いつも使ってる名前のユーザを追加してしばらく操作したけど、
Pi以外だと音をだす時とシリアルポートを使う時にpermissionが無いと言われるので、Piのままの方がヨサゲ


SSHでログイン

Raspberry PiのIPアドレスを調べる
sudo ifconfig
192.168.1.109だった

キーボードが多いと邪魔なので、手元のMacからログインする。
ssh pi@192.168.1.109


手元のMacの~/.ssh/configに
Host pi
HostName 192.168.1.109
port 22
User pi
こういう設定を書いて、

ssh pi
で接続するようにした。


色々アップデート、日本語環境

ディスクが遅いのか、けっこう待つ
sudo apt-get update
sudo apt-get upgrade

sudo apt-get install console-data
sudo apt-get install language-pack-ja
sudo apt-get install ttf-takao-mincho ttf-takao
sudo apt-get install locales
sudo dpkg-reconfigure locales


環境を整える

sudo apt-get install emacs23-nox screen zsh git


他のlinuxでいつも使ってる設定ファイルを持ってきて快適化
https://github.com/shokai/linux-dotfiles
https://github.com/shokai/mac-dot-emacs


zshellを使う
which zsh
chsh


ネットワーク設定

USBにWiFi刺した。

参考:WiFi/HowToUse – Debian Wiki

/etc/network/interfaces を設定する。
auto lo

iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
iface wlan0 inet static
wpa-ssid 自宅のSSID
wpa-psk WPAのパスワード
address 192.168.1.5
netmask 255.255.255.0
gateway 192.168.1.1
dns-nameservers 192.168.1.1


設定を有効に
sudo /etc/init.d/networking restart


これでしばらくは固定IPでWPA2なWiFiに接続できていたんだけど、理由はよくわからないが接続できなくなったのでeth0のほうを使うようにした。
あとで何とかする。

何とかした → Raspberry PiにWiFi付けた


Rubyをインストール


-fullパッケージができてインストール楽になりましたね
sudo apt-get install ruby1.8-full rubygems

ruby -v
gem -v
ruby 1.8.7 (2012-02-08 patchlevel 358) と gem 1.8.24が入った。

もう1.8は終わったので1.9以上にしたほうがいいです(2013年6月)

Twitterする


Twをインストールした

sudo gem install tw system_timer
tw # 認証する
tw raspberry piからtwでtwitterしてる



Arduinoを使う


Arduino Firmtaa gemでサーボやLEDやらを動かしてみた
sudo gem install arduino_firmata



Arduino IDEで [File] -> [Examples] -> [Firmata] -> [StandardFirmata]をArduinoの書き込んでおく。


デバイス名はDuemillanoveだとttyUSB0、UNOだとttyACM0らしい。
Duemillanoveは一度使うと抜き差ししないと認識しなくなるバグが発覚した。あとで直す。
UNOは問題ない。

直した → Raspberry Pi + Firmata + Arduino Duemillanoveのバグを直した


digital 11にLED、digital10にサーボを接続した
#!/usr/bin/evn ruby
require 'rubygems'
require 'arduino_firmata'

arduino = ArduinoFirmata.connect ARGV[0]

loop do
puts "0 -> 180"
arduino.digital_write 13, true
0.upto(180) do |i|
arduino.analog_write 11, i
arduino.servo_write 10, i
sleep 0.01
end

puts "180 -> 0"
arduino.digital_write 13, false
180.downto(0) do |i|
arduino.analog_write 11, i
arduino.servo_write 10, i
sleep 0.01
end

end


明るさをツイート


CdSをArduinoのAnalog 0に接続
Arduino 温度・明るさセンサ設置


ワンライナーでツイート
echo "Raspberry Piの明るさ `arduino_firmata --arduino=/dev/ttyACM0 analog_read 0`" | tw --pipe



これを使った → プログラムを一切書かずに、ネットワーク越しにArduinoを操作する

crontabに登録しておけば定期的にツイートできる。


USBカメラで撮影

CUIでUSBカメラキャプチャをやる
logicoolの古いwebcamがあったので使った。(上の写真のやつ)
古くてもう売ってないっぽい。
Raspbianなら、USB video class対応しているwebcamつまり最近のやつならどれでもドライバ無しで認識すると思う。


sudo apt-get install fswebcam
カメラつなげて
fswebcam -d /dev/video0 -D 2 -r 400 --jpeg 95 capture.jpg
これで撮影できた。

0

プログラムを一切書かずに、ネットワーク越しにArduinoを操作する

sshdが起動しているサーバーにArduino Firmata on Rubyをインストールして、firmataをインストールしたArduinoを刺すだけでok


Arduinoの準備

Arduino IDEで [File] -> [Examples] -> [Firmata] -> [StandardFirmata] を書き込む


サーバー側の準備

ArduinoをUSBポートに刺す。


rubyのarduino_firmata gemをインストールする。
sudo gem install arduino_firmata
arduino_firmata --help
arduino_firmata gemをインストールすると、arduino_firmataという実行コマンドが使えるようになる。

arduino_firmata analog_read 1
これだけでanalog 1の値が読める。

arduino_firmata servo_write 11, 135
11ピンに接続したサーボモータが135度に回転させる。
コマンドからarduinoの基本的な機能は全部使える。


手元のMacからサーバーのArduinoを動かす

sshコマンドプロキシでセンサー読める
ssh user@example.com arduino_firmata analog_read 0
sshは、「ssh 接続先 コマンド」でサーバーにコマンドを実行させて結果を得てすぐ切断する事ができる。
arduino_firmataコマンドと組み合わせれば、全くプログラム書かずにコマンド1行で家のサーバーに刺さってるArduinoのCdSで明るさが取得したり、サーボモーターを動かしたりできる。


その他の例

例えばtweetさせたり
echo "明るさ `arduino_firmata analog_read 0`" | tw --pipe
Twを使ってる




Ruby以外の言語からでもセンサーを読むぐらいならできるし、cronに組み込んだりもできるし、そこそこ便利なのでは

0

RubyからArduinoを操作できるようにFirmataプロトコルを移植した

Javaから移植した
Arduino Firmata on Ruby

インストール

gem install arduino_firmata
Ruby 1.8.7と1.9.2で動作確認してる。serialport gemを使ってるのでJRubyでは動かない。


できること・使い方

RubyからArduinoのデジタル・アナログの入出力が使える。

例えばTwの内部APIと温度センサLM35DZと組み合わせると、9行で温度をtweetできたりして便利。
#usr/bin/env ruby
require 'rubygems'
require 'arduino_firmata'
require 'tw'

arduino = ArduinoFirmata.connect "/dev/tty.usbmodem621"
puts temp = arduino.analog_read(1)*100*5/1024 # 摂氏1度毎に10mV出力なので計算する
client = Tw::Client.new
client.auth "shokai"
client.tweet "現在の温度 #{temp}度"


あとはSinatraと組み合わせて20行ぐらいでブラウザからArduino動かしたりとかもできる



Firmataとは


http://firmata.org
Firmata(ふぁるまーた)はProcessingからArduinoを制御するために5年ぐらい前に作られたプロトコルだ。

Arduinoに Firmataファームウェア を書き込むと、USBシリアル通信経由でパソコンとやりとりしてIOを操作したり色々やってくれる。
プログラムを書く側はArduinoのコードを書いたりパソコンとの通信を意識したりする必要が無くなり、
手元のRubyやProcessingだけを書けば済むのでとても楽になる。
ただし、通信する分だけ遅くなるので超細かくモーターを制御する等には向いていない。


Processing以外にもMax/MSPやopenFrameworksなど色々なプログラミング言語からArduinoを制御する時に使われるようになったり、
また逆に、Arduino以外のボード(Funnel IOなど)をProcessingから制御するのにも使われてたりしている。

いろんな言語とボードを接続するのに便利なプロトコルなのだが、
PhidgetsがあるんだからArduinoはスタンドアロンで使うべきじゃないの?という印象だった。2週間前までは。

八王子の山奥のopenFrameworksセミナーで使ったGrove Systemが拡張パーツの多さ・入手の容易さ・自分で拡張しやすいという点でPhidgetsを食ってしまっていたので、Rubyでも使いたくなった。
つまり Ruby+Firmata+Arduino+GroveSystem 最強なのでは。全部オープンソースだし。

実装はそんなに難しくなくて昨日お風呂にはいる時間を削って作ってみたらすぐ動いたのでgemにした。
Arduino playground – Processing にあったJavaのFirmataライブラリをまるごとRubyで書きなおした。


Rubyっぽい書き方


せっかくRubyで書いてるので使いやすいAPIにしたい。

デバイス名を省略してconnectしても適当に探して接続したりとか、
ADコンバータにcallback登録できるようにしてみた。
arduino = ArduinoFirmata.connect

arduino.on_analog_changed 0 do |value|
puts "analog pin 0 changed #{value}"
arduino.analog_write 11, value
end

ブロックを使うと、arduino.analog_readをanalog_readだけに省略できたりとか
ArduinoFirmata.connect do
puts "firmata version #{version}"

30.times do
an = analog_read 0
analog_write 11, an
sleep 0.01
end
end


簡単なチュートリアルも Arduino Firmata on Ruby に書いたし、
今後も機能追加するので(未実装のon_digital_changed等)見ると良いと思います。