Take Control Deco Lights

12/18

デコレーションライトを制御する

目次

Xmasっぽいネタ

100均でLEDの電飾が売っていたので、ラズパイで操作できそうなので衝動買い。

左のやつ

使ったのはラズパイ3B+。
GPIO操作はShellからデバイスファイルへ書き込みをすればON・OFFを制御できる。
ただShellからやると細かい制御ができないので、今回はnodejsからGPIOでPWM出力ってのをやってみようかな。
GPIOは21を使う。Pin番号は40。

Shellの例を挙げると

#!/bin/bash

INTERVAL=1
PORT=21
DEVPATH=/sys/class/gpio/gpio${PORT}

echo out > $DEVPATH/direction
for i in $(seq 1 100);
do
        echo "ON"
        echo 1 > $DEVPATH/value
        sleep 0.2
        echo "OFF"
        echo 0 > $DEVPATH/value
        sleep 0.1
done
echo 0 > $DEVPATH/value

これでもできなくはないとは思うけど、実行速度でいえばnodejsのほうが早そうな気がするので、そちらで組んでみる。
調べたら、rpioというモジュールがあったので、それを使ってみる。
PWM出力の場合、LOWとHIGHで電圧が0Vと3.3Vで制御できるようなので、
同モジュールを使うことでsleepも用意されているようなので、ちゃちゃっとできそう。

rpio.js

const _rpio = require('rpio');
const crypto = require('crypto');

// init
var rpio = {};
rpio._ = _rpio;
rpio.device = {
	opened: false,
	pin: 21,
};

// functions 
/**
 *
 * Return randomize number
 *
 */
var Random=()=>{
	const buff=crypto.randomBytes(8);
	const hex=buff.toString("hex");
	const rand=parseInt(hex, 16);
	let s=(''+rand).split('');
	return parseInt(s[3])/10;
}

/**
 *
 * rpio.open()
 * rpio.close()
 * rpio.on()
 * rpio.sleep()
 * rpio.off()
 * rpio.blink(msec)
 * rpio.device = { status, pin }
 *
 */
rpio.open=()=>{
	if(rpio.device.opened){
		console.log(`device has already opened`);
		return false;
	}
	rpio._.open(rpio.device.pin, rpio._.OUTPUT, rpio._.LOW);
	rpio.device.opened=true;
	console.log('device opened');
	return true;
}
rpio.close=()=>{
	if(!rpio.device.opened){
		console.log(`device hasn't opened yet`);
		return false;
	}
	rpio._.close(rpio.device.pin);
	rpio.device.opened=false;
	console.log('device closed');
	return true;
} 
rpio.sleep=(msec=1000)=>{
	if(isNaN(msec)){
		console.log(`argument was not valid`);
		return false;
	}
	rpio._.msleep(msec);
	return true;
}
rpio.on=()=>{
	if(!rpio.device.opened){
		console.log(`device hasn't opened yet`);
		return false;
	}
	rpio._.write(rpio.device.pin, rpio._.HIGH);
}
rpio.off=()=>{
	if(!rpio.device.opened){
		console.log(`device hasn't opened yet`);
		return false;
	}
	rpio._.write(rpio.device.pin, rpio._.LOW);
}
rpio.blink=async (onTimer=1000,offTimer=100)=>{
	await rpio.on();
	await rpio.sleep(onTimer);
	await rpio.off();
	await rpio.sleep(offTimer);
}
 
module.exports = rpio;

こんな感じにモジュール化してみたので、呼び出し元で

index.js

const rpio=require("./rpio");
rpio.device.pin=40;

var blink=async (counter=1, timer1=1000, timer2=100)=>{
	rpio.open();
	for(let i=0;i<counter;i++){
		await rpio.blink(timer1, timer2);	
	}
	rpio.close();
}

blink();

こんな感じにしてあげれば、1秒光って消える。
blink関数の引数は、光らせる回数(counter)、光っている時間[ms](timer1)、光っていない時間[ms](timer2)になっているので

blink(10, 30, 10);

こんな感じにすれば、ピカピカと結構はやく明滅する。

最後に

ラズパイ+Google Homeで時報やら家で起こっているいろいろなことを喋らせているが、これがあれば視覚的にもお知らせしてくれる。
結構面白い。


コメント: