でんげき☆ Network Service

Raspberry Pi 4 で運用実験中 Connect checker

No.37

(M5) ATOM Lite でまぁまぁスマートなリモコンを作ろう

202307171653523-admin.png
 
今年の初めに…かれこれ 18 年くらい住んでたボロアパートをぶっ壊すってんで追い出されて今度は高級マンションの最上階に引っ越してきました!(>_<)w そんな高級マンションには…ご入居前リフォームで 2022 年製のエアコンに交換されていたのはいいんだけどちょっと使いづらいんですよね
何が使いづらいかっていうと…リモコンでのタイマーセットが不便なんですよ 以前のボロアパートで使ってたエアコンはリモコンに RTC(時計) が実装されていたのでタイマーセットも絶対時間で行うことができていたんですよ それがご新居のエアコンのリモコンには RTC(時計) が付いてないもんだでタイマーセットしようとすると「7時間後」って感じの相対時間での設定になるんですよ 不便ですよね(-_-;)
そんな訳なんでもちっとタイマーセットしやすいリモコンをどうにかするっていうか…せっかくなんでスマホちゃん等と連動させて絶対時間でエアコンの On/Off を制御できるリモコンを作ってみることにしました

昨年に「安いじゃん!」って思って買っておいた (M5) ATOM Lite が手元にあるんでそれを使うことにしました 今買うなら (M5) ATOMS3 Lite  のほうがいいのかも知れないけど未確認です汗
それと CGI っていうか Perl が使える Web サーバが必要です 今回は Raspberry Pi OS にセットアップした Apache を使ってるけど…プロバイダなどで供されている CGI の使える Web サーバでも大丈夫だと思います

そうそう今回使う (M5) ATOM Lite には RTC が載っていません それ即ち時計が使えないって事なんでその辺をどうにかしなければなりません
そこで一定時間(今回は約30秒)ごとに Web サーバにアクセスして…アクセスされた Web サーバが現在時刻(とエアコン設定内容)を返しそれにより時刻の判定を行うようにしました

  :

それでは最初に (M5) ATOM Lite の方から初めていきましょう 開発環境は Linux っていうか Snap 版の Arduino IDE を使いました まぁ Arduino IDE であれば Windows 版とかでも同じく使えるとは思いますが未確認です汗 そんな Arduino IDE の設定は M5StickC Plus の開発環境を構築する が参考になると思います ボードを追加した後に「M5Stack-ATOM」を設定すれば ok です

お次は (M5) ATOM Lite 向けのライブラリのインストールですかね これは「ツール」メニューから「ライブラリを管理…」を選んで検索窓に必要なキーワードを入れて出てきたものをインストールってする感じですかね

20230717165352-admin.png
m5atom」と入れて出てきた「M5Atom」をインストールする

202307171653522-admin.png
irremoteesp8266」と入れて出てきた「IRremoteEsp8266」をインストールする

202307171653521-admin.png
heatpumpir」と入れて出てきた「HeatpumpIR」をインストールする

これでライブラリ類の準備も完了ですかね それではコードを見ていきましょう…っていうか手探りの「どうにか動く」テスト的なものだったのが意外と問題なく動いてしまって「あーなんか書き直すのもめんどくさいなー」って気分が昂ぶってきたんでそんなテスト的なものをそのまま載せています 動作未保証なのはもちろんとして…諸々をきちっと書き直して使ってください それだけが私の望みです汗

  :

----- Start of remcon.ino -----
#include <M5Atom.h> // Atom のヘッダファイルを準備
#include <WiFiMulti.h>
#include <HTTPClient.h>
#include <MitsubishiHeatpumpIR.h>

const char* url = "http://user:pass@hoge.orz/remocon/read.cgi"; // 現在時刻&設定内容の場所
const char* ssid = "WiFi_ssid";  // SSID
const char* password = "WiFi_pass";  // パスワード

const uint16_t kIrLed = 12; // 赤外線 LED 送信用のポート番号
IRSenderBitBang irSender(kIrLed); // 赤外線LEDが接続されているピン番号
HeatpumpIR *airCon = new MitsubishiFDHeatpumpIR();  // 三菱エアコンのインスタンス

// FastLED ライブラリの設定(CRGB構造体)
CRGB dispColor(uint8_t r, uint8_t g, uint8_t b) {
  return (CRGB)((r << 16) | (g << 8) | b);
}

WiFiMulti WiFiMulti;  // Wi-Fi を使いたい

void setup() {
  Serial.begin(115200);
  Serial.println("");

  M5.begin(true, false, true);  // 本体初期化(UART有効, I2C無効, LED有効)
  M5.dis.drawpix(0, dispColor(0, 0, 0));  // LED全消灯(赤, 緑, 青)

  WiFiMulti.addAP(ssid, password); // 「SSID」と「パスワード」を設定しておく
  Serial.print("Fi-Fi Connecting.");
}

void loop() {
  while (WiFiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    M5.dis.drawpix(0, dispColor(255, 0, 0));  //LED(赤)
    delay(500);
  }
  Serial.print("ADDR: ");
  Serial.println(WiFi.localIP());

  M5.dis.drawpix(0, dispColor(20, 20, 20)); // LED(白)

  HTTPClient http;
  http.begin(url);
  Serial.print("GET: ");
  int httpCode = http.GET();  // GET メソッドでファイルを取得
  Serial.println(httpCode);
//  Serial.println(http.errorToString(httpCode));

  if (httpCode > 0) {
    String htdoc = http.getString();  // 取得したファイルの内容
    Serial.println(htdoc);

//  YYYY/MM/DD HH:YY:MM(WDAY)\ts?,HH:MM e?,HH:MM m?
//  現在年/月/日 時:分:秒(曜日)\t開始フラグ,時:分 終了フラグ,時:分 モード
    String now_hour = htdoc.substring(11, 13);  // 現在時を取得
    String now_min = htdoc.substring(14, 16);   // 現在分を取得

    String st = htdoc.substring(25, 27);        // 開始フラグを取得
    String ed = htdoc.substring(34, 36);        // 終了フラグを取得

    String st_hour = htdoc.substring(28, 30);   // 開始時
    String st_min = htdoc.substring(31, 33);    // 開始分

    String ed_hour = htdoc.substring(37, 39);   // 終了時
    String ed_min = htdoc.substring(40, 42);    // 終了分

    String md = htdoc.substring(43, 45);        // モードを取得

    if (st == "s1" && now_hour == st_hour && now_min == st_min) {
      if (md == "m1") {
        Serial.println("Cool");
        M5.dis.drawpix(0, dispColor(0, 0, 255));  //LED(青)
        airCon->send(irSender, POWER_ON, MODE_COOL, FAN_1, 28, VDIR_DOWN, HDIR_AUTO); // 冷房
      } else if (md == "m2") {
        Serial.println("Hot");
        M5.dis.drawpix(0, dispColor(255, 255, 0));  //LED(黄)
        airCon->send(irSender, POWER_ON, MODE_HEAT, FAN_1, 16, VDIR_DOWN, HDIR_AUTO); // 暖房
      } else {
        Serial.println("Dry");
        M5.dis.drawpix(0, dispColor(0, 255, 0));  //LED(緑)
        airCon->send(irSender, POWER_ON, MODE_DRY, FAN_1, 28, VDIR_DOWN, HDIR_AUTO); // 除湿
      }
    }

    if (ed == "e1" && now_hour == ed_hour && now_min == ed_min) {
      Serial.println("--- Stop ---");
      M5.dis.drawpix(0, dispColor(255, 0, 255));  //LED(紫)
      airCon->send(irSender, POWER_OFF, MODE_COOL, FAN_1, 28, VDIR_DOWN, HDIR_AUTO); // 電源 Off
    }

  } else {  // ファイルの取得に失敗している
    Serial.println("Error");
  }

  delay(30000);
}
----- End of remcon.ino -----
※デバッグ用のシリアル通信のアレが残っているんで実稼働時には消したほうがいいかも知れないです

冒頭の #include <MitsubishiHeatpumpIR.h> は…まぁ見ての通り三菱社製のエアコン制御をする時に使うものです これが他社製であれば
#include <DaikinHeatpumpIR.h>  // ダイキン社製
#include <FujitsuHeatpumpIR.h>  // 富士通社製
#include <HitachiHeatpumpIR.h>  // 日立社製
#include <PanasonicHeatpumpIR.h>  // パナソニック社製
#include <ToshibaHeatpumpIR.h>  // 東芝社製
こんな感じになるんじゃないかと思います(未確認) 詳しくは Aruduino IDE の関連フォルダ Arduino/libraries/HeatpumpIR/ を眺めてみるといいかと思います

  :

データ(と時間)を取ってくる Web サーバの設定と… Wi-Fi 接続に関する設定を行います
const char* url = "http://user:pass@hoge.orz/remcon/read.cgi"; // 現在時刻&設定内容の場所
const char* ssid = "WiFi-ssid";  // SSID
const char* password = "WiFi-pass";  // パスワード

保安上っていうか恐らくベーシック認証なりをかけて運用すると思うのですが…その際に ID とパスワードの入力を自動化しておかねばなりません そんなときは http://user:pass@hoge.orz/remcon/read.cgi って感じで URL の前に「user:pass@」を付ければ自動で認証してくれます この書き方は一般的なブラウザでも(警告が出るかもだけど)使えます
その次に Wi-Fi の SSID とパスワードの設定を行います 上記のベーシック認証と併せて平文のパスワードを記すことになるので取り扱いには十分注意してください

  :

HTTPClient http;
http.begin(url);
int httpCode = http.GET();  // GET メソッドでファイルを取得

Wi-Fi 接続が確立したら目的のサーバからデータを取ってきます 後でも説明しますが…ここで得られるデータは次のようになっています

YYYY/MM/DD HH:YY:MM(WDAY)[タブ(\t)]s?,HH:MM e?,HH:MM m?
[タブ(\t)] の前半がアクセスした時点での日時
[タブ(\t)] の後半がエアコンの開始/終了の時刻とモードを指しています
例えば 12 時 34 分に作動させたい場合は s1,12:34 となります その次が e1,23:45 だったら 23 時 45 分に電源を切る動作となります これが s0 もしくは e0 だった場合は何も動作しないようにしています
行末の m? は動作モードを指しています m1 が冷房 m2 が暖房 m3 が除湿です 
http.GET(); した際のバッファサイズが不明だったんで…できるだけ切り詰めて必要最小限の内容にしました バッファに余裕があればもっと見やすい内容にするのもアリかもしれませんね

  :

そして実際に赤外線で信号を送信する部分です
airCon->send(irSender, POWER_ON, MODE_COOL, FAN_1, 28, VDIR_DOWN, HDIR_AUTO); // 冷房

各パラメータの意味は以下のようになっています
// airCon->send( irSender, POWER_**, MODE_**, FAN1, 温度設定, VDIR_** , HDIR_** ); // 設定項目 ※温度設定は「整数値」で
//  Arduino/libraries/HeatpumpIR/HeatpumpIR.h
//
// ・POWER (電源)
//    POWER_ON (on)
//    POWER_OFF (off)
// ・MODE (モード)
//    MODE_AUTO (自動)
//    MODE_COOL (冷房)
//    MODE_HEAT (暖房)
//    MODE_DRY (除湿)
//    MODE_ON (不明)
//    MODE_OFF (不明)
// ・FAN (風量)
//    FAN_AUTO
//    FAN_1 (弱)
//    FAN_2
//    FAN_3
//    FAN_4
//    FAN_5 (強)
// ・VDIR (風向高さ)
//    VDIR_AUTO
//    VDIR_UP
//    VDIR_MUP
//    VDIR_MIDDLE
//    VDIR_MDOWN
//    VDIR_DOWN
// ・HDIR (風向左右)
//    HDIR_AUTO
//    HDIR_LEFT
//    HDIR_MLEFT
//    HDIR_MIDDLE
//    HDIR_MRIGHT
//    HDIR_RIGHT

エアコンの設定温度は整数値で指定する必要があるようです 最近は 0.5℃ 間隔で設定できるエアコンが増えてる感じですが…そこまで細かい制御には対応できないっぽいです また今回のプログラムでは設定温度を即値の決め打ちしています 使い勝手を高めるのであればこの辺も外部から変更できるようにすべきですね

だいたいこんな感じですかね これを delay(30000); して約 30 秒間隔のループで回しています なにかの都合…例えば http.GET(); した際にサーバの返答が遅れたりするとループ間隔が長くなり指定された時間を通り越してしまうかも?って思ってこのくらいの間隔にしました まぁこの辺は各環境によりけりで程よい設定にしてもらえればなぁって思います

  :

さて…お次は UI っていうか Web サーバ側の云々ですかね 用意するのは 4 つのファイル(index.html, index.css, index.cgi, read.cgi)とスクリプトが生成する 1 つのファイル(data.txt)です

----- Start of index.html -----
<!DOCTYPE html>
<html lang="ja">
<head>
   <meta charset="UTF-8">
   <!-- ビューポートの設定 -->
   <meta name="viewport" content="width=device-width,initial-scale=1">
   <!-- スタイルシートの読み込み -->
   <link href="./index.css" rel="stylesheet">
   <title>M5 Atom Lite タイマー予約</title>
</head>
<body>

<center><div class="red"></div></center>
<center><form action="./index.cgi" method="get">
   <div>
      <label for="name"><a href="./index.cgi">M5 Atom Lite タイマー予約</a></label>
   </div>
   <div><hr class="double" width=80% noshade></div>
   <div>
      <label><input class="st" type="checkbox" name="st" value="1">「入り」を使う</label>
   </div>
   <div>
      <select name="st_hour">
         <option class="st_hour" value="00">00</option>
         <option class="st_hour" value="01">01</option>
         <option class="st_hour" value="02">02</option>
         <option class="st_hour" value="03">03</option>
         <option class="st_hour" value="04">04</option>
         <option class="st_hour" value="05">05</option>
         <option class="st_hour" value="06">06</option>
         <option class="st_hour" value="07">07</option>
         <option class="st_hour" value="08">08</option>
         <option class="st_hour" value="09">09</option>
         <option class="st_hour" value="10">10</option>
         <option class="st_hour" value="11">11</option>
         <option class="st_hour" value="12">12</option>
         <option class="st_hour" value="13">13</option>
         <option class="st_hour" value="14">14</option>
         <option class="st_hour" value="15">15</option>
         <option class="st_hour" value="16">16</option>
         <option class="st_hour" value="17">17</option>
         <option class="st_hour" value="18">18</option>
         <option class="st_hour" value="19">19</option>
         <option class="st_hour" value="20">20</option>
         <option class="st_hour" value="21">21</option>
         <option class="st_hour" value="22">22</option>
         <option class="st_hour" value="23">23</option>
      </select>時
      <select name="st_min">
         <option class="st_min" value="00">00</option>
         <option class="st_min" value="10">10</option>
         <option class="st_min" value="20">20</option>
         <option class="st_min" value="30">30</option>
         <option class="st_min" value="40">40</option>
         <option class="st_min" value="50">50</option>
      </select> 分
   </div>
   <div><hr class="double" width=80% noshade></div>
   <div>
      <label><input class="ed" type="checkbox" name="ed" value="1">「切り」を使う</label>
   </div>
   <div>
      <select name="ed_hour">
         <option class="ed_hour" value="00">00</option>
         <option class="ed_hour" value="01">01</option>
         <option class="ed_hour" value="02">02</option>
         <option class="ed_hour" value="03">03</option>
         <option class="ed_hour" value="04">04</option>
         <option class="ed_hour" value="05">05</option>
         <option class="ed_hour" value="06">06</option>
         <option class="ed_hour" value="07">07</option>
         <option class="ed_hour" value="08">08</option>
         <option class="ed_hour" value="09">09</option>
         <option class="ed_hour" value="10">10</option>
         <option class="ed_hour" value="11">11</option>
         <option class="ed_hour" value="12">12</option>
         <option class="ed_hour" value="13">13</option>
         <option class="ed_hour" value="14">14</option>
         <option class="ed_hour" value="15">15</option>
         <option class="ed_hour" value="16">16</option>
         <option class="ed_hour" value="17">17</option>
         <option class="ed_hour" value="18">18</option>
         <option class="ed_hour" value="19">19</option>
         <option class="ed_hour" value="20">20</option>
         <option class="ed_hour" value="21">21</option>
         <option class="ed_hour" value="22">22</option>
         <option class="ed_hour" value="23">23</option>
      </select>時
      <select name="ed_min">
         <option class="ed_min" value="00">00</option>
         <option class="ed_min" value="10">10</option>
         <option class="ed_min" value="20">20</option>
         <option class="ed_min" value="30">30</option>
         <option class="ed_min" value="40">40</option>
         <option class="ed_min" value="50">50</option>
      </select>分
   </div>
   <div><hr class="double" width=80% noshade></div>
    <div>
      <input class="md" type="radio" name="md" value="1">冷房
      <input class="md" type="radio" name="md" value="2">暖房
      <input class="md" type="radio" name="md" value="3">除湿
   </div>

   <div><hr class="hrline" width=80% noshade></div>
   <div>
      <input class="submit" type="submit" value="予約">
   </div>
</form></center>

</body>
</html>
----- End of index.html -----
index.html ってファイル名なんで…デフォルトで表示されるファイルっぽいですが実際にはそのような用途には使っていません デザインしやすいようにファイルを分割してあるだけで実際に表示は index.cgi が行います

----- Start of index.css -----
/* ボディ */
body {   /* 一般的な表示部 */
   margin: 0 ;
   padding: 0 ;
   font-size: 20px ;
   line-height: 3 ;
}

input {   /* チェックボックス */
   width:         25px;
   height:         25px;
   -moz-transform:      scale(1.4);
   -webkit-transform:   scale(1.4);
   transform:      scale(1.4);
}

select {   /* プルダウンメニュー */
   font-size: 30px ;
}

.hrline {   /* 罫線(?) */
   border: none;
   background-color: #fff;
   border-width: 1px 0 0 0;
   border-top: double;
   border-color: black;
}

.submit {   /* 送信ボタン */
   width:         100px;
   height:         40px;
   -moz-transform:      scale(1.4);
   -webkit-transform:   scale(1.4);
   transform:      scale(1.4);
}

.red {   /* 設定変更した */
   font-size: 40px ;
   color: #ff0000;
}

/* スマホだけに適用するCSS */
@media screen and ( max-width:479px ) {
   body {   /* 一般的な表示部 */
      font-size: 20px ;
   }

   input {   /* チェックボックス */
      width:         25px;
      height:         25px;
      -moz-transform:      scale(1.4);
      -webkit-transform:   scale(1.4);
      transform:      scale(1.4);
   }

   select {   /* プルダウンメニュー */
      font-size: 25px ;
   }

   .hrline {   /* 罫線(?) */
      border: none;
      background-color: #fff;
      border-width: 1px 0 0 0;
      border-top: double;
      border-color: black;
   }
   .submit {   /* 送信ボタン */
      width:         100px;
      height:         40px;
      -moz-transform:      scale(1.4);
      -webkit-transform:   scale(1.4);
      transform:      scale(1.4);
   }

   .red {   /* 設定変更した */
      font-size: 40px ;
      color: #ff0000;
   }
}
----- End of index.css -----
でっか文字な表示にしたくて見様見真似で用意しました 見様見真似の即興ってことで CSS について何一つ理解していません汗 おかしな所しかないと思うけど…まぁその辺は生温かい目で見守って頂けると幸いに思います(瀧汗

----- Start of index.cgi -----
#!/usr/bin/perl

$datafile = "./data.txt";   # ATOM Lite が読みにくるファイル
$htmlfile = "./index.html";   # ベースとなる HTML ファイル

if ($ENV{'REQUEST_METHOD'} eq 'POST') {   # POST メソッドで送られてきた場合
   read(STDIN, $query, $ENV{'CONTENT_LENGTH'});
} else {   # GET メソッドで送られてきた場合
   $query = $ENV{'QUERY_STRING'};
}

#### ATOM Lite が読みにくるデータファイルを作成する ####
open (DATA, $datafile);
$data = <DATA>;   # 既存のデータファイルを読み内容を取り出しておく
if ($data =~ /s(\d),(\d\d):(\d\d) e(\d),(\d\d):(\d\d) m(\d)/) {
   $in{'st'} = $1;
   $in{'st_hour'} = $2;
   $in{'st_min'} = $3;
   $in{'ed'} = $4;
   $in{'ed_hour'} = $5;
   $in{'ed_min'} = $6;
   $in{'md'} = $7;
}
close (DATA);

if ($query) {   # データを受信していた場合の処理
   open (DATA, ">", $datafile);   
   foreach $data (split(/&/, $query)) {   # 「&」で分割して全て処理する
      ($key, $value) = split(/=/, $data);   # 「name=value」のそれぞれに分割して連想配列を作っていく
      $value =~ s/\+/ /g;   # 以下ざっくりとした URL デコードする
      $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack('C', hex($1))/eg;
      $value =~ s/\t//g;
      $in{"$key"} = $value;   # value = $in{"$name"} の連想配列が出来上がる
   }
   # 送られてきた内容を適用してデータファイルを更新
   if (!($query =~ /st=/)) { $in{'st'} = '0'; }   # チェックボックスの挙動がアレなんで個別対応(汗
   if (!($query =~ /ed=/)) { $in{'ed'} = '0'; }   # チェックボックスの挙動がアレなんで個別対応(汗
   if ($in{'st'}) { print DATA "s1,"; } else { print DATA "s0,"; }
   if ($in{'st_hour'}) { printf DATA "%02d:", $in{'st_hour'}; } else { print DATA "00:"; }
   if ($in{'st_min'}) { printf DATA "%02d ", $in{'st_min'}; } else { print DATA "00 "; }
   if ($in{'ed'}) { print DATA "e1,"; } else { print DATA "e0,"; }
   if ($in{'ed_hour'}) { printf DATA "%02d:", $in{'ed_hour'}; } else { print DATA "00:"; }
   if ($in{'ed_min'}) { printf DATA "%02d ", $in{'ed_min'}; } else { print DATA "00 "; }
        if ($in{'md'} eq "1") { print DATA "m1\n"; } elsif ($in{'md'} eq "2") { print DATA "m2\n"; } else { print DATA "m3\n"; }
   close (DATA);
}

open (IN, $htmlfile);   # 以下ベースとなる HTML ファイルを読み込み設定時間などを反映させる

print "Content-type: text/html; charset=UTF-8\n\n";
@lines = <IN>;
foreach (@lines) {
   if ($query) { s/(<div class="red">)(<\/div>)/$1設定しました$2/; }

   if ($in{'st'} eq "1") { s/(class="st")/$1 checked/; }
   if ($in{'st_hour'}) { s/(class="st_hour" value=")($in{'st_hour'}")/$1$2 selected/; }
   if ($in{'st_min'}) { s/(class="st_min" value=")($in{'st_min'}")/$1$2 selected/; }
   if ($in{'ed'} eq "1") { s/(class="ed")/$1 checked/; }
   if ($in{'ed_hour'}) { s/(class="ed_hour" value=")($in{'ed_hour'}")/$1$2 selected/; }
   if ($in{'ed_min'}) { s/(class="ed_min" value=")($in{'ed_min'}")/$1$2 selected/; }
        if ($in{'md'}) { s/(name="md" value=")($in{'md'}")/$1$2 checked="checked"/; }

   print $_;
}
close (IN);
----- End of index.cgi -----
実際に表示を受け持つ index.cgi です 表示を受け持ちつつ…フォームで入力された値を解釈して data.txt を生成します そしてそのフォームで入力された値 index.html の内容を書き換えて表示するようになっています こうしておけば以前の設定内容を次回の設定に引き継げるようになるので便利かなーって思いまして
そんな訳なんで .htaccess で Web サーバの設定変更が可能な場合は DirectoryIndex index.cgi としてデフォルトで読み出されるファイルに設定しておくといいでしょう

あとこの index.cgi は GET メソッドでデータを受けれられるので…極端な話パラメータ付きの URL を直打ちすることでも設定が可能です 例えば 08 時 20 分冷房 で作動させ 19 時 30 分 に電源を切る場合だと
http://user:pass@hoge.orz/remocon/index.cgi?st=1&st_hour=08&st_min=20&ed=1&ed_hour=19&ed_min=30&md=1
こんな感じの URL になります それ即ち wget や curl などのコマンドでアクセスすることが可能となり…さらに cron などを使えば毎日の動作や毎週の動作といった感じで自動化することも可能になります いや実際に試してはないですけどたぶん大丈夫だと思います汗

----- Start of read.cgi -----
#!/usr/bin/perl

print "Content-type: text/plain; charset=UTF-8\n\n";

# 現在日時の表示
@wdays = ( "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime(time());
printf "%04d/%02d/%02d %02d:%02d:%02d(%s)\t", $year + 1900, $mon + 1, $mday, $hour, $min, $sec, $wdays[$wday];

$datafile = "./data.txt";   # ブラウザで設定した内容のファイル
open (DATA, $datafile);
print <DATA>;   # ファイルの 1 行目を読み取り表示する
close (DATA);
----- End of read.cgi -----
(M5) ATOM Lite がアクセスしてくるファイル(CGI)です 現在日時を整形して表示して…あとは index.cgi が生成した data.txt の内容をくっつけて送信してくれます

  :

ごちゃごちゃ長くなったんで以下にまとめときます 「名前を付けてリンク先を保存」とかすれば手間がなくていいと思いますたぶん
remcon.ino   (M5) ATOM Lite 用 Arduino Sketch ファイル
index.html   表示のベースとなる HTML ファイル
index.css   でっか文字にするためのアレ
index.cgi   ページ表示しつつデータファイルを作成する
read.cgi   (M5) ATOM Lite が読みに来る先のやつ
data.txt  index.cgi が作成するデータファイル

20230717165352-admin.jpg
そして後はいい感じに設置して完了ですかね (M5) ATOM Lite の赤外線はかなり飛距離が短いんで…エアコンにへばりつけるような設置になっちゃうのかな

あーあと余談っていうか注意事項ですが (M5) ATOM Lite が読みに来る read.cgi は数十秒に 1 回のペースで 24 時間 365 日延々とアクセスがあります そのままの Web サーバだと…そのアクセス毎にログファイルが蓄積されることになります もし可能なら Web サーバの設定を変更して…このアクセスに対してのみログの書き込みを抑制するなどしたほうがいいと思います ざっくり SetEnvIf nolog  なんて感じのキーワードでぐぐれば必要な情報に辿り着けるとイイナ!

  :

そんな感じで最後までご覧いただきありがとございました汗 ざっくりテスト用に作ったのをイジくりまわした代物なのでいろいろおかしな部分はありますが…手っ取り早く動作を体感してみたい!って時には役立つかもです それにしても 1,000円 ちょっとで買える (M5) ATOM Lite はホントすごいですよね きちんと筐体に収められていつつ… Wi-fi で接続を確立して HTTP でデータを取ってくることができる 赤外線 LED でリモコンのような動作もさせられる 欲を云えば RTC(時計) が欲しかったかなって感じではあるけど…それもどっかのサーバに接続して時刻を取得すればそれほど問題にはならないんでまぁいいかな♪ なんかそんなかんじで #Arduino #M5StickC

情報 <19935文字>

DASHBOARD

■複合検索:

  • 投稿者名:
  • 投稿年月:
  • #タグ:
  • カテゴリ:
  • 出力順序:

■ハッシュタグ:

■カテゴリ:

■日付検索:

■機器状態:

Raspberry Pi 4 Status

編集

RSSフィード