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

ESP 8266. Не получается правильно сформировать строку запроса к серверу через АТ-команды. Подскажите

Himalart

New member
Пытаюсь отправлять данные на Тhingspeak через АТ-команды.
Пробовал програмно с использованием библиотеки Тhingspeak - все работает замечательно.

Пробовал просто из строки браузера:
https://api.thingspeak.com/update?api_key=ХХХХ65CE76RMХХ&field2=1200

Опять-таки все работает превосходно - данные принимаются.

Пытаюсь повторить через АТ-команды:

AT+CIPSTART="TCP","api.thingspeak.com",80
CONNECT
OK

AT+CIPSEND=108

OK
> GET /update?api_key=ХХХХ65CE76RMХХ&field1=100 HTTP/1.1\r\n Host: api.thingspeak.com\n Connection: close\r\n\r\n\r\n


SEND OK

Сервер отвечает, что это 400 Bad Request

ЧТО В СТРОКЕ ЗАПРОСА НЕ ТАК?????
 

fandy

Member
В этом Ваша проблема. Для TCP сервера это именно эти 4 символа, а не возврат каретки и перевод строки.
Если Вы введете отдельными строками в терминале (при включенном добавлении CR и NL)
GET /update?api_key=ХХХХ65CE76RMХХ&field1=100
HTTP/1.1\r\n Host: api.thingspeak.com
Connection: close
и пустую строку, все заработает.

И без Connection: close тоже должно.
 

AlexRyzh

New member
Подскажите, как в скетче добавить field2?
Есть скетч, отладочный, отлично работает. Для отладки я отправлял на thingspeak.com d field1 константу float tempC = 78;
Хочу добавить еще константу для второго поля float tempD = 45;
Что нужно добавить, изменить, чтоб заполнять 2 и более поля field?
Вот рабочий код для одного поля field1. Подключено к Ардуино перекрестно (RX->TX, TX->RX)

Код:
#define SSID "AR"
#define PASS "29121962"
#define IP "184.106.153.149" // thingspeak.com

String GET = "GET /update?api_key=NEXXXXXXXKFG0ICQ&field1=";
void setup()

{
  Serial.begin(115200);
Serial.println("AT");
delay(5000);
if(Serial.find("OK")){
connectWiFi();
}

}

void loop(){
float tempC = 78;
char buffer[10];
String tempF = dtostrf(tempC, 4, 1, buffer);
updateTemp(tempF);
delay(60000);
}
             /////////Functions///////////////////////
             /////////Connect TCP & GET Server////////
void updateTemp(String tenmpF)
{
String cmd = "AT+CIPSTART=\"TCP\",\"";
cmd += IP;
cmd += "\",80";
Serial.println(cmd);
delay(2000);
if(Serial.find("Error")){
return;
}
cmd = GET;
cmd += tenmpF;
cmd += "\r\n";
Serial.print("AT+CIPSEND=");
Serial.println(cmd.length());
if(Serial.find(">")){
Serial.print(cmd);
}else{
Serial.println("AT+CIPCLOSE");
}

}
           
             //////////ConnectWiFi////////////////////
boolean connectWiFi(){
Serial.println("AT+CWMODE=1");
delay(2000);
String cmd="AT+CWJAP=\"";
cmd+=SSID;
cmd+="\",\"";
cmd+=PASS;
cmd+="\"";
Serial.println(cmd);
delay(5000);
if(Serial.find("OK")){
return true;
}
else{
return false;
}

}
 

AlexRyzh

New member
Спсибо, разобрался. Нашел в сети как формируется запрос для 2 и более полей, отсюда и плясал.
Формирую запрос таким образом и все работает:
Код:
cmd = "GET /update?api_key=DYUWXXXXXC4XFMBJ&field1=";
cmd += tempC;
cmd += "&field2=";
cmd += tempD;
cmd += "\r\n";
 

obuhanoe

New member
Добрый день!
Если автор темы не против хотел бы спросить тут:
ESP8266-01 подключена к Arduino, ESP отвечает на АТ-команды, питание отдельное 3,3В
Если Вы введете отдельными строками в терминале (при включенном добавлении CR и NL)
GET /update?api_key=ХХХХ65CE76RMХХ&field1=100
HTTP/1.1\r\n Host: api.thingspeak.com
Connection: close
и пустую строку, все заработает.
У меня тоже ошибка 400 Bad Request, хотел уточнить, что означает
и пустую строку, все заработает.
т.е. вводим Connection: close, жмем Enter в терминале и после этого еще раз на Enter?

Спасибо.
 

fandy

Member
Для того, чтобы запросить HTTP документ надо установить соединение с HTTP сервером, а затем отправить ему HTTP запрос. Минимум 3 строчки:
1. GET /page.html HTTP/1.0
2. Host: yourhost.com
3. Пустая строка.

Первое - метод запроса (GET), страница (вместо page.html пишите свою) и протокол.
Второе имя хоста.
Третье, пустая строка - признак окончания запроса.

Если у Вас пишет Bad Request, скорее всего неправильно передаете вторую строку (имя хоста).
 

fandy

Member
Чтобы было совсем понятно...
Запустите telnet, введите:
o 193.107.237.64 80
GET / HTTP/1.0
Host: esp8266.ru
И еще раз Enter
и Вы получите стартовую страницу этого сайта, на котором мы сейчас (esp8266.ru)
 

obuhanoe

New member
Для того, чтобы запросить HTTP документ надо установить соединение с HTTP сервером, а затем отправить ему HTTP запрос. Минимум 3 строчки:
последовательность действий следующая:
Код:
AT+CWMODE=1
AT+CWJAP="ssid","pass"
AT+CIPSTART="TCP","site.ru",80
AT+CIPSEND=82
>
GET /page/log.php?data=QQQQWWWRR HTTP/1.1
Host: site.ru
Connection: close
Если я вас правильно понял, строку Connection: close заменить однократным нажатием Enter?

Так как нет под рукой Arduino смогу проверить вечером.

Спасибо.
 
Последнее редактирование:

obuhanoe

New member
Чтобы было совсем понятно...
Запустите telnet, введите:
Запустить - запустил, на первой команде висит и пишет идет подключение и все. Нажимаю любую клавишу - 400 Bad Request
Минимум 3 строчки:
1. GET /page.html HTTP/1.0
2. Host: yourhost.com
3. Пустая строка.
3 пункт не воспринимает, только если добавляю Connection: close
тогда опять 400 ошибка.

Что и как можно еще проверить, Спасибо.
 

fandy

Member
Запустить - запустил, на первой команде висит и пишет идет подключение и все.
Так и должно быть.


Еще раз проверил через telnet.
Все работает. Там таймаут 2 секунды, надо клавиши быстро нажимать. Если копируете и вставляете, не получится.
 

fandy

Member
Да, маленькая английская. Если в телнете ввести ?, он сам все расскажет.

Я просто пытался объяснить какой минимальный запрос надо отправить.
Но у меня 200 выдает. И код документа следом..
 

obuhanoe

New member
и Вы получите стартовую страницу этого сайта, на котором мы сейчас (esp8266.ru)
Вроде бы получилось, много символов похоже на стартовую страницу.
Тоже самое сделал для сайта на который я отправляю данные, он мне ответил HTTP/1.1 301 Moved Permanently.
Не пойму тогда почему ошибку 400 выдает из скетча?
Код:
void setup()
{
Serial.begin(9600);
Serial2.begin(9600);
Serial2.println("AT");
Serial.println("Start working!!!");
}

void loop() // run over and over
{
if (Serial2.available()){
  Serial.println(Serial2.readString());
}

String txt_in="";

if (Serial.available()) {
  txt_in=Serial.readString();
  Serial.println(txt_in);
  Serial2.println(txt_in);

}
 

fandy

Member
Я не помню точно, но вроде Serial.readString не выкидывает cr и nl из потока.
 

obuhanoe

New member
Я не помню точно, но вроде Serial.readString не выкидывает cr и nl из потока.
Команды
Код:
AT+CWMODE=1
AT+CWJAP="ssid","pass"
AT+CIPSTART="TCP","site.ru",80
AT+CIPSEND=82
выполняются же.

С удовольствием бы попробовал вместо АТ команд, готовую библиотеку.
Подойдет ли ESP8266WIFI.h для этого или что-нибудь другое посоветуете ?
 

obuhanoe

New member
Проблему решил.
Необходимо верно указывать количество отправляемых байт в команде AT+CIPSEND и после Connection: close
обязательно \r\n\r\n(если в коде) или дважды нажать на кнопку Enter(через Терминал)
 
Сверху Снизу