Как побороть ошибку "busy s" при отправке Arduino+esp8266
- Войдите на сайт для отправки комментариев
Всем привет.
Разрабатываю свой вариант температурного логгера в классичесском исполнении: Arduino+ESP8266+Thingspeak.
Особая потребность в отслеживании нескольких (пока 4) температур.
И столкнулся с проблемой зависания вай-фай модуля с ответом "busy s" при превышении некоего предела длины строки при отправке: "GET /update?key=хххххххххххххх&field1=ххххх HTTP/1.1\r\n".
По крайне мере, такое обьяснение я нагуглил.
В тестовых попытках при непосредственном задании значения в строке, например:
"GET /update?key=хххххххххххххх&field1=15 HTTP/1.1\r\n"
все проходит нормально и сервер принимает значение.
Но при попытке вставки переменной в строку уже превышатеся некий предел и ESP зависает, на все команды выдает "busy s" и помогает только передерг питания. При попытке вставить несколько значений "&field2=", "&field3=" естественно виснет аналогичным образом.
Самое интерсное что в других скетчах в инете вроде встречаю примеры передачи &field2= цепочкой в одной строке и вроде проблем нет. Но там никто не цитирует всю сроку GET /update?key= и API key, а через string переменные, хотя я не понимаю что это меняет... все равно на выходе ESP получит строку одинаковой длины, без разницы как она была создана в скетче - процитирована полностью или составлена из переменных...
С переменными связываться пока не хочу, так как еще не сильно силе в синтаксисе стринговых переменных, а мне важно полностью понимать что и где значит, пусть даже программа и будет крупнее.
В общем, прощу совета и помощи в этом вопросе.
ESP8266 AT 021, библиотека ESP8266pro-master
#include <SoftwareSerial.h>
#include <ESP8266pro.h>
#include <ESP8266proClient.h>
SoftwareSerial espSerial(9, 10); // RX, TX
ESP8266pro wifi(espSerial, Serial); // Serial, DebugSerial
const char* ssid = "*****";
const char* password = "*******";
float toffice1 = 25;
float toffice2 = 26;
float thome = 27;
float tkotel = 60;
String a;
String b;
void setup()
{
espSerial.begin(9600);
Serial.begin(9600);
// инициализация модуля -----------------------------------------------------------
wifi.begin(eODM_Dump); // Disable all debug messages
// подключение-------------------------------------------------------------------------
do {
if (!wifi.stationConnect(ssid, password))
delay(5000);
}
while (wifi.stationIP() == NULL_IP);
Serial.print("ESP IP: ");
Serial.println(wifi.stationIP());
//передача-----------------------------------------------------------------------------
String a(toffice1);
String b(toffice2);
ESP8266proClient con(wifi, printResponse);
con.connectTcp("184.106.153.149", 80);
con.send("GET /update?key=ххххххххххххххххх&field1=20 HTTP/1.1\r\n"); // только в таком виде посылка уходит нормально
con.send("Host: api.thingspeak.com\r\n");
con.send("Accept: */*\r\n");
con.send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n");
con.send("\r\n");
con.waitResponse();
con.close();
}
void loop()
{
}
// Optional method to process remote response------------------------------------------------
void printResponse(ESP8266proConnection* connection, char* buffer, int length, boolean completed)
{
Serial.print(buffer);
}
в 38 и 39 строках это что ?
38String a(toffice1);39String b(toffice2);почему обьявил тип float, а инициализировал целыми числами ?
Это преобразование в строку. Это я пытался вставить переменную в значение в строке отправки на Thingspeak.
Может я и неправильно сделал (хотя сделал по примеру из инета), но проверить не могу так как все равно любое превышение длины строки дает "busy s"...
Вот ссылка на тот пример, который я использовал при преобразовании:
http://forum.amperka.ru/threads/%D0%9F%D1%80%D0%B5%D0%BE%D0%B1%D1%80%D0%B0%D0%B7%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D1%87%D0%B8%D1%81%D0%BB%D0%B0-%D0%B2-%D1%81%D1%82%D1%80%D0%BE%D0%BA%D1%83.740/
В другой теме я нашел как вы обьясняли причину в символах перевода каретки...
http://arduino.ru/forum/apparatnye-voprosy/polzuet-li-kto-wifi-moduli-esp8266-podelites-vpechatleniyami?page=17
Но честно говоря - не сильно понял что конкретно надо делать с символами \r\n в моем случае.
Обьясните как для новичка.. Буду очень благодарен.
преобразовуют тип так a = String(toffice);
С вставкой преобразованной переменной в сроку разобрался, уже одну строку с переменной отсылает без ошибки busy s...
Осталось понять как отправить подряд несколько значений без переполнения длины...
если запрос неверный то ниче не приходит от сервера лишь буси с или ответ 400
Разобрался. Решено.
В моем случае помогло установка задержек в полсекунды между каждыми отправками на сервер.
И нормально отправляет длинные строки и сервер нормально принимает.
ESP8266proClient con(wifi, printResponse); con.connectTcp("184.106.153.149", 80); delay(500); con.send("GET /update?key=P32TFDS2OBFHORCH&field1="+a+"&field2="+b+"&field3="+c+"&field4="+d+" HTTP/1.1\r\n"); delay(500); con.send("Host: api.thingspeak.com\r\n"); delay(500); con.send("Accept: */*\r\n"); delay(500); con.send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n"); delay(500); con.send("\r\n"); delay(500);там вроде достаточно после connectTCP поставить задержку
Не могу добиться работы esp через softwareserial... Arduino Nano.
Сорость модуля поменял на 9600, если через hardware - то все работает, соединение создает, веб-сервер запускается и тп. А с софтовым портом, прямо беда какая-то, уже не знаю чего надо. Выдает в терминал bysyp...
#include <SoftwareSerial.h> SoftwareSerial ESPport(11, 12); ////////////////////// RX, TX #define BUFFER_SIZE 128 char buffer[BUFFER_SIZE]; void setup() { Serial.begin(9600); // Терминал ESPport.begin(9600); // ESP8266 clearSerialBuffer(); // очистка буфера Serial Serial.println("RESET 3,5 sek"); Serial.println(GetResponse("AT+RST",3400)); // перезагрузка ESP Serial.println(GetResponse("AT+CWMODE=1",300)); // режим клиента connectWiFi("keenetic","***"); // подключаемся к домашнему роутеру (имя точки, пароль) Serial.println(GetResponse("AT+CIPMODE=0",300)); // сквозной режим передачи данных. Serial.println(GetResponse("AT+CIPMUX=1",300)); // multiple connection. Serial.print("Start TCP-server: "); Serial.println(GetResponse("AT+CIPSERVER=1,88", 300)); // запускаем ТСР-сервер на 88-ом порту Serial.println(GetResponse("AT+CIPSTO=2", 300)); // таймаут сервера 2 сек Serial.println(GetResponse("AT+CIFSR", 300)); // узнаём адрес } ///////////////////основной цикл, принимает запрос от клиента/////////////////// void loop() { } /////////////////////отправка АТ-команд///////////////////// String GetResponse(String AT_Command, int wait) { String tmpData; ESPport.println(AT_Command); delay(wait); while (ESPport.available() >0 ) { char c = ESPport.read(); tmpData += c; if ( tmpData.indexOf(AT_Command) > -1 ) tmpData = ""; else tmpData.trim(); } return tmpData; } //////////////////////очистка ESPport//////////////////// void clearSerialBuffer(void) { while ( ESPport.available() > 0 ) { ESPport.read(); } } ////////////////////очистка буфера//////////////////////// void clearBuffer(void) { for (int i =0;i<BUFFER_SIZE;i++ ) { buffer[i]=0; } } ////////////////////подключение к wifi///////////////////// boolean connectWiFi(String NetworkSSID,String NetworkPASS) { String cmd = "AT+CWJAP=\""; cmd += NetworkSSID; cmd += "\",\""; cmd += NetworkPASS; cmd += "\""; Serial.println(cmd); Serial.println(GetResponse(cmd,6500)); }Нашел причину: имя роутера было с маленькой буквы написано, а надо было с заглавной, оставлю предыдущий пост, может кому будет полезно, мое потраченное время сэкономит его кому-то еще :)