2026年8月15日土曜日

2ch温度ロガー(デジタル温度センサ版)の回路図・スケッチ

夏休み、少し帰省していました。帰省してもやることは庭木の剪定、伐採、草むしり、除草剤撒きなど自宅と同じです。あとお墓参り。往路では大渋滞にはまり普段の2倍の時間がかかり、帰路では高速で台風一過の土砂降りに見舞われトホホです。

天気鍋は結構利用していますが、雲が多くて最高温度記録は更新できていません。最高温度に達する前にお昼のそうめん冷や麦に使ってしまうのも一因ですが。今日は冷やし中華に利用。午前中、雲が多くて温度は60℃弱でした。

天気鍋の温度推移の記録に使っている2ch温度ロガーは昨年9月に作り始め、今年の2月には、回路図・スケッチをアップしていました(アップしたことを忘れていた)。ところが、温度センサの防水が破れて異常値を記録 するようになってしまったため、急遽 防水対応のデジタル温度プローブへの交換を行いました。最初からこれを使えばよかった。

以下、これまでの経緯です。

主な機能は以下の通り。
  • 測定の正確な日時はWiFi経由のntpサーバから取得
  • microSDのsetup.txtファイルに平文でWiFiのSSID,Password 及び測定時間間隔のデフォルトの番号を記載(0:1秒, 1:10秒, 2:30秒, 3:1分, 4:5分, 5:10分)
     例)
    SSID mySSID
    PW   myPassWord
    Interval 0
  • 時間間隔は電源投入後にタクトスイッチでも変更可能(5秒経過すると測定を開始)
  • WiFiがない環境で使う際は、タクトスイッチを押しながら電源オン
    WiWi設定があっても繋がらない場合には、複数回トライして諦める
    WiWiがない場合、或いは何度トライして繋がらない場合には日時を26年1月1日00:00:00とする
  • ログはmicroSD内にタイムスタンプ付のcsvファイルとして格納する
    WiFiに繋がない、繋がらない、ntpサーバに繋がらない際の日時は 2026-01-01 00:00:00となる
  • ファイル名が重複する場合にはファイル名に追番が付く
  • 測定は指定した時刻が時間間隔で正時になったとき
  • 例)10秒毎なら0秒、10秒、20秒…のとき、1分毎なら毎分0秒のとき
  • スリープから1秒毎の割り込みで目覚めて正時になったか確認(再びスリープ)
デジタル温度センサ(プローブ)へ交換したあとの回路図とスケッチです。無保証です。ハード、ソフトの修正をできるだけ少なく済ませたので無駄な処理などもあります。今ならAIがもっとスマートなコードを書いてくれそう。


//---------------------------------------------------------------------------------------
//                                                                         '26.07.29 naka
//                                                                         '26.01.31 naka
//                                                                   ver.0 '25.09.14 naka
//  ESP32 2ch温度ロガー(小型液晶に時刻も表示)
//
//  ・測定の正確な日時はWiFi経由のntpサーバから取得
//  ・microSDのsetup.txtファイルに平文でWiFiのSSID,Password 及び測定時間間隔の
//    デフォルトの番号を記載(0:1秒, 1:10秒, 2:30秒, 3:1分, 4:5分, 5:10分)
//    例)SSID mySSID
//        PW   myPassWord
//        Interval 0
//  ・時間間隔は電源投入後にタクトスイッチでも変更可能(5秒経過すると測定を開始)
//  ・WiFiがない環境で使う際は、タクトスイッチを押しながら電源オン
//  ・WiWi設定があっても繋がらない場合には、複数回トライして諦める
//  ・WiWiがない場合、或いは何度トライして繋がらない場合には日時を26年1月1日00:00:00とする
//  ・ログはmicroSD内にタイムスタンプ付のcsvファイルとして格納する
//  ・ファイル名が重複する場合にはファイル名に追番が付く
//  ・WiFiに繋がない、繋がらない、ntpサーバに繋がらない際の日時は"2026-01-01 00:00:00"となる
//  ・測定は指定した時刻が時間間隔で正時になったとき
//    例)10秒毎なら0秒、10秒、20秒…のとき、1分毎なら毎分0秒のとき
//  ・スリープから1秒毎の割り込みで目覚めて正時になったか確認(再びスリープ)
//
//  改版履歴
//  '26.07.29 センサをディジタルセンサDS18B20に変更
//---------------------------------------------------------------------------------------
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <ESP32Time.h>
#include <SD.h>
#include "FS.h"
#include "SPIFFS.h"
#include "esp_adc_cal.h"
ESP32Time rtc;

#define SD_CS 16   // SD card chip select
#define TACT_SW 25 // タクトスイッチ(WiFi未使用指示、測定時間間隔セット用)
const int SENSOR_PIN1 = 32; // 温度センサの出力ピンを接続
const int SENSOR_PIN2 = 33; // 温度センサの出力ピンを接続

esp_adc_cal_characteristics_t adc_chars;

#define SETUP_FILE "/setup.txt"
#include <FaBoLCDmini_AQM0802A.h>
FaBoLCDmini_AQM0802A lcd;

// デジタルセンサ
// https://github.com/PaulStoffregen/OneWire
#include <OneWire.h>
// https://github.com/milesburton/Arduino-Temperature-Control-Library
#include <DallasTemperature.h>
#define TEMPERATURE_PRECISION 12 // sensor resolution: 9 - 12bit

OneWire oneWireCh1(SENSOR_PIN1);
OneWire oneWireCh2(SENSOR_PIN2);
DallasTemperature sensorsCh1(&oneWireCh1);
DallasTemperature sensorsCh2(&oneWireCh2);
DeviceAddress tempDeviceAddressCh1;
DeviceAddress tempDeviceAddressCh2;

// microSDのsetupファイルに記載されているものが設定される
char ssid[24];
char password[24];

int interval;
int interval_i = 0;
const int interval_tbl[] = {1,10,30,60,300,600}; // 測定間隔(秒)
const int interval_tbl_size = 6;
char LogFile[64]; // 記録用のcsvファイル名(タイムスタンプから自動作成)

void setup()
{
  char msg[17];
  struct tm timeinfo;
  char logfilename[64];

  pinMode(TACT_SW, INPUT);

  // モニタLCD設定
  SetupLCD();
  delay(1000);

  // setupファイルを読み、WiFiのssid,password、測定間隔のデフォルトを取得
  if (!SD.begin(SD_CS, SPI, 24000000)) {
    dispLCD_msg("microSD failed  ","                ");
    while(true); 
  }
  read_setup_file(SETUP_FILE);

  bool wifi_flag = false;
  if (digitalRead(TACT_SW)==LOW) {
    dispLCD_msg("WiFi dosen't use","                ");
    while(digitalRead(TACT_SW)==LOW);
  }
  else {
    dispLCD_msg("Connecting WiFi ","                ");
    if (wifi_connect()) {
      wifi_flag = true;
    }
    else {
      dispLCD_msg("Connect failed  ","                ");
      delay(1000);
    }
  }
  delay(1000);

  if (wifi_flag) {
      // WiFi接続に成功した場合、NTPサーバに接続し、時刻設定
      configTime(9 * 3600L, 0, "ntp.nict.jp", "time.google.com", "ntp.jst.mfeed.ad.jp"); 
      int loopcnt = 0;
      while (!getLocalTime(&timeinfo)) {
        dispLCD_msg("Failed get time ","Retrying ...    ");
        if (++loopcnt>5) { // 念のため5回繰り返してダメなら抜ける
          wifi_flag = false;
          break; 
        }
        delay(500);
      }
    dispLCD_msg("                ","                ");
    wifi_disconnect(); // 以降はWiFi未接続にする
  }

  // 起動時にSWが押されていたか、WiFi接続に失敗か、ntpサーバからの時刻取得に失敗した場合は下記の日付と時刻設定
  if (!wifi_flag) {
    rtc.setTime(1767225600); // 2026-01-01 00:00:00		
  }

  // 測定時間間隔の設定(5秒無操作で戻ってくる)
  set_interval();

  // デジタルセンサ
  sensorsCh1.getAddress(tempDeviceAddressCh1, 0); // get device0 address
  sensorsCh1.setResolution(tempDeviceAddressCh1, TEMPERATURE_PRECISION); // set resolution
  sensorsCh2.getAddress(tempDeviceAddressCh2, 0); // get device0 address
  sensorsCh2.setResolution(tempDeviceAddressCh2, TEMPERATURE_PRECISION); // set resolution

  sensorsCh1.begin();
  sensorsCh2.begin();

  // ダミーで1回空読み(1発目に-127℃が返ってくることがあったので)
  sensorsCh1.requestTemperatures(); // request temp.
  float temp = sensorsCh1.getTempCByIndex(0); 
  sensorsCh2.requestTemperatures(); // request temp.
  temp = sensorsCh2.getTempCByIndex(0); 

  // ログファイル名を決めるためにタイムスタンプ取得
  getLocalTime(&timeinfo);
  sprintf(logfilename, "%02d%02d%02d_%02d%02d%02d.csv",(timeinfo.tm_year + 1900)%100, timeinfo.tm_mon + 1, timeinfo.tm_mday,timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);

  // WiFiに繋がない場合、時刻情報を取得できないためタイムスタンプのファイル名が同じになることを防ぐ。
  get_unique_filename("",logfilename,LogFile,sizeof(LogFile));

  // 測定開始メッセージ
  dispLCD_msg("Start           ","     measurement");

  // 1,000,000us = 1sのタイマー設定
  esp_sleep_enable_timer_wakeup(1000000);

}

void loop()
{ 
  // 温度を測定してログファイルに書き出す
  measurement(interval);

  // ライトスリープ(タイマー割り込みで1秒毎に目覚める)
  esp_light_sleep_start();
}

void set_interval() {
  disp_interval(interval_i); // 現在の設定時間を表示

  int prevmsec = millis();
  while ((millis() - prevmsec)<5000) {  // 5秒反応が無ければ時間設定を抜ける
    if (digitalRead(TACT_SW)==LOW) {
      interval_i++;
      prevmsec = millis();
      if (interval_i>=interval_tbl_size) interval_i = 0;

      disp_interval(interval_i); // 現在の設定時間を表示
      while (digitalRead(TACT_SW)==LOW) {}  // SWが離されるまで待つ
      delay(20); //チャタリング対策
      prevmsec = millis();
    }
  }

  interval = interval_tbl[interval_i];
  return;
}

void disp_interval(int i) {
  int time = interval_tbl[i];
  char msg[20];

  if (time<60)
    sprintf(msg,"%11d(sec)",time);
  else
    sprintf(msg,"%11d(min)",time/60);
  dispLCD_msg("set interval    ",msg);
}

void measurement(int period) {
  char yymmddhhmmss[17],hhmmss[10],timestamp[17];
  struct tm timeinfo;
  getLocalTime(&timeinfo);

  // 測定する時間なのか確認(割り込みは1秒毎なので)
  bool flag = false;
  if (period==1) flag = true;
  else if (period==10 && timeinfo.tm_sec%10==0) flag = true; 
  else if (period==30 && timeinfo.tm_sec%30==0) flag = true; 
  else if (period==60 && timeinfo.tm_sec==0)    flag = true; 
  else if (period==120 && timeinfo.tm_sec==0 && timeinfo.tm_min%2==0) flag = true; 

  if (flag) {
    sprintf(timestamp,"%02d:%02d:%02d",timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec);
    sprintf(yymmddhhmmss, "%02d%02d%02d %s",(timeinfo.tm_year + 1900)%100, timeinfo.tm_mon + 1, timeinfo.tm_mday, timestamp);

    float temp1 = sens_temp_digitalCh1();
    float temp2 = sens_temp_digitalCh2();
    char buff1[8],buff2[8],buff[24];
    dtostrf(temp1,4,1,buff1);
    dtostrf(temp2,4,1,buff2);
    sprintf(buff, "%4s%cC , %4s%cC",buff1,0xDF,buff2,0xDF);
    dispLCD_msg(yymmddhhmmss,buff);

    write_logfile(timestamp,buff1,buff2);  // microSDに書き込み
  }

}

float sens_temp_digitalCh1() {
  float temp;
  sensorsCh1.requestTemperatures();       // request temp.
  temp = sensorsCh1.getTempCByIndex(0);   // get temp.
  return temp;
}

float sens_temp_digitalCh2() {
  float temp;
  sensorsCh2.requestTemperatures();       // request temp.
  temp = sensorsCh2.getTempCByIndex(0);   // get temp.
  return temp;
}

void dispLCD_msg(char msg1[],char msg2[]) {
  lcd.clear();
  lcd.setCursor(0, 0); // Col,Raw
  lcd.print(msg1);
  lcd.setCursor(0, 1); // Col,Raw
  lcd.print(msg2);
}

void write_logfile(char* timestamp, char* buff1,char* buff2){
  char buff[32];
  File outputFile = SD.open(LogFile,FILE_APPEND);
  
  sprintf(buff,"%s,%s,%s",timestamp,buff1,buff2);
  outputFile.println(buff);
  outputFile.close();
}

void SetupLCD() {
  delay(150);
  lcd.begin();
  lcd.command(0x38);
  delay(1);
  lcd.command(0x39);
  delay(1);
  lcd.command(0x14);
  delay(1);
  lcd.command(0x71);
  delay(1);
//  lcd.command(0x51);  // 5V
  lcd.command(0x56);  // 3.3V
  delay(2);
  lcd.command(0x6c);
  delay(300);
  lcd.command(0x38);
  delay(1);
  lcd.command(0x01);
  delay(2);
  lcd.command(0x0c);
  delay(2);
}

// Wifi接続
bool wifi_connect() {
  char msg[128];
  bool connected = false;

  for (int i=0;i<3;i++) { // WiFi接続、3回繰り返す
    WiFi.begin(ssid, password);    
    long int StartTime=millis();
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        if ((StartTime+5000) < millis()) break; // 5秒待って繋がらないときは諦める
    } 
  
    if (WiFi.status() == WL_CONNECTED) {
      IPAddress ip = WiFi.localIP();
      sprintf(msg,"%d.%d.%d.%d",ip[0], ip[1], ip[2], ip[3]);
      dispLCD_msg("Connected IP    ",msg);
      connected = true;
      break;
    }
    delay(100);
  } 

  if (connected)
    return true;
  else {
    wifi_disconnect();
    delay(100);
    return false;
  }

}

void wifi_disconnect() {
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

int read_setup_file(char* fileName) {
  char  buff[128];
  char  key[128],val[128];

  File setupFile = SD.open(fileName,FILE_READ);
  if (setupFile) {
    while (readLine(setupFile,buff)>=0) {
      if (buff[0]!='#') {
        sscanf(buff,"%s %s",&key,&val);
        if (strcmp(key,"SSID")==0) {
          strcpy(ssid,val);
        }
        else if (strcmp(key,"PW")==0) {
          strcpy(password,val);
        }
        else if (strcmp(key,"Interval")==0) {
          int ival;
          sscanf(val,"%d",&ival);
            if (ival>=0 && ival<interval_tbl_size) { // 異常値チェック
              interval_i = ival;
            }
          }
      }
    }
    setupFile.close();
  }

  return 0;
}

// microSDから1行読み取る
int readLine(File fp, char *buff){
  int i = 0;
  if(!fp.available()) {
    return -1;
  }
  while (fp.available()) {
    char c = fp.read();
    if (c=='\r');
    else if (c=='\n') break;
    else buff[i++] = c;
  }
  buff[i] = 0;
  
  return i;
}

/**
 * 重複しないファイル名を生成する関数 (ChatGPTに書いてもらった)
 * @param fs_prefix マウントポイント (例: "/spiffs")
 * @param base_name 元のファイル名 (例: "data.txt")
 * @param out_path  結果を格納するバッファ
 * @param max_len   バッファの最大サイズ
 */
void get_unique_filename(const char* fs_prefix, const char* base_name, char* out_path, size_t max_len) {
    char temp_path[128];
    char name_part[64];
    char ext_part[16];
    
    // 拡張子を探す
    const char *dot = strrchr(base_name, '.');
    if (dot) {
        size_t name_len = dot - base_name;
        strncpy(name_part, base_name, name_len);
        name_part[name_len] = '\0';
        strcpy(ext_part, dot);
    } else {
        strcpy(name_part, base_name);
        ext_part[0] = '\0';
    }

    // 最初は元の名前でチェック
    snprintf(out_path, max_len, "%s/%s", fs_prefix, base_name);
    struct stat st;
    int counter = 1;

    // ファイルが存在し続ける間、ループ
    while (SD.exists(out_path)) {
        // "パス/ベース名 + 数字 + 拡張子" を組み立て
        snprintf(out_path, max_len, "%s/%s_%d%s", fs_prefix, name_part, counter, ext_part);
        counter++;
        
        // 無限ループ防止(必要に応じて)
        if (counter > 999) break; 
    }
}

//---------------------------------------------------------------------------------------
// EOF
//---------------------------------------------------------------------------------------

2026年8月9日日曜日

夏休みの自由研究:ソーラークッカー 天気鍋(鍋蓋あり)とナビ異常

今朝、クルマに乗ったらナビが「12月25日、クリスマスです」と喋ったのでビックリ。日付の認識がおかしくなっている。しばらく前から日付が変だなと思っていたけど、そのうち直るかと思いそのままにしていた。今日は流石におかしい、と思いナビの設定画面を調べた。でも日付設定のメニューは無い。確かにGPSから日時を得ているので、設定しなくてもいいはずだよね。

ググってみたら、GPSの週カウンタのロールオーバーが原因らしい。GPSはなんと週のカウンタが10ビット(0~1,023)で、起点が1980年1月6日とのこと。1,024週(約19.6年)でカウンタが0に戻ってしまうので、何も対策してないと年月日がおかしくなる。ちなみに我が家のナビはまだ19.6年は経過してないけど、ナビのプログラムが起点としたところから10ビットを越えたのだろう。

ナビ内部のカウンタを例えば16ビットとかにしておけば、GPSから飛んでくる週カウンタが0に戻ってもキャリー処理でナビでは継続してカウントできると思うけど、そうしてない理由は何だろう。そんなに長期間ナビが動くことを想定してなかった? 対策はファームの書き換えらしいけど、すでにサポートが終わっているかも。トヨタの販売店に電話したら現在夏季休業中とのこと。休業明けに電話してみる。

さて、天気鍋は今日も午前中雲が多かったけど出してみました。これまでと違い、今日は鍋の蓋を閉じてみました。これまでは透明バケツの蓋は閉じてましたが、鍋の蓋はステンレスで反射するので閉じてなかった。鍋の蓋を閉じた方が熱が逃げるのを防げるかも知れないのと、アルミホイルの反射板により鍋の側面から熱を加えられるので上面からの熱はあまり気にしなくてよいかも知れない。と思い、試してみました。


午前中、雲が多かったので温度上昇はゆっくり。お昼過ぎてから直射日光が連続して当たる様になりました。最高温度は14:00過ぎの73.4℃でした。蓋の効果はあったのか?


自然相手で条件が日々異なるので比較するのが難しい。

2026年8月8日土曜日

夏休みの自由研究:ソーラークッカー 天気鍋(手動太陽追尾)

待望の夏休みに入りましたが、初日は庭木の剪定です。午前中は曇が多くて剪定作業にはよかったのですが、天気鍋には厳しい条件でした。それでも熱中症に注意して、スポーツドリンク飲みながら1時間ごとに休憩し、午前中約3時間の作業でした。今日は剪定だけで草むしりまではできなかった。休み中、どこかでやらねば。

天気鍋は以下のような温度推移でした。今朝は曇っていたので太陽追尾のターンテーブルは出さずに実験。11時過ぎあたりから晴れ間も多くなったので、時々手動で太陽の方を向けていました。

11時頃まではあまり水温は上がらず55℃くらい。その後は太陽のおかげで上がり始め、最高温度は72.1℃でした。外気温が急激に上がっているところはセンサに直接太陽光が当たっていたためだと思う。手動太陽追尾のタイミングで影になるところに移した。

グラフで15:00頃に段があるのは、太陽に向け直したのが原因だと思う。太陽追尾はちゃんと効果があることが確認できたのかな、と思っている。

夏休み中、終日晴れる日を期待したいが、週間天気予報をみると来週はずっと曇りや雨が多そう。温度ロガーのプログラムや回路図をアップしていなかったので、需要があるか不明ですが、夏休み中になんとかしたい。

2026年8月2日日曜日

夏休みの自由研究:ソーラークッカー 天気鍋(太陽追尾の評価)

温度ロガーのセンサを防水デジタル温度センサに交換して天気鍋を評価してみました。

朝8:30頃に評価を開始。この時点ではまだ太陽が東の方にあって陽が当たっていないけど、一応太陽の方を向けてセット。まだ太陽追尾のターンテーブルを制御するarduinoブレッドボードのまま。効果が確認できたらユニバーサル基板に載せ替えるつもり。


お昼過ぎ、かなり熱くなってきて蓋に結露ができています。昼前あたりから時々雲が流れてきて直射日光が当たる時間が少なくなってきました。温度の記録更新は厳しそう。


温度変化の様子です。12:00頃に70℃に達した後はあまり上がりませんでした。最高水温は14:00過ぎに72.6℃を記録。残念ながらこれまでの記録75℃には達しませんでした。

交換した防水デジタル温度センサも今のところ調子よく動いています。


太陽追尾のターンテーブル
の効果は明確には分からない結果でしたが、昼頃には70℃になるので、そうめん冷や麦を茹でるには十分です。今日は記録をとるためにお昼の麺類はパスしました。

また暑くて終日快晴が期待できる日があったら記録を取ってみます。普段は特に記録せずに、かみさんが天気鍋を普段使いする予定。

2026年8月1日土曜日

夏休みのイベント;真夏のアイスショー他

7月最終日の金曜日は休みをとって、辰巳アイスアリーナで開催されたアイスショーにでかけました。りくりゅうペア初プロデュースのアイスショーとして話題になったもの。公式サイトThe Destinyはココ。真夏のアイスショーで外と中の温度差が、、、羽織るものを準備して観戦。オリンピック出場ペア、アイスダンスの生の演技を観ていたらあっという間。よかった。

写真は公演後のオフィシャル写真撮影の様子(演技中は写真撮影禁止)。一番前がりくりゅうペア。みんな軽々持ち上げていてスゴイ!!


この日はホテルをとってウォーターフロント周辺を散策。陽が落ちても暑いけど、海風があって多少はよい感じ。ビッグサイトの夜の風景は初めて。


朝はホテルでゆっくりしてチェックアウト時間間際に外にでるとすでに猛烈な暑さ。そんな中、豊洲市場に足を運びました。豊洲市場ができたのが2018年とのことなので、もう8年も経っているが初めて訪れた。

場外の飲食街と市場の見学コースを巡ってきましたが、インバウンドの外国人観光客が目立ちました。結構歩いた。ホテルでの朝食が遅かったのとたっぷり食べてしまったのでお腹が減らず、ここでの食事はパス。


帰りは高輪ゲートウェイシティの NEWoMan(ニューマン)高輪 に寄ってみました。LUFTBAUMという28階にある植物空間は圧巻。熱帯です。以前にきたときは駅前は何もなかったのに高層ビルが並び、巨大シティになってました。この街作りも資本集約産業か? これがペイできるのだからすごい。

建物内は快適ですが、外は猛烈な暑さと湿気です。体調崩しそうなので早めに帰宅しました。明日晴れたらセンサを交換した温度ロガーで天気鍋の評価をするつもり。

2026年7月30日木曜日

2ch温度ロガーの温度センサ交換

先日、天気鍋の水温測定中に異常値を記録した温度ロガーですが、レジンで封止した温度センサの防水が破れた模様だったので、最初から防水対応になっているデジタル温度センサに交換しました。ロガーの製作記事はこちら など。

写真は交換前のロガーと、新たに購入した防水デジタル温度センサです。ケーブルが予想より太い。これまでのアナログ温度センサの接続はコネクタにしてあったので容易に交換できます。ケース内左上のホットボンドで固めてあるのがピンヘッダを使ったコネクタ。


防水デジタル温度センサDS18B20というものでアマゾンで購入。2つでよかったが3つで安かったので、予備を考えて3個入り。


信号線にプルアップ抵抗が必要だったので、ユニバーサル基板の切れ端に抵抗を載せてピンヘッダを挿してコネクタ代わり。半田付け箇所が切れないようにホットボンドで固めています。あと、ケーブルが太かったのでチャンネル毎に別のゴムブッシュを通しました。


プログラム変更は、アナログセンサをAD変換して温度を読んでいた部分を、1ワイヤーのデジタル通信での読み取りにした。このセンサは複数センサを並列に繋いでも個別のアドレス毎に読み取れるらしいが、今回はこれまで2ポート使っていたのでそのままチャンネル毎にポートを分けました。

測定している様子。ch2は手で触っているので高めに出ています。


防水性能はまだ分かりません。今週末、晴れたら天気鍋で試してみます。

2026年7月26日日曜日

夏休みの自由研究:ソーラークッカー 天気鍋(トラブル発生)

太陽を追尾するターンテーブルの調整は、ぼほよくて12時間で180度回転しました。今日は朝のうち晴れたり曇ったりだったので、あまり期待しないでターンテーブルに載せた天気鍋の評価です。写真はまだ南東の方を向いています。これが徐々に南に向いていく。


途中で温度を見たら、温度ロガーが200℃を越えていておかしなことになっていました。センサが壊れた?かと思い、急遽外気を測定していた他方のセンサも鍋に入れて測定を継続。

結果、当初から鍋に入れていたセンサの温度はずっと異常(グラフ橙色)、もう一方も終盤になって異常値を記録するようになっていました。昼にそうめんを茹でるために鍋を回収したので今日の最高温度は66.7℃付近。十分熱くなっていてソーラークッカーはちゃんと働いています。

鍋からセンサを取り出してみると、レジンで固めたセンサが柔らかくなっていて水が進入した気がします。こんなになるのかとちょっと意外。調べてみると、一般的なレジンの耐熱温度は70~80℃らしい。これではダメですね。繰り返し70℃前後のお湯の温度を計っていたので徐々に劣化したのかと思う。


耐熱レジンで固めようかと思ってアマゾンで調べたら結構高い。それではと防水仕様になっているデジタルセンサを使うことにしました。小型の金属チューブに入ったケーブル一体型のセンサです。今までのセンサはアナログだったので、ESP32で書いたロガーのプログラムを変更する必要がありますが、大した手間ではないと期待。ただ、これまでの記録と差が生じる可能性もある。

週末にはロガーの改修ができるかと思っています。その後、快晴で暑くなってくれるとよいのですが。