Pages

2015年12月27日

ESP-WROOM-02でYoを送るボタンを作ってみた

今年の夏からESP-WROOM-02で色々やっているけど、よく考えたら公開できるものを何も出してなかったので簡単なものを作ってみたり。

ボタンを押すとYoが飛ぶ、という単純明快なボタンです。
誰かにYoを送るも良し、自分のusernameを設定しておいて呼び鈴にするも良し。
Li-Poと充電回路を内蔵しているので、完全ワイヤレス動作も可能。


ESP-WROOM-02周りの回路はこんな感じ。(レギュレータとLi-Po充電回路は省略)

構成は、ESP-WROOM-02(写真の緑のボードはオリジナル)と
無接点プッシュスイッチ(コード付) (秋月電子通商)
リチウムイオン電池充電基板(1A) [CHR4056-MCU1A] (aitendo)
リチウムポリマー電池(3.7V/850mAh) (aitendo)

今回使った無接点プッシュスイッチはスイッチ自体に電源を入れてあげる必要がありますが、上記回路図には書いてません。
プッシュスイッチの代わりにリードスイッチやマイクロスイッチにするというのもOK。

ケースは3Dプリンターで出力。
こんな感じで収まります。(まだ裏蓋を作ってない...)


ソースコードはGithubに。
https://github.com/9SQ/esp8266-Yo-button

今回はWiFiClientSecureではなく、WiFiClientを使ってます。
本当はhttpsでPOSTすべきなのですが、まだWiFiClientSecureの動作が微妙で何故かレスポンスを受け取れなかったので、とりあえずhttpでPOSTしてます。
(通信経路が信頼できない場合は使わない方が良いですね)

仕組みとしては、単純にHTTP POSTするだけなので、宛先をYoから別のもの(IFTTTなど)に変更すれば、色々応用が利くはず...

2015年12月26日

Panasonic製ネットワークカメラのレンズ曇りを取る

Panasonic製のネットワークカメラ BB-HCE481の修理依頼が来た時の記録。
故障と呼べるのかは謎だけど、前玉のレンズ内側が曇って映像が不鮮明というのが今回の修理理由。
前玉にアクセスするまで結構な手順があったので、今後のためにもメモとして残しておくことに。

1. 左右のプラスチックカバーを外す

片方は上下チルト用のステッピングモーター、もう片方は台座に入っている基板から来ているフレキが見えます。


2. 更に左右のプラスチックカバーを外す

1で外したカバーの下に隠れていたネジを外すと、片側にはチルト用ステッピングモーター制御基板、もう片側にはステッピングモーターとその軸からカメラ部横のギアに張ってあるベルトが登場。

3. カメラ部を分離

ステッピングモーターが見える側の軸はEリングで留められているので、マイナスドライバーなどを隙間に突っ込んで捻ると取れる。
もう片方はねじ止めされている基板を外し、同様にEリングを外すと上に持ち上がる。


4. カメラ部を分解

横のネジを全部外してギアを取ると、カメラ部の上側が外れる。
下側も同様に。
実は下記の写真は掃除後に組み立てるときに撮ったので、レンズが綺麗になってたりします...

5. 基板をレンズ部から外す

ネジで止まっている基板を順次外していきます。
左の写真はカメラ部のメインっぽい基板。
レンズと逆側についてる基板を外すと、イメージセンサーが登場。

下側にはレンズ部内に入っている中玉を動かすためのモーター制御ICが付いていました。

6. レンズ部へと続くケーブルを外す

これが面白いと思ったところ。
フレキが入っていってる謎の丸いプラスチックケース。
開けるとフレキがゼンマイ状になっていて、これのおかげで回転する部分と外側で通信が可能になっている訳です。

7. 金属板、フォーカス制御用のモーターを外す

ネジで止まっているので、見えているネジから外していくと分離可能。

8. レンズ部を分解

ついにレンズ部分に到達!
後ろから1枚づつ外していきます。
レンズを外すとシャッターが登場


全部外すとこんな感じ。

9. 前玉のお掃除

一眼レフとか用のレンズクリーニングキットで拭いていきます。
左はbefore、右がafter。

10. 逆の手順で組み立て

フレキとか切らないように注意しながら、組み立てていきます...
終わり。

まとめ

Panasonicのネットワークカメラ、とても良くできてます。

カメラとしてのスペックは、画素数は38万画素、光学21倍ズーム、F値1.6~3.6。
分解して分かったレンズ部の構成は、中玉が3枚、レンズ2枚を2つのモーターで前後に移動させることでフォーカス合わせを実現しているという感じ。
ちなみに、チルト部分はフォトリフレクタと羽で回転角の限界を見ているようで、バラして組み上げた時に角度がずれていても、初回起動時のイニシャライズ(頂点で位置合わせしている)でバッチリ初期位置に戻っていました。

これ、2006年製なので約10年前の製品でビジネス向けなのですが、当時は定価16万円くらいしたそうです。
外見はなんだか無骨なデザインですが、中身は技術の塊っていう感じ。
ビジネス向けの製品として売ってるので当然といえば当然ですが、とっても良くできている、これなら10万超えてても納得だな〜という感想。
#Pla**xとかの製品と比較したら大変失礼なレベルの完成度

最後に外から見た前玉の曇りbefore/afterの写真で終わりとします。


2015年12月8日

地震とか火山噴火情報を閲覧できるWebサイトを作った

作るのを思い立ってから半年くらい掛かった... (実質作業時間は短い)

地震火山詳報
http://evi.prioris.jp

地震と火山(桜島に限らない)に関する気象庁XML電文情報と、それに付随する情報を配信するWebサイトです。
これの立ち上げに伴い、桜島詳報を閉じました。
現時点では火山噴火情報は未実装ですが、統合するつもりで地震火山詳報とネーミングしたので、近々実装します。
と言っても、桜島詳報のコードをちょっと改造して合体させるだけなのですが、最近全国的に火山活動が落ち着いているのでモチベーションが...
実装しました!
12月12日より、噴火に関する火山観測報も追加しました。
桜島詳報では桜島の噴火・爆発のみを扱っていましたが、地震火山詳報では桜島以外の火山(阿蘇山など)の情報を配信されます。

発生した地震の詳細ページでは、震源と揺れを観測した地域の震度がGoogle Mapsライクな操作感で閲覧できます。
例 : 震源・震度情報(2015年12月4日 5時40分頃に発生した地震) - 地震火山詳報

震源や震度のアイコンをクリックすると、上記画像のように地名や座標が表示されます。
地図はOpenStreetMapを使っています。
あとレスポンシブ対応なのでスマホでもPCでも良い感じに閲覧可能です。

地震火山詳報は、地震に関する情報をTwitterとPushbulletでも配信しています。
(Pushbulletって何?っていう人は、EngadgetとかLifehackerの記事を読むといいです。)

Twitter : @Prioris_EVI
Pushbullet : #earthquake_jp

上記Pushbulletのチャンネルは、日本全国のすべての地震(震度1〜)をプッシュ通知で教えてくれるので若干鬱陶しいです。
(日本全国でこんな頻度で地震が起きてるんだ〜!っと認識するのには最高ですが)
というわけで、震度3以上の地震があった時だけプッシュ通知してくれるチャンネルもあります。

Pushbullet : #earthquake_int3over

桜島、阿蘇山の噴火・爆発時プッシュ通知はYoにて配信しています。

Yo : SAKURAJIMA (鹿児島県 桜島の噴火・爆発時に配信)
Yo : ASOSAN (熊本県 阿蘇山の噴火・爆発時に配信)

技術的な話


以下の記事の集大成みたいな感じです。

PostgreSQLとPostGISで国土数値情報(行政区域)を扱ってみる (2015/06)
PostGISで気象庁の細分区域&市町村等に対応する重心を求める (2015/06)
OpenLayers 3で気象庁発表の震度をマッピングする (2015/07)
OL3で扱える地図タイルをShapeから生成する (2015/12)

あと、ベースとして以下も。
桜島が噴火したYoの裏側 (2014/08)

上記の記事中にも書いていますが、気象庁XML電文から震度マップ(GeoJSON)を作るのに必要なデータやGeoJSON生成コードはオープンソースとして公開しています。

9SQ/jma-eqarea-centroid (気象庁が用いる地域区分の重心座標テーブル)
9SQ/jma-eqxml2geojson (気象庁XMLから上記テーブルを利用してGeoJSONを生成する)
9SQ/seismic-intensity-map (震度GeoJSONをOpenStreetMapにオーバーレイ表示する)

...以下詳細...

気象庁から送られてくる震源・震度に関する情報のXML電文には、発生時刻や地震の規模を表すマグニチュード、震源地の座標、津波に関するコメント、そして揺れを観測した地域の地域コードと地名、震度が含まれています。
このXML電文から、震源地の座標を地図にプロットするのは非常に簡単ですが、各地の震度を、その地域の中心となる場所にプロットするというのが結構面倒です。
というのも、気象庁は地域コードや地名のテーブルは公開していますが、その中心(厳密に言えば重心)座標は提供していません。
また、気象庁の区域割りはちょっと特殊で、例えば「石狩地方北部」みたいに、ある程度の市区町村をまとめていたりします。
そこで、まずこれらの区域の中心座標を求めよう、ということで...

1. PostgreSQLとPostGISで国土数値情報(行政区域)を扱ってみる (2015/06)
国土交通省から提供されている行政区域(群市区町村みたいな区域割り)のShapefileをPostgreSQLに読み込んで

2. PostGISで気象庁の細分区域&市町村等に対応する重心を求める (2015/06)
PostGISを使って気象庁が提供している区域とすり合わせて、重心を出力し、テーブルを作り

3. OpenLayers 3で気象庁発表の震度をマッピングする (2015/07)
作成した重心テーブルと気象庁XML電文からOpenLayersなどの地図システムで扱えるGeoJSON形式のデータを生成する

という流れで、震度を地図上のその地域の上に表示させることが出来ました。
ちなみに、表示される位置が中心ではなく重心なのは、地域の形が収まるバウンディングボックスから中心を求めてしまうと、突起やへこみ、極端に長細い岬が出ているような地形ではそれらに引っ張られて視覚的(感覚的?実際的?)な中心から外れてしまうからです。
重心をSQLを叩いてパッと計算(全国分計算するのには数分掛かりましたが)することができるのは、PostGIS最強としか言えません。

この生成した重心座標のテーブルは、上にもリンク張っていますが、GitHubに置いているので、これから気象庁による区域割りの地図上に何か情報を表示させるようなことをしたい方は使ってみてください。

裏側の話


昨年作った桜島の噴火情報配信サイト「桜島詳報」と若干設計が異なります。
以下は、桜島詳報とプッシュ通知システムの構成。


さらに詳しいスライド版はこちら

桜島詳報ではSubscriber自身に色々と他の処理もさせていました。
そして、詳細ページにアクセスする度にXML本体をパースしてサーバ側でページを組み立ていました。

今回のシステムでは、SubscriberはXMLの保存と、電文の種類別に行う動作を振り分けるBridgeに概要を渡すところまでさせています。
それと、概要とUUIDを一緒にMySQLへ入れていた処理を廃止して、XMLをJSONに変換してMongoDBに入れるようにしています。
(桜島詳報のシステムを合体させるために、元のXMLも一緒に保存しています)


今回のシステムでは電文が届く度にjsonが生成され、詳細ページにアクセスすると生成されたjsonを取得してクライアントサイドでページを組み立てていく仕組みです。

届いた電文が震源・震度情報の場合の処理は以下のとおり。


将来的にAPIとか公開するかもなぁーということで、複数のサーバに分けています。
(現時点では性能に余裕があるので1つのVPSの中に上記4つが詰まっている)
地震火山詳報は上記のEVIの部分になります。
今回新たにEDSという地震に関する情報を保存&提供するサーバと、AZMAPという日本の地図タイルを持っているサーバを作りました。

地震火山詳報の震源・震度情報一覧から任意の1ページを開くと、info.json(発生日時や最大震度、マグニチュードなどが入っている)、smallScalePoints.json(広域ポイント)、largeScalePoints.json(詳細ポイント)の3つがEDSからダウンロードされて、JavaScript(jQuery, OpenLayers3)で処理されます。

地震火山詳報のページ内では提供していませんが、情報を各種SNSに流す時に付属させるデータとして、震度マップをWebKitに描画させてキャプチャした画像も生成しています。
こんな画像がTwitterに震源・震度情報の概要と共に投稿されます。


似たような震源・各地の震度画像出力エンジンを作っている会社もありますが、こちらは普通のHTML/CSS/JSで記述されたWebページから画像を生成しているので、簡単に出力する画像のデザインが可能というわけです。

この画像地図は詳細ページの地図と違って、OpenStreetMapの地図タイルを使用していません。
国土交通省の国土数値情報(行政区分)Shapefileから地図タイルを生成して、使用しています。(この地図タイルを持っているのがAZMAPサーバ)

関連する話


これも公開していないのですが、気象庁XML電文が届く度にheadlineをJSONに変換して流しているWebSocketサーバも作って使っています。
これは、グローバルIPを持つサーバが無いと受け取れない気象庁XML電文を、どこでも受信できるように...という考えで立てているのですが、キャパシティがそんなに無いので(今のところ)自分用です。
これをRaspberry Piで受けとって64x16ドットのフルカラーLEDマトリクスに表示させたりしている話は、また改めて記事にしようと思います。

感想と告知


  • 自分の想像(妄想)を形にするものづくりは楽しい。生きている、生きていける理由。
  • Web系欲が満たされたので、またしばらく組み込み系に戻ります。
  • 3か月くらい前から、はぐれエンジニアになって実家療養中です。

2015年12月5日

OL3で扱える地図タイルをShapeから生成する

OpenLayers3で扱える地図タイルを国土交通省 国土数値情報(行政区域)から生成する方法のメモ。
この方法で出力すればOpenLayers3以外(Leafletなど)でも利用可能です。

使用するのは

1. Shapefileからmbtilesを生成する


LearnOSMに詳しい手順が載っているので、おおまかな手順だけ。

1. TileMillを起動し、New projectから新しいプロジェクトを作成する
2. 適当なFilenameを入力し、Image formatを選択し、Addをクリック
この時、デフォルトの世界地図を利用しない(読み込むShapefile以外必要ない)場合は、Default dataのチェックを外す
3. Editor画面になったら、左下のLayersからAdd layerをクリック
4. Datasourceで読み込みたいShapefileを選択し、Save & Styleをクリック
5. Layerが追加されるので、適宜デザインを調整する(デザインはCartoCSSで記述可能)
6. 右上のExportからMBTilesを選択する
7. 書き出す範囲やズームレベルを以下のような形で選択し、Export
おおまかな容量がZoomの下に表示されるので、参考程度に。
(100GB+とかの場合、出力に結構な時間を要する&ファイルサイズが大きくなるので注意)

2. mbtilesから地図タイルを生成する


今回はTileMillで出力したjapan.mbtilesからjapan/tiles下に"Z/X/Y.png"の形で出力した。
git clone git://github.com/mapbox/mbutil.git
cd mbutil
python setup.py install
mb-util japan.mbtiles japan/tiles

tilesディレクト下の構造を保ったまま、適宜設置する。

3. OL3で開く


ol.min.jsなどを呼び出してあげてから、以下のような感じで。
var map = new ol.Map({
    target: 'map',
    renderer: 'canvas',
    layers: [
        new ol.layer.Tile({
          source: new ol.source.XYZ({
            url: '/tiles/{z}/{x}/{y}.png'
          })
        }),
        new ol.layer.Tile({
          source: new ol.source.TileWMS({
            attributions: [new ol.Attribution({
              html: "地図データ © 国土交通省 国土数値情報(行政区域)"
            })]
          })
        })
    ],
    view: new ol.View({
        //中心座標(仮指定)
        center: ol.proj.transform([134.15, 35.27], 'EPSG:4326', 'EPSG:3857'),
        zoom: 6
    })
});

(OpenLayers 3.11.2で動作確認済み)

WGS84あたりに測地系を揃えてあげれば、QGISなどで作ったShapefileも同じ手法で地図タイルにできるので、色々なデータをOL3で見ると面白い(かも)