Пользует ли кто WiFi-модули ESP8266 ? Поделитесь впечатлениями.

Araris
Offline
Зарегистрирован: 09.11.2012

e3p7j пишет:

Может быть, при использовании UDP таких проблем не будет, не знаю.

Я знаю - будут ))) Пробовал и TCP, и UDP, проблемы те же. Размер пакета - 32 байта, кстати.

dremdem
Offline
Зарегистрирован: 02.03.2015

Araris пишет:

Я знаю - будут ))) Пробовал и TCP, и UDP, проблемы те же. Размер пакета - 32 байта, кстати.

Таки ви хочете сказать шо если я от NTP-сервера по UDP получаю ( а перед этим отправляю ) стандартные 48 байт, то я их не получу или получу не так ?

Araris
Offline
Зарегистрирован: 09.11.2012

dremdem пишет:

Таки ви хочете сказать шо если я от NTP-сервера по UDP получаю ( а перед этим отправляю ) стандартные 48 байт, то я их не получу или получу не так ?

Нет, конечно получите. У меня дома четыре ESP8266 общаются бродкастными UDP-пакетами достаточно стабильно (для меня), но добиться 100%-ной отправки/получения пакетов я не могу (впрочем, уже и не хочу, надоело бороться с проблемами АТ-прошивки). Основной вывод я сделал следующий: чем реже и чем меньше посылаем, тем стабильнее работает.

Кстати, сейчас экспериментирую с LUA на NODEMCU - в общем пока та же фигня.

NEGr
Offline
Зарегистрирован: 12.05.2014

Вот еще какая штука выяснилась: если модуль находится в режиме AT+CIPMUX=0 или если модуль находится в режиме AT+CIPMUX=1  но tcp сервер не поднят, то отправка на web-сервер осуществляется практически без потерь. Иначе отправка происходит стабильно ,но в определенный момент начинают идти одни неудачные попытки.

Может у кого есть мысли на этот счет??

dremdem
Offline
Зарегистрирован: 02.03.2015

Araris пишет:

Нет, конечно получите. У меня дома четыре ESP8266 общаются бродкастными UDP-пакетами достаточно стабильно (для меня)

А вы не можете выложить кусок скетча с отправкой и получением UDP-пакетов ?

Может я что-то делаю не так.

Я уж и побайтно пытался считывать из сериала, и массово, толку ноль.

Коннект с NTP-сервером идет, данные туда отсылаются, а вот на приеме одна и та же слабочитаемая фигня.

Добро бы если фигня изменялась со времем ( надежда на то что я просто ее расшифровать не могу ), но приходит один и тот же мусор.

Вот тут : https://darkbyte.ru/2015/78/esp8266-debrick-after-ciupdate-fatal-exception/ какой-то профи показывает как прошить ESP-05, но я еще не настолько познал безначальное ДАО, чтобы выпаивать флеш-память и программировать ее, а потом обратно запаивать ))

Logik
Offline
Зарегистрирован: 05.08.2014

1.  А кто знает как на прошивке NODEMCU выполнить заливку произвольного файла (ну картинку жапег например) в файловую систему модуля?

2. Порывшись в операторах Lua обнаружил соответствующую команду для компиляции скрипта в байт-код. Не взлетело. Кто пробовал, получилось? Вопрос актуальнейший т.к. байт-код и работает быстрей и места много меньше занимает. 

Araris
Offline
Зарегистрирован: 09.11.2012

dremdem пишет:

А вы не можете выложить кусок скетча с отправкой и получением UDP-пакетов ?

Может я что-то делаю не так.

Я уж и побайтно пытался считывать из сериала, и массово, толку ноль.

Коннект с NTP-сервером идет, данные туда отсылаются, а вот на приеме одна и та же слабочитаемая фигня.

Куски скетча выложу чуть позже.

Насчет NTP, если особых требований к точности нет, то для получения текущей даты/времени можно использовать такой способ: 

1.Посылаете запрос, ну например на www.time.org.

2.Принимаете ответ и находите в нем строку вида "<title>Welcome To The WWW Clock (beta) - Thursday 5th of March 2015 5:45:04 AM GMT</title>"

3.Выпарсиваете из строки все, что нужно.

MaksMS
Offline
Зарегистрирован: 11.03.2013

Тогда проще на любом своем сервере создать скрипт отдачи времени и даты в любом удобном формате.

Такой вариант может и не будет очень точным, но сэкономит ресурсы..

Araris
Offline
Зарегистрирован: 09.11.2012

Вот куски скетча, как видите, ничего особенного для связи по UDP не нужно.





//#define DEBUG 1 
#include <SoftwareSerial.h> 
#define TARGETSSID "Araris"
#define PASS "************" 
String ESPSendString;
String ESPReceivedString; 
boolean ESPConnected = false;
unsigned long ESPLastReceivedTimer = 0;
int ESPSendErrorCounter = 0;
int ESPNumberConnectRetries = 30;
SoftwareSerial ESPSerial(ESP8266_RX,ESP8266_TX); // RX, TX

void setup()
{
ESPSerial.begin(9600);
ESPSerial.setTimeout(3000); 
ESPConnected = ESPRestart();
while ( !ESPConnected ) { delay(600000); ESPConnected = ESPRestart(); } // Next try after 10 minutes 
ESPLastReceivedTimer = millis();
}

void loop()
{
//////////////////// ESP RESTART IF ERRORS
if ( millis() < ESPLastReceivedTimer ) { ESPLastReceivedTimer = millis(); } // millis() overflow
if ( ((millis() - ESPLastReceivedTimer) > 120000) || ( ESPSendErrorCounter >= 5 ) ) 
 { ESPConnected = ESPRestart(); ESPLastReceivedTimer = millis(); }
//////////////////// ESP RECEIVE
ESPReceivedString = "";
if ( ESPSerial.available() ) { ESPReceivedString = ESPReceive(); }
if ( ESPReceivedString != "" )
 {
 #ifdef DEBUG 
 Serial.print("RECEIVED "); 
 Serial.println(ESPReceivedString); 
 #endif

 // ...

 }
}

boolean ESPRestart()
{
ESPSerial.println("AT+RST");
ESPFlushSerial(300);
ESPSerial.println("AT+CSYSWDTENABLE");
ESPFlushSerial(100);
String ESPcmd;
ESPcmd = "AT+CWJAP=\"";
ESPcmd += TARGETSSID;
ESPcmd += "\",\"";
ESPcmd += PASS;
ESPcmd += "\"";
for ( int i = 1; i <= ESPNumberConnectRetries; i++ )
 {
 #ifdef DEBUG
 Serial.println(i);
 #endif 
 ESPSerial.println(ESPcmd);
 delay(3000);
 if ( ESPSerial.find("OK") )
  {
  #ifdef DEBUG
  Serial.println("Connected");
  #endif
  ESPSerial.println("AT+CWMODE=1");
  ESPFlushSerial(100);
  ESPSerial.println("AT+CIPMUX=1");
  ESPFlushSerial(100);
  ESPSerial.println("AT+CIPSERVER=1,48569");
  ESPFlushSerial(100);
  ESPSerial.println("AT+CIPSTO=120");
  ESPFlushSerial(100);
  ESPSerial.println("AT+CIPSTART=4,\"UDP\",\"192.168.0.255\",48569,1112,0");
  ESPFlushSerial(100);
  ESPSendErrorCounter = 0;
  ESPLastReceivedTimer = millis();
  return true;
  }
 } 
#ifdef DEBUG
Serial.println("no connect");
#endif
return false;
}

void ESPFlushSerial(int delaymsec)
{
delay(delaymsec);
while ( ESPSerial.available() ) { ESPSerial.read(); }
}

void ESPSend() // Broadcast ESPSendString
{
if ( !ESPConnected ) return;
if ( ESPSendString == "" ) return;
ESPSerial.print("AT+CIPSEND=4,");
ESPSerial.println(ESPSendString.length());
if ( ESPSerial.find(">") ) { ESPSerial.print(ESPSendString); }
if ( ESPSerial.find("SEND OK") )
 {
 ESPSendErrorCounter = 0;
 #ifdef DEBUG
 Serial.print("SENDED "); Serial.println(ESPSendString); 
 #endif
 }
else
 {
 ESPSendErrorCounter++; 
 #ifdef DEBUG 
 Serial.print("Error="); Serial.println(ESPSendErrorCounter); 
 #endif
 }
} 

String ESPReceive()
{
if ( !ESPConnected ) return "";
String ReceivedString = "";
String TimeString = "";
delay(100);
while (ESPSerial.available())
 {
 char c = ESPSerial.read();
 if ( (c != '\r') && (c != '\n') ) { ReceivedString += c; }
 }
if ( ReceivedString != "" ) { ESPLastReceivedTimer = millis(); }
if ( (ReceivedString != "") && (ReceivedString.indexOf("+IPD,0,") >= 0) ) 
 {
 int pos = ReceivedString.indexOf(":") + 1;
 ReceivedString = ReceivedString.substring(pos);
 pos = ReceivedString.length() - 2;
 ReceivedString = ReceivedString.substring(0,pos);
 }
else { ReceivedString = ""; }
return ReceivedString;
}

 

e3p7j
Offline
Зарегистрирован: 09.01.2015

Araris пишет:

Вот куски скетча, как видите, ничего особенного для связи по UDP не нужно.

А какую модель Arduino Вы используете?

Araris
Offline
Зарегистрирован: 09.11.2012

e3p7j пишет:

А какую модель Arduino Вы используете?

Одна Мега, одна Уно и две Нано. Обмен данными между ними четыремя. Приведенные куски кода у всех одинаковые.

Мега каждые пять секунд отправляет запросы поочередно каждой из трех остальных Ардуин, они отвечают на запросы.

Vладимир
Offline
Зарегистрирован: 27.01.2015
#include <SoftwareSerial.h>
SoftwareSerial wifiSerial(10, 11); // RX, TX // here i tried with 10,11 and 2,3


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

void loop() 

{
 while ( Serial.available()>0 ) 
  { 
    wifiSerial.write(Serial.read()); 
  }

while ( wifiSerial.available()>0 ) 
  { 
     Serial.write(wifiSerial.read());
  }
}  

всем привет.

потратил целый день но так и не смог добится от esp8266-07 (at 020) ответа на АТ команду "AT+RST" , и вывести её в Serial.print

ответ то приходит но я его вижу как стрякозябры , такое чувство что скорость порта не та стоит ,

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

Jon2013
Offline
Зарегистрирован: 18.12.2013

Фатальная ошибка в скетче.

Serial - это аппаратный порт. Он жестко привязан к пинам 10 и 11.

А Вы пытаитесь на него еще и прогамный порт навесить.

Возьмите для SoftwareSerial любые другие 2 пина и к ним подцепите терминал.

Для терминала скорость установите стандартную: 9600.

 

Araris
Offline
Зарегистрирован: 09.11.2012

Jon2013 пишет:

Фатальная ошибка в скетче.

Serial - это аппаратный порт. Он жестко привязан к пинам 10 и 11.

Это что-то новенькое... А не к пинам 0 и 1 часом ?

В случае Меги есть еще "three additional serial ports: Serial1 on pins 19 (RX) and 18 (TX), Serial2 on pins 17 (RX) and 16 (TX), Serial3 on pins 15 (RX) and 14 (TX)."

Также замечу, что SoftwareSerial скоростей выше 19200 не поддерживает.

Vладимир
Offline
Зарегистрирован: 27.01.2015

я на разных пинах пробовал . на связке 2,3 результат токайже

в описании на софтсериал вроде написано скорость до 115200.

а как можно понизить скорость порта в ESP8266 в прошивке AT 20 или AT 21

Araris
Offline
Зарегистрирован: 09.11.2012

Vладимир пишет:

я на разных пинах пробовал . на связке 2,3 результат токайже

в описании на софтсериал вроде написано скорость до 115200.

а как можно понизить скорость порта в ESP8266 в прошивке AT 20 или AT 21

1. Есть немало руководств по началу работы с ESP8266, например http://geektimes.ru/post/241054/

2. Да, написано, написано неверно. На самом деле до 19200. Погуглите, проверьте.

3. Для v0.21 есть команда AT+ UART, почитайте http://esp8266.ru/esp8266-at-commands-v021/

 

Jon2013
Offline
Зарегистрирован: 18.12.2013

Araris пишет:
Это что-то новенькое... А не к пинам 0 и 1 часом ?

В случае Меги есть еще "three additional serial ports: Serial1 on pins 19 (RX) and 18 (TX), Serial2 on pins 17 (RX) and 16 (TX), Serial3 on pins 15 (RX) and 14 (TX)."

Также замечу, что SoftwareSerial скоростей выше 19200 не поддерживает.

Сорри, все так. Что-то у меня переклинило с этими портами.

Vладимир
Offline
Зарегистрирован: 27.01.2015

на 21 прошивке и скорости 9600 заработало .

ответы ok\error\ready приходят нормально

а вот инфа из запрося AT+RST стрякозябрами даже в терминальных прогах )) 

 

Araris
Offline
Зарегистрирован: 09.11.2012

Vладимир пишет:

а вот инфа из запрося AT+RST стрякозябрами даже в терминальных прогах )) 

У меня то же самое, там только в конце есть немного осмысленного текста.

MaksMS
Offline
Зарегистрирован: 11.03.2013

Это сообщение бутлоадера, причем на китайском языке..

Sirocco
Offline
Зарегистрирован: 28.09.2013

А есть уже софт или прошивка\библиотека для ESP8266, которая бы слушала GET запрос и передавала его содержимое в RxTx ?

Araris
Offline
Зарегистрирован: 09.11.2012

Готового решения не видел (искал, есть подобная идея). Прошивка NodeMCU (описание API https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_ru) + язык Lua. Этими инструментами вполне реализуемо.

NEGr
Offline
Зарегистрирован: 12.05.2014

Всем очередной привет.

Хочу поделиться результатами по проблеме отправки данных со связки arduino+esp8266(07) на web server.

Если на esp8266 не поднимать tcp server, то отправка происходит без потерь. Тестировал почти неделю, отправляя данные(показания температуры) раз в минуту.

Для остальных своих устройтв, на которых необходим был tcp server для приема GET запросов от web servera, пришлось делать проверку отправки сообщений и если она неудачна, то производить отправку снова.

Тока мне этот метод не очень нравится)!! Может у кого есть какие-то мысли по поводу, почкему поднятый на esp tcp server влияет на отправку сообщений на web-server. Может быть причина в прошиве? 

MaksMS
Offline
Зарегистрирован: 11.03.2013

Скорее всего в прошивке что-то недоработано.. У меня в проекте esp8266 все работает одновременно и отлично..

NEGr
Offline
Зарегистрирован: 12.05.2014

MaksMS пишет:

Скорее всего в прошивке что-то недоработано.. У меня в проекте esp8266 все работает одновременно и отлично..

а какая у тебя версия прошики?

MaksMS
Offline
Зарегистрирован: 11.03.2013

У меня своя версия прошивки :)

Скорее всего тут такое ограничение накладывается из-за одновременного использования UART..

Dr. Morg
Offline
Зарегистрирован: 17.03.2015

У меня похожая задача,- нужно отправлять данные в GET запросе на сервер, а в ответ получать данные с сервера.

Ни одну неделю уже убил на борьбу с ESP8266 для реализации этого, однако, стабильной работы так добиться и не удалось...

Вот мой скетч:

#include <SoftwareSerial.h>
 
#define SSID "ssid" // введите ваш SSID
#define PASS "pwd" // введите ваш пароль
#define DST_IP "api.myhost.ru" // удалённый хост
SoftwareSerial wifi(11, 12); // RX, TX для отладки

void setup()
{
  Serial.begin(9600);
  //Serial.setTimeout(5000);  
  wifi.begin(9600); // для отладки
  //wifi.setTimeout(5000);
  Serial.println("Init");
  wifi.println("AT+RST"); // сброс и проверка, если модуль готов
  delay(2000);
  if(wifi.find("OK")) {
    Serial.println("WiFi - Module is ready");
  }else{
    Serial.println("Module dosn't respond.");
    while(1);
  }
  delay(1000);
  // try to connect to wifi
  boolean connected=false;
  for(int i=0;i<5;i++){
    if(connectWiFi()){
      connected = true;
      break;
    }
  }
  if (!connected){
    while(1);
  }
  delay(1000);
  wifi.println("AT+CIPMUX=1");
}
void loop()
{
  String data="";
  char readChar;
  String cmd = "AT+CIPSTART=1,\"TCP\",\"";
  cmd += DST_IP;
  cmd += "\",80";
  wifi.println(cmd);
  Serial.println(cmd);
  if(wifi.find("Error")) return;
  delay(1000);
  cmd = "GET /arduino.php?id=1 HTTP/1.1\r\n";
  cmd += "Host: api.myhost.ru:80\r\n";
  cmd += "Connection: Keep-alive\r\n";
  cmd += "User-agent: Espressuino\r\n";
  cmd += "Accept: */*\r\n\r\n";
  wifi.print("AT+CIPSEND=1,");
  Serial.print("AT+CIPSEND=1,");
  wifi.println(cmd.length());
  Serial.println(cmd.length());
  delay(1000);
  if(wifi.find(">")){
    Serial.print(">");
    wifi.print(cmd);
    Serial.println(cmd);
  }else{
    wifi.println("AT+CIPCLOSE=1");
    Serial.println("connection timeout");
    delay(1000);
    return;
  }
    boolean found = 0;
  while (wifi.available()) {
    readChar = (char)wifi.read();
    if (readChar == '!')
    {
      Serial.println("START_CHAR found");  
      found = 1;
    } else if (readChar == '$')
    {
      Serial.println("END_CHAR found");
      break;
    }
    if(found) data += String(readChar);
    Serial.print(readChar);
  }
  data = data.substring(data.indexOf("!")+1);
  Serial.println("data: "+data);
  Serial.println();
  delay(3000);
}
 
boolean connectWiFi()
{
  Serial.println("AT+CWQAP");
  wifi.println("AT+CWQAP");
  delay(1000);
  Serial.println("AT+CWMODE=1");
  wifi.println("AT+CWMODE=1");
  delay(1000);
  String cmd="AT+CWJAP=\"";
  cmd+=SSID;
  cmd+="\",\"";
  cmd+=PASS;
  cmd+="\"";
  Serial.println(cmd);
  wifi.println(cmd);
  delay(2000);
  if(wifi.find("OK")){
    Serial.println("OK, Connected to WiFi.");
    return true;
  }else{
    Serial.println("Can not connect to the WiFi.");
    return false;
  }
}

Если убираю вывод в Serial, то в ответ от сервера всегда тишина, если убираю вроде бы лишние HTTP заголовки, запрос GET не выполняется, сервер отдаёт 400 ошибку.

В текущем виде схема работает не стабильно,- периодически от сервера приходят пустые ответы.

Кто-то использует подобную схему обмена данными с сервером? Удалось получить стабильный результат?

Прошивки перебрал все доступные, на 0.9.2.2 (ESP_8266_v0.9.2.2 AT Firmware.bin) работает менее стабильно, но зато стабилизатор 1117 греется терпимо, на 0.9.5.0 (AT21SDK95-2015-01-24.bin) стабилизатор в момент обмена данными греется градусов до 80...

Araris
Offline
Зарегистрирован: 09.11.2012

Dr. Morg пишет:

У меня похожая задача,- нужно отправлять данные в GET запросе на сервер, а в ответ получать данные с сервера.

А как у Вас с размерами буферов UART (SERIAL_BUFFER_SIZE) для Hardware/Software Serial ? String cmd немаленькая ведь получается.

Dr. Morg
Offline
Зарегистрирован: 17.03.2015

HardwareSerial буферы увеличены до 256

\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h

#if !(defined(SERIAL_TX_BUFFER_SIZE) && defined(SERIAL_RX_BUFFER_SIZE))
#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 16
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 256
#define SERIAL_RX_BUFFER_SIZE 256
#endif
#endif

У SoftwareSerial буфер был 64, забыл про него совсем...

Увеличил до 256, буду тестить

\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.h

#define _SS_MAX_RX_BUFF 256 // RX buffer size

 

Dr. Morg
Offline
Зарегистрирован: 17.03.2015

Увеличение буфера проблему не решило,- по-прежнему если не дублировать команды в Serial, то от сервера ответов нет, если же дублировать, то  иногда даже работает, но постоянно присутствует мусор и обрезанное эхо запроса, а иногда данные с сервера так и не доходят:

Init
WiFi - Module is ready
AT+CWQAP
AT+CWMODE=1
AT+CWJAP="ssid","pwd"
OK, Connected to WiFi.
AT+CIPSTART="TCP","api.myhost.ru",80
AT+CIPSEND=121
connection timeout
AT+CIPSTART="TCP","api.myhost.ru",80
AT+CIPSEND=121
>GET /arduino.php?id=1 HTTP/1.1
Host: api.myhost.ru:80
Connection: Keep-alive
User-agent: Espressuino
Accept: */*


 GЁЃ
Ґ‚JХ	Љ“¦R]'
БҐ№myhost.ru:80
Connection: Keep-alive
User-essuino
Accept: */*


SEND OK

+IPD,204:HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Tue, 17 Mar 2015 06:47:43 GMT
Content-Type: text/plain
Content-Length: 28
Connection: keep-alive
X-Powered-By: PHP/5.3.29

п»їSTART_CHAR found
!1426072321,104,36,134,20,0END_CHAR found
data: 1426072321,104,36,134,20,0

AT+CIPSTART="TCP","api.myhost.ru",80
AT+CIPSEND=121
>GET /arduino.php?id=1 HTTP/1.1
Host: api.myhost.ru:80
Connection: Keep-alive
User-agent: Espressuino
Accept: */*


 GЁЃ
Ґ‚JХ	Љ“¦R]'
БҐ№myhost.ru:80
Connection: Keep-alive
User-essuino
Accept: */*


SEND OK

+IPD,204:HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Tue, 17 Mar 2015 06:50:28 GMT
Content-Type: text/plain
Content-Length: 28
Connection: keep-alive
X-Powered-By: PHP/5.3.29

п»їSTART_CHAR found
!1426072321,104,36,134,20,0END_CHAR found
data: 1426072321,104,36,134,20,0

AT+CIPSTART="TCP","api.myhost.ru",80
AT+CIPSEND=121
>GET /arduino.php?id=1 HTTP/1.1
Host: api.myhost.ru:80
Connection: Keep-alive
User-agent: Espressuino
Accept: */*


 GЁЃ
Ґ‚JХ	Љ“¦R]'
БҐ№myhost.ru:80
Connection: Keep-alive
User-essuino
Accept: */*


SEND OK
data: 

Самая мистика в том, что без Serial.println(cmd);  и Serial.print(readChar); вообще данные с сервера не получает...

Модифицировал скетч, так стало постабильнее данные возвращать:

#include <SoftwareSerial.h>
 
#define SSID "ssid" // введите ваш SSID
#define PASS "pwd" // введите ваш пароль
#define DST_IP "api.myhost.ru" // удалённый хост
SoftwareSerial wifi(11, 12); // RX, TX для отладки

void setup()
{
  Serial.begin(9600);
  //Serial.setTimeout(5000);  
  wifi.begin(9600); // для отладки
  //wifi.setTimeout(5000);
  Serial.println("Init");
  wifi.println("AT+RST"); // сброс и проверка, если модуль готов
  delay(2000);
  if(wifi.find("OK")) {
    Serial.println("WiFi - Module is ready");
  }else{
    Serial.println("Module dosn't respond.");
    while(1);
  }
  delay(1000);
  // try to connect to wifi
  boolean connected=false;
  for(int i=0;i<5;i++){
    if(connectWiFi()){
      connected = true;
      break;
    }
  }
  if (!connected){
    while(1);
  }
  delay(1000);
  wifi.println("AT+CIPMUX=0"); // установка в режим одиночного соединения
}
void loop()
{
  String data="";
  char readChar;
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += DST_IP;
  cmd += "\",80";
  wifi.println(cmd);  
  if(wifi.find("Error")) return;
  Serial.println(cmd);
  delay(1000);
  cmd = "GET /arduino.php?id=1 HTTP/1.1\r\n";
  cmd += "Host: api.myhost.ru:80\r\n";
  cmd += "Connection: Keep-alive\r\n";
  cmd += "User-agent: Espressuino\r\n";
  cmd += "Accept: */*\r\n\r\n";
  wifi.print("AT+CIPSEND=");  
  wifi.println(cmd.length());
  Serial.print("AT+CIPSEND=");
  Serial.println(cmd.length());
  delay(1000);
  if(wifi.find(">")){
    Serial.print(">");
    wifi.print("GET /arduino.php?id=1 HTTP/1.1\r\n");
    wifi.print("Host: api.myhost.ru:80\r\n");
    wifi.print("Connection: Keep-alive\r\n");
    wifi.print("User-agent: Espressuino\r\n");
    wifi.print("Accept: */*\r\n\r\n");
    wifi.flush();
    Serial.println(cmd);    
    cmd="";
  }else{
    wifi.println("AT+CIPCLOSE");
    Serial.println("connection timeout");
    delay(1000);    
    return;
  }
    boolean found = 0;
  while (wifi.available()) {
    readChar = (char)wifi.read();
    if (readChar == '!')
    {
      Serial.println("START_CHAR found");  
      found = 1;
    } else if (readChar == '$')
    {
      Serial.println("END_CHAR found");
      break;
    }
    if(found) data += String(readChar);
    Serial.print(readChar);
  }
  data = data.substring(data.indexOf("!")+1);
  Serial.println("data: "+data);
  wifi.flush();
  Serial.println();
  delay(3000);
}
 
boolean connectWiFi()
{
  Serial.println("AT+CWQAP");
  wifi.println("AT+CWQAP");
  delay(1000);
  Serial.println("AT+CWMODE=1");
  wifi.println("AT+CWMODE=1");
  delay(1000);
  String cmd="AT+CWJAP=\"";
  cmd+=SSID;
  cmd+="\",\"";
  cmd+=PASS;
  cmd+="\"";
  Serial.println(cmd);
  wifi.println(cmd);
  delay(2000);
  if(wifi.find("OK")){
    Serial.println("OK, Connected to WiFi.");
    return true;
  }else{
    Serial.println("Can not connect to the WiFi.");
    return false;
  }
}

 

Araris
Offline
Зарегистрирован: 09.11.2012

Загадочная зависимость от Serial, возможно, связана с тем, что ESP не всегда успевает ответить, а вывод в Serial дает ему необходимую задержку.Еще неплохо бы для контроля добавить после отправки (после строки 67)  if ( wifi.find("SEND OK") ).

Далее, если сработало while (wifi.available()) - это не значит, что в приемном буфере уже находятся ВСЕ принятые данные. Дайте задержку, пусть ESP успеет до конца принять.

ESP не настолько быстр, работайте с ним не торопясь )). Команда "AT+CIPSEND" во всех АТ-прошивках имеет немалые проблемы, об этом немало написано. Так что особо не удивляйтесь трудностям.

Кстати, строка 58 явно лишняя, почитайте про Serial.find()

Dr. Morg
Offline
Зарегистрирован: 17.03.2015

За счёт избавления от длинной строки и замены её размером постоянной части заголовков и размером добавляемой переменной удалось сэкономить 86 байт бинарного кода (строка 53):

unsigned int len = 127 + data_ok.length();

За счёт ввода дополнительного символа ("%") в данные, для отсечения возвращяемых сервером заголовков, удалось оставить размер RX буфера SoftwareSerial в размере 64 байт (строка 87):

if(wifi.find("%")){

Это позволило сэкономить 192 байта ОЗУ по сравнению с RX буфером 256 байт или 448 байт экономии при размере буфера 512 байт.

На протяжении 2,5 часов беспрерывной работы по отправке/получению данных 1 раз в 8 секунд не выявлено ни одного (!!!) сбоя!

Код требует ещё доработки для отлова зависания модуля, пропадания сети, хардресета в случае неудачного пуска, но уже юзабелен по сравнению с тем, что было ранее.

Прошивка 0.9.5 (AT21SDK95-2015-01-24.bin), скорость 9600, SoftwareSerial, питание от Arduino Uno.

Код скетча:

#include <SoftwareSerial.h>

#define SSID "ssid" // введите ваш SSID
#define PASS "pwd" // введите ваш пароль
#define DST_IP "api.myhost.ru" // удалённый хост
SoftwareSerial wifi(11, 12); // RX, TX для отладки

String data_ok = "";

void setup()
{
  Serial.begin(9600);
  //Serial.setTimeout(5000);  
  wifi.begin(9600); // для отладки
  //wifi.setTimeout(5000);
  Serial.println("Init");
  wifi.println("AT+RST"); // сброс и проверка, если модуль готов
  //delay(2000);
  if(wifi.find("OK")) {
    Serial.println("WiFi - Module is ready");
  }else{
    Serial.println("Module dosn't respond.");
    // добавить HardReset модуля 
    while(1);
  }
  delay(1000);
  // try to connect to wifi
  boolean connected=false;
  for(int i=0;i<5;i++){
    if(connectWiFi()){
      connected = true;
      break;
    }
  }
  if (!connected){
    while(1);
  }
  delay(1000);
  wifi.println("AT+CIPMUX=0"); // установка в режим одиночного соединения
}

void loop()
{
  String data="";
  char readChar;
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += DST_IP;
  cmd += "\",80";
  wifi.println(cmd);  
  if(wifi.find("Error")) return;
  Serial.println(cmd);
  delay(1000);
  unsigned int len = 127 + data_ok.length();
  //cmd = "GET /arduino.php?id=1&data="+data_ok+" HTTP/1.1\r\n";
  //cmd += "Host: api.myhost.ru:80\r\n";
  //cmd += "Connection: Keep-alive\r\n";
  //cmd += "User-agent: Espressuino\r\n";
  //cmd += "Accept: */*\r\n\r\n";
  wifi.print("AT+CIPSEND=");  
  wifi.println(len); //cmd.length()
  if(wifi.find("OK")) {
    Serial.print("AT+CIPSEND=");
    Serial.println(len); //cmd.length()
  }else{
    Serial.println("Error send content length!");
    return;
  }
  if(wifi.find(">")){
    //Serial.print(">");
    wifi.print("GET /arduino.php?id=1&data=");
    wifi.print(data_ok+" HTTP/1.1\r\n");
    wifi.print("Host: api.myhost.ru:80\r\n");
    wifi.print("Connection: Keep-alive\r\n");
    wifi.print("User-agent: Espressuino\r\n");
    wifi.print("Accept: */*\r\n\r\n");
    wifi.flush();
    //Serial.println(cmd);
    cmd="";    
  }else{
    wifi.println("AT+CIPCLOSE");
    Serial.println("connection timeout");
    delay(1000);    
    return;
  }  
  if(wifi.find("SEND OK")){  
    boolean found = 0;
    if(wifi.find("%")){
      delay(2000);
      while (wifi.available()) {      
        readChar = (char)wifi.read();
        if (readChar == '!')
        {
          //Serial.println("START_CHAR found");  
          found = 1;
        } else if (readChar == '$')
        {
          //Serial.println("END_CHAR found");
          break;
        }
        if(found) data += String(readChar);
        //Serial.print(readChar);
      }
      data_ok = data.substring(data.indexOf("!")+1);
      Serial.println();
      Serial.println("data: "+data_ok);
      wifi.flush();
      Serial.println();
    }
  }
delay(3000);  
}
 
boolean connectWiFi()
{
  Serial.println("AT+CWQAP");
  wifi.println("AT+CWQAP");
  delay(1000);
  Serial.println("AT+CWMODE=1");
  wifi.println("AT+CWMODE=1");
  delay(1000);
  String cmd="AT+CWJAP=\"";
  cmd+=SSID;
  cmd+="\",\"";
  cmd+=PASS;
  cmd+="\"";
  Serial.println(cmd);
  wifi.println(cmd);
  delay(2000);
  if(wifi.find("OK")){
    Serial.println("OK, Connected to WiFi.");
    return true;
  }else{
    Serial.println("Can not connect to the WiFi.");
    return false;
  }
}

 

Dr. Morg
Offline
Зарегистрирован: 17.03.2015

Araris пишет:

Загадочная зависимость от Serial, возможно, связана с тем, что ESP не всегда успевает ответить, а вывод в Serial дает ему необходимую задержку.Еще неплохо бы для контроля добавить после отправки (после строки 67)  if ( wifi.find("SEND OK") ).

/* вырезано */

Спасибо за свежие мысли, они очень пригодились в устранении нестабильной работы модуля!

А ведь я уже хотел забросить это неблагодарное дело и уйти на Ethernet Shield :)

Araris
Offline
Зарегистрирован: 09.11.2012

Никуда не уходите, у ESP8266 большой потенциал (и пока еще сырой SDK).

Dr. Morg
Offline
Зарегистрирован: 17.03.2015

Araris пишет:

Никуда не уходите, у ESP8266 большой потенциал (и пока еще сырой SDK).

Не ухожу :)

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

 

IKIF
Offline
Зарегистрирован: 06.03.2015

День добрый,
Я вижу что эта вифи карточка вызывает некий ажиотаж.
Как я понял , подключается свего по 2 dig пинам к ардуино.
Какие у нее минусы/проблемы/недостатки/ограничения ?

 

Хочу в конечном итоге по вифи подключаться к ардуино с компа/смарфона , видеть состояние (освещение и мощьность освещения, температуру,... ) , а так же менять это всё....

 

 

 

Araris
Offline
Зарегистрирован: 09.11.2012

IKIF, более конкретный вопрос получит больше ответов.

Dr. Morg
Offline
Зарегистрирован: 17.03.2015

Araris пишет:

Никуда не уходите, у ESP8266 большой потенциал (и пока еще сырой SDK).

Всё-таки рано оказалось в продакшн его...

С таймаутом SoftwareSerial в 2000мс наблюдается следующая картина:

AT+CIPSTART="TCP","api.myhost.ru",80
Error establishing TCP connection!
AT+CIPSTART="TCP","api.myhost.ru",80
Error establishing TCP connection!
AT+CIPSTART="TCP","api.myhost.ru",80
Error establishing TCP connection!
AT+CIPSTART="TCP","api.myhost.ru",80
Error establishing TCP connection!
AT+CIPSTART="TCP","api.myhost.ru",80
AT+CIPSEND=144

data: 104,36,134,20,0,0
TargTemp: 104
Pval: 36
Ival: 134
Dval: 20
HeaterState: 0
HeaterOnOff: 0

AT+CIPSTART="TCP","api.myhost.ru",80
Error establishing TCP connection!
AT+CIPSTART="TCP","api.myhost.ru",80
Error establishing TCP connection!
AT+CIPSTART="TCP","api.myhost.ru",80
Error establishing TCP connection!
AT+CIPSTART="TCP","api.myhost.ru",80
Error establishing TCP connection!
AT+CIPSTART="TCP","api.myhost.ru",80
AT+CIPSEND=144

data: 104,36,134,20,0,0
TargTemp: 104
Pval: 36
Ival: 134
Dval: 20
HeaterState: 0
HeaterOnOff: 0

С увеличением таймаута до 5000мс, количество ошибок установления соединения падает до 2, на 3 попытке соединение устанавливается, но общее время между результативными попытками больше, чем при таймауте 2000мс и 4 ошибках.

Код немного модифицирован по сравнение с ранее опубликованным:

#include <SoftwareSerial.h>

#define SSID "ssid" // введите ваш SSID
#define PASS "pwd" // введите ваш пароль
#define DST_IP "api.myhost.ru" // удалённый хост
SoftwareSerial wifi(11, 12); // RX, TX для ESP8266

String data_ok = "";

void setup()
{
  Serial.begin(9600);
  //Serial.setTimeout(5000);  
  wifi.begin(9600); 
  wifi.setTimeout(2000);
  Serial.println("Init");
  wifi.println("AT+RST"); 
  //delay(2000);
  if(wifi.find("OK")) {
    Serial.println("WiFi - Module is ready");
  }else{
    Serial.println("Module dosn't respond.");
    //while(1);
    return;
  }
  //delay(1000);
  // try to connect to wifi
  boolean connected=false;
  for(int i=0;i<5;i++) {
    if(connectWiFi()) {
      connected = true;
      break;
    }
  }
  if (!connected) {
    while(1);
    //return;
  }
  //delay(1000);
  wifi.println("AT+CIPMUX=0");
}

void loop()
{
  String data="";
  char readChar;
  String cmd = "AT+CIPSTART=\"TCP\",\"";
  cmd += DST_IP;
  cmd += "\",80";
  wifi.println(cmd);  
  //if(wifi.find("Error")) return;
  Serial.println(cmd);
  //delay(1000);
  unsigned int len = 127 + data_ok.length();
  //cmd = "GET /arduino.php?id=1&data="+data_ok+" HTTP/1.1\r\n";
  //cmd += "Host: api.myhost.ru:80\r\n";
  //cmd += "Connection: Keep-alive\r\n";
  //cmd += "User-agent: Espressuino\r\n";
  //cmd += "Accept: */*\r\n\r\n";
  if(wifi.find("OK")) {
    wifi.print("AT+CIPSEND=");  
    wifi.println(len); //cmd.length()
  }else{
    Serial.println("Error establishing TCP connection!");
    return;
  }
  if(wifi.find("OK")) {
    Serial.print("AT+CIPSEND=");
    Serial.println(len); //cmd.length()
  }else{
    Serial.println("Error send content length!");
    return;
  }
  if(wifi.find(">")) {
    //Serial.print(">");
    wifi.print("GET /arduino.php?id=1&data=");
    wifi.print(data_ok+" HTTP/1.1\r\n");
    wifi.print("Host: api.myhost.ru:80\r\n");
    wifi.print("Connection: Keep-alive\r\n");
    wifi.print("User-agent: Espressuino\r\n");
    wifi.print("Accept: */*\r\n\r\n");
    wifi.flush();
    //Serial.println(cmd);
    cmd="";    
  } else {
    wifi.println("AT+CIPCLOSE");
    Serial.println("Connection timeout!");
    //delay(1000);    
    return;
  }  
  if(wifi.find("SEND OK")) {
    boolean found = 0;
    if(wifi.find("%")) {
      delay(2000); // ожидаем данные в RX буфере
      while (wifi.available()) {      
        readChar = (char)wifi.read();
        if (readChar == '!') {
          //Serial.println("START_CHAR found");  
          found = 1;
        } else if (readChar == '$') {
          //Serial.println("END_CHAR found");
          break;
        }
        if(found) data += String(readChar);
        //Serial.print(readChar);
      }
      data_ok = data.substring(data.indexOf("!")+1);
      //long timestamp = data_ok.substring(0,data.indexOf(",")).toInt();
      //data = data_ok.substring(data_ok.indexOf(",")+1);
      //int TargTemp = data.substring(0,data.indexOf(",")).toInt();
      int TargTemp = data_ok.substring(0,data.indexOf(",")).toInt();
      data = data.substring(data.indexOf(",")+1);
      int Pval = data.substring(0,data.indexOf(",")).toInt();
      data = data.substring(data.indexOf(",")+1);
      int Ival = data.substring(0,data.indexOf(",")).toInt();
      data = data.substring(data.indexOf(",")+1);
      int Dval = data.substring(0,data.indexOf(",")).toInt();
      data = data.substring(data.indexOf(",")+1);
      int HeaterState = data.substring(0,data.indexOf(",")).toInt();
      data = data.substring(data.indexOf(",")+1);
      boolean HeaterOnOff = data.substring(0,data.indexOf(",")).toInt();
      Serial.println();
      Serial.println("data: "+data_ok);
      //Serial.print("timestamp: "); Serial.println(timestamp);
      Serial.print("TargTemp: "); Serial.println(TargTemp);
      Serial.print("Pval: "); Serial.println(Pval);
      Serial.print("Ival: "); Serial.println(Ival);
      Serial.print("Dval: "); Serial.println(Dval);
      Serial.print("HeaterState: "); Serial.println(HeaterState);
      Serial.print("HeaterOnOff: "); Serial.println(HeaterOnOff);
      wifi.flush();
      Serial.println();
    }
  }
//delay(60000);
}
 
boolean connectWiFi()
{
  Serial.println("AT+CWQAP");
  wifi.println("AT+CWQAP");
  //delay(1000);
  if(wifi.find("OK")) {
    Serial.println("AT+CWMODE=1");
    wifi.println("AT+CWMODE=1");
  }
  //delay(1000);
  String cmd="AT+CWJAP=\"";
  cmd+=SSID;
  cmd+="\",\"";
  cmd+=PASS;
  cmd+="\"";
  if(wifi.find("OK")) {
    Serial.println(cmd);
    wifi.println(cmd);
  }
  //delay(2000);
  if(wifi.find("OK")) {
    Serial.println("OK, Connected to WiFi.");
    return true;
  } else {
    Serial.println("Can not connect to the WiFi.");
    return false;
  }
}

И самое неприятное, что на работе с Linksys E4200 всё вроде бы более или менее стабильно работает, а дома с Apple AirPort Express начинаются ошибки соединения. Причём если подключаюсь к ESP8266 напрямую и отправляю АТ команды вручную, то в 99% проблем не наблюдаю. Иногда вылезает DNS Fail при AT+CIPSTART

Araris
Offline
Зарегистрирован: 09.11.2012

Вышел ESP8266 IoT SDK v1.0.0 AT v0.22

 Читаем http://esp8266.ru/esp8266-iot-sdk-v1-0-0-at-v0-22/

 

DamirX
Offline
Зарегистрирован: 13.03.2015

Всем салют!

Вот, есть кое-какая документация

https://drive.google.com/folderview?id=0BwK3EhAfht8uWTdBdG55NEFCakE&usp=...

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Подключил 07, хватило GPIO15 на землю и CH_PD на VCC, через 10K, внешнее питание 3.3В и к компу через USB-TTL на CP2102. Пашет, перешил на SDK v1.0.0 AT v0.22. В сети появился, со смарта подключился нормально. Сначала накосячил, вместо GPIO15 подключал GPIO5 :) Не работало.
Пока больше ничего не тестил.
Теперь можно поиграться :)

Araris
Offline
Зарегистрирован: 09.11.2012

kisoft пишет:
CH_PD на VCC через 10K

Осмелюсь утверждать, что 10K - необязательно.

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Вышла Ардуино ИДЕ с поддержкой субьекта....

http://hackaday.com/2015/03/28/arduino-ide-support-for-the-esp8266/

dremdem
Offline
Зарегистрирован: 02.03.2015

trembo пишет:

Вышла Ардуино ИДЕ с поддержкой субьекта....

http://hackaday.com/2015/03/28/arduino-ide-support-for-the-esp8266/

 

Я правильно понял, что теперь можно шить с помощью ардуины и заливать туда ( в ESP8266 ) скетчи ?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Araris пишет:

kisoft пишет:
CH_PD на VCC через 10K

Осмелюсь утверждать, что 10K - необязательно.


Я понимаю, что это вход, потому пофиг на резистор. Однако для игр можно через кнопку на землю. Я вчера так игрался, чтобы питание не передергивать.
Плюс сделал по аналогии с другими пинами, что бы не париться.

Araris
Offline
Зарегистрирован: 09.11.2012

dremdem пишет:

Я правильно понял, что теперь можно шить с помощью ардуины и заливать туда ( в ESP8266 ) скетчи ?

Поняли правильно, можно, но есть нюансы. Проект новый, весьма сырой и до ума еще не доведенный. Подробности - http://www.arduinesp.com/ , http://esp8266.ru/arduino-ide-esp8266/

Araris
Offline
Зарегистрирован: 09.11.2012

Что-то разактивилась тема, подниму пожалуй.

Статья "Многофункциональный датчик температуры/влажности на ESP8266 или еще один шаг к «интернету вещей»". На базе прошивки NodeMCU.

Здесь: http://habrahabr.ru/post/255359/

MikSer
Offline
Зарегистрирован: 27.01.2012

Хорошая обертка + поддержка АТ 0.22 https://github.com/itead/ITEADLIB_Arduino_WeeESP8266

wgaint
Offline
Зарегистрирован: 15.03.2015

Не могу получить от esp8266 числа.

Есть домашний сервер на денвере, простая страница UTF8 которая отвечает на GET запрос числовыми значениями: время, температура.

Не могу распарсить ответ (перевести в числа int).

Учебный пример работает:

/*
* malloc-free JSON parser for Arduino
* Benoit Blanchon 2014 - MIT License
*/

#include <JsonParser.h>

void ParseAnObject()
{
    char json[] = "{\"temp\":200,\"timer\":120}"; // Эту строку отдает php с сервера

    JsonParser<32> parser;

    Serial.print("Parse ");
    Serial.println(json);

    JsonHashTable hashTable = parser.parseHashTable(json);

    if (!hashTable.success())
    {
        Serial.println("JsonParser.parseHashTable() failed");
        return;
    }

  int timer = hashTable.getLong("timer");
    Serial.print("timer=");
    Serial.println(timer);   
    
    int temp = hashTable.getLong("temp");
    Serial.print("temp=");
    Serial.println(temp);
  //выводит правильно
}

void setup()
{
    Serial.begin(9600);
}

void loop()
{delay(2000);
 ParseAnObject();
}

А вот в связке с ESP получаю нулевые значения:

char json[40] = "{"; //Длинна массива не известна заранее, строка начнется "key{"
int temp ;
int timer; 

//подключение и запрос к серверу опущу

unsigned int i = 0; //счетчик времени
  int n = 1; // счетчик символов
  
          while (!Serial1.find("key{")){} //вход в строку
          while (i<5000) { //опрос в течении 5000 циклов
                          if(Serial1.available()) {
                            char c = Serial1.read(); //читаем строку
                            json[n]=c; //заполняем массив
                            if(c=='}') {n++;  json [n] = '\0';   break;} //конец массива
                            n++;
                            i=0; }
            i++;
          }
          
     Serial.println(json);
//Тут я вижу правильный результат, нужную строку
     JsonParser<32> parser;
      JsonHashTable hashTable = parser.parseHashTable(json);
             if (!hashTable.success())
              {
                  Serial.println("JsonParser.parseHashTable() failed");
                  return;
              }
    timer = hashTable.getLong("timer");
    Serial.print("timer=");
    Serial.println(timer);
    
    temp = hashTable.getLong("temp");
    Serial.print("temp=");
    Serial.println(temp);

//А тут выводит нулевые значения.

Куда еще поковырять? Длинна массива json? Кодировка?

 

 

semenov2009
Offline
Зарегистрирован: 05.08.2014

Может и не надо уже - но отвечу на вопрос о синхронизации времени с NTP через esp8266.

Работа с esp8266 идет без библиотек, только с помощью AT-команд.

Все пашет, время приходит всегда.  

Ниже - вырезка из основной программы настенных часов, только то, что отностится к синхронизации по NTP.

/*
Настенные часы на семисегментных индикаторах GNS23011

Модуль управления - Arduino Pro Mini 3V 8MHz
Часы - DS3231 в виде готового модуля с резервным аккумулятором
Модуль ESP8266 для получения времени с NTP через WiFi

*/

#define ISDEBUG // Мы в отладке

#include <SPI.h>         
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"
#include <DS1307RTC.h>
#include <Time.h>
#include <Wire.h>
#include <BMP180.h>
#include <Metro.h>
#include <SoftwareSerial.h>


// For NTP & ESP8266
SoftwareSerial mySerial(16, 17); // A2 - RX, A3 - TX
unsigned long started=0; 
uint32_t out=0; 
time_t NTPtime=0;
//tmElements_t tm;
int c0, lenght=0;
const unsigned long seventyYears = 2208988800UL;     
const unsigned long LocalTimeZone = 10800UL;  // GMT+3   
const int NTP_PACKET_SIZE= 48; // NTP time stamp is in the first 48 bytes of the message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets 
// Сервер WWW.BELGIM.BY 178.124.164.107

time_t lastNTPtime = 0; // время получения времени от NTP

/////////////////////////////////////////////////////////////////////////////
// Периодичность действий
#ifdef ISDEBUG  
Metro NTPTimeSync = Metro(900000); //Если отладка - период синхронизации RTC по NTP 15 минут
#endif
#ifndef ISDEBUG  
Metro NTPTimeSync = Metro(14400000); //Период синхронизации RTC по NTP (4 часа)
#endif
Metro ReadRTCtime_period = Metro(600000); //Период чтения значений из RTC (10 минут)
Metro Trans_period = Metro(180000); //Период отправки данных (3 минуты)
Metro PIR_period = Metro(1000); //Период опроса PIR (1 секунда)

unsigned long PreviousClockTime, i; 
boolean dotsEnable=true; 

tmElements_t tm;

void setup() {


  mySerial.begin(9600);

  
  setTime(RTC.get()) ; //установим системное время из часов ds1307
#ifdef ISDEBUG
  Serial.println("RTC reading OK");
  PrintTime (now());
#endif
   ShowRTC(); // Отобразим время
   //Запрашиваем время с NTP сервера
#ifdef ISDEBUG  
   Serial.println("Request for NTP ..."); 
#endif    
     GetNTP_esp8266(); // 
     //Если время получили успешно, то записываем данные в RTC
     if (NTPtime!=0) 
        {
          setTime(NTPtime); 
          RTC.set(now());
          lastNTPtime=NTPtime;
#ifdef ISDEBUG
          Serial.println("NTP updated OK!");
          PrintTime (now());
#endif
        }
   ShowRTC();  
} //end of setup
 
void loop() {
if (ReadRTCtime_period.check() == 1)
   {
     setTime(RTC.get()) ; //установим системное время из часов ds3231
#ifdef ISDEBUG
  Serial.println("RTC reading OK");
  PrintTime (now());
#endif
   }
   
#ifdef ISDEBUG
//  PrintTime (now());
#endif
  if (NTPTimeSync.check() == 1) //Синхронизация по времени
     {
     ShowRTC(); // Для начала - отобразим время
     //Запрашиваем время с NTP сервера
#ifdef ISDEBUG  
    Serial.println("Request for NTP ..."); 
#endif    
     GetNTP_esp8266(); // секунд около 40
     //Если время получили успешно, то записываем данные в RTC
     if (NTPtime!=0) 
        {
          setTime(NTPtime); 
          RTC.set(now());
          lastNTPtime=NTPtime;
#ifdef ISDEBUG
          Serial.println("NTP updated OK!");
          PrintTime (now());
#endif
        }
     ShowRTC();  
     }  
  
    ShowRTC();
    dotsEnable=true;
    PreviousClockTime = millis(); 
    i=1;
    while (abs(millis()-PreviousClockTime) < 20000) // 20 секунд крутим цикл
           { 
            if ( (abs(millis()-PreviousClockTime)) >= (i*1000)) 
                 {dotsEnable=!dotsEnable; 
                  ShowRTC();
                  if (!dotsEnable) {analogWrite(dotsPin, 0);}
                  i++;
                 };
            checkClockButtons();//обработка нажатий кнопок установки часов
            if (PIR_period.check() == 1) {checkPIR();} //обработка срабатывания датчика движения    
           };  

} //loop


// ФУНКЦИИ ДЛЯ ЧАСОВ
void ShowRTC()
{
#ifdef ISDEBUG
  Serial.println("Show RTC ...");
#endif
    SetBrightness();
    analogWrite(dotsPin, dots);
    RTC.read(tm);
    IntToDigits (tm.Hour);     
    if (tm.Hour < 10) { d1=11; } 
    digit1 = SegmentValue (d1);
    digit2 = Digit1toDigit2 (SegmentValue (d2));
    IntToDigits (tm.Minute);
    digit3 = SegmentValue (d1);
    digit4 = Digit1toDigit2 (SegmentValue (d2));
    ShowInfo();
#ifdef ISDEBUG
//    PrintTime(RTC.get());
    Serial.print("Hour = ");
    Serial.print(tm.Hour);
    Serial.print("  Minute = ");
    Serial.println(tm.Minute);
#endif
} 



time_t GetNTP_esp8266()
{
  NTPtime=0;
  mySerial.println("AT+RST");
  delay(1000);
  mySerial.println("AT+CWMODE=1");
  delay(2000);

#ifdef ISDEBUG
  Serial.println("Connect to my AP");
#endif
  mySerial.println("AT+CWJAP=\"MY_AP_NAME\",\"PASSWORD\""); // \"  - так передается двойная кавычка внутри двойных кавычек 
  delay(8000);
  setNTPpacketBuffer();

#ifdef ISDEBUG
  Serial.println("Connect to NTP");
#endif
  mySerial.println("AT+CIPSTART=\"UDP\",\"178.124.164.107\",123,34000");
  delay(5000);

#ifdef ISDEBUG
  Serial.println("Send lenght 48 bytes");
#endif
  mySerial.println("AT+CIPSEND=48");
  delay(4000);
  while ( mySerial.available()) mySerial.read();
//  delay(100);
 
#ifdef ISDEBUG
  Serial.println("Send NTP packet ");
#endif
  for (int i=0; i<NTP_PACKET_SIZE; i++) {mySerial.write(packetBuffer[i]); }
#ifdef ISDEBUG
  Serial.println("NTP packet sended ");
#endif
delay(10000);
#ifdef ISDEBUG
  Serial.println("Receive Message");
#endif
if (mySerial.available())
   {
   started = millis(); 
   do {c0 = mySerial.read();} while ((c0 != ':') && (mySerial.available()));
   for (int i=0; i<NTP_PACKET_SIZE; i++) {packetBuffer[i] = mySerial.read(); 
//                                           Serial.print(packetBuffer[i],HEX); Serial.print(","); 
                                         }
   out = (uint32_t(packetBuffer[40])<<24) + (uint32_t(packetBuffer[41])<<16) + (uint32_t(packetBuffer[42])<<8) + uint32_t(packetBuffer[43]) ;
   NTPtime = out - seventyYears + LocalTimeZone + 12;
   }
else {
#ifdef ISDEBUG
  Serial.println("No data received!");
#endif
     mySerial.println("AT+CIPCLOSE");
     return 0;
     }
#ifdef ISDEBUG
  Serial.println("Close connection");
#endif
  mySerial.println("AT+CIPCLOSE");
//  delay(1000);
return NTPtime;
}

void setNTPpacketBuffer()
{
  // set all bytes in the buffer to 0
  memset(packetBuffer, 0, NTP_PACKET_SIZE); 
  // Initialize values needed to form NTP request
  // (see URL above for details on the packets)
  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
  packetBuffer[1] = 0;     // Stratum, or type of clock
  packetBuffer[2] = 6;     // Polling Interval
  packetBuffer[3] = 0xEC;  // Peer Clock Precision
  // 8 bytes of zero for Root Delay & Root Dispersion
  packetBuffer[12]  = 49; 
  packetBuffer[13]  = 0x4E;
  packetBuffer[14]  = 49;
  packetBuffer[15]  = 52;
}

#ifdef ISDEBUG
void PrintTime (time_t ttt)
{
 tmElements_t tttm;
 Serial.print("UNIXTIME   ->>>>   ");
 Serial.print(ttt,HEX);
 Serial.print("   ->>>>   ");
 Serial.println(ttt,DEC);
 breakTime(ttt, tttm);  
 Serial.print("Date time is: ");
 Serial.print(tttm.Day);
 Serial.print(".");
 Serial.print(tttm.Month);
 Serial.print(".");
 Serial.print(tttm.Year+1970);
 Serial.print(" - ");
 Serial.print(tttm.Hour);
 Serial.print(":");
 if ( (tttm.Minute) < 10 ) {
     // In the first 10 minutes of each hour, we'll want a leading '0'
     Serial.print('0');
    }
 Serial.print(tttm.Minute);
 Serial.print(":");
 if ( (tttm.Second) < 10 ) {
     Serial.print('0');
    }
 Serial.print(tttm.Second);
 Serial.println(); // Start a new line.
}
#endif

 

Да, написано для прошивки esp8266 0.21, в новой 0.22 команды расширились, но смысл тот же.