Веб сервер

Тема в разделе "ESP8266, ESP32", создана пользователем TebEnkov2222, 14 июн 2018.

  1. TebEnkov2222

    TebEnkov2222 Гик

    Господа, добрый день.. У меня такой вопрос: можно ли сделать веб сервер на esp-32. Обычный веб сервер я знаю как сделать. Но с оформлением большие проблемы.. И у меня нету модуля sd карты.. Можно ли как то поместить сайт в саму память esp-32?
     
  2. DIYMan

    DIYMan Guest

    Вопрос: чем отличается обычный веб-сервер от необычного? Ориентацией?

    Ещё вопрос: уверен, что знаешь, как сделать? Чтобы в соответствии с RFC по HTTP всё было, да? Точно уверен? Точно знаешь? Или просто сдёрнешь из куцых примеров, что в поставке? Так вот: в примерах - там НИГДЕ нету имплементации худо-бедненького веб-сервера - там нищебродство, и половину заголовков просто не обрабатываются. Так, заимплементили кой-чего - не более, но это точно не тянет на гордое звание "веб-сервер" ;)

    Так точно знаешь, как сделать веб-сервер? Если точно знаешь - расскажи, плз, как у тебя имплементированы обработчики запроса и ответа Content-Disposition, например.
     
    Andrey12 нравится это.
  3. TebEnkov2222

    TebEnkov2222 Гик

    Да, точно знаю.. т. к. на уне я уже делал (псевдо) сервер. Выводилась температура, влажность (с DHT11), время.. И можно было управлять 2 реле..
    Вот код..
    Код (C++):

    #include <Wire.h>             // Подключаем бибилиотеку для работы с I2C устройствами
    #include <DS3231.h>           // Подключаем библиотеку для работы с RTC DS3231

    #include "dht.h"

    #include <SPI.h>             //библиотека для работы с SPI
    #include <Ethernet.h>

    #define dht_apin A0

    dht DHT;

    DS3231 clock;
    RTCDateTime DateTime;         // Определяем сущность структуры RTCDateTime (описанной в библиотеке DS3231) для хранения считанных с часов даты и времени
    RTCAlarmTime Alarm1;          // Определяем сущность структуры RTCAlarmTime (описанной в библиотеке DS3231) для хранения считанных с первого будильника настроек даты и времени

           byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDA, 0x02 };    
    //MAC адрес вашего Ethernet-модуля, если его у вас нет, введите любой
    //или оставьте тот, что в примере

          //указываем IP адрес
          //будьте внимательны! IP адрес указывается тот, который вы получили запустив пример DhcpAdressPrinter
          IPAddress ip(192,168,1,103);    //пример МОЕГО IP адреса, вы вводите сюда СВОЙ

      //инифиализация библиотеки Ethernet server library
    EthernetServer server(80);

    boolean newInfo = 0;  
    boolean reley_1 = 0;
    boolean reley_2 = 0;
    boolean isAlarm = false;      // Логическая переменная для обработки сигнала о срабатывании будильника
    boolean alarmState = false;   // Логическая переменная для обработки индикации при срабатывании будильника
    int alarmLED = 4;             // Пин, к которому подключаем индикатор срабатывания будильника (светодиод)

    void alarmFunction()                                  // Функция, вызываемая при срабатывании будильника
    {
      isAlarm = true;                                     // Присваиваем значение "истина" переменной для обработки срабатывания будильника
    }

    void setup(){
      Serial.begin(9600);
         clock.begin();                    // Инициализируем работу с объектом библиотеки DS3231
         clock.enableOutput(false);        // Определяем назначение вывода SQW (INT) для генерации прерываний при сработке будильников
         clock.setDateTime(__DATE__, __TIME__);                  // Устанавливаем время на часах, основываясь на времени компиляции скетча)
         clock.setAlarm1(0, 0, 0, 10, DS3231_MATCH_S);           // Устанавливаем первый будильник на срабатывание в 10 сек. каждой минуты. Режим DS3231_MATCH_S сообщает о том, что ориентироваться надо на секунды.
         pinMode(alarmLED, OUTPUT);                              // Определяем пин подключения питания светодиода, как исходящий
         attachInterrupt(0, alarmFunction, FALLING);             // Задаем функцию для обработки прерывания 0 (на пине 2)
      pinMode(6, OUTPUT);
      pinMode(7, OUTPUT);
                       
      //запускаем сервер с указанными ранее MAC и вашим IP
      Ethernet.begin(mac, ip);
      server.begin();

    }

    void loop()
    {

      DHT.read11(dht_apin);

      {
      DateTime = clock.getDateTime();                                                 // Считываем c часов текущие значения даты и времени в сущность DateTime
      Alarm1 = clock.getAlarm1();                                                     // Считываем c первого будильника текущие настройки даты и времени в сущность Alarm1
      Serial.println(clock.dateFormat("d.m.Y H:i:s - l   ", DateTime));               // Определяем формат вывода даты и выводим на монитор серийного порта
      Serial.println("Temperature: " + String(clock.readTemperature()));              // Выводим значения температуры
      Serial.println("Alarm: " + String(clock.dateFormat("__ __:__:s", Alarm1)));     // Выводим настройки будильника                              
      Serial.println();                                                               // Перевод строки
      delay(1000);                                                                    // Задержка в 1 секунду
    }

      //принимаем данные, посылаемые клиентом
      EthernetClient client = server.available();
      if(client){                                       //если запрос оканчивается пустой строкой
      boolean currentLineIsBlank = true;                //ставим метку об окончании запроса (дословно: текущая линия чиста)
      while (client.connected()) {                      //пока есть соединение с клиентом
        if (client.available()) {                       //если клиент активен
          char c = client.read();                       //считываем посылаемую информацию в переменную "с"
                                                     
          if(newInfo && c == ' '){                      //если переменная новой информации = 1 и "с", в которой записан запрос, равен пустой строке
            newInfo = 0;                                //то обнуляем переменную поступления новой информации
          }
         
          if(c == '$'){                                 //если переменная "с", несущая отправленный нам запрос, содержит символ $
                                                        //(все новые запросы) - "$" подразумевает разделение получаемой информации (символов)
            newInfo = 1;                                //то пришла новая информация, ставим метку новой информации в 1
          }
         
          /************************************************************************************************
          Примечание:
          Символ $ используется как обычный символ, который разделяет 1 от 2
          На практике применяют символ &, который разделяет новые переменные от последующих
          Это использьуется, например, в GET-запросах, которые выглядят подобным образом:
          client.print("GET /controlbar/wp-content/data.php?uid=" + ID + "&type=" + type + "&value=" + value);
          как видите, знак & разделяет значение переменной - ID и переменную type    
          ***************************************************************************************************/

         
                                                         //Проверяем содержание URL - присутствует $1 или $2
          if(newInfo == 1){                              //если есть новая информация
              Serial.println(c);
              if(c == '1'&&reley_1==0){                              //и "с" содержит 1
              Serial.println("ON");
              digitalWrite(6, HIGH);                    //то зажигаем светодиод
              reley_1=1;
              }
             
              if(c == '2'&&reley_1==1){                              //если "с" содержит 2
              Serial.println("OFF");
              digitalWrite(6, LOW);                     //гасим светодиод
              reley_1=0;
              }  
             
              if(c == '3'&&reley_2==0){                              //и "с" содержит 1
              Serial.println("ON");
              digitalWrite(7, HIGH);  
              reley_2=1;
              }
             
              if(c == '4'&&reley_2==1){                              //если "с" содержит 2
              Serial.println("OFF");
              digitalWrite(7, LOW);                     //гасим светодиод
              reley_2=0;
              }  
          }
         
         
          if (c == '\n') {                              //если "с" равен символу новой строки
            currentLineIsBlank = true;                  //то начинаем новую строку
          }
          else if (c != '\r') {                         //иначе, если "с" не равен символу возврата курсора на начало строки
            currentLineIsBlank = false;                 //то получаем символ на текущей строке
          }
       
          if (c == '\n' && currentLineIsBlank) {        //выводим HTML страницу
            client.println("HTTP/1.1 200 OK");          //заголовочная информация
            client.println("Content-Type: text/html");
            client.println("Connection: close");
            client.println("Refresh: 30");              //автоматическое обновление каждые 30 сек
            client.println();
            client.println("<!DOCTYPE HTML>");          //HTML тип документа
            client.println("<html>");                   //открытие тега HTML
            client.println("<head>");
            client.print("<title>My web Server</title>");                  //название страницы
            client.println("</head>");
            client.println("<body>");
            client.print("<H1>My web Server</H1>");                        //заголовк на странице
            client.print("<a>Current humidity = </a>");
            client.print(DHT.humidity,1);
            client.print("<a>%</a>");
            client.println("<br />");
            client.print("<a>temperature = </a>");
            client.print(DHT.temperature,1);
            client.print("<a>C</a>");
            client.println("<br />");
            client.print("<H2>Reley_1</H2>");
            client.print("<a href=\"/$1\"><button>Off</button></a>");       //кнопка включить
            client.print("<a href=\"/$2\"><button>On</button></a>");      //кнопка выключить
            client.println("<br />");
            client.print("<H2>Reley_2</H2>");
            client.print("<a href=\"/$3\"><button>Off</button></a>");       //кнопка включить
            client.print("<a href=\"/$4\"><button>On</button></a>");      //кнопка выключить
            client.println("<br />");
            client.println("</body>");    
            client.println("</html>");                  //закрываем тег HTML
            break;                                      //выход
          }
       
        }
       
      }
      delay(1);                                          //время на получение новых данных
      client.stop();                                     //закрываем соеднение

    }
    }
    не знаю, правильно ли я делал.. Но я делал так..
    И (псевдо) сайты тоже умею делать.. (только html и css)
     
  4. TebEnkov2222

    TebEnkov2222 Гик

    Можно было использовать JS или JQeri.. Но тогда я их не знал..
     
  5. TebEnkov2222

    TebEnkov2222 Гик

    И не знаю.. Можно ли их туды впихнуть (не пробовал)..)
     
  6. TebEnkov2222

    TebEnkov2222 Гик

    Ну я имел в виду: тот что в примерах(чистый html), и То что ты хочешь получить в конечном итоге (Красивый, с оформлением, со всякими там датчиками, шпунтиками и всем всем всем...) =)
     
  7. DIYMan

    DIYMan Guest

    Где там в коде имплементация веб-сервера - ткните плз пальцем. Не надо подменять понятия: тот код, что вы продемонстрировали, не имеет никакого отношения к веб-серверу. Вывод: вы таки не знаете, что такое веб-сервер.
     
  8. DIYMan

    DIYMan Guest

    Какое ко всему этому имеет отношение, ВНИМАНИЕ, веб-сервер? Вижу только одно совпадение - буква H в аббревиатуре HTML - да, протокол HTTP тоже имеет такую букву в аббревиатуре, и даже с таким же значением. Однако, совпадение понятия hypertext не делает веб-сервер хоть в какой-то степени причастным к языку разметки, коим является, по определению, HTML. Да и HTTP уже давно вырос из первоначального определения HyperText Transfer Protocol, строго говоря - взять хотя бы тот факт, что файл стилей (*.css) - по определению гипертекстом не является, хотя и может передаваться посредством протокола HTTP.

    Вам точно нужен именно веб-сервер? Или вы хотите просто красивые странички? Что такое веб-сервер, по определению: https://ru.wikipedia.org/wiki/Веб-сервер
     
  9. TebEnkov2222

    TebEnkov2222 Гик

    Извиняюсь.. Не много не до понял...
    Ладно, разобрался.. По идее нужен то Веб Сервер.. (удаленноё управление котлом). Так как лок. сеть не подойдет. Но и красиво то тоже нужно.. Противно будет смотреть на полупустой белый лист... Но мне хотя бы просто веб сервер разобрать..
     
  10. DIYMan

    DIYMan Guest

    Сложность задачи зависит от того, насколько полной вы хотите сделать имплементацию HTTP. В простейшем случае (возможно, вас это устроит) - достаточно реализовать обработку методов GET и POST (что касается POST - то там достаточно обработки multipart-form-data - это то же самое, что в GET в параметрах, грубо говоря), URI decode и encode (чтобы корректно работать с escape-последовательностями), обработку некоторых заголовков и выдачу нескольких типов статусов ответа. Будет куцый такой, но уже веб-серверок.
     
  11. TebEnkov2222

    TebEnkov2222 Гик

    Ну я так и не понял... Как работать с интернет сервером?.. Посмотрел.. Есть с использование 80 порта.. Но не знаю, подойдёт ли.. Задача такая у меня: Нужно поставить 2 датчика ds18b20, датчик напряжения и на будущее датчик давления (пока не будет). Подумал я.. На оформление пофиг.. Как мне ВООБЩЕ сделать интернет сервер, с выходом из любой точки мира?
     
  12. Mitrandir

    Mitrandir Гуру

    http://wikihandbk.com/wiki/ESP8266:Примеры/Веб-сервер_с_помощью_ESP8266_и_IDE_Arduino
     
  13. ИгорьК

    ИгорьК Гуру

    Не нужен тебе сервер - отправляй данные на общедоступный или платный Mqtt брокер и забирай их из любой точки мира. Мало головной боли и времени на реализацию.
     
    DIYMan, Igor68 и Mitrandir нравится это.
  14. ИгорьК

    ИгорьК Гуру

  15. ИгорьК

    ИгорьК Гуру

    Вот у меня сейчас на iot.eclipse.org в ветке test001/# висит устройство.
    SmartSelect_20180628-121225_MQTT Dash.jpg
    Берешь программку MQTT dash на андроиде и можешь подергать.
     
  16. DIYMan

    DIYMan Guest

    Присоединяюсь к Игорю - MQTT наше всё, не надо выдумывать себе головняк, надо пользоваться хорошими проверенными решениями ;)
     
    Mitrandir нравится это.
  17. b707

    b707 Гуру

    Сдается мне, что ТС спрашивает совсем о другом - как ему в локальной сети поднять сервер, который будет виден из любой точки мира?
    Если да - то ардуина или ЕСП к этому вопросу вообще не имют отношения...

    А вообще, меня всегда прикалывают подобные запросы :) Ну нафига управлять газовым котлом из другой точки мира? :))) Можно подумать, что пишет Дмитрий Шпаро или Федор Конюхов, который 11 месяцев в году болтается где-то в океане :)
    Вся эта автоматизация по интернет - пустая игрушка. Система должна работать сама, не требуя от хозяина постоянных поправок через сеть.
     
  18. Mitrandir

    Mitrandir Гуру

    Не согласен, з мой езжу кататься на лыжах на Игору( небольшой горнолый комплекс под Питером) . У меня дача в километрах 10. Выезжаю с города запускаю обогрев. Показавшись еду ночевать на дачу, там уже тепло.
     
  19. ИгорьК

    ИгорьК Гуру

    +100500
     
  20. TebEnkov2222

    TebEnkov2222 Гик

    Ну знаете ли.. Я живу в деревне.. У нас часто бывают перебои со светом.. А котёл у нас.. Честно говоря, не совсем адекватно работает.. Свет выключится.. Котёл встанет, не выключится.. Насосы качать не будут.. А нас дома не будет.. И все.. И весь дом взлетит на воздух.. По этому ЖЕЛАТЕЛЬНО разработать такую систему.. По крайней мере просто для слежения: какая температура на котле, в системе, какое давление в системе. присутствует ли свет, включен ли котёл..