Таки ви хочете сказать шо если я от NTP-сервера по UDP получаю ( а перед этим отправляю ) стандартные 48 байт, то я их не получу или получу не так ?
Нет, конечно получите. У меня дома четыре ESP8266 общаются бродкастными UDP-пакетами достаточно стабильно (для меня), но добиться 100%-ной отправки/получения пакетов я не могу (впрочем, уже и не хочу, надоело бороться с проблемами АТ-прошивки). Основной вывод я сделал следующий: чем реже и чем меньше посылаем, тем стабильнее работает.
Кстати, сейчас экспериментирую с LUA на NODEMCU - в общем пока та же фигня.
Вот еще какая штука выяснилась: если модуль находится в режиме AT+CIPMUX=0 или если модуль находится в режиме AT+CIPMUX=1 но tcp сервер не поднят, то отправка на web-сервер осуществляется практически без потерь. Иначе отправка происходит стабильно ,но в определенный момент начинают идти одни неудачные попытки.
1. А кто знает как на прошивке NODEMCU выполнить заливку произвольного файла (ну картинку жапег например) в файловую систему модуля?
2. Порывшись в операторах Lua обнаружил соответствующую команду для компиляции скрипта в байт-код. Не взлетело. Кто пробовал, получилось? Вопрос актуальнейший т.к. байт-код и работает быстрей и места много меньше занимает.
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 не поддерживает.
Это что-то новенькое... А не к пинам 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 не поддерживает.
Сорри, все так. Что-то у меня переклинило с этими портами.
Хочу поделиться результатами по проблеме отправки данных со связки arduino+esp8266(07) на web server.
Если на esp8266 не поднимать tcp server, то отправка происходит без потерь. Тестировал почти неделю, отправляя данные(показания температуры) раз в минуту.
Для остальных своих устройтв, на которых необходим был tcp server для приема GET запросов от web servera, пришлось делать проверку отправки сообщений и если она неудачна, то производить отправку снова.
Тока мне этот метод не очень нравится)!! Может у кого есть какие-то мысли по поводу, почкему поднятый на esp tcp server влияет на отправку сообщений на web-server. Может быть причина в прошиве?
Если убираю вывод в 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...
Увеличение буфера проблему не решило,- по-прежнему если не дублировать команды в Serial, то от сервера ответов нет, если же дублировать, то иногда даже работает, но постоянно присутствует мусор и обрезанное эхо запроса, а иногда данные с сервера так и не доходят:
Загадочная зависимость от Serial, возможно, связана с тем, что ESP не всегда успевает ответить, а вывод в Serial дает ему необходимую задержку.Еще неплохо бы для контроля добавить после отправки (после строки 67) if ( wifi.find("SEND OK") ).
Далее, если сработало while (wifi.available()) - это не значит, что в приемном буфере уже находятся ВСЕ принятые данные. Дайте задержку, пусть ESP успеет до конца принять.
ESP не настолько быстр, работайте с ним не торопясь )). Команда "AT+CIPSEND" во всех АТ-прошивках имеет немалые проблемы, об этом немало написано. Так что особо не удивляйтесь трудностям.
Кстати, строка 58 явно лишняя, почитайте про Serial.find()
За счёт избавления от длинной строки и замены её размером постоянной части заголовков и размером добавляемой переменной удалось сэкономить 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.
Загадочная зависимость от Serial, возможно, связана с тем, что ESP не всегда успевает ответить, а вывод в Serial дает ему необходимую задержку.Еще неплохо бы для контроля добавить после отправки (после строки 67) if ( wifi.find("SEND OK") ).
/* вырезано */
Спасибо за свежие мысли, они очень пригодились в устранении нестабильной работы модуля!
А ведь я уже хотел забросить это неблагодарное дело и уйти на Ethernet Shield :)
День добрый,
Я вижу что эта вифи карточка вызывает некий ажиотаж.
Как я понял , подключается свего по 2 dig пинам к ардуино.
Какие у нее минусы/проблемы/недостатки/ограничения ?
Хочу в конечном итоге по вифи подключаться к ардуино с компа/смарфона , видеть состояние (освещение и мощьность освещения, температуру,... ) , а так же менять это всё....
С увеличением таймаута до 5000мс, количество ошибок установления соединения падает до 2, на 3 попытке соединение устанавливается, но общее время между результативными попытками больше, чем при таймауте 2000мс и 4 ошибках.
Код немного модифицирован по сравнение с ранее опубликованным:
И самое неприятное, что на работе с Linksys E4200 всё вроде бы более или менее стабильно работает, а дома с Apple AirPort Express начинаются ошибки соединения. Причём если подключаюсь к ESP8266 напрямую и отправляю АТ команды вручную, то в 99% проблем не наблюдаю. Иногда вылезает DNS Fail при AT+CIPSTART
Подключил 07, хватило GPIO15 на землю и CH_PD на VCC, через 10K, внешнее питание 3.3В и к компу через USB-TTL на CP2102. Пашет, перешил на SDK v1.0.0 AT v0.22. В сети появился, со смарта подключился нормально. Сначала накосячил, вместо GPIO15 подключал GPIO5 :) Не работало.
Пока больше ничего не тестил.
Теперь можно поиграться :)
Я понимаю, что это вход, потому пофиг на резистор. Однако для игр можно через кнопку на землю. Я вчера так игрался, чтобы питание не передергивать.
Плюс сделал по аналогии с другими пинами, что бы не париться.
Может быть, при использовании UDP таких проблем не будет, не знаю.
Я знаю - будут ))) Пробовал и TCP, и UDP, проблемы те же. Размер пакета - 32 байта, кстати.
Я знаю - будут ))) Пробовал и TCP, и UDP, проблемы те же. Размер пакета - 32 байта, кстати.
Таки ви хочете сказать шо если я от NTP-сервера по UDP получаю ( а перед этим отправляю ) стандартные 48 байт, то я их не получу или получу не так ?
Таки ви хочете сказать шо если я от NTP-сервера по UDP получаю ( а перед этим отправляю ) стандартные 48 байт, то я их не получу или получу не так ?
Нет, конечно получите. У меня дома четыре ESP8266 общаются бродкастными UDP-пакетами достаточно стабильно (для меня), но добиться 100%-ной отправки/получения пакетов я не могу (впрочем, уже и не хочу, надоело бороться с проблемами АТ-прошивки). Основной вывод я сделал следующий: чем реже и чем меньше посылаем, тем стабильнее работает.
Кстати, сейчас экспериментирую с LUA на NODEMCU - в общем пока та же фигня.
Вот еще какая штука выяснилась: если модуль находится в режиме AT+CIPMUX=0 или если модуль находится в режиме AT+CIPMUX=1 но tcp сервер не поднят, то отправка на web-сервер осуществляется практически без потерь. Иначе отправка происходит стабильно ,но в определенный момент начинают идти одни неудачные попытки.
Может у кого есть мысли на этот счет??
Нет, конечно получите. У меня дома четыре ESP8266 общаются бродкастными UDP-пакетами достаточно стабильно (для меня)
А вы не можете выложить кусок скетча с отправкой и получением UDP-пакетов ?
Может я что-то делаю не так.
Я уж и побайтно пытался считывать из сериала, и массово, толку ноль.
Коннект с NTP-сервером идет, данные туда отсылаются, а вот на приеме одна и та же слабочитаемая фигня.
Добро бы если фигня изменялась со времем ( надежда на то что я просто ее расшифровать не могу ), но приходит один и тот же мусор.
Вот тут : https://darkbyte.ru/2015/78/esp8266-debrick-after-ciupdate-fatal-exception/ какой-то профи показывает как прошить ESP-05, но я еще не настолько познал безначальное ДАО, чтобы выпаивать флеш-память и программировать ее, а потом обратно запаивать ))
1. А кто знает как на прошивке NODEMCU выполнить заливку произвольного файла (ну картинку жапег например) в файловую систему модуля?
2. Порывшись в операторах Lua обнаружил соответствующую команду для компиляции скрипта в байт-код. Не взлетело. Кто пробовал, получилось? Вопрос актуальнейший т.к. байт-код и работает быстрей и места много меньше занимает.
А вы не можете выложить кусок скетча с отправкой и получением 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.Выпарсиваете из строки все, что нужно.
Тогда проще на любом своем сервере создать скрипт отдачи времени и даты в любом удобном формате.
Такой вариант может и не будет очень точным, но сэкономит ресурсы..
Вот куски скетча, как видите, ничего особенного для связи по 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; }Вот куски скетча, как видите, ничего особенного для связи по UDP не нужно.
А какую модель Arduino Вы используете?
А какую модель Arduino Вы используете?
Одна Мега, одна Уно и две Нано. Обмен данными между ними четыремя. Приведенные куски кода у всех одинаковые.
Мега каждые пять секунд отправляет запросы поочередно каждой из трех остальных Ардуин, они отвечают на запросы.
#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
ответ то приходит но я его вижу как стрякозябры , такое чувство что скорость порта не та стоит ,
хотя через терминальные проги на этой скорости ответы приходят нормальные
Фатальная ошибка в скетче.
Serial - это аппаратный порт. Он жестко привязан к пинам 10 и 11.
А Вы пытаитесь на него еще и прогамный порт навесить.
Возьмите для SoftwareSerial любые другие 2 пина и к ним подцепите терминал.
Для терминала скорость установите стандартную: 9600.
Фатальная ошибка в скетче.
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 не поддерживает.
я на разных пинах пробовал . на связке 2,3 результат токайже
в описании на софтсериал вроде написано скорость до 115200.
а как можно понизить скорость порта в ESP8266 в прошивке AT 20 или AT 21
я на разных пинах пробовал . на связке 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/
В случае Меги есть еще "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 не поддерживает.
Сорри, все так. Что-то у меня переклинило с этими портами.
на 21 прошивке и скорости 9600 заработало .
ответы ok\error\ready приходят нормально
а вот инфа из запрося AT+RST стрякозябрами даже в терминальных прогах ))
а вот инфа из запрося AT+RST стрякозябрами даже в терминальных прогах ))
У меня то же самое, там только в конце есть немного осмысленного текста.
Это сообщение бутлоадера, причем на китайском языке..
А есть уже софт или прошивка\библиотека для ESP8266, которая бы слушала GET запрос и передавала его содержимое в RxTx ?
Готового решения не видел (искал, есть подобная идея). Прошивка NodeMCU (описание API https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_ru) + язык Lua. Этими инструментами вполне реализуемо.
Всем очередной привет.
Хочу поделиться результатами по проблеме отправки данных со связки arduino+esp8266(07) на web server.
Если на esp8266 не поднимать tcp server, то отправка происходит без потерь. Тестировал почти неделю, отправляя данные(показания температуры) раз в минуту.
Для остальных своих устройтв, на которых необходим был tcp server для приема GET запросов от web servera, пришлось делать проверку отправки сообщений и если она неудачна, то производить отправку снова.
Тока мне этот метод не очень нравится)!! Может у кого есть какие-то мысли по поводу, почкему поднятый на esp tcp server влияет на отправку сообщений на web-server. Может быть причина в прошиве?
Скорее всего в прошивке что-то недоработано.. У меня в проекте esp8266 все работает одновременно и отлично..
Скорее всего в прошивке что-то недоработано.. У меня в проекте esp8266 все работает одновременно и отлично..
а какая у тебя версия прошики?
У меня своя версия прошивки :)
Скорее всего тут такое ограничение накладывается из-за одновременного использования UART..
У меня похожая задача,- нужно отправлять данные в 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...
У меня похожая задача,- нужно отправлять данные в GET запросе на сервер, а в ответ получать данные с сервера.
А как у Вас с размерами буферов UART (SERIAL_BUFFER_SIZE) для Hardware/Software Serial ? String cmd немаленькая ведь получается.
HardwareSerial буферы увеличены до 256
\Arduino\hardware\arduino\avr\cores\arduino\HardwareSerial.h
У SoftwareSerial буфер был 64, забыл про него совсем...
Увеличил до 256, буду тестить
\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\SoftwareSerial.h
Увеличение буфера проблему не решило,- по-прежнему если не дублировать команды в Serial, то от сервера ответов нет, если же дублировать, то иногда даже работает, но постоянно присутствует мусор и обрезанное эхо запроса, а иногда данные с сервера так и не доходят:
Самая мистика в том, что без 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; } }Загадочная зависимость от Serial, возможно, связана с тем, что ESP не всегда успевает ответить, а вывод в Serial дает ему необходимую задержку.Еще неплохо бы для контроля добавить после отправки (после строки 67) if ( wifi.find("SEND OK") ).
Далее, если сработало while (wifi.available()) - это не значит, что в приемном буфере уже находятся ВСЕ принятые данные. Дайте задержку, пусть ESP успеет до конца принять.
ESP не настолько быстр, работайте с ним не торопясь )). Команда "AT+CIPSEND" во всех АТ-прошивках имеет немалые проблемы, об этом немало написано. Так что особо не удивляйтесь трудностям.
Кстати, строка 58 явно лишняя, почитайте про Serial.find()
За счёт избавления от длинной строки и замены её размером постоянной части заголовков и размером добавляемой переменной удалось сэкономить 86 байт бинарного кода (строка 53):
За счёт ввода дополнительного символа ("%") в данные, для отсечения возвращяемых сервером заголовков, удалось оставить размер 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; } }Загадочная зависимость от Serial, возможно, связана с тем, что ESP не всегда успевает ответить, а вывод в Serial дает ему необходимую задержку.Еще неплохо бы для контроля добавить после отправки (после строки 67) if ( wifi.find("SEND OK") ).
/* вырезано */
Спасибо за свежие мысли, они очень пригодились в устранении нестабильной работы модуля!
А ведь я уже хотел забросить это неблагодарное дело и уйти на Ethernet Shield :)
Никуда не уходите, у ESP8266 большой потенциал (и пока еще сырой SDK).
Никуда не уходите, у ESP8266 большой потенциал (и пока еще сырой SDK).
Не ухожу :)
Начинаю внедрять код и модуль в основной проект, текущая стабильность уже устраивает для моих задач.
День добрый,
Я вижу что эта вифи карточка вызывает некий ажиотаж.
Как я понял , подключается свего по 2 dig пинам к ардуино.
Какие у нее минусы/проблемы/недостатки/ограничения ?
Хочу в конечном итоге по вифи подключаться к ардуино с компа/смарфона , видеть состояние (освещение и мощьность освещения, температуру,... ) , а так же менять это всё....
IKIF, более конкретный вопрос получит больше ответов.
Никуда не уходите, у ESP8266 большой потенциал (и пока еще сырой SDK).
Всё-таки рано оказалось в продакшн его...
С таймаутом SoftwareSerial в 2000мс наблюдается следующая картина:
С увеличением таймаута до 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
Вышел ESP8266 IoT SDK v1.0.0 AT v0.22
Читаем http://esp8266.ru/esp8266-iot-sdk-v1-0-0-at-v0-22/
Всем салют!
Вот, есть кое-какая документация
https://drive.google.com/folderview?id=0BwK3EhAfht8uWTdBdG55NEFCakE&usp=...
Подключил 07, хватило GPIO15 на землю и CH_PD на VCC, через 10K, внешнее питание 3.3В и к компу через USB-TTL на CP2102. Пашет, перешил на SDK v1.0.0 AT v0.22. В сети появился, со смарта подключился нормально. Сначала накосячил, вместо GPIO15 подключал GPIO5 :) Не работало.
Пока больше ничего не тестил.
Теперь можно поиграться :)
Осмелюсь утверждать, что 10K - необязательно.
Вышла Ардуино ИДЕ с поддержкой субьекта....
http://hackaday.com/2015/03/28/arduino-ide-support-for-the-esp8266/
Вышла Ардуино ИДЕ с поддержкой субьекта....
http://hackaday.com/2015/03/28/arduino-ide-support-for-the-esp8266/
Я правильно понял, что теперь можно шить с помощью ардуины и заливать туда ( в ESP8266 ) скетчи ?
Осмелюсь утверждать, что 10K - необязательно.
Я понимаю, что это вход, потому пофиг на резистор. Однако для игр можно через кнопку на землю. Я вчера так игрался, чтобы питание не передергивать.
Плюс сделал по аналогии с другими пинами, что бы не париться.
Я правильно понял, что теперь можно шить с помощью ардуины и заливать туда ( в ESP8266 ) скетчи ?
Поняли правильно, можно, но есть нюансы. Проект новый, весьма сырой и до ума еще не доведенный. Подробности - http://www.arduinesp.com/ , http://esp8266.ru/arduino-ide-esp8266/
Что-то разактивилась тема, подниму пожалуй.
Статья "Многофункциональный датчик температуры/влажности на ESP8266 или еще один шаг к «интернету вещей»". На базе прошивки NodeMCU.
Здесь: http://habrahabr.ru/post/255359/
Хорошая обертка + поддержка АТ 0.22 https://github.com/itead/ITEADLIB_Arduino_WeeESP8266
Не могу получить от 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? Кодировка?Может и не надо уже - но отвечу на вопрос о синхронизации времени с NTP через esp8266.
Работа с esp8266 идет без библиотек, только с помощью AT-команд.
Все пашет, время приходит всегда.
Ниже - вырезка из основной программы настенных часов, только то, что отностится к синхронизации по NTP.
Да, написано для прошивки esp8266 0.21, в новой 0.22 команды расширились, но смысл тот же.