うごくものをつくる

個人的な学習ノート

基礎技術メモ 工作物

ESP32で作る光目覚まし時計(JavaScriptもちょっと使ってみた)

目次

光目覚まし時計……という呼び方が正式なのかどうかは分からないけど、世の中には音ではなく光で目を覚まさせる目覚まし時計がある。

起床時刻をセットすると、その数十分前からライトがじわじわと明るくなっていくので、その光で自然と目覚められる、というもの。

日の出で徐々に明るくなって自然と目が覚めてくるので、大きな音でいきなり叩き起こされるよりも朝の目覚めがスッキリするらしい……

ということでこれを作ってみた。

いきなり完成図。使用しているパワーLEDがひとつだけ種類が違うが、これは単に白色LEDの手持ちをちょうど全部使い切ってしまってあとひとつ足りず、仕方なく青色LEDを使ったためだ。

今回の回路はLED3つを直列に接続した配置なため、一つ足りないからといって一つ抜いたままでは残り2つにも電流が流れず無駄になってしまう。なので手持ちのパワーLEDで残っていた青色LEDを使用した。

回路基板

毎度おなじみElecrowに基板を発注した。

電源は12Vで、マイコンにESP32を使うためレギュレータで3.3Vに降圧してマイコン用電源とする。LEDは3つ直列に配置し、MOSFETでオン・オフできるようにしている。(LED3個直列で点灯できる程度の電圧があれば良いので、電源は必ずしも12Vじゃなくても良い。電流制限抵抗の抵抗値を調整することで9Vとかも可。)

それだけのごくシンプルな回路である。

ESP32はWebサーバーとして起動するように設定して、サーバーにアクセスすることでLEDをブラウザのボタンでオンオフしたり、起床時刻や現在時刻を設定することで、時間が来るとじわじわLEDが明るくなっていく、という光目覚まし機能も実行できるようにしている。明るさの調整はPWM制御で行った。

パソコンのブラウザからアクセスしたときの画面

こういうふうにボタンを配置している。ちなみに上のスクリーンショットはパソコンでESP32にアクセスしたときのものだが、スマホからアクセスするとこんな感じ。

スマートフォンのブラウザからアクセスしたときの画面

画面サイズに応じて配置が変わっていい感じの大きさになる。いわゆるレスポンシブデザインというものである。僕はWebデザインの技術がまったく無く、HTMLもCSSも書けないので、ChatGPTにお願いして作ってもらったよ。

JavaScriptによるPOSTリクエスト

前回の記事にて、formタグを用いたESP32サーバーへのPOSTリクエストの送信方法、およびPOSTリクエストが送られた際のESP32の処理について記載した。

今回もLEDのオンオフや時刻設定のたびにPOSTリクエストを送信することになるわけだが、今後の応用も考えて、formタグではなくJavaScriptからPOSTを送信するような処理にした。

function btnValueSend(event) {
    event.preventDefault(); // フォームのデフォルト動作を無効化する
    let e = window.event;
    let elem = e.target;
    let elemId = elem.id;
    let elemVal = elem.value;
    const fd = new FormData();
    if(elemId == 'on'){
      fd.append('data1', "on");
    }
    else if(elemId == 'off'){
      fd.append('data1', "off");
    }
    else if(elemId == 'change'){
      fd.append('data1', "change");
    }
    fetch('/', {
      method: 'POST',
      body: fd
    })
    .then(response => {
      console.log('Response received:', response);
    })
    .catch(error => {
      console.error('Error occurred:', error);
    });
    alert('送信終了');
    doReload();
  }

function doReload() {
    window.location.reload();
}

これが今回使用したJavaScriptである。これで、「data1」という名前のデータがPOSTリクエストとしてESP32に送られる。data1の中身は、押したボタンが「LED 点灯」のボタンであればonという文字列、「LED 消灯」のボタンであればoffという文字列、「タイマーオンオフ切替」のボタンであればchangeという文字列が入る。タイマーオンオフ切替とは、時間が来たら自動でLEDをつけたり消したりする処理をオンにするかオフにするかの切り替え機能である。

どのボタンが押されたのかを判定するためには、HTMLページにおいてボタン側にidを付けておく。

<button onclick="btnValueSend(event)" id="on" class="button-red" value="onPushed">LED点灯</button>
<button onclick="btnValueSend(event)" id="off" class="button-blue" value="offPushed">LED消灯</button>
<button onclick="btnValueSend(event)" id="change" class="button-green" value="onoffChange">タイマーオンオフ切替</button>

ボタンのidにon、off、changeをそれぞれつけている。これがボタンに付けられている名前のようなものなので、先ほどのJavaScriptにて「onという名前のついたボタンが押されたなら、onという文字列を送信」というような処理をさせている。

なお、上のHTMLタグでは名前(id)だけでなく、値(value)も格納させている。しかし特に活用はしていないので今回の例では必要はない。

前回の記事通り、このデータの中身を受け取るためのESP32のコードは、

String btnData = server.arg("data1");

とすることで、JavaScriptによってdata1と名前をつけられてPOSTリクエストでブラウザからESP32に送られてきた文字列を、String型で読み取ることができる。

なお、JavaScriptで複数のデータを送りたいときには、先ほどのJavaScriptの、

if(elemId == 'on'){
      fd.append('data1', "on");
    }

この部分を、

if(elemId == 'on'){
      fd.append('data1', "on");
      fd.append('data2', "secondValue");
    }

という風に書き換えると、data2という名前のデータを送ることができる。

もちろんこれは先程と同様に、ESP32側でString btnData2 = server.arg(“data2”); とすることで、2つめのデータ文字列を受け取ることができる。

今回は複数のデータをまとめて送るような使い方はしていないが。

動作確認

こんな感じで、ブラウザからボタンを押すとLED を点灯/消灯させることができる。

ちゃんとボタン操作でESP32を操作できている。ちなみに、URLにリンクでアクセス(GETリクエスト)することでESP32側の関数を呼び出すのと異なり、今回の方法はページの遷移を伴わない。POST送信後にJavaScriptでページの更新をさせることで、現在の点灯状態とかを画面に反映できるようにしている。

フォームの入力内容をJavaScriptで送る

さて、今回の作品は一応目覚まし時計であるので、現在時刻やLED点灯開始する時刻を設定できなければならない。

時刻設定画面

こんな感じでHTMLページにフォームを用意しておいて、ここに数字を記入することで時刻設定できるようにしている。フォームの入力内容を送信するJavaScriptコードは、

function formValueSend(event) {
    event.preventDefault(); // フォームのデフォルト動作を無効化する
    let e = window.event;
    let elem = e.target;
    let elemId = elem.id;
    let element = document.getElementById(elemId);//フォームの内容を取得
    const fd = new FormData();
    fd.append('btn', elemId);
    fd.append('value', element.value);
    fetch('/timeset.html', {
      method: 'POST',
      body: fd
    })
    .then(response => {
      console.log('Response received:', response);
    })
    .catch(error => {
      console.error('Error occurred:', error);
    });
    alert('送信終了');
    doReload();
  }

function doReload() {
    window.location.reload();
}

上のコードの6行目にて、フォームの内容を取得している。element.valueが具体的なフォームの中身であるので、これをvalueという名前で送信している。さらに、先ほどのLED点灯/消灯ボタンのときと同様に、送信ボタンに名前(id)を付けておき、そのidをbtnというデータ名で送っている。

あとは先ほどの複数データを送るときのやり方を参考に、ESP32側ではまずボタンの種類をserver.arg(“btn”);で読み取って判別し、次にフォームに入力された内容をserver.arg(“value”);を用いて読み取る。あとは読み取った文字列を数値に変換して、時刻設定の変数として使ってやれば良い。

まとめ

・JavaScriptを用いて、ボタンを押した時にボタンの名称やフォームの中身をJavaScriptでESP32に送信することができた。

・ボタンにidを付けておき、JavaScriptでidを確認することで、どのボタンが押されたのがを判別して送るデータの中身を変える。

・これを使えば朝すっきり目覚められる。(※個人の感想です。)

おわり

twitterアカウントを作ったのでフォローよろしくお願いします。

返信する

メールアドレスが公開されることはありません。 が付いている欄は必須項目です