jeffy が 2021年02月27日22時17分24秒 に編集
回路図とコードを更新しました
記事種類の変更
製作品
本文の変更
# はじめに 冬至を挟んだある程度の期間は日が昇るのが遅く,朝起きてもまだまだ暗かったりします.そんなときにベッド横から太陽光と同じ光を浴びれば,きっと明るく一日が始まるはずです.なので暗い朝を明るく照らすデバイスを作りました. # どんなデバイスか ![動作の様子](https://camo.elchika.com/b1540ef4a3c5c2a85fa6e6334433b50d755847b2/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f64373230643161362d303138372d346538382d396438332d6436616663373764613736652f34303936336431342d333761342d343935372d393934382d623332336166323764653733/) [動作時の動画](https://twitter.com/jeffy890765/status/1360799117874634752?s=20) 起きるべき時間になると目覚まし時計に連動し,太陽光に近い波長の光を出します.出てくる光を横向きに曲げるために反射板が動きます. 寝る前にデバイスの電源をオンにしておき,目覚まし時計の隣に置いておけば,太陽や天気に関わらず明るい朝を迎えられます. # 構成の詳細 ## LED部分 ![LED部分](https://camo.elchika.com/e8461c87e6e28c20c89362be69cc815ec71e6b44/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f64373230643161362d303138372d346538382d396438332d6436616663373764613736652f35323562343239382d396462392d343030642d386536392d333638613062653861383334/) 今回のデバイスに使用したLEDは,秋月電子で販売されている[豊田合成の太陽光LED](https://akizukidenshi.com/catalog/g/gI-15528/)です.それを[定電流源IC](https://akizukidenshi.com/catalog/g/gI-06133/)により駆動しています. LED3つを直列に接続し,それに対して定電流源ICを3つ並列に接続することで60mAの電流が流れるようにしています.それが3列並んでいます.それぞれにはArduinoボードのDCプラグからの12Vがかかるようにしています. どちらも表面実装部品ですが,気合で通常の基板に実装しています.多少の歪みはしょうがないです. LEDは上向きに実装してあるため,その光軸を横向きにするために,アルミ板を小さく切って反射板として取り付けています.反射板はサーボモータに取り付けており,LEDと連動して発光時に適切な角度に調節されます. ## マイクで連動 ![マイク](https://camo.elchika.com/20b215d4b8e59c043e8aaa3ece168c723e91c552/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f64373230643161362d303138372d346538382d396438332d6436616663373764613736652f62383730666336382d663530322d343430382d386536352d663033333135613630653732/) 今回使用しているボードにはESP32が載っています.最初はこれをネットに繋いで時間を取得して光を出そうと思っていたのですが,その作業がめんどくさくなってしまったので計画を変更しました. 起きるときには目覚まし時計が鳴っているはずです.その音をマイクで取得し,FFTにより目覚まし時計の音だと判断してLEDを発光させることにしました.そのために[このページ](http://pages.switch-science.com/letsiot/sound/)を参考に目覚まし時計の音の周波数を確認し,その周波数で反射板とLEDが動作するようにしました. せっかくESP32を使っているのにその良さを全然使ってない気がしますが,それについては今後の改良でなんとかなるはずです.
# 回路図 今回作製したデバイスの回路図が以下になります.LEDと定電流源ICにはACアダプタから12Vを供給し,その後にMOSFETを使用して全体のオンオフを制御しています.回路図中ではLEDと定電流源ICは1セットしかありませんが,実際には3セットあります.
![回路図](https://camo.elchika.com/573d027ac622b36a5c9971014468f6cad630ac9c/687474703a2f2f73746f726167652e676f6f676c65617069732e636f6d2f656c6368696b612f76312f757365722f64373230643161362d303138372d346538382d396438332d6436616663373764613736652f62366262633166612d323930382d343633302d616435362d376535313765346335663963/)
# まとめ いつでも明るい朝が迎えられるように,起きるべき時間になると明るく照らしてくれるデバイスを作りました.これで外が暗くても,天気が悪くても明るい朝を迎えられます.今後はESP32をより使用して,ネット経由で動作時刻の設定ができるようにしていきたいです. 注意事項としては,朝が明るくなっても,起きられるかどうかはやはり本人次第である,ということです.
# 参考文献とコード
# 参考文献,コード
[1] AmbientでIoTをはじめよう http://pages.switch-science.com/letsiot/sound/
[2] コード https://github.com/jeffy890/artif_light
[2] コード https://github.com/jeffy890/artif_light ``` #include "arduinoFFT.h" #include <Servo.h> #define SAMPLING_FREQUENCY 10000 #define MIC 36 const uint16_t FFTsamples = 256; double vReal[FFTsamples]; double vImag[FFTsamples]; arduinoFFT FFT = arduinoFFT(vReal, vImag, FFTsamples, SAMPLING_FREQUENCY); Servo servo; unsigned int sampling_period_us; float dmax = 5.0; float value = 0; void sample(int nsamples) { for (int i = 0; i < nsamples; i++) { unsigned long t = micros(); vReal[i] = (double)analogRead(MIC) / 4095.0 * 3.6 + 0.1132; vImag[i] = 0; while ((micros() - t) < sampling_period_us) ; } } void DCRemoval(double *vData, uint16_t samples) { double mean = 0; for (uint16_t i = 1; i < samples; i++) { mean += vData[i]; } mean /= samples; for (uint16_t i = 1; i < samples; i++) { vData[i] -= mean; } } bool judgeFreq(int nsamples) { for (int band = 0; band < nsamples; band++) { float d = vReal[band]; if (d > dmax) { value = (band * 1.0 * SAMPLING_FREQUENCY) / FFTsamples / 1000; Serial.print(d); Serial.print(" "); Serial.println(value); if (value > 1.8 && value < 2.2) { return true; } } } return false; } void setup() { pinMode(MIC, INPUT); pinMode(27, OUTPUT); digitalWrite(27, LOW); // set led pin low(mosfet is off) servo.attach(13); servo.write(90); // set servo position sampling_period_us = round(1000000 * (1.0 / SAMPLING_FREQUENCY)); //Serial.begin(9600); } void loop() { digitalWrite(27, LOW); servo.write(90); sample(FFTsamples); DCRemoval(vReal, FFTsamples); FFT.Windowing(FFT_WIN_TYP_HAMMING, FFT_FORWARD); FFT.Compute(FFT_FORWARD); FFT.ComplexToMagnitude(); bool judge = judgeFreq(FFTsamples / 2); if (judge == true) { digitalWrite(27, HIGH); for (int i = 0; i < 45; i++) { servo.write(i); } delay(6000); } } ```