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

forest516 が 2021年02月20日23時10分09秒 に編集

初版

タイトルの変更

+

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

タグの変更

+

秋葉原2021

+

M5Stack

+

ソレノイド

メイン画像の変更

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

記事種類の変更

+

製作品

本文の変更

+

# 動機 天気をあれこれする子たちいわく、ただの空模様に心を動かされてしまうらしい。晴れると気持ちが良くなるよね。ならばそれをいつでもできるようになれば、どこでも気分を盛り上げることが…。なんてことはなく、愛と、天気を変える瞬間を体験したい思いだけで、僕にできることをやった結果。 # 再現方法の選定 ## 雨音の再現 ビーズを紐に結んだりなど色々試してみた結果、**針金が直接傘を叩く音**が一番近いという結論に。 ### 材料 - 針金 - プラバン - 結束バンド - ソレノイド - サーボモータの丸型ホーン - ガムテープ 1. プラバンを円形に切り、適当な長さの針金を括り付けていく(向きを整えるガイドとして結束バンドで固定) 2. サーボモータの丸型ホーンを繋ぎとして、針金を取り付けた円盤をソレノイドに固定する 3. ソレノイドと傘は、ガムテープで固定 4. ソレノイドを上下運動させると、針金が揺れて傘を叩く ![キャプションを入力できます](https://camo.elchika.com/e2aa93136042c5956f5485130d49d7f2326dc806/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f36303462343862342d323030302d343165322d623339622d6663343731376331313138372f32393039633736302d323539332d343330642d623632352d333161373634613132623134/) ## 祈りの再現 **手を組んで、一定時間祈ること**を再現したいため、湿度センサーを選択。 手でくるむと、じわじわと湿度が上がっていくので、適当に決めたしきい値を超えるとソレノイドを止める=晴れにすることにする。 # 回路部仕組み ## 材料 - M5GO[[M5GO IoTスターターキット](https://www.switch-science.com/catalog/3875/)] - 温湿度センサー[M5Go IoTスターターキット内のENVセンサー] - モータードライバ[[PU-2709](https://www.elekit.co.jp/product/PU-2709)] - ソレノイド[[CBS07300140](http://www.takaha.co.jp/SHOP/cbs0730.html)] - モバイルバッテリー(PD対応) - Type-C USBテスター[TC66C] (モバイルバッテリーから指定電圧を出力させるために使用) - micro SDカード ## 構成 ![構成図](https://camo.elchika.com/29529cc3e9a78d5d566e855d171b5f04dfa69e5a/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f36303462343862342d323030302d343165322d623339622d6663343731376331313138372f35626139366464612d303535392d346135362d613663612d636665613034373761663730/) - ソレノイドの電源をモバイルバッテリーから9Vとる - GNDは 共通化する ## プログラム - hum_thresholdが湿度のしきい値 - 演出として、SDカードに保存したイラストを画面に表示することで、現在の状態を示す - 演出として、M5GOのLEDバーの色を雨と晴れで変更させる ```arduino #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(); } ``` ## 実際の挙動 @[youtube](https://www.youtube.com/watch?v=ETepJujUFIk&feature=youtu.be)