Последовательное чтение и отправка в UDP
Я пытался отправить все, что получено от serial по udp, но это не работает должным образом. сторона приемника показывает номер 50 51 53 ..... результат, как показано ниже скриншота:
кто-нибудь может мне помочь, пожалуйста, исправить ?
скетч отправителя:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char* ssid = "MikroTik";
const char* password = "12345678";
unsigned int localPort = 2390;
WiFiUDP Udp;
void setup() {
delay(1000);
Serial.begin(115200);
WiFi.begin(ssid, password);
Udp.begin(localPort);
}
void loop() {
Udp.beginPacket("10.5.50.23", localPort);
int val = Serial.read();
Udp.print(val);
Udp.endPacket();
delay(10);
}
скетч приемника:
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char* ssid = "MikroTik";
const char* password = "12345678";
unsigned int localPort = 2390;
char packetBuffer[255];
WiFiUDP Udp;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED){
delay(500);
Serial.print(".");
}
Udp.begin(localPort);
}
void loop() {
delay(10);
if (Udp.parsePacket()) {
int len = Udp.read(packetBuffer, 255);
if (len > 0) {
packetBuffer[len] = 0;
Serial.println(packetBuffer);
}
}
}
@ErfanDL, 👍-1
Обсуждение1 ответ
Проблема заключается в различных интерпретациях двоичных данных и заключается в этих двух строках:
int val = Serial.read();
Udp.print(val);
То, что вы записываете в последовательный монитор, - это текст в кодировке ASCII. Каждый байт данных соответствует одному символу. Если вы пишете a
, это принимается за ASCII - представление. В шестнадцатеричном формате этот символ равен 0x61,
а в десятичном-97
. Это фактическое значение, которое передается в ESP по последовательному каналу. Затем вы считываете это в целое число. ТАКИМ образом, val
будет иметь значение 97. Затем вы используете Udp.print(val)
. Все функции print()
предназначены для создания удобочитаемого представления данных, что означает кодировку ASCII (это стандартное соглашение Arduino). Итак, в основном вы сказали здесь: "Вот у вас есть число (целое число). Распечатайте его в UDP-пакете в удобочитаемой (ASCII) форме". Таким образом, UDP-пакет теперь содержит строку ASCII "97". Вероятно, вы набрали цифру 5
, а затем 4
несколько раз. Их десятичные значения равны 53 и 52.
Вероятно, существует также функция Udp.write()
. Функции write()
по соглашению не изменяют данные. Они просто пишут это без интерпретации. Таким образом, с помощью Udp.write()
фактическое двоичное значение полученных данных будет отправлено, и буква a
будет отображаться как буква a
на последовательном выходе приемника.
Это хорошо работает до тех пор, пока вы хотите отправлять только отдельные байты в своих пакетах. Также обратите внимание, что Serial.read()
вернет -1
, если в буфере нет данных для чтения. Поэтому, чтобы справиться с этим, вам нужно увеличить код отправителя:
Считывайте только с последовательного сервера, если в буфере действительно есть данные. Вы можете использовать оператор if для этого, например:
if(Serial.available()){ // read in this if statement
Считывание всех данных с последовательного до определенного символа - разделителя, который отмечает конец полного сообщения. Обычно
для этого используется символ новой строки \n. Вы можете настроить последовательный монитор так, чтобы он использовал символ новой строки в качестве окончания строки (затем он добавляется к набранному тексту при нажатии клавиши Enter). В Интернете есть много примеров кодов для этого.
- Как читать и записывать EEPROM в ESP8266
- Как сделать выводы Tx и Rx на ESP-8266-01 в выводах GPIO?
- Как навсегда изменить скорость передачи данных ESP8266 (12e)?
- Как заставить 5-вольтовое реле работать с NodeMCU
- Как исправить: Invalid conversion from 'const char*' to 'char*' [-fpermissive]
- ESP8266 не подключается к Wi-Fi
- AT-команда не отвечает на последовательный монитор
- Разница между этими двумя платами NodeMCU?
спасибо за ответ. извините, я новичок в кодировании arduino можете ли вы помочь мне и отредактировать мой код, чтобы он работал правильно ?, @ErfanDL
Какая именно помощь вам нужна? Я объяснил, что вы должны заменить Udp.print() на Udp.write(). Дальнейшие правки зависят от того, что вы хотите сделать с кодом. Вы действительно описали это., @chrisl
хорошо, я перешел на Udp.write(val), но на стороне приемника отображается только первый номер последовательного чтения. например, вместо того, чтобы показывать число 300, он отображает число 3, @ErfanDL
Это та часть, которая касается чтения до символа-разделителя. Например, для этого вы можете использовать Serial.readStringUntil('\n'). Это блокирующая функция, но это должно быть нормально для вашего случая. Извините, но я не буду писать код за вас. В Интернете есть много примеров кодов и учебных пособий по этому поводу. Вы также можете посмотреть на пример
serialEvent
, который поставляется с Arduino IDE, @chrislПомимо проблем с кодом, я надеюсь, вы понимаете, что UDP не является "надежным" протоколом. Это не гарантирует, что вы получите все, что было отправлено, и не скажет вам, если что-то упадет., @romkey