部屋の換気状態が適切かどうか調べてみたくて、MH-Z19Bとobnizを組みあわせて、計測した二酸化炭素濃度を表示するものを作成してみました。
コードはyukilabさんが作成したものを参考にしたので、自力で作成したのは回路くらいですね(笑)
↓こんな感じにobniz Boardにco2濃度が表示されます(コードを実行しているブラウザにも表示されます)
MH-Z19Bはご覧のように、端子が穴になっているので、このままではジャンパワイヤで接続できません
ピンヘッダーを適切にカットして、センサーの端子穴に入れてハンダ付けします
完成です!
端子が結構小さいのでハヅキルーペがあると、見やすくなってハンダ付けが捗ります
obnizのオンラインエディタに入力します
今回参考にしたコードは、センサーが若干違うのか、ppmの計算式が手元のセンサーとデータシートと異なっていました。
データシート 7ページ目には、CO2 concentration = HIGH * 256 + LOW とのことなので以下のように修正しています。
修正前の部分
let level = data[2] * 100 + data[3];
修正後の部分
let level = data[2] * 256 + data[3];
ほぼ参考にしたコードのままなので、センサーの取得間隔は20秒、LEDが点滅するしきい値は1500ppmとなっています。
<html lang="ja">
<head>
<title>CO2 level</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://obniz.io/js/jquery-3.2.1.min.js"></script>
<script src="https://unpkg.com/[email protected]/obniz.js"></script>
<style type="text/css">
.sub {
vertical-align: sub;
font-size: smaller;
}
</style>
</head>
<body>
<div id="obniz-debug"></div>
<h1>CO<span class="sub">2</span> level</h1>
<button id="read" style="display:none">read</button>
<div id="print"></div>
<div id="app"></div>
<script crossorigin src="https://unpkg.com/[email protected]/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/[email protected]/umd/react-dom.production.min.js"></script>
<script>
let obniz = new Obniz("OBNIZ_ID_HERE");
let onconnect_func = async function () {
let power = obniz.wired("USB", {gnd: 3, vcc: 2});
let led = obniz.wired("LED", {anode: 10, cathode: 11});
let co2history = [];
obniz.keepWorkingAtOffline(true);
power.on();
let uart0 = obniz.getFreeUart();
obniz.uart0.start({tx: 0, rx: 1, baud: 9600});
led.on();
await obniz.wait(3000);
led.off();
obniz.uart0.onreceive = function (data, text) {
if (data[0] == 0xff && data[1] == 0x86) {
let level = data[2] * 256 + data[3];
co2history.push(level);
if (co2history.length > 100) {
co2history.splice(0, 1);
}
ReactDOM.render(
React.createElement('h1', null, level.toString() + 'ppm'),
document.getElementById("app")
);
obniz.display.drawing(false);
obniz.display.clear();
// obnize display resolution is 128*64
var x0 = 0;
var y0 = 64 - co2history[0] / 40;
for (let i = 0; i < co2history.length; i++) {
let val = 64 - co2history[i] / 40;
obniz.display.line(x0, y0, i, val);
x0 = i;
y0 = val;
}
obniz.display.line(0, 64 - 25, 128, 64 - 25);
obniz.display.line(0, 64 - 50, 32, 64 - 50);
obniz.display.font('Consolas', 20);
obniz.display.pos(40, 2);
obniz.display.print(level.toString() + 'ppm');
obniz.display.font('Avenir', 8);
obniz.display.pos(0, 64 - 25);
obniz.display.print("1000");
obniz.display.pos(0, 64 - 50);
obniz.display.print("2000");
obniz.display.drawing(true);
if (level > 1500) {
high_alert(level / 100);
}
}
};
let read_co2 = function () {
obniz.uart0.send([0xff, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79]);
};
let high_alert = async function (n) {
for (let i = 0; i < n; i++) {
led.on();
await obniz.wait(300);
led.off();
await obniz.wait(300);
}
};
$('#read').click(read_co2);
setInterval(read_co2, 20 * 1000); // update every 20sec
};
obniz.onconnect = onconnect_func;
</script>
</body>
</html>
センサーのデータシートにはPreheat time 3minとあるので、コードを実行して3分経過しないと正確なCO2濃度にならないようです。
たしかに起動してしばらくは、いつも同じ数値が表示されている気がします。
もし、サーバレスで定期実行させたい場合は、センサーの電源を常時供給させないといけませんね。
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント