2015年1月22日木曜日

そして、部品沼は淀む

Google Spreadsheetを使って「次に通販で頼む品物」などをメモしてます。これは秋月用のページ…


で、ある程度の金額になるか、急に欲しい必要なものが出てきた時には型番をコピーして…


ペーストすれば…


発注できてしまう…

便利すぎて困っちゃう…

2015年1月21日水曜日

Ember+Bootstrap3でナイスなモーダルダイアログを

なんだろう、この「居るよね、こういう奴」感w

…出そうとしてハマった記録です。

■公式ページ■

USING MODAL DIALOGSというページがあるのですが…この通りやっても動きません。何で動かなかったのかはこれから調べるんですが…とにかく、下の方にあるサンプルコード表示窓から正しくコピペしても動きません。ああもう、何時間ツブしたんだよorz

■ここがバッチリ■

で、どうにかならないかと探して出てきたのがここ。
  MASTER YOUR MODALS IN EMBER.JS
ember modal dialogで探すと2番目に出てくるんですけどね。ともかく、テキスト読みながら、必要なhandlebarsを補っていけば、ちゃんと動きます。bootstrapのfade dialogも効いて、ズルっとダイアログが出てきた瞬間「やったー!」と大声を上げてフロアの人の注目を浴びてしまいました。

なお、コピペで動かない場合には、一番下にサンプルコードのページがありますので、そちらを使ってください。自分でコピペしたものと比べると間違いがよくわかります…私のように。

ステップバイステップでコードの意味が解説されているので改造も簡単だし…今後はここで勉強しようっと>ember guru

■{{outlet}}について■

Emberを扱い慣れている方には当たり前のことなのだと思いますが、ググってもすぐには出てこなかったことなので説明しておきます。

ご存知の通りEmberはone page htmlをWebアプリを作ることができます。その際、一度に表示されるのは
<script type="text/x-handlebars">
で示されるテンプレートで区切られた範囲です。ただ、通常のWebアプリではツールバー、フッター、サイドバーなど共通の要素が多いです。そういうのをいちいち、各テンプレート内に置くのはあまりにもダサいです。こういう場合には、
<script type="text/x-handlebars">
  {{toolbar}}
  {{outlet}}
  {{footer}}
</script>
のようにして外側を定義します。ここでは data-template-name が指定されていませんが、なしだとアプリケーション全体で共通して【外側】として扱われ、遷移したページは勝手に {[outlet}} のところに挿入されます。

…知りませんでした。

知らなかったので【内側】の部分を全部コンポーネントで作って {{yield}} で挿入していました。ははははははははははははh orz

また、
{{outlet}}
{{outlet "modal"}}
と並べて書いておけば、常時outletに【内側】のページが表示され、指示をすればその上にモーダルダイアログが表示されます。overlayに関するスタイルなどは勝手にemberが面倒を見てくれます(サンプルではbootstrapが装飾してくれています)。以下のコードは、ダイアログを開くためのボタンで、
<button {{action 'showModal' 'settings-modal' model}}>settings</button>
そこから呼び出されるのが以下の関数です。
showModal: function(name, model) {
  this.render(name, {
    into: 'application',
    outlet: 'modal',
    model: model
  });
}
結果として {{outlet "modal"}} に、'settings-modal'というコンポーネントが表示されます。くどいですが、outletは予約語、'modal'は名称です。

■data-template-nameなしと"index"指定■

ついでに <script type="text/x-handlebars" data-template-name="index"> に関しては「何も指定しなければ初期状態で表示される」ぐらいしか書いていないのですが、これと data-template-name なしのhandlebarsとの違いは、なしは外側ページ、data-template-name="index"アリは外側ページのoutletに初期表示されるテンプレート、っていうことになるようです。

蛇足ですが、なしだとApplicationController、アリだとIndexControllerがcontrollerになります。暗黙の了解が多くて悩むことも多いのですが、わかってしまえばスッキリですね。

なおjsbin.comを使うと、アトリビュートを削ったり {{outlet}} を足したりした結果が即座に反映されるので、とても勉強になります。ぜひご自身の目でお確かめください。

さーて、明日はAuthenticationを調べて、その後は無限スクロールをpromiseとbootstrapを使って実装してみます。このペースなら、予定通り今週中に開発中のアプリに必要な技術要素をだいたい網羅できそうだなぁ。

いやはや…@53歳。

2015年1月20日火曜日

Ember.jsで初心者が落ちた穴

Building Web Apps with Ember.js [Kindle版]

大変、頼りになります。

Emberを使ってハマったネタを集約しておきます。まぁ、わかってしまえば「ドキュメント読めよw」って感じなんだけど…チュートリアルの更新が追いつかなかったり、暗黙の設定が若干進みすぎ気味のframeworkなので、自分が落とし穴に落ちていることすら気づかないこともあるので。
  1. Routingを呼ぶ #linkTo は #link-to に変わりました。
  2. handlebarsの id は id から data-template-name に変わりました。
  3. コンポーネントの名前は、必ずダッシュを含む必要があります。
    data-template-name="side-bar"
    みたいな感じで。ダッシュ取るとエラー出ませんが、動きません(記事)。

Ember.jsのコンポーネントを使う

こんなにでっかく書いてあるのにorz

昨日はEmberのコンポーネントを使おうとして見事にハマりました。

結論から申しますと、コンポーネントの名前は、ダッシュで切らないといけません。公式のGUIDEにも書いてあります。しかし、そこに気付かなかったために3時間ツブしました。フレームワークを再ダウンロードしたり、ページ上で読み込む順番を変えたり、もう思いつく限りの試行錯誤をしたけど動かない。あげく、チュートリアルの関連コードを貼ってみたら動いてしまう。で、何度目かにようやく「コンポーネント名は、ダッシュを含まないとあかんよ(Components must have a dash in their name.)」の記述に気づいた次第。動いたさ。ああ動いたさ。

なお、ハマったネタとして、こっちにまとめておきます。今後、ネタが増えないことを祈ります。いやマジで。とりあえず、ChromeのEmber Inspectorを試してみます。

以下余談。

MVCとしてのEmberは大変良く出来ています。サイズはやたらデカいのですが、実際に走らせてみると表示はむしろ他のMVCフレームワークよりも速く、特にどこかEOF(NeXTSTEPのEnterprise Object Frameworkなんて知ってる人いるかなー)を思い出させるようなオブジェクトの連携に関しては重いという感じがありません。設計思想もCoCが徹底されていて余計な設定やらBoilerplateな記述はほとんど必要ありません(まぁ「暗黙の設定」が多すぎて、それでハマることも多いんですがw)。

が。

どっかでも批判されていましたが、ドキュメントの更新が追いついておらず、公式サイトでもチュートリアル本文とサンプルコードが一致していなかったり、CoCなのに重要なアトリビュート名が変わったりで「もう誰も信じない!」な状態に陥ることもあります。

#linkToが#link-toに変わったこととか、idがdata-template-nameになったり。上記のリンクを含めて本家のサイトでもバラバラだし、日本語の解説ページで一番充実しているDevelopers.ioのこの入門シリーズにも反映していただけるとありがたいのですが…。

…まぁDevelopers.ioで一番改めてもらいたいのは、あの歯茎だけどね。とにかくバナーの写真のお前らはこっち見るなw

…それはともかく…ドキュメントはしっかり読みましょう。少なくとも「Note」ってところぐらいはね。

2015年1月17日土曜日

SOP-28ピン(過去最多)のリフロー

これは成功した方。フラックスが汚い。

久しぶりにはんだリフロー。antendoのハンダメッキ基板にSOPの28ピンという過去最多のピン数でしたが、2枚に行って1勝1敗でした。

なるべくペーストの塗布を少なくした方が2箇所もブリッジして失敗し、多めに盛った方が成功という不思議な結果でした。足のまわりをルーペで見ても問題ないので、プラスチックパッケージの下でブリッジしているんですかね。フットプリントにはみ出した分の拭き取りが甘かったかもしれませんが、品質管理(w)の基本である証跡(塗布してパッケージを乗っける前の写真)を撮り忘れたのが致命的でした。

なお、塗布には例によってマイナスドライバーを使いました。写真のように、盛大にはみ出してはいるのですが、塗った後、パッケージと基板に挟まる部分については拭き取りました(つもりだった)。

使用機材は1200wのホットプレートと、放射温度計です。どっちもアマゾン。ハンダは共晶ハンダを使っています。換気のため、台所の換気扇の真下で作業を行い、窓を一箇所、細く開いて循環性を高めます。

温度制御は例によってまったくの手動ですが、こんな感じ:

  1. 予熱して150度前後になったら電源を切り蓋をし、2-3分放置。
  2. 温度を測定して140-160度ぐらいの場所を探して基板を置く
  3. 蓋をして1分間放置(この間電源はOFF)
  4. 蓋を開けてヒーターON
  5. 基板周辺の温度が230度を超えないようチェック
  6. 超えたところでヒーターをOFF。その後も温度は上昇を続けるので、それを見越して早く切るわけです。何度で切るかは使っているホットプレートや置き場所、室温によっても違うのですが…基板を乗せない状態で何度も試して「この温度で切れば250度を越えない温度」を求めておきます。うちの場合、それが230度でした。
  7. ハンダが溶けてきます。基板の上の温度などもチェックして230度を超えているようなら問題なし、なるべく早く冷ましましょう。と言っても、取れる手段はうちわで扇ぐぐらいしかないんですが。
  8. ハンダが固まる温度を下回ったら、素早くピンセットなどで基板を取り出します。

以下、役に立たない写真です。


aitendoのLEDドライバ基板

1枚目。塗布後。

冷ましているところ。検査の結果は2箇所ブリッジ

2枚目。手が滑って落ちた。汚え。

位置を直した。やっぱり汚え。でも結果は正常だったからイヤになる。
まぁ、そんな感じで。

3Dプリンタならぬ、プリント基板プリンタがKickstarterとかに出ているみたいですが、いくらぐらいなんでしょうねぇ。最終的に焼結する必要があるみたいですが、表面実装部品もそのときついでに焼付けできる=スキージングが要らなくなるのであれば少し高くても欲しいのですが。

2015年1月12日月曜日

Play!アプリとBoneScriptの通信 - 3.BoneScript

「BBBとは?」みたいな余計な説明がなくて中身が濃い。

というわけで、Play!アプリとBoneScriptの通信、完結編です。

  1. 構成
  2. Playアプリ
  3. BoneScript

■BoneScript■

以前、BoneScriptで7セグメントLEDを駆動したら、毎秒170桁しかダイナミック点灯させることができずにちらつきました。その際には各セグメントのon/offもループしていたのでおよそ毎秒7x170回はループしていた、ということになります。ダイナミック点灯は無理でも毎秒10回程度のサンプリングなら余裕ですね。8bit時代のBASICマイコンで空のFOR〜NEXTループを回すと250回ぐらいだったかなぁ(遠い目)。

ということで、以下ソースです。


特に目新しいことはしていません(できません)。line 11で100m秒ごとのインターバルを設定してchechPIRを呼び出し、digitalReadのコールバックとしてprintStatusを呼び出しています。

printStatusでは100m秒ごとにサンプリングして入力がHIGHならcountDetectedをインクリメントし、「1分間のうち何秒間、PIRセンサがHIGHを返してくるか(なおPIRセンサは負論理で動きを検出するとLOWになるのですが、トランジスタでレベル変換した時に正論理に変わってます)」を求めています。結果はCSVとしてファイルに書き出し(line no 56 - 62)、JsonとしてWeb APIに送っています(line no 64 - 94)。

その処理自体は簡単なのですが、起動直後の中途半端な「分」を無視したり(prevMinute==99)、「睡眠記録」として作ったので昼の12時でファイル名が切り替わるようにしたりで(line no 44 - 54)、ちょっと面倒になっています。

なお、日付書式の変換には下記で公開されている「formatDate」を使わせていただきました。ありがとうございます。上記ソースを試す場合には末尾にformatDateをコピペしてください。
Qiita : 日付フォーマットなど 日付系処理

■今後の予定■

現状ではセンサーを追加したらDBの定義からやり直さなければいけないですが…それはなんぼ何でもIoTっぽくないので、定義を抽象化するなりシリアライズして「思いついたらすぐセンサーを追加してグラフ化」という路線を目指してみましょうか。

そういえばXivery申し込んだんだけど、返事が来ない…まぁXiveryを使っていたら、Play!でグラフ化するなんてことをやろうとは思わなかったでしょうから、むしろ感謝すべきかなw

2015年1月11日日曜日

Play!アプリとBoneScriptの通信 - 2.Playアプリ

もうこの本なしでは行きていけない(Play的に)

というわけで、前回の続きです。

  1. 構成
  2. Playアプリ
  3. BoneScript

■機能■

  1. Webページ
    1. ログイン
    2. グラフ表示
  2. Web API
    1. ユーザ登録 / 更新
    2. データ受信
    3. データ返信
こんだけです。ユーザ登録もAPIで済ませてます…まぁ自分用なので。

■githubリポジトリ■

公開しました。TareObjects/ShowSensorsです。

■ダメなコード■

公開してから気づいたのですが、System.outがそのまま残っていますねぇ…お恥ずかしい。一度必要なところはログに書き換えたのですが、余計なことをしてroll backかけた際に巻き添えになり、また書きなおすのも面倒なのでそのままに。

そのうち直しますm(_ _)m。

Calendarを定義しているところでやたらと
calFrom.set(Calendar.MILLISECOND, 0);
ってのが出てきます。不要なところもあるのですが、ミリ秒単位に初期化されていない値が入ってて一致しない、というバグでしばらく時間を潰してしまったので、それ以来入れてます。まさにあつものに懲りてなますを吹くってやつですねorz

■一応、Playプロジェクトを作るところから■

コマンドラインで
$ activator new ShowSensors
を実行し、プロンプトでplay-javaテンプレートを選択します。できたら
cd ShowSensors
activator run
これでアプリに必要なライブラリなどが自動的にダウンロードされ、ビルドされます。メッセージが落ち着いたらブラウザで http://localhost:9000 を表示するとplay!の画面が表示されます。なお、この画面は、conf/routesの

GET     /            controllers.Application.index()
public static Result index() {
return ok(index.render("Your new application is ready."));
}
及びapp/views/index.scala.html, app/views/main.scala.htmlから生成されています。

■Playプロジェクトにソースを追加する■

Play!は「設定より規約」なので、所定のディレクトリにファイルを作れば、あとは勝手にactivatorが認識してくれます。ただ、vimだけで作業している分にはそれでも問題ないのですが、Eclipseで作業する場合にはコマンドライン側でソースを追加した後、一度Eclipseを終了してから
activator eclipse
でeclipse用の設定を更新し、Eclipseを起動してからプロジェクトを右クリック→Refreshをする必要があります。

また、通常はactivator runしたままで作業を続けられるのですが、build.sbtなどappディレクトリの外にあるプロジェクトの構成に関する部分を修正した場合には、一度activatorを終了してから再起動し、activatorのプロンプト上で
update
eclipse
clean
run
とします。cleanは省略しても良いはずですが、一度ハマったことがあってそれ以来念のため実行するようにしています。

■モデル■

今回、persistentにはEbeanを使います。Springにはいい思い出がないのと、せっかくPlay!がCoCなのにXMLでチマチマやってられっか、ってことでw

モデルはデータベース用とWeb API用が必要です。データベース用はUser.javaとSensorData.java、Web APIとして返すJsonの定義にSensorDataRest.javaです。

いずれも特別なことはしていませんが、SensorData.javaでMany to Oneリレーションシップを定義する際に通常はpublicでインスタンス定義すればそれでOKなはずですが何故かうまく動いてくれず、ググったところ「play!のバグじゃね? アクセサにしたら動いたよ」とのことで、回避できました。

ソース:

それにしても、こんな風にクエリを書けるのは、ホントに楽です。S2JDBCを更に洗練した感じで、今までEOFのEOQualifier最高!と思っていましたが、宗旨替えします。


■ユーザ登録/更新■

Application.javaのnewUser()、フツーです。


■データ受信■

Application.java、receive()。curlをそのままソースに貼っておくと手動テストが楽ですが、こうやってコピペに頼るからいつまで経っても覚えないんですよね…。


■データ返信■

データを返すAPIとして、GET用とPOST用を用意しました。こっちはGET用です。


■認証■

人生で大事なことはタイミングにC調に無責任、と歌ったのは今は亡き植木等師匠ですが、Playでの認証機能に最低限必要なのは、ログインのためのフォームとAuthenticatorの実装、あとは認証の必要なAPIに@Security.Authenticated(Secured.class)アノテーションを付けてやるだけです。

詳細についてはこちら(「認証機能の追加」)…というか、ほぼここからコピペして使ってます。

■データ表示■

Playとしては、Application.javaで単にgraph.scala.htmlを返しているだけです。

で、そのgraph.scala.htmlではD3.jsを使って、PlayアプリのWeb API(上記「データ返信」のところ)からデータを読み込み、グラフを描画しています。以下はデータを読み込んで15分ごとの平均値を求める処理です。平均値なんてサーバ側で求めたほうが良いと思うのですが、動かしてみたら思っていた以上に速かったのでそのままにしていますw なお、念のためですが、これだけでグラフが出るわけでなく、この後に縦軸横軸などの設定が続きます。

■次回は■

いやー、ほんとにサンプルを切り貼りしただけで何にもしていないのですが、でも1つにまとめて動かすのにホント苦労しましたわ。

さて、次はBoneScriptを公開します(しました)。明日の予定です…三連休で良かった。

gist、知りませんでした…

大掃除の成果

今までここにソースを貼るときには、手動でソースを成型して書式を設定してました。貼った後で改行が崩れていたりするとまたそれを治すのが面倒で。

が。gistって便利っすね…何の手間も要らないっすね…。

ということで、途中まで書いてたPlay+Bonescriptの件、現在修正中です。

2015年1月10日土曜日

Play!アプリとBoneScriptの通信 - 1.構成

余分なジャンパが苦闘の痕跡を示すのだった

表題の通り、PIRセンサーの状態をBeaglebone black上のBoneScriptで読み取ってHeroku上のPlayアプリへ送り、D3.jsを使ってグラフ表示する方法をまとめました。

  1. 構成
  2. Playアプリ
  3. BoneScript

■アナログは苦手■

前回の記事の後PIRセンサの調子が悪くなってしまい、対応に追われました。どうもPIRモジュールの温度特性が良くないようで、プルアップ抵抗などを調整してうまく動くようにした後、外出や就寝で暖房がきれると徐々に特性が悪化してしまいます。

今回使っているPIRの最終段はオープンコレクタなのですが…コレクタ側に100Ωの保護抵抗が入っているためlowでも電圧がすっきり落ちてくれません。プルアップで調整するのも面倒になってきたので、これは2SC1815でバッファ入れて解決しました。ベースを10k、コレクタを1kΩで3.3vからプルアップし、エミッタをGND、コレクタからBBBのGPIOにつないでます。



あともう一つ、PIRからのノイズなのか、そのままだとGNDに200mVぐらいのスパイクノイズが乗ってしまってます。これも使い始めたころはなかったのですが、室温が15度を切るようになったから悪化したように思います。なので、4.7μFのケミコンと0.1μのセラコンを入れたところ見違えるように安定しました。

いやはや。

■ハードウェア構成■

センサには秋月の焦電型赤外線センサモジュールを用い、Beaglebone blackの5v電源出力とGNDを接続、上記回路で安定させてからBBBのP8_19に接続しています。非常に単純です。

なお、別のところでも書きましたが、最初は以前秋月で売っていたParallaxのPIR Rev.Aを使ってみたのですが…室内での人の動きと無関係に信号が出ていて、どうやっても改善しなかったので諦めました。現在秋月での扱いが終了しているのは、何か問題があったからではないか?と邪推している今日このごろ。貧乏サラリーマンの数百円を無駄にした恨み、思い知るがいい(違

■まずPlay側■

あっちこっちのサンプルの寄せ集めですが、こんな構成になっています。
controllers---Application.java
              Secured.java
models--------SensorData.java
              SensorDataRest.java
views---------graph.scala.html
              index.scala.html
              login.scala.html
              main.scala.html
Secured.javaなんてファイル名はまさにこのサンプルそのまま、笑ってやってください。

このアプリをHeroku上で稼働させています。データベースには同じくHerokuのPostgreSQLを用いています。どっちも無料枠内。PaaS万歳。

グラフ表示アプリには必要最小限の認証を付けました。でないと「留守・就寝中を世界に向けて発信する」アプリになってしまいますので。

グラフの表示にはD3.jsを使っています。ブラウザ上のD3からPlayアプリのAPIを叩いてJsonで過去24時間分の1分ごとのデータを受け取り、15分単位に集計してグラフを表示します。

■BBB側■

Beaglebone black Rev.Cはほぼ素のママで、BoneScriptを動かしています。0.1秒ごとにサンプリングして1分間のうち何秒間センサが動きを検出したかを集計し、1分ごとにHeroku上へとJSON形式のデータを送っています。

今のところ、送信エラー時のリトライは行っていません。Herokuは24時間に一度勝手にインスタンスがリスタートするので、エラーが出たらバッファにためといて再送するような仕組みを入れておくべきなのですが…。

■次回■

Play!のソースについてご説明します。公開しました。

2015年1月6日火曜日

Energia + MSP430G2でのハマりポイント

そうさ、またデジタル時計さ。MSP430G2553+RTC+秋月巨大LED
小数点のポートはデバッグ用に使用中

■UART関連■

同じG2でも、UARTのTxとRxが逆になっているものがあるので気をつけましょう。2553でもRevision 1.4以前とRevision 1.5は異なります。これはLauchPad基板のジャンパで切り替えるようになっています。

Guide to the MSP430 LaunchPad (MSP-EXP430G2)

シリアルモニタでLaunchPadからSerial.write / printで出力されてくる値を見るにはTxを使うのですが、ジャンパが違っていると書き込みできません。Energiaからの書き込みは正常にできるので、てっきり正しくつながっているものと思い込んでいたら、違いましたorz

■sprintfがクラッシュ■

複雑な書式指定をするとメモリ領域がメチャメチャになってクラッシュします。小さなプログラムだと通っちゃうことが多いのですが、10KBを越えるようなプログラムで、例えば、
sprintf(buf, "%02d%02d%03d%d", h, m, t1, t2);
とやると、以下のような症状が出たりします。

  • bufに値が入らない
  • 数秒ごとに繰り返しsetupが呼び出される
  • シリアルポートが文字列の途中でぶっちぎれる
  • 一度電源引っこ抜かないとEnergiaから書き込めなくなる


解決策としては、バッファとして使うメモリにvolatile指定を行い、sprintfの書式、特に数値変換については極力単純にして、あとは(上の行と同等のことをするには):
volatile char buf[16],temp1[16], temp2[16];
sprintf((char *)temp1, "%d", 10000 + h*100 + m);
sprintf((char *)temp2, "%d", 10000 + t1*10+t2);
sprintf((char *)buf, "%s%s", (char *)temp1+1, (char *)temp2+1);
で1つにまとめます。temp1,temp2を+1しているのは最初の'1'をスキップさせる古いc言語のテクニックです(懐かしい…)。

■MSP430G2553について■

これ温度センサー内蔵なんですね。analogRead(TEMPSENSOR)使うと華氏*10で返ってくるので、楽です。ワンチップで温度計作れます。我が家の他の温度計とも誤差1度以内なので、まぁ合っているんだろうなぁ、みたいなw

で、巨大LEDですが…3.3v駆動+PWMで制御しているのをいいことに、電流制限抵抗なしでつないでます。良い子は真似してはいけません。

さて、あとはRTCとの接続か…。

一応Xtalを外付けしてオープンソースのライブラリをつかえばリアルタイムクロックとしても動くのですが、年月日まで管理してくれないのでその辺を自前で実装するのが面倒くさい。かといって、RTCについても以前RTC-8564NBをArduinoにつないだときのソースを探すのが面倒くさい。

昨日今日とsprintfで全能力を使い果たしてしまったので、まぁそのうち元気が出たら作ります。

私を何より元気にするのは現金なんすけどねw

■追記■
これをデジタル時計として動くようにしました。ソース公開してます。予定ではRTCチップを外付けする予定でしたが、水晶発信しだけ外付けして使いました。