kueika が 2021年02月28日17時43分24秒 に編集
ソースコードをの不備を若干修正
記事種類の変更
製作品
本文の変更
# はじめに コロナでのテレワークの増加で、家での作業時間が増加している方々が多くなったと考えられます。 テレワークが本格導入されていろいろなメリット、デメリットがあることがわかってきました。 以下にテレワークのメリット、デメリットを列挙してみます **メリット** - 使い慣れたデスクでの作業 - 休憩がとりやすくなった - 通勤・通学時間が無くなり、寝られる時間が増えた **デメリット** - 職場、学校とは異なり作業にどのくらい取り組んだかが把握しずらく、長時間の労働になってしまう - 自己管理が苦手な人には作業の効率が落ちてしまう可能性がある - 目が行き届かないので困っている人がいたときに助けにくい 今回はデメリットの一つである長時間の労働になることを防ぐことができるように、 デスクでの作業時間を計測することができるシステムを作ってみました 概略図(下手でごめんなさい・・・) ![システムの想定状況](https://camo.elchika.com/7db1208d3d3872b9098b249f38fe114a215f3ea6/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35636564316563632d333135302d346661322d383937642d6261616535333137396434392f31353864626433642d393233662d343166612d383964392d313666343866373866393530/) 以下が制作したシステムを設置した写真となります ![実際に設置した写真](https://camo.elchika.com/ae302ec8db5258e3502bbc59a0b98813a2cbdbb6/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35636564316563632d333135302d346661322d383937642d6261616535333137396434392f31663736383462632d623166622d346465372d393062322d666338393130373235653665/) # システムの流れ 1. ToFとPIRセンサを用いて設置場所に人がいるかを判別 2. ToFとPIRセンサのどちらでも人がいると判断出来たら、作業時間を増やしていく 3. 離席しているとき(両方で人がいる判定が真でないとき)離席時間を増やしていく 4. 一定の連続時間を超えて離席と判定されたら、作業時間をリセットしてを全体の時間に計上する ![LCDの画面](https://camo.elchika.com/67661ebe9c088a4d36817513a8af6f87f9b603ab/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35636564316563632d333135302d346661322d383937642d6261616535333137396434392f32666361666537622d366338322d343533382d623665392d303832316437353863646361/) Status がSensingと表示された時にはPIRセンサが人を感知している状態です ToF lengthが障害物(人)との距離を示しています Work Timeが一セッションごとの作業時間でLeft Timeが連続離席時間です ALL Time が全体の作業時間となります # 使用したデバイス **[M5StickC](https://www.switch-science.com/catalog/5517/)** ![キャプションを入力できます](https://camo.elchika.com/67b5bba08c1787c3fe8ebf46fd6b926b66df12c6/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35636564316563632d333135302d346661322d383937642d6261616535333137396434392f31363366646338352d353732662d343935302d623038652d383434323634613837643734/) **[M5Stack PIR Motion Unit](https://www.switch-science.com/catalog/5697/)** ![キャプションを入力できます](https://camo.elchika.com/604b71f31fd504819ad241160e53a669fc4600a3/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35636564316563632d333135302d346661322d383937642d6261616535333137396434392f62366137336463642d623032382d346164632d393839342d363066656666346530383230/) **[M5StickC ToF HAT](https://www.switch-science.com/catalog/6059/)** ![キャプションを入力できます](https://camo.elchika.com/b1e1159527fa120486288d8ac40c7ce45391a20a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35636564316563632d333135302d346661322d383937642d6261616535333137396434392f36323964636636612d326661662d346136342d393730622d343736666637613862613639/) # なぜPIRのみで作らないのか PIRセンサ自体の信頼性があまり高くなかったため、設置場所から人が座った時の距離の変化も条件に付けくわえることでできる限り正確に記録をつけたかったからです 手をかざしているときでも感知していないと表されていることが下の写真からもわかります 手をかざしていても感知していない↓ ![PIRの動作が不安定である画像](https://camo.elchika.com/164f2cf619bcaa97d38bc9bd8cf1ceb0d57eb5ad/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f35636564316563632d333135302d346661322d383937642d6261616535333137396434392f39633635666563302d303066632d343936642d623065642d616539316562346466393261/) # ソースコード GitHubにも上げる予定 ```arduino:M5stickCのソースコード #include <M5StickC.h> #include <Wire.h> #include <VL53L0X.h> boolean count_flag = false; // ToFセンサで計測可能な限界距離 int tof_max_length = 8190; int tof_setting_position = 700; // 座っている時間 int count = 0; // 離席している連続時間 int left_time = 0; int positionX = 0; int all_time = 0; // ToF Sensor VL53L0X sensor; TFT_eSprite img = TFT_eSprite(&M5.Lcd); void setup() { Serial.begin(115200); Wire.begin(0, 26, 100000); M5.begin(); M5.Lcd.setRotation(3); M5.Lcd.setTextColor(YELLOW); M5.Lcd.setCursor(65, 10); M5.Lcd.setTextColor(WHITE); pinMode(33, INPUT); sensor.setTimeout(500); if (!sensor.init()) { img.setCursor(10, 10); img.print("Failed"); img.pushSprite(0, 0); Serial.println("Failed to detect and initialize sensor!"); while (1) {} } // Start continuous back-to-back mode (take readings as // fast as possible). To use continuous timed mode // instead, provide a desired inter-measurement period in // ms (e.g. sensor.startContinuous(100)). sensor.startContinuous(); } void loop() { uint16_t distance = sensor.readRangeContinuousMillimeters(); Serial.print(distance); if (sensor.timeoutOccurred()) { Serial.print(" TIMEOUT"); } Serial.println(); M5.Lcd.setCursor(0, 5); M5.Lcd.print("Status: "); M5.Lcd.setCursor(0, 15); M5.Lcd.print("Value: "); M5.Lcd.setCursor(0, 25); M5.Lcd.print("ToF length: "); M5.Lcd.setCursor(0, 45); M5.Lcd.print("Work Time: "); M5.Lcd.setCursor(0, 55); M5.Lcd.print("Left Time: "); M5.Lcd.setCursor(0, 65); M5.Lcd.print("All Time: "); M5.Lcd.fillRect(75, 5, 200, 25, BLACK); M5.Lcd.fillRect(75, 15, 200, 25, BLACK); M5.Lcd.fillRect(75, 25, 200, 25, BLACK); M5.Lcd.fillRect(75, 45, 200, 25, BLACK); M5.Lcd.fillRect(75, 55, 200, 25, BLACK); M5.Lcd.fillRect(75, 65, 200, 25, BLACK); if (digitalRead(33) == 1) { M5.Lcd.setCursor(75, 5); M5.Lcd.print("Sensing"); M5.Lcd.setCursor(75, 15); M5.Lcd.print("1"); M5.Lcd.setCursor(75, 25); M5.Lcd.print(distance); M5.Lcd.setCursor(75 + positionX, 45); M5.Lcd.print(count); M5.Lcd.setCursor(75, 55); M5.Lcd.print(left_time); M5.Lcd.setCursor(75, 65); M5.Lcd.print(all_time); Serial.println("PIR Status: Sensing"); Serial.println(" value: 1"); } else { M5.Lcd.setCursor(75, 5); M5.Lcd.print("Not Sensed"); M5.Lcd.setCursor(75, 15); M5.Lcd.print("0"); M5.Lcd.setCursor(75, 25); M5.Lcd.print(distance); M5.Lcd.setCursor(75 , 45); M5.Lcd.print(count); M5.Lcd.setCursor(75, 55); M5.Lcd.print(left_time); M5.Lcd.setCursor(75, 65); M5.Lcd.print(all_time); Serial.println("PIR Status: Not Sensed"); Serial.println(" value: 0"); }
// pir & tof どちらかが人の存在を感知しているとき
// pir & tof 両方でが人の存在を感知しているとき
if (digitalRead(33) == 1 && distance < tof_setting_position) { count++; left_time = 0; } else { // 離席時間が5分以上なら・・・ 作業時間の一つが終了 left_time++;
if (left_time > 20) {
if (left_time > 300) {
count_flag = true; all_time = count; } } if (count_flag) { Serial.println("Work Session END"); count = 0; left_time = 0; count_flag = false; } Serial.print("passed time: "); Serial.println(count); Serial.print("left time: "); Serial.println(left_time); delay(1000); M5.update(); } ``` # まとめ・今後の展望 ひとまず、目的の要件を満たしたシステムを作ることができました。 今後の展望としては計測を長期で行い、MQTTでデータを送信してデータベースでためていくことで月ごとのデスクでの作業時間が閲覧できるようにシステムを拡張していきたいと思います。