Проблема в твиттере с ESP8266 через Thingspeak - PullRequest
0 голосов
/ 19 июня 2019

Я запрограммировал свой ESP8266 для считывания влажности почвы. В зависимости от влажности включается водяной насос. Теперь я хотел, чтобы ESP чирикнул разные предложения в зависимости от ситуации. Поэтому я подключил свой аккаунт в твиттере к thingspeak.com и следовал этому коду Подключение к интернету работает нормально.

Проблемы: Он не пишет в Твиттере каждый раз, и если он пишет в Твиттере, в Твиттере появляется только первое слово из предложения.

Согласно форуму, где я нашел код, я уже пытался заменить все пробелы между словами на "% 20". Однако тогда в твиттере вообще ничего не появляется. Также отдельные слова не всегда публикуются в твиттере.

Это код, с которым у меня проблемы:

// if connection to thingspeak.com is successful, send your tweet!
if (client.connect("184.106.153.149", 80))
{
  client.print("GET /apps/thingtweet/1/statuses/update?key=" + API + "&status=" + tweet + " HTTP/1.1\r\n");
    client.print("Host: api.thingspeak.com\r\n");
    client.print("Accept: */*\r\n");
    client.print("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n");
    client.print("\r\n");
  Serial.println("tweeted " + tweet);
}

Я не получаю никаких сообщений об ошибках. Может быть, вы могли бы помочь мне сделать это видимым, если твит был действительно отправлен, и как мне удается твитнуть целое предложение. Я использую Arduino IDE версии 1.8.9 и загружаю на эту доску Остальная часть кода работает нормально. Единственная проблема - это твит.

Обновление

Я сейчас попробовал несколько разных вещей:

  1. Проверка ответа сервера

    Работает и очень помогает. Результаты:

    • Отдельные слова, так как строка не получает никакого ответа
    • То же самое для строк типа "Test% 20Tweet"
    • Строки с несколькими словами, такими как «Test Tweet», получают следующий ответ, и первое слово строки отображается как твит

HTTP / 1.1 200 OK

Сервер: nginx / 1.7.5

Дата: ср., 19 июня 2019 г. 18:44:22 GMT

Content-Type: text / html; кодировка = UTF-8 * * тысяча сорок-три

Длина содержимого: 1

Соединение: keep-alive

Статус: 200 ОК

X-Frame-Options: SAMEORIGIN

Access-Control-Allow-Origin: *

Методы контроля доступа-разрешения: GET, POST, PUT, OPTIONS, DELETE, PATCH

Access-Control-Allow-Headers: origin, content-type, X-Requested-With

Access-Control-Max-Age: 1800

ETag: W / "RANDOM_CHARS"

Cache-Control: max-age = 0, private, must-revalidate

X-Request-Id: THE_ID

1

Я думаю, что длина содержимого может быть проблемой? Но я не знаю, как изменить это в этом коде.

  1. Проверка успешного подключения

    Я реализовал это в своем коде, и он никогда не появляется на мониторе. Поэтому я думаю, что у меня никогда не было проблем с не подключением.

  2. Использовать имя хоста вместо IP-адреса

    Я попробовал это и никогда не получал плохой запрос. С другой стороны, в твиттере вообще ничего не появляется.

1 Ответ

1 голос
/ 19 июня 2019

Проверьте, содержит ли ваша переменная tweet какие-либо символы новой строки (возврат каретки или перевод строки). Например, следующая переменная может вызвать проблемы

String tweet = "Tweet no. 1\r\n";

из-за символов новой строки в конце. Эти символы приведут к обрыву первой строки HTTP-запроса. Т.е. вместо

GET / apps / thingtweet / 1 / statuses / update? Key = api_key & status = Tweet no. 1 HTTP / 1.1 \ r \ n

стало бы

GET / apps / thingtweet / 1 / statuses / update? Key = api_key & status = Tweet no. 1 \ г \ п

и сервер отклонит его с ошибкой 400 (неверный запрос).

С другой стороны

String tweet = "Tweet no. 1";

было бы хорошо.

Если ваши твиты могут содержать такие символы, попробуйте закодировать их, прежде чем передавать их в client.print():

  tweet.replace("\r", "%0D");
  tweet.replace("\n", "%0A");

Использовать имя хоста вместо IP-адреса

Согласно https://uk.mathworks.com/help/thingspeak/writedata.html, соответствующее имя хоста для используемого вами API - api.thingspeak.com. Используйте это вместо IP-адреса. Это предпочтительно, потому что IP-адрес, на который указывает имя хоста, может регулярно меняться. (Используемый вами IP-адрес даже не является правильным - и, возможно, уже устарел.)

Т.е., изменить

if (client.connect("184.106.153.149", 80)) {

до

if (client.connect("api.thingspeak.com", 80)) {

Конечная точка API

Вы уверены, что используете правильную конечную точку API? Согласно приведенной выше ссылке, похоже, что конечная точка API вам нужна https://api.thingspeak.com/update.json - поэтому вам может потребоваться изменить

client.print("GET /apps/thingtweet/1/statuses/update?key=" + API + "&status=" + tweet + " HTTP/1.1\r\n");

до

client.print("GET /update.json?api_key=" + API + "&status=" + tweet + " HTTP/1.1\r\n");

Проверьте, успешно ли установлено соединение

В настоящее время ваше устройство отправляет HTTP-запрос, если успешно подключается к серверу, но не дает никаких указаний, если соединение не удается! Поэтому добавьте блок else для обработки этого сценария и уведомите пользователя через последовательную консоль.

if (client.connect("api.thingspeak.com", 80)) {
  client.print("GET /apps/thingtweet/1/statuses/update?key=" + API + "&status=" + tweet + " HTTP/1.1\r\n");
  // etc.
}
else {
  Serial.println("Connection to the server failed!");
}

Проверка ответа сервера

Чтобы проверить ответ от сервера, добавьте следующий блок в ваш основной цикл, который будет печатать ответ сервера через последовательную консоль.

delay(50);
while (client.available()) {
  String response_line = client.readString();
  Serial.println(response_line);
}

Чтобы уточнить: этот код должен входить в вашу loop() функцию.

Ответ должен содержать строку состояния - например, HTTP/1.1 200 OK, если запрос был успешным, или HTTP/1.1 400 Bad Request, если возникла проблема.

В случае ответа Bad request полное сообщение, скорее всего, будет содержать больше информации о точной причине, по которой запрос не был выполнен.

HTTP против HTTP

Наконец, вы уверены, что API поддерживает (обычный, незашифрованный) HTTP и HTTP? Если нет, то это может быть вашей проблемой.

...