버튼입력을 통한 컨트롤 및 MQTT를 이용한 통신을 서버에 전송 하고자 한다.
그리고 유지 보수를 위해 펌웨어를 OTA로 업데이트 할 수 있도록 하고자 한다.
1. 펌웨어의 목적 정의
스위치를 통해 하고자 하는 목적을 먼저 정의를 해야합니다.
제가 원하는 목적들을 정의를 하자면 아래와 같습니다.
1. 버튼으로 스위치 컨트롤
1-1. 어떠한 경우에도 최우선적으로 작동
1-2. 버튼 작동했을때 상태를 서버로 전송
2. MQTT 구독, 발행
3. 웹 컨트롤 기능
3-1. OTA 기능
3-2. 테스트 컨트롤 및 상태값 확인
2. 목적 별 필요 기능
1번. 핀&릴레이 컨트롤 및 인터럽트
버튼 입력을 통해 컨트롤 하고자 하면 핀 & 릴레이 컨트롤이 필요합니다.
핀 : 버튼을 눌렀을때 해당 신호를 esp칩셋에 전송할때 사용되는 입력 포트
릴레이 : 전력 차단, 차단 해제를 맡은 스위치 부품
인터럽트를 통해 입력이 들어올시 지정된 기능이 최우선적으로 작동합니다.
인터럽트 : 이 기능을 지원하는 핀을 인터럽트 핀 으로 지정 시, 이 핀으로 들어오는 신호가 존재 할 경우 하던 일 모두 멈추고 해당 일을 바로 실행하도록 하는 기능
2번. MQTT 기능
MQTT를 통해 구독, 발행이 모두 가능해야합니다.
구독을 통해 서버로부터 오는 상태값 확인 요청, 원격 제어 데이터를 수신합니다.
발행을 통해 서버로 상태값 리턴, 원격 제어 결과 리턴을 할 수 있습니다.
3번. 웹 기능
웹 기능은 두가지 기능으로 필요합니다.
펌웨어 OTA 로 업데이트
상태값 체크 및 테스트 제어 시스템입니다.
그러면 코드는 어떻게 할지 이번엔 하나씩 보겠습니다.
3. 코드 살펴보기
1번. 버튼 이벤트 및 인터럽트 세팅
ICACHE_RAM_ATTR void getButton(void) {
// short press butoon to change state of relay
if (digitalRead(BUTTONPIN) == false ) {
++ButtonCount;
}
if (digitalRead(BUTTONPIN) == false && ButtonCount > 1 && ButtonCount < 12 ) {
setRelay(!RelayState); // change relay
if(RelayState==true){
client.publish(mqtt_topic,"{\"sender\":\"self\",\"message\":\"On\",\"room\":\"test\"}");
}
else{
client.publish(mqtt_topic,"{\"sender\":\"self\",\"message\":\"Off\",\"room\":\"test\"}");
}
ButtonCount = 0;
delay(500);
}
/* long press button restart */
if (ButtonCount > 12) {
setLED(!LEDState);
buttonTick.detach(); // Stop Tickers
/* Wait for release button */
while (!digitalRead(BUTTONPIN)) yield();
delay(100);
ESP.restart();
}
if (digitalRead(BUTTONPIN) == true) ButtonCount = 0;
ButtonFlag = false;
}
하나씩 보겠습니다.
ICACHE_RAM_ATTR
인터럽트가 발생했을때 실행할 함수 앞에 붙여줘야 합니다.
플래시에 있던 함수를 램으로 이동하는 역할이라고 합니다.
digitalRead(BUTTONPIN)
BUTTONPIN에 해당하는 핀의 값을 읽어 옵니다.
※ BUTTONPIN은 int형 변수입니다. 전체 코드에서 보시면 이해가 됩니다.
false일 경우 작동안함(off), true 일 경우 작동 상태(on)입니다.
ButtonCount
몇번 눌러졌나를 확인합니다. 이는 나중에 길게 눌렀을 경우 재시작을 하기 위해 12번 눌러졌을때까지( = 길게 누름) 카운터를 합니다.
setRelay(!RelaySta)
릴레이(스위치)를 현재 상태와 반대로 설정합니다.
client.publish
mqtt 관련 함수 입니다. topic, message를 파라미터로 가집니다.
attachInterrupt(BUTTONPIN, getButton, FALLING);
setup 함수내에 존재하는 인터럽트 선언입니다.
파라미터로 인터럽트로 사용할 핀번호, 콜백함수, 발동 조건 (FALLING : on->off 즉 버튼을 땔때. RISING, CHANGE 도 있습니다.)를 가집니다.
2번. MQTT
void mqtt_publish(char* message,const char* sender){
if(!client.connected()){
Serial.println("Mqtt reconnect");
reconnect();
}
client.loop();
char output[256];
StaticJsonDocument<256> doc;
doc["sender"] = sender;
doc["message"] = message;
doc["room"] = mqtt_id;
serializeJson(doc, output);
client.publish(mqtt_topic, output);
Serial.println("Mqtt Send");
delay(100);
}
void callback(char* topic, byte* payload, unsigned int length) {
String Msg = "";
int i=0;
Serial.println("Mqtt Message Arrived here");
while (i<length) Msg += (char)payload[i++];
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, Msg.c_str(), length);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
char error_put[64];
StaticJsonDocument<64> doc;
doc["sender"] = "self";
doc["message"] = error.c_str();
doc["room"] = mqtt_id;
client.publish(mqtt_topic, error_put);
return;
}
const char* sender = doc["Light"]["sender"];
const char* message = doc["Light"]["message"];
const char* destination = doc["Light"]["destination"];
String message_str = message;
String destination_str = destination;
if(message_str.equals("ON")){
if(RelayState == true){
mqtt_publish("already On", sender);
}
else{
setRelay(!RelayState);
mqtt_publish("On", sender);
}
}
else if(message_str.equals("STATE")){
if(RelayState == true){
mqtt_publish("On", sender);
}
else{
mqtt_publish("Off", sender);
}
}
else{
if(message_str.equals("OFF")){
if(RelayState == true){
setRelay(!RelayState);
mqtt_publish("Off", sender);
}
else{
mqtt_publish("already Off", sender);
}
}
}
}
void reconnect() {
if(client.connected()){
Serial.println("Already connected on mqtt server");
client.publish(mqtt_topic_con, "test button is already conneted on mqtt server");
}
else{
// Loop until we're reconnected
Serial.println("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(mqtt_id)) { //change to ClientID
Serial.println("connected");
// ... and resubscribe
client.subscribe(mqtt_topic_sub);
// Once connected, publish an announcement...
client.publish(mqtt_topic_con, "{\"sender\":\"self\",\"message\":\"reconneted\",\"room\":\"test\"}");
} else {
Serial.print("failed, rc=");
Serial.println(client.state());
}
}
}
mqtt_publish()
mqtt 발행하는 함수 입니다.
연결 상태 체크 후 원하는 메세지를 json 타입으로 직렬화 이후 발행합니다.
callback()
mqtt 구독하는 함수 입니다.
연결되어 있는 mqtt서버로 부터 구독 중인 곳으로 메세지가 올 경우 처리 합니다.
reconnect()
mqtt 재연결하는 함수입니다.
client.setServer(mqtt_server,mqtt_port);
client.setCallback(callback);
reconnect();
setup 함수 내에서 mqtt 연결 코드입니다.
3번. 웹 기능
/*
* printMAC
* Print the device MAC address to the serial port.
*/
void printMAC(void) {
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC: ");
Serial.print(mac[0],HEX);
Serial.print(":");
Serial.print(mac[1],HEX);
Serial.print(":");
Serial.print(mac[2],HEX);
Serial.print(":");
Serial.print(mac[3],HEX);
Serial.print(":");
Serial.print(mac[4],HEX);
Serial.print(":");
Serial.println(mac[5],HEX);
}
/*
* handleNotFound
* Return a 404 error on not found page.
*/
void handleNotFound() {
server.send(404, "text/plain", "404: Not found");
}
/*
* handleMainPage - GET
* Return Text for main page on GET
*/
void handleGET() {
//Quick LED Flash
//setLED(!LEDState);
//Serve Page
Serial.println("Serviced Page Request");
String buff;
buff = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
buff += "<html><head>\n";
buff += "<style type=\"text/css\">\n";
buff += "html {font-family: sans-serif;background:#f0f5f5}\n";
buff += ".submit {width: 10%; height:5vw; font-size: 100%; font-weight: bold; border-radius: 4vw;}\n";
buff += "@media (max-width: 1281px) {\n";
buff += "html {font-size: 3vw; font-family: sans-serif;background:#f0f5f5}\n";
buff += ".submit {width: 40%; height:20vw; font-size: 100%; font-weight: bold; border-radius: 15vw;}}\n";
buff += "</style>\n";
buff += "<meta content=\"text/html; charset=utf-8\">\n";
buff += "<title>Mcity - Wifi Power Switch</title></head><body>\n";
buff += "</pre>\n";
buff += "Wifi-enabled IIoT Power Switch\n";
buff += "<form action=\"/device\" method=\"POST\">\n";
buff += "<h2>Device ID: " + String(ESP.getChipId()) + "</h2>\n";
buff += "<h2>Device topic: " + String(mqtt_topic_sub) + "</h2>\n";
buff += "<h2>Relay State: ";
if (RelayState) {
buff += "ON</h2>\n";
} else {
buff += "OFF</h2>\n";
}
buff += "<input type=\"hidden\" name=\"return\" value=\"TRUE\">";
buff += "<input type=\"submit\" name=\"state\" class=\"submit\" value=\"ON\" style=\"" + OnButt + "\">\n";
buff += "<input type=\"submit\" name=\"state\" class=\"submit\" value=\"OFF\" style=\"" + OffButt + "\">\n";
buff += "<input type=\"submit\" name=\"state\" class=\"submit\" value=\"SEND\" style=\"" + SendButt + "\">\n";
buff += "</form></body></html>\n";
server.send(200, "text/html", buff);
//Quick LED Flash
delay(20);
//setLED(!LEDState);
}
void RelayStateGET(){
String buff;
if (RelayState) {
buff = "ON\n";
mqtt_publish("test On message","test");
} else {
buff = "OFF\n";
mqtt_publish("test Off message","test");
}
server.send(50, "text/html", buff);
}
/*
* handleStatePOST
* Modify state on POST
*/
void handleStatePOST() {
/* request for www user/password from client */
if (!server.authenticate(WWWUSERNAME, WWWPASSWORD))
return server.requestAuthentication();
if (server.arg("state") == "ON") setRelay(true);
if (server.arg("state") == "OFF") setRelay(false);
//Redirect to home page is user requests it.
if (server.arg("return") == "TRUE") handleGET();
else handleStateGET();
}
/*
* handleStateGET
* Print state on GET
*/
void handleStateGET() {
//Serve Page
Serial.println("Serviced API Request");
//Print Relay state
String buff;
if (RelayState) {
buff = "ON\n";
mqtt_publish("test On message","test");
} else {
buff = "OFF\n";
mqtt_publish("test Off message","test");
}
server.send(200, "text/html", buff);
//Quick LED Flash
delay(20);
//setLED(!LEDState);
}
/*
* setRelay
* Sets the state of the Relay
*/
void setRelay(bool SetRelayState) {
//Switch the HTML for the display page
if (SetRelayState == true) {
OnButt = BUTTONON;
OffButt = BUTTONNOACT;
}
if (SetRelayState == false) {
OnButt = BUTTONNOACT;
OffButt = BUTTONOFF;
}
//Set the relay state
RelayState = SetRelayState;
digitalWrite(RELAYPIN, RelayState);
//Set the LED to opposite of the button.
//setLED(!SetRelayState);
}
상태값 체크 및 테스트 제어 시스템입니다. 여기는 저도 외부 코드를 참조한 부분이라 원본 코드 링크를 남겨두겠습니다.
https://github.com/mcity/sonoff-wifi-iot-switch/blob/master/mcity-sonoff.ino
통합 코드
#include <Ticker.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266HTTPUpdateServer.h>
#include <PubSubClient.h>
#include <SimpleTimer.h>
#include <ArduinoJson.h>
#define APSSID "WIFI NAME" //AP SSID
#define APPASSWORD "WIFI PASSWORD" //AP password
#define SERVERPORT 80 //Web server port
#define WWWUSERNAME "admin" // Set www user name
#define WWWPASSWORD "admin" // Set www user password
#define OTAUSER "OTAadmin" // Set OTA user
#define OTAPASSWORD "OTApassword" // Set OTA password
#define OTAPATH "/firmware"// Set path for update
#define RELAYPIN 15 // GPIO12 relay pin -> GPIO15
#define LEDPIN 16 // GPIO13 GREEN LED (active low)-> GPIO16 change to wifi connect
#define BUTTONPIN 5 // GPIO0 button pin -> GPIO5
#define CLICKPIN 0 //test button
#define BUTTONTIME 0.05 // [s] time between button read
#define BUTTONON "color: green; border: 3px #fff outset;"
#define BUTTONOFF "color: red; border: 3px #fff outset;"
#define BUTTONNOACT "color: black; border: 7px #fff outset;"
#define BUTTONDEBOUNCE 1 //Minimum number of seconds between a valid button press or relay switch.
#define mqtt_server "192.168.0.1"
#define mqtt_port 1883
#define mqtt_id "test"
#define mqtt_topic "MyHome/Light/test"
#define mqtt_topic_sta "MyHome/Light/Sub/Server/State"
#define mqtt_topic_con "MyHome/Light/Sub/Server/Connect"
#define mqtt_topic_sub "MyHome/Light/Pub/test"
bool LEDState = true; // Green LED off
bool RelayState = false; // Relay off
bool ButtonFlag = false; // Does the button need to be handled on this loop
char ButtonCount = 0; // How many cycles/checks the button has been pressed for.
String OnButt;
String OffButt;
String SendButt;
//Setup classes needed from libraries.
MDNSResponder mdns;
Ticker buttonTick;
Ticker tickerConnect;
ESP8266WebServer server(SERVERPORT);
ESP8266HTTPUpdateServer httpUpdater;
//mqttclient
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
SimpleTimer timerCnt;
volatile bool blinkOn;
volatile unsigned long nextMil;
void setup(void){
// Init
pinMode(BUTTONPIN, INPUT);
pinMode(LEDPIN, OUTPUT);
pinMode(RELAYPIN, OUTPUT);
pinMode(CLICKPIN, INPUT_PULLUP);
attachInterrupt(BUTTONPIN, getButton, FALLING);
Serial.begin(115200);
delay(5000);
//Start wifi connection
Serial.println("Connecting to wifi..");
WiFi.begin(APSSID, APPASSWORD);
//Print MAC to serial so we can use the address for auth if needed.
printMAC();
// Wait for connection - Slow flash
Serial.print("Waiting on Connection ...");
while (WiFi.status() != WL_CONNECTED) {
digitalWrite(LEDPIN, LOW);
delay(500);
Serial.print(".");
//Serial.println(WiFi.status());
digitalWrite(LEDPIN, HIGH);
delay(500);
}
setLED(false);
//Print startup status and network information
Serial.println("");
Serial.print("Connected to: ");
Serial.println(APSSID);
Serial.print("IP: ");
Serial.println(WiFi.localIP());
Serial.print("Gateway: ");
Serial.println(WiFi.gatewayIP());
Serial.print("Subnet: ");
Serial.println(WiFi.subnetMask());
Serial.print("Device ID: ");
Serial.println(ESP.getChipId());
if (mdns.begin("esp8266", WiFi.localIP())) {
Serial.println("MDNS: Responder Started");
}
//Setup HTTP Server Endpoints
server.on("/", HTTP_GET, handleGET);
server.on("/device", HTTP_POST, handleStatePOST);
server.on("/device", HTTP_GET, handleStateGET);
server.on("/state",HTTP_GET,RelayStateGET);
server.on("/change",HTTP_GET,RelayChange);
server.onNotFound(handleNotFound);
httpUpdater.setup(&server, OTAPATH, OTAUSER, OTAPASSWORD); //OTA Update endpoint
//Start the web server
server.begin();
client.setServer(mqtt_server,mqtt_port);
client.setCallback(callback);
reconnect();
//Start up blink of LED signaling everything is ready. Fast Flash
for (int i = 0; i < 10; i++) {
setLED(!LEDState);
delay(100);
}
Serial.println("Server is up.");
//Enable periodic watcher for button event handling
buttonTick.attach(BUTTONTIME, buttonFlagSet);
}
//mqtt
void mqtt_publish(char* message,const char* sender){
if(!client.connected()){
Serial.println("Mqtt reconnect");
reconnect();
}
client.loop();
char output[256];
StaticJsonDocument<256> doc;
doc["sender"] = sender;
doc["message"] = message;
doc["room"] = mqtt_id;
serializeJson(doc, output);
client.publish(mqtt_topic, output);
Serial.println("Mqtt Send");
delay(100);
}
void callback(char* topic, byte* payload, unsigned int length) {
String Msg = "";
int i=0;
Serial.println("Mqtt Message Arrived here");
while (i<length) Msg += (char)payload[i++];
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, Msg.c_str(), length);
if (error) {
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
char error_put[64];
StaticJsonDocument<64> doc;
doc["sender"] = "self";
doc["message"] = error.c_str();
doc["room"] = mqtt_id;
client.publish(mqtt_topic, error_put);
return;
}
const char* sender = doc["Light"]["sender"];
const char* message = doc["Light"]["message"];
const char* destination = doc["Light"]["destination"];
String message_str = message;
String destination_str = destination;
if(message_str.equals("ON")){
if(RelayState == true){
mqtt_publish("already On", sender);
}
else{
setRelay(!RelayState);
mqtt_publish("On", sender);
}
}
else if(message_str.equals("STATE")){
if(RelayState == true){
mqtt_publish("On", sender);
}
else{
mqtt_publish("Off", sender);
}
}
else{
if(message_str.equals("OFF")){
if(RelayState == true){
setRelay(!RelayState);
mqtt_publish("Off", sender);
}
else{
mqtt_publish("already Off", sender);
}
}
}
}
void reconnect() {
if(client.connected()){
Serial.println("Already connected on mqtt server");
client.publish(mqtt_topic_con, "test button is already conneted on mqtt server");
}
else{
// Loop until we're reconnected
Serial.println("Attempting MQTT connection...");
// Attempt to connect
if (client.connect(mqtt_id)) { //change to ClientID
Serial.println("connected");
// ... and resubscribe
client.subscribe(mqtt_topic_sub);
// Once connected, publish an announcement...
client.publish(mqtt_topic_con, "{\"sender\":\"self\",\"message\":\"reconneted\",\"room\":\"test\"}");
} else {
Serial.print("failed, rc=");
Serial.println(client.state());
}
}
}
/*
* printMAC
* Print the device MAC address to the serial port.
*/
void printMAC(void) {
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC: ");
Serial.print(mac[0],HEX);
Serial.print(":");
Serial.print(mac[1],HEX);
Serial.print(":");
Serial.print(mac[2],HEX);
Serial.print(":");
Serial.print(mac[3],HEX);
Serial.print(":");
Serial.print(mac[4],HEX);
Serial.print(":");
Serial.println(mac[5],HEX);
}
/*
* handleNotFound
* Return a 404 error on not found page.
*/
void handleNotFound() {
server.send(404, "text/plain", "404: Not found");
}
/*
* handleMainPage - GET
* Return Text for main page on GET
*/
void handleGET() {
//Quick LED Flash
//setLED(!LEDState);
//Serve Page
Serial.println("Serviced Page Request");
String buff;
buff = "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\n";
buff += "<html><head>\n";
buff += "<style type=\"text/css\">\n";
buff += "html {font-family: sans-serif;background:#f0f5f5}\n";
buff += ".submit {width: 10%; height:5vw; font-size: 100%; font-weight: bold; border-radius: 4vw;}\n";
buff += "@media (max-width: 1281px) {\n";
buff += "html {font-size: 3vw; font-family: sans-serif;background:#f0f5f5}\n";
buff += ".submit {width: 40%; height:20vw; font-size: 100%; font-weight: bold; border-radius: 15vw;}}\n";
buff += "</style>\n";
buff += "<meta content=\"text/html; charset=utf-8\">\n";
buff += "<title>Mcity - Wifi Power Switch</title></head><body>\n";
buff += "</pre>\n";
buff += "Wifi-enabled IIoT Power Switch\n";
buff += "<form action=\"/device\" method=\"POST\">\n";
buff += "<h2>Device ID: " + String(ESP.getChipId()) + "</h2>\n";
buff += "<h2>Device topic: " + String(mqtt_topic_sub) + "</h2>\n";
buff += "<h2>Relay State: ";
if (RelayState) {
buff += "ON</h2>\n";
} else {
buff += "OFF</h2>\n";
}
buff += "<input type=\"hidden\" name=\"return\" value=\"TRUE\">";
buff += "<input type=\"submit\" name=\"state\" class=\"submit\" value=\"ON\" style=\"" + OnButt + "\">\n";
buff += "<input type=\"submit\" name=\"state\" class=\"submit\" value=\"OFF\" style=\"" + OffButt + "\">\n";
buff += "<input type=\"submit\" name=\"state\" class=\"submit\" value=\"SEND\" style=\"" + SendButt + "\">\n";
buff += "</form></body></html>\n";
server.send(200, "text/html", buff);
//Quick LED Flash
delay(20);
//setLED(!LEDState);
}
void RelayStateGET(){
String buff;
if (RelayState) {
buff = "ON\n";
mqtt_publish("test On message","test");
} else {
buff = "OFF\n";
mqtt_publish("test Off message","test");
}
server.send(50, "text/html", buff);
}
void RelayChange(){
setRelay(!RelayState);
RelayStateGET();
}
/*
* handleStatePOST
* Modify state on POST
*/
void handleStatePOST() {
/* request for www user/password from client */
if (!server.authenticate(WWWUSERNAME, WWWPASSWORD))
return server.requestAuthentication();
if (server.arg("state") == "ON") setRelay(true);
if (server.arg("state") == "OFF") setRelay(false);
//Redirect to home page is user requests it.
if (server.arg("return") == "TRUE") handleGET();
else handleStateGET();
}
/*
* handleStateGET
* Print state on GET
*/
void handleStateGET() {
//Serve Page
Serial.println("Serviced API Request");
//Print Relay state
String buff;
if (RelayState) {
buff = "ON\n";
mqtt_publish("test On message","test");
} else {
buff = "OFF\n";
mqtt_publish("test Off message","test");
}
server.send(200, "text/html", buff);
//Quick LED Flash
delay(20);
//setLED(!LEDState);
}
/*
* setRelay
* Sets the state of the Relay
*/
void setRelay(bool SetRelayState) {
//Switch the HTML for the display page
if (SetRelayState == true) {
OnButt = BUTTONON;
OffButt = BUTTONNOACT;
}
if (SetRelayState == false) {
OnButt = BUTTONNOACT;
OffButt = BUTTONOFF;
}
//Set the relay state
RelayState = SetRelayState;
digitalWrite(RELAYPIN, RelayState);
//Set the LED to opposite of the button.
//setLED(!SetRelayState);
}
/*
* setLED
* Sets the state of the LED
*/
void setLED(bool SetLEDState) {
LEDState = SetLEDState; // set green LED
digitalWrite(LEDPIN, LEDState);
}
/*
* ButtonFlagSet
* Sets a variable so that on next loop, the button state is handled.
*/
void buttonFlagSet(void) {
ButtonFlag = true;
}
/* Read and handle button Press*/
ICACHE_RAM_ATTR void getButton(void) {
// short press butoon to change state of relay
if (digitalRead(BUTTONPIN) == false ) {
++ButtonCount;
}
if (digitalRead(BUTTONPIN) == false && ButtonCount > 1 && ButtonCount < 12 ) {
setRelay(!RelayState); // change relay
if(RelayState==true){
client.publish(mqtt_topic,"{\"sender\":\"self\",\"message\":\"On\",\"room\":\"test\"}");
}
else{
client.publish(mqtt_topic,"{\"sender\":\"self\",\"message\":\"Off\",\"room\":\"test\"}");
}
ButtonCount = 0;
delay(500);
}
/* long press button restart */
if (ButtonCount > 12) {
setLED(!LEDState);
buttonTick.detach(); // Stop Tickers
/* Wait for release button */
while (!digitalRead(BUTTONPIN)) yield();
delay(100);
ESP.restart();
}
if (digitalRead(BUTTONPIN) == true) ButtonCount = 0;
ButtonFlag = false;
}
/*
* loop
* System Loop
*/
void loop(void){
server.handleClient(); // Listen for HTTP request
if(!client.connected()) reconnect();
client.loop();
}
전체 코드입니다.
해당 코드는 깃허브에 올려두었습니다.
추가적으로 제가 사용중인 제품은 아래 링크에 있습니다.
이 제품의 핀 번호와 역할은 아래 사진과 같습니다.
'홈 IoT > 기타' 카테고리의 다른 글
EPS8266 MQTT 통신(라이브러리 교체) (2) | 2024.06.15 |
---|---|
DB 테이블 데이터 정리 (0) | 2023.05.09 |
파트 별 JSON 데이터 타입 설정 (0) | 2023.05.02 |
ESP8266 에서 MQTT 통신하기 (0) | 2023.04.24 |