first functional product

This commit is contained in:
Siwat Sirichai 2024-01-12 01:25:06 +07:00
parent 8c64463b46
commit e88760c299
5 changed files with 121 additions and 26 deletions

View file

@ -12,5 +12,6 @@
platform = espressif32 platform = espressif32
board = wt32-eth01 board = wt32-eth01
framework = arduino framework = arduino
lib_deps = siwats/ESPMegaProR3@^2.0.4 lib_deps = siwats/ESPMegaProR3@^2.0.7
monitor_speed = 115200 monitor_speed = 115200
;build_flags = -DCORE_DEBUG_LEVEL=5

View file

@ -15,9 +15,11 @@ void CUDDisplay::begin(std::function<rtctime_t()> getTime, DigitalInputCard *inp
auto bindedHandlePWMChange = std::bind(&CUDDisplay::handlePWMChange, this, std::placeholders::_1, std::placeholders::_2); auto bindedHandlePWMChange = std::bind(&CUDDisplay::handlePWMChange, this, std::placeholders::_1, std::placeholders::_2);
auto bindedHandleACChange = std::bind(&CUDDisplay::handleACChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto bindedHandleACChange = std::bind(&CUDDisplay::handleACChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
auto bindedHandleTouch = std::bind(&CUDDisplay::handleTouch, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3); auto bindedHandleTouch = std::bind(&CUDDisplay::handleTouch, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
auto bindedHandlePayload = std::bind(&CUDDisplay::handlePayload, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
this->outputCallbackHandle = this->outputCard->registerChangeCallback(bindedHandlePWMChange); this->outputCallbackHandle = this->outputCard->registerChangeCallback(bindedHandlePWMChange);
this->climateCallbackHandle = this->climateCard->registerChangeCallback(bindedHandleACChange); this->climateCallbackHandle = this->climateCard->registerChangeCallback(bindedHandleACChange);
this->registerTouchCallback(bindedHandleTouch); this->registerTouchCallback(bindedHandleTouch);
this->registerPayloadCallback(bindedHandlePayload);
this->reset(); this->reset();
delay(1000); delay(1000);
this->jumpToPage(1); this->jumpToPage(1);
@ -91,7 +93,7 @@ void CUDDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t event)
if (!ac_control_enabled) break; if (!ac_control_enabled) break;
if (event != TOUCH_TYPE_RELEASE) if (event != TOUCH_TYPE_RELEASE)
break; break;
this->climateCard->setFanSpeed(1); this->climateCard->setFanSpeed(3);
break; break;
case COMPONENT_AC_FAN_MODE_MEDIUM_BUTTON: case COMPONENT_AC_FAN_MODE_MEDIUM_BUTTON:
if (!ac_control_enabled) break; if (!ac_control_enabled) break;
@ -103,7 +105,7 @@ void CUDDisplay::handleTouch(uint8_t page, uint8_t component, uint8_t event)
if (!ac_control_enabled) break; if (!ac_control_enabled) break;
if (event != TOUCH_TYPE_RELEASE) if (event != TOUCH_TYPE_RELEASE)
break; break;
this->climateCard->setFanSpeed(3); this->climateCard->setFanSpeed(1);
break; break;
default: default:
break; break;
@ -165,7 +167,7 @@ bool CUDDisplay::calculateFanGroupState() {
// Check if all fans are on // Check if all fans are on
bool fanOn = false; bool fanOn = false;
for (uint8_t i = 4; i < 7; i++) { for (uint8_t i = 4; i < 7; i++) {
if (this->outputCard->getState(i) == 0) { if (this->outputCard->getState(i)) {
fanOn = true; fanOn = true;
break; break;
} }
@ -243,13 +245,13 @@ void CUDDisplay::updateACState() {
this->displayAdapter->print(fan_speed == 0 ? COMPONENT_AC_FAN_MODE_AUTO_PIC_ACTIVE : COMPONENT_AC_FAN_MODE_AUTO_PIC_INACTIVE); this->displayAdapter->print(fan_speed == 0 ? COMPONENT_AC_FAN_MODE_AUTO_PIC_ACTIVE : COMPONENT_AC_FAN_MODE_AUTO_PIC_INACTIVE);
this->sendStopBytes(); this->sendStopBytes();
this->displayAdapter->print("fan_1_btn.pic="); this->displayAdapter->print("fan_1_btn.pic=");
this->displayAdapter->print(fan_speed == 1 ? COMPONENT_AC_FAN_MODE_HIGH_PIC_ACTIVE : COMPONENT_AC_FAN_MODE_HIGH_PIC_INACTIVE); this->displayAdapter->print(fan_speed == 3 ? COMPONENT_AC_FAN_MODE_HIGH_PIC_ACTIVE : COMPONENT_AC_FAN_MODE_HIGH_PIC_INACTIVE);
this->sendStopBytes(); this->sendStopBytes();
this->displayAdapter->print("fan_2_btn.pic="); this->displayAdapter->print("fan_2_btn.pic=");
this->displayAdapter->print(fan_speed == 2 ? COMPONENT_AC_FAN_MODE_MEDIUM_PIC_ACTIVE : COMPONENT_AC_FAN_MODE_MEDIUM_PIC_INACTIVE); this->displayAdapter->print(fan_speed == 2 ? COMPONENT_AC_FAN_MODE_MEDIUM_PIC_ACTIVE : COMPONENT_AC_FAN_MODE_MEDIUM_PIC_INACTIVE);
this->sendStopBytes(); this->sendStopBytes();
this->displayAdapter->print("fan_3_btn.pic="); this->displayAdapter->print("fan_3_btn.pic=");
this->displayAdapter->print(fan_speed == 3 ? COMPONENT_AC_FAN_MODE_LOW_PIC_ACTIVE : COMPONENT_AC_FAN_MODE_LOW_PIC_INACTIVE); this->displayAdapter->print(fan_speed == 1 ? COMPONENT_AC_FAN_MODE_LOW_PIC_ACTIVE : COMPONENT_AC_FAN_MODE_LOW_PIC_INACTIVE);
this->sendStopBytes(); this->sendStopBytes();
this->displayAdapter->print("temp_txt.txt=\""); this->displayAdapter->print("temp_txt.txt=\"");
this->displayAdapter->print(temperature); this->displayAdapter->print(temperature);
@ -265,4 +267,9 @@ void CUDDisplay::setACControlEnabled(bool enabled) {
} }
bool CUDDisplay::getACControlEnabled() { bool CUDDisplay::getACControlEnabled() {
return ac_control_enabled; return ac_control_enabled;
}
void CUDDisplay::handlePayload(uint8_t payload_type, uint8_t *payload, uint8_t length)
{
} }

View file

@ -47,14 +47,14 @@ Pin Mapping
#define COMPONENT_AC_FAN_MODE_AUTO_PIC_ACTIVE 20 #define COMPONENT_AC_FAN_MODE_AUTO_PIC_ACTIVE 20
#define COMPONENT_AC_FAN_MODE_AUTO_PIC_INACTIVE 19 #define COMPONENT_AC_FAN_MODE_AUTO_PIC_INACTIVE 19
#define COMPONENT_AC_FAN_MODE_LOW_BUTTON 8 #define COMPONENT_AC_FAN_MODE_LOW_BUTTON 8
#define COMPONENT_AC_FAN_MODE_LOW_PIC_ACTIVE 22 #define COMPONENT_AC_FAN_MODE_LOW_PIC_ACTIVE 26
#define COMPONENT_AC_FAN_MODE_LOW_PIC_INACTIVE 21 #define COMPONENT_AC_FAN_MODE_LOW_PIC_INACTIVE 25
#define COMPONENT_AC_FAN_MODE_MEDIUM_BUTTON 9 #define COMPONENT_AC_FAN_MODE_MEDIUM_BUTTON 9
#define COMPONENT_AC_FAN_MODE_MEDIUM_PIC_ACTIVE 24 #define COMPONENT_AC_FAN_MODE_MEDIUM_PIC_ACTIVE 24
#define COMPONENT_AC_FAN_MODE_MEDIUM_PIC_INACTIVE 23 #define COMPONENT_AC_FAN_MODE_MEDIUM_PIC_INACTIVE 23
#define COMPONENT_AC_FAN_MODE_HIGH_BUTTON 10 #define COMPONENT_AC_FAN_MODE_HIGH_BUTTON 10
#define COMPONENT_AC_FAN_MODE_HIGH_PIC_ACTIVE 26 #define COMPONENT_AC_FAN_MODE_HIGH_PIC_ACTIVE 22
#define COMPONENT_AC_FAN_MODE_HIGH_PIC_INACTIVE 25 #define COMPONENT_AC_FAN_MODE_HIGH_PIC_INACTIVE 21
#define COMPONENT_BACKGROUND_AC_LOCK 2 #define COMPONENT_BACKGROUND_AC_LOCK 2
#define COMPONENT_BACKGROUND_AC_UNLOCK 1 #define COMPONENT_BACKGROUND_AC_UNLOCK 1
@ -71,6 +71,7 @@ class CUDDisplay : public ESPMegaDisplay {
void handleTouch(uint8_t page, uint8_t component, uint8_t event); void handleTouch(uint8_t page, uint8_t component, uint8_t event);
void handlePWMChange(uint8_t pin, uint8_t value); void handlePWMChange(uint8_t pin, uint8_t value);
void handleACChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature); void handleACChange(uint8_t mode, uint8_t fan_speed, uint8_t temperature);
void handlePayload(uint8_t payload_type, uint8_t* payload, uint8_t length);
void sendClock(); void sendClock();
void setACControlEnabled(bool enabled); void setACControlEnabled(bool enabled);
bool getACControlEnabled(); bool getACControlEnabled();

View file

@ -2,8 +2,8 @@
#include <cud_display.hpp> #include <cud_display.hpp>
/*********************************************** /***********************************************
* Begin Configuration * * Begin Configuration *
************************************************/ ************************************************/
// Display Configuration // Display Configuration
#define cudDisplayAdapter Serial2 #define cudDisplayAdapter Serial2
@ -11,7 +11,10 @@
#define CUD_DISPLAY_TX_PIN 4 #define CUD_DISPLAY_TX_PIN 4
#define CUD_DISPLAY_RX_PIN 17 #define CUD_DISPLAY_RX_PIN 17
//Air Conditioner Configuration // Air Conditioner Configuration
#define AIR_CONDITIONER_LOCK_FRAM_ADDRESS 4900
#define AIR_CONDITIONER_LOCK_RELATIVE_TOPIC "ac_lock"
#define AIR_CONDITIONER_LOCK_SET_RELATIVE_TOPIC "ac_lock/set"
#define AIR_CONDITIONER_SENSOR_TYPE AC_SENSOR_TYPE_DHT22 #define AIR_CONDITIONER_SENSOR_TYPE AC_SENSOR_TYPE_DHT22
#define AIR_CONDITIONER_SENSOR_PIN 32 #define AIR_CONDITIONER_SENSOR_PIN 32
#define AIR_CONDITIONER_IR_PIN 5 #define AIR_CONDITIONER_IR_PIN 5
@ -27,8 +30,7 @@ AirConditioner ac = {
.mode_names = mode_names, .mode_names = mode_names,
.fan_speeds = 4, .fan_speeds = 4,
.fan_speed_names = fan_speed_names, .fan_speed_names = fan_speed_names,
.getInfraredCode = &getInfraredCode .getInfraredCode = &getInfraredCode};
};
/*********************************************** /***********************************************
* End Configuration * * End Configuration *
@ -37,42 +39,119 @@ AirConditioner ac = {
ESPMegaPRO espmega = ESPMegaPRO(); ESPMegaPRO espmega = ESPMegaPRO();
CUDDisplay cudDisplay = CUDDisplay(&cudDisplayAdapter); CUDDisplay cudDisplay = CUDDisplay(&cudDisplayAdapter);
ClimateCard climateCard = ClimateCard(AIR_CONDITIONER_IR_PIN, ac, ClimateCard climateCard = ClimateCard(AIR_CONDITIONER_IR_PIN, ac,
AIR_CONDITIONER_SENSOR_TYPE, AIR_CONDITIONER_SENSOR_PIN, AIR_CONDITIONER_SENSOR_TYPE, AIR_CONDITIONER_SENSOR_PIN,
AIR_CONDITIONER_RMT_CHANNEL); AIR_CONDITIONER_RMT_CHANNEL);
void setup() { void handleMqttMessage(char *topic, char *payload)
{
Serial.printf("MQTT Message: %s %s\n", topic, payload);
if (!strcmp(topic, AIR_CONDITIONER_LOCK_SET_RELATIVE_TOPIC))
{
if (!strcmp(payload, "lock"))
{
lockAC();
espmega.iot->publishRelative(AIR_CONDITIONER_LOCK_RELATIVE_TOPIC, "lock");
}
else if (!strcmp(payload, "unlock"))
{
unlockAC();
espmega.iot->publishRelative(AIR_CONDITIONER_LOCK_RELATIVE_TOPIC, "unlock");
}
}
}
void lockAC()
{
espmega.fram.write8(AIR_CONDITIONER_LOCK_FRAM_ADDRESS, 0);
cudDisplay.setACControlEnabled(false);
}
void unlockAC()
{
espmega.fram.write8(AIR_CONDITIONER_LOCK_FRAM_ADDRESS, 1);
cudDisplay.setACControlEnabled(true);
}
void sendStopBytes()
{
Serial.write(0xFF);
Serial.write(0xFF);
Serial.write(0xFF);
}
void sendExtStopBytes()
{
cudDisplayAdapter.write(0xFF);
cudDisplayAdapter.write(0xFF);
cudDisplayAdapter.write(0xFF);
}
void setup()
{
Serial.begin(115200);
cudDisplayAdapter.begin(CUD_DISPLAY_BAUD_RATE, SERIAL_8N1, CUD_DISPLAY_RX_PIN, CUD_DISPLAY_TX_PIN);
sendExtStopBytes();
cudDisplayAdapter.print("rest");
sendExtStopBytes();
sendStopBytes();
Serial.print("rest");
sendStopBytes();
Serial.print("boot_state.txt=\"Core Initializing . . .\"");
sendStopBytes();
espmega.begin(); espmega.begin();
Serial.print("boot_state.txt=\"IoT Initializing . . .\"");
sendStopBytes();
espmega.enableIotModule(); espmega.enableIotModule();
ETH.begin(); ETH.begin();
espmega.iot->bindEthernetInterface(&ETH); espmega.iot->bindEthernetInterface(&ETH);
Serial.print("boot_state.txt=\"Network Initializing . . .\"");
sendStopBytes();
espmega.iot->loadNetworkConfig(); espmega.iot->loadNetworkConfig();
espmega.iot->connectNetwork(); espmega.iot->connectNetwork();
Serial.print("boot_state.txt=\"MQTT Initializing . . .\"");
sendStopBytes();
espmega.iot->loadMqttConfig(); espmega.iot->loadMqttConfig();
espmega.iot->connectToMqtt(); espmega.iot->connectToMqtt();
Serial.print("boot_state.txt=\"Display Initializing . . .\"");
espmega.enableInternalDisplay(&Serial); espmega.enableInternalDisplay(&Serial);
espmega.enableWebServer(80); espmega.enableWebServer(80);
espmega.inputs.registerCallback(on_pin_change); espmega.inputs.registerCallback(on_pin_change);
espmega.outputs.setAutoSaveToFRAM(true); espmega.outputs.setAutoSaveToFRAM(true);
espmega.installCard(3, &climateCard); espmega.installCard(2, &climateCard);
climateCard.bindFRAM(&espmega.fram, 5000); climateCard.bindFRAM(&espmega.fram, 5000);
climateCard.loadStateFromFRAM(); climateCard.loadStateFromFRAM();
climateCard.setFRAMAutoSave(true); climateCard.setFRAMAutoSave(true);
espmega.display->bindClimateCard(&climateCard); espmega.display->bindClimateCard(&climateCard);
espmega.iot->registerCard(3); espmega.iot->registerCard(0); // Register the Input Card
cudDisplayAdapter.begin(CUD_DISPLAY_BAUD_RATE, SERIAL_8N1, CUD_DISPLAY_RX_PIN, CUD_DISPLAY_TX_PIN); espmega.iot->registerCard(1); // Register the Output Card
espmega.iot->registerCard(2); // Register the Climate Card
auto bindedGetTime = std::bind(&ESPMegaPRO::getTime, &espmega); auto bindedGetTime = std::bind(&ESPMegaPRO::getTime, &espmega);
cudDisplay.begin(bindedGetTime, &espmega.inputs, &espmega.outputs, &climateCard); cudDisplay.begin(bindedGetTime, &espmega.inputs, &espmega.outputs, &climateCard);
if (espmega.fram.read8(AIR_CONDITIONER_LOCK_FRAM_ADDRESS))
{
lockAC();
}
else
{
// AC is unlocked
unlockAC();
}
espmega.iot->subscribeRelative(AIR_CONDITIONER_LOCK_SET_RELATIVE_TOPIC);
espmega.iot->registerRelativeMqttCallback(&handleMqttMessage);
} }
void loop() { void loop()
{
espmega.loop(); espmega.loop();
cudDisplay.loop(); cudDisplay.loop();
} }
void on_pin_change(uint8_t pin, uint8_t value) { void on_pin_change(uint8_t pin, uint8_t value)
{
// For pin 0-6, when the pin value changes, toggle the corresponding PWM pin // For pin 0-6, when the pin value changes, toggle the corresponding PWM pin
if (pin < 7) { if (pin < 7)
{
bool new_value = !espmega.outputs.getState(pin); bool new_value = !espmega.outputs.getState(pin);
espmega.outputs.digitalWrite(pin, new_value); espmega.outputs.digitalWrite(pin, new_value);
} }

View file

@ -3,6 +3,13 @@
#include <cud_display.hpp> #include <cud_display.hpp>
#include <ir_codes.hpp> #include <ir_codes.hpp>
void handleMqttMessage(char *topic, char *payload);
void lockAC();
void unlockAC();
void sendStopBytes();
void sendExtStopBytes();
void setup(); void setup();
void loop(); void loop();