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

скетч с конфигуратором в eeprom, сервер и клиент

Vitaly

Member
Хочу поделится своим скетчем с конфигуратором в eeprom, может быть будет кому-то полезно
Сохранение настроек c crc, включение/выключение клиента wifi, отправлялки данных на сервер через GET
проверка адреса клиента и запрет менять настройки со стороны wifi station

имя точки задается из переменной и последних 4х символом мак адреса, пароль точки аналогично

Готов выслушать любые комментарии)

aESPtemplate.ino


edit:
Добавил возможность выключения точки при подключении в режиме клиента, сохранение пустых паролей и что-то еще по мелочи.

edit:
для работы http ota нужен сервер отдающий прошивки, например с таким скриптом esp.php.txt
 
Последнее редактирование:

Evgeniy

New member
Спасибо большое, крутой скетч, все работает! Было бы вообще супер, если бы, была возможность точку доступа из WIFI эфира убирать, так как, когда устройств много большой список интернет-вещей в качестве точек доступа создаёт дискомфорт при подключении или переключении WIFI.
 

Vitaly

Member
Спасибо большое, крутой скетч, все работает! Было бы вообще супер, если бы, была возможность точку доступа из WIFI эфира убирать, так как, когда устройств много большой список интернет-вещей в качестве точек доступа создаёт дискомфорт при подключении или переключении WIFI.
пока что логика такая что все настройки только через точку доступа

можно конечно приделать что-то в проверку подключения
после wifiInitOk = true;
WiFi.mode(WIFI_STA);
тогда если подключился точку вырубит, но включить ее можно будет только на рестарте если клиент не подключается
 

uvaxut

New member
Дабы не плодить тему, набросал тоже простенькую заготовку сохранения параметров в eeprom. При первом запуске модуль ( у меня esp-01) включается в режиме открытой точки доступа. Далее, по адресу 192.168.4.1 открываем страницу настроек, в которой указываем SSID и пароль точки, к которой надо подключиться, жмем Save и перегружаемся. После перезагрузки модуль цепляется к точке доступа. Чтобы перейти в режим настройки заново, надо после старта и подключения к АР подать минус на gpio0 и перезагрузить модуль.
собственно, код:
Код:
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <EEPROM.h>

String str = "";
boolean conf = false;

String html_header = "<html>\
  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\
  <head>\
    <title>ESP8266 Settings</title>\
    <style>\
      body { background-color: #cccccc; font-family: Arial, Helvetica, Sans-Serif; Color: #000088; }\
    </style>\
  </head>";
 
ESP8266WebServer server(80);
void setup(void)
{ 
    byte len_ssid, len_pass;
   
    delay(1000);
    Serial.begin(115200);
    Serial.println();   
   
    EEPROM.begin(98);

    len_ssid = EEPROM.read(96);
    len_pass = EEPROM.read(97);
    if(len_pass > 64) len_pass = 0;
   
  pinMode(0, INPUT_PULLUP);
  if((len_ssid < 33) && (len_ssid != 0)){ 
    // Режим STATION 
      WiFi.mode( WIFI_STA);
      unsigned char* buf_ssid = new unsigned char[32];
      unsigned char* buf_pass = new unsigned char[64];
      for(byte i = 0; i < len_ssid; i++) buf_ssid[i] = char(EEPROM.read(i));
      buf_ssid[len_ssid] = '\x0';
      const char *ssid  = (const char*)buf_ssid;
      for(byte i = 0; i < len_pass; i++) buf_pass[i] = char(EEPROM.read(i + 32));
      const char *pass  = (const char*)buf_pass;
      buf_pass[len_pass] = '\x0';
     
      Serial.print("SSID: ");
      Serial.print(ssid);
      Serial.print("   ");
      Serial.print("Password: ");
      Serial.println(pass);
     
      WiFi.begin(ssid, pass);
      // 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());
    }
    else // Режим SoftAP
      {
        const char *ssid_ap = "ESPap";
       
        WiFi.mode(WIFI_AP);
       
        Serial.print("Configuring access point...");
    /* You can remove the password parameter if you want the AP to be open. */
    WiFi.softAP(ssid_ap);

        delay(2000);
    Serial.println("done");
    IPAddress myIP = WiFi.softAPIP();
    Serial.print("AP IP address: ");
    Serial.println(myIP);
    server.on("/", handleRoot);
        server.on("/ok", handleOk);
    server.begin();
    Serial.println("HTTP server started");   
      }   
   
}
void loop() {
  server.handleClient();
  // Перевод модуля в режим конфигурации путем замыкания GPIO0 на массу
  if((digitalRead(0) == LOW) && !conf){
    EEPROM.write(96,255);
    EEPROM.commit();
    EEPROM.end();
    conf = true;
    Serial.println("Please reboot module for coniguration");
  }
}

void handleRoot() {
  String str = "";
  str += html_header;
  str += "<body>\
    <form method=\"POST\" action=\"ok\">\
      <input name=\"ssid\"> WIFI Net</br>\
      <input name=\"pswd\"> Password</br></br>\
      <input type=SUBMIT value=\"Save settings\">\
    </form>\
  </body>\
</html>";
server.send ( 200, "text/html", str );
}

void handleOk(){
  String ssid_ap;
  String pass_ap;
  unsigned char* buf = new unsigned char[64];

  String str = "";
  str += html_header;
  str += "<body>";
 
  EEPROM.begin(98);
 
  ssid_ap = server.arg(0);
  pass_ap = server.arg(1);

  if(ssid_ap != ""){
    EEPROM.write(96,ssid_ap.length());
    EEPROM.write(97,pass_ap.length());
    ssid_ap.getBytes(buf, ssid_ap.length() + 1);
    for(byte i = 0; i < ssid_ap.length(); i++)
      EEPROM.write(i, buf[i]);
    pass_ap.getBytes(buf, pass_ap.length() + 1);
    for(byte i = 0; i < pass_ap.length(); i++)
      EEPROM.write(i + 32, buf[i]);
    EEPROM.commit();
    EEPROM.end();
   
    str +="Configuration saved in FLASH</br>\
    Changes applied after reboot</p></br></br>\
    <a href=\"/\">Return</a> to settings page</br>";
  }
  else {
    str += "No WIFI Net</br>\
    <a href=\"/\">Return</a> to settings page</br>";
  }
  str += "</body></html>";
  server.send ( 200, "text/html", str );
}
 

pvvx

Активный участник сообщества
Дабы не плодить тему, набросал тоже простенькую заготовку сохранения параметров в eeprom.
А собственное питание на RTC провели?
Если дернуть Чип за CH_PD или снять питание 3.3V, то данные из памяти RTC улетают...
Может проще записывать параметры в flash? Всё равно SDK их записывает в flash при любом изменении настроек WiFi и по нескольку раз, протирая дырку в 3-х последних секторах flash (последний сектор стирается и пишется всегда, т.к. в нем контроль предыдущих 2-х секторов со всеми данными для WiFi, даже теми, к которыми вы не имеете доступа в SDK - структура в 888 bytes для SDK 1.2.0).
https://github.com/pvvx/esp8266web/blob/master/app/main/app_main.c#L198
По этому совершенно не ясен смысл дублирования последней конфигурации WiFi в EEPROM.
 
Последнее редактирование:

uvaxut

New member
А собственное питание на RTC провели?
Если дернуть Чип за CH_PD или снять питание 3.3V, то данные из памяти RTC улетают...
Может проще записывать параметры в flash? Всё равно SDK их записывает в flash при любом изменении настроек WiFi и по нескольку раз, протирая дырку в 3-х последних секторах flash (последний сектор стирается и пишется всегда, т.к. в нем контроль предыдущих 2-х секторов со всеми данными для WiFi, даже теми, к которыми вы не имеете доступа в SDK - структура в 888 bytes для SDK 1.2.0).
https://github.com/pvvx/esp8266web/blob/master/app/main/app_main.c#L198
По этому совершенно не ясен смысл дублирования последней конфигурации WiFi в EEPROM.
Не совсем понял сути ответа. После прошивки этого скетча модуль входит в режим настройки, в котором указываются ssid и пароль, которые затем записываются в eeprom. При последующем запуске эти параметры считываются и модуль коннектится к точке доступа, которую ранее указали. Естественно при снятии питания ничего никуда не улетает, в данный момент модуль лежит на столе и все корректно работает. Смысл сохранения в eeprom в том, что это всего лишь заготовка для проекта, а потом, когда все будет сделано, и конечный девайс необходимо будет подключить к любой другой точке, то надо будет лишь зайти в режим настройки и поменять параметры, а не прошивать модуль заново.
Сорри за безграмотность, но что такое RTC ?
 

pvvx

Активный участник сообщества
Не совсем понял сути ответа. После прошивки этого скетча модуль входит в режим настройки, в котором указываются ssid и пароль, которые затем записываются в eeprom. При последующем запуске эти параметры считываются и модуль коннектится к точке доступа, которую ранее указали.
Каким образом "эти параметры считываются и модуль коннектится к точке доступа, которую ранее указали" если было отключено питание или используется ножка CH_PD у модуля? После неё все данные в EEPROM часиков невалидны, если часы в чипе не запитаны от своего источника питания на 1.0..0.8 В к ноге RTC_VCC (разные источники - разное название, а нога номер 5 чипа ESP8266EX и у всех модулей не выведена и никуда не подключена, кроме немецкого модуля).
Потребление по питанию часов (по ноге RTC_VDD)
Сорри за безграмотность, но что такое RTC ?
Real Time Clock - часики, встроенный аппаратный блок в ESP8266 со своей памятью в 1024 байта, называемой EEPROM. Он производит и перезапуск чипа по deep_sleep. Имеет вывод своего питания, когда основное питание чипа отключено.
 
Последнее редактирование:

uvaxut

New member
Модуль подключен так: VCC и CH_PD +3.3в БП, GND к минусу БП, RX, TX к компьютеру. Заливаю прошивку, в режиме АР настраиваю, ОТКЛЮЧАЮ БП, потом заново включаю БП модуль и он (видимо каким-то неведомым образом)
подключается к точке доступа
 

pvvx

Активный участник сообщества
Модуль подключен так: VCC и CH_PD +3.3в БП, GND к минусу БП, RX, TX к компьютеру. Заливаю прошивку, в режиме АР настраиваю, ОТКЛЮЧАЮ БП, потом заново включаю БП модуль и он (видимо каким-то неведомым образом)
подключается к точке доступа
Неведомый образ:
Всё равно SDK их записывает в flash при любом изменении настроек WiFi и по нескольку раз, протирая дырку в 3-х последних секторах flash (последний сектор стирается и пишется всегда, т.к. в нем контроль предыдущих 2-х секторов со всеми данными для WiFi, даже теми, к которыми вы не имеете доступа в SDK - структура в 888 bytes для SDK 1.2.0).
https://github.com/pvvx/esp8266web/blob/master/app/main/app_main.c#L198
По этому совершенно не ясен смысл дублирования последней конфигурации WiFi в EEPROM.
Один раз задав конфигурацию WiFi при следующем старте SDK возьмет её из описанного сохранения.
 

uvaxut

New member
Один раз задав конфигурацию WiFi при следующем старте SDK возьмет её из описанного сохранения.
При первом запуске нет никакой еще конфигурации и модуль не знает куда ему коннектиться. Я не знаю, о чем мы спорим и что кому доказываем, у меня модуль работает, все сохраняется, чтение параметров с eeprom происходит нормально (в консоли видно считанный ssid и пароль).
 

Vitaly

Member
При первом запуске нет никакой еще конфигурации и модуль не знает куда ему коннектиться. Я не знаю, о чем мы спорим и что кому доказываем, у меня модуль работает, все сохраняется, чтение параметров с eeprom происходит нормально (в консоли видно считанный ssid и пароль).
речь похоже о том что eeprom там не во флэш сейчас пишет, а энергозависимую память

надо попробовать настроенный модуль оставить без питания на подольше или сразу "дернуть Чип за CH_PD или снять питание 3.3V"

я попробую, позже
 

pvvx

Активный участник сообщества
речь похоже о том что eeprom там не во флэш сейчас пишет, а энергозависимую память.
Кроме того, конфигурация записанная в SDK применяется при старте до инициализации всего остального, обеспечивая предельную скорость подключения, а не в цикле после инициализации и уже исполнении пользовательского кода. В пользовательском коде уже поздно сравнивать конфиги, можно только назначить новый.
По этому даже если сохранять конфиги WiFi самим в flash, то это будет дубль. Он может быть необходим для частых переключений, чтобы помнить предыдущие настройки или производить переключения по событиям...
 

Vitaly

Member
Кроме того, конфигурация записанная в SDK применяется при старте до инициализации всего остального, обеспечивая предельную скорость подключения, а не в цикле после инициализации и уже исполнении пользовательского кода. В пользовательском коде уже поздно сравнивать конфиги, можно только назначить новый.
По этому даже если сохранять конфиги WiFi самим в flash, то это будет дубль. Он может быть необходим для частых переключений, чтобы помнить предыдущие настройки или производить переключения по событиям...
Лично мне нужны были не только настройки wifi, но и разные настройки по отправке данных и тд

Вопрос с пропаданием настроек очень интересен, пока я такого не наблюдаю.
 

pvvx

Активный участник сообщества
Вопрос с пропаданием настроек очень интересен, пока я такого не наблюдаю.
Потому, что у вас не EEPROM, а flash - используется последний сектор после SPIFFS. Т.е. дублируете настройки с записью в другую область flash.
 

Vitaly

Member
Потому, что у вас не EEPROM, а flash - используется последний сектор после SPIFFS. Т.е. дублируете настройки с записью в другую область flash.
Попробуем подвести итоги - в esp есть еепром в котором без доппитания настройки пропадают. (?) Доступен только при работе через sdk

Пользователей arduinoESP это не волнует потому что библиотека eeprom "использует один сектор во флеш памяти, начиная с адреса 0x7b000 для хранения данных"

Правильно ?
 

pvvx

Активный участник сообщества
Попробуем подвести итоги - в esp есть еепром в котором без доппитания настройки пропадают. (?)
Да.
Доступен только при работе через sdk
Нет - везде. Просто находится в адресном пространстве процессора.

Пользователей arduinoESP это не волнует потому что библиотека eeprom "использует один сектор во флеш памяти, начиная с адреса 0x7b000 для хранения данных"

Правильно ?
Да. И каждая команда EEPROM.commit(); вызывает стирание и запись этого сектора (до дырки :)). Выключение питания в данный момент не спасает от потери всех сохранений в таком EEPROM. + затраты памяти в 4 килобайта под буфер сектора.
+ при линковке внешней физической EEPROM в arduino надо плясать с бубном.
Или попросту - с EEPROM "развели", сделав убогую эмуляцию.
Пользователям arduinoESP это же всё равно :) Главное опубликовать "скетч" :)
 
Последнее редактирование:

Vitaly

Member
Да.
Или попросту - с EEPROM "развели", сделав убогую эмуляцию.
Пользователям arduinoESP это же всё равно :) Главное опубликовать "скетч" :)
Пользователям ардуины надо не забывать, что частое использование такого "eeprom" убивает флэш, так почему бы и нет. Если настройки меняются хорошо если раз в год, а скорее и реже, этой эмуляции более чем.
 

pvvx

Активный участник сообщества
Пользователям ардуины надо не забывать, что частое использование такого "eeprom" убивает флэш, так почему бы и нет. Если настройки меняются хорошо если раз в год, а скорее и реже, этой эмуляции более чем.
Дык вся arduino так и сделана - на попробовать, но не для использования в реальных проектах. Плюс пользователи arduin любят броские названия (типа "скетч") и тут - EEPROM, которые этим не являются. Из чего следует, что главная тема у них - реклама.
Вот я и повелся на ваш обман. Думал, что прилепили хоть память RTС, т.к. её обычно и называли EEPROMпо аналогии встроенной к микросхемам RTC...
 
Последнее редактирование:

uvaxut

New member
pvvx, почему-то мне кажется, что вы не любите пользователей ардуины (это мое сугубо личное ИМХО). Да, Vitaly правильно все объяснил, произошла подмена понятия "eeprom", но тема находится в разделе arduino ide, поэтому уж простите нас, что в этой среде eeprom не является на самом деле таковой. Если программа в среде Arduino IDE называется скетч, то это уж не мы придумали, и уж тем более темы создаются не ради рекламы, а чтобы пригодилось другим. Я читал Ваши темы, и огромный респект Вам за Ваши познания, до которых лично мне еще очень далеко, но не судите нас "ардуинщиков" строго, мы только учимся.
простите за офф.
 

pvvx

Активный участник сообщества
pvvx, почему-то мне кажется, что вы не любите пользователей ардуины (это мое сугубо личное ИМХО). Да, Vitaly правильно все объяснил, произошла подмена понятия "eeprom", но тема находится в разделе arduino ide, поэтому уж простите нас, что в этой среде eeprom не является на самом деле таковой. Если программа в среде Arduino IDE называется скетч, то это уж не мы придумали, и уж тем более темы создаются не ради рекламы, а чтобы пригодилось другим. Я читал Ваши темы, и огромный респект Вам за Ваши познания, до которых лично мне еще очень далеко, но не судите нас "ардуинщиков" строго, мы только учимся.
простите за офф.
Это не в ваш огород, а в писателей Arduino IDE. Плохо сделали эмуль EEPROM, а память часов занята загрузчиком :)
 
Сверху Снизу