WeMos D1 отправка данных на удалённый сервер

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

Коннектится к сети без проблем, но не передаёт ничего в add.php. Вообще не обращается на сервер - логи пустые.

Если запустить сервер на самой плате, то всё работает, но передавать на удалённый сервер никак не хочет.

Причём не получается ни на WeMos D1 ни на CH340 Node MCU V3.

Какая-то обидная ошибка в коде, но я её в упор не вижу. Видать за вторые сутки глаз замылился((

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
const char* ssid = "Wi-Fi"; //задаем имя точки доступа, к которой будем подключаться
const char* password = "12341234"; //и пароль от этой точки доступа
const char* host = "test.site.ru";
long Pressure = 24425;
float temp_21 = 22;
float temp_22 = 33;
float t = 38;
float h = 87;
void setup() {
Serial.begin(9600); //отладочную информацию будем выводить в терминал
delay(100);
//WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password); //подключаемся к точке доступа с заданными именем и паролем
while (WiFi.status() != WL_CONNECTED) //ожидаем подключение, статус WL_CONNECTED означает что соединение установлено
  {
  delay(500);
  Serial.print(".");
  }
Serial.println("");
Serial.println("WiFi connected"); //оповещение в терминал, что соединение с точкой доступа установлено
Serial.println("Server started");
Serial.println(WiFi.localIP()); //получаем IP WeMos
Serial.println(WiFi.macAddress()); //получаем MAC-адрес WeMos
Serial.println(WiFi.subnetMask()); //маску подсети
Serial.println(WiFi.gatewayIP()); //IP- шлюза
Serial.println(WiFi.SSID());// имя сети, к которой подключен WeMos
Serial.println(WiFi.RSSI()); //и уровень сигнала
}
void loop() {
WiFiClient client;
   
if (client.connect(host, 80)) {
  Serial.println("Sending...");
  client.print("GET /add.php?");
  client.print("code=hSb2va8");
  client.print("&");
  client.print("press180=");
  client.print(Pressure);
  client.print("&");
  client.print("Dallas21=");
  client.print(temp_21);
  client.print("&");
  client.print("Dallas22=");
  client.print(temp_22);
  client.print("&");
  client.print("t=");
  client.print(t);
  client.print("&");
  client.print("h=");
  client.print(h);
  client.println(" HTTP/1.1\r\n");
  client.print( "Host: " );
  client.println(host);
  client.println( "Connection: close" );
  client.println();
  client.println();
  client.stop();
  client.flush();
  Serial.println("End sending!");
  delay(10000);
}
}

Спасибо за помощь!

b707
Offline
Зарегистрирован: 26.05.2017

после слова Host в 54 строке попробуйте указать реальный хост и после него два перевода строки, вот так:

client.print( "Host: arduino.ru\r\n\r\n" );

 

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

Попробовал. Не помогает.

Artemiy
Offline
Зарегистрирован: 20.10.2014

А попробуйте POST передавать. И логи на сервере посмотрите. Их вообще нет или может строка запроса битая?

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

Да пробовал POST - пофиг.
В том то и проблема, что логи пустые - сервер ничего не получает от платы. Если бы запрос был кривой, то это отразилось бы в логах, а здесь вообще тишина - никто к серверу не обращается.

Может криво библиотека встала?
Вы какой пользуетесь?

У меня:

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

Может плату откатить до версии 2.2, 2.1 или 2.0?

Может это глюк 2.3?

Artemiy
Offline
Зарегистрирован: 20.10.2014

Я пробовал из примеров скетч - у меня на вемосе он заработал. Я в нем правда сам еще недавно только разбираться начал.

Посмотрите Примеры -> ESP8266WIFI -> WiFiClient

  // We now create a URI for the request
  String url = "/input/";
  url += streamId;
  url += "?private_key=";
  url += privateKey;
  url += "&value=";
  url += value;
  
  Serial.print("Requesting URL: ");
  Serial.println(url);
  
  // This will send the request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" + 
               "Connection: close\r\n\r\n");

И попробуйте строку запроса обернуть как в примере.

b707
Offline
Зарегистрирован: 26.05.2017

Artemiy пишет:

И попробуйте строку запроса обернуть как в примере.

имхо, смысл не в том, как обернуть строку - а просто надо подобрать синтаксиси запроса. Я бы посоветовал написать коротенький скетч, который только отправляет запрос на сервер и показывает ответ, например, в сериале. И потом поиграть строкой запроса - нужен ли параметр Host,Connection и  сколько пустых строк в конце и тд

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

Artemiy пишет:

И попробуйте строку запроса обернуть как в примере.

Делал - пофиг.

Этот мой запрос отлично работает на изернет шилде. Вот решил wifi использовать и начались танцы с бубном.
Дело не в запросе. Если бы запрос был кривой, то это отразилось бы в логах сервера. А логи пустые. До сервера ничего не долетает.

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

b707 пишет:

поиграть строкой запроса - нужен ли параметр Host,Connection и  сколько пустых строк в конце и тд

Строка запроса отлично работает на изернет шилде на этом же сервере, с этим же add.php.  Это тот же код, только вместо изернета прописан вифи.

И подключаюсь к тому же роутеру. Только по проводам всё работает, а по воздуху - хрен.

b707
Offline
Зарегистрирован: 26.05.2017

golgofa_rus пишет:

И подключаюсь к тому же роутеру. Только по проводам всё работает, а по воздуху - хрен.

Совет тот же - упростите скетч до предела и пробуйте получить /index.html с гугля, к примеру

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

b707 пишет:

Совет тот же - упростите скетч до предела и пробуйте получить /index.html с гугля, к примеру

Есть однозначно рабочий скетч для проверки?
Чтобы не я сам писАл, опять упёрся лбом в стену и искал уже проблему в тестовом скетче, чтобы найти проблему в первоначальном...

Мой скетч прост до невозможности. До строки 36 всё однозначно работает.
Похож как две капли воды на все рабочие скетчи, которые я только встретил в инете. У всех работает, у меня хрен((

PS^ Попробовал на изернет шилде специально ломать запрос - изменять количество переводов строк, удалять куски и т.п. Данные перестают записываться в базу, но в логах сервера всё это отражено. Запросы то идут. GET срабатывает.

В случае с вифи GET не срабатывает - в логах пусто(((((

b707
Offline
Зарегистрирован: 26.05.2017

golgofa_rus пишет:

[

Есть однозначно рабочий скетч для проверки?

зачем Вам чей-то "рабочий скетч"? Надо добиться работы Вашего.

Возьмите свой код до строки 36, а дальше вставьте строки 13-15 из сообщения #6. Установите host - google.ru URL - /index.html и добавьте получения ответа и вывод его в сериал. И все.

"Чудес не бывает", если у вас до 34-36 строки все работает без ошибок, в сеть входите, IP получаете и тд - не может запрос не отрабатываться...

Кстати, попробуйте вместо имени хоста вставить IP-адрес... хотя если у вас все подключается, влиять не должно.

В общем, я о том, что гадать, что может быть не так - мы тут будем долго. Пробовать методом тыка в данном случае будет эффективнее с вашей стороны. Цель - лобиться хоть какого-то отклика от сервака. хоть с ошибками - дальше уже будет проще.

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

b707 пишет:

если у вас до 34-36 строки все работает без ошибок, в сеть входите, IP получаете и тд - не может запрос не отрабатываться...

Однозначно.

b707 пишет:

Цель - добиться хоть какого-то отклика от сервака. хоть с ошибками - дальше уже будет проще.

Абсолютно верно! Пошёл пробовать с гуглом...

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

const char* host = "google.ru";

void loop() {

//  WiFiClient client = server.available(); //создаем клиент
  WiFiClient client;
       
if (client.connect(host, 80)) {

  if ( WiFi.status() == WL_CONNECTED ) {
    Serial.println(WiFi.localIP());
  }
  Serial.println("Sending..."); 

String url = "/index.html";
url += "?private_key=";
url += "privateKey";
url += "&value=";
url += "value";

Serial.print("Requesting URL: ");
Serial.println(url);

client.print(String("GET ") + url + " HTTP/1.1\r\n" +
             "Host: " + host + "\r\n" + 
             "Connection: close\r\n\r\n");

  char aw = client.read();
  Serial.print("Server Answer: ");
  Serial.println(aw);
  
  client.stop();
  client.flush();
  
  Serial.println("End sending!");
  delay(10000);   
}

Задница какая-то((

b707
Offline
Зарегистрирован: 26.05.2017

golgofa_rus

не увидел, где у вас устанавливается host. На вский случай выводите в сериал и его, как вы это делаете с URL. И еще - я же просил из URL выкинуть все, кроме /index.html. Закомментируйте пока строки с 14 по 17

Artemiy
Offline
Зарегистрирован: 20.10.2014

golgofa_rus пишет:

Есть однозначно рабочий скетч для проверки?

Попробуйте в стандартных примерах:

Примеры -> ESP8266WIFI -> WiFiClient

К гуглу запрос идет и возвращается ответ. Сам вчера пробовал.

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

b707 пишет:

не увидел, где у вас устанавливается host. 

Плевать на этот гугл. Я с ним слепой.
Пошли запросы на мой сервак. Правда я плату поменял - вернул взад CH340 Node MCU V3
Мучаю код дальше.

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

Короче, заработало.

Итог такой: то, что 8266ethernet прекласно работает с кучей client.print, вовсе не означает, что 8266wifi тоже их переварит в таком количестве. Он хочет почему-то только один, заранее собранный client.print.

Заработало в таком виде:

Serial.println("Sending...");
  
  String url = "/add.php?";
  url += "k=752hSb2va887";
  url += "&";
  url += "press180=";
  url += Pressure;
  url += "&";
  url += "Dallas21=";
  url += temp_21;
  url += "&";
  url += "Dallas22=";
  url += temp_22;
  url += "&";
  url += "t=";
  url += t;
  url += "&";
  url += "h=";
  url += h;

  Serial.print("Requesting URL: ");
  Serial.println(host+url);

  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
             "Host: " + host + "\r\n" + 
             "Connection: close\r\n\r\n");

  client.stop();
  client.flush();
  
Serial.println("End sending!");

Я знал, что строку можно составить несколькими способами, но даже представить не мог, что один из них ну совершенно не подходит для wifi.

ОГРОМНАЯ благодарность b707  и Artemiy  !!!

b707
Offline
Зарегистрирован: 26.05.2017

golgofa_rus пишет:

Я знал, что строку можно составить несколькими способами, но даже представить не мог, что один из них ну совершенно не подходит для wifi.

Скорее всего, дело не в строке. Думаю, каждый оператор client.print() отсылал свою строку отдельным запросом - вот сервер и не мог понять, в чем дело. Отсылка по сети имеет свои особенности...

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

b707 пишет:

Отсылка по сети имеет свои особенности...

В данном случае отсылка по wifi имеет свои особенности... Не надо на другие сети наговаривать - обидятся))

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

Другая проблемка нарисовалась - String url режется до 128 знаков((
По идее же его длина ограничивается только наличием оперативной памяти?

Artemiy
Offline
Зарегистрирован: 20.10.2014

ШЛите POST, если вы отправляете данные.

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

И чем это поможет? Какое отношение POST имеет к длине строки?

b707
Offline
Зарегистрирован: 26.05.2017

golgofa_rus пишет:

Другая проблемка нарисовалась - String url режется до 128 знаков((
По идее же его длина ограничивается только наличием оперативной памяти?

Вариантов может быть масса. Если у вас большой скетч с кучей данных. может система уже не в состоянии выделить больше 128 байт непрерывныи куском. А может этот лимит где-нибудь прописан - в конфиге арудуино IDE для Вемоса или в заголовках WiFi библиотеки.

Честно говоря. я бы даже искать не стал. Что мешает разбить длинный запрос на два или три?

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

Скетч малюсенький - использую плату только для получение данных от Меги и отправки в таблицу на сервак.
Сама плата не имеет столько входов, сколько у меня датчиков. (Сразу скажу, что вешать тьму датчиков на один вход по I2C, в моём случае, не вариант вообще).
Т.е. она только получает строку и отправляет её в инет.
Свободной памяти вагон.

b707 пишет:

Что мешает разбить длинный запрос на два или три?

Да разбить вообще не проблема, но это тащит за собой другие неудобства...
Данные пишутся в таблицу. Естественно запись всех показаний - это одна строка с одним ID, временем, и должна быть записана за один раз, иначе на месте недостающих значений нули...
Придётся городить огород - разбивать таблицу на столько таблиц, скольку будет кусков для передачи.

Поэтому самый бескровный вариант - найти кто и где режет до 128-ми и увеличить хотя бы до 256...

b707
Offline
Зарегистрирован: 26.05.2017

golgofa_rus пишет:

Да разбить вообще не проблема, но это тащит за собой другие неудобства...
Данные пишутся в таблицу. Естественно запись всех показаний - это одна строка с одним ID, временем и должна быть записана за один раз, иначе на месте недостающих значение нули...
Придётся городить огород - разбивать таблицу на столько таблиц, скольку будет кусков для передачи.

Поэтому самый бескровный вариант - найти кто и где режет до 128-ми и увеличить хотя бы до 256...

я довольно много работал с БД и рискну дать несколько советов. Не обязательно разбивать таблицу "на много таблиц". Пишите в строку только те данные, что пришли, на остальных выставляйте не 0. а NULL (или любое другое значение, по которому вы четко будете видеть, что это именно "отсутствие данных" - NULL  подходит идеально). При дальнейшем анализе значения NULL очень легко отбросить.

Вообще, сама загрузка только всех данных разом - логически это не вполне правильно. Датчики могут иметь (даже должны) разный период опроса, кроме того, какой-то датчик может быть выключен или вообще отсутствовать. То есть даже если вы решите проблему с длиной строки - я бы советовал предусмотреть возможность сохранения и анализа неполных записей в таблице. Без этого вы сами ограничиваете гибкость своей системы. Изменения логики БД, имхо, тут требуются минимальные.

b707
Offline
Зарегистрирован: 26.05.2017

И еще немного - можете вообще не обращать внимания. если не согласны. Я бы... в своей базе - сделал бы так: каждое значение с датчика - отдельная строка таблицы. И таблицу бы максимально упростил - оставил бы только графы Timestamp, sensor_ID(номер датчика) и значение. Если у вас сейчас в таблице предусмотрены отдельные колонки для каждого датчика - это, вообще-то, очень плохой дизайн БД. Понадобится добавить\убрать новый датчик - будете каждый раз менять структуру всей таблицы? - а в моем варианте вообще не надо ничего менять.

Можно сделать отдельные таблицы по типу датчиков - например температурные в одну, давления в другую. Можно - по расположению - датчики комнаты1, комнаты2 и тд  Но смысл тот же - не надо предусматривать отдельные колонки под конкретный датчик. Выборка статистики по отдельном датчику из общей таблицы делается очень быстро - это именно та задача, под которую заточен SQL сервер.

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

Не. На каждый датчик ствоя строка - это жуть.
Когда всё в одной строке, то любые выборки делаются одной строкой кода в мускуле сразу по всем.
Да и чисто визуально разобраться в такой таблице намного проще. Но спорить не буду. Каждый делает как привык.

b707 пишет:

Можно сделать отдельные таблицы по типу датчиков - например температурные в одну, давления в другую. Можно - по расположению - датчики комнаты1, комнаты2 и тд  Но смысл тот же - не надо предусматривать отдельные колонки под конкретный датчик. 

Это возможный вариант, о котором я и говорил, но по затратам сил и времени, мне кажется, легче найти кто режет строку...

golgofa_rus
Offline
Зарегистрирован: 22.06.2017

b707 пишет:

Пишите в строку только те данные, что пришли, на остальных выставляйте не 0. а NULL (или любое другое значение, по которому вы четко будете видеть, что это именно "отсутствие данных" - NULL  подходит идеально). При дальнейшем анализе значения NULL очень легко отбросить.

......

я бы советовал предусмотреть возможность сохранения и анализа неполных записей в таблице. Без этого вы сами ограничиваете гибкость своей системы. Изменения логики БД, имхо, тут требуются минимальные.

Да. Здесь вы абсолютно правы. Задумался на эту тему.
Нужно просто предусмотреть возможность неполных записей и обязательно сделаю это, тем более при таком подходе не нужно создавать несколько таблиц, но пока...

Всё-таки ищу какая собака режет строковые переменные))

b707
Offline
Зарегистрирован: 26.05.2017

golgofa_rus пишет:

Не. На каждый датчик ствоя строка - это жуть.

вообще-то именно так правильно. Представьте, что у вас 100 датчиков - будете монстрячить таблицу со 100 колонками?

golgofa_rus пишет:

Когда всё в одной строке, то любые выборки делаются одной строкой кода в мускуле сразу по всем.
Да и чисто визуально разобраться в такой таблице намного проще.

Зачем делать выборку сразу по всем? Вы на одном графике будете выдавать одновременно значения температуры. влажности и давления? Мне даж интересно, приведите эту "одну строку мускула", которая выдает осмысленные результаты по всем датчикам? - просто для примера

А визуально посмотреть данные из общей таблицы совсем несложно, используйте условие where для конкретного датчика и вуаля