定刻到着装置FRISK型 HWはOK SWは追い込み中

Maker Faire Tokyo 2013に出展予定の定刻到着装置、HWは何とかなった。現在SWの作成、絶賛追い込み中。

定刻到着装置FRISK型表

定刻到着装置FRISK型表

定刻到着装置FRISK型裏

定刻到着装置FRISK型裏

↑、まだフラックスを洗浄してないので、ちょっと汚いけど・・・。ちゃんとフリスクケースに収まりまするん(ふたも閉まります)

Seeed Studio(Fusion PCB)に基板を発注したのが、9/21。Seeed Studioから基板が発送されたのが、9/27。予定では、10月の第2週ぐらいには家に届くんじゃね?と思っていたら、おそらくは、中国の国慶節なる大型連休にぶつかったためなかなか荷物が届かず・・・。結局、基板が家に届いたのは、10/18の夕方。

そこから、あばばあばばと、1枚だけ半田付け -> あらかじめ準備しておいたテストプログラムを動作させHWの期待動作を確認 -> 残りの基板の半田付け開始(量産開始?)で、現在、両面完成が11枚、部品面だけ完成が5枚。0.4mmピッチの10ピンDFNも、コツ?をつかめば意外と何と無かった。

以下、今後のために、今回、実装していて(半田付け)していて、掴んだコツなど。未来の自分に向けて。(自己流なので多分正しくないよ。とりあえず、部品が基板にくっついていればいいレベル)

  • 基板のカット
    プラスチックカッター、替え刃ケチるな。切れ味落ちたら、交換しろ。切れ味落ちた状態と、交換した後、作業効率が全然違う。
  • DFNの半田付け
    テープで固定 -> 手で半田付けという順番は、お前には無理、諦めろ。半田付けしている間にずれる。
    クリームハンダ -> 大体な感じでチップを載せる -> ホットプレートで半田溶かす -> フラックスたっぷり塗る -> 半田ごての小手先(まさに先端部分)を、チップと基板の接点に当てて横にずらす。これでうまくいく。
  • クリームハンダを爪楊枝で早くランドに塗る方法
    爪楊枝の先にクリームハンダを少量つける時に、爪楊枝をポールとみなしたときに、半田が”旗”のようになるようにつける。爪楊枝の軸ではなく、旗となった部分をランドにくっつける。爪楊枝を指で回転させながら、爪楊枝を基板から離す。これで、少量のクリームハンダが、まるで小さなボールのようにランドに載るはず。
  • mini USBコネクタとQFPは、ホットプレート作戦ではなく、手半田の方が早くて間違いない
  • 表面実装チップICをつける時に、固定のためにクリームハンダが使える
    対角線のピンにクリームハンダ -> 半田ごてでクリームハンダ溶かす -> 位置決定 -> 残りの足は、普通にフラックス塗って半田ごてで半田付け。すべての足をクリーム半田でやる作戦は、良くない。というのも、足と足のあいだに、微妙にとけ残ったクリームはんだが残ってしまい取り除くのが大変。(ヒートガン手に入れたら、状況変わるかもなので、それを試せ、俺)

ホットプレートで半田付けする作戦は、片面しか使えないのが、つらいなぁ。Make終わったら、今後のために、オーブントースターリフロー炉つくってみようかね・・・。

10ピン DFNパッケージ ちぃせぇ

Digi-keyから、定刻到着装置で使う部品が届きました。

DFN10

写真は、今回、この工作が成功するか否かの最大のポイント、約2mm*2mm角 0.4mmピッチ 10ピンのDFNパッケージの加速度センサです。果たして半田付けできるか?

頭の中で思い浮かべていたものよりも、さらに小さいぞ・・・

これ手で付けられたら、他のやつも大丈夫という自信になるな。頑張ろう。

Maker Faire Tokyo 2013 出展します

先日事務局よりMaker Faire Tokyoへの出展承認がおりまして、それに向けて、ホゲホゲと作業を進めております。ああ、もう出展許可メールが届いてから10日もたつのか・・・。

出展物は、よほどのことが無い限り大きく分けて次の2つを予定しています。

 その1. 定刻到着装置FRISK型

先日の記事に書いたとおり、徒歩で目的地まで行くときに、定刻に着くことができるようになる(かもしれない)装置です。FRISKケースに収まるサイズなので、FRISK型。

下は現時点での基板設計。まだ、部品が届いてないので、部品が届いたあと、フットプリントなど最終確認してからFusion PCBに発注する予定のものです。

定刻到着装置基板

加速度センサーで歩くピッチを検出、GPSで現在位置 & 時刻を把握、それらと、マイクロSDカード内のルート情報を照らし、目的地に定刻どおりに着くために補正された歩くピッチを計算、そのピッチを音で知らせるというものです。単純な、GPSロガーとしても利用できるようにするつもりです。

電源は、リチウムポリマー電池でUSB経由で充電可能。また、USB接続で、マイクロSDカードの内容の読み書き / ファームウエアの更新を可能にする予定です。

コヤツがうまく完成できるか? 最大のリスクは、加速度センサの半田付けです。0.4mmピッチの10ピンのDFNパッケージ。果たして、私の力量で手に負えるものなのか・・・。不安でいっぱいです。

その2. はかどるん

前回作成したはかどるんを、若干数、用意します。

・・・その理由は、その1.がコケタときの保険です。

—–

今回の定刻到着装置は、GPSモジュールやらリチウムポリマー電池やらなんやらのせいで、はかどるんより結構なパーツ代がかかるので、頒布数はかなり少なくする予定です。

Maker Faire Tokyo 2013出展申し込み

今年も Maker Faire への出展申し込みを行いました。 http://makezine.jp/event/mft2013/

去年は、出展可否は、なんと、申し込み早いものだったらしく、今年からは、事務局での選考が行われるとのこと。新ネタと、去年出した はかどるん を出すつもりで申し込みましたが、新ネタも相変わらず見た目が地味・・・ 動いたり光ったりしない。 選考、大丈夫かいな?

さて、その新ネタの名前は 「定刻到着装置(FRISK型)」

名前の通り、毎日の通勤・通学、駅などまでの歩き道、間に合わないと思って早歩きしたら早くついてしまったとか、その逆、ゆっくり歩きすぎて遅刻してしまったなどを、いちいち時計を見て頭使って歩くペースを調整しなくても大丈夫にする装置です。

ちなみに、MFTに申し込むときの名前は「定刻到着装置」。FRISK型をあえて外しました。なぜならば、現時点でFRISKケースに入りきるか微妙だから・・・ 何とか収めたいなぁ。

これからちょろちょろ「定刻到着装置」の記録について、記事にしていくです。

電力測定するよ (SQLite3 / Python / JSON / Chart.js とか)

前からちょろちょろ作っていた 「電力測定するやつ」 が一通り完成した。正確には、電力ではなく、電流を測定するやつだが。

Pythonとか、JSONとか、Chart.jsなどという、C言語ばっかり書いている私にとっては、最近ぽい(そうでもない?)ものをグニグニくみあわせてみた。お勉強をかねて。

電流測定とデータの蓄積

この電流測定するやつは、電流を測定するモジュール(AVR+Xbee)と、測定結果を蓄積する部分(Raspberry Pi+Xbee)に分かれる。

  • 電流を測定する部分
    消費電力測定

    • AVR (ATMega8) が、30秒に一回Wakeupし、電流センサの値(電圧出力)を1秒間の間128回 AD変換する。128回の測定値の合計(正確には基準点との絶対値の合計)を、その時刻の消費電流量とする
    • AVRは、12回分の測定結果が溜まるごと、つまり30秒 * 12回 = 5分ごとに、その5分間の平均消費電流値を求める。
    • AVRは、1時間ごとに、XBeeをWakeupし、その1時間の間の5分ごとの平均消費電流データをXbeeを使って、Raspberry Piに送る。
    • これにより、電子レンジの利用など1分ぐらいの消費電流変化も捉えられるようにするとともに、乾電池で電力測定部分を計算上1年以上動作可能にした。
    • 測定したデータがいつ採取したしたものか分かるよう、RTCモジュールを搭載。RTCの値は、Raspberry Piとの通信時に、適宜、Raspberry Pi側の時刻に構成されるようにした。
    • 一応、本当に1年以上動くか評価するために、電池電圧のデータも、電流量のデータとともに、Raspberry Piに送信するようにしてある
  • 測定結果を蓄積する部分
    • Raspberry PiにXbeeを取り付けたものを利用。
    • 測定部分から送られてきたデータは、Raspberry Pi上で動かしているデーモンが、SQLite3のデータベースにガシガシつっこむ。

データの表示

データの表示部分が、自分にとって、新しい試み。

まず、測定データは、SQLite3のデータベースの次のテーブルにがしがし、記録される。

CREATE TABLE samples ( sample_time TEXT, sample_type INTEGER, value INTEGER, PRIMARY KEY(sample_time, sample_type) );

ここで、sample_type は、測定値のタイプ(0 : 電流測定値、1 : 電池電圧測定値)を示す。

このデータベースに対して「過去48時間の1時間後との電流値平均」「過去1ヶ月の1日ごとの電流値平均」「過去1年間の1Weekごとの電流値平均」を求めるSQLを発行し、その情報をJSONデータとして吐き出すCGIをPythonを用いて作成。

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

def get_json_labels_data_pair(cursor):
	label = []
	value = []
	for r in c:
		label.append(r[0])
		value.append(r[1])
	return {"labels" : label, "data": value}

db = sqlite3.connect("//home/pi/XbeeDaemon/samples.db")

# 過去48時間の1時間後との電流値平均
sql = (
	"select strftime('%m-%d %H', sample_time) as time,avg(value)"
	" from samples"
	" where sample_type = 0"
	"  and julianday(sample_time) "
	"     >= julianday(datetime('now', 'localtime', '-48 hour'))"
	" group by time order by time;"
)
c = db.execute(sql)
hour_data = get_json_labels_data_pair(c)

# 過去1ヶ月の1日ごとの電流値平均
sql =  (
	"select strftime('%Y-%m-%d', sample_time) as time,avg(value)"
	" from samples"
	" where sample_type = 0"
	"  and julianday(sample_time) "
	"     >= julianday(datetime('now', 'localtime', '-1 month'))"
	" group by time order by time;"
)
c = db.execute(sql)
day_data = get_json_labels_data_pair(c)

# 過去1年間の1Weekごとの電流値平均
sql =  (
	"select strftime('%Y-%m (%W)', sample_time) as time, avg(value)"
	" from samples"
	" where sample_type = 0"
	"  and julianday(sample_time) "
	"     >= julianday(datetime('now', 'localtime', '-1 year'))"
	" group by time order by time;"
)
c = db.execute(sql)
week_data = get_json_labels_data_pair(c)

send_data = {"hour" : hour_data, "day" : day_data, "week" :  week_data}

print "Content-type: application/json"
print
print json.dumps(send_data)

で、最後に、このCGIプログラムを呼び出して、JSONデータを取得し、その情報を Chart.js によって表示するHTMLファイルを作成。

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<script src="./Chart.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<script type="text/javascript">
function drawChart(labelData, targetCanvas)
{
	var chartData = {
		datasets : [
			{
				fillColor : "rgba(151,187,205,0.5)",
				strokeColor : "rgba(151,187,205,1)",
				pointColor : "rgba(151,187,205,1)",
				pointStrokeColor : "#fff",
			}
	  	]
	};
	chartData.labels = labelData.labels;
	chartData.datasets[0].data = labelData.data;
	new Chart(targetCanvas.getContext("2d")).Line(chartData);
}
function updateChart ()
{
	$.getJSON("http://pi/cgi-bin/Power.py", function(json) {
		drawChart(json.hour, document.getElementById("hourChart"));
		drawChart(json.day, document.getElementById("dayChart"));
		drawChart(json.week, document.getElementById("weekChart"));
	});
}
$(function(){
	var currentChart = 0;
	var chart = $("#chartArea").children('div');

	$(chart).hide();

	updateChart();
	setInterval(updateChart, 60 * 60 * 1000); // 一時間ごとに更新

	$(chart[currentChart]).show();
	setInterval(function()
		{
			var nextChart = currentChart + 1;
			if (nextChart >= chart.length) {
				nextChart = 0;
			}
			$(chart[currentChart]).fadeOut(1000);
			$(chart[nextChart]).fadeIn(1000);
			currentChart = nextChart;
		},
		30 * 1000 // 30秒置きに切り替え
	);

});
</script>
<style type="text/css">
#chartArea {
	height: 600px;
	width: 850px;
	overflow:hidden;
	position:relative;
}
.chart {
	position:absolute;
}
</style>
</head>
<body>
<H1>消費電流量表示するやつ</h1>
<div id="chartArea">
<div id="divhour" class="chart">
<h2>過去48時間のデータ(1時間単位)</h2>
<canvas id="hourChart" height="500" width="800"></canvas>
</div>
<div id="divday" class="chart">
<h2>過去1ヶ月のデータ(1日単位)</h2>
<canvas id="dayChart" height="500" width="800"></canvas>
</div>
<div id="divweek" class="chart">
<h2>過去1年のデータ(1週間単位)</h2>
<canvas id="weekChart" height="500" width="800"></canvas>
</div>
</div>
</body>
</html>

んで、このHTMLにブラウザからアクセスすると、次のような画面が30秒、お気に切り替わって表示される、と。(まだ測定を始めて1週間ぐらいなので、過去1ヶ月と1年の表示はしょんぼりな感じ)

過去48時間のデータ

過去1ヶ月のデータ

過去1年のデータ

あとは、Raspberry Piを常時テレビにつないでおいて、Raspberry Pi起動とともに、Raspberry Piの標準Webブラウザ Midori を全画面で起動して、上記のHTMLを表示するようにする。加えて、現在は、センサの生データを表示しているので、電気メータの実測値から係数を求めて、W(KWh)単位でグラフ表示するようにすれば、おしまいかな。

思ったこと

  • センサの値とかは、とりあえず、データベースに放り込んでおけば、SQL 1つでグニグニできるので、良い感じ。
  • ちょっと勉強でも、それっぽく使える。JQueryとかChart.jsとか、すごいね。。。

Makefile 別ディレクトリに中間ファイル & 自動依存関係設定

普段、自分でMakefileを書くことはほとんど無い。あったとしても、ちょっとしたプログラムでソースファイルとして数個のCソースがあるようなもの。なので、Makefileの知識は、ターゲットと依存関係を : で区切って書くとか、変数が使えて、その参照は$(~)でやるとか、そういうぐらいしかなかった。

ところが、ある程度の規模があるプログラムを作成することになり、ちょっと自分流Makefileというものを、ちゃんと作っておこうと思い立つ。一回作っておけば、使いまわしできるからね。

こんなことができれば・・・・という自分の要求は、以下のとおり。

  1. 中間ファイル(オブジェクトファイル)は、ソースとは別のディレクトリに吐き出させたい。ただし、ここで、元となるソースは複数のディレクトリ内に散在している。
  2. ソースからインクルードしているヘッダなどの依存関係も、ちゃんとなんとかしてほしい
  3. ビルドは、最速である必要はないが、モッサリしているのは嫌
  4. 新しいソースを追加したとき、いろんなところを書き換えるのは嫌

適当にググレば、そんなMakefileのサンプルがわんさか出てきて、コピペで終了と思ったが、甘かった。1.と2.を同時に実現する方法がなかなか見つからない・・・。

ということで、Makefileの仕様を勉強しながら、自分流Makefileをつくる。

例題

例として次のようなディレクトリ・ファイル構成を考える。

 / 
 | Makefile / main.c / ValDef.h / Funcs.h
 |- SubDir1
 |   |   func.c
 |   |- SubSub
 |         func.c
 |- SubDir2
 |   func.c
 |- Build
     中間ファイルはここに吐き出させたい

作業スペースのルートに Makefile と Cコード(main.c)とヘッダファイル。そしてサブのディレクトリに、複数のCコード(func.c)が存在している状態。複数のディレクトリに同じファイル名のCファイルがあるのが曲者だ。既存のソースの流用などをしたいとき、同じファイル名のcファイルが複数存在することはありうる。

こういうMakefileを作った

SRCS = \
	main.c \
	SubDir1/func.c \
	SubDir1/SubSub/func.c \
	SubDir2/func.c

INC_DIR = .

BUILD_DIR = Build

OBJS=$(addprefix $(BUILD_DIR)/,$(patsubst %.c,%.o,$(SRCS)))
DEPS=$(patsubst %.o,%.d, $(OBJS))

CC = gcc
TARGET = TestProg.exe
CFLAGS += $(addprefix -I,$(INC_DIR))
LDFLAGS += 

all: $(BUILD_DIR) $(TARGET)

$(BUILD_DIR):
	mkdir -p $(BUILD_DIR)

$(TARGET) : $(OBJS)
	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^

$(BUILD_DIR)/%.o : %.c
	mkdir -p $(dir $@); \
	$(CC) -c $(CFLAGS) -o $@ $<

$(BUILD_DIR)/%.d : %.c
	mkdir -p $(dir $@); \
	$(CC) -MM $(CFLAGS) $< \
	| sed 's/$(notdir $*).o/$(subst /,\/,$(patsubst %.d,%.o,$@) $@)/' > $@ ; \
	[ -s $@ ] || rm -f $@

clean:
	rm -rf $(BUILD_DIR) $(TARGET)

.PHONY: all clean
-include $(DEPS)

上記のMakefileを、Buildディレクトリがまだできていない状態から実行したときに何が行われるのか、ちゃんと理解しようとすると、以下のとおり。

  1. makeは41行目のinclude $(DEPS)にしたがって、Build/main.d や、Build/SubDir1/func.d などのファイルをincludeしようとするが、これらファイルが 存在していないことに気づく。ゆえに、まずは ~.d ファイルがターゲットとなっているルールを見つける。
  2. ~.dを生成するルールは31~35行目にある。
    例えば、Build/SubDir1/func.d は、$(BUILD_DIR)/%.d にマッチする。このとき、%の部分(stemと言うらしい)は、SubDir1/func なので、make は、Build/SubDir1/func.d が依存するファイルが、 SubDir1/func.c であると認識する。
  3. fund.dを吐き出すための Build/SubDir1 ディレクトリを作成する。(32行目)
  4. gcc -MM オプションを使って func.c がincludeしているヘッダの一覧を標準出力に出力させる。ここで、gccの出力は、以下のフォーマットになる。
    func.o: SubDir1/func.c Funcs.h

    このままでは、次の理由でNGである。

    • .oファイルの相対パスが書かれていない。これでは、Func.h を書き換えても、Build/SubDir1/func.o を新たに生成する必要があると、makeは思わない。
    • .h ファイルに新しいincludeを追加したときに、.dファイルが新しく生成されない。

    そこでsedを使って、gccの出力を以下のようになるように書き換える。

    Build/SubDir1/func.o Build/SubDir1/func.d: SubDir1/func.c Funcs.h

    さらに、gcc -MMが失敗して、空の .d ファイルができてしまった場合は、その .d ファイルを削除するようにした。

  5. .dが出来上がるとincludeが成功するので、次にmakeは$(TARGET)の依存ファイルである各種.oファイルを生成しようとする
  6. そのルールは27-30行目に書いてあるので、それに従い、.oを作成
  7. .oができると24行目のルールで最終生成物 TARGET が出来上がる

・・・なんとか、できました。

電力使用量測定するよ

消費電力測定

 

先月だったか、東京電力からの毎月の電力使用量のお知らせと一緒に、一日の時間帯での電気使用量が異なるいくつかの家庭用のプランがありますよーというお知らせが入っていた。

どうやら申請するとメーターが交換されて、例えば朝得プランなんていうものに入ると、朝の電力が割安になるらしい。で、どのプランに入るのかが一番安いのかは、東京電力のサイトから試算できるようになっているのだが、その方法は、あなたは何時ぐらいに家をでますか~? といった質問から求めるもので、いまいち、本当のところ、どのプランが自分にあっているのか良く分からない。

・・・ということで、家の電力使用量をモニタリングしてみようと思い立つ。

現在、システム全体は未完成。

画像のものは、作成した現在の消費電流(など)を定期的に測定し、その情報をある程度、貯めてからXbeeを使って、送信するというもの。後で、詳細書こう・・・。

情報の受け取り手はXbeeを接続したRaspberry Pi。とりあえず、受け取ったデータを、がしがしDBにぶち込んで、あとでソレを集計するみたいな・・・ことを考え中。

このサイトは何か?

  • 馬鹿にならないよう、頑張るために、技術的なこととか記録していく自己満足なもの。
  • 記事がたまってきて、誰かの目に付いて、反応があると、頑張りの後押しになると思ったもの。

・・・続くのか?