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

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-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-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サーバArduinoにTCP通信でボールの情報を送る。

ArduinoはTCP通信のために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を積んだArduinoにTCPパケットとして送信する。ArduinoのIPアドレスとリスンポートは"192.168.254.100:9999"とした。

ArduinoがTCPパケットを受信するために、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時間くらいかけて半田付けして、こうもスパゲッティになってしまうと直す気にもなれず、ソフトウェア(コード)の方をハードの仕様に合わせた。こういう柔軟性は、ソフトウェアの強みだろう。

2010-11-27(土)

[][]WebSocketとDeviceMotion Eventで遊ぶ

iPod touch(第2世代と第4世代)のiOSを4.2.1にアップデートした。Safari on iPhone & iPad 4.2: Accelerometer, WebSockets & better HTML5 support | Breaking the Mobile Webによれば、SafariのHTML5対応が強化されたらしい。

試しに遊んでみる。

WebSocketとDeviceMotion Eventの組み合わせに着目して、複数のボールがiPod touchのモーションによって動き、そのボールの位置がWebSocketを通してWebページを閲覧している全てのデバイスに通知/共有される、というシナリオを考えた。

図にすると以下のような感じ。1つのデバイスが1つのボールを制御し、WebSocketを通じて共有されるデータは「どのボールがどの位置にあるか」という単純なデータとする。

f:id:LaclefYoshi:20101127124936p:image

完成したものがこちら。

まず、1つのiPod touchとGoogle Chromeで同じWebページを開き、iPod touchでボールを動かした。WebSocketを通して、Google Chromeにもボールの動きが反映されている。

D

次に、2つのiPod touchとGoogle Chromeで同じWebページを開き、それぞれのiPod touchで別々のボールを動かした。左のiPod touchが赤ボールで、右が青ボール。WebSocketを通して、2つのiPod touchとGoogle Chromeでボールの動きが共有されている。

D

積んだ本の上にデジカメを置いて両手でiPod touchを操作する様子を撮るのは、結構大変だった (もうちょっと上手く撮りたかった)。

WebページはHTML5で以下のように書いた。ボールはもちろんcanvasで書いている (ただの塗り潰した円だけど)。WebSocketサーバが動いていない時の挙動など、エラー処理は省いてある。

Webページが通信するためのWebSocketサーバにはTornado (ver.1.1)を用いた。

Webページに直書きしてあるが、IPアドレスとして192.168.254.23を持つMacbookでWebサーバとWebSocketサーバを動かし、デバイスは"http://192.168.254.23/balls.html"を参照しWebページを開くと、"ws://192.168.254.23:8888/balls"で参照されるWebSocketサーバにコネクションを張る。WebSocketサーバがコネクション(Webページを開いているデバイス)を管理して、ある端末から送信されたデータを他の端末に転送する。

WebSocketはCometと比べて、ずっと簡単だった。

ところで、同じバージョンのiOSでも、出来ることと出来ないことがあってちょっと戸惑っている。Safariなら第4世代だとDeviceOrientation Eventが取れて、第2世代だと取れないとか。まあ古いものはどう頑張っても段々と時代遅れになるということらしい。

2010-11-20(土)

[][]GrowlメッセージNotifo転送するGrowlプラグイン

Apple Push Notification ServiceiPod touchで使っていると、何でもこれに集約したくなる。

最近、Twitterの公式アプリがPush Notificationに対応したし、Push Notificationに特化した(自分でメッセージを構築出来る)アプリには、im.kayac.comNotifoBoxcarProwlなどがある。

BoxcarとProwlには、自分のMacのGrowlメッセージ(Growlが外部のアプリケーションからイベントを受けて表示するメッセージ)を、Push NotificationとしてiPod touch/iPhone(勿論、BoxcarかProwlアプリをインストール済み)に転送/表示する機能がある。Prowlはそれを売りにしている。この機能は両者ともGrowlプラグインとして実装されている。自分のMacにこのプラグインを入れて、Macが動いている間、イベントを検出してメッセージ転送する仕組みのようだ。

Boxcarはアプリのインタフェースがイマイチで重い。Prowlは有料。どちらも使いたくない。

そこで、Growl Display Plugin Sampleを元に、Growlプラグインを作った。


このプラグインは、自分のMacのGrowlメッセージNotifo転送し、NotifoアプリがインストールされたiPhone/iPod touchメッセージを表示する。ほとんど同じコードim.kayac.com版も作れるが、まだ手を付けていない。

インストールには、ダウンロードしたzipファイルを解凍、あるいはビルドして得られた、"Notifo.growlView"をダブルクリックする。

設定は、全てGrowlのPreferencesパネルで行う。このプラグインは「表示オプション」タブで「Notifo」として表示される。ここで、NotifoのUsernameとAPI Keyを入れる。ラベルは、iPod touchメッセージ転送したときの接頭辞として使うオプション(日本語OK)。

f:id:LaclefYoshi:20101120134322p:image

全てのGrowlメッセージiPod touch転送して見たいとは思わないので、このプラグインを用いるアプリケーション、あるいはアプリケーションの中の特定のイベントについて、このプラグインを表示に用いる設定をする。「アプリケーション」タブで任意のアプリケーションの設定が出る。更に「通知」タブでイベント毎に表示を設定することが出来る。

f:id:LaclefYoshi:20101120134321p:image

後は、いつも通りアプリケーションを使っていれば、いつもGrowlメッセージとしてMacのデスクトップに表示されていたものが、Notifoを通してiPod touchに表示される。

f:id:LaclefYoshi:20101120134324j:image f:id:LaclefYoshi:20101120134323j:image

BoxcarやProwlは、Push Notificationと共にデスクトップにもGrowlメッセージを表示するオプションがあるようだが、まだGrowlの中身を熟知していないため、方法が分からなかった。また、優先度によってメッセージを表示するかを設定するオプションがあるようだが、これは必要性を感じなかったので省いた。

2010-07-06(火) つゆ!

[][][]weechatを使っていて、話しかけられたらiPod touchに通知する

WeeChat, the extensible chat clientはchat clientの1つで、僕は主にIRCクライアントとして使っている。weechatと同様CUIのIRCクライアントで有名なものにはno titleなどがあるが、weechatはGTKによるGUIもある(らしい/使ってない)。

weechatはPythonやPerl、Ruby、Lua、Tcl(!)でプラグインを書くことが出来、WeeChat :: scriptsに既に便利なプラグインが幾つか登録されている。

僕も先日、notifo(iPod touchにPush Notificationを送るサービス)を使ったnotifyプラグインをPythonで書いてweechatチームに送り、無事Script: notifo_notify.pyとして公開してもらった。

簡単に使い方を書いておこう。

他のプラグインと同様、autoloadディレクトリに入れていないプラグインは、スクリプトがある場所を指定し手動でロードする。

f:id:LaclefYoshi:20100706211906p:image

初期状態だと、notifoAPIを使うためのユーザ名/API Secret(notifoにログインしてSettingsの頁に書いてある)が設定されていないので、色々とメッセージが出る。

f:id:LaclefYoshi:20100706211908p:image

そこで、メッセージに従いプラグインの設定を記述、保存する。

/set plugins.var.python.notifo_notify.username HOGE
/set plugins.var.python.notifo_notify.api_secret XFOOBARX

一度設定すれば設定は保存されるので、再起動時でも2回目以降のプラグインloadingではメッセージは控えめになる。

f:id:LaclefYoshi:20100706211907p:image

IRCなどで他人と会話をしていて、他人のメッセージに自分のユーザ名が含まれているなど、weechatでhighlight設定をした単語が含まれるメッセージが届くと、notifoを通じて自分のiPod touchにそれが通知される。

f:id:LaclefYoshi:20100706211909p:image

f:id:LaclefYoshi:20100706211903p:image

あるいは、private messageを受け取った場合(IRCでは/query)にも、同様に通知される。

f:id:LaclefYoshi:20100706211905p:image

f:id:LaclefYoshi:20100706211904p:image

本にゲームに論文に、iPod touchを見ている時間がそれなりにあり、きっとiPadを買ったらもっとMacbookを見る時間が減るのではないかとも思うが、このようにPush Notificationで何か(なんでも)を知らせる設定をしておけばうっかりミスは減るだろう。notifoには何時間何分後に知らせてくれるTimerのオプションもある。

2010-06-18(金)

[]iPod touchでPush Notification Serviceによる通知を活用するためのサービス

im.kayac.com

サービス登録後、iPod touch/iPhoneに専用アプリを導入し紐付けることでPush Notification通知が有効になる。

APIが公開されており、任意のプログラムから叩くことで自分宛の通知を自由に送ることが出来る。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import hashlib
import urllib

IMKAYACCOM_USER = "YOUR_USERNAME"
IMKAYACCOM_SECRETKEY = "YOUR_SECRETKEY"

## im.kayac.com

def post_imkayaccom(message, handler=None):
    # handler: "Custom URL Scheme" / e.g. http://***, skype:***
    url = "http://im.kayac.com/api/post/" + IMKAYACCOM_USER
    signature = hashlib.sha1(message+IMKAYACCOM_SECRETKEY).hexdigest()
    opt_dict = {"message": message, "sig": signature}
    if handler is not None: opt_dict.update({"handler": handler})
    opt = urllib.urlencode(opt_dict)
    res = urllib.urlopen(url, opt)
    print res.read()

msg = u"こんばんは、奥さん。".encode("UTF-8")
post_imkayaccom(msg, "http://komachi.yomiuri.co.jp/")

notifo

登録、iPod touch/iPhoneに専用アプリ導入、と使い方はim.kayac.comとほぼ同じ。

im.kayac.comと違い、サービスに登録すると、指定時間に通知するサービスや株価が指定の値になると通知するサービス、Twitterでreplyがあると通知するサービスなどを利用することが出来る。Boxcarというアプリもプラグインを導入することで同様のPush Notificationを実現しているが、notifoWeb上でサービスの設定(有効/無効、時間/しきい値指定など)をする。また、通知ログもサービス上に蓄積される。

APIの使い方は、im.kayac.comと違うところはBASIC認証をする必要があるところくらい。

#!/usr/bin/python
# -*- coding: utf-8 -*-

import urllib
import urllib2

NOTIFO_USER = "YOUR_USERNAME"
NOTIFO_API_SECRET = "YOUR_API_SECRET"

def post_notifo(message, handler=None, label=None, title=None):)
    # handler: "Custom URL Scheme" / e.g. http://***, skype:***
    # label: name of service
    # title: title of event
    url = "https://api.notifo.com/v1/send_notification"
    opt_dict = {"msg": message}
    if handler is not None: opt_dict.update({"uri": handler})
    if label is not None: opt_dict.update({"label": label})
    if title is not None: opt_dict.update({"title": title})
    opt = urllib.urlencode(opt_dict)
    req = urllib2.Request(url, opt)
    basic = "Basic %s" % ":".join([NOTIFO_USER, NOTIFO_API_SECRET]).encode("base64").strip()
    req.add_header("Authorization", basic)
    res = urllib2.urlopen(req)
    print res.read()

msg = u"こんにちは、二次元。".encode("utf-8")
post_notifo(msg, "http://jun.2chan.net/", label="Python", title="I sent it!")

GitHubには、notifoによるPush Notification機能が付いたらしい

APIが公開されているということで、インターネット上の何かの変化に限らず、Arduino(センサ)と組み合わせたりWebカメラと組み合わせたり、現実世界の様々なものの変化を(iPod touchを通して)自分に伝えるために適した道具になる。昔のCMに、実家の母が使うポットにセンサが取り付けてあり、使用状況を離れた場所の息子が携帯電話を通して知る、というような商品の紹介があったが、まさにああいう使い方も良いだろう。

過去に皆が夢見たユビキタス環境のイメージ映像では、ウェアラブルデバイスとしてヘッドマウントディスプレイが人の顔に装着されていて、何か(友達が近くにいる、友達が呼んでいる等)あれば目の前にメッセージが通知されていた。ゲームをしていてもスリープ状態にしていても通知がやってくるPush Notificationはこの環境の実現の第一歩だ。

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 |