編集履歴一覧に戻る
keiske-hongyoのアイコン画像

keiske-hongyo が 2021年08月13日18時15分09秒 に編集

初版

タイトルの変更

+

簡易WBGT警報機の製作

タグの変更

+

Seeeduino

+

Xiao

+

BME280

メイン画像の変更

メイン画像が設定されました

記事種類の変更

+

製作品

本文の変更

+

## 1. はじめに 今回は息子が夏休みの課題で「生活に役に立つものを製作しなさい」があったので、いろいろと考え、この時期は熱中症になる可能性が高いので、暑さ指数(WGBT)から暑さの警戒レベルをLEDで表示し、最高レベルになるとブザーで知らせるものを製作することにしました。 ## 2.使用部品について 今回の回路には表1に示す部品を使用しました。 |使用部品|名称|備考| |---|---|---| |マイコン|Seeeduino Xaio|秋月電子で購入| |温度・湿度センサ|AKI-BME280|秋月電子で購入| |抵抗|1kΩ|LEDの電流制御用| |抵抗|10kΩ|トランジスタのプルダウン抵抗| |トランジスタ|2SC1815|ブザーのドライブ用| |スイッチ|タクトスイッチ|ブザー制御用| ## 3. 回路について 回路図を図1に示します。電源についてはSeeeduino XaioのUSB端子からとっています。 ![図1 簡易WBGT警報機回路図](https://camo.elchika.com/dc0521214df5f34c3f534613edce51de74dfc017/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f33646164353039642d616133622d343132302d616433622d6638623565376137366139332f62313062333739382d346565332d343135392d613361612d613630353366346438393139/) ## 4.動作について センサから温度・湿度の情報を取得して、そのデータをもとにWBGTを求め、その結果を3段階に分別し、LEDを点灯させます。また、最高レベルになるとブザーで知らせるようにしています。 WGBTのデータについては[Symamoneさん製作された簡易WBGT警報機の製作ページ](https://symamone-tec.com/measuring_wbgt_m5stick-c/)のデータを使用させていただいています。また、WGBTのテーブル処理方法も使用させてもらっています。感謝です。 ## 5. プログラムについて 今回もArduinoを使用して、プログラムを作成しました。とりあえず、動作確認用で作成したのでプログラムは汚いです…。 ```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.最後に  今回は息子の夏休みの宿題として、製作してみましたが、タイマーやセンサとの通信などを使用し、製作しているのでマイコン制御を勉強するにはよい教材だと思います。今回の記事がマイコン制御を勉強するのに少しでも参考になってくれれば幸いです。