• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Помогите сделать управление esp8266 по wifi с помощью другой esp8266

SugreonLeks

New member
Здравствуйте. Задача такая.
Есть esp8266 с web интерфейсом (кнопки ON и OFF), работает как клиет по wifi и подключается ко второй esp8266.
Есть вторая esp8266, которая раздаёт интернет по wifi (server).
Если включить обе esp8266 они видят друг друга и если подключится телефоном к esp8266 и открыть браузер, можно зайти на esp8266 и управлять кнопками ON и OFF.
Как сделать так, что бы когда включалась esp8266 server и соединялась со второй esp8266, server эмитировал нажатие на кнопки как делается это на телефоне через браузер?

Выкладываю два кода программы, помогите пожалуйста.


----------------------------------------------------------


Клиент:

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

//#include <BlynkSimpleEsp8266.h>
#include <SoftwareSerial.h>
SoftwareSerial mySerial(D1, D2); // RX, TX
String motion ;
MDNSResponder mdns;

// Wi-Fi
const char* ssid = "test";
const char* password = "12345678";

byte arduino_mac[] = { 0xDE, 0xED, 0xBA, 0xFE, 0xFE, 0xED };
IPAddress ip(192, 168, 2, 2);
IPAddress gateway(192, 168, 2, 1);
IPAddress subnet(255, 255, 255, 0);

ESP8266WebServer server(80);

int D0_pin = 16;
int D2_pin = 2;
int D1_pin = 5;
long rssi;
long rssi2;
long rssi3;
long rssi4;
long rssi5;
long pik;
long sing;
long singu;

void setup(void) {

Serial.begin(115200); //Скорость порта для связи Arduino с компьютером
Serial.println("Goodnight moon!");
mySerial.begin(115200); //Скорость порта для связи Arduino с GSM модулем
mySerial.println("AT");

pinMode(D4, INPUT);
pinMode(D7, INPUT);
pinMode (D0, OUTPUT) ;
pinMode (D3, OUTPUT) ;
pinMode (D5, OUTPUT) ;
pinMode (D4, OUTPUT) ;
pinMode (D6, OUTPUT) ;

delay(2000);
Serial.begin(115200);
// Debug console
WiFi.mode(WIFI_STA);

// while (WiFi.status() != WL_CONNECTED)
// Blynk.begin(auth, ssid, pass);
// You can also specify server:
//Blynk.begin(auth, ssid, pass, "blynk-cloud.com", 8442);
//Blynk.begin(auth, ssid, pass, IPAddress(192,168,1,100), 8442);
pik = 0;
sing = 2;
singu = 2;

// preparing GPIOs
pinMode(D0_pin, OUTPUT);
digitalWrite(D0_pin, LOW);
pinMode(D2_pin, OUTPUT);
digitalWrite(D2_pin, LOW);
pinMode(D1_pin, OUTPUT);
digitalWrite(D1_pin, LOW);


delay(100);
Serial.begin(115200);
WiFi.begin(ssid, password);
WiFi.config(ip, gateway, subnet);


Serial.println("");

// Wait for connection
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

if (mdns.begin("esp8266", WiFi.localIP())) {
Serial.println("MDNS responder started");
}

//+++++++++++++++++++++++ START LED-1 ++++++++++++++++++++
server.on("/", []() {
server.send(200, "text/html", webPage());
});
server.on("/socket1On", []() {
digitalWrite(D0_pin, HIGH);
server.send(200, "text/html", webPage());
delay(100);

});
server.on("/socket1Off", []() {
digitalWrite(D0_pin, LOW);
server.send(200, "text/html", webPage());
delay(100);
//+++++++++++++++++++++++ END LED-1 ++++++++++++++++++++

//+++++++++++++++++++++++ START LED-2 ++++++++++++++++++++
});
server.on("/socket2On", []() {
digitalWrite(D2_pin, HIGH);
server.send(200, "text/html", webPage());
delay(100);
});
server.on("/socket2Off", []() {
digitalWrite(D2_pin, LOW);
server.send(200, "text/html", webPage());
delay(100);

// +++++++++++++++++++++++ END LED-2 ++++++++++++++++++++

//+++++++++++++++++++++++ START LED-3 ++++++++++++++++++++
});
server.on("/socket3On", []() {
digitalWrite(D1_pin, HIGH);
server.send(200, "text/html", webPage());
delay(100);
});
server.on("/socket3Off", []() {
digitalWrite(D1_pin, LOW);
server.send(200, "text/html", webPage());
delay(100);

// +++++++++++++++++++++++ END LED-3 ++++++++++++++++++++


});
server.begin();
Serial.println("HTTP server started");
}

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


if (mySerial.available())
Serial.write(mySerial.read());
if (Serial.available())
mySerial.write(Serial.read());


long rssi = WiFi.RSSI();

}

String webPage()
{
String web;
web += "<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"/> <meta charset=\"utf-8\"><title>ESP 8266</title><style>button{color:red;padding: 10px 27px;}</style></head>";
web += "<h1 style=\"text-align: center;font-family: Open sans;font-weight: 100;font-size: 20px;\">ESP8266 Web Server</h1><div>";
//++++++++++ LED-1 +++++++++++++
web += "<p style=\"text-align: center;margin-top: 0px;margin-bottom: 5px;\">----LED 1----</p>";
if (digitalRead(D0_pin) == 1)
{
web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #43a209;margin: 0 auto;\">ON</div>";
}
else
{
web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #ec1212;margin: 0 auto;\">OFF</div>";
}
web += "<div style=\"text-align: center;margin: 5px 0px;\"> <a href=\"socket1On\"><button>ON</button></a>&nbsp;<a href=\"socket1Off\"><button>OFF</button></a></div>";
// ++++++++ LED-1 +++++++++++++

//++++++++++ LED-2 +++++++++++++
web += "<p style=\"text-align: center;margin-top: 0px;margin-bottom: 5px;\">----Сигнализация----</p>";
if (digitalRead(D2_pin) == 1)
{
web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #43a209;margin: 0 auto;\">ON</div>";
}
else
{
web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #ec1212;margin: 0 auto;\">OFF</div>";
}
web += "<div style=\"text-align: center;margin: 5px 0px;\"> <a href=\"socket2On\"><button>ON</button></a>&nbsp;<a href=\"socket2Off\"><button>OFF</button></a></div>";
// ++++++++ LED-2 +++++++++++++

//++++++++++ LED-3 +++++++++++++
web += "<p style=\"text-align: center;margin-top: 0px;margin-bottom: 5px;\">----LED 3----</p>";
if (digitalRead(D1_pin) == 1)
{
web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #43a209;margin: 0 auto;\">ON</div>";
}
else
{
web += "<div style=\"text-align: center;width: 98px;color:white ;padding: 10px 30px;background-color: #ec1212;margin: 0 auto;\">OFF</div>";
}
web += "<div style=\"text-align: center;margin: 5px 0px;\"> <a href=\"socket3On\"><button>ON</button></a>&nbsp;<a href=\"socket3Off\"><button>OFF</button></a></div>";
// ++++++++ LED-2 +++++++++++++

// ========REFRESH=============
web += "<div style=\"text-align:center;margin-top: 20px;\"><a href=\"/\"><button style=\"width:158px;\">REFRESH</button></a></div>";
// ========REFRESH=============


web += "</div>";
return (web);
}

********************************************************************************
********************************************************************************
********************************************************************************


Сервер:

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

/* Установите здесь свои SSID и пароль */
const char* ssid = "test"; // SSID
const char* password = "12345678"; // пароль
const char* host = "192.168.2.2";
/* Настройки IP адреса */
IPAddress local_ip(192, 168, 2, 1);
IPAddress gateway(192, 168, 2, 1);
IPAddress subnet(255,255,255,0);

ESP8266WebServer server(80);

void setup()
{
Serial.begin(115200);


WiFi.softAP(ssid, password);
WiFi.softAPConfig(local_ip, gateway, subnet);
delay(100);
}

void loop()
{
server.handleClient();

Serial.print("Connecting to ");
Serial.println(host);

WiFiClient client; // Класс WiFiClient используется для создания подключения по TCP
const int httpPort = 80;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed"); // Если сайт недоступен
return; // Прерываем данную итерацию цикла
}

Serial.println();
Serial.println("closing connection");
delay(5000);


}

--------------------------------------------------------------------------------------
 

yurik72

Member
Честно говоря, надо понимать задачу. Возможно решается другими способами. В данной постановке необходимо твоему серверу постоянно иметь список клиентов и что то отсылать. Упуская это из виду, вопрос то в другом.
Надо на сервере написать часть которая как browser отсылает команды на ESP
 

yurik72

Member
Честно говоря, надо понимать задачу. Возможно решается другими способами. В данной постановке, необходимо твоему серверу постоянно иметь список клиентов и что то отсылать. Упуская это из виду, вопрос то в другом.
Надо на сервере написать часть которая как browser отсылает команды на ESP
Для этого используй класс HTTPClient, т.е. на сервере код примерно

WiFiClient client;
HTTPClient http;
if (http.begin(client,"http://<IP or HostName>/socket1On")) {

int httpCode = http.GET();
// httpCode will be negative on error
if (httpCode > 0) { // HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d ", httpCode);
}
}


-------
Упускаю из виду как ты определишь <IP or HostName>
 

pvvx

Активный участник сообщества
Упускаю из виду как ты определишь <IP or HostName>
И как определить текущее состояние переключателя.
Т.е. всё упускаете. :)
Классическое решение лежит в области создания локального сервера-хранилища состояний со связью с внешними устройствами. Если устройство меняет состояние - оно оповещает сервер и наоборот, но опять-же внешнее устройство опрашивает сервер. А весь протокол с изменениями состояний устройств осуществляется с данными от сервера, а не самого устройства.
В такой схеме не надо выяснять кто и где и каждая функция может быть разнесена на разные устройства.
 

pvvx

Активный участник сообщества
А самый примитивный протокол для связи с базой - это Modbus TCP. Хотите никчемного усложнения системы и наворота - тогда MQTT.
Для каждого устройства выделяете поля в адресном пространстве памяти и пишите примитивный шлюз типа Modbus-Websocket и подобные, чтобы управлять всей системой удаленно с помощью простейших статических (!) HTML-JS страниц, которые размещаются совершенно где угодно.
И у вас возникает преимущество в том, что вы имеете полный снимок состояния всех устройств в одном флаконе... Т.е. можете закрутить любые зависимости между устройствами.
 

SugreonLeks

New member
В Будущем будет сделано 4 физических кнопки. При нажатии на одну, надо что бы был послан сигнал приметно такого типа:
http://192.168.2.2/socket2On или http://192.168.2.2/socket2Off
В телефоне при нажатие на кнопку именно эти адреса появляются в браузере. Необходимо что бы esp8266 сама нажимала эти кнопки или посылала запрос как в браузере.
 

SugreonLeks

New member
Получилось. Спасибо очень огромное всем кто помог.

Вот итоговый код.


void loop()
{
server.handleClient();

Serial.print("Connecting to ");
Serial.println(host);

WiFiClient client; // Класс WiFiClient используется для создания подключения по TCP

const int httpPort = 80;
HTTPClient http;
if (!client.connect(host, httpPort)) {
Serial.println("connection failed"); // Если сайт недоступен
return; // Прерываем данную итерацию цикла
}


if (http.begin(client,"http://192.168.2.2 /socket2On")) {

int httpCode = http.GET();
// httpCode will be negative on error
if (httpCode > 0) { // HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d ", httpCode);
}
}

delay(1000);

if (http.begin(client,"http://192.168.2.2 /socket2Off")) {

int httpCode = http.GET();
// httpCode will be negative on error
if (httpCode > 0) { // HTTP header has been send and Server response header has been handled
Serial.printf("[HTTP] GET... code: %d ", httpCode);
}
}

delay(10);



Serial.println();
Serial.println("closing connection");
delay(1000);


}

Тема закрыта.
 

yurik72

Member
И как определить текущее состояние переключателя.
Т.е. всё упускаете. :)
Ну человек задал конкретный вопрос и получил конкретный ответ. Он же не описал задачу свою.
Тем более получилось у него, чем и рады за него.
Можно конечно городить все что угодно и MQTT и ModBus. Главное чтобы задача была решена :)
В данном конкретном примере мой совет SugreonLeks
задуматься над решенией задачи от обратного, Т.е. когда клиент ( исходя из примера выше) просыпается или постоянно в цикле отсылает запрос на сервер , по примеру приведенному мной, а сервер принимает решение и отвечает клиентy, что сделать

Т.е. мы еще имплементируем такой же webserver на стороне СЕРВЕР.
Клиент шлет например запрос http://server/socketon (если включен), а сервер отвечает
например 0 или 1, соответственно, что сделать дальше. при такой архитектуре серверу не надо заботиться и знать кто подключен. Все "живые" клиенты сами спрашивают что делать

P.S. ради будущих комментов, добавлю что помог решить человеку задачу. И предложенный вариант конечно примитивный. Я например в своих задачах, если не используется что то аля MQTT, всегда обмениваюсь не простыми get/post запросами а с телом содержащим json...
 

pvvx

Активный участник сообщества
P.S. ради будущих комментов, добавлю что помог решить человеку задачу. И предложенный вариант конечно примитивный. Я например в своих задачах, если не используется что то аля MQTT, всегда обмениваюсь не простыми get/post запросами а с телом содержащим json...
Угу - так и развивается тупость, а потом говорят что оно "работает" :)
Гнать халтуру и советовать это другим не все могут себе позволить. :p
 

SugreonLeks

New member
Спасибо за советы. В данном случае мне именно это решение и было нужно, простое. Так как не надо отслеживать что в каком положение находится. Клиент опрашивает сервер, и как только сервер появился на связи, сервер ему сказал что и как делать, тот выполнил и всё. Я понимаю что оно должно "немножко" по другому работать.
Спасибо за помощь.
 

Atom

Member
Хотите никчемного усложнения системы и наворота - тогда MQTT.
Ну почему же никчемного? отладку MQTT можно вести в консоли, не используя специализированного ПО. А вот с ModBus нужно еще тулчэйн собрать. И чаще всего не бесплатный.
Хотя тут как в сексе - все на любителя, что другие могут назвать извращением.
 
Сверху Снизу