HCesp/Setup.cpp
2026-04-17 11:34:49 +09:00

318 lines
9.6 KiB
C++

#include "HermitCrab.h"
#include "Config.h"
#include "AHT2x.h"
#include "NTC_10K.h"
#include "ZCD.h"
#include "History.h"
#include "ConnectWiFi.h"
#include "WiFiHost.h"
#include "TimeManager.h"
#include "OTA.h"
#include "UI.h"
#include "BLEScan.h"
#include <esp_wifi.h>
#include "esp_coexist.h"
#include "hal/timer_ll.h"
#define TAG_SETUP "TAG_SETUP"
// Task handle
TaskHandle_t TaskHandle_0;
bool g_bWiFiSetupExecuted = false;
bool g_bWiFiHasBeenConnected = false;
extern STATUS_TYPE status;
extern CHistory history;
extern timg_dev_t *tg1;
void setupConfig();
void setupStatus();
void restoreStatus();
void setupWiFi();
void setupPostWiFi(bool bBoot);
void setupPins();
void setupSensor();
void setupZCD();
void setup_BLE();
void scanI2C();
void setup() {
timer_ll_set_clock_prescale(tg1, 1, 80000);
timer_ll_set_count_direction(tg1, 1, GPTIMER_COUNT_UP);
tg1->hw_timer[1].loadhi.val = 0UL;
tg1->hw_timer[1].loadlo.val = 0UL;
tg1->hw_timer[1].load.val = 1UL;
timer_ll_enable_alarm(tg1, 1, false); // No ISR needed for watchdog
timer_ll_enable_counter(tg1, 1, true);
// put your setup code here, to run once:
#ifdef DEBUG
Serial.begin(115200);
#endif
//esp_log_level_set("*", ESP_LOG_INFO); // Global log level
//esp_log_level_set("BLE_POLL", ESP_LOG_INFO); // Module-specific level
//esp_coex_preference_set(ESP_COEX_PREFER_BT);
DPRINTLN(" **********************");
DPRINTF(" SETUP - Start - ver. %s type: %d\n", HC__VERSION, THIS_DEVICE_TYPE);
DPRINTLN(" **********************");
g_bWiFiHasBeenConnected = false;
g_bWiFiHasBeenConnected = false;
g_nYear = 2024;
g_nMonth = 10;
g_nDay = 15;
g_nHour = 0;
g_nMinute = 0;
g_nSecond = 0;
bShowSensor = false;
setupConfig();
setupStatus();
setupPins();
scanI2C();
setupSensor();
ui.setup();
ui.message(0, (char *) "WiFi...");
setupWiFi();
if (aht25.sensor() || aht10_0x39.sensor()) {
ui.message(4, (char *) "Sensor... OK!");
} else {
ui.message(4, (char *) "Sensor... None!");
}
ui.message(5, (char *) "ZCD...");
setupZCD();
ui.message(5, (char *) "ZCD... OK!");
ui.message(6, (char *) "Setup OK!");
//if (!isWiFiConnected) delay(3000);
ble.setupConnect(config.nBLESensorAddr, config.nBLESensorAddr2);
// Restore Status
restoreStatus();
// Create a task pinned to core 0
xTaskCreatePinnedToCore(
core0Task, // Function to run as a task
"Task0", // Task name
20480, // Stack size in words
NULL, // Task input parameter
1, // Priority of the task
&TaskHandle_0, // Task handle
0 // Core 0
);
DPRINTLN("Setup Completed\n========================\n");
}
// ======================================================================
//
// Setup
//
// ======================================================================
void setupConfig() {
config.load();
history.loadPID();
config.m_nDeviceType = THIS_DEVICE_TYPE;
}
void setupWiFi() {
// Set WiFiEvent
WiFi.onEvent(WiFiEvent);
strncpy(BLE_SSID, config.ssid, sizeof(BLE_SSID));
strncpy(BLE_PW, config.pw, sizeof(BLE_PW));
// Connect WiFi for OTA
if (config.ssid[0] && config.pw[0]) {
#if defined(ESP32)
esp_wifi_set_max_tx_power(74);
#elif defined(ESP8266)
WiFi.setOutputPower(20.5f);
pinMode(16,OUTPUT);
digitalWrite(16, LOW);
int c = 0;
#endif
DPRINTF("BOOT: Connecting to WiFi: SSID: '%s', PW: '%s'\n", config.ssid, config.pw);
WiFi.mode(WIFI_STA);
WiFi.begin(config.ssid, config.pw);
unsigned long beginTime = millis();
while (WiFi.status() != WL_CONNECTED) {
delay(250);
DPRINT('.');
if (millis() - beginTime > 30000)
break;
}
DPRINTLN();
if (WiFi.status() == WL_CONNECTED) {
ledcWrite(PIN_LED_WIFI, PWM_FULL); // LED_OFF
ui.message(0, (char *) "WiFi...OK!");
DPRINTLN("WiFi - Connected at SETUP");
DPRINTF("WiFi - SSID(%s) PW(%s) IP(%s)\n", config.ssid, config.pw, WiFi.localIP().toString().c_str());
g_bWiFiHasBeenConnected = true;
setupPostWiFi(true);
} else {
DPRINTLN("WiFi - ** NOT ** Connected at SETUP.");
//WiFi.disconnect(false, true, 500);
}
}
}
void setupPostWiFi(bool bBoot = false) {
if (WiFi.status() == WL_CONNECTED) {
// Time
if (bBoot) ui.message(1, (char *) "Time...");
timeManager.begin();
vTaskDelay((bBoot ? 500 : 250)/portTICK_PERIOD_MS);
timeManager.checkNTPResponse();
if (bBoot) {
if (timeManager.hasNTPUpdate()) {
ui.message(1, (char *) "Time...OK!");
// OTA
DPRINTLN("Setup - TimeManager.begin()");
DPRINTLN("\n===============================\n");
DPRINTLN(" Trying OTA");
ui.message(2, (char *) "Update check...");
checkOTA(true);
ui.message(2, (char *) "Update OK!");
DPRINTLN(" OTA Process completed!");
DPRINTLN("===============================\n");
} else {
ui.message(2, (char *) "Update check SKIPPED!");
timeManager.sendNTPRequest();
}
}
// Host
if (bBoot) ui.message(3, (char *) "Server...");
host.Setup();
DPRINTLN("Setup - host.Setup()");
if (bBoot) ui.message(3, (char *) "Server...OK!");
g_bWiFiSetupExecuted = true;
}
}
void setupPins() {
// --- Basic Digital Pin Initialization ---
pinMode(PIN_HEATER1, OUTPUT);
pinMode(PIN_HEATER2, OUTPUT);
digitalWrite(PIN_HEATER1, HEATER_OFF);
digitalWrite(PIN_HEATER2, HEATER_OFF);
// --- 1. High Speed Group: Motor and Fan (~26kHz) ---
// Core 2.0.17 uses APB (80MHz). 80MHz / (3 * 1024) ≈ 26kHz.
ledcAttachChannel(PIN_MOTOR, PWM_26KHZ_FREQ, PWM_RESOLUTION, PWM_MOTOR_CHANNEL);
ledcAttachChannel(PIN_FAN, PWM_26KHZ_FREQ, PWM_RESOLUTION, PWM_FAN_CHANNEL);
// --- 2. Medium Speed Group: LED & Heaters (1221Hz) ---
// 80MHz / (64 * 1024) = 1220.7Hz.
ledcAttachChannel(PIN_LIGHT, PWM_1KHZ_FREQ, PWM_RESOLUTION, PWM_LIGHT_CHANNEL);
ledcAttachChannel(PIN_LED_HEATER1, PWM_1KHZ_FREQ, PWM_RESOLUTION, PWM_HEATER1_CHANNEL);
ledcAttachChannel(PIN_LED_HEATER2, PWM_1KHZ_FREQ, PWM_RESOLUTION, PWM_HEATER2_CHANNEL);
// --- 3. Low Speed Group: Mist & WiFi LED (1.19Hz) ---
// Initialized at 1Hz to bypass the slow divider calculation/WDT panic.
// Must be ESP32 coer version 3.0.2 in ordre to set 1Hz
ledcAttachChannel(PIN_MIST, PWM_1HZ_FREQ, PWM_RESOLUTION, PWM_MIST_CHANNEL);
ledcAttachChannel(PIN_LED_WIFI, PWM_1HZ_FREQ, PWM_RESOLUTION, PWM_WIFI_LED_CHANNEL);
// --- Initial State Writes ---
ledcWrite(PIN_MOTOR, PWM_OFF);
ledcWrite(PIN_FAN, PWM_OFF);
ledcWrite(PIN_LIGHT, PWM_OFF);
ledcWrite(PIN_MIST, PWM_OFF);
ledcWrite(PIN_LED_WIFI, (PWM_FULL * 4) / 5); // 80% Initial Blink
// Heaters (Inverted logic for MOSFET safety)
ledcWrite(PIN_LED_HEATER1, PWM_FULL - PWM_OFF);
ledcWrite(PIN_LED_HEATER2, PWM_FULL - PWM_OFF);
}
void setupStatus() {
if (config.bStatusSaved) {
status = config.statusSave;
config.bStatusSaved = false;
}
// init sensor and counter
status.nTemp1 = 0;
status.nTemp2 = 0;
status.nTemp3 = 0;
status.nHumid1 = 0;
status.nHumid2 = 0;
status.zcdAC = 0;
status.zcdLoad = 0;
status.nFlags = 0x00;
}
void restoreStatus() {
if (isWiFiConnected()) {
if (timeManager.hasNTPUpdate()) {
time_t now;
time(&now);
uint32_t gap = (uint32_t)now - config.statusSave.now;
DPRINTF("Reboot within %.1f seconds after last reset... \n", gap / 1000.0f);
if (gap < 60000 && config.bStatusSaved) {
status = config.statusSave;
status.nFlags |= (uint16_t)(config.statusSave.nFlags & 0xFF);
status.nLightDuty = 0;
config.bStatusSaved = false;
DPRINTLN(" Status Restored!");
} else {
DPRINTLN(" Status NOT Restored!");
}
}
}
}
void scanI2C() {
Wire.begin();
DPRINTLN("I2C - Scanning...");
for (byte addr = 1; addr < 127; addr++) {
Wire.beginTransmission(addr);
if (Wire.endTransmission() == 0) {
DPRINTF("I2C - Found device at address: 0x%02X\n", addr);
}
}
DPRINTLN(" Scanning Done.");
}
void setupSensor() {
// AHTx0
if (aht25.setup()) {
delay(82);
aht25.readSensor(millis());
DPRINTF("AHT25 initialized successfully at 0x38. Temp: %.2f, Humid: %.2f%%\n",
aht25.getTemperature() / 100.0f, aht25.getHumidity() / 100.0f);
}
delay(10);
if (aht10_0x39.setup(0x39)) { //begin(PIN_SCL, PIN_SDA, AHT10_ADDRESS_0X39)) {
delay(82);
if (aht10_0x39.readSensor(millis())) {
//aht10_0x39.initBuffer();
}
DPRINTF("AHTx0 initialized successfully at 0x39. Temp: %.2f, Humid: %.2f%%\n",
aht10_0x39.getTemperature() / 100.0f , aht10_0x39.getHumidity() / 100.0f );
}
delay(10);
history.init(status.nTemp1, status.nHumid1);
if (!aht25.sensor() && !aht10_0x39.sensor()) {
DPRINTF("AHTx0 initialization failed. SCL:%d SDA:%d\n", PIN_SCL, PIN_SDA );
}
// Temp3 - NTC
ntc.setup(config.bNTCNegativePolarity);
status.nTemp3 = ntc.getTemp();
}