つくった理由
最近、授業はオンラインになり、仕事はテレワークと、家にいる時間が多くなりました。
そうなると、この寒い季節、または、暑い季節には外は実は適温なのに、エアコンをつけっぱなしにしてしまったり、外がジメジメとしているのに洗濯ものを干しっぱなしにしてしまったり、していませんか?私はしょっちゅうこんなことをしてしまって、電気代がとても高くなったり、洗濯物が生乾きになったりと、まぁ困っていました。そこで、室内にいても常に外の今の気温や湿度がわかるようなものを製作しようと考えました。
製作物
なるべく小さく、かつ、部屋に置いておいても気にならないものをつくりたかったので、M5 ATOM LiteとM5 ATOM Matrix、ENV2ユニットを使用しました。ATOMはとてもシンプルで小さく、部屋のどこに置いてあってもその空間に馴染んでくれます。
上の写真の左側のユニットは室外用で、ベランダの壁に貼ることを想定しています。また、右側のATOM Matrixは、室内で外の気候をモニターするために使用します。
表示には数字を使わず、色と場所で気温と湿度を表現しています。実際の動作動画はこちらから。きれいですね。
しくみ
構成はこのようになっています。ENV.2のSHT3XとATOM LiteがIICで通信、気温と湿度を取得します。その後、WiFiのAPとして起動してあるATOM Matrixに接続し、UDP通信で気温と湿度をMatrixに送信、表示します。
まずはLite側のソースコードを置いておきます。
Lite.ino
/************************************************
Lite.ino
*************************************************
receive tmp, humid and send them to ATOMMatrix
*************************************************
AkubiCot
************************************************/
#include <M5Atom.h>
// WiFi
#include <WiFi.h>
#include <WiFiudp.h>
// ENV.2
#include "Adafruit_Sensor.h"
#include "SHT3X.h"
SHT3X sht30;
// sensor settings
float tmp = 0.0;
float hum = 0.0;
float tmpavg=0.0;
float humavg=0.0;
// WiFi settings
const char *ssid = "hogehoge";
const char *pass = "hogehoge";
const char *addr = "192.168.4.1";
WiFiUDP udp;
// UDP Settings
const int lite_port = 50007;
const int matrix_port = 50008;
// get sensor data
void getsensor(){
if(sht30.get()==0){
for(int i=0; i<100; i++){
tmp = sht30.cTemp; //temp[C]
hum = sht30.humidity; //humid[%]
tmpavg = tmpavg + tmp;
humavg= humavg + hum;
}
// average
tmpavg = tmpavg / 100;
humavg = humavg / 100;
}
}
void setup() {
M5.begin(true, true, true);
Wire.begin();
WiFi.begin(ssid, pass);
delay(50);
udp.begin(lite_port);
delay(50);
Serial.begin(115200);
// batt status
M5.dis.drawpix(0, 0x0000f0);
}
void loop(){
getsensor(); // get sensor data
// send data to Matrix
udp.beginPacket(addr, matrix_port);
udp.write(tmpavg);
delay(1000);
udp.write(humavg);
delay(1000);
udp.endPacket();
delay(8000);
}
温度と湿度を取得し、送る。とても単純なプログラムです。hogehoge
部分は、Matrix側のSSID、パスワードを入力します。
次に、受信側のMatrixのコードです。
Matrix.ino
/************************************************
Matrix.ino
*************************************************
receive tmp, humid from Lite and display
*************************************************
AkubiCot
************************************************/
#include <M5Atom.h>
// WiFi
#include <WiFi.h>
#include <WiFiUdp.h>
#include <WiFiClient.h>
#include <WiFiAP.h>
// receive data settings
float rtmp = 0.0;
float rhum = 0.0;
// WiFi settings
const char *ssid = "hogehoge";
const char *pass = "hogehoge";
const IPAddress ip(192, 168 ,4 ,1 );
const IPAddress subnet(255,255,255,0);
WiFiUDP udp;
// UDP settings
const int lite_port = 50007;
const int matrix_port = 50008;
int i,j,k;
// connected
void goodcnt(){
delay(50);
for(i=10; i<15; i++){
M5.dis.drawpix(i, 0x0000f0);
}
M5.dis.drawpix(15, 0x0000f0);
M5.dis.drawpix(19, 0x0000f0);
for(j=20; j<25; j++){
M5.dis.drawpix(j, 0x0000f0);
}
}
// clear display
void clearDis(){
for(k=0; k<25; k++){
M5.dis.drawpix(k, 0x000000);
}
}
// display tmp
void tmpDis(){
if(rtmp<6.00){
M5.dis.drawpix(0, 0x0000f0);
delay(50);
}
else if(rtmp>=6.00 && rtmp<11.00){
M5.dis.drawpix(1, 0x0000f0);
delay(50);
}
else if(rtmp>=11.00 && rtmp<21.00){
M5.dis.drawpix(2, 0x00f000);
delay(50);
}
else if(rtmp>=21.00 && rtmp<31.00){
M5.dis.drawpix(3, 0x00f000);
delay(50);
}
else{
M5.dis.drawpix(0, 0xf00000);
delay(50);
}
}
// display humid
void humDis(){
if(rhum<20.00){
M5.dis.drawpix(5, 0x0000f0);
delay(50);
}
else if(rhum>=20.00 && rhum<40.00){
M5.dis.drawpix(6, 0x0000f0);
delay(50);
}
else if(rhum>=40.00 && rhum<60.00){
M5.dis.drawpix(7, 0x00f000);
delay(50);
}
else if(rhum>=60.00 && rhum<80.00){
M5.dis.drawpix(8, 0x00f000);
delay(50);
}
else{
M5.dis.drawpix(9, 0xf00000);
delay(50);
}
}
void setup(){
M5.begin(true, true, true);
// start WiFiAP
WiFi.softAP(ssid, pass);
delay(100);
WiFi.softAPConfig(ip, ip, subnet);
udp.begin(matrix_port);
delay(50);
Serial.begin(115200);
}
void loop(){
if(udp.parsePacket()){
rtmp = udp.read();
delay(50);
rhum = udp.read();
delay(50);
Serial.print("temp:");
Serial.println(rtmp);
Serial.print("humid:");
Serial.println(rhum);
clearDis();
tmpDis();
humDis();
goodcnt();
delay(10000);
}
// cannot connect to Lite
else{
clearDis();
M5.dis.drawpix(10, 0x00f000);
M5.dis.drawpix(14, 0x00f000);
M5.dis.drawpix(16, 0x00f000);
M5.dis.drawpix(17, 0x00f000);
M5.dis.drawpix(18, 0x00f000);
M5.dis.drawpix(20, 0x00f000);
M5.dis.drawpix(24, 0x00f000);
delay(10000);
}
}
SoftAP
でAPとして立ち上げ、外のLiteと通信します。通信できないときは下部分に赤で×が、通信できた場合は上部分に湿度と気温、下部分に〇が表示されます。きれいです。
終わりに
10秒ごとに更新するプログラムとなっていますが、この更新するタイミングで一度Matrix側のLEDがすべて消えてしまうので、少し気になります。また、起動するタイミングが悪いと、delay
を使用しているので、LiteとMatrixの接続に10秒ほどかかります。このあたり、今後直していきたいと考えています。あと、外に設置するLiteが丸裸でかわいそうなので、ケース製作にも挑戦したいですね。
ここまでご覧いただき、ありがとうございました。
-
AkubiCot
さんが
2021/02/28
に
編集
をしました。
(メッセージ: 初版)
-
AkubiCot
さんが
2021/02/28
に
編集
をしました。
-
AkubiCot
さんが
2021/02/28
に
編集
をしました。
ログインしてコメントを投稿する