ESP8266 отправляет данные на сайт, но не возвращает статус

У меня проблема с моим esp8266, он подключается к моему сайту и отправляет 89 байт данных, но возвращает статус подтверждения, все, что я получаю, это ОТПРАВИТЬ ОК, но я не получаю подтверждения от своего сервера

Это мой код ниже

 #include <SoftwareSerial.h>
#include<time.h>

SoftwareSerial ESP8266(3, 2); // прием, передача
//ОПРЕДЕЛИТЕ ЗДЕСЬ ВСЕ ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
unsigned int timeout_start_val;
char scratch_data_from_ESP[20];//первый байт - это длина байтов
char payload[150];
byte payload_size=0, counter=0;
char ip_address[16];
char youtube_subs[10];
char youtube_views[13];
char current_temp[5];
char hi_temp[5];
char lo_temp[5];

//РЕЖИМЫ
const char CWMODE = '3';//CWMODE 1=СТАНЦИЯ, 2=APMODE, 3=ОБА
const char CIPMUX = '1';//CIPMUX 0=одно подключение, 1=несколько подключений
//Пароль

const char SSID_ESP[]="Xamel";//"AOTEA TZ";//из константы

const char SSID_KEY[]="cewu5103";//"wyrnC592";

//ОПРЕДЕЛИТЕ ЗДЕСЬ КЛЮЧЕВЫЕ СЛОВА
const char keyword_OK[]="OK";
const char keyword_FAIL[]="FAIL";
const char keyword_Ready[] = "Ready";
const char keyword_no_change[] = "no change";
const char keyword_blank[] = "#&";
const char keyword_ip[] = "192.";
const char keyword_rn[] = "\r\n";
const char keyword_quote[] = "\"";
const char keyword_carrot[] = ">";
const char keyword_sendok[] = "SEND OK";
const char keyword_linkdisc[] = "Unlink";
const char keyword_CHECKCWMODE[] = "+CWMODE:3";
const char keyword_URL_CONNECTION_ERROR[]="Link typ ERROR";
const char TEST_URL[]="";

const char GET_URL[]="GET /ESP8266_BackEnd/SaveDetail.php?Name=";
int str1=strlen(GET_URL);
const char Name[]="Alex ";
int str2=strlen(Name);


const char TRAILING_URL[]="HTTP/1.1 \\r\\nHost: www.pick2get.com\\r\\n\\r\\n";
int str3=strlen(TRAILING_URL);
int strTotal=str1+str2+str3;

const char AT_CIPSTART[]="AT+CIPSTART=4,\"TCP\",\"pick2get.com\",80 \r\n";
const char AT_CIPSEND[]="AT+CIPSEND=4,";
//прототип функции
boolean read_until_ESP(const char keyword1[], int key_size, int timeout_val, byte mode);
void serial_dump_ESP();
boolean setup_ESP(const char SSID_ESP[],const char SSID_KEY);
String url="&School=4D616B6F6E676F";
void setup() {
  // Открытие последовательной связи и ожидание открытия порта:
  Serial.begin(9600);
  while (!Serial) {
    ; // ждем подключения последовательного порта. Требуется только для родного порта USB
  }


  //.print("Общая длина строки");Serial.println(strTotal);

  // устанавливаем скорость передачи данных для порта SoftwareSerial
  ESP8266.begin(9600);
  //

  //Serial.println(read_until_ESP(keyword_URL_CONNECTION_ERROR,sizeof(keyword_URL_CONNECTION_ERROR),5000,0));
  setup_ESP(SSID_ESP,SSID_KEY);

  ESP8266.print(AT_CIPSTART);
  ESP8266.print("");
  delay(1000);

  ESP8266.print(AT_CIPSEND);
  ESP8266.print(strTotal);
  ESP8266.print("\r\n");
  delay(1000);
  ESP8266.print("");
  ESP8266.print(GET_URL);
  ESP8266.print(Name);
  ESP8266.print(TRAILING_URL);
  delay(1000);
  ESP8266.print("");
  //ESP8266.println("&Grade=466F726D204F6E65");
  //ESP8266.println("&DeviceIP=3139322E3136382E302E31");
  //ESP8266.println(TRAILING_URL);



}

void loop() { // повторяем снова и снова
  byte buffer[300];
  if (ESP8266.available()) {
   Serial.write(ESP8266.read());
  }
  if (Serial.available()) {
    ESP8266.write(Serial.read());
  }
}

Это вывод, созданный на последовательном мониторе

ESP CHECK OK
ESP RESET OK
ESP RESET OK
timeout
ESP CWMODE SET FAILED
CWMODE ALREADY SET
SETTING SSID_ESP: Xamel
SETTING SSID_KEY: cewu5103
ESP SSID SET OK DEVICE CONNECTED
CHECKING FOR AN IP ADDRESS
IP ADDRESS = 192.168.4.1
ESP CIPMUX SET
AT+CIPSTART=4,"TCP","pick2get.com",80 


OK
Linked
AT+CIPSEND=4,89

> GET /ESP8266_BackEnd/SaveDetail.php?Name=Alex HTTP/1.1 \r\nHost: www.pick2get.com\r\n\r\n
SEND OK

OK
Unlink

Может ли кто-нибудь помочь здесь.

При добавлении ESP8266.print("+IPD\r\n"); это результат, который я получаю

    ESP CHECK OK
ESP RESET OK
ESP RESET OK
timeout
ESP CWMODE SET FAILED
CWMODE ALREADY SET
SETTING SSID_ESP: Xamel
SETTING SSID_KEY: cewu5103
ESP SSID SET OK DEVICE CONNECTED
CHECKING FOR AN IP ADDRESS
IP ADDRESS = 192.168.4.1
ESP CIPMUX SET
AT+CIPSTART=4,"TCP","pick2get.com",80 

AT+CIPSEND=4,89

busy p...

OK
Linked
GET /ESP8266_BackEnd/SaveDetail.php?Name=Alex HTTP/1.1 \r\nHost: www.pick2get.com\r\n\r\n

wrong syntax

ERROR
AT+IPD


ERROR

Мне удалось исправить отсутствие ответа сервера, удалив \r\n \nd и заменив их обычными \r\n\r\n

enter code here
const char TRAILING_URL[]="HTTP/1.1 \r\nHost: www.pick2get.com \r\n\r\n";
int str3=strlen(TRAILING_URL);
int strTotal=str1+str2+str3;

const char AT_CIPSTART[]="AT+CIPSTART=4,\"TCP\",\"pick2get.com\",80 \r\n";
const char AT_CIPSEND[]="AT+CIPSEND=4,";

В этих строках удалось получить ответ сервера

+IPD,4,392:HTTP/1.1 400 Неверный запрос Дата: вторник, 15 мая 2018 г., 12:07:08 по Гринвичу Сервер: Апач Длина контента: 226 Подключение: близко Тип содержимого: текст/html; кодировка = iso-8859-1

ошибка 400, неверный запрос Неверный запрос

Ваш браузер отправил запрос, который этот сервер не смог понять.

наконец-то я отладил и исправил все ошибки, и код работает просто отлично Это и сервер возвращает статус 200

Оказывается, я просто указал GET-запросу неправильный путь к папке с этим кодом строки в переменной GET_URL

const char GET_URL[]="GET pick2get.com/ESP8266_BackEnd/SaveDetail.php?Name=";

Я заменил это

const char GET_URL[]="GET /ESP8266_BackEnd/SaveDetail.php?Name=";

И получили желаемый результат

+IPD,4,166:HTTP/1.1 200 ОК Дата: вторник, 15 мая 2018 г., 12:22:49 по Гринвичу Сервер: Апач Улучшение: h2 Подключение: Обновление Передача-кодирование: по частям Тип контента: text/html

2

ОК

+IPD,4 191:16 Подключено успешно 5с ДАННЫЕ ПЕРЕДАНЫ УСПЕШНО ИМЯ СТУДЕНТА ПОЛУЧЕНО: Alex
ИМЯ СТУДЕНТА ПОЛУЧЕНО:
3б ПОЛУЧЕНА СТУДЕНЧЕСКАЯ ОЦЕНКА:
ПОЛУЧЕНО IP-АДРЕС УСТРОЙСТВА:

ОК

+IPD,4,42:1f Новая запись успешно создана 0 Большое спасибо, ребята, ниже приведен полный рабочий код

 /*
Множественный серийный тест программного обеспечения

Получает от аппаратного серийного номера, отправляет на Software Serial.
Получает от SoftwareSerial, отправляет hardware serial.

Схема:
* RX — это цифровой контакт 10 (подключение к TX другого устройства)
* TX — это цифровой контакт 11 (подключается к RX другого устройства)

Примечание:
Не все выводы на Mega и Mega 2560 поддерживают прерывания изменения,
поэтому для RX можно использовать только следующее:
10, 11, 12, 13, 50, 51, 52, 53, 62, 63, 64, 65, 66, 67, 68, 69

Не все выводы на Leonardo и Micro поддерживают прерывания изменения,
поэтому для RX можно использовать только следующее:
8, 9, 10, 11, 14 (МИСО), 15 (СКК), 16 (МОСИ).

созданный еще в глубине веков
изменено 25 мая 2012 г.
Нолави Соломон



*/
#include <SoftwareSerial.h>
#include<time.h>

Программное обеспечение Serial ESP8266(3, 2); // прием, передача
//ОПРЕДЕЛИТЕ ЗДЕСЬ ВСЕ ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ
беззнаковое целое время timeout_start_val;
charcratch_data_from_ESP[20];//первый байт - это длина байтов
символьная полезная нагрузка[150];
byte payload_size=0, counter=0;
char ip_адрес[16];


//РЕЖИМЫ
const char CWMODE = '3';//CWMODE 1=СТАНЦИЯ, 2=APMODE, 3=ОБА
const char CIPMUX = '1';//CIPMUX 0=одно подключение, 1=несколько подключений
//Пароль

const char SSID_ESP[]="Xamel";//"AOTEA TZ";//из константы

const char SSID_KEY[]="cewu5103";//"wyrnC592";

//ОПРЕДЕЛИТЕ ЗДЕСЬ КЛЮЧЕВЫЕ СЛОВА
const char keyword_OK[]="OK";
const char keyword_FAIL[]="FAIL";
const char keyword_Ready[] = "Готово";
const char keyword_no_change[] = "без изменений";
const char keyword_blank[] = "#&";
const char keyword_ip[] = "192.";
const char keyword_rn[] = "\r\n";
const char keyword_quote[] = "\"";
const char keyword_carrot[] = ">";
const char keyword_sendok[] = "ОТПРАВИТЬ ОК";
const char keyword_linkdisc[] = "Отключить связь";
const char keyword_CHECKCWMODE[] = "+CWMODE:3";
const char keyword_URL_CONNECTION_ERROR[]="ОШИБКА типа ссылки";
//const char TEST_URL[]="";

const char GET_URL[]="GET /ESP8266_BackEnd/SaveDetail.php?Name=";
int str1 = strlen (GET_URL);
const char Имя[]="Алекс";
int str2 = strlen (имя);


const char TRAILING_URL[]="HTTP/1.1\r\nХост: www.pick2get.com \r\n\r\n";
int str3 = strlen (TRAILING_URL);
int strTotal=str1+str2+str3;

const char AT_CIPSTART[]="AT+CIPSTART=4,\"TCP\",\"pick2get.com\",80 \r\n";
const char AT_CIPSEND[]="AT+CIPSEND=4,";
//прототип функции
логическое значение read_until_ESP (const char ключевое слово1 [], int key_size, int timeout_val, байтовый режим);
недействительными serial_dump_ESP();
логическое значение setup_ESP(const char SSID_ESP[],const char SSID_KEY);
//String url="&School=4D616B6F6E676F";
недействительная установка () {
// Открытие последовательной связи и ожидание открытия порта:
Серийный.начать(9600);
пока (!Серийный) {
; // ждем подключения последовательного порта. Требуется только для родного порта USB
}


//.print("Общая длина строки");Serial.println(strTotal);

// устанавливаем скорость передачи данных для порта SoftwareSerial
ESP8266.начало(9600);
//

//Serial.println(read_until_ESP(keyword_URL_CONNECTION_ERROR,sizeof(keyword_URL_CONNECTION_ERROR),5000,0));
setup_ESP (SSID_ESP, SSID_KEY);

ESP8266.print(AT_CIPSTART);
ESP8266.print("");
delay(1000);

ESP8266.print(AT_CIPSEND);
ESP8266.print(strTotal);
ESP8266.print("\r\n");
delay(1000);
ESP8266.print("");
ESP8266.print(GET_URL);
ESP8266.print(Имя);
ESP8266.print(TRAILING_URL);
// задержка (3000);
//ESP8266.print("");
// задержка (2000);
//ESP8266.print("\r\n");
// задержка (2000);
//ESP8266.print("");
//ESP8266.print("AT+IPD\r\n");
//ESP8266.println("&Grade=466F726D204F6E65");
//ESP8266.println("&DeviceIP=3139322E3136382E302E31");
//ESP8266.println(TRAILING_URL);



}

void loop() { // повторяем снова и снова
байтовый буфер[300];
если (ESP8266.доступно()) {
Serial.write(ESP8266.read());
}
если (серийный.доступный()) {
ESP8266.write(Serial.read());
}
}


логическое значение read_until_ESP (const char ключевое слово1 [], int key_size, int timeout_val, байтовый режим) {
timeout_start_val=millis();//для тайм-аута
char data_in[20];//это буфер - если ключевое слово длиннее 20, то увеличить его
intcratch_length=1;//длина массива рабочих данных
key_size--;//поскольку мы собираемся получить лишний символ от sizeof()

// ЗАПОЛНЯЕМ БУФЕР
for(byte i=0; i<key_size; i++){//нам нужен только буфер, если ключевое слово

//управление временем
while(!ESP8266.available()){//ждите, пока новый байт не будет отправлен из ESP – хороший способ синхронизировать работу с последовательным портом.
if((millis()-timeout_start_val)>timeout_val){//если в течение тайм-аута ничего не происходит, уходите отсюда
Serial.println ("время ожидания");
return 0;//это завершит функцию
}//тайм-аут
}// пока !доступно

data_in[i]=ESP8266.read();// сохраняем байт в буфер 'data_in[]

if(mode==1){//это сохранит все данные в файлеcrat_data_from
cratch_data_from_ESP[scratch_length]=data_in[i];//начинается с 1
cratch_data_from_ESP[0]=scratch_length;// [0] используется для хранения длины массива
cratch_length++;//увеличиваем длину
}//режим 1

}//для я

// БУФЕР ЗАПОЛНЕН, ПОЭТОМУ НАЧНИТЕ ВВОД НОВЫХ ДАННЫХ И ИЗВЛЕЧЕНИЕ СТАРЫХ ДАННЫХ
while(1){//оставаться здесь, пока не будет найдено ключевое слово или не истечет время ожидания

//проходим по всему буферу и ищем ключевое слово
//эта проверка здесь, на тот случай, если первое, что было выведено из ESP, было ключевым словом, означающим, что буфер действительно был заполнен ключевым словом
for(byte i=0; i< key_size; i++){
if(keyword1[i]!=data_in[i])//если не совпадает, выходим из поиска
перерыв; // убирайся отсюда
if(i==(key_size-1)){//мы полностью прошли ключевое слово, не нарушая его, должно быть совпадение!
вернуть 1; // верни 1 и убирайся отсюда!
}//если
}//для байта i


//запускаем буфер
for(byte i=0; i<(key_size-1); i++){// keysize-1, потому что все смещено – см. следующую строку
data_in[i]=data_in[i+1];// таким образом, данные с номером 0 становятся данными с номером 1 и т. д.... последнее значение — это место, куда мы поместим новые данные
}//для


//управление временем
while(!ESP8266.available()){// то же самое, что и в буфере
if((millis()-timeout_start_val)>timeout_val){
Serial.println ("время ожидания");
вернуть 0;
}//тайм-аут
}// пока !доступно



data_in[key_size-1]=ESP8266.read();//сохраняем новые данные в последней позиции в буфере

if(mode==1){//продолжать сохранять все, если это установлено
cratch_data_from_ESP[scratch_length]=data_in[key_size-1];
скретч_данные_из_ESP[0]=скретч_длина;
скретч_длина++;
}//режим 1

/* ТОЛЬКО ДЛЯ ОТЛАДКИ
если(ESP8266.переполнение())
Serial.println("*ПЕРЕВЕРНИТЕ");
*/

}//пока 1




}//читаем до ESP


логическое значение setup_ESP(const char SSID_ESP[],const char SSID_KEY[]){//возвращает 1 в случае успеха

ESP8266.print("AT\r\n");// Отправьте только 'AT', чтобы убедиться, что ESP отвечает
//эта функция read_until_... используется для поиска ключевого слова в ответе ESP — подробнее об этом позже и в самой функции
if(read_until_ESP(keyword_OK,sizeof(keyword_OK),5000,0))//ищем ключевое слово "ОК" с тайм-аутом 5 секунд
Serial.println("ПРОВЕРКА ESP ОК");
еще
Serial.println ("ОШИБКА ПРОВЕРКИ ESP");
serial_dump_ESP();//это просто считывает все, что находится в буфере, и то, что еще поступает из ESP

ESP8266.print("AT+RST\r\n");// Сделайте сброс - кто знает, в каком состоянии он был, лучше начать заново
if(read_until_ESP(keyword_Ready,sizeof(keyword_Ready),5000,0))//находим ключевое слово "Готово" - выполнение занимает на несколько секунд больше
Serial.println("ESP RESET OK");//в зависимости от версии FW на ESP, иногда Ready пишется строчной буквой r - готово
еще
Serial.println("ОШИБКА СБРОСА ESP");
серийный_дамп_ESP();
ESP8266.print("AT+RST\r\n");// Сделайте сброс - кто знает, в каком состоянии он был, лучше начать заново
if(read_until_ESP(keyword_Ready,sizeof(keyword_Ready),5000,0))//находим ключевое слово "Готово" - выполнение занимает на несколько секунд больше
Serial.println("ESP RESET OK");//в зависимости от версии FW на ESP, иногда Ready пишется строчной буквой r - готово
еще
Serial.println("ОШИБКА СБРОСА ESP");
серийный_дамп_ESP();

ESP8266.print("AT+CWMODE=");// устанавливаем CWMODE
ESP8266.print(CWMODE);//просто отправить то, что установлено в константе
ESP8266.print("\r\n");
if(read_until_ESP(keyword_OK,sizeof(keyword_OK),1000,0))//находим ключевое слово "ОК"
Serial.println ("ESP CWMODE SET");
еще

Serial.println("ESP CWMODE SET FAILED");//вероятно, произойдет сбой, так как возвращается "без изменений", если уже установлено - было бы неплохо проверить два слова
ESP8266.println("AT+CWMODE?");
if(read_until_ESP(keyword_CHECKCWMODE,sizeof(keyword_CHECKCWMODE),1000,0))
{
Serial.println("CWMODE УЖЕ УСТАНОВЛЕН");
серийный_дамп_ESP();
}
серийный_дамп_ESP();

//Здесь устанавливаются SSID и PW
Serial.print("НАСТРОЙКА SSID_ESP: ");
Serial.println(SSID_ESP);
Serial.print("НАСТРОЙКА SSID_KEY: ");
Serial.println(SSID_KEY);
//Точка DEbug


ESP8266.print("AT+CWJAP=");//
ESP8266.print("\"");
ESP8266.print(SSID_ESP);//
ESP8266.print("\",\"");
ESP8266.print(SSID_KEY);//
ESP8266.print("\"\r\n");
if(read_until_ESP(keyword_OK,sizeof(keyword_OK),5000,0)==1)//находим ключевое слово "ОК"
Serial.println("ESP SSID SET OK DEVICE CONNECTED");
иначе, если (read_until_ESP (keyword_FAIL, sizeof (keyword_FAIL), 5000,0) == 1)
Serial.println ("ESP SSID SET FAILED");
серийный_дамп_ESP();

// Это проверяет и сохраняет IP-адрес
Serial.println("ПРОВЕРКА IP-АДРЕСА");
ESP8266.print("AT+CIFSR\r\n");//команда для получения IP-адреса из ESP
if(read_until_ESP(keyword_rn,sizeof(keyword_rn),10000,0)){//ищите первый \r\n после AT+CIFSR echo - режим примечания '0', IP-адрес сразу после этого
if(read_until_ESP(keyword_rn,sizeof(keyword_rn),1000,1)){//ищите второй \r\n и сохраняйте все, что он получает, mode='1'
// сохраняем IP-адрес в своей переменной ip_address[]
for(int i=1; i<=(scratch_data_from_ESP[0]-sizeof(keyword_rn)+1); i++)//что i<=... потребует некоторого объяснения, см. следующие строки
ip_address[i] =cratch_data_from_ESP[i];//заполняем ip_address полученными скретч-данными
//i=1, потому что i=0 - это длина данных, найденных между двумя ключевыми словами, НО это включает длину второго ключевого слова, поэтому i<= до длины минус
// размер ключевого слова, но помните, что sizeof() вернет один дополнительный, который будет вычтен, поэтому я просто добавил его обратно в +1
ip_address[0] = (scratch_data_from_ESP[0]-sizeof(keyword_rn)+1);//сохраняем длину ip_address в [0], то же самое, что и раньше
Serial.print("IP ADDRESS = ");//распечатайте его для проверки
for(int i=1; i<=ip_address[0]; i++)//отправляем IP-адрес
Serial.print(ip_address[i]);
Серийный.println("");
}}//если сначала \r\n
еще
Serial.print("ОШИБКА IP-АДРЕСА");
серийный_дамп_ESP();

ESP8266.print("AT+CIPMUX=");// устанавливаем CIPMUX
ESP8266.print(CIPMUX);//из константы
ESP8266.print("\r\n");
if(read_until_ESP(keyword_OK,sizeof(keyword_OK),5000,0))//находим ключевое слово "ОК" или "без изменений"
Serial.println("ESP CIPMUX SET");
еще
Serial.println ("ESP CIPMUX SET FAILED");
серийный_дамп_ESP();


//вот и все! Можно сделать, вложив все вместе, поэтому, если что-то не получается, он возвращает «0», а если он проходит весь путь, он возвращает «1» ... ну ладно



}//настройка ESP

// довольно простая функция - прочитать все из последовательного буфера и все, что приходит, и избавиться от этого
недействительными serial_dump_ESP () {
температура угля;
пока(ESP8266.доступно()){
темп =ESP8266.read();
delay(1);//можно поэкспериментировать с этим значением, если происходит переполнение буфера
}//пока


}//серийный дамп

, 👍-1

Обсуждение

Что произойдет, если вы напишете +IPD\r\n в качестве следующей AT-команды? (https://github.com/espressif/ESP8266_AT/wiki/IPD), @Maximilian Gerhardt

@MaximilianGerhardt Можете ли вы рассказать подробнее, я почти новичок с esp8266, @Charles

Я думаю, вам нужно отправить эту дополнительную AT-команду для получения данных. Добавьте ESP8266.print("+IPD\r\n"); в качестве последнего оператора в вашей функции setup. См. https://www.espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf, @Maximilian Gerhardt

Я добавил эту команду AT, и, похоже, есть синтаксическая ошибка., @Charles

Отредактируйте свой вопрос с обновленным кодом и ошибкой., @Maximilian Gerhardt

Можете попробовать команду "+IPD,500\r\n". Это должно запросить 500 байт от соединения. Попробуйте поиграть с цифрой., @Maximilian Gerhardt

\\r\\n; Вы уверены, что вам нужно дважды экранировать эти новые строки?, @Gerben

@Gerben большое спасибо, очевидно, заменив \\r\\n на обычный \r\n, я получаю ответ, видимо, его статус 400, но он все еще прогрессирует :), @Charles

У @Gerben когда-либо была ситуация, когда esp8266 просто зависал после отправки запроса на получение, @Charles

С ESP ничего не делал. Попробуйте выяснить, где программа останавливается. В большинстве случаев это просто программная проблема. Если программа время от времени перестает работать, вы можете рассмотреть возможность включения WatchDog., @Gerben


1 ответ


1

В заголовке http должно быть указано "Connection: keep-alive", по умолчанию стоит "Connection: close", и поэтому вы никогда не получите ничего взамен от сервера.

Я описал все это вместе с образцом кода в https://arduino.stackexchange.com/a/54558/48149

.

В примере кода используется библиотека WifiEsp для подключения к ESP8266.

,

Да, спасибо, я исправил это давно, но все равно большое уважение за ваш вклад, @Charles