Qiita obniz Advent Calendar 2019
本投稿は、Qiita Advent Calendar 2019 12/19(木) も兼ねています!
デジタルとアナログの融合!
毎年恒例(?)の三軒茶屋えほん保育園での「えぽん巡業」に行ってきました。三軒茶屋えほん保育園では今回が3回目。
1回目は普段通り「えぽん」を楽しんでもらいましたが、2回目は「いつもと同じじゃつまらない!」とキノコたちの意地があります。
そこでクリスマス時期だったこともあり、デジタルえほんとリアルのクリスマスツリーの融合をしました。
詳細は以下より
そして、3回目の今回。さて、何をしようかとキノコたちは頭に生えたキノコをもふもふしながら考えました。
やはりデジタルとアナログの融合がいい、子供達に何かしらアナログでの創作活動や手を動かすことをして欲しい。と。
デジタルにもアナログにもそれぞれ良さがあるので、その融合こそがキノコの目指すところです。
プラレールを走らせよう!
そこで思いついたのがプラレール。
プラレールを保育園内に敷き詰めて、子供たちには線路の周りに積み木やブロックで街を作ってもらおう!
動物園、水族館、レストラン、お花屋さんなど。
そして街が出来上がったら汽車を走らせよう!
そんな構想が頭に浮かびました。
あとは「えぽん」のストーリー・仕込みと、どうやってプラレールと連動させるか?
そこはもうデジタルのお話。キノコが得意とするところです。
デモ動画はこちら。デジタルえほんを読み進め「しゅっぱつ」と読むと、実際のプラレールが走り出します。
こんな感じ

準備をするキノコたち

親子キノコで準備中

micro:bit踏切

街の入り口はobnizセンサー

何やら細工された電車。こちらもobniz

敷き詰められたレール
子供たちがまちづくり!





街を作成中のこどもたち
親御さんも参加されてたり、親子での創作というコミュニケーション・親子の時間を作れたことも何よりです。
子供たちにはデジタルえほんとプラレールがITの技術によって連動しているという発想はないと思いますが、楽しんでくれたからそれでいい!
obnizについて
今回は、プラレールがトンネルを通過したことを検知するために距離センサー「GP2Y0A21YK0F」と、デジタルえほんからのトリガーでプラレールを走らせるためにDCモーター制御をしました。
/**
* obniz DCMotor制御
*/
export class ObnizDCMotorClient extends ObnizClient {
private motor: any;
private power: number = 60;
constructor() {
super();
}
static init(): ObnizDCMotorClient {
return;
}
/**
* obnizへ通知オン
*/
start(): void {
this.motor = this.obniz.wired('DCMotor', { forward: 0, back: 1 });
this.motor.power(this.power);
this.motor.move(true);
}
/**
* obnizへ通知オフ
*/
stop(): void {
if (!this.motor) {
return;
}
this.motor.stop();
}
setPower(power: number): void {
if (!power) {
return;
}
this.power = power;
}
disConnect(obnizId: string): Rx.Observable {
this.stop();
return super.disConnect(obnizId);
}
}
export class ObnizLightSensorClient extends ObnizClient {
private intervalId: any;
constructor() {
super();
}
/**
* GP2Y0A21YK0Fの読取を開始
*
* obniz.wired後、start発火
* ExecuteDistance以内を検知したらexecute発火
* その後、EndDistance以上離れたことを検知したらended発火
* @param trigger
*/
startSensor(lightSensorSetting: ILightSensorSetting, trigger: IObnizReceiverEvent): void {
if (!this.obniz) {
console.log('obniz is not connected.');
return;
} else if (
!lightSensorSetting ||
lightSensorSetting.execSensorDistance <= 0 ||
lightSensorSetting.endSensorDistance <= 0 ||
lightSensorSetting.detectionSensorInterval <= 0 ) { console.log('specified sensor setting value is invalid.'); return; } // すでに読取中に読取くるかも if (this.intervalId) { console.log('obniz is already read.'); return; } const sensor = this.obniz.wired('GP2Y0A21YK0F', { vcc: 0, gnd: 1, signal: 2 }); if (!sensor) { console.log('obniz sensor is not available.'); return; } let fired: boolean = false; if (trigger.started) { trigger.started(); } // 規定感覚ごとに距離をチェック this.intervalId = setInterval(() => {
sensor.getWait().then((distance: number) => {
console.log(`distance is ${distance}`);
// 規定距離以内になったら発火
if (distance <= lightSensorSetting.execSensorDistance && !fired) { if (trigger.executed) { trigger.executed(); } fired = true; } else if (distance >= lightSensorSetting.endSensorDistance && fired) {
if (trigger.ended) {
trigger.ended();
}
// 発火後endSensorDistance以上離れたら、再び発火検知開始
fired = false;
}
});
}, lightSensorSetting.detectionSensorInterval);
}
endSensor(): void {
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
}
}
}