• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Заливаем скетчи в ESP8266, управляем каналами по Wi-Fi, создаем свои сети.

Paul_B

Member
Итак, овладел заливкой скетчей в ESP8266 (ESP-07).

Физически сделал три кнопки, подключенные к GPIO-0, RES, EN (он же CH-PD или что-то созвучное, но на плате ESP-07 он зовется как EN), второй конец кнопок - к земле (GND), эти же выводы подтянуты через 10кОм к +3.3В.



Для прошивки в нее скетча достаточно начать кнопку GPIO-0 (замкнуть на землю) и любую (как оказалось) из кнопок RES или EN. Потом нажать в Arduino-IDE на заливку скетча. Естественно должны быть залиты в Ардуино-ИДЕ все библиотеки - как это сделать полно информации в инете.
После заливки скетча он сразу же запускается.
Вот пример простенького скетча, который по запросу из браузера по команде http://192.168.1.72/gpio/t получает ответ о температуре и влажности, а по командам
http://192.168.1.72/gpio/4/1 или http://192.168.1.72/gpio/4/0 управляет состоянием вывода GPIO-4 (всего выведено 6 каналов для возможности управления).

Само устройство убрал в корпус из-под блока питания (совместно с БП на 5 вольт и стабилизатором на 3.3 В.



На устройстве задан статический IP 192.168.1.72
Код:
#include <ESP8266WiFi.h>
#include <DHT.h>
#include <DHT_U.h>

#define All_GPIO_OUT 6
int GPIO_OUT[All_GPIO_OUT]= {4,5,13,14,15,16};

const char* ssid = "MyHomeWiFi";
const char* password = "My_password";
IPAddress ip(192, 168, 1, 73); //Node static IP
IPAddress gateway(192, 168, 1, 5);
IPAddress subnet(255, 255, 255, 0);

#define DHTTYPE DHT11     // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321#define DHTTYPE DHT11     // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
//#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

// датчик DHT:
const int DHTPin = 12;
// инициализируем датчик DHT:
DHT dht(DHTPin, DHTTYPE);


int GPIO_OUT_S[All_GPIO_OUT];
int i,j,val,ind;
String s;
long Tm,Tm1;
float t,h,hic;

// Create an instance of the server specify the port to listen on as an argument
WiFiServer server(80);

void setup() {
  Serial.begin(115200);
  delay(10);
  pinMode(2, OUTPUT);
  digitalWrite(2, HIGH);

  dht.begin();

  for(i=0;i<All_GPIO_OUT;i++)
    {
     pinMode(GPIO_OUT[i], OUTPUT);
     digitalWrite(GPIO_OUT[i], 0);
     GPIO_OUT_S[i]=0;
    }
 
  // Connect to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
 
  WiFi.config(ip, gateway, subnet);
 
  WiFi.begin(ssid, password);

  ind=0;
  i=0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
    i++;
    if(i%2==0) digitalWrite(2, HIGH);
    else digitalWrite(2, LOW);
  }
  Serial.println("");
  Serial.println("WiFi connected");
  digitalWrite(2, LOW);
 
  // Start the server
  server.begin();
  Serial.println("Server started");
   // Print the IP address
  Serial.println(WiFi.localIP());

}

void loop() {
  // Check if a client has connected
   
  WiFiClient client = server.available();
  if (!client) { 
    Flash_GPIO(); 
    return;
   
  }
 
  // Wait until the client sends some data
  Serial.println("new client");
  while(!client.available()){
    delay(1);
  }
 
  // Read the first line of the request
  String req = client.readStringUntil('\r');
  Serial.println(req);
  client.flush();
 
  // Match the request
  j=0;
  val=-1;
  for(i=0;i<All_GPIO_OUT;i++)
    {
     s="/gpio/"+String(GPIO_OUT[i])+"/0";
     if (req.indexOf(s) != -1)
       {
        val = 0;
        break;
       } 
     s="/gpio/"+String(GPIO_OUT[i])+"/1";
     if (req.indexOf(s) != -1)
       {
        val = 1;
        break;
       }
    }
 
  if (req.indexOf("/gpio/t") != -1) 
    {
     val=2;   
     // данные от датчика могут запаздывать на 2 секунды
     // (это очень медленный датчик):
     h = dht.readHumidity();
     // считываем температуру в Цельсиях (по умолчанию):
     t = dht.readTemperature();
     // проверяем, корректны ли считанные данные,
     // и если нет, то выходим и начинаем заново:
     if (isnan(h) || isnan(t) ) {
       Serial.println("Failed to read from DHT sensor!");
       // "Не удалось прочитать данные от датчика DHT"
       s="DHT Failed";       
      }
      else{
            // рассчитываем градусы в Цельсиях а также влажность:
            hic = dht.computeHeatIndex(t, h, false);     
            // все эти Serial.print() ниже можно удалить,
            // т.к. они для отладочных целей:
            Serial.print("Humidity: ");  //  "Влажность: "
            Serial.print(h);
            Serial.print(" %\t Temperature: ");  //  "Температура: "
            Serial.print(t);
            Serial.print(" *C ");
            //  "Тепловой индекс: "
            Serial.print(hic);
            Serial.print(" *C ");
            s="T="+String(t)+" H="+String(h)+" Index="+String(hic);
          } 

    }
  if (req.indexOf("/gpio/h") != -1) 
    {
     val=3;   

    } 
   
  if(val==-1) {
    Serial.println("invalid request");
    client.stop();   
    return;
  }

  if(val==0 || val==1)
   {
    digitalWrite(GPIO_OUT[i], val);
    GPIO_OUT_S[i]=val;
 
    s="";
    // Prepare the response
    // s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\n<html>\r\n";
    s +="GPIO" +String(GPIO_OUT[i])+" is now "; 
    s += (val)?"high":"low";
  //  s += "</html>\n";

  // Send the response to the client

   }

  client.flush(); 
  client.print(s);
  delay(10);
  client.stop();
  delay(1);
  Serial.println("Client disonnected");

  // The client will actually be disconnected 
  // when the function returns and 'client' object is detroyed
 Flash_GPIO();
}

void Flash_GPIO()
{
int k=0; 

Tm=millis()/1000;

if(Tm-Tm1>=2)
  {     

   for(i=0;i<All_GPIO_OUT;i++)
   if(GPIO_OUT_S[i]==1) k++;
   if(k==0)
     {
       digitalWrite(2, HIGH);
       delay(100);
       digitalWrite(2, LOW);
     }
   else {
         for(i=0;i<k;i++)   
          {   
           digitalWrite(2, HIGH);
           delay(300);
           digitalWrite(2, LOW); 
           delay(200);   
           }
        }
     
   Tm1=millis()/1000;
  }
   
}

Можно аналогичные команды выполнять из командной строки, используя утилиту wget.exe.
Вот простенькие строки в bat-файле для проверки возможности
call wget -t 1 -O wg.txt http://192.168.1.72/gpio/t
pause
call wget -t 1 -O wg.txt http://192.168.1.72/gpio/4/1
pause
call wget -t 1 -O wg.txt http://192.168.1.72/gpio/5/1
pause
call wget -t 1 -O wg.txt http://192.168.1.72/gpio/15/1
pause
call wget -t 1 -O wg.txt http://192.168.1.72/gpio/16/1
pause

Это что сделано.....
Теперь о том что хочется....
 

Paul_B

Member
Теперь о том что хочется. Все эти манипуляции с управлениями я могу производить в своей домашней сети, при этом знать IP-адрес устройства, соответственно, чтобы внести любые изменения - надо опять заливать скетч, что не очень удобно. Хотелось бы, чтобы был один сервер на ESP8266, который бы создавал свою точку доступа со своим именем. На нем бы крутилась программа, скажем управления обогревом на основании показаний датчиков температуры, которые раскиданы по комнатам, а вот эти датчики, которые также реализованы на базе ESP8266 автоматически подключались к этой сети. Просто заложить в скетч просто SSID сети проще, чем прописывать IP-адреса для каждого датчика в своей домашней сети, особенно, если это сделать для кого-то.
 

=AK=

New member
Теперь о том что хочется. Все эти манипуляции с управлениями я могу производить в своей домашней сети, при этом знать IP-адрес устройства, соответственно, чтобы внести любые изменения - надо опять заливать скетч, что не очень удобно.
А вы в своем скетче сделайте так:
- После того, как подключились к сети, прочитайте свой динамический адрес
- Раз в минуту или около того отправляйте широковещательное UDP сообщение такого примерно содержания: "я модуль ESP-07, исполняю скетч такой-то, мой IP адрес такой-то"

Ну и программку на РС напишите, которая будет ловить эти сообщения, выстраивать список имеющихся модулей и управлять ими по командам пользователя, используя их IP адреса. :)
 

kab

New member
Теперь о том что хочется. Все эти манипуляции с управлениями я могу производить в своей домашней сети, при этом знать IP-адрес устройства, соответственно, чтобы внести любые изменения - надо опять заливать скетч, что не очень удобно. Хотелось бы, чтобы был один сервер на ESP8266, который бы создавал свою точку доступа со своим именем. На нем бы крутилась программа, скажем управления обогревом на основании показаний датчиков температуры, которые раскиданы по комнатам, а вот эти датчики, которые также реализованы на базе ESP8266 автоматически подключались к этой сети. Просто заложить в скетч просто SSID сети проще, чем прописывать IP-адреса для каждого датчика в своей домашней сети, особенно, если это сделать для кого-то.
Сергей Третьяков на этом сайте предлагает открытую систему (на Arduino IDE) весьма похожую, как Вы описываете. Кнопочка "Поиск..." вверху на странице - может творить чудеса ... :)
 

Paul_B

Member
В том-то и дело, что не знаю по каким словам искать. По "открытая система" ничего не ищется.
 

kab

New member
В том-то и дело, что не знаю по каким словам искать. По "открытая система" ничего не ищется.
Пошаговая инструкция :)
1. Открываете ссылку на тему в моей подписи
2. Нажимаете кнопочку "Мне нравится" - это обязательно, иначе не сработает:D
3. Ищете пост Сергея Третьякова.
4. У него в подписи открываете ссылу на видеоуроки
5. Изучаете.
6. Что хотите уточнить - обращаетесь к Сергею.

Я же предлагал поискать по поиску "Третьяков". Но там будет, наверно, слишком много. Поэтому лучше по инструкции :)
 

Алексей.

Active member
- Раз в минуту или около того отправляйте широковещательное UDP сообщение такого примерно содержания: "я модуль ESP-07, исполняю скетч такой-то, мой IP адрес такой-то"
"мой IP адрес такой-то" какой смысл отправлять? получатель и так его определит, и не нужно "прочитать свой динамический адрес"

Отправлять мультикаст было бы правильнее, пусть все устройства общаются в своей группе.
 

enjoynering

Well-known member
вообще то помещать html страницу или заголовки html запросов в тело скетча - это моветон и признак корявости.
 

kab

New member
вообще то помещать html страницу или заголовки html запросов в тело скетча - это моветон и признак корявости.
Это признак того, что человек начал учится в этой области и совершенно обоснованно начинает с более простых задач, где логика решения более прозрачна.
Если при обучении в любой области человек застрял на "букваре" и не может/не хочет двигаться дальше - это значит, что он занялся не своим делом. "Моветон" и "корявость" - обычно, это не вина, а беда человека...
 

Paul_B

Member
Наверное вы не поняли что мне хочется. Я не хочу, чтобы все это работало в моей сети. Я хочу, чтобы я вышел в поле, подключил устройства к питанию 220 вольт и у меня все должно начать работать. Одна ESP (сервер) должна создать точку доступа с именем, скажем ESP8266-07 (это имя можно прописать в скетче), остальные (клиенты) ESP должны подключаться к этой, а она должна ими управлять. Программу клиентов я написал выше, а вот как организовать на ESP точку доступа с рассылкой сообщений клиентам? А если этот сервер еще может быть клиентом для моей домашней сети, то ваще будет жесть.

Что передавать свои IP клиенты могут - это уже детали.
 

kab

New member
точку доступа с рассылкой сообщений клиентам
Тут несколько нарушена логика - обычно сервер не производит рассылку по своей инициативе, а отвечает на запрос клиента. Правда, если реализовывать через UDP, то можно реализовать и просто рассылку.
 

gerkimuyda

New member
вообще то помещать html страницу или заголовки html запросов в тело скетча - это моветон и признак корявости.
Разве? А вы как предлагаете? Для маленькой проги создавать файловую систему, писать в нее файл, а потом городить обработчик этого файла, чтобы в нужные места вместо команд подставлять нужные значения? и это даже не на компе, а на маленьком слабеньком чипике? :)
 

Paul_B

Member
Тут несколько нарушена логика - обычно сервер не производит рассылку по своей инициативе, а отвечает на запрос клиента. Правда, если реализовывать через UDP, то можно реализовать и просто рассылку.
Игра слов.
Я же написал - один создает точку доступа (аналог роутера), SSID сети прописан во всех скетчах на всех устройствах, пароль на вход тоже). Как подключаются клиенты я знаю - написал выше скетч.
Основной вопрос - как на ESP реализовать создание этой точки доступа и аналог посылания запросов через браузер типа http://IP-адрес-клиента/gpio/t
Понятно, что клиент, подключаясь к серверу, определяет свой локальный адрес и отправляет его на сервер. Сервер посылает запросы клиенту для управления им.
Вот все что я хочу узнать.

Сразу возникает вопрос - могут ли клиенты слать запросы друг другу через сервер (тот, кто организует точку доступа)?
 

Алексей.

Active member
вообще то помещать html страницу или заголовки html запросов в тело скетча - это моветон и признак корявости.
Для выполнения запросов, которые меняют состояние сервера, через вызов метода "GET", сознательно не вызывая метод "POST", здесь, я думаю, считается нормой :D
 

kab

New member
Игра слов.
Я же написал - один создает точку доступа (аналог роутера), SSID сети прописан во всех скетчах на всех устройствах, пароль на вход тоже). Как подключаются клиенты я знаю - написал выше скетч.
Основной вопрос - как на ESP реализовать создание этой точки доступа и аналог посылания запросов через браузер типа http://IP-адрес-клиента/gpio/t
Понятно, что клиент, подключаясь к серверу, определяет свой локальный адрес и отправляет его на сервер. Сервер посылает запросы клиенту для управления им.
Вот все что я хочу узнать.

Сразу возникает вопрос - могут ли клиенты слать запросы друг другу через сервер (тот, кто организует точку доступа)?
создание этой точки доступа
- Это не проблема - примеров полно, могу попозже поискать ссылки

аналог посылания запросов через браузер
- Про это я писал в другой теме - могу вечером дать ссылку точнее
 
Сверху Снизу