подскажите по Serial и esp8266
- Войдите на сайт для отправки комментариев
Пт, 17/06/2016 - 22:00
подскажите, делаю отправку и прием на сервер, решил протестировать код, и непонятно как сериал работает или софтсериал, и .flush
#include <SoftwareSerial.h>
SoftwareSerial esp(10, 11); // RX, TX
void setup() {
Serial.begin(9600); //запускаем встроенный сЕриал
while (!Serial) {;}
esp.begin(9600); //запускаем софтварный сЕриал
///////////////////////
char ssid[] = "Wi-Fika";
char pass[] = "123Lion45";
///////////////////////
Serial.println("1");
/// /// ///
//проверяем готов ли к работе модуль esp8266
esp.println("AT+RST");
delay(250);
while(!esp.find("ready")){
delay(1000);
}
esp.flush();
delay(250);
/// /// ///
Serial.println("2");
//посылаем для теста команду АТ и ждем ответа ОК
esp.println("AT");
//delay(500);
while((esp.available() > 0)) {
Serial.write(esp.read());}
while(!esp.find("OK")) delay(500);
esp.flush();
/// /// ///
Serial.println("3");
//переводим модуль в режим "клиент-station", если он не в нем
esp.println("AT+CWMODE_DEF?");
if(!esp.find("1"))
{
esp.println("AT+CWMODE_DEF=1");
delay(10);
esp.println("AT+RST");
delay(500);
while(!esp.find("rsady")) delay(1000);
}
esp.flush();
/// /// ///
Serial.println("4");
/*
//ищем нашу сеть ssid и если находим, то подключаемся
while(true)
{
//сканируем сеть
esp.println("AT+CWLAP");
delay(1000);
while((esp.available() > 0)) Serial.write(esp.read());
while(1) {
if(esp.find("OK")) break;
Serial.println("555");
delay(1000);
}
//если нашли нашу точку
if(esp.find(ssid))
{
esp.flush();
//подключаемся к нашей точке
esp.println(printf("AT+CWJAP_DEF=\"%s\",\"%s\"", ssid, pass));
//ждем до конца подключения
while(!esp.find("GOT IP") && !esp.find("OK")) delay(1000);
esp.flush();
break;
}
}
*/
Serial.println("5");
/// /// ///
}
void loop() {
while (esp.available() > 0) { // смотрим что ответил есп после отправки
Serial.write(esp.read());
}
}
Serial.println(цифра) искал где код не работает, и пытался читать ответ между кусками кода так
while (esp.available() > 0) { // смотрим что ответил есп после отправки |
87 |
Serial.write(esp.read()); |
88 |
} |
добавлял delay(), пытался чистить ответ esp.flush(), но как то непонятно для меня ведет себя ответ, esp.find() искал ответы от модуля есп8266, до 35 строки ищет правильно, а дальше я искаверкал ответ в 44 строке, но посчитало, что ответ верный, подскажите где мои ошибки...
ну наверное плохо объяснил, сам незнал как спросить
1) обьясните как работает Serial.flush()
2) как мне узнать ответ, например, этой части кода
esp.println("AT+RST");19delay(250);20while(!esp.find("ready")){21delay(1000);22}23esp.flush();делал так:
while(esp.availlable > 0) Serial.write(esp.read);
Если CWMODE уже равен единице, то строки 40-44 просто не будут выполняться, может в этом причина ?
да, вот не должны, но они почему то исполняются. Почему то тут esp.find() не ищет правильно и в следующем коде, что закоментирован
Как Вы узнаёте, что они исполняются ?
я поотделял Serial.println(цифра) куски кода и смотрю где останавливается, там с "1" проходит, я посмотрел, что модуль отвечает CWMODE:1 и так пытался find найти, но следующий закоментированный ищет криво... я счас еще раз проверю, а то вначале написал код, думал все верно, а тут началось, с ардуино плохо знаком
Я не пользуюсь esp.find(), поэтому советую попытаться увидеть ответы ESP.
После 37-й строки временно вставьте
delay(250); while(esp.availlable > 0) Serial.write(esp.read);
Если в ответе действительно нет единички, перенесите
delay(250); while(esp.availlable > 0) Serial.write(esp.read);
за 43-ю строку, посмотрите ответ там.
да я вот аытаюсь увидеть ответы, сегодня с утра сижу разбираюсь, тип так и смотрю ответы delay(250); while(esp.availlable > 0) Serial.write(esp.read); только делай ставлю перед некоторыми командами и 650мс, а то если меньше выкидает не полностью ответ, если в find вписываешь строку то выводит текст после найденной подстроки, так на заметку
#include <SoftwareSerial.h> SoftwareSerial esp(10, 11); // RX, TX void setup() { Serial.begin(9600); //запускаем встроенный сЕриал while (!Serial) {;} esp.begin(9600); //запускаем софтварный сЕриал /////////////////////// char ssid[] = "Wi-Fika"; char pass[] = "123Lion45"; /////////////////////// Serial.println("1"); /// /// /// //проверяем готов ли к работе модуль esp8266 esp.println("AT+RST"); delay(250); while(!esp.find("ready")){ delay(1000); } esp.flush(); delay(250); /// /// /// Serial.println("2"); //посылаем для теста команду АТ и ждем ответа ОК esp.println("AT"); while(!esp.find("OK")) { delay(500); } esp.flush(); /// /// /// Serial.println("3"); //переводим модуль в режим "клиент-station", если он не в нем esp.println("AT+CWMODE_DEF?"); esp.flush(); if(!esp.find("1")) { esp.println("AT+CWMODE_DEF=1"); delay(10); esp.flush(); esp.println("AT+RST"); delay(650); Serial.print("lllttt"); while(!esp.find("ready")) delay(1000); } esp.flush(); /// /// /// Serial.println("4"); //ищем нашу сеть ssid и если находим, то подключаемся while(true) { do{ //сканируем сеть esp.println("AT+CWLAP=\"Wi-Fika\""); Serial.println("---"); delay(650); } while(!esp.find("\"Wi-Fika\",-")); //подключаемся к нашей точке while(!esp.find("GOT IP")) { delay(650); Serial.print("111"); esp.println("AT+CWJAP_DEF=\"Wi-Fika\",\"192.168.1.109\""); delay(1000); while(esp.available() > 0) Serial.write(esp.read()); } esp.flush(); break; } //end setup() Serial.println("5"); /// /// /// } void loop() { //Serial.print(1); if (esp.available() > 0) Serial.write(esp.read()); if (Serial.available() > 0) esp.write(Serial.read()); }дошел до 62 строки, этот код чет выдает busy p
блин, в 67 строке вместо пароля вписал ип адрес, вроде эта часть кода работает, но вот непойму почему ответ прочитать не всегда могу, поэтому тестить проблемно
delay(250); while(esp.availlable > 0) Serial.write(esp.read);
на некотором участке читает, на некотором не полный ответ? Т.е не выводит в сериал полный ответ, как при ручном вводе команд по сериал, при ручном все приходит, или из-за маленькой скорости 9600бод.
ESP не столь быстр на ответы, поэтому "алгоритм" - давать достаточно времени между командами и на ожидание ответа. Тогда, как Вы уже и сами увидели, не будет ни "busy p", не неполных ответов. Сколько минимально давать времени - это зависит от конкретной АТ-команды, тут метод подбора Вам в помощь.
Для примера приведу свою функцию (ре)инициализации для ESP8266 в адаптированном виде. Оба последовательных порта в данном случае "железные", оба на 9600, на мелких Ардуино работает через SoftwareSerial.
boolean ESPRestart( { int ESPNumberConnectRetries = 20; Serial.println("Resetting ESP.."); Serial2.println("AT+RST"); ESPFlushSerial(300); Serial2.println("AT+CSYSWDTENABLE"); ESPFlushSerial(100); String ESPcmd; ESPcmd = "AT+CWJAP=\""; ESPcmd += "************************"; // тут имя сети ESPcmd += "\",\""; ESPcmd += "************************"; // тут пароль ESPcmd += "\""; Serial.println("Connecting to WiFi.."); for ( int i = 1; i <= ESPNumberConnectRetries; i++ ) { Serial.print("Try "); Serial.println(i); Serial2.println(ESPcmd); delay(200); if ( Serial2.find("OK") ) // Опаньки ! Оказывается я тоже пользуюсь find(), совсем запамятовал. { Serial.println("Connected to WiFi."); ESPFlushSerial(200); Serial2.println("AT+CWMODE=1"); ESPFlushSerial(200); Serial2.println("AT+CIPMUX=1"); ESPFlushSerial(200); Serial2.println("AT+CIPSERVER=1,48569"); // я пользуюсь UDP, это Вам не понадобится ESPFlushSerial(200); Serial2.println("AT+CIPSTO=120"); ESPFlushSerial(200); Serial2.println("AT+CIPSTART=4,\"UDP\",\"192.168.0.255\",48569,1112,0"); // опять же UDP... ESPFlushSerial(200); return true; } } Serial.println("Can't connect."); return false; } void ESPFlushSerial(int delaymsec) { // ждём и вычищаем буфер delay(delaymsec); while ( Serial2.available() ) { Serial2.read(); } }busy p было из-за того, что вместо пароля ип адрес вписал по ошибке.
да там можно все проще, счас все данные для подключения можно хранить в ЕЕПРОМ есп, т.е команды есть в прошивке и только проверять подключен ли к сети модуль, так надо и сделать, а то памяти уже у меня ушло под 20%, а я еще ничего не передавал )), тяжело тестировать этот ардуино, нельзя как то тестить без заливки кода в сам МК ? Сча буду извращатся, потом отпишусь, а то есть еще вопросы, написал парсер для приема ответов от сервера, но писал в ВижуалСтудио, а с прикрутить к ардуино еще то ))
и подскажите, что делает метод .flush() ? а то не совсем понятно его предназначение.
и подскажите, что делает метод .flush() ? а то не совсем понятно его предназначение.
Вы уже второй раз спрашиваете об этом, как-то неудобно в Гугл посылать, но надо бы...
так и не понял работу flush, как он работает правильно, ждет до окончания передачи, чет не заметил.
вот код, по сути этого всего и ненадо, если все настроить вручную на есп8266, но вот есть вопрос, как вывести данные от запроса подключения к сети из 67 строки
если написать так
#include <SoftwareSerial.h> SoftwareSerial esp(10, 11); // RX, TX void setup() { Serial.begin(9600); //запускаем встроенный сЕриал while (!Serial) {;} esp.begin(9600); //запускаем софтварный сЕриал /////////////////////// char ssid[] = "Wi-Fika"; char pass[] = "123Lion45"; /////////////////////// int i = 0; Serial.println("1"); /// /// /// //после перезагрузки ардуино перезагружаем модуль esp8266 //и ждем готовности esp.println("AT+RST"); delay(1000); while(!esp.find("ready")) delay(650); /// /// /// Serial.println("2"); //посылаем для теста команду АТ и ждем ответа ОК esp.println("AT"); while(!esp.find("OK")) delay(650); /// /// /// Serial.println("3"); delay(250);//очищаем буфер while(esp.available()) esp.read(); //переводим модуль в режим "клиент-station", если он не в нем esp.println("AT+CWMODE?"); if(!esp.find(":1")) { esp.println("AT+CWMODE_DEF=1"); delay(650); esp.println("AT+RST"); delay(1000); while(!esp.find("ready")) delay(650); } /// /// /// Serial.println("4"); delay(250);//чисттим буфер while(esp.available()) esp.read(); //ищем нашу сеть ssid и если находим, то подключаемся while(true) { do{ //сканируем сеть esp.println("AT+CWLAP=\"Wi-Fika\""); delay(2000); Serial.println("CWLAP"); } while(!esp.find("\"Wi-Fika\",-")); delay(250);//чистим буфер while(esp.available() > 0) esp.read(); esp.println("AT+CWJAP_DEF=\"Wi-Fika\",\"123Lion45\""); //подключаемся к нашей точке while(!esp.find("WIFI GOT IP")) { Serial.println("111"); delay(100); } break; } while(1){ delay(50); while(esp.available() > 0) Serial.write(esp.read()); } //end setup() Serial.println("5"); /// /// /// } void loop() { if (esp.available() > 0) Serial.write(esp.read()); if (Serial.available() > 0) esp.write(Serial.read()); }и подскажите, что делает метод .flush() ? а то не совсем понятно его предназначение.
Олег, Вы уже два дня про него спрашиваете. Неужели за это время не было минутки посмотреть на него? Вот он, блин - всего несколько строк, если комментарии не считать
void HardwareSerial::flush() { // If we have never written a byte, no need to flush. This special // case is needed since there is no way to force the TXC (transmit // complete) bit to 1 during initialization if (!_written) return; while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) { if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0)) // Interrupts are globally disabled, but the DR empty // interrupt should be enabled, so poll the DR empty flag to // prevent deadlock if (bit_is_set(*_ucsra, UDRE0)) _tx_udr_empty_irq(); } // If we get here, nothing is queued anymore (DRIE is disabled) and // the hardware finished tranmission (TXC is set). }а вот, вызываемая из него функция _tx_udr_empty_irq.
void HardwareSerial::_tx_udr_empty_irq(void) { // If interrupts are enabled, there must be more data in the output // buffer. Send the next byte unsigned char c = _tx_buffer[_tx_buffer_tail]; _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE; *_udr = c; // clear the TXC bit -- "can be cleared by writing a one to its bit // location". This makes sure flush() won't return until the bytes // actually got written sbi(*_ucsra, TXC0); if (_tx_buffer_head == _tx_buffer_tail) { // Buffer empty, so disable interrupts cbi(*_ucsrb, UDRIE0); } }Всё это есть на Вашем компьютере. Даже в гугл лезть не надо. Что мешало посмотреть самому?
ступил жестко ))), забыл что код открытый ))), это пипец ))), пасиб
Да, не за что, бывает.