jeffyのアイコン画像
jeffy 2021年02月14日作成 (2021年02月27日更新)
製作品 製作品 閲覧数 995
jeffy 2021年02月14日作成 (2021年02月27日更新) 製作品 製作品 閲覧数 995

暗い朝を明るくしよう

暗い朝を明るくしよう

はじめに

冬至を挟んだある程度の期間は日が昇るのが遅く,朝起きてもまだまだ暗かったりします.そんなときにベッド横から太陽光と同じ光を浴びれば,きっと明るく一日が始まるはずです.なので暗い朝を明るく照らすデバイスを作りました.

どんなデバイスか

動作の様子
動作時の動画

起きるべき時間になると目覚まし時計に連動し,太陽光に近い波長の光を出します.出てくる光を横向きに曲げるために反射板が動きます.

寝る前にデバイスの電源をオンにしておき,目覚まし時計の隣に置いておけば,太陽や天気に関わらず明るい朝を迎えられます.

構成の詳細

LED部分

LED部分

今回のデバイスに使用したLEDは,秋月電子で販売されている豊田合成の太陽光LEDです.それを定電流源ICにより駆動しています.
LED3つを直列に接続し,それに対して定電流源ICを3つ並列に接続することで60mAの電流が流れるようにしています.それが3列並んでいます.それぞれにはArduinoボードのDCプラグからの12Vがかかるようにしています.

どちらも表面実装部品ですが,気合で通常の基板に実装しています.多少の歪みはしょうがないです.

LEDは上向きに実装してあるため,その光軸を横向きにするために,アルミ板を小さく切って反射板として取り付けています.反射板はサーボモータに取り付けており,LEDと連動して発光時に適切な角度に調節されます.

マイクで連動

マイク

今回使用しているボードにはESP32が載っています.最初はこれをネットに繋いで時間を取得して光を出そうと思っていたのですが,その作業がめんどくさくなってしまったので計画を変更しました.

起きるときには目覚まし時計が鳴っているはずです.その音をマイクで取得し,FFTにより目覚まし時計の音だと判断してLEDを発光させることにしました.そのためにこのページを参考に目覚まし時計の音の周波数を確認し,その周波数で反射板とLEDが動作するようにしました.

せっかくESP32を使っているのにその良さを全然使ってない気がしますが,それについては今後の改良でなんとかなるはずです.

回路図

今回作製したデバイスの回路図が以下になります.LEDと定電流源ICにはACアダプタから12Vを供給し,その後にMOSFETを使用して全体のオンオフを制御しています.回路図中ではLEDと定電流源ICは1セットしかありませんが,実際には3セットあります.

回路図

まとめ

いつでも明るい朝が迎えられるように,起きるべき時間になると明るく照らしてくれるデバイスを作りました.これで外が暗くても,天気が悪くても明るい朝を迎えられます.今後はESP32をより使用して,ネット経由で動作時刻の設定ができるようにしていきたいです.

注意事項としては,朝が明るくなっても,起きられるかどうかはやはり本人次第である,ということです.

参考文献,コード

[1] AmbientでIoTをはじめよう http://pages.switch-science.com/letsiot/sound/
[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);
  }
}
  • jeffy さんが 2021/02/14 に 編集 をしました。 (メッセージ: 初版)
  • jeffy さんが 2021/02/14 に 編集 をしました。
  • jeffy さんが 2021/02/27 に 編集 をしました。 (メッセージ: 回路図とコードを更新しました)
ログインしてコメントを投稿する