1. はじめに
今回は息子が夏休みの課題で「生活に役に立つものを製作しなさい」があったので、いろいろと考え、この時期は熱中症になる可能性が高いので、暑さ指数(WGBT)から暑さの警戒レベルをLEDで表示し、最高レベルになるとブザーで知らせるものを製作することにしました。
2.使用部品について
今回の回路には表1に示す部品を使用しました。
使用部品 | 名称 | 備考 |
---|---|---|
マイコン | Seeeduino Xaio | 秋月電子で購入 |
温度・湿度センサ | AKI-BME280 | 秋月電子で購入 |
抵抗 | 1kΩ | LEDの電流制御用 |
抵抗 | 10kΩ | トランジスタのプルダウン抵抗 |
トランジスタ | 2SC1815 | ブザーのドライブ用 |
スイッチ | タクトスイッチ | ブザー制御用 |
3. 回路について
回路図を図1に示します。電源についてはSeeeduino XaioのUSB端子からとっています。
4.動作について
センサから温度・湿度の情報を取得して、そのデータをもとにWBGTを求め、その結果を3段階に分別し、LEDを点灯させます。また、最高レベルになるとブザーで知らせるようにしています。
WGBTのデータについてはSymamoneさん製作された簡易WBGT警報機の製作ページのデータを使用させていただいています。また、WGBTのテーブル処理方法も使用させてもらっています。感謝です。
5. プログラムについて
今回もArduinoを使用して、プログラムを作成しました。とりあえず、動作確認用で作成したのでプログラムは汚いです…。
簡易WBGT警報機プログラム
#include <Arduino.h>
#include <BME280I2C.h>
#include <TimerTCC0.h>
#include <Wire.h>
#define ON 0
#define OFF 1
#define BUZ_TIME 100
volatile unsigned char bz_ctrl;
volatile unsigned char bz_pat; // ブザーパターン格納変数
volatile unsigned long timer,sw_timer;
BME280I2C bme; // Default : forced mode, standby time = 1000 ms
// Oversampling = pressure ×1, temperature ×1, humidity ×1, filter off,
//WBGT計算テーブル
const int WBGT[20][17] = {{15, 15, 16, 16, 17, 17, 18, 19, 19, 20, 20, 21, 21, 22, 23, 23, 24},
{15, 16, 17, 17, 18, 18, 19, 19, 20, 21, 21, 22, 22, 23, 24, 24, 25},
{16, 17, 17, 18, 19, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25, 25, 26},
{17, 18, 18, 19, 19, 20, 21, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27},
{18, 18, 19, 20, 20, 21, 22, 22, 23, 23, 24, 25, 25, 26, 27, 27, 28},
{18, 19, 20, 20, 21, 22, 22, 23, 24, 24, 25, 26, 26, 27, 28, 28, 29},
{19, 20, 21, 21, 22, 23, 23, 24, 25, 25, 26, 27, 27, 28, 29, 29, 30},
{20, 21, 21, 22, 23, 23, 24, 25, 25, 26, 27, 28, 28, 29, 30, 30, 31},
{21, 21, 22, 23, 24, 24, 25, 26, 26, 27, 28, 29, 29, 30, 31, 31, 32},
{21, 22, 23, 24, 24, 25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33},
{22, 23, 24, 24, 25, 26, 27, 27, 28, 29, 30, 30, 31, 32, 33, 33, 34},
{23, 24, 25, 25, 26, 27, 28, 28, 29, 30, 31, 31, 32, 33, 34, 34, 35},
{24, 25, 25, 26, 27, 28, 28, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36},
{25, 25, 26, 27, 28, 29, 29, 30, 31, 32, 33, 33, 34, 35, 36, 37, 37},
{25, 26, 27, 28, 29, 29, 30, 31, 32, 33, 33, 34, 35, 36, 37, 38, 38},
{26, 27, 28, 29, 29, 30, 31, 32, 33, 34, 34, 35, 36, 37, 38, 39, 39},
{27, 28, 29, 29, 30, 31, 32, 33, 34, 35, 35, 36, 37, 38, 39, 40, 41},
{28, 28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 37, 38, 39, 40, 41, 42},
{28, 29, 30, 31, 32, 33, 34, 35, 35, 36, 37, 38, 39, 40, 41, 42, 43},
{29, 30, 31, 32, 33, 34, 35, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44}};
/*******************************************************************************
* timerTcc0Isr - タイマーCC0の割り込み処理 *
* argument : None *
* return : None *
*******************************************************************************/
void timerTcc0Isr()
{
static unsigned long buz_tm = 0;
if (bz_ctrl == OFF) bz_pat = 0x00;
/* ブザー制御*/
if (buz_tm > BUZ_TIME)
{
((bz_pat & 0x80)) ? digitalWrite(10, HIGH) : digitalWrite(10, LOW);
bz_pat <<= 1;
buz_tm = 0;
}
// タイマーカウントアップ
buz_tm++; timer++; sw_timer++;
}
//////////////////////////////////////////////////////////////////
void setup()
{
Wire.begin();
while (!bme.begin())
{
//Serial.println("Could not find BME280 sensor!");
delay(500);
}
// タイマーの設定
TimerTcc0.initialize(1000); // 1msに設定
TimerTcc0.attachInterrupt(timerTcc0Isr); // 割込関数の設定
pinMode(6, INPUT_PULLUP);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(13, OUTPUT);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
digitalWrite(13, HIGH);
// ブザー初期化
bz_pat = 0x00;
bz_ctrl = ON;
//タイマー初期化
timer = 0;
}
//////////////////////////////////////////////////////////////////
void loop()
{
float temp(NAN), hum(NAN), pres(NAN);
unsigned int t, h;
int tmp_idx, hum_idx;
BME280::TempUnit tempUnit(BME280::TempUnit_Celsius);
BME280::PresUnit presUnit(BME280::PresUnit_Pa);
if (timer >= 2000)
{
bme.read(pres, temp, hum, tempUnit, presUnit);
t = temp;
h = hum;
t = ((temp - 0.1) + 1);
tmp_idx = t - 21;
hum_idx = h / 5 - 3;
if (WBGT[tmp_idx][hum_idx] <= 24)
{
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, HIGH);
bz_pat = 0x00;
}
else if ((WBGT[tmp_idx][hum_idx] > 24) && (WBGT[tmp_idx][hum_idx] <= 27))
{
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
bz_pat = 0x00;
}
else if ((WBGT[tmp_idx][hum_idx] > 27) && (WBGT[tmp_idx][hum_idx] <= 30))
{
digitalWrite(7, HIGH);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
bz_pat = 0x55;
}
else
{
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
bz_pat = 0xff;
}
timer = 0;
}
if (digitalRead(6) == ON) {
sw_timer = 0;
while(sw_timer <= 50);
if (digitalRead(6) == OFF) {
if (bz_ctrl == ON) {
bz_ctrl = OFF;
digitalWrite(13, LOW);
}
else {
bz_ctrl = ON;
digitalWrite(13, HIGH);
}
}
}
}
5.最後に
今回は息子の夏休みの宿題として、製作してみましたが、タイマーやセンサとの通信などを使用し、製作しているのでマイコン制御を勉強するにはよい教材だと思います。今回の記事がマイコン制御を勉強するのに少しでも参考になってくれれば幸いです。
投稿者の人気記事
-
keiske-hongyo
さんが
2021/08/13
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する