DiaryException このページをアンテナに追加 RSSフィード Twitter

2010-12-31(金)

[][]Arduino + iPod touchで遠隔スケッチの反響

WebブラウザとArduinoに接続したグラフィックLCDで遠隔スケッチを書いて、まず、Makeプロモートして記事が掲載された。

Page not found | Make: DIY Projects and Ideas for Makers

ここまでは想定内だったが、意外に反響があった。

Arduino, iPod touch turns an LCD into a browser-based sketch pad (video)

no title

iPod touch and Arduino Create Remote Etch a Sketch – MacStories

iPod touch e Arduino se unem, viram uma ferramenta de desenho remoto | MacMagazine.com.br

no title

Control graphical LCD with iPod touch | Embedded projects from around the web

Blog - Electronics-Lab

iPod Touch e Arduino trasformano un LCD in un pannello da disegno [Curiosità] - iPhone Italia

何に使うものか(何のための設計か)が書かれていないという意見があるが、そんなアプリケーション自分で考えるものであって、発信者押し付けがましく述べるべきではないと思っている。説明書がない電子製品クールと感じるのと同じだ。

日本語ブログを書いているだけでは、こうはならなかっただろう。世界に伝えるためには、英語という道具は有効だと肌で感じた。

2010-12-25(土)

[][]WebブラウザArduino接続したグラフィックLCDで遠隔スケッチ

秋月グラフィックLCD(GLCD、バックライト付グラフィック液晶表示器 128x64ドット SG12864ASLB−GB: ディスプレイ・表示器 秋月電子通商-電子部品・ネット通販)を買ったので、GLCDをArduinoに繋いで、iPod touchで描いた絵を表示させるシステム作ってみた

iPod touchSafari上に表示したWebページのタッチイベントを読むことで絵を描く。イベントは通常のWebブラウザマウスイベントだと"mousedown"/"mouseup"/"mousemove"だが、iOSSafariは"touchstart"/"touchend"/"touchmove"となる。しかも、タッチイベントは同時に複数点で発生する事(マルチタッチ)が考慮されており、どのイベント採用するか決定する必要がある。今回は、シングルタッチによるイベントとし、最初に発生したイベントのみを扱う。タッチイベントが発生した点をプロットしていけば、絵になるという考えだ。

タッチイベントが発生した点の集合:点データはWebSocketを通してWebSocketサーバに送る。

次に、Arduino接続したGLCDを制御するプログラムを書いた。シリアルポートからデータを受け取り、それをGLCD上にプロットする。GLCDの制御にはKS0108 libraryを用いている。Ethernet Shieldを使ってもう少しネットワーク機器っぽくしてみたかったが、GLCDが使用するArduinoピンが多いので諦めた。Arduino Megaっぽいものがあればどうにかなるかもしれない。

最後に、iPod touchSafari上に表示したWebページから送られてくる点データを、Arduinoシリアルポート転送するWebSocketサーバPython/Tornadoで書いた。Arduinoとの通信にはpySerialを用いている。

解説文を含めた実演動画作成して公開した。

D

絵心があれば何か描けるのだろうが、デモにしてはインパクトの弱い(しかも汚い)手書き文字の描画にした。

2010-12-24(金)

[]コミケiOSアプリを販売する方法を考える

出来るだけコミケに限らず、手渡しによるiOSアプリの販売手法を考える。

Androidアプリであれば、Market未登録の野良アプリでもapkファイルCD-ROMに収録して販売/配布すれば、購入者各自のAndroid端末でSDカード経由などでインストール可能なので問題ない。

iOSアプリ場合、必ずiTunes Store経由でアプリインストールする必要があるので、こうはいかない。ユーザテストアドホック配布を用いるのは、購入者によるiPhone構成ユーティリティによるUUID参照と通知の手間、配布アプリのUUID登録数に上限があることなどがネックとなり、コミケでの販売手段として不向きだと考える。

その場でiPhone/iPod touchを借りて販売者のPCによりアプリインストールすることも不適当であるアプリダウンロードしたアカウントと紐付けられるので、販売者がダウンロード/インストールしたアプリを購入者が後日アップデートする場合は販売者のアカウントが必要となり、実質アップデート不可となるので(次回のコミケアップデート対応ということは出来るが)避けるべきである

思い付いたのは、iTunes Storeアプリ詳細画面にある「このAppを贈る」機能を使うことである

f:id:LaclefYoshi:20101224202313p:image

使ったことはないが、宛先のメールアドレス名前入力すれば、こちらがアプリの代金を支払う形となり、メールの受け取り側は無料アプリダウンロード出来るそうだ。

アプリ購入者にはコミケの会場でお金を支払ってもらい、メールアドレス名前を教えてもらう。手書きは誤字等トラブルになりそうなので避ける。予め名刺などを持参するよう呼び掛けるのも良いし、iPadで簡易入力フォームアプリを作ってテーブルに置いて入力してもらうのも良いだろう。後日、入力してもらったメールアドレス宛に、販売者から「このAppを贈る」で自分アプリダウンロードしてもらう。

大手でもなければ気にしなくてもいい事かもしれないが、その場でメールアドレス入力してもらうとなると順番待ちの列が出そうだ。

「このAppを贈る」には「ギフトメールで送信する」か「ギフト自分プリントする」という2つの手段が提供されているらしい。メールアドレスを聞かずに、予めアプリギフトコードプリントした紙を販売すれば、通常の販売と同様、列をさばくことが出来る。但し、メールアドレスを聞いて後日配布するのと異なり、アプリの販売数はプリントした紙の枚数と同一になる。「売り切れ」ならまだ良いが、「余り」が出てしまうと予めギフトとして購入したアプリの代金が無駄になってしまう(ギフトコードに有効期限はあるのだろうか?)。従って、購入者数の正確な読みが求められる。

アプリ購入者にはアプリを購入してから手に入れるまでの時間差が発生するが、コミケ限定の価格としiTunes Storeに登録した価格よりも安く売ればお得感を演出できる。あるいは、アプリ価格はそのままにして、購入時に特典(アプリではなく実際のもの。例えば小冊子など)を付加価値とする。販売者は予めにしろ後日にしろiTunes Storeに登録した価格アプリを購入する必要があるので、その販売段階では実質マイナスになるが、アプリ課金アプリを用いた活動で収入を得ることでマイナスを補うことが出来ると考える。あるいは、抱き合わせ販売によりアプリ単価より高い価格で販売することで儲けを出すことも出来るだろう。

ということで、コミケ限定アプリの配布は難しそうだが、コミケで販売を促進させるということは出来そうだ。

2010-12-18(土)

[][]Arduino+Ethernet Shieldでim.kayac.comにメッセージポストしてiPod touchで見る

前回(もう1年前だが)、Arduinoの状態をim.kayac.comに送信してiPod touchで確認する - DiaryExceptionでは、PCPythonスクリプト仲介にして、Arduinoの状態をメッセージとしてim.kayac.comにポストした。最近ようやくEthernet Shieldを購入し、色々と遊んでいる内に、PCを介さずにArduinoから直接im.kayac.comにメッセージポスト出来るようになった。


成果物は、Arduinoライブラリとして公開している。

ライブラリメッセージに文字数制限などを組み込んであるが、"Imkayaccom.h"等をちょっといじるだけで変更出来るので自由に使って欲しい。

実演動画も掲載。

D

複数のスイッチを並べて、スイッチ毎に違うメッセージポストする方が面白かったか

メッセージは"\n"(改行)を入れることも出来るし、固定文字列ではなくArduinoのある時点の状態を文字列としてメッセージとすることが出来る。デバイスとの対話のために適した道具になると思う。

実は、ArduinoからNotifoメッセージポストたかったのだが、NotifoAPIURLHTTPSで、ArduinoSSL通信をさせるのは酷だったので、やめた。im.kayac.comのAPIURLHTTPで、認証方式は複数の選択肢があり、まるでArduinoのためにあるのではないかと思うほど、使い易かった。

もし、何らかの理由でライブラリを用いることが出来ないなら、以下のコードを参考にArduinoコードに埋め込めば良い。

2010-12-13(月)

[]Google Chromeデフォルト検索google.comにする

google.co.jp検索日本語Webページが優先されてしまう。一部の分野では英語によって記述されたものが一次資料となる場合が多々あり、日本語による記述を優先していると発見が遅れてしまう。また、Google検索の新機能はgoogle.comでまず提供され、google.co.jpでの新機能提供は(ローカライズなどを経て)後回しとなることが多く、google.comに比べ機能的に劣る面がある。

Google Chromeアドレスバーを用いた検索は、日本語環境だとgoogle.co.jpによる検索になる。これを変更するには「環境設定」-「Default search」の[管理]ボタンを押す。「検索エンジンウィンドウ左下の[+]を押して、google.com検索を追加する。

f:id:LaclefYoshi:20101213123735j:image

名前キーワードは任意(僕は名前Google.com、キーワードgcにした)。URLは以下のものを入力する。

http://www.google.com/search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&q=%s

[OK]ボタンを押し、「検索エンジンウィンドウに戻る。

検索エンジンリストから、今追加したgoogle.com検索を選択し[既定にする]ボタンを押す。

ついでに、これまでデフォルトで使っていたgoogle.co.jp検索(名前Google)にキーワードを追加する(僕はgjにした)。

これで、アドレスバーを用いた検索デフォルトgoogle.comが用いられる。google.co.jp検索をする場合は、アドレスバーに先ほど設定したgoogle.co.jp検索キーワード(gj)を入力し、Tabを押してから検索語を入力する。

参考に、google.co.jpgoogle.comで「javascript」という検索語を用いて検索した結果を掲載する。

f:id:LaclefYoshi:20101213125406j:image

f:id:LaclefYoshi:20101213125405j:image

google.co.jpを用いた検索結果にはWikipediaのページが2つも含まれており、好ましくない結果となっていることが分かる。


余談。

google.com検索URLを以下のようにすると、reading level統計/フィルタ機能が使えるようになる。

http://www.google.com/search?{google:RLZ}{google:acceptedSuggestion}{google:originalQueryForSuggestion}sourceid=chrome&ie={inputEncoding}&tbs=rl:1&q=%s

2010-12-11(土)

[]ファイルシステム監視システム: inotify

Dropboxを使っていると、指定ディレクトリ以下に含まれるファイル更新(作成、削除、編集)される度にDropboxを通して複数のファイルシステムで同期される。各PCインストールされたDropboxデスクトップソフトファイルシステム監視しているらしい。

Linuxだと、inotifyを使うことによって、ファイル監視アプリケーションを作ることが出来る。Ubuntuだと、aptにlibinotifyとかinotify-toolsというものがあるので、それらをインストールすれば良い。

inotify-toolsをインストールすると、inotifywaitとinotifywatchというコマンドインストールされる。inotifywaitは指定ディレクトリ(指定を省略するとコマンドを実行したディレクトリ)内のファイル監視する。inotifywatchは指定ディレクトリ内のファイル監視した統計コマンドを終了した時に出力する。Dropboxの様に、ファイル監視更新の度に何かするには、inotifywaitを使う。

$ inotifywait -m -r TARGET_DIR  # -m = --monitor, -r = --recursive
Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.

## ls
TARGET_DIR/ OPEN,ISDIR
TARGET_DIR/ CLOSE_NOWRITE,CLOSE,ISDIR

## touch test
TARGET_DIR/ CREATE test
TARGET_DIR/ OPEN test
TARGET_DIR/ ATTRIB test
TARGET_DIR/ CLOSE_WRITE,CLOSE test

## cat test
TARGET_DIR/ OPEN test
TARGET_DIR/ CLOSE_NOWRITE,CLOSE test

## echo "this is a statement" >> test
TARGET_DIR/ OPEN test
TARGET_DIR/ MODIFY test
TARGET_DIR/ CLOSE_WRITE,CLOSE test

## mv test test1
TARGET_DIR/ MOVED_FROM test
TARGET_DIR/ MOVED_TO test1

## cp test1 test
TARGET_DIR/ OPEN test1
TARGET_DIR/ CREATE test
TARGET_DIR/ OPEN test
TARGET_DIR/ CLOSE_WRITE,CLOSE test
TARGET_DIR/ CLOSE_NOWRITE,CLOSE test1

## rm test
TARGET_DIR/ DELETE test

出力をCSV書式にするにはオプションに"-c"を加える。

$ inotifywait -c -m -r TARGET_DIR/

## ls
TARGET_DIR/,"OPEN,ISDIR",
TARGET_DIR/,"CLOSE_NOWRITE,CLOSE,ISDIR",

## touch test
TARGET_DIR/,CREATE,test
TARGET_DIR/,OPEN,test
TARGET_DIR/,ATTRIB,test
TARGET_DIR/,"CLOSE_WRITE,CLOSE",test

## rm test
TARGET_DIR/,DELETE,test

出力書式をもっといじるなら、"--format"と"--timefmt"オプションを使う。

$ inotifywait --format "%T %e %w%f" --timefmt "%Y-%m-%d %H:%M" -m -r TARGET_DIR/
2010-12-11 13:32 DELETE TARGET_DIR/test1

libinotifyをPythonから使うなら、python-pyinotifyというパッケージaptにあるのでインストールする。ライブラリ名はpyinotifyである。中身はctypesによるlibinotifyのラッパになっている。

pyinotifyを使ったコードを書けば、ファイルシステムイベント毎に何かさせることが出来る。例えばデスクトップ通知を出したりファイルを処理して何か出力したり

$ python pyinotify_test.py

## touch test1
create  /home/saeki/TARGET_DIR/test1

## rm test1
delete  /home/saeki/TARGET_DIR/test1

MacだとKqueueFSEventsを使えばinotifyと似たことが出来るようだが、簡単に使うためのツールは見つからなかった。

2010-12-04(土)

[][][]DeviceMotion Event/WebSocketを使ってiPod touchArduino操作する

WebSocketとDeviceMotion Eventで遊ぶ - DiaryExceptionで、iOS 4.2.1にしたiPod touchでWebSocketとDeviceMotion Eventが使えることが分かったので、HTML/JSを用いたアプリケーション(Webアプリケーション)から離れて、iPod touchからArduino操作するアプリケーションを考えた。

3章に分けて解説する。

設計

iPod touch (Webページ) <-WebSocket通信-> WebSocketサーバ <-TCP通信-> Arduino の、各要素間通信でやり取りするデータは、JSON形式によって記述する。

iPod touchSafariで表示するWebページにはボールがあり、色をフォームで赤/緑から選択する。ボールの位置は、iPod touchの傾き:DeviceMotion Eventから決定する。Webページはボール情報(色と位置)をWebSocket通信によりWebSocketサーバに送り、WebSocketサーバArduinoTCP通信でボール情報を送る。

ArduinoTCP通信のためにEthernet Shieldを接続し、WebSocketサーバから受け取ったボール情報可視化するためのマトリックスLED接続する。マトリックスLEDには8x8LEDを搭載し赤/緑の色が表示可能なBU5004-RGを用いる。LEDドライバにはMAX7219を2つ(赤用/緑用)を用いる。

f:id:LaclefYoshi:20101204095129p:image

実装

Webサーバ兼WebSocketサーバTornadoで書いた。Webページは"http://192.168.254.23:8888/"で参照し、WebSocketサーバには"ws://192.168.254.23:8888/ball"で参照する。

上記コードIPアドレス:"192.168.254.23"を持つPCで実行しておく。

WebSocketサーバは、Webページを読み込んだiPod touchからJSON形式のデータを受け取り、受け取ったデータをそのまま、Ethernet Shieldを積んだArduinoTCPパケットとして送信する。ArduinoIPアドレスとリスンポートは"192.168.254.100:9999"とした。

ArduinoTCPパケットを受信するために、Ethernet library(Arduino開発環境に標準搭載)を用いた。WebSocketサーバから受け取ったJSON形式のデータを処理するためにaJson libraryを用いた。また、MAX7219によるマトリックスLED点灯制御のためにMatrix library(Arduino開発環境に標準搭載)を用いた。

複数個のマトリックスLEDとMAX7219の配線、Arduinoとの配線はMatrix & Sprite Arduino Libraries, for a many-LED display!等を参考にすれば分り易い。

f:id:LaclefYoshi:20101203223605j:image

WebSocketサーバから受け取るデータには、ボールの色と位置が含まれる。ボール色はマトリックスLEDの点灯色とし、ボール位置から点灯させるLEDを決定する。iPod touchボールの位置はX方向で0から300、Y方向で0から336の値を取る。マトリックスはX/Y方向8個配置されており、0から7の値を取るので、組み込み関数mapを用いて調整する。

JSON形式のデータはaJson libraryによりparse、aJsonObjectから値を取り出す。

ArduinoEthernet Shieldを載せ、マトリックスLED接続し、LANケーブルを繋いでおく。上記コードArduino開発環境コンパイルして、Arduinoにuploadしておく。

WebページはDeviceMotion Event/WebSocketを用いるため、HTML5で書く。WebページがiPod touchSafariによって読み込まれた段階で、WebSocketサーバとの通信を確立し、DeviceMotion EventによりiPod touchの傾きを計測する。1秒毎にボールの位置を更新し、WebSocketサーバJSON形式でボールの色と位置を含むデータを送る。

Webサーバを兼ねているWebSocketサーバコードと同じディレクトリに、上記HTMLファイルを置いておく。

実演

$ ls
balls_canvas.html   balls_websocket.py
$ python balls_websocket.py
(Web/WebSocketサーバ待機中)

iPod touchSafariWebページを読み込み、iPod touchを傾けるとWebページ内のボールが動く。ボールの位置と色に合わせて、Arduino接続されたマトリックスLEDドットが動く(点灯するLEDが変化する)。

D

1秒毎の位置更新で、ボールの動きに滑らかさが欠けているが、あまり細かい時間で位置を更新するとArduinoの処理が追いつかず沈黙してしまうので、1秒とした。

おまけ

f:id:LaclefYoshi:20101202012909j:image

Arduinoコードの中に書いてあるが、MAX7219とマトリックスLEDとの配線を間違えている。

ユニバーサル基板でちまちま2時間くらいかけて半田付けして、こうもスパゲッティになってしまうと直す気にもなれず、ソフトウェア(コード)の方をハード仕様に合わせた。こういう柔軟性は、ソフトウェアの強みだろう。

2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2013 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2014 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2016 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2017 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
Connection: close