forest516のアイコン画像
forest516 2021年02月20日作成
製作品 製作品 閲覧数 1131
forest516 2021年02月20日作成 製作品 製作品 閲覧数 1131

天気を雨から晴れにするのを体験できる傘

天気を雨から晴れにするのを体験できる傘

動機

天気をあれこれする子たちいわく、ただの空模様に心を動かされてしまうらしい。晴れると気持ちが良くなるよね。ならばそれをいつでもできるようになれば、どこでも気分を盛り上げることが…。なんてことはなく、愛と、天気を変える瞬間を体験したい思いだけで、僕にできることをやった結果。

再現方法の選定

雨音の再現

ビーズを紐に結んだりなど色々試してみた結果、針金が直接傘を叩く音が一番近いという結論に。

材料

  • 針金
  • プラバン
  • 結束バンド
  • ソレノイド
  • サーボモータの丸型ホーン
  • ガムテープ
  1. プラバンを円形に切り、適当な長さの針金を括り付けていく(向きを整えるガイドとして結束バンドで固定)
  2. サーボモータの丸型ホーンを繋ぎとして、針金を取り付けた円盤をソレノイドに固定する
  3. ソレノイドと傘は、ガムテープで固定
  4. ソレノイドを上下運動させると、針金が揺れて傘を叩く

キャプションを入力できます

祈りの再現

手を組んで、一定時間祈ることを再現したいため、湿度センサーを選択。
手でくるむと、じわじわと湿度が上がっていくので、適当に決めたしきい値を超えるとソレノイドを止める=晴れにすることにする。

回路部仕組み

材料

  • M5GO[M5GO IoTスターターキット]
  • 温湿度センサー[M5Go IoTスターターキット内のENVセンサー]
  • モータードライバ[PU-2709]
  • ソレノイド[CBS07300140]
  • モバイルバッテリー(PD対応)
  • Type-C USBテスター[TC66C] (モバイルバッテリーから指定電圧を出力させるために使用)
  • micro SDカード

構成

構成図

  • ソレノイドの電源をモバイルバッテリーから9Vとる
  • GNDは 共通化する

プログラム

  • hum_thresholdが湿度のしきい値
  • 演出として、SDカードに保存したイラストを画面に表示することで、現在の状態を示す
  • 演出として、M5GOのLEDバーの色を雨と晴れで変更させる
#include <M5Stack.h> #include <Adafruit_NeoPixel.h> #include "DHT12.h" #define M5GO_NUM_LEDS 10 #define M5GO_DATA_PIN 15 #define SOLENOID 26 Adafruit_NeoPixel ledBar = Adafruit_NeoPixel(M5GO_NUM_LEDS, M5GO_DATA_PIN, NEO_GRB + NEO_KHZ800); DHT12 dht12; //Preset scale CELSIUS and ID 0x5c. float hum_threshold = 20.0; boolean raining = false; boolean sole_tgle = true; // 画像の描画する座標 int image_x = 44; int image_y = 0; // ledBar int gray_r = 216; int gray_g = 214; int gray_b = 213; // デバッグ用 boolean debug_mode = false; // 文字位置 int text_x = 280; int text_y = 0; int text_line = 16; // バー位置 int bar_x = 280; int bar_y = text_y + text_line*2; int bar_w = 35; int bar_h = 200; void setup() { M5.begin(); M5.Power.begin(); Wire.begin(); ledBar.begin(); pinMode(SOLENOID, OUTPUT); M5.Lcd.setBrightness(10); Serial.println(F("ENV Unit(DHT12 and BMP280) test...")); M5.Lcd.clear(WHITE); } void loop() { // float tmp = dht12.readTemperature(); float hum = dht12.readHumidity(); // Serial.printf("Temperatura: %2.2f*C Humedad: %0.2f%%\r\n", tmp, hum); // デバッグ if (debug_mode == true) { M5.Lcd.fillRect(bar_x, bar_y, 320, 240, WHITE); M5.Lcd.setTextColor(BLACK, WHITE); M5.Lcd.setTextSize(2); M5.Lcd.setCursor(text_x, text_y); M5.Lcd.printf("%2.0f%%", hum); M5.Lcd.setCursor(text_x, text_y + text_line); M5.Lcd.printf("%2.0f%%", hum_threshold); M5.Lcd.fillRect(bar_x, bar_y + bar_h - (int)hum*2, bar_w, (int)hum*2, GREEN); M5.Lcd.drawRect(bar_x, bar_y, bar_w, bar_h, BLUE); int bar_t = bar_y + bar_h - (int)hum_threshold*2; M5.Lcd.drawLine(bar_x, bar_t, bar_x + bar_w, bar_t, RED); } if ( hum >= hum_threshold ) { raining = false; Serial.println("weather is sun"); } if (raining == true) { rainSole(); M5.Lcd.drawJpgFile(SD, "/mark_tenki_umbrella.jpg", image_x, image_y); setLedBarColor(0, 0, 255); switch ( (int)(hum_threshold - hum) ){ case 0: case 1: ledBar.setPixelColor(3, ledBar.Color(gray_r, gray_g, gray_b)); ledBar.setPixelColor(M5GO_NUM_LEDS - 4, ledBar.Color(gray_r, gray_g, gray_b)); case 2: ledBar.setPixelColor(2, ledBar.Color(gray_r, gray_g, gray_b)); ledBar.setPixelColor(M5GO_NUM_LEDS - 3, ledBar.Color(gray_r, gray_g, gray_b)); case 3: case 4: case 5: ledBar.setPixelColor(1, ledBar.Color(gray_r, gray_g, gray_b)); ledBar.setPixelColor(M5GO_NUM_LEDS - 2, ledBar.Color(gray_r, gray_g, gray_b)); case 6: case 7: case 8: ledBar.setPixelColor(0, ledBar.Color(gray_r, gray_g, gray_b)); ledBar.setPixelColor(M5GO_NUM_LEDS - 1, ledBar.Color(gray_r, gray_g, gray_b)); ledBar.show(); break; } } else if (raining == false) { digitalWrite(SOLENOID, LOW); M5.Lcd.drawJpgFile(SD, "/mark_tenki_hare.jpg", image_x, image_y); setLedBarColor(255, 60, 46); if ( hum < hum_threshold - 10 ) { setLedBarColor(gray_r, gray_g, gray_b); } } // スイッチ操作 // update button state M5.update(); // if you want to use Releasefor("was released for"), use .wasReleasefor(int time) below if (M5.BtnA.wasReleased()) { raining = true; Serial.println("reset"); } else if (M5.BtnB.wasReleased()) { if (debug_mode) { hum_threshold--; } } else if (M5.BtnC.wasReleased()) { if (debug_mode) { hum_threshold++; } } else if (M5.BtnB.wasReleasefor(700)) { debug_mode = !debug_mode; Serial.printf("debug:%d\n", debug_mode); if (debug_mode == false) { M5.Lcd.fillRect(text_x, text_y, 320, 240, WHITE); } } delay(50); } void rainSole(void) { if (sole_tgle) { digitalWrite(SOLENOID, HIGH); } else { digitalWrite(SOLENOID, LOW); } sole_tgle = !sole_tgle; } void setLedBarColor(int r, int g, int b) { for (int i=0; i < M5GO_NUM_LEDS; i++) { ledBar.setPixelColor(i, ledBar.Color(r,g,b)); } ledBar.show(); }

実際の挙動

ここに動画が表示されます

ログインしてコメントを投稿する