前回M5StickCで作ったWBGT警報機。
ちょこっと改良したのでご紹介。
追加機能①:カラーバー追加
WBGTの値によって背景の色を変えていましたが、単体で見ると微妙に分かりにくかったので、
下にカラーバーとして表示する色を一通り出しておきました。わかりやすくなった…と思う。
オマケ:M5StickC標準の表示色
このあたりに、LCDに表示する色として標準で登録されている色が載ってますが、いまいちどんな色か分かりにくかったので、
(色の表現がR:5ビット、G:6ビット、B:5ビットなのでPCでのRGB表記とも違います)
一覧表にしました。
(PC・スマホの画面や印刷とM5StickCの液晶とも完全に同じ色ではないです…目安程度に)
追加機能②:不快指数に対応
もうひとつ、蒸し暑さを定量的に表す数値として不快指数があります。
不快指数も気温と湿度から求められます。こちらはよく知られた数式があります。
$$DI = 0.81T_d + 0.01H (0.99T_d – 14.3) + 46.3$$
$T_d$が気温、$H$が湿度です。
こちらは画面背景色を8段階で表示しました。
(~60:シアン(水色)、60~65:緑、65~70:黄緑、70~75:黄色、75~80:オレンジ、80~85:赤、85~90:紫、90~:茶色)
カラーバーをWBGT表示モードと全くの別物(色数もバーの幅が違う表示)にすることで、一目でモードが分かるようにしました。
アラームについて
前回、応用アイデアとして「アラームを鳴らす」ということに触れましたが、M5StickCには内蔵スピーカーがないのでそのままでは鳴らせません。(外付けスピーカーが要る)
一方、M5Stackならスピーカーが付いてますしMicroSDカードも使える(wavファイル等の再生で実現できる)ので、アラームを盛り込むならこっちの方がよさそうです。
また今度M5Stackでも作ってみます。
液晶画面もM5Stackの方が大きいので視認性もよさそうですね。あと背面に磁石が入っているので冷蔵庫とかスチールラックに貼り付けれます。
→M5StickCにも磁石入ってました。どっちも冷蔵庫とかスチールラックとかにくっつきます。
スケッチ
以上2点を盛り込んで、こんな感じです。
M5StickC正面の「M5」ボタンを押すと、WBGTモードと不快指数モードを切り替えできます。
(ボタンを押している間はカラーバーが全体に表示され、ボタンを離すと測定値を表示します。)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 | #include <M5StickC.h> #include "DHT12.h" #include <Wire.h> #include "Adafruit_Sensor.h" #include <Adafruit_BMP280.h> DHT12 dht12; Adafruit_BMP280 bme; #define refreshRate 5000 long timer = 0; //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}}; void setup() { M5.begin(); Wire.begin(0,26); M5.Lcd.setRotation(3); M5.Lcd.setTextColor(BLACK); pinMode(M5_BUTTON_HOME, INPUT); if (!bme.begin(0x76)){ Serial.println("Could not find a valid BMP280 sensor, check wiring!"); while (1); } Serial.print("\n\rCalibrate done.."); M5.Lcd.fillRect( 0, 0, 32, 80, CYAN); M5.Lcd.fillRect( 32, 0, 32, 80, GREEN); M5.Lcd.fillRect( 64, 0, 32, 80, YELLOW); M5.Lcd.fillRect( 96, 0, 32, 80, ORANGE); M5.Lcd.fillRect(128, 0, 33, 80, RED); timer = millis(); } void loop() { //表示モード 0:WBGT 1:不快指数(DI) static int ViewMode = 0; //温度データ取得 float tmp = dht12.readTemperature(); //温度データを小数点以下切り上げ int tmp_i = (tmp-0.1) + 1; //温度インデックス int index_tmp = tmp_i - 21; //湿度データ取得 float hum = dht12.readHumidity(); //湿度データを整数型に int hum_i = hum; //湿度インデックス int index_hum = hum / 5 - 3; //WBGT表示値 int WBGT_V = WBGT[index_tmp][index_hum]; //不快指数 int DI = 0.81*tmp+0.01*hum*(0.99*tmp-14.3)+46.3; //M5ボタンでモード切替 if(digitalRead(M5_BUTTON_HOME) == LOW){ ViewMode++; if(ViewMode==2) ViewMode=0; switch(ViewMode){ case 0: //WBGTモード M5.Lcd.fillRect( 0, 0, 32, 80, CYAN); M5.Lcd.fillRect( 32, 0, 32, 80, GREEN); M5.Lcd.fillRect( 64, 0, 32, 80, YELLOW); M5.Lcd.fillRect( 96, 0, 32, 80, ORANGE); M5.Lcd.fillRect(128, 0, 32, 80, RED); break; case 1: //不快指数モード M5.Lcd.fillRect( 0, 0, 20,80,CYAN); M5.Lcd.fillRect( 20, 0, 20,80,GREEN); M5.Lcd.fillRect( 40, 0, 20,80,GREENYELLOW); M5.Lcd.fillRect( 60, 0, 20,80,YELLOW); M5.Lcd.fillRect( 80, 0, 20,80,ORANGE); M5.Lcd.fillRect(100, 0, 20,80,RED); M5.Lcd.fillRect(120, 0, 20,80,PURPLE); M5.Lcd.fillRect(140, 0, 20,80,MAROON); break; } while(digitalRead(M5_BUTTON_HOME)==LOW){} //モード切替後、すぐに表示させる timer -= 5000; } //画面描画 if(millis()>timer+refreshRate){ timer = millis(); switch(ViewMode){ case 0: //WBGTモード if(WBGT_V<=20){ M5.Lcd.fillRect(0,0,160,70,CYAN); }else if(WBGT_V>20 && WBGT_V<=24){ M5.Lcd.fillRect(0,0,160,70,GREEN); }else if(WBGT_V>24 && WBGT_V<=27){ M5.Lcd.fillRect(0,0,160,70,YELLOW); }else if(WBGT_V>27 && WBGT_V<=30){ M5.Lcd.fillRect(0,0,160,70,ORANGE); }else{ M5.Lcd.fillRect(0,0,160,70,RED); } M5.Lcd.setCursor(5, 50 ,2); M5.Lcd.printf("WBGT-------------------"); M5.Lcd.setCursor(95, 15 ,6); M5.Lcd.printf("%d",WBGT_V); break; case 1: //不快指数モード if(DI<=54){ M5.Lcd.fillRect(0,0,160,70,CYAN); }else if(DI<=60){ M5.Lcd.fillRect(0,0,160,70,GREEN); }else if(DI<=65){ M5.Lcd.fillRect(0,0,160,70,GREENYELLOW); }else if(DI<=70){ M5.Lcd.fillRect(0,0,160,70,YELLOW); }else if(DI<=75){ M5.Lcd.fillRect(0,0,160,70,ORANGE); }else if(DI<=80){ M5.Lcd.fillRect(0,0,160,70,RED); }else if(DI<=85){ M5.Lcd.fillRect(0,0,160,70,PURPLE); }else{ M5.Lcd.fillRect(0,0,160,70,MAROON); } M5.Lcd.setCursor(5, 50 ,2); M5.Lcd.printf("DI-----------------------"); M5.Lcd.setCursor(95, 15 ,6); M5.Lcd.printf("%d",DI); break; } M5.Lcd.setCursor(5, 10 ,2); M5.Lcd.printf("Temp: %2.1fC", tmp); M5.Lcd.setCursor(5, 30 ,2); M5.Lcd.printf("Humid: %2.0f%%", hum); } } |
コメント