Myu
2025年12月17日水曜日
ESP32灯油残量センサー 実験
まだ、測定値が安定しないので、新たに容量カウント補正用のセンサ(タンク入口までの短い線)を追加して、しばらくデータをとってみることにした。追加PINはGPIO15。esp32から外に出ている線がぬれるだけで、測定値に影響するので、補正できないか試す予定。
*******esp32 #include
#include
#include "esp_sleep.h" #include
#include "SparkFunBME280.h" #define TOUCH_PIN 12 #define TOUCH_PIN2 15 #define LED_PIN 2 #define SLEEP_SECONDS 21600 // 6時間 #define SERIAL_EN 0 // 1=debug, 0=off #if SERIAL_EN #define S_BEGIN(...) Serial.begin(__VA_ARGS__) #define S_PRINT(...) Serial.print(__VA_ARGS__) #define S_PRINTLN(...) Serial.println(__VA_ARGS__) #define S_PRINTF(...) Serial.printf(__VA_ARGS__) #define S_END(...) Serial.end() #else #define S_BEGIN(...) #define S_PRINT(...) #define S_PRINTLN(...) #define S_PRINTF(...) #define S_END(...) #endif const char* ssid = "***"; const char* password = "********"; const char* host = "*.*.*.*"; // Raspberry Pi IP const int port = 8888; const char* path = "/py/cap"; String url; String cprint; BME280 bme; void setup() { S_BEGIN(115200); delay(100); uint16_t capValue= readTouchStable(TOUCH_PIN); delay(300); uint16_t capValue2= readTouchStable(TOUCH_PIN2); delay(100); Wire.begin(21, 22); // SDA=21, SCL=22(SCKは間違い) bme.setI2CAddress(0x76); if (bme.beginI2C() == false) { S_PRINTLN("BME280 not detected!"); } else { S_PRINTLN("BME280 connected."); } WiFi.begin(ssid, password); S_PRINTLN("Connecting to WiFi"); while (WiFi.status() != WL_CONNECTED) { delay(500); S_PRINTLN("."); } S_PRINTLN("\nWiFi connected"); // uint16_t capValue = touchRead(TOUCH_PIN); S_PRINTF("Touch value: %d\n", capValue); S_PRINTF("Touch2 value: %d\n", capValue2); float tempC = bme.readTempC(); float humidity = bme.readFloatHumidity(); float pressure_hPa = bme.readFloatPressure() / 100.0; S_PRINTF("Temp: %.2f C, Humidity: %.2f %%, Pressure: %.2f hPa\n", tempC, humidity, pressure_hPa); url = String(path) + "?cap=" + String(capValue) + "&t=" + String(tempC, 1) + "&h=" + String(humidity, 1) + "&p=" + String(pressure_hPa, 1) + "&cap2=" + String(capValue2); cprint = String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"; WiFiClient client; if (client.connect(host, port)) { S_PRINTLN("Connected to server"); client.print(cprint); while (client.connected() || client.available()) { if (client.available()) { String line = client.readStringUntil('\n'); S_PRINTLN(line); } } client.stop(); } else { S_PRINTLN("Connection failed url=" + url); } S_PRINTLN("Going to sleep..."); delay(100); WiFi.disconnect(true); WiFi.mode(WIFI_OFF); digitalWrite(LED_PIN, LOW); S_END(); esp_sleep_enable_timer_wakeup(SLEEP_SECONDS * 1000000ULL); esp_deep_sleep_start(); } void loop() { } int readTouchStable(int pin) { // チャネル切替直後の捨て読み (void)touchRead(pin); delay(5); int sum = 0; for (int i = 0; i < 8; i++) { sum += touchRead(pin); delay(5); // ほんの少し間隔 } return sum / 8; } *******bottle latest_cap = None LOG_FILE = "cap_log.txt" MAX_LINES = 200 def read_log(): if not os.path.exists(LOG_FILE): return [] with open(LOG_FILE, "r") as f: return f.readlines() def write_log(lines): with open(LOG_FILE, "w") as f: f.writelines(lines) latest_cap = None LOG_FILE = "cap_log.txt" MAX_LINES = 200 def read_log(): if not os.path.exists(LOG_FILE): return [] with open(LOG_FILE, "r") as f: return f.readlines() def write_log(lines): with open(LOG_FILE, "w") as f: f.writelines(lines) @app.route('/py/cap') def cap_handler(): cap_value = request.query.cap # ?cap=123 または ?cap=list10 list10だと最新の10個データ表示 if cap_value: if cap_value.startswith("list"): # ?cap=listN の場合 try: n = int(cap_value[4:]) lines = read_log() start = max(0, len(lines) - n) latest_lines = lines[start:] response.content_type = 'application/json' # JSON形式で返す result = [] for line in latest_lines: dt_str,value_str,value_t,value_p,value_h,value_str2 = line.strip().split(',', 5) result.append({ "datetime": dt_str, "cap": int(value_str), "temp": float(value_t), "hpa": float(value_p), "hum": float(value_h), "cap2":int(value_str2) }) return json.dumps(result) except ValueError: response.status = 400 return "Invalid list parameter" else: # 数値の場合 try: t_value= request.query.t p_value= request.query.p h_value= request.query.h cap2_value= request.query.cap2 latest_cap = int(cap_value) latest_t=float(t_value) latest_p=float(p_value) latest_h=float(h_value) #latest_cap2=int(cap2_value) latest_cap2 = int(cap2_value) if cap2_value else 0 now_str = datetime.now().strftime("%Y-%m-%d %H:%M:%S") line = f"{now_str},{latest_cap},{latest_t},{latest_p},{latest_h},{latest_cap2}\n" # ログを読み込んで追記 lines = read_log() lines.append(line) # 最大行数を維持 if len(lines) > MAX_LINES: lines = lines[-MAX_LINES:] write_log(lines) return f"Cap value {latest_cap} saved.\n" except ValueError: response.status = 400 return "Invalid value" else: # パラメータなし → 最新値返す if latest_cap is not None: response.content_type = 'application/json' return json.dumps({"latest_cap": latest_cap}) else: response.status = 404 return "No data yet" @app.route('/py/captable') def captable(): return """
灯油タンク残量概算
残量データ一覧
a:
b:
再計算
日時
cap
残量cm
気温
気圧
湿度
cap2
""" @app.route('/py/dashboard2') def dashboard2(): return """
Dashboard
Dashboard
""" @app.route('/py/capgraph') def capgraph(): return """
残量グラフ
残量 / 温度 / 気圧 / 湿度 グラフ
"""
0 件のコメント:
コメントを投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿