2011年5月17日火曜日

Puredata で簡易サンプラー その2

前回は Puredata(以下 Pd) で簡易サンプラーを作成しました。
今回はPduino を使って Arduino に接続したスイッチに反応させます。

Pd は配線が込み入ってくると、なんだか分からなくなってしまいます。
Pduino のサンプルは最初から凄いことになっているので、不要なところは消して行きましょう。

こんな感じになりました。


最初に IO ポートの設定をします。
StandardFirmata_2_2_forUNO_0_3 の場合、初期値は
・A0-A5 はアナログ入力
・D0,D1 は通信用のため使用不可
・D2-D13 はデジタル出力 (初期値:LOW)
になっています。

今回はD11 を入力(スイッチを接続)、D13 を出力(LEDを接続、またはボード上の[L]) にします。... (1)
input に指定しただけでは、内蔵プルアップが ON にならないようです。
そこで、(2) の [digital 11 1( というメッセージでプルアップを有効にします。

Arduino にスイッチ(SW) を接続してみましょう。
(スイッチが無くても、D11 とGND をショートすれば、スイッチの替わりになります。)


この状態で、(4) のトグルが、D11 に接続したスイッチに反応することが確認できます。
(反応しない場合は、Firmata との通信ができているか確認してください。)

(3) の [digital 13 $1( というメッセージは、上のトグルをON/OFF すると、
[digtal 13 1( と[digital 13 0( が交互に送られます。これにより、Arduino のボード上のLED (L) がON/OFF します。


次に、(4) のD11 と、(3) のD13 を接続します。... (5)
これで、スイッチのON/OFF で、LED のON/OFF ができます。
(論理は反転しています(スイッチON でLED OFF)。間に[== 0] をいれれば、再度反転してスイッチ ON で LED ON になります。)

次に、スイッチON のときに、Bang を送るようにします。トグルにそのままBang を接続すると、ON/OFF の両方でBang が出てしまうので、[sel 0] で、トグルがOFF (D11 のスイッチがON) になったときだけ、Bang を出すようにします。 ... (6)

これで、スイッチが押されたときに Bang が出るようになりました。
(D13 のLED は確認用なので、接続しなくても構いません。)

この後は、前回のサンプラーのBang (Play_1) と、今回のBang を接続すれば完了です。
どちらかをコピー&ペーストして、1つのファイルにしても良いのですが、別の方法もあります。Bang のProperties (右クリックして選択)を表示します。


Messages という欄に、send-symbol, receive-symbol という項目があります。
このsend - receive は、線でつないだときと同じように、指定したsymbol 同士を接続する機能です。
この接続は別ウインドウでもOK です。つまり、前回のファイルと、今回のファイルを同時に開いておき、今回のBang にsend-symbol を、前回のBang にreceive-symbol を指定する事で、ウインドウをまたいだ接続ができます。


ケロミンの声をサンプリングするデモ動画



Puredata で簡易サンプラー その1


Puredata (以下Pd)で簡単な音を出すパッチの紹介です。
「サンプラー」とは、マイクなどで録音(サンプリング)した音を、任意のタイミングで再生するものです。
Arduino (Pduino) と組み合わせて、外部のセンサーやボタンに反応して音を出す、といった使い方を想定しています。

Pd は一般的な音楽ソフトのように、「音楽ファイルを再生」といった機能がありません。
Array (配列) にサンプルデータを記憶し、音として再生する、といった手順をとります。

今回は、sample という名前の 88,200点(44.1kHz サンプリングで 2秒分)のArray を使っています。
Array へのデータ書き込みは [tabwrite~ sample] で行っています。
その上の [Sampling_from_Mic] をBang すると、[adc~] (A/D Converter)から88,200点(2秒)、サンプリングします。

単純に再生するだけであれば、緑の[Play_2] をBang します。
すると、[tabplay~ sample] を使って、Array のデータを44.1kHz で取り出します。

取り出したデータは [dac~] (D/A Converter) に入力することで、音として再生されます。
(その間にある [hip~ 5](High-Pass Filter) は直流カットのため、[*~ 0.5] は音量調整のために入れています。)

・[dac~] の入力は、この例では Lch, Rch の2系統ありますが、データがモノラルなので、同じデータを入れています。
・[soundfiler] の周りはファイルの読み書きです。
・[; pd dsp $1;( は Media メニューの audio ON, audio OFF と同等の動作です。


水色の[Play_1] の方はもう少し複雑な読み出しをしています。
事前に作り込んだオーディオファイルなら良いのですが、マイクからサンプリングすると、どうしてもマウスのクリック音や、発声までの無音が入ってしまいます。
それらを取りたかったので、[Slider_1] を付けてみました。
(このSlider はArray と連動しているわけではなく、単純にサイズを合わせただけのものです。)

Array の波形を見ながら、不要な部分を[Slider_1] で指示します。
この値を [vline~] に入力します。
[vline~] に入力しているのは、Array の開始点、終了点、再生時間 の3つのパラメータです。
[/ -44.1] という部分で、通常の再生スピードとなります。この値を他の数値にすると、再生ピッチが変わります。うまく調整することで、音階も作れます。

[vline~] の出力を [tabread4~ sample] に入力する事で、開始点と再生ピッチを指定した再生が可能になります。



Puredata ファイル(zip 圧縮) : Download


2011年5月12日木曜日

PureData から Growl 通知


Growl はMac の画面上にメッセージを通知するソフトです。
何を通知するかというと、対応アプリケーションのメッセージです。
メールやメッセンジャーサービスだけでなく、様々なソフトが処理の完了などの通知を行います。


この記事で知ったのですが、Terminal コマンド growlnotify によって、コマンドラインからもメッセージが送れるとのこと。(growlnotify はGrowl と一緒にダウンロードされますが、別途インストールする必要が有ります。)

ということは、前回同様、Puredata からshell パッチを使って送れるのです。





さらに、記事で紹介されている iOS アプリ「Boxcar」を使えば、iPhone にも通知できます。
Arduino に接続したセンサー の値を Pduino で読み取って Growl 経由でiPhone に通知!
なんてことも、プログラムなしで出来てしまうのです。


今回の図にある、"Hello" は送れましたが、"Hello, World" や"Hello World" は期待通りになりませんでした。
どうやら PureData のメッセージオブジェクトはスペースやカンマが区切り文字として扱われ、それらをエスケープする文字や手段(" クオートで囲むなど)がない(スペースを含んだメッセージが送れない)ようです。

何か回避方法は無いのでしょうか、、、?


2011年5月11日水曜日

OSC で iTunes をコントロールする


これまでに、Arduino や iPhone を使った OSC の送信を紹介してきました。
OSC 対応のソフトはPuredata やQuartz Composer などがありますが、他のソフトもコントロールできると便利です。
iTunes など Mac のソフトの多くは、AppleScript という、コマンドによる操作手段が用意されています。

そこで、OSC を受信して、AppleScript を飛ばすソフトを探してみました。
OSCulator というソフトでできるらしいのですが、 $39-... ちょっと高い。

AppleScript はTerminal コマンドの osascript でも実行可能です。
そこで、Puredata のshell パッチを使い、osascript コマンドによってAppleScript を実行してみます。
(以前に、Quartz Composer から同じようなことをやった気もしますが、、、)

本来なら、shell に osascript -e 'tell application "iTunes" to play' というメッセージを投げれば良いと思うのですが、これではエラーに。いろいろ試した結果、



1. AppleScript Editor でAppleScript を作成、保存する
2. 1で作成したスクリプトをフルパスで起動するコマンド文(Message Object)を作成
3. Shell Object に2 のMessage を送る

例えば、「~/Documents/itunes-play.scpt」に保存したAppleScript 起動する場合

osascript /Users/YOUR_USER_NAME/Documents/itunes-play.scpt

このようなメッセージをshell に送れば良いことが分かりました。


事前にPuredata とこのPatch を起動して準備する必要がありますが、反応は良好です。
スライダーなどで大量のOSC を送ると、処理が終わる前に次のOSC メッセージが来てしまうので、
ignor という、メッセージを制限するパッチを使ってみました。



iTunes のボタンに対応するAppleScript コマンドはそれぞれ
再生(停止):playpause
次の曲:next track
前の曲:previous track
ボリューム:set sound volume to 100 -- (0 ... 100)
です。


再生(停止)の場合は

tell application "iTunes"
playpause
end tell

だけでOK です。
ボリューム調整は引数が必要なので、

on run argv
tell application "iTunes"
set sound volume to argv
end tell
end run

このようなスクリプトにします。
このページをMac OS X で見ている場合、次のリンクから AppleScript Editor を起動できます。




2011年5月8日日曜日

Arduino XBee Shield Wireless プログラミング

前回、Arduino Fio のWireless プログラミングを行いました。
その最後に書いた通り、Arduino Uno + XBee Shield ではうまく行かなかったので、今回はそれを検証します。

エラーはこの通りです。

avrdude: stk500_recv(): programmer is not responding


今回はeJackino (この本の付録基板)という Duemilanove (Uno の1つ前のモデル) 相当のArduino 互換ボードを使ってみました。
すると、あっさり書き込みOKでした。


折角なので検証のため、直結をやめてケーブル接続にします。必要な配線は

電源 (+5V,Xbee Shield 上に3.3V のレギュレータが載っています。Xbee は3.3V 動作です)、GND、TX(D1)、RX(D0)、Reset の5本です。

線を外すことで、わざとエラーをおこします。



通信ができていないときのエラー(RX or TX を外したとき)

avrdude: stk500_recv(): programmer is not responding
avrdude: stk500_recv(): programmer is not responding

リセットができていないときのエラー(Reset を外したとき)

avrdude: stk500_getsync(): not in sync: resp=0x30
avrdude: stk500_disable(): protocol error, expect=0x14, resp=0x51

となりました。

さらに、Arduino Uno とeJackino で使っているマイコンを入れ替えたり、このページを参考に、リセット回路の強化を試してみました。リセット信号直列のコンデンサは XBee Shield 上に載っていたので、追加したのはNPN トランジスタ(2sc1815) と抵抗10kΩのみ





結果

本体設定 (Tools > Board)マイコン
(ブートローダー)
リセット
回路強化
結果
eJackinoArduino Duemilanove
or Nano w/ ATmega328
Duemilanove相当なしOK
eJackinoArduino Duemilanove
or Nano w/ ATmega328
Duemilanove相当ありOK
Arduino
Uno
Arduino UnoArduino UnoなしError
Arduino
Uno
Arduino UnoArduino UnoありError
Arduino
Uno
Arduino Duemilanove
or Nano w/ ATmega328
Duemilanove相当なしError
Arduino
Uno
Arduino Duemilanove
or Nano w/ ATmega328
Duemilanove相当ありOK
Arduino
Uno
Arduino UnoDuemilanove相当なしError
Arduino
Uno
Arduino UnoDuemilanove相当ありError


Arduino Uno とDuemilanove は、ブートローダーが異なるため、そのあたりに原因がありそうです。
(5/15 追記:Uno のブートローダーが115kbps で書き込むらしいので、XBee の速度(ATBD) を115kbps にしてみましたが、やはりだめでした。)

結局、Uno のWireless プログラミングの方法は分かりませんでしたが、Duemilanove (相当) では問題なさそうです。
同じくDuemilanove 相当の「akizukino」こと、AE-ATmega 基板(秋月電子・150円) を購入したので、これを USBシリアルアダプタなしで作るのもありかなと思っています。

緑がAE-ATmega 基板、上の小さいのは eJackino mini と eJackino pico。

2011年5月7日土曜日

Arduino Fio (Wireless プログラミング篇)

Arduino Fio の XBee を使ったワイヤレスアップロードの紹介です。
前回は USB シリアルアダプタによる転送を行いました。

XBee (Series 1) を正しく設定すれば、USB シリアルアダプタは購入しなくても、Arduino IDE からプログラム転送する事が出来ます。
Fio の公式ページ (Arduino.cc) とFunnel のページ (funnel.cc) を読んだ上で、Mac OS X 上のArduino IDE (ver 0022) で使う場合に特化して説明します。

それぞれのページに、複数の方法が書いてありますが、XBee Config Tool というソフトを使うのが簡単です。
ハードウェアは2 台の XBee (Series 1) モジュール、1 台の Arduino Fio、1 台の XBee Explorer USB (USB アダプタ)を使っています。

[XBee モジュールの設定]
作業前に悩んだ以下の点を説明します。

1. AT コマンドによる設定は必須?

(結論) >> 不要です。XBee Config Tool を使うと、そのコマンド群のように設定されます。
 特別な理由がなければ XBeeConfig Tool を使うのが良いでしょう。

2. XBee ファームウェアのバージョンは?
>> http://funnel.cc/Hardware/FIO?userlang=ja
>> XBee無線モデムのファームウェアのバージョンを確認し、
>> 1.0.A.5または1.0.C.Dよりも古い場合にはX-CTUを使用してファームウェアを
>> アップデートする

(結論) >> XBee Config Tool で[Read] ボタンを押すと、表示されます。
 AT コマンド(ATVR) で調べることもできます。
 ファームウェアバージョンについては、最近購入したものであれば問題ないと思います。(Mac ではアップデートできなさそう)

3. XBeeConfig Tool は使えるの?Fio XbeeConfigTool とXBeeConfig Tool は何が違う?

>> http://arduino.cc/en/Main/ArduinoBoardFioProgramming
>> You can configure your radios using a terminal application,
>> or using X-CTU on Windows, or you can use the Fio XBee Config Tool.
>> This is a modified version of Shigeru Kobayashi's XBeeConfigTool.

(結論) >> この2つは同じものの様です。Funnelソフトウェアとして配布されているXBee Config Tool (のMac 版) は ver 1.0-r787 の場合、
funnel-1.0-r787/tools/XBeeConfigTerminal/application.macosx/XBeeConfigTerminal.app
にあります。付属のソースコード同士を比較しましたが、(空白や改行などの違いを除くと)Fio XBee Config Tool との違いは、ウインドウに表示される名称だけでした。
(Modify の結果が、Funnel の方にも取り込まれているようです。)

既に Funnel ソフトウェア をダウンロードしている場合は、あらためてFio XBee Config Tool をダウンロードする必要はありません。

4. XBee Config Tool の通信速度設定は?

(結論) >> 自動で設定されるようです。
XBee を57.6kbps にした場合と、9600bps にした場合と試しましたが、どちらでも大丈夫でした。

5. wireless bootloader が必要?

>> Wireless XBee/AVR Bootloading tutorial

(結論) >> 不要です。Arduino Fio を使う場合、この手順は読まなくて良いようです。


**********
実際の設定は

Mac で使うXBee モジュールの設定


Arduino Fio で使うXBee モジュールの設定

1. Serial Port を選択(XBee Explorer のポートを選択)
2. Mode を選択(Mac 側で使う方をProgramming radio に、Arduino で使う方をArduino Fio radio に)
3. Baud rate を選択(最近買ったものならATmega328 なので、57600 を選択)
4. PAN ID を設定(0000 からFFFF までの好きな値、2台とも同じ値にする)
5. MYID を設定 (0000, 0001 が自動でセットされるのでそのままでOK)
6. DLID を設定 (FFFF, 0000 が自動でセットされるのでそのままでOK)

選択・設定をしたら [Config] ボタンを押して書き込みます。
Arduino 側とMac 側と、別々の設定になるので、間違えないように印を付けた方がいいと思います。(MYID を書くと良いと思います。)

[ハードウェアの設定]


・Arduino Fio 側は、すでにジャンパがついていました。
・XBee Explorer 側は説明の通り、RTS とDIO3 をショートしました。

[Arduino IDE の設定]
・(Tools > Serial Port) XBee Explorer のポート(usbserial で始まる) を選択。
・(Tools > Board) Arduino Fio を選択。

あとは、Arduino Fio の電源をON にし、通常通りにアップロードすれば OKです。


いろいろと調べすぎてしまって大変でしたが、実際に必要な作業はとても簡単です。
同じ方法で、Arduino Uno + XBee Shield も試したのですが、こちらは上手く行きませんでした。(原因調査中)

2011年5月4日水曜日

Arduino Fio (導入篇)


Arduino Fio は「マイコンとXBee とリチウムポリマバッテリー(と adobe Flash)」の組み合わせを簡単にするために作られた、「Funnel I/O」というArduino 派生機種だったもので、現在は正式に Arduino ブランドとして販売されています。

細かい経緯はさておき、以前 XBee を買った際にこちらも買ってみました。
(予算がなくて追加の Xbee は買えなかったのですが、、、)

基本的な使い方は他の Arduino と同じですが、いくつか注意点があります。

1. Arduino には Arduino Uno などの5V 版と、Arduino Pro などの 3.3V 版があり、Fio は3.3V 仕様です。
2. USB 端子がありますが、電源(バッテリーの充電)専用です。通信機能はありません。


XBee 経由での書き込みはまたの機会にして、シリアルアダプタによる書き込みを行ってみました。


これは以前、別の要件で買った(そして使ってなかった)sparkfun のFTDI アダプタです。これを使ってみましょう。
FTDI アダプタも3.3V 仕様と5V 仕様があります。そして手持ちのこれは5V、、、

メーカーのサイトに説明がありますが、このアダプタはパターンカット&ジャンパ(ハンダでショートする)で 3.3V/5V 相互に変更可能です。
(もともと、FTDI のチップ(FT232RL) がそのような仕様になっています。)



しかし、また戻す事もあるかもしれないし、少し面倒、、、


ここで再検討。Arduino で使うATmega チップの電源仕様は1.8V 〜5.5V と広く、3.3V 版も5V 版も同じチップを使っています。じゃあ、5V で書き込んで良いんじゃないの?
ということで、パターン(→Schematic)を追ってみると、XBee モジュール(2.8 〜 3.4V)とバッテリー(3.7V) を外せば問題なさそう。

というわけで、5V で書き込み決行。


書き込みは、ヘッダピンを半田付けせず、押し当てる形で行いました。(これは公式ページにも書いてある由緒正しい方法です。)

試しにシリアルエコーバックのプログラムを書きこみ、そのままUSB 経由で通信を確認。
つづいて Firmata (StandardFirmataForFio) を書き込みました。
Fio 用のFirmata は先のFunnel のサイトからダウンロードできます。(Funnel は他にも便利なツールがあるので、別途紹介したいと思います。)

1.0-r787 の場合は、以下のファイルです。
funnel-1.0-r787/hardware/fio/firmware/StandardFirmataForFio/StandardFirmataForFio.pde

この回と同様、Pduino でXBee 経由の通信テストを行い、成功しました。


シリアルエコーバックプログラムの例
(シリアルの通信速度とXBee の通信速度を合わせます。Pduino 用に 57.6kbps にしているので、57600 になっています。)

//============================
void setup() {
Serial.begin(57600);
}
void loop() {
if (Serial.available()) {
Serial.print((char) Serial.read());
delay(10);
}
}
//============================


2011年5月3日火曜日

Arduino で OSC (無線篇)


OSC はEthernet を使った通信なので、無線LAN(WiFi) でも問題なく使用することができます。
iOS (iPhone)用のソフトも複数あります。

ここで、Arduino 用のWiFi シールドがあれば良いのですが、日本で入手できる(そして技適取得済みの)製品は現時点ではありません。
WiPort という製品(→Recotana さん)もあるのですが、結構高いですし、Arduino 用のライブラリもありません。

仕方が無いので、小型の WiFi ルーターを使ってみましょう。

機種の条件は
・有線LAN と無線LAN を変換するブリッジモード(無線LAN コンバーター)が使える。
・持ち運びが出来るよう、なるべく小型、低消費電力(バッテリーで動作させたい)。

以上を検討すると、ぴったりの製品があります。

Planex のCQW-MRB (現行品はCQW-MRB2) です。

これは USB のデータ通信端末をWiFi 機器で使うための、ポータブルルーターです。
なぜか有線LAN ポートも付いていて、バッテリー内蔵。しかもWiPort より安い。
(CQW-MRB2 が出たので、CQW-MRBは5000円以下で買えるようです。CQW-MRB2 は、低消費電力になり、バッテリ寿命が倍増(2時間→4時間)したようです。)

前回のLED 4つのサンプルを、iPod touch から操作します。
(OSC ソフトは Recotana さんの iOSC を使用。)
ネットワークはこのようになります。



かなり無理矢理ですが、一応バッテリーで動作します。
応用で、iPhone から赤外線リモコン機器を操作する装置などが作れます。
(据え置きルーターで充分ですが、、、)


動作の様子



おまけ:なぜか組み立てる所から撮った take 1




追記:コメントがあったので、iOSC のセッティング方法をまとめてみました。



Arduino で OSC (実践篇)


前回は IO_test_aduino を動かしました。
このサンプルでは OSC を送って LED をOn/Off しましたが、OSC で受信した値を使用していませんでした。
OSC アドレス「/ard/led」にデータを送ると、どんな値でも(値がなくても)、LED の On/Off を交互にします。

今回はより実用的に、「1」を送るとOn、「0」を送るとOff というようにしてみましょう。

Digital 出力の High/Low で、LED を点灯するだけなので、回路図は省略します。Digital2, 3, 4, 5 を使いました。
ネットワークの設定は前回と同じです。

受信した値を使用するには、受信したメッセージオブジェクトに対して、getArgInt() または getArgFloat() を送ります。
詳しくはこのサンプルを参考にして下さい。

File > Examples > OSCClass > example_OSC > simple recieve > Arduino_Server

今回は、Int で0 または 1 を送るので、その値を if で場合分けして、LED をOn/Off しました。
それぞれのポート毎に別のOSC アドレスを割り当てて、ledProcess() を以下のように変更しました。

void ledProcess(OSCMessage *mes, int port){

if(mes-> getArgInt(0)){
digitalWrite(port, HIGH); //LED ON
}else{
digitalWrite(port, LOW); //LED OFF
}

}
注意点
1. 前回同様、OSC アドレスの比較時に先頭の"/" を付けない事。
2. 原因はよくわからないのですが、second アドレスが3文字 (/ard/led) だと受信できないことがあったので、4文字 (/ard/led1, /ard/led2, /ard/led3...) にしました。

スケッチはこちらです。(サンプルスケッチの改変です。私の権利主張はしません。)

PureData (Pd_extended) でOSC を送信する場合、Toggle オブジェクトをつけると、元の動作と同様になります。

よろしければ Puredata のOSC 送受信サンプルもどうぞ。 →こちらから。

Arduino で OSC (応用篇)



以前、Ethernet Shield を使ったOSC の送信を紹介しました。
今回は同じOSC Library から、より実践的なサンプル 「IO_test_arduino」を使ってみましょう。

File > Examples > OSCClass > example_OSC > IO test > IO_test_arduino

このサンプルでは Pot (Potentiometer)、Switch の読み取り(OSC Send)と、LED の点灯(OSC Receive)を行うことが出来ます。

Pot はAnalog 0 に接続したボリューム(半固定抵抗)、Switch はDigital 3 に接続したスイッチです。LED はDigital 2 に接続します。

スイッチは1kΩでプルアップしています。(Arduino の内蔵プルアップ抵抗を使うとより簡単です。)上図では LED を High 出力のときONになるように接続していますが、プログラムではLow 出力のときON となっています。(On/Off が反転しています。)


Network の構成はこうなっています。


あとはOSC の送受信を行えば良いのですが、、、
今回もそのままでは動きませんでした。

1. コンパイルエラーが起きます。 > 前回同様、SPI ライブラリの追加が必要です。
2. OSC 受信ができません。(送信は問題なし)

OSC のアドレスを宣言する箇所と、loop の中で OSC アドレスを比較している箇所を抜き出します。

OSC アドレス宣言部

char *topAddress="/ard";
char *subAddress[3]={ "/led" , "/switch" , "/pot" };

受信OSC アドレス比較部

//osc arrive check
if ( osc.available() ) {
//toplevel address matching
if( !strcmp( recMes.getAddress(0) , topAddress ) ){
//second level address matching
if( !strcmp( recMes.getAddress(1) , subAddress[0] ) ){
ledProcess();
}
}
}


strcomp で文字列比較を行っていますが、getAddress(0)、getAddress(1) には"/" が付いていません。
手抜きですが、以下のようにしました。

OSC アドレス宣言部(修正後)

char *topAddress="/ard";
char *topAddress2="ard";
char *subAddress[3]={ "led" , "/switch" , "/pot" };

受信OSC アドレス比較部(修正後)

//osc arrive check
if ( osc.available() ) {
//toplevel address matching
if( !strcmp( recMes.getAddress(0) , topAddress2 ) ){
//second level address matching
if( !strcmp( recMes.getAddress(1) , subAddress[0] ) ){
ledProcess();
}
}
}


これで ledProcess() が呼ばれるようになります。
スケッチのダウンロードはこちらから。(サンプルスケッチの改変です。私の権利主張はしません。)

Pd extended と通信している様子です。Pot を回す、Sw を押すとき、それぞれ OSC が送られます。また、/ard/led にOSC を送るとled が点灯・消灯します。