ESP8266 - ESP01S с реле. Одновременное переключение реле с помощью http (GPIO0) и GPIO2

У меня есть модуль ESP8266 с таким реле: https://aliexpress.com/item/4000348370586.html. Мне удалось управлять модулем, я могу деактивировать и активировать реле с помощью http-запроса со следующим кодом.

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>

#ifndef STASSID
#define STASSID "wifi_name"
#define STAPSK  "wifi_password"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;

ESP8266WebServer server(80);

IPAddress ip(192, 168, 0, 101); //статический ip ESP
IPAddress gateway(192, 168, 0, 1);   //IP-адрес вашего WiFi-роутера (шлюза)
IPAddress subnet(255, 255, 255, 0);  //Маска подсети
IPAddress dns(8, 8, 8, 8);  // DNS
const char* deviceName = "ligth101";

const int relayPin = 0;

void handleOn() {
    digitalWrite(relayPin, LOW);
    setCrossOrigin();
    server.send(200, "text/plain", "Ligth on");
}

void handleOff() {
    digitalWrite(relayPin, HIGH);
    setCrossOrigin();
    server.send(200, "text/plain", "Ligth off");
}

void handlePing() {
    setCrossOrigin();
    server.send(200, "text/plain", "ligth");
}

void configPin(){
    pinMode(relayPin, OUTPUT);
    digitalWrite(relayPin, HIGH);
}

void configWifi(){
    WiFi.setAutoConnect(false);
    WiFi.disconnect();
    WiFi.hostname(deviceName);
    WiFi.config(ip, subnet, gateway, dns);
    WiFi.begin(ssid, password);    
    while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    }
}

void setCrossOrigin(){
    server.sendHeader(F("Access-Control-Allow-Origin"), F("*"));
    server.sendHeader(F("Access-Control-Max-Age"), F("600"));
    server.sendHeader(F("Access-Control-Allow-Methods"), F("PUT,POST,GET,OPTIONS"));
    server.sendHeader(F("Access-Control-Allow-Headers"), F("*"));
}

void sendCrossOriginHeader(){
    setCrossOrigin();
    server.send(204);
}

void configServerPaths(){
    server.on(F("/ping"), HTTP_OPTIONS, sendCrossOriginHeader);
    server.on(F("/ping"), HTTP_GET, handlePing);

    server.on(F("/on"), HTTP_OPTIONS, sendCrossOriginHeader);
    server.on(F("/on"), HTTP_GET, handleOn);

    server.on(F("/off"), HTTP_OPTIONS, sendCrossOriginHeader);
    server.on(F("/off"), HTTP_GET, handleOff);
    
    server.begin();
}

void setup() {
    configPin();    
    configWifi();
    configServerPaths();
}

void loop() {
    server.handleClient();
}

Теперь я хочу использовать контакт GPIO2 для включения и выключения реле. Желаемым поведением является изменение состояния реле независимо от того, исходит ли оно от кнопки или от HTTP-запроса.

Я пробовал следующие модификации кода:

const int buttonPin = 2;
int buttonState = 0;

void configPin(){
    ...
    digitalWrite(buttonPin, LOW);
}

void handleButton(){
    buttonState=digitalRead(buttonPin);
    if(buttonState == HIGH) {
        digitalWrite( relayPin, !digitalRead(relayPin) );
        delay(1000);
    } 
}

void loop() {
    server.handleClient();
    handleButton();
}

С этими изменениями кода я протестировал следующие две модификации оборудования:

  1. Размещение переключателя между землей и GPIO2. В результате каждый раз, когда я нажимаю кнопку, реле остается прерывистым, бесконечно переходя из одного состояния в другое.
  2. Размещение переключателя между землей и GPIO2, но добавление резистора между переключателем и выводом GPIO2, но это тоже не работает.

Есть ли способ деактивировать/активировать реле с помощью GPIO2 с помощью кнопки и через http в том числе?

Спасибо!

, 👍0

Обсуждение

Здесь есть ряд проблем. 1) GPIO2 — это выход TX1 первого последовательного порта. Вы не можете использовать его, если у вас также есть последовательный вывод через Serial 1 (что может быть, а может и не быть). 2) Почему вы устанавливаете для buttonPin значение LOW, когда используете его в качестве входа? 3) Вы никоим образом не устраняете дребезг кнопки. 4) Используете ли вы подтяжку или опускание для кнопки, или ни то, ни другое? Из вашего описания непонятно., @StarCat

удалите digitalWrite из handleOn(), handleOff() и из handleButton()... только установите или снимите флаг в этих трех функциях.... поместите digitalWrite (управление реле) в конец loop() ... если флаг установлен, то включите реле ... если флаг очищен, то выключите реле .... вы можете легко расширить свой код, чтобы установить и очистить флаг используя таймер, если хотите, @jsotola


1 ответ


2

В отличие от esp-01, на esp-01S контакты io 0 и io 2 имеют подтягивающий резистор.

Подключите кнопку между io 2 и землей, и вы увидите НИЗКИЙ уровень, если кнопка нажата.

Используйте переменную состояния для состояния реле, не считывайте контакт (работает ли вообще чтение состояния выходного контакта с помощью digitalRead на esp8266?).

,