2025年11月22日土曜日

有効積算温度のグラフ表示

 元々、自分の庭の温湿度をDBに蓄えたかったのは、それを利用して庭の花の開花時期などを予想したりする事をしたかったからですが、安定的に(バッテリ切れ等なく)温湿度を計測できる環境の制作に時間が係り、手を付けられていませんでしたが、Xiao S3のdeep sleep 時14μAは、流石に効果があり、1か月以上安定に動作しています。

 で、本題の有効積算温度グラフ表示を実装してみることにしました。

 まづ、有効積算温度(Effective Accumulated Temperature)とは;

 農業技術辞典 によれば「温度の日平均値をそのまま合計したもの。基準温度以下の温度は生育に寄与しないという考え方に基づき、生育に必要な最低温度(基準温度、発育ゼロ点ともいう)以上の日の日平均温度を合計した値を有効積算温度と呼ぶ。....」(コピペ出来なかったので転記)とあります。 


従って、DBから日平均温度を計算し、基準温度を超えた分だけを足してゆくようなSQLを書いてやればよいことになり、これをグラフ表示するようにすればよいわけです。 

 

 

SQLを含むphpのソースは;

<?php
//  include('funcs.php');
//$threshold = 3;  
//  $location='GardenEast';
//  $startDate = 20250401;
//  $endDate = 20251030;

$averagedataPoints = array();
  $temp;
  $dbh = db_connect();
  $handle = $dbh->prepare('select yyyymmdd, location, case when avg_temp - :threshold > 0 then (avg_temp - :threshold) else 0 end as datapoint from dailydataview where location = :location and yyyymmdd between :start and :end');
  $handle->execute(['threshold' => $threshold, 'location' => $location,'start'=> $startDate,'end'=>$endDate]);
  $result = $handle->fetchAll(PDO::FETCH_OBJ);
  $temp1 = 0;
  $count = 0;
  foreach ($result as $row) {
    $temp1 = $temp1 + $row->datapoint;
    $a = substr($row->yyyymmdd,4,2)."月".substr($row->yyyymmdd,6)."日";
    $label = $a . "(".$count."日)";
    array_push($averagedataPoints, array("y"=> number_format($temp1, 2, '.', '' ), "label"=>$label));
    $count = $count+1;
 }
 $handle=null;
 $result=null;
// print json_encode($averagedataPoints,JSON_NUMERIC_CHECK).'
'; ?>

これを表示するcanvasjs/php/htmlのコードは以下のようにしましたが、formへの指定入力内容が消えてブランクのままグラフの上に残るので見てくれが悪く、「何とかならないのか?」苦慮中です。 指定内容はグラフの方に表示されるので、間違いはありませんが、、、。

また、積算温度の予測機能は持っていませんので、過去の積算温度推移を併記させるようにと考えましたが、DBの過去のデータに欠落があって、開始時期とかが指定通りにならないことがあるので、現時点では、単年の表示のみ。 

作業中、1000以上の数字がグラフ表示されなくて、1~2日悩みましたが、phpのnumber_formatが引数を3つ取り、2番目が小数点以下、3番目が千の単位の区切りを指定できるようになっているため、省略すると千の単位にコンマが入り、これがCanvasJsで問題を起こすのでした。要注意!! 

<thtml>
  <head>
   <script>
    <?php
      include "/usr/local/www/data/DBAccess/funcs.php";
      include "/usr/local/www/data/utilities.php";
      $threshold = $_POST['threshold'];
      $location = $_POST['location'];
      $startDate=$_POST['startDate'];
      $endDate = $_POST['endDate'];
      include "/usr/local/www/data/DBAccess/AccumulatedTemperature2.php";
    ?>
    window.onload = function () {
	var chart = new CanvasJS.Chart("chartContainer", {
	    animationEnabled: true,
	    theme: "light2",
	    title:{
		text:  ,
	    },
	    subtitles: [
		{
		    text: ,
		    fontColor: "blue",
		    fontSize:20
		},
		{
		    text: ,
		    fontColor: "blue",
		    fontSize:15
		}
	    ],
            axisY: {
		title: "積算温度(°C)",
 		lineColor: "#C24642",
		tickColor: "#C24642",
		labelFontColor: "#C24642",
		titleFontColor: "#C24642",
		interlacedColor: "#F0F8FF" ,
		includeZero: true,
		suffix: "°C",
	    },
 	    data: [
		{
		    name: "積算温度",
		    type: "line",
		    indexLabelFontSize: 16,
		    color: "rgba(255,0,0,0.3)", // red
		    lineThickness: 3,
		    showInLegend: true,
		    yValueFormatString: "#0.## °C",
		    dataPoints: <?php echo json_encode($averagedataPoints, JSON_NUMERIC_CHECK); ?>
 		},
	    ]
	});
	chart.render();
    }
    </script>
  </head>
  <body>
    <form action="" method="post">
      閾値(温度°C):<input name="threshold" type="text" value="10" />
      開始日時(YYYYMMDD):<input name="startDate" type="text" />
      終了日時(YYYYMMDD):<input name="endDate" type="text" />
      場所:<select name="location">
	<option value="GardenEast"></option>
	<option value="GardenCenter"></option>
	<option value="GardenNorth"></option>
	<option value="MyRoom"></option>
      </select>
      <input type="submit" value="submit" />
    </form>
    <div id="chartContainer" style="height: 600px; width: 90%;"></div>
    <script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
  </body>
</html>

 

 

 

2025年10月26日日曜日

温湿度モニター(続き) 

バッテリの充電をしても直ぐに止まってしまうので、止む無く回収修理することにしました。しかし、5年前の物で入手できるものは既になく、今更ESP8266でもないのでESP32-S3,SHT45で作り直してみることにしました。 ESP32と言っても色々あるので、deep sleep 時の消費電力を比較するために、ESP32-S3,Xiao ESP32-S3,ESP32-C3,XiaoESP32-C3 を入手して、いくつか動作試験をしてみました。

最初に、ExampleにあるWiFiScanにdeep sleep testのコードを足して比較してみました。最初に5V電源を供給して比較してみると、ESP32-S3(ESP32-S3 Dev moduleで動かしたもの)でdeep sleep時に350μAとなる結果で、Xiao -S3,-C3共に上手く結果が出ませんでした。 deep sleepするとUSBportが切れてしまい、動作状態がわからなくなるので、TX/RXを使ってシリアルで動作をモニターする必要があるのですが、、、、

最初これがうまくいかず、ググって之を見つけ、Arduinoの設定を左のように
変更。再コンパイル、インストール。

これで、動作状況を確認できるので、3.7VのLiPo電池で温度と湿度をサーバにリポートする実際のプログラムを走らせて、deep sleep時の消費電流を測定してみました。 技適認証の問題がありますのでXiao ESP32-S3とXiao ESP32-C3、ESP32-S3を測定してみました。結果、右のようにXiaoESP32-S3が一番消費電流が少なかったので、これを使うことにしました。(Xiao ESP32-C3の消費電流についてはWEBに記載のあるものと殆ど一緒なので、問題はないと思いますが、、、)

ここにはESP32-S3のdeep sleep時の電流値が3.8V/14μAとありますので、大きくは間違っていない、と思います。 なお、仕事中の電流値は動きが激しく時間も短いので、肉眼で見た時の凡その最大値です。 また、最近のESP32には3V3の定電圧電源回路(バッテリ充電の為の制御回路も)とか、USB・Serialとか色々なペリフェラルが入っているので、細かく電源制御するために、より内部に精通している必要があり、全部端折って、手っ取り早く実機に仕立てて消費電流を見て判断するのが早道かもしれません。

あまりに何もない接続図なので、省略してましたが、将来??とならないように記録しておきます。 汎用のボードに直付けしています。 スケッチもSHT-4xのサンプルスケッチ にWiFiくっ付けただけですが、一応備忘録として、、、。

 

 

 

 

Weather monitorのソースコード

//    FILE: SHT4x_demo.ino
//  AUTHOR: Rob Tillaart
// PURPOSE: demo
//     URL: https://github.com/RobTillaart/SHT4x

/*
For async call:
requestData(measurementType = SHT4x_MEASUREMENT_SLOW);

For sync call:
read(uint8_t measurementType = SHT4x_MEASUREMENT_SLOW, bool errorCheck = true);

| measurement type                    |  duration  |  heater  |  power   |  notes  |
|:-----------------------------------:|:----------:|:--------:|:--------:|:-------:|
| SHT4x_MEASUREMENT_SLOW              |     9 ms   |     N    |     -    | default |
| SHT4x_MEASUREMENT_MEDIUM            |     5 ms   |     N    |     -    |
| SHT4x_MEASUREMENT_FAST              |     2 ms   |     N    |     -    |
| SHT4x_MEASUREMENT_LONG_HIGH_HEAT    |  1100 ms   |     Y    |  200 mW  |
| SHT4x_MEASUREMENT_LONG_MEDIUM_HEAT  |  1100 ms   |     Y    |  110 mW  |
| SHT4x_MEASUREMENT_LONG_LOW_HEAT     |  1100 ms   |     Y    |   20 mW  |
| SHT4x_MEASUREMENT_SHORT_HIGH_HEAT   |   110 ms   |     Y    |  200 mW  |
| SHT4x_MEASUREMENT_SHORT_MEDIUM_HEAT |   110 ms   |     Y    |  110 mW  |
| SHT4x_MEASUREMENT_SHORT_LOW_HEAT    |   110 ms   |     Y    |   20 mW  |
  
  Ken Yamada 2025/10/04
  Extended to sending the data every determined period to the server thru WiFi
  This is for ESP32-S3-zero, Seeed Studio Xiao esp32s3, expecting less than 14uA at sleeping time.
*/
#include "WiFi.h"
#include "Wire.h"
#include "SHT4x.h"

#define uS_TO_S_FACTOR 1000000ULL  // Conversion factor for micro seconds to seconds
#define TIME_TO_SLEEP 60 * 15      // Time ESP32 will go to sleep (in seconds) 15 minutes.

#define SHT_DEFAULT_ADDRESS 0x44
#define SHT_PW 4
#define SDA 5
#define SCL 6

#ifndef STASSID
#define STASSID "XXXXXXXX"
#define STAPSK "***********"
//#define IDENTIFIER "TEST"
//#define IDENTIFIER "GardenCenter"
#define IDENTIFIER "GardenEast"
//#define IDENTIFIER "GardenWest"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;
const char* Identifier = IDENTIFIER;
const char* host = "your host address";
const uint16_t port = 80;

SHT4x sht;

// Method to print the reason by which ESP32 has been awaken from sleep
void print_wakeup_reason() {
  esp_sleep_wakeup_cause_t wakeup_reason;
  wakeup_reason = esp_sleep_get_wakeup_cause();
  switch (wakeup_reason) {
    case ESP_SLEEP_WAKEUP_EXT0: Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1: Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
    case ESP_SLEEP_WAKEUP_TIMER: Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD: Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP: Serial.println("Wakeup caused by ULP program"); break;
    default: Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
  }
}
void setup() {
  esp_log_level_set("i2c.master", ESP_LOG_NONE);  //Patch work, don't know if it is ok to ignore.
  //esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
  //esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_SLOW_MEM, ESP_PD_OPTION_OFF);
  //esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_FAST_MEM, ESP_PD_OPTION_OFF);
  pinMode(SHT_PW, OUTPUT);  // For SHT powering
  Serial.begin(115200);
  while (!Serial)
    ;  //  uncomment if needed

  print_wakeup_reason();

  //WiFi setup
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  // wire setup, SHT start
  digitalWrite(SHT_PW, HIGH);  // turn on SHT power
  delay(100);
  Wire.begin(SDA, SCL);  //Define(SDA,SCL)
  Wire.setClock(100000);

  sht.begin();
  // deep sleep setup
  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);

  //  Summary of setup
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");
}
void loop() {
  WiFiClient client;
  if (!client.connect(host, port)) {
    Serial.println("connection failed");
    delay(5000);
    return;
  }
  sht.read();  // default SHT4x_MEASUREMENT_SLOW and true for CRC check
  delay(100);
  digitalWrite(SHT_PW, LOW);  //Switch off SHT 

  String url = "/weather/weather_log.php";
  url += "?location=" + String(Identifier);  // ID to identify location
  url += "&temperature=" + String(sht.getTemperature());
  url += "&humidity=" + String(sht.getHumidity());
  url += "&pressure=" + String("-----");
  Serial.print("Requesting URL: ");
  Serial.println("GET " + url);

  client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n");
  delay(500);
  // Read all the lines of the reply from server and print them to Serial
  Serial.println("Returned message from server: ");
  delay(500);
  while (client.available()) {
    String line = client.readStringUntil('\r');
    Serial.print(line);
  }
  Serial.println("Closing connection.");
  client.stop();

  delay(1000);
  WiFi.mode(WIFI_OFF);  //
  Serial.flush();
  esp_deep_sleep_start();  // Start sleep!!
}
//  -- END OF FILE --

2025年8月18日月曜日

温湿度モニター

 2020年頃から使用している屋外の温湿度モニターが曇天が続いたせいで動作しなくなったので、部屋に持ち込んで5VのUSBで充電。 充電完了後様子を見ると、Error 408でデータが送られてこない。 「おい、おい、どうなってんだ? 今までは問題なかったのに。本体が壊れたかな?」と思い、本体に手を入れようと思ったのですが、5年も前に制作したものに手を入れるのは億劫なので、取り敢えず、自分のWEBをググってみると、同じようなトラブルの記載がありました。

過去の書き込みを調べてみると、電源電圧が4Vを超えていないと、本体で使用しているNJU7223(3.3V3端子レギュレータ)が3.3V出してくれず、このような症状になるような記載がありました(確定ではない)。 使用していたLiバッテリの電圧を調べてみると満充電後でも3.7V位にしかなっていない。これだと、3.3Vが供給できません。

HW-107なる中華製のLiバッテリの保護モジュールを使って、太陽電池とLi電池、モニター本体との接続をしていますが、どうもLiバッテーリがヘタって4.2V出てくれなくなったようで、Liバッテリを新しいものに取り換えて、1日充電して、なんとかエラーは出なくなりましたので、庭の所定の場所に設置。

当分はこれでOKかな?  しかし、5~6年前の物は、自分で作ったものでも手を入れるのは億劫。 

 

2025年7月19日土曜日

Flex 6600のSD card交換

 v3.9.19にアップグレードしようとしたら、firmwareのアップデートの所でエラーが出て進めない。面倒なので、そのままv3.9.18で使っていながら、FlexのHelpDeskにサポート依頼。

久しぶりにTim Ellison(W4TME)が担当で回答があり、「症状からするとSD cardが壊れているので、無償で送るので交換するように」という事だったので、住所を連絡したら、3日ほどでFedExー>JPで到着。


時間が取れたので土曜日に本体開けてSD Cardの交換をしてみると、 最初はコールドスタートして、アンバー色のボタンを押すとグリーンの点滅、そして赤の点滅。 コールドスタートで、アンバー色のボタンを長押しすると薄い青(白色)の点灯、そして赤の点滅。 

いずれにせよ立ち上がらない! ググってみると同じような症状でファンが回っていないが、何度かリブートすると治った、等の報告が見られたが、釈然としない。 再度、HepDeskに書き込み(あ、向こうの土曜日! 明後日でないとダメかな?)と、土曜日に作業したことを悔やむ。

で、暇なので、再度SD Card周りを触って見てみると、 SD Cardのフォルダー(金属のクリップのようになっている)が結構緩い! SD Cardを適当と思われる位置に置いて、上からフォルダを押さえ、動かないように送られてきたカプトンのテープでフォルダ(SD Card)を固定して、電源を入れてみると、今度は暫くして、LEDがグリーンの点灯。ファンも回っている。


PCからSmartSDRでアクセスしようとするが、当該の機器が見つからない!と返ってくる。「あー、やっぱりHelpDesk行きかな?」と思い、電源を入れっぱなしにして(グリーンの点灯が維持されている状態を確認して)、10分ほど他の事をして、もう一度SmartSDRからアクセスしてみると、今度は無事アクセスでき、問題なく動作してくれている。

あ、プロフィルが消えているので、バックアップから読み込まないとプロファイル使えません(事前にプロファイルはPCにバックアップを取っておきましょう!) 

Timの説明によれば、送られてきたSD Cardにはfirmwareとライセンス内容(ブランク)が入っていて、最初に立ち上がるとFlexのライセンスサーバにインターネットで接続して、ライセンス内容を確認してダウンロード、SD Cardに書き込むようなので、ライセンス内容の取得(書き込み)に少し時間が係るようだ。 (新品であれば、SmartSDRがライセンスサーバにアクセスを誘導して、ライセンスの購入・取得をさせ、その後にその内容をFirmwareに書き込んで、使用できるようになっているらしい。 Flexにライセンスという概念がなかった時代から使用しているので、ここら辺がわかっていませんね。)

中は、テキサスの田舎とまでは言いませんが、結構広々と配置され、余裕の配置です。 また、筐体の上蓋を外すのに上面4本、側面5本づつ(10本)計14本のビスを外さないと開けられない、という、ちょっと量産製品ではない作りになっていました。 (ちなみに、底の方も側面は10本のビスで止められており、底板の所も何本かのビスで止められていると思われますが、今回は必要なかったので、開けておらず、調べてもいません)

 

2025年6月15日日曜日

SSDの初期化

 昨年の暮れから、Window11のインストールに手を焼いて、其の度に面倒なので新品のSSDにインストールしてしまったために、使いもしないのに1TBのSSDが5~6個転がる状況。

で、取り敢えず、使わないものは初期化しておこうと「ディスクの管理」 から弄ってみるがパーティションが消えてくれない! いろいろググってみると、「Windowsコマンドプロンプと」から初期化する方法が見つかったので、それを実行。

何本もSSDが刺さっているので、ちょっとビクビク、、、。 

  1. 管理者としてコマンドプロンプトを実行
  2. diskpart
  3. list disk
  4. select disk x
  5. clean

 で、無事終了でした。 

備忘録として、、、 

 







2025年5月22日木曜日

SmartDAXがインストールできない(続き)

「シャンメー、Windows11から新規に入れなおしてみっか」、ということでSSDをcleanして、Windows11を入れなおしてみると、Ethernetへのアクセスができずにインストール途中で止まってしまう。Windows10/11ともにうまくゆかない! firmwareの問題?と思っても、ちょっと手元にfirmwareをダウンロードするシステムを持っていないので、止む無くパソコン工房にMBを持ち込んで、MB,メモリ、CPU夫々調べてもらう。 と、なんとCPUが死んでる!? これって、Ehterにつながらなかったのとは関係ないので、持ち込む前にoverclockを実験していたので、その所為かもしれないが、CPUいかれたのは初めて。 MBとCPUを修理依頼(CPUの外箱が無いので保証されないかもしれないが、一縷の望みを託す)。

修理が終わるのを待つわけにはゆかないので、Intel Core U7 265FとZ890 MAX GAMING WIFI7を新たに買ってきて、新規インストールしてみたら、 全然問題なくインストールでき、SmartSDR/CAT/DAXもちゃんとインストールできました。 何が問題だったのか、判然としませんが、USBケーブルからのRFIがいくつかのドライバなどを壊してしまっている可能性は否定できないので、そこら辺かと推測するしかない。尚、いわく付きの24H2もインストールしてみましたが、全然問題なし!  

昨年末から、Windows11でひどく出費が重なってしまった!! (と、入れなおす度にライセンス認証を要求され、0120の電話でAI嬢と長ったらしい番号の読み上げ確認をさせられるのには閉口する)

お陰でZS8Wは10/12/30mは聞こえていながら、QSO出来ずに終わってしまい、17/15のFT8のみでした。 ペディション中は余計なことをすべきではない教訓。 

後日、IC-7300のUSB接続ができるようにUSBケーブルにパッチンコアてんこ盛りにして、準備はしてますが、トラブるのが怖いので、実験はしていません(このまま、箱入り状態かも)。

ついでに、何故か30/40/80mのダイポールの40mトラップの同軸Cが放電して壊れていましたーこれも原因が雨滴なのか?よくわからない。 トラップのCが壊れていても、他のバンドは影響ないんですね、当たり前と言えば当たり前ではありますが、、、。


2025年5月12日月曜日

Windows11 24H2 とsamba


調子に乗ってminiPCのバージョンアップを24H2までやってしまったら、sambaにアクセスできなくなって、慌ててここ のPowerShellでの下の2行の実行でアクセスできるようになりました。

前にも同じことをした覚えがあるけど、すぐにわすれちゃうよね。

Set-SmbClientConfiguration -RequireSecuritySignature $false -Force
Set-SmbClientConfiguration -EnableInsecureGuestLogons $true -Force 



有効積算温度のグラフ表示

 元々、自分の庭の温湿度をDBに蓄えたかったのは、それを利用して庭の花の開花時期などを予想したりする事をしたかったからですが、安定的に(バッテリ切れ等なく)温湿度を計測できる環境の制作に時間が係り、手を付けられていませんでしたが、Xiao S3のdeep sleep 時14μAは...