ProcessPacket using JumpTable

This commit is contained in:
Heuideog Yi @ PC RnD1 2026-04-24 08:42:52 +09:00
parent 3eeeb8304d
commit 95cbe9f950
15 changed files with 581 additions and 526 deletions

View File

@ -24,7 +24,7 @@ void CONFIG_TYPE::init() {
bNightControl = false; bNightControl = false;
bControlTemperature = true; bControlTemperature = true;
bControlHumidity = true; bControlHumidity = true;
bEnableIO = true; bCheckAC = true;
bAC2_OnOff = false; bAC2_OnOff = false;
nNightStartHour = 18; nNightStartHour = 18;
@ -32,18 +32,25 @@ void CONFIG_TYPE::init() {
nNightEndHour = 6; nNightEndHour = 6;
nNightEndMin = 0; nNightEndMin = 0;
ac1ControlMode = PHASE_CONTROL;
ac2ControlMode = ZCD_CONTROL;
// Block 2 - Sensor and Temperature/Humidity Settings // Block 2 - Sensor and Temperature/Humidity Settings
nTempTarget = 260; nTempTarget = 260;
nTempTargetNight = 260; nTempTargetNight = 260;
nTemp1Offset = 0; nTemp1Offset = 0;
nTemp2Offset = 0; nTemp2Offset = 0;
nTemp3Offset = 0; nTemp3Offset = 0;
nHumidTarget = 880; nHumidTarget = 800;
nHumidTargetNight = 880; nHumidTargetNight = 800;
nHumid1Offset = 0; nHumid1Offset = 0;
nHumid2Offset = 0; nHumid2Offset = 0;
nTemp1SensorType = TEMP_SENSOR_TYPE::BLE_TUYA; nTemp1SensorType = TEMP_SENSOR_TYPE::BLE_TUYA;
nTemp2SensorType = TEMP_SENSOR_TYPE::AHT20; nTemp2SensorType = TEMP_SENSOR_TYPE::AHT20;
nTempSafety = 290;
bNTCNegativePolarity = true;
nBLEScanInterval = 143;
bBLETest = false;
Kp_Temp1 = 3.0f; // Load Kp for Temperature control Kp_Temp1 = 3.0f; // Load Kp for Temperature control
Kd_Temp1 = 750.0f; // Load Kd for Temperature control Kd_Temp1 = 750.0f; // Load Kd for Temperature control
@ -52,27 +59,43 @@ void CONFIG_TYPE::init() {
Kp_Humidity = 2.0f; // Load Kp for Humidity control Kp_Humidity = 2.0f; // Load Kp for Humidity control
Kd_Humidity = 150.0f; // Load Kd for Humidity control Kd_Humidity = 150.0f; // Load Kd for Humidity control
LR_Humidity = 0.08f; // Load learning rate for Humidity LR_Humidity = 0.08f; // Load learning rate for Humidity
Kp_Temp2 = 3.0f; // Load Kp for Temperature control
Kd_Temp2 = 750.0f; // Load Kd for Temperature control
LR_Temp2 = 0.05f; // Load learning rate for Temperature
Kp_Humid2 = 2.0f; // Load Kp for Humidity control
Kd_Humid2 = 150.0f; // Load Kd for Humidity control
LR_Humid2 = 0.08f; // Load learning rate for Humidity
Kp_Temp3 = 3.0f; // Load Kp for Temperature control
Kd_Temp3 = 750.0f; // Load Kd for Temperature control
LR_Temp3 = 0.05f; // Load learning rate for Temperature
Kp_Humid3 = 2.0f; // Load Kp for Humidity control
Kd_Humid3 = 150.0f; // Load Kd for Humidity control
LR_Humid3 = 0.08f; // Load learning rate for Humidity
// Block 3 - AC1 and AC2 // Block 3 - AC1 and AC2
// Day/Night Min/Max/Start On/Off THigh/Low Time B/E Period Hum H/L // Day/Night Min/Max/Start On/Off THigh/Low Time B/E Period Hum H/L
config.ac1 = {CONTROL_TEMP_HEAT_PID, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,24*60-1, 60, 5, 920,880 }; config.ac1 = {CONTROL_TEMP_HEAT_PID, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,24*60-1, 60, 5, 820,780 };
config.ac2 = {CONTROL_TEMP_HEAT, 0, 0,0, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 920,880 }; config.ac2 = {CONTROL_TEMP_HEAT, 0, 0,0, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 820,780 };
// Block 4 = Mist and Fan // Block 4 = Mist and Fan
// Day/Night Min/Max/Start On/Off THigh/Low Time B/E Period Hum H/L // Day/Night Min/Max/Start On/Off THigh/Low Time B/E Period Hum H/L
config.mist = {CONTROL_HUMIDITY_INC_PID, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 920,880 }; config.mist = {CONTROL_HUMIDITY_INC_PID, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 820,780 };
config.fan = {CONTROL_TEMP_COOL, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 920,880 }; config.fan = {CONTROL_TEMP_COOL, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 820,780 };
// Block 5 - Motor and Light // Block 5 - Motor and Light
// Day/Night Min/Max/Start On/Off THigh/Low Time B/E Period Hum H/L // Day/Night Min/Max/Start On/Off THigh/Low Time B/E Period Hum H/L
config.motor = {CONTROL_PERIOD, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 920,880 }; config.motor = {CONTROL_PERIOD, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 820,780 };
config.light = {CONTROL_DAY_NIGHT, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 920,880 }; config.light = {CONTROL_DAY_NIGHT, 0, 1,1, 0, 1000, 0, 250,0, 920,880, 0,25*60-1, 60, 5, 820,780 };
// Block 6 - Environment and Operations // Block 6 - Environment and Operations
bSendStatusSerial = false;
bConfigSaved = false; bConfigSaved = false;
bStatusSaved = false; bStatusSaved = false;
bSendStatusSerial = false;
// //
// Reserved // Reserved
@ -81,8 +104,8 @@ void CONFIG_TYPE::init() {
for (int i = 0; i < 17; i = i + 8) { for (int i = 0; i < 17; i = i + 8) {
m_nChipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; m_nChipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
} }
m_nPublicPort = 3939;
m_nDeviceType = THIS_DEVICE_TYPE; m_nDeviceType = THIS_DEVICE_TYPE;
m_nPublicPort = 3939;
// //
// WiFi Client Only // WiFi Client Only
@ -90,19 +113,26 @@ void CONFIG_TYPE::init() {
m_nDisplayTime = 1800; m_nDisplayTime = 1800;
m_nDisplayTempHigh = 40; m_nDisplayTempHigh = 40;
m_nDisplayTempLow = 20; m_nDisplayTempLow = 20;
m_nTempHigh = 20; m_nTempHigh = 25;
m_fShowRealTime = 0x000F; m_fShowRealTime = 0x000F;
m_fShowHistory = 0x000F;
// Names m_nEpochTime = 0;
strcpy(m_sDeviceName, "Beta X"); m_nTimeOffset = 9 * 60 * 60;
strcpy(m_sMake, "VisionSoft"); m_bFahrenheit = false;
strcpy(m_sModel, "HermitCrab");
strncpy(m_sVersion, HC__VERSION, 11);
// WiFi - SSID and Password // WiFi - SSID and Password
strcpy(ssid, "RECALL"); strcpy(ssid, "RECALL");
strcpy(pw, "BBBB9999"); strcpy(pw, "BBBB9999");
//Block 10
strcpy(m_sDeviceName, "Beta X");
strcpy(m_sMake, "VisionSoft");
// Block 11
strcpy(m_sModel, "HermitCrab");
strncpy(m_sVersion, HC__VERSION, 11);
ESP_LOGI(TAG,"Config Initialized"); ESP_LOGI(TAG,"Config Initialized");
} }

View File

@ -70,17 +70,14 @@ enum TEMP_SENSOR_TYPE {
typedef struct CONFIG_STRUCT { typedef struct CONFIG_STRUCT {
uint16_t m_nSignature1; uint16_t m_nSignature1;
// Block 1 - Control and EnvironMent // Block 1 - Control and EnvironMent
// Offset 2 // Offset 2
bool bSmartControl; bool bSmartControl;
bool bNightControl; bool bNightControl;
bool bControlTemperature; bool bControlTemperature;
bool bControlHumidity; bool bControlHumidity;
bool bEnableIO;
bool bCheckAC; bool bCheckAC;
bool bAC2_OnOff; bool bAC2_OnOff;
bool bdummy;
uint8_t nNightStartHour, nNightStartMin, nNightEndHour, nNightEndMin; uint8_t nNightStartHour, nNightStartMin, nNightEndHour, nNightEndMin;
float Kp_Temp2; // Load Kp for Temperature control float Kp_Temp2; // Load Kp for Temperature control
float Kd_Temp2; // Load Kd for Temperature control float Kd_Temp2; // Load Kd for Temperature control
@ -88,28 +85,33 @@ typedef struct CONFIG_STRUCT {
float Kp_Temp3; // Load Kp for Temperature control float Kp_Temp3; // Load Kp for Temperature control
float Kd_Temp3; // Load Kd for Temperature control float Kd_Temp3; // Load Kd for Temperature control
float LR_Temp3; // Load learning rate for Temperature float LR_Temp3; // Load learning rate for Temperature
uint8_t ac1ControlMode, ac2ControlMode; // ZCD_CONTROL || PHASE_CONTROL
uint8_t bPadding1[2];
union { union {
uint64_t nBLESensorAddr2; uint64_t nBLESensorAddr2;
uint8_t nBLESensorAddrBytes2[8]; uint8_t nBLESensorAddrBytes2[8];
}; };
uint8_t ac1ControlMode, ac2ControlMode; // ZCD_CONTROL || PHASE_CONTROL float Kp_Humid2;
char bExtra[64 - 8 * sizeof(bool) - 4 * sizeof(uint8_t) - 6 * sizeof(float) - sizeof(uint64_t) - 2 * sizeof(uint8_t)]; float Kd_Humid2;
float LR_Humid2;
char bExtra[64 - 6 * sizeof(bool) - 8 * sizeof(uint8_t) - 9 * sizeof(float) - sizeof(uint64_t)];
// Block 2 - Sensor and TargetTemperature and Himidity // Block 2 - Sensor and TargetTemperature and Himidity
// Offset 64 + 2 // Offset 64 + 2
int16_t nTempTarget, nTempTargetNight; // Target Temperature int16_t nTempTarget, nTempTargetNight; // Target Temperature
int16_t nTemp1Offset, nTemp2Offset, nTemp3Offset; int16_t nTemp1Offset, nTemp2Offset, nTemp3Offset;
uint16_t nHumidTarget, nHumidTargetNight; uint16_t nHumidTarget, nHumidTargetNight;
int16_t nHumid1Offset, nHumid2Offset; int16_t nHumid1Offset, nHumid2Offset;
uint8_t nTemp1SensorType; // TempSensor Type enum uint8_t nTemp1SensorType; // TempSensor Type enum
uint8_t nTemp2SensorType; // TempSensor Type enum uint8_t nTemp2SensorType; // TempSensor Type enum
float Kp_Temp1; // Load Kp for Temperature control
float Kd_Temp1; // Load Kd for Temperature control
float LR_Temp1; // Load learning rate for Temperature
float Kp_Humidity; // Load Kp for humidity control
float Kd_Humidity; // Load Kd for humidity control
float LR_Humidity; // Load learning rate for humidity
int16_t nTempSafety; int16_t nTempSafety;
float Kp_Temp1; // Load Kp for Temperature control
float Kd_Temp1; // Load Kd for Temperature control
float LR_Temp1; // Load learning rate for Temperature
float Kp_Humidity; // Load Kp for humidity control
float Kd_Humidity; // Load Kd for humidity control
float LR_Humidity; // Load learning rate for humidity
union { union {
uint64_t nBLESensorAddr; uint64_t nBLESensorAddr;
uint8_t nBLESensorAddrBytes[8]; uint8_t nBLESensorAddrBytes[8];
@ -118,28 +120,36 @@ typedef struct CONFIG_STRUCT {
uint8_t nBLEScanInterval; uint8_t nBLEScanInterval;
uint8_t bBLETest; uint8_t bBLETest;
char nTempExtra[64 - 10 * sizeof(int16_t) - 6 * sizeof(float) - 5 * sizeof(uint8_t) - sizeof(uint64_t)]; char nTempExtra[64 - 10 * sizeof(int16_t) - 6 * sizeof(float) - 5 * sizeof(uint8_t) - sizeof(uint64_t)];
union {
struct {
// Block 3 - AC1 and AC2
// Offset 128 + 2
DEVICE_PARAM_TYPE ac1;
DEVICE_PARAM_TYPE ac2;
// Block 4 - Mist and Fan
// Offset 192 + 2
DEVICE_PARAM_TYPE mist;
DEVICE_PARAM_TYPE fan;
// Block 5 - Motor and Light
// Offset 256 + 2
DEVICE_PARAM_TYPE motor;
DEVICE_PARAM_TYPE light;
};
DEVICE_PARAM_TYPE deviceParamArray[6];
};
// Block 3 - AC1 and AC2
// Offset 128 + 2
DEVICE_PARAM_TYPE ac1;
DEVICE_PARAM_TYPE ac2;
// Block 4 - Mist and Fan
// Offset 192 + 2
DEVICE_PARAM_TYPE mist;
DEVICE_PARAM_TYPE fan;
// Block 5 - Motor and Light
// Offset 256 + 2
DEVICE_PARAM_TYPE motor;
DEVICE_PARAM_TYPE light;
// Block 6 - Environment and Operations // Block 6 - Environment and Operations
// Offset 320 + 2 // Offset 320 + 2
bool bSendStatusSerial;
bool bConfigSaved; bool bConfigSaved;
bool bStatusSaved; bool bStatusSaved;
char nEnvExtra[32 - 3 * sizeof(bool)]; float Kp_Humid3; // Load Kd for humidity control
float Kd_Humid3; // Load Kp for humidity control
float LR_Humid3; // Load learning rate for humidity
bool bSendStatusSerial;
char nEnvExtra[32 - 3 * sizeof(bool) - 3*sizeof(float)];
// Offset 352 + 2 // Offset 352 + 2
STATUS_TYPE statusSave; STATUS_TYPE statusSave;
@ -177,17 +187,18 @@ typedef struct CONFIG_STRUCT {
char nModelExtra[64 - 44]; char nModelExtra[64 - 44];
// Offset 704 + 2 // Offset 704 + 2
char padAlign8[4];
uint16_t m_nSignature2; uint16_t m_nSignature2;
#ifdef ESP32 #ifdef ESP32
// ConfigStruct Size: 708 // ConfigStruct Size: 712
public: public:
void init(); void init();
bool load(); bool load();
void save(); void save();
//bool saveToServer(); //bool saveToServer();
#endif #endif
} CONFIG_TYPE; } __attribute__((aligned(8))) CONFIG_TYPE;
#pragma pack(pop) // Restore previous alignment setting #pragma pack(pop) // Restore previous alignment setting
extern class Preferences preferences; extern class Preferences preferences;

View File

@ -4,6 +4,7 @@
extern bool g_bWiFiSetupExecuted; extern bool g_bWiFiSetupExecuted;
extern bool g_bWiFiHasBeenConnected; extern bool g_bWiFiHasBeenConnected;
void setupPostWiFi(bool bBoot = false); void setupPostWiFi(bool bBoot = false);
void reconnectWiFi(unsigned long tickMillis, bool bConnecting, wl_status_t status);
void WiFiEvent(WiFiEvent_t event) { void WiFiEvent(WiFiEvent_t event) {
switch (event) { switch (event) {
@ -40,20 +41,24 @@ void checkAndUpdateWiFiCredentials() {
} }
} }
IRAM_ATTR IRAM_ATTR void checkWiFi(unsigned long tickMillis) {
void checkWiFi(unsigned long tickMillis) {
static unsigned long lastAttempt = 0;
static bool bConnecting = false; static bool bConnecting = false;
wl_status_t status = WiFi.status(); wl_status_t status = WiFi.status();
// Connected // Connected
if (status == WL_CONNECTED) { if (status == WL_CONNECTED) {
bConnecting = false; bConnecting = false;
g_bWiFiHasBeenConnected = true; g_bWiFiHasBeenConnected = true;
return; // Already connected, no need to proceed further return; // Already connected, no need to proceed further
} }
// Not Connected
reconnectWiFi(tickMillis, bConnecting, status);
}
void reconnectWiFi(unsigned long tickMillis, bool bConnecting, wl_status_t status) {
static unsigned long lastAttempt = 0;
checkAndUpdateWiFiCredentials(); checkAndUpdateWiFiCredentials();
// Connecting // Connecting

View File

@ -20,7 +20,7 @@
#ifndef DEBUG #ifndef DEBUG
#define DEBUG 1 // Set to 0 to disable debug output #define DEBUG 1 // Set to 0 to disable debug output
#endif #endif
//#undef DEBUG #undef DEBUG
//#define BLE_DEBUG //#define BLE_DEBUG
@ -152,6 +152,8 @@ enum EVENT_TYPE {
#define FLAG_BLE_NODATA (0x0800) #define FLAG_BLE_NODATA (0x0800)
#define FLAG_BLE_LOST (0x1000) #define FLAG_BLE_LOST (0x1000)
#define PHASE_CONTROL 0
#define ZCD_CONTROL 1
#pragma pack(push) /* push current alignment to stack */ #pragma pack(push) /* push current alignment to stack */
#pragma pack(1) /* set alignment to 1 byte boundary */ #pragma pack(1) /* set alignment to 1 byte boundary */
@ -200,14 +202,15 @@ typedef struct STATUS_STRUCT {
uint16_t nLightDuty; uint16_t nLightDuty;
uint16_t nLightTargetDuty; uint16_t nLightTargetDuty;
// 24 // 24
uint16_t nFlags;
// 26
// Current Time // Current Time
uint32_t now; uint32_t now;
// 28
uint16_t nFlags;
// 30 // 30
// AC status // AC status
uint8_t zcdAC; uint8_t zcdAC;
uint8_t zcdLoad; uint8_t zcdLoad;

View File

@ -22,6 +22,11 @@
STATUS_TYPE status; STATUS_TYPE status;
// 코어 버전이 3.0.2가 아니면 컴파일 중단
#include <esp_arduino_version.h>
static_assert(ESP_ARDUINO_VERSION == ESP_ARDUINO_VERSION_VAL(3, 0, 2),
"This project requires ESP32 Arduino Core 3.0.2");
// Time // Time
volatile unsigned short g_nYear, g_nMonth, g_nDay, g_nHour, g_nMinute, g_nSecond; volatile unsigned short g_nYear, g_nMonth, g_nDay, g_nHour, g_nMinute, g_nSecond;
volatile uint32_t g_millis = 0l; volatile uint32_t g_millis = 0l;
@ -584,9 +589,6 @@ MY_IRAM_ATTR char *printStatus(unsigned long tick, bool bLong) {
printTime(bLong), strHeat1, strMist, strLight1, printTime(bLong), strHeat1, strMist, strLight1,
history.getKpTemperature(), history.getKdTemperature(), history.getKpTemperature(), history.getKdTemperature(),
history.getKpHumidity(), history.getKdHumidity()); history.getKpHumidity(), history.getKdHumidity());
// Send out to clients
// ESP_LOGI(TAG_MAIN,"%s\n", szStatus);
} }
return szStatus; return szStatus;
} }

View File

@ -1,11 +1,8 @@
#include "Arduino.h" #include <Arduino.h>
#include "HermitCrab.h" #include "HermitCrab.h"
#include "NTC_10K.h"
#include "Config.h" #include "Config.h"
#include "NTC_10K.h"
#include "driver/gpio.h"
#include "driver/adc.h"
const float resistance[] = { const float resistance[] = {
3360850.37, // -40°C 3360850.37, // -40°C
@ -74,6 +71,23 @@ void NTC_10K::setup(bool bNegativePolarity) {
m_nTemp = -9999; m_nTemp = -9999;
m_fTemp = -9999.0f; m_fTemp = -9999.0f;
m_fLastTemp = 0.0f; m_fLastTemp = 0.0f;
// =========================
// 1. NTC (ADC 설정)
// =========================
// 1.1. 핸들 및 설정 변수 선언
adc_oneshot_unit_init_cfg_t init_config = {
.unit_id = ADC_UNIT_1,
};
adc_oneshot_new_unit(&init_config, &adc1_handle);
// 1.2. 채널 설정 (감쇠비 포함)
adc_oneshot_chan_cfg_t config = {
.atten = ADC_ATTEN_DB_12, // 11 대신 12 사용 (이전 답변 참고)
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
adc_oneshot_config_channel(adc1_handle, ADC_CHANNEL_3, &config);
} }
/** /**
@ -90,7 +104,9 @@ void NTC_10K::readSensor() {
float currentInstantTemp; // High-precision intermediate float currentInstantTemp; // High-precision intermediate
// 1. Hardware Acquisition // 1. Hardware Acquisition
int adcValue = constrain(adc1_get_raw(ADC1_CHANNEL_3), 1, 4094); //int adcValue = constrain(adc1_get_raw(ADC1_CHANNEL_3), 1, 4094);
int adcValue;
adc_oneshot_read(adc1_handle, ADC_CHANNEL_3, &adcValue);
// 2. Voltage and Resistance Calculation // 2. Voltage and Resistance Calculation
Vin = (float)adcValue * _vRef / _RESO; Vin = (float)adcValue * _vRef / _RESO;

View File

@ -7,6 +7,7 @@
#define NTC_COUNT 32 #define NTC_COUNT 32
#define NTC_MASK (NTC_COUNT - 1) #define NTC_MASK (NTC_COUNT - 1)
#include <esp_adc/adc_oneshot.h>
class NTC_10K { class NTC_10K {
private: private:
@ -24,6 +25,8 @@ private:
float m_fTemp; float m_fTemp;
float m_fLastTemp; float m_fLastTemp;
adc_oneshot_unit_handle_t adc1_handle;
public: public:
void setup(bool bNegativePolarity); void setup(bool bNegativePolarity);
void readSensor(); void readSensor();

View File

@ -17,7 +17,7 @@
// OTA // OTA
// //
// ============================================================== // ==============================================================
const char *HC__VERSION = "20260419022"; const char *HC__VERSION = "20260424001";
#define UPDATE_PORT ((uint16_t) 443) #define UPDATE_PORT ((uint16_t) 443)
const char *url = "visionsoft.kr"; const char *url = "visionsoft.kr";
const char *uri = "/sc/pages/firmware_download.php"; const char *uri = "/sc/pages/firmware_download.php";

View File

@ -14,12 +14,9 @@
#include "esp_coexist.h" #include "esp_coexist.h"
// GPIO Headers // GPIO Headers
#include "driver/gpio.h" #include <driver/gpio.h>
#include "driver/timer.h" #include <driver/timer.h>
#include "driver/adc.h"
#define TAG_SETUP "TAG_SETUP"
// Task handle // Task handle
TaskHandle_t TaskHandle_0; TaskHandle_t TaskHandle_0;
@ -68,17 +65,23 @@ void setup() {
bShowSensor = false; bShowSensor = false;
// Hardware // Basic settings before wifi/OTA
setupPWM(); setupPWM(); // Required for LED blinking
setupGPIO1(); setupGPIO1();
setupConfig();
setupStatus(); setupConfig(); // Wifi SSID/PW
scanI2C(); scanI2C(); // Wire init
setupSensor(); setupSensor(); // Wire Scan
ui.setup(); ui.setup(); // ui for OLED Display
setupWiFi();
// Wifi and Update Check
setupWiFi(); // Wifi AP, OTA, Time Service
setupStatus(); // Requires Time Service from WiFi Setup.
// Pins
// Temp/Humod Sensor
if (aht25.sensor() || aht10_0x39.sensor()) { if (aht25.sensor() || aht10_0x39.sensor()) {
ui.message(4, (char *) "Sensor... OK!"); ui.message(4, (char *) "Sensor... OK!");
} else { } else {
@ -124,9 +127,6 @@ void setupGPIO1() {
// ========================= // =========================
// 1. NTC (ADC 설정) // 1. NTC (ADC 설정)
// ========================= // =========================
// adc1_config_channel_atten에서 내부적으로 핀 설정을 하므로 방향 설정은 생략 가능합니다.
adc1_config_width(ADC_WIDTH_BIT_12); // 0~4095
adc1_config_channel_atten(ADC1_CHANNEL_3, ADC_ATTEN_DB_11);
// ========================= // =========================
// 2. UI Buttons 설정 // 2. UI Buttons 설정

7
UI.cpp
View File

@ -222,7 +222,7 @@ CUI::CUI()
void CUI::setup() { void CUI::setup() {
// Initialize the display // Initialize the display
ESP_LOGI(TAG_UI," UI - setup()"); DPRINTLN("[UI] setup()");
bOK = false; bOK = false;
bDot = false; bDot = false;
bButtonChanged = false; bButtonChanged = false;
@ -249,18 +249,19 @@ void CUI::setup() {
lastpDUnit = nullptr; lastpDUnit = nullptr;
// Check if device exists // Check if device exists
// Wire.begin();
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
Wire.beginTransmission(i2caddr); Wire.beginTransmission(i2caddr);
if (Wire.endTransmission() == 0) { if (Wire.endTransmission() == 0) {
bOK = true; bOK = true;
ESP_LOGI(TAG_UI," UI - device Found at 0x%02X\n", i2caddr); DPRINTF("[UI] Setup - device Found at 0x%02X\n", i2caddr);
break; break;
} }
delay(50); delay(50);
} }
if (!bOK) { if (!bOK) {
ESP_LOGI(TAG_UI," UI - device NOT found at 0x%02X\n", i2caddr); DPRINTF("[UI] Setup - device NOT found at 0x%02X\n", i2caddr);
return; return;
} }

6
UI.h
View File

@ -102,9 +102,9 @@ private:
// //
// Button ISR's // Button ISR's
// //
void IRAM_ATTR buttonSetISR(void *); void buttonSetISR(void *);
void IRAM_ATTR buttonUpISR(void *); void buttonUpISR(void *);
void IRAM_ATTR buttonDownISR(void *); void buttonDownISR(void *);
extern CUI ui; extern CUI ui;
#endif #endif

View File

@ -164,8 +164,7 @@ void CWiFiHost::CloseConnection()
m_nMode = MODE_WAITING; m_nMode = MODE_WAITING;
} }
IRAM_ATTR IRAM_ATTR void CWiFiHost::Loop(unsigned long clock)
void CWiFiHost::Loop(unsigned long clock)
{ {
if (!isWiFiConnected()) return; if (!isWiFiConnected()) return;
@ -251,8 +250,7 @@ void CWiFiHost::Loop(unsigned long clock)
} }
} }
MY_IRAM_ATTR MY_IRAM_ATTR void CWiFiHost::SendHeartBeat(unsigned long clock) {
void CWiFiHost::SendHeartBeat(unsigned long clock) {
if (!isWiFiConnected()) { if (!isWiFiConnected()) {
//ESP_LOGI(TAG_WIFI_HOST,"WiFiHost - SendHeartBeat() called while not connected!"); //ESP_LOGI(TAG_WIFI_HOST,"WiFiHost - SendHeartBeat() called while not connected!");
return; return;
@ -304,8 +302,7 @@ void CWiFiHost::SendHeartBeat(unsigned long clock) {
} }
} }
MY_IRAM_ATTR MY_IRAM_ATTR void CWiFiHost::MonitorUDP() {
void CWiFiHost::MonitorUDP() {
// Listen for UDP External port // Listen for UDP External port
IPAddress ip; IPAddress ip;
int size = udpExternal.parsePacket(); int size = udpExternal.parsePacket();
@ -358,8 +355,42 @@ void CWiFiHost::MonitorUDP() {
} }
} }
IRAM_ATTR typedef union {
void CWiFiHost::CheckClient(unsigned long clock) float f;
uint32_t u;
} float_bits;
// Optimized for range +/- 0.0001 to +/- 3000
IRAM_ATTR uint16_t f32tof16(float f32) {
float_bits fb;
fb.f = f32;
// Extract sign, move to bit 15
uint32_t sign = (fb.u >> 16) & 0x8000;
// Shift exponent from 8-bit (bias 127) to 5-bit (bias 15)
// 0x7f800000 masks the exponent
uint32_t exp = ((((fb.u & 0x7f800000) >> 23) - 127 + 15) & 0x1f) << 10;
// Truncate 23-bit mantissa to 10-bit
uint32_t mant = (fb.u >> 13) & 0x03ff;
return (uint16_t)(sign | exp | mant);
}
IRAM_ATTR float f16tof32(uint16_t f16) {
float_bits fb;
// Shift sign to bit 31
uint32_t sign = (uint32_t)(f16 & 0x8000) << 16;
// Shift exponent from 5-bit (bias 15) back to 8-bit (bias 127)
uint32_t exp = (((f16 >> 10) & 0x1f) - 15 + 127) << 23;
// Shift 10-bit mantissa back to 23-bit
uint32_t mant = (f16 & 0x03ff) << 13;
fb.u = sign | exp | mant;
return fb.f;
}
IRAM_ATTR void CWiFiHost::CheckClient(unsigned long clock)
{ {
// 1. Quick exit if no data is ready to be read // 1. Quick exit if no data is ready to be read
int available = wifiClient.available(); int available = wifiClient.available();
@ -370,7 +401,6 @@ void CWiFiHost::CheckClient(unsigned long clock)
// 2. Peek or Read the packet // 2. Peek or Read the packet
// We use readBytes because we already verified 'available' >= size // We use readBytes because we already verified 'available' >= size
int count = wifiClient.readBytes((uint8_t*)&cpkt, sizeof(TCP_PACKET)); int count = wifiClient.readBytes((uint8_t*)&cpkt, sizeof(TCP_PACKET));
if (count == sizeof(TCP_PACKET)) { if (count == sizeof(TCP_PACKET)) {
// 3. Validation Logic // 3. Validation Logic
bool sigMatch = (cpkt.sig1 == SIGNATURE1 && cpkt.sig2 == SIGNATURE2); bool sigMatch = (cpkt.sig1 == SIGNATURE1 && cpkt.sig2 == SIGNATURE2);
@ -382,7 +412,7 @@ void CWiFiHost::CheckClient(unsigned long clock)
} else { } else {
// 4. Recovery Logic: Instead of a blocking while-loop, // 4. Recovery Logic: Instead of a blocking while-loop,
// clear the socket buffer and wait for the next loop cycle. // clear the socket buffer and wait for the next loop cycle.
ESP_LOGW(TAG_WIFI_HOST, "Protocol out of sync. Flushing %d bytes", available); DPRINTF("[Host] ErrPacket CMD(%d) OP(%d) len(%d) sig(%s)\n", cpkt.cmd, cpkt.op, cpkt.len, sigMatch ? "OK" : "fail");
while(wifiClient.available() > 0) { while(wifiClient.available() > 0) {
wifiClient.read(); // Efficiently dump the garbage wifiClient.read(); // Efficiently dump the garbage
} }
@ -390,327 +420,333 @@ void CWiFiHost::CheckClient(unsigned long clock)
} }
} }
IRAM_ATTR IRAM_ATTR void CWiFiHost::ProcessPacket(TCP_PACKET& pkt)
void CWiFiHost::ProcessPacket(TCP_PACKET& pkt)
{ {
switch (pkt.cmd) // Jump Table definition (GCC Labels-as-values)
{ static const void* jump_table[] = {
// System [0] = &&L_DEFAULT,
case CMD_HEARTBEAT: // Connection & Control
m_nLastReceivedTime = millis(); [CMD_HEARTBEAT] = &&L_CMD_HEARTBEAT,
//ESP_LOGI(TAG_WIFI_HOST,"H"); [CMD_HELLO] = &&L_CMD_HELLO,
break; [CMD_DROP_CONNECTION] = &&L_CMD_DROP_CONNECTION,
case CMD_HELLO: [CMD_RESET_REASON] = &&L_CMD_RESET_REASON,
case CMD_HELLO_DEBUG: [CMD_RESTART] = &&L_CMD_RESTART,
{ [CMD_SEND_HISTORY] = &&L_CMD_SEND_HISTORY,
// Send the Config Data to PC [CMD_RESET_SENSOR] = &&L_CMD_RESET_SENSOR,
// Send Packet Back [CMD_RESET_DISPLAY] = &&L_CMD_RESET_DISPLAY,
ESP_LOGI(TAG_WIFI_HOST,"WiFi - HELLO received");
pkt.u16[0] = SIGNATURE1;
pkt.n16[1] = sizeof(CONFIG_TYPE);
pkt.u16[2] = SIGNATURE2;
config.m_nChipId;
SendPacket(pkt);
// Send Data Packets
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Config Send pending...");
int sent = SendData((uint8_t*)&config, sizeof(CONFIG_TYPE));
m_bHelloSent = true;
}
break;
case CMD_DROP_CONNECTION:
wifiClient.stop();
m_bClientConnected = false;
m_nMode = MODE_WAITING;
ESP_LOGI(TAG_WIFI_HOST,"WiFI - Client requets to DROP CONNECTION");
break;
case CMD_RESET_REASON:
pkt.n16[0] = esp_reset_reason();
SendPacket(pkt);
break;
case CMD_SAVE_RESTART:
if (pkt.u16[0] == SIGNATURE1 &&
pkt.u16[1] == SIGNATURE2) {
yield();
Restart();
}
break;
case CMD_RESET_RESTART:
if (pkt.u16[0] == SIGNATURE1 &&
pkt.u16[1] == SIGNATURE2) {
pkt.cmd = CMD_DROP_CONNECTION;
SendPacket(pkt);
yield();
Restart();
}
break;
case CMD_SEND_HISTORY:
if (pkt.u16[0] == SIGNATURE1 && pkt.u16[1] == SIGNATURE2) {
int16_t count = history.getRingCount();
if (count > 0 ) {
// inform client the count of history
pkt.op = count;
SendPacket(pkt);
int16_t size = history.getRingSize();
if (count < size) {
ESP_LOGI(TAG_WIFI_HOST,"WfFi Host - SendData - Whold part of History (%d)\n", count);
SendData(history.getRingData1()/* &ring[tail] */, sizeof(STATUS_TYPE) * count);
} else {
int count1st = size - history.getRingTail();
ESP_LOGI(TAG_WIFI_HOST,"WfFi Host - SendData - 1st part of History Total(%d), 1st(%d) H(%d) T(%d)\n",
count, count1st, history.getRingHead(), history.getRingTail());
SendData(history.getRingData1(), sizeof(STATUS_TYPE) * count1st),
// Mark pending to send the second part: from the start to head-1
//SendData(history.getRingData2() /* &ring[0] */, sizeof(STATUS_TYPE) * head);
m_bSendHistoryPending = true;
m_nPendingHistoryCount = history.getRingHead();
}
}
}
break;
case CMD_RESET_SENSOR:
aht25.setScanFlag(true);
aht10_0x39.setScanFlag(true);
break;
// Config // Config
case CMD_INIT_CONFIG: [CMD_INIT_CONFIG] = &&L_CMD_INIT_CONFIG,
if (pkt.u16[0] == SIGNATURE1 && [CMD_LOAD_CONFIG] = &&L_CMD_LOAD_CONFIG,
pkt.u16[1] == sizeof(CONFIG_STRUCT) && [CMD_SAVE_CONFIG] = &&L_CMD_SAVE_CONFIG,
pkt.u16[2] == SIGNATURE2) { [CMD_SEND_CONFIG] = &&L_CMD_SEND_CONFIG,
config.init(); [CMD_RECV_CONFIG] = &&L_CMD_RECV_CONFIG,
config.save(); [CMD_SET_DEVICE_PARAM] = &&L_CMD_SET_DEVICE_PARAM,
} [CMD_GET_DEVICE_PARAM] = &&L_CMD_GET_DEVICE_PARAM,
break;
case CMD_LOAD_CONFIG:
if (pkt.u16[0] == SIGNATURE1 &&
pkt.u16[1] == sizeof(CONFIG_STRUCT) &&
pkt.u16[2] == SIGNATURE2) {
config.load();
history.loadPID();
}
break;
case CMD_SAVE_CONFIG:
if (pkt.u16[0] == SIGNATURE1 &&
pkt.u16[1] == sizeof(CONFIG_STRUCT) &&
pkt.u16[2] == SIGNATURE2) {
config.save();
}
break;
case CMD_RECV_CONFIG:
// Receive Confif Data from PC
if (pkt.u16[0] == SIGNATURE1 &&
pkt.u16[1] == sizeof(CONFIG_STRUCT) &&
pkt.u16[2] == SIGNATURE2) {
ReceiveData((uint8_t *)&configCopy, sizeof(CONFIG_TYPE));
m_bReceiveConfigPending = true;
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Receive Config initiated...");
}
break;
case CMD_SEND_CONFIG:
if (pkt.u16[0] == SIGNATURE1 &&
pkt.u16[1] == sizeof(CONFIG_STRUCT) &&
pkt.u16[2] == SIGNATURE2) {
SendPacket(pkt);
SendData((const uint8_t *)&config, (unsigned int) sizeof(config));
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Send Config initiated...");
}
break;
// PID
case CMD_INIT_PID_PARAM:
history.savePID();
break;
case CMD_LOAD_PID_PARAM:
history.loadPID();
break;
case CMD_SAVE_PID_PARAM:
history.savePID();
break;
case CMD_SET_PID:
config.Kp_Temp1 = pkt.f[0];
config.Kd_Temp1 = pkt.f[1];
config.LR_Temp1 = pkt.f[2];
config.Kp_Humidity = pkt.f[3];
config.Kd_Humidity = pkt.f[4];
config.LR_Humidity = pkt.f[5];
history.loadPID();
break;
case CMD_GET_PID:
pkt.f[0] = config.Kp_Temp1;
pkt.f[1] = config.Kd_Temp1;
pkt.f[2] = config.LR_Temp1;
pkt.f[3] = config.Kp_Humidity;
pkt.f[4] = config.Kd_Humidity;
pkt.f[5] = config.LR_Humidity;
SendPacket(pkt);
break;
// Control // Control
case CMD_SET_CONTROL: [CMD_SET_CONTROL] = &&L_CMD_SET_CONTROL,
config.bSmartControl = pkt.by[0] ? true : false; [CMD_GET_CONTROL] = &&L_CMD_GET_CONTROL,
config.bNightControl = pkt.by[1] ? true : false;
config.bControlTemperature = pkt.by[2] ? true : false;
config.bControlHumidity = pkt.by[3] ? true : false;
break;
case CMD_GET_CONTROL:
pkt.by[0] = config.bSmartControl ? 0xFF : 0;
pkt.by[1] = config.bNightControl ? 0xFF : 0;
pkt.by[2] = config.bControlTemperature ? 0xFF : 0;
pkt.by[3] = config.bControlHumidity ? 0xFF : 0;
SendPacket(pkt);
break;
// Operation // Set
case CMD_SET_TEMP_TARGET: [CMD_SET_TEMP_TARGET] = &&L_CMD_SET_TEMP_TARGET,
config.nTempTarget = pkt.u16[0]; [CMD_SET_TEMP_TARGET_NIGHT] = &&L_CMD_SET_TEMP_TARGET_NIGHT,
ESP_LOGI(TAG_WIFI_HOST,"WiFi - TempTarget changed to: %d\n", pkt.u16[0]); [CMD_SET_HUMID_TARGET] = &&L_CMD_SET_HUMID_TARGET,
break; [CMD_SET_SENSOR_OFFSET] = &&L_CMD_SET_SENSOR_OFFSET,
case CMD_SET_TEMP_TARGET_NIGHT: [CMD_SET_HEATER1_DUTY] = &&L_CMD_SET_HEATER1_DUTY,
config.nTempTargetNight = pkt.u16[0]; [CMD_SET_MANUAL_HEATER1] = &&L_CMD_SET_MANUAL_HEATER1,
ESP_LOGI(TAG_WIFI_HOST,"WiFi - TempTargetNight changed to: %d\n", pkt.u16[0]); [CMD_SET_HEATER2_DUTY] = &&L_CMD_SET_HEATER2_DUTY,
break; [CMD_SET_MANUAL_HEATER2] = &&L_CMD_SET_MANUAL_HEATER2,
case CMD_SET_HUMID_TARGET: [CMD_SET_MIST_DUTY] = &&L_CMD_SET_MIST_DUTY,
config.nHumidTarget = pkt.u16[0]; [CMD_SET_MANUAL_MIST] = &&L_CMD_SET_MANUAL_MIST,
ESP_LOGI(TAG_WIFI_HOST,"WiFi - HumidTarget changed to: %d\n", pkt.u16[0]); [CMD_SET_FAN_DUTY] = &&L_CMD_SET_FAN_DUTY,
break; [CMD_SET_MANUAL_FAN] = &&L_CMD_SET_MANUAL_FAN,
case CMD_SET_SENSOR_OFFSET: [CMD_SET_MOTOR_DUTY] = &&L_CMD_SET_MOTOR_DUTY,
config.nTemp1Offset = pkt.n16[0]; [CMD_SET_MANUAL_MOTOR] = &&L_CMD_SET_MANUAL_MOTOR,
config.nHumid1Offset = pkt.n16[1]; [CMD_SET_LIGHT_DUTY] = &&L_CMD_SET_LIGHT_DUTY,
if (pkt.n16[2] > 1) { [CMD_SET_MANUAL_LIGHT] = &&L_CMD_SET_MANUAL_LIGHT,
config.nTemp2Offset = pkt.n16[2]; [CMD_SET_TIME_NIGHT] = &&L_CMD_SET_TIME_NIGHT,
config.nHumid2Offset = pkt.n16[3]; [CMD_SET_WIFI_CLIENT_DISPLAY] = &&L_CMD_SET_WIFI_CLIENT_DISPLAY,
if (pkt.n16[2] > 2)
config.nTemp3Offset = pkt.n16[4];
}
ESP_LOGI(TAG_WIFI_HOST,"WiFi - SensorOffset changed to: %d, %d\n", pkt.n16[0], pkt.n16[1]);
break;
case CMD_SET_AC1_PARAM: // PID
config.ac1 = pkt.device; [CMD_INIT_PID_PARAM] = &&L_CMD_INIT_PID_PARAM,
break; [CMD_LOAD_PID_PARAM] = &&L_CMD_LOAD_PID_PARAM,
case CMD_SET_AC2_PARAM: [CMD_SAVE_PID_PARAM] = &&L_CMD_SAVE_PID_PARAM,
config.ac2 = pkt.device; [CMD_SET_PID] = &&L_CMD_SET_PID,
break; [CMD_GET_PID] = &&L_CMD_GET_PID
case CMD_SET_MIST_PARAM: };
config.mist = pkt.device;
break;
case CMD_SET_FAN_PARAM:
config.fan = pkt.device;
break;
case CMD_SET_MOTOR_PARAM:
config.motor = pkt.device;
break;
case CMD_SET_LIGHT_PARAM:
config.light = pkt.device;
break;
// Status // Bounds check to prevent illegal memory access
case CMD_SET_HEATER1_DUTY: if (pkt.cmd >= CMD_COUNT || pkt.cmd <= 0) goto L_DEFAULT;
status.nHeater1Duty = pkt.u16[0]; DPRINTF("[HOST] CMD(%d) OP(%d) LEN(%d) U[%d][%d][%d][%d]\n",
if (pkt.u16[1]) pkt.cmd, pkt.op, pkt.len, pkt.u16[0], pkt.u16[1], pkt.u16[2], pkt.u16[3]);
status.nFlags |= FLAG_MANUAL_HEATER1;
else
status.nFlags &= ~FLAG_MANUAL_HEATER1;
if (status.nHeater1Duty == 0) {
setHeater1Duty(0);
}
break;
case CMD_SET_HEATER2_DUTY:
status.nHeater2Duty = pkt.u16[0];
if (pkt.u16[1])
status.nFlags |= FLAG_MANUAL_HEATER2;
else
status.nFlags &= ~FLAG_MANUAL_HEATER2;
if (status.nHeater2Duty == 0) {
setHeater2Duty(0);
}
break;
case CMD_SET_MIST_DUTY:
status.nMistDuty = pkt.u16[0];
if (pkt.u16[1])
status.nFlags |= FLAG_MANUAL_MIST;
else
status.nFlags &= ~FLAG_MANUAL_MIST;
break;
case CMD_SET_FAN_DUTY:
status.nFanDuty = pkt.u16[0];
if (pkt.u16[1])
status.nFlags |= FLAG_MANUAL_FAN;
else
status.nFlags &= ~FLAG_MANUAL_FAN;
break; // Direct jump
case CMD_SET_MOTOR_DUTY: goto *jump_table[pkt.cmd];
status.nMotorDuty = pkt.u16[0];
if (pkt.u16[1])
status.nFlags |= FLAG_MANUAL_MOTOR;
else
status.nFlags &= ~FLAG_MANUAL_MOTOR;
break;
case CMD_SET_LIGHT_DUTY:
status.nLightTargetDuty = pkt.u16[0];
if (pkt.u16[1])
status.nFlags |= FLAG_MANUAL_LIGHT;
else
status.nFlags &= ~FLAG_MANUAL_LIGHT;
break;
// Manual Operation L_CMD_HEARTBEAT:
case CMD_SET_MANUAL_HEATER1: m_nLastReceivedTime = millis();
if (pkt.u16[0]) return;
status.nFlags |= FLAG_MANUAL_HEATER1;
else
status.nFlags &= ~FLAG_MANUAL_HEATER1;
break;
case CMD_SET_MANUAL_HEATER2:
if (pkt.u16[0])
status.nFlags |= FLAG_MANUAL_HEATER2;
else
status.nFlags &= ~FLAG_MANUAL_HEATER2;
break;
case CMD_SET_MANUAL_MIST:
if (pkt.u16[0])
status.nFlags |= FLAG_MANUAL_MIST;
else
status.nFlags &= ~FLAG_MANUAL_MIST;
break;
case CMD_SET_MANUAL_FAN:
if (pkt.u16[0])
status.nFlags |= FLAG_MANUAL_FAN;
else
status.nFlags &= ~FLAG_MANUAL_FAN;
break;
case CMD_SET_MANUAL_LIGHT:
if (pkt.u16[0])
status.nFlags |= FLAG_MANUAL_LIGHT;
else
status.nFlags &= ~FLAG_MANUAL_LIGHT;
break;
// Time L_CMD_HELLO:
case CMD_SET_TIME_NIGHT: DPRINTLN("[WiFi] HELLO received");
config.nNightStartHour = pkt.u16[0]; pkt.u16[0] = SIGNATURE1;
config.nNightStartMin = pkt.u16[1]; pkt.n16[1] = (int16_t)sizeof(CONFIG_TYPE);
config.nNightEndHour = pkt.u16[2]; pkt.u16[2] = SIGNATURE2;
config.nNightEndMin = pkt.u16[3]; SendPacket(pkt);
break; SendData((uint8_t*)&config, sizeof(CONFIG_TYPE));
case CMD_SET_WIFI_CLIENT_DISPLAY: m_bHelloSent = true;
config.m_nDisplayTempHigh = pkt.n16[0]; return;
config.m_nDisplayTempLow = pkt.n16[1];
config.m_nDisplayTime = pkt.n16[2];
config.m_fShowRealTime = pkt.n16[3];
config.m_fShowHistory = pkt.n16[4];
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Client Display Settings changed.");
break;
default: L_CMD_DROP_CONNECTION:
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Packet Received Type: %d\n", pkt.cmd); wifiClient.stop();
break; m_bClientConnected = false;
m_nMode = MODE_WAITING;
DPRINTLN("[WiFI] Host - Client requests to DROP CONNECTION");
return;
L_CMD_RESET_REASON:
pkt.n16[0] = (int16_t)esp_reset_reason();
SendPacket(pkt);
return;
L_CMD_RESTART:
if (pkt.u16[0] == SIGNATURE1 && pkt.u16[1] == SIGNATURE2) {
if (pkt.op)
config.save();
pkt.cmd = CMD_DROP_CONNECTION;
SendPacket(pkt);
Restart();
} }
return;
L_CMD_SEND_HISTORY:
if (pkt.u16[0] == SIGNATURE1 && pkt.u16[1] == SIGNATURE2) {
int16_t count = history.getRingCount();
if (count > 0 ) {
pkt.op = count;
SendPacket(pkt);
int16_t size = history.getRingSize();
if (count < size) {
SendData(history.getRingData1(), sizeof(STATUS_TYPE) * count);
} else {
int count1st = size - history.getRingTail();
SendData(history.getRingData1(), sizeof(STATUS_TYPE) * count1st);
m_bSendHistoryPending = true;
m_nPendingHistoryCount = history.getRingHead();
}
}
}
return;
L_CMD_RESET_SENSOR:
aht25.setScanFlag(true);
aht10_0x39.setScanFlag(true);
return;
L_CMD_RESET_DISPLAY:
return;
L_CMD_INIT_CONFIG:
if (pkt.u16[0] == SIGNATURE1 && pkt.u16[1] == sizeof(CONFIG_STRUCT) && pkt.u16[2] == SIGNATURE2) {
config.init();
config.save();
}
return;
L_CMD_LOAD_CONFIG:
if (pkt.u16[0] == SIGNATURE1 && pkt.u16[1] == sizeof(CONFIG_STRUCT) && pkt.u16[2] == SIGNATURE2) {
config.load();
history.loadPID();
}
return;
L_CMD_SAVE_CONFIG:
if (pkt.u16[0] == SIGNATURE1 && pkt.u16[1] == sizeof(CONFIG_STRUCT) && pkt.u16[2] == SIGNATURE2) {
config.save();
}
return;
L_CMD_RECV_CONFIG:
if (pkt.u16[0] == SIGNATURE1 && pkt.u16[1] == sizeof(CONFIG_STRUCT) && pkt.u16[2] == SIGNATURE2) {
ReceiveData((uint8_t *)&configCopy, sizeof(CONFIG_TYPE));
m_bReceiveConfigPending = true;
m_bSaveReceivedConfig = pkt.op ? true : false;
DPRINTLN("[WiFi] Host - Receive Config initiated...");
}
return;
L_CMD_SEND_CONFIG:
if (pkt.u16[0] == SIGNATURE1 && pkt.u16[1] == sizeof(CONFIG_STRUCT) && pkt.u16[2] == SIGNATURE2) {
SendPacket(pkt);
SendData((const uint8_t *)&config, sizeof(config));
DPRINTLN("[WiFi] Host - Send Config initiated...");
}
return;
L_CMD_SET_DEVICE_PARAM:
config.deviceParamArray[pkt.op] = pkt.device;
return;
L_CMD_GET_DEVICE_PARAM:
pkt.device = config.deviceParamArray[pkt.op];
return;
L_CMD_GET_CONTROL:
pkt.by[0] = config.bSmartControl ? 0xFF : 0x00;
pkt.by[1] = config.bNightControl ? 0xFF : 0x00;
pkt.by[2] = config.bControlTemperature ? 0xFF : 0x00;
pkt.by[3] = config.bControlHumidity ? 0xFF : 0x00;
SendPacket(pkt);
return;
L_CMD_SET_CONTROL:
config.bSmartControl = pkt.by[0] ? true : false;
config.bNightControl = pkt.by[1] ? true : false;
config.bControlTemperature = pkt.by[2] ? true : false;
config.bControlHumidity = pkt.by[3] ? true : false;
return;
L_CMD_SET_TEMP_TARGET:
config.nTempTarget = pkt.u16[0];
config.nTempTargetNight = pkt.u16[1];
return;
L_CMD_SET_TEMP_TARGET_NIGHT:
config.nTempTargetNight = pkt.u16[0];
return;
L_CMD_SET_HUMID_TARGET:
config.nHumidTarget = pkt.u16[0];
return;
L_CMD_SET_SENSOR_OFFSET:
config.nTemp1Offset = pkt.n16[0];
config.nTemp2Offset = pkt.n16[1];
config.nTemp3Offset = pkt.n16[2];
config.nHumid1Offset = pkt.n16[3];
config.nHumid2Offset = pkt.n16[4];
//config.nHumid3Offset = pkt.n16[5]; T3 = NTC No Humidity
return;
L_CMD_SET_HEATER1_DUTY:
status.nHeater1Duty = pkt.u16[0];
L_CMD_SET_MANUAL_HEATER1:
if (pkt.u16[1]) status.nFlags |= FLAG_MANUAL_HEATER1;
else status.nFlags &= ~FLAG_MANUAL_HEATER1;
if (status.nHeater1Duty == 0) setHeater1Duty(0);
return;
L_CMD_SET_HEATER2_DUTY:
status.nHeater2Duty = pkt.u16[0];
L_CMD_SET_MANUAL_HEATER2:
if (pkt.u16[1]) status.nFlags |= FLAG_MANUAL_HEATER2;
else status.nFlags &= ~FLAG_MANUAL_HEATER2;
if (status.nHeater2Duty == 0) setHeater2Duty(0);
return;
L_CMD_SET_MIST_DUTY:
status.nMistDuty = pkt.u16[0];
L_CMD_SET_MANUAL_MIST:
if (pkt.u16[1]) status.nFlags |= FLAG_MANUAL_MIST;
else status.nFlags &= ~FLAG_MANUAL_MIST;
return;
L_CMD_SET_FAN_DUTY:
status.nFanDuty = pkt.u16[0];
L_CMD_SET_MANUAL_FAN:
if (pkt.u16[1]) status.nFlags |= FLAG_MANUAL_FAN;
else status.nFlags &= ~FLAG_MANUAL_FAN;
return;
L_CMD_SET_MOTOR_DUTY:
status.nMotorDuty = pkt.u16[0];
L_CMD_SET_MANUAL_MOTOR:
if (pkt.u16[1]) status.nFlags |= FLAG_MANUAL_MOTOR;
else status.nFlags &= ~FLAG_MANUAL_MOTOR;
return;
L_CMD_SET_LIGHT_DUTY:
status.nLightTargetDuty = pkt.u16[0];
L_CMD_SET_MANUAL_LIGHT:
if (pkt.u16[1]) status.nFlags |= FLAG_MANUAL_LIGHT;
else status.nFlags &= ~FLAG_MANUAL_LIGHT;
return;
L_CMD_SET_TIME_NIGHT:
config.nNightStartHour = pkt.u16[0];
config.nNightStartMin = pkt.u16[1];
config.nNightEndHour = pkt.u16[2];
config.nNightEndMin = pkt.u16[3];
return;
L_CMD_SET_WIFI_CLIENT_DISPLAY:
config.m_nDisplayTempHigh = pkt.n16[0];
config.m_nDisplayTempLow = pkt.n16[1];
config.m_nDisplayTime = pkt.n16[2];
config.m_fShowRealTime = pkt.n16[3];
config.m_fShowHistory = pkt.n16[4];
return;
L_CMD_INIT_PID_PARAM:
L_CMD_SAVE_PID_PARAM:
history.savePID();
return;
L_CMD_LOAD_PID_PARAM:
history.loadPID();
return;
L_CMD_SET_PID:
config.Kp_Temp1 = f16tof32(pkt.u16[0]);
config.Kd_Temp1 = f16tof32(pkt.u16[1]);
config.LR_Temp1 = f16tof32(pkt.u16[2]);
config.Kp_Temp2 = f16tof32(pkt.u16[3]);
config.Kd_Temp2 = f16tof32(pkt.u16[4]);
config.LR_Temp2 = f16tof32(pkt.u16[5]);
config.Kp_Temp3 = f16tof32(pkt.u16[6]);
config.Kd_Temp3 = f16tof32(pkt.u16[7]);
config.LR_Temp3 = f16tof32(pkt.u16[8]);
config.Kp_Humidity = f16tof32(pkt.u16[9]);
config.Kd_Humidity = f16tof32(pkt.u16[10]);
config.LR_Humidity = f16tof32(pkt.u16[11]);
config.Kp_Humid2 = f16tof32(pkt.u16[12]);
config.Kd_Humid2 = f16tof32(pkt.u16[13]);
config.LR_Humid2 = f16tof32(pkt.u16[14]);
config.Kp_Humid3 = f16tof32(pkt.u16[15]);
config.Kd_Humid3 = f16tof32(pkt.u16[16]);
config.LR_Humid3 = f16tof32(pkt.u16[17]);
history.loadPID();
return;
L_CMD_GET_PID:
pkt.u16[0] = f32tof16(config.Kp_Temp1);
pkt.u16[1] = f32tof16(config.Kd_Temp1);
pkt.u16[2] = f32tof16(config.LR_Temp1);
pkt.u16[3] = f32tof16(config.Kp_Temp2);
pkt.u16[4] = f32tof16(config.Kd_Temp2);
pkt.u16[5] = f32tof16(config.LR_Temp2);
pkt.u16[6] = f32tof16(config.Kp_Temp3);
pkt.u16[7] = f32tof16(config.Kd_Temp3);
pkt.u16[8] = f32tof16(config.LR_Temp3);
pkt.u16[9] = f32tof16(config.Kp_Humidity);
pkt.u16[10] = f32tof16(config.Kd_Humidity);
pkt.u16[11] = f32tof16(config.LR_Humidity);
pkt.u16[12] = f32tof16(config.Kp_Humid2);
pkt.u16[13] = f32tof16(config.Kd_Humid2);
pkt.u16[14] = f32tof16(config.LR_Humid2);
pkt.u16[15] = f32tof16(config.Kp_Humid3);
pkt.u16[16] = f32tof16(config.Kd_Humid3);
pkt.u16[17] = f32tof16(config.LR_Humid3);
SendPacket(pkt);
return;
L_DEFAULT:
DPRINTF("[WiFi] Host - Unknown Packet: %d\n", pkt.cmd);
return;
} }
IRAM_ATTR IRAM_ATTR int CWiFiHost::SendPacket(TCP_PACKET& pkt)
int CWiFiHost::SendPacket(TCP_PACKET& pkt)
{ {
size_t sent = 0; size_t sent = 0;
if (m_bClientConnected && wifiClient && wifiClient.connected()) if (m_bClientConnected && wifiClient && wifiClient.connected())
@ -720,23 +756,21 @@ int CWiFiHost::SendPacket(TCP_PACKET& pkt)
return sent; return sent;
} }
IRAM_ATTR IRAM_ATTR size_t CWiFiHost::SendData(const uint8_t* data, size_t size) {
size_t CWiFiHost::SendData(const uint8_t* data, size_t size) {
if (data != nullptr) { if (data != nullptr) {
m_nMode = MODE_SEND; m_nMode = MODE_SEND;
m_pDataSend_data = (char *) data; m_pDataSend_data = (char *) data;
m_nDataSend_size = size; m_nDataSend_size = size;
m_nDataSend_sent = 0; m_nDataSend_sent = 0;
ESP_LOGI(TAG_WIFI_HOST,"WfFi Host - SendData(size: %d)\n", size); DPRINTF("[HOST] Host - SendData(size: %d)\n", size);
return size; return size;
} }
return 0; return 0;
} }
IRAM_ATTR
// This function sends a small "chunk" then returns false. // This function sends a small "chunk" then returns false.
// It returns true ONLY when the entire buffer is finished. // It returns true ONLY when the entire buffer is finished.
bool CWiFiHost::SendData(unsigned long clock) IRAM_ATTR bool CWiFiHost::SendData(unsigned long clock)
{ {
if (!m_pDataSend_data || m_nDataSend_size == 0) return true; if (!m_pDataSend_data || m_nDataSend_size == 0) return true;
@ -766,8 +800,7 @@ bool CWiFiHost::SendData(unsigned long clock)
return true; return true;
} }
IRAM_ATTR IRAM_ATTR size_t CWiFiHost::ReceiveData(uint8_t* data, size_t size)
size_t CWiFiHost::ReceiveData(uint8_t* data, size_t size)
{ {
m_nMode = MODE_RECV; m_nMode = MODE_RECV;
m_pDataReceive_data = (char *) data; m_pDataReceive_data = (char *) data;
@ -776,8 +809,7 @@ size_t CWiFiHost::ReceiveData(uint8_t* data, size_t size)
return size; return size;
} }
IRAM_ATTR MY_IRAM_ATTR bool CWiFiHost::ReceiveData(unsigned long clock)
bool CWiFiHost::ReceiveData(unsigned long clock)
{ {
// Receive Data // Receive Data
size_t nSize = 0; size_t nSize = 0;
@ -806,22 +838,25 @@ bool CWiFiHost::ReceiveData(unsigned long clock)
if (m_bReceiveConfigPending && m_pDataReceive_data == (char *)&configCopy) { if (m_bReceiveConfigPending && m_pDataReceive_data == (char *)&configCopy) {
config = configCopy; config = configCopy;
history.loadPID(); history.loadPID();
ESP_LOGI(TAG_WIFI_HOST,"WiFi - Config Received"); DPRINTLN("[WiFi] Host - Config Received");
m_bReceiveConfigPending = false; m_bReceiveConfigPending = false;
if (m_bSaveReceivedConfig) {
config.save();
m_bSaveReceivedConfig = false;
}
} }
ESP_LOGI(TAG_WIFI_HOST," ReceiveData: Data Receive Completed!"); DPRINTLN("[WIFI] Host - ReceiveData: Data Receive Completed!");
return true; return true;
} }
if (nSize <= 0 && clock - m_nLastReceivedTime > 5000) { if (nSize <= 0 && clock - m_nLastReceivedTime > 5000) {
ESP_LOGI(TAG_WIFI_HOST," ReceiveData: TimeOut Abort!"); DPRINTLN("[WIFI] Host - ReceiveData: TimeOut Abort!");
return true; return true;
} }
return false; return false;
} }
IRAM_ATTR IRAM_ATTR void CWiFiHost::SendHeartBeat() {
void CWiFiHost::SendHeartBeat() {
if (m_bHelloSent) { if (m_bHelloSent) {
hostPacket.cmd = CMD_HEARTBEAT; hostPacket.cmd = CMD_HEARTBEAT;
time_t now = time(NULL); // Get current time in seconds time_t now = time(NULL); // Get current time in seconds

View File

@ -46,97 +46,58 @@ enum OPERATION_MODE {
enum ENUM_COMMAND enum ENUM_COMMAND
{ {
// Command // Connection & control
CMD_HEARTBEAT = 1, // 1 HeartBeat - prevents disconnect from the host CMD_HEARTBEAT = 1, // 1 HeartBeat - prevents disconnect from the host
CMD_HELLO, // 0 Hello
// Connection
CMD_HELLO = 101, // 0 Hello
CMD_DROP_CONNECTION, CMD_DROP_CONNECTION,
CMD_RESET_REASON, CMD_RESET_REASON,
CMD_RESTART,
// Device Command
CMD_SAVE_RESTART = 201,
CMD_RESET_RESTART,
CMD_SEND_HISTORY, CMD_SEND_HISTORY,
CMD_PAUSE,
CMD_RESUME,
CMD_RESET_SENSOR, CMD_RESET_SENSOR,
CMD_RESET_DISPLAY, CMD_RESET_DISPLAY,
// OTA Update
CMD_UPDATE_CHECK = 301,
CMD_UPDATE_AVAILABLE,
CMD_UPDATE_FORCED,
// Config // Config
CMD_INIT_CONFIG = 1201, CMD_INIT_CONFIG,
CMD_LOAD_CONFIG, CMD_LOAD_CONFIG,
CMD_SAVE_CONFIG, CMD_SAVE_CONFIG,
CMD_SEND_CONFIG, CMD_SEND_CONFIG,
CMD_RECV_CONFIG, CMD_RECV_CONFIG,
CMD_SEND_CONFIG_SERVER, CMD_SET_DEVICE_PARAM,
CMD_LOAD_CONFIG_SERVER, CMD_GET_DEVICE_PARAM,
// control
CMD_SET_CONTROL,
CMD_GET_CONTROL,
// Set
CMD_SET_TEMP_TARGET,
CMD_SET_TEMP_TARGET_NIGHT,
CMD_SET_HUMID_TARGET,
CMD_SET_SENSOR_OFFSET,
CMD_SET_HEATER1_DUTY,
CMD_SET_MANUAL_HEATER1,
CMD_SET_HEATER2_DUTY,
CMD_SET_MANUAL_HEATER2,
CMD_SET_MIST_DUTY,
CMD_SET_MANUAL_MIST,
CMD_SET_FAN_DUTY,
CMD_SET_MANUAL_FAN,
CMD_SET_MOTOR_DUTY,
CMD_SET_MANUAL_MOTOR,
CMD_SET_LIGHT_DUTY,
CMD_SET_MANUAL_LIGHT,
CMD_SET_TIME_NIGHT,
CMD_SET_WIFI_CLIENT_DISPLAY, // Graph TempHigh, TempLow, TimeScale etc.
// PID // PID
CMD_INIT_PID_PARAM = 1301, CMD_INIT_PID_PARAM,
CMD_LOAD_PID_PARAM, CMD_LOAD_PID_PARAM,
CMD_SAVE_PID_PARAM, CMD_SAVE_PID_PARAM,
CMD_SET_PID, CMD_SET_PID,
CMD_GET_PID, CMD_GET_PID,
// Control // End of valid command
CMD_SET_CONTROL = 1401, CMD_COUNT
CMD_GET_CONTROL,
// Operation
CMD_SET_TEMP_TARGET = 1501,
CMD_SET_TEMP_TARGET_NIGHT,
CMD_SET_HUMID_TARGET,
CMD_SET_SENSOR_OFFSET,
CMD_SET_AC1_PARAM,
CMD_SET_AC2_PARAM,
CMD_SET_MIST_PARAM,
CMD_SET_FAN_PARAM,
CMD_SET_MOTOR_PARAM,
CMD_SET_LIGHT_PARAM,
// Status
CMD_SET_HEATER1_DUTY = 2101,
CMD_SET_HEATER2_DUTY,
CMD_SET_MIST_DUTY,
CMD_SET_FAN_DUTY,
CMD_SET_FAN_DUTY_AUTO,
CMD_SET_MOTOR_DUTY,
CMD_SET_MOTOR_DUTY_AUTO,
CMD_SET_LIGHT_DUTY,
// Manual Operations
CMD_SET_MANUAL_HEATER1 = 2201,
CMD_SET_MANUAL_HEATER2,
CMD_SET_MANUAL_MIST,
CMD_SET_MANUAL_FAN,
CMD_SET_MANUAL_MOTOR,
CMD_SET_MANUAL_LIGHT,
// Time
CMD_SET_TIME_HEATER1 = 2301,
CMD_SET_TIME_HEATER2,
CMD_SET_TIME_MIST,
CMD_SET_TIME_FAN,
CMD_SET_TIME_MOTOR,
CMD_SET_TIME_LIGHT,
CMD_SET_TIME_NIGHT,
// UI
CMD_SET_WIFI_CLIENT_DISPLAY = 2401, // Graph TempHigh, TempLow, TimeScale etc.
CMD_SET_OLED_CONTRAST,
CMD_SET_OLED_DISPLAY_CHECKAC,
// Debugging
CMD_HELLO_DEBUG = 9101,
CMD_SHOW_CODE,
COMPUTE_TIME_MAX,
CMD_INVALID = 9999
}; };
#pragma pack(push) /* push current alignment to stack */ #pragma pack(push) /* push current alignment to stack */
@ -157,6 +118,7 @@ typedef struct TCP_PACKET_STRUCT
int32_t n32[10]; int32_t n32[10];
uint32_t u32[10]; uint32_t u32[10];
float f[10]; float f[10];
float f16[20];
STATUS_TYPE status; STATUS_TYPE status;
DEVICE_PARAM_TYPE device; DEVICE_PARAM_TYPE device;
}; //40 : 52 }; //40 : 52
@ -250,6 +212,7 @@ private:
size_t m_nDataReceive_received; size_t m_nDataReceive_received;
bool m_bReceiveConfigPending; bool m_bReceiveConfigPending;
bool m_bSaveReceivedConfig;
bool m_bSendHistoryPending; bool m_bSendHistoryPending;
int16_t m_nPendingHistoryCount; int16_t m_nPendingHistoryCount;

27
zcd.cpp
View File

@ -26,9 +26,6 @@
#define EFFECTIVE_POWER 0.86 #define EFFECTIVE_POWER 0.86
#define LEADING_TIME_RATIO 0.06 #define LEADING_TIME_RATIO 0.06
#define PHASE_CONTROL 0
#define ZCD_CONTROL 1
// ESP32 Clock Constants // ESP32 Clock Constants
const uint32_t AC_CYCLE_TIME_CLOCKS = 8333; // Half cycle of 60Hz AC in clock cycles const uint32_t AC_CYCLE_TIME_CLOCKS = 8333; // Half cycle of 60Hz AC in clock cycles
const uint32_t EFFECTIVE_HALF_CYCLE = EFFECTIVE_POWER * AC_CYCLE_TIME_CLOCKS; // Effective half cycle in clock cycles const uint32_t EFFECTIVE_HALF_CYCLE = EFFECTIVE_POWER * AC_CYCLE_TIME_CLOCKS; // Effective half cycle in clock cycles
@ -103,7 +100,7 @@ short getHeater2Duty() {
} }
// Function to set the duty based on percentage (0 to 10000) // Function to set the duty based on percentage (0 to 10000)
void IRAM_ATTR setHeater1Duty(short duty) { MY_IRAM_ATTR void setHeater1Duty(short duty) {
if (ac1ControlMode == ZCD_CONTROL) { if (ac1ControlMode == ZCD_CONTROL) {
if (duty > 10000) duty = 10000; if (duty > 10000) duty = 10000;
dutyAC1TableIndex = (uint8_t)((duty + 10000/32)/625); dutyAC1TableIndex = (uint8_t)((duty + 10000/32)/625);
@ -130,11 +127,11 @@ void IRAM_ATTR setHeater1Duty(short duty) {
uint32_t nDuty = duty * PWM_FULL / 10000; uint32_t nDuty = duty * PWM_FULL / 10000;
ledcWrite(PIN_LED_HEATER1, PWM_FULL - nDuty); ledcWrite(PIN_LED_HEATER1, PWM_FULL - nDuty);
ESP_LOGD(TAG_ZCD,"Set Duty: %.2f%%, Timer Count: %u clock cycles", duty, dutyHeater1); //DPRINTF("[ZCD] Set Duty: %.2f%%, Timer Count: %u clock cycles", duty, dutyHeater1);
} }
// Function to set the duty based on percentage (0 to 10000) // Function to set the duty based on percentage (0 to 10000)
void IRAM_ATTR setHeater2Duty(short duty) { MY_IRAM_ATTR void setHeater2Duty(short duty) {
if (config.bAC2_OnOff) { if (config.bAC2_OnOff) {
if (duty >= 10000) { if (duty >= 10000) {
duty = 10000; duty = 10000;
@ -171,19 +168,9 @@ void IRAM_ATTR setHeater2Duty(short duty) {
uint32_t nDuty = duty * PWM_FULL / 10000; uint32_t nDuty = duty * PWM_FULL / 10000;
ledcWrite(PIN_LED_HEATER2, PWM_FULL - nDuty); ledcWrite(PIN_LED_HEATER2, PWM_FULL - nDuty);
ESP_LOGD(TAG_ZCD,"Set Duty: %.2f%%, Timer Count: %u clock cycles\n", duty, dutyHeater2); //DPRINTF("[ZCD] Set Duty: %.2f%%, Timer Count: %u clock cycles\n", duty, dutyHeater2);
} }
#define SET_TIMER_0_SAFE(duty) do { \
timerWrite(timerHeater1, 0); \
timerAlarm(timerHeater1, duty, false, 0); \
} while(0)
#define SET_TIMER_1_SAFE(duty) do { \
timerWrite(timerHeater2, 0); \
timerAlarm(timerHeater2, duty, false, 0); \
} while(0)
void IRAM_ATTR timer0ISR(void *) { void IRAM_ATTR timer0ISR(void *) {
#ifdef DEBUG_ZCD #ifdef DEBUG_ZCD
zcdLoadISRCount++; zcdLoadISRCount++;
@ -233,7 +220,7 @@ void IRAM_ATTR timer1ISR(void *)
// Zero-Cross Detection Interrupt Service Routine // Zero-Cross Detection Interrupt Service Routine
void IRAM_ATTR zcdACISR(void *) { void IRAM_ATTR zcdACISR(void *) {
// 1. Power side AC ZCD Count // 1. Power side AC ZCD Count
zcdACISRCount++; zcdACISRCount = zcdACISRCount + 1;
fireStatusTimer0 = 0; fireStatusTimer0 = 0;
fireStatusTimer1 = 0; fireStatusTimer1 = 0;
@ -267,13 +254,13 @@ void IRAM_ATTR zcdACISR(void *) {
timer_set_alarm(TIMER_GROUP_1, TIMER_1, TIMER_ALARM_EN); timer_set_alarm(TIMER_GROUP_1, TIMER_1, TIMER_ALARM_EN);
fire_enable_2 = true; fire_enable_2 = true;
} }
seqStep = ++seqStep & 0x0F; seqStep = (seqStep + 1) & 0x0F;
} }
void IRAM_ATTR zcdLoadISR(void *) { void IRAM_ATTR zcdLoadISR(void *) {
// Load side AC ZCD Count // Load side AC ZCD Count
#ifndef DEBUG_ZCD #ifndef DEBUG_ZCD
zcdLoadISRCount++; zcdLoadISRCount = zcdLoadISRCount + 1;
#endif #endif
} }

13
zcd.h
View File

@ -3,17 +3,16 @@
// ZCD // ZCD
void setupZCD(); void setupZCD();
short getHeater1Duty();
void setHeater1Duty(short duty); void setHeater1Duty(short duty);
void setHeater2Duty(short duty); void setHeater2Duty(short duty);
short getHeater1Duty();
void IRAM_ATTR zcdACISR(void *); void zcdACISR(void *);
void IRAM_ATTR zcdLoadISR(void *); void zcdLoadISR(void *);
void IRAM_ATTR timer0ISR(void *); void timer0ISR(void *);
void IRAM_ATTR timer1ISR(void *); void timer1ISR(void *);
#define DEBUG_ZCD //#define DEBUG_ZCD
#define ENABLE_TIMERS
#if defined(ESP8266) #if defined(ESP8266)
void setMistDuty(short duty); void setMistDuty(short duty);