ESP8266 отправляет TCP HEX-пакет из 4 символов
Я создаю пульт дистанционного управления для своих WiFi-RGB-ламп. У меня есть ESP8266, который должен отправлять один TCP-пакет с 4 символами.
Мой код:
#include <ESP8266WiFi.h>
const char* ssid = "Wifi";
const char* password = "wifikey";
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
}
void setup() {
Serial.begin(115200);
WiFi.disconnect(true);
delay(1000);
WiFi.onEvent(WiFiEvent);
WiFi.begin(ssid, password);
}
void loop() {
delay(1000);
const uint16_t port = 5577;
const char * host = "192.168.178.150";
WiFiClient client;
client.connect(host, port);
client.print(char(0x71));
client.print(char(0x24));
client.print(char(0x0f));
client.print(char(0xa4));
client.flush();
client.stop();
delay(5000);
}
Проблема: я отправляю 4 TCP-пакета, хотя должен отправить 1 TCP-пакет со всеми 4 символами.
Спасибо за помощь.
@Bonar Scripta, 👍0
Обсуждение1 ответ
После поисков и экспериментов по этому вопросу я пришел к выводу, что краткий ответ на этот вопрос заключается в том, что вам нужно отправить командную строку как буфер символов И поместить вашу шестнадцатеричную кодированную команду для контроллера светодиода как экранированную строку символов.
Вот мой код (он переключает контроллер светодиодов между зеленым и синим каждые 5 секунд, но вы можете расширить его для других команд и цветов, как описано на http://jpelectron.com/sample/Electronics/WiFi%20LED%20control/):
/*
Отправка команд на светодиодный контроллер через сеть Wi-Fi и плату Wemos D1
*/
#include <ESP8266WiFi.h>
const char* ssid = "***yourWifiSSID***"; //Измените это значение для вашей сети
const char* password = "***yourWifiPassword***"; //Измените это значение для вашей сети
boolean connected = false;
boolean colorToggle = false;
void WiFiEvent(WiFiEvent_t event) {
//Serial.printf("[WiFi-event] событие: %d\n", event);
switch(event) {
case 3:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connected = true;
break;
case 6:
Serial.println("WiFi lost connection");
connected = false;
break;
}
// 0 : WL_IDLE_STATUS, когда Wi-Fi находится в процессе смены статусов
// 1 : WL_NO_SSID_AVAIL в случае, если настроенный SSID не может быть достигнут
// 3 : WL_CONNECTED после успешного установления соединения
// 4 : WL_CONNECT_FAILED если пароль неверный
// 6 : WL_DISCONNECTED, если модуль не настроен в режиме станции
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT); // Инициализируем вывод LED_BUILTIN как выход
Serial.begin(115200);
WiFi.disconnect(true);
delay(1000);
WiFi.onEvent(WiFiEvent);
WiFi.begin(ssid, password);
Serial.println("");
// Ожидание соединения
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
// функция цикла выполняется снова и снова вечно
void loop() {
//если мы подключены
if(connected){
digitalWrite(LED_BUILTIN, LOW); //Включаем светодиод на плате
turnLEDSOn();
}
else
{
digitalWrite(LED_BUILTIN, HIGH); //Выключаем светодиод на плате
setup();
}
}
void turnLEDSOn() {
const uint16_t port = 5577;
const char * host = "192.168.10.2"; //Измените на IP-адрес вашего контроллера светодиодов
WiFiClient client;
if (client.connect(host, port)) //Попробовать подключиться к TCP-серверу
{
Serial.println("Connected to LED Controller... ");
if (colorToggle)
{ //Зеленый
char command[] = "\x31\x00\xff\x00\x00\x00\xf0\x0f\x2f";
client.write((uint8_t *)command, sizeof(command));
colorToggle = false;
delay(5000);
}
else
{ //Синий
char command[] = "\x31\x00\x00\xff\x00\x00\xf0\x0f\x2f";
client.write((uint8_t *)command, sizeof(command));
colorToggle = true;
delay(5000);
}
Serial.println("Command sent ... "); // команда — это цвет или анимация, отправляемая на контроллер светодиода
}
else
{
Serial.println("connection failed ... ");
}
if (client.available())
{
//Чтение с контроллера светодиодов
char c = client.read();
Serial.print(c);
}
if (!client.connected())
{
Serial.println();
Serial.println("disconnecting ... ");
client.stop();
for(;;);
}
}
- ESP8266 TCP-соединение WiFiClient проблема
- Веб-сервер ESP8266 недоступен через 2 минуты после сброса
- ESP8266 не подключается к Wi-Fi
- Как подключить Wi-Fi Shield ESP-12E-ESP8266-UART-WIFI-Wireless-Shield к Arduino
- Можно ли отключить WiFi на ESP8266?
- Несколько клиентских серверов через Wi-Fi
- Как отключить или остановить точку доступа в ESP8266?
- ESP8266 — действительно ли у него по умолчанию плохой радиус действия Wi-Fi?
Поток данных TCP не ориентирован на пакеты, скорее, это деталь, скрытая в самой реализации; правильно реализованный TCP-сервер *должен* принимать данные, поступающие в любой комбинации пакетов, включая один символ на пакет, слова или строки, разбитые между пакетами, пакеты, содержащие конец одного объекта и начало другого и т. д., @Chris Stratton
Вы можете попробовать отправить все символы одним print(), но по сути вы пытаетесь использовать недокументированное поведение одного объекта, чтобы приспособиться к ошибочному поведению другого., @Chris Stratton
Похоже, проблема на принимающей стороне. Попробуйте сдвинуть/сделать ИЛИ всех значений в один
unsigned long
и отправить его одним вызовомprint
., @Johnny Mopp