如何在 esp8266 中接收来自 python 通过 UDP 发送的结构
How to receive the struct sent over UDP from python , in esp8266
我正在从我的电脑发送 UDP 数据包到 esp8266,但是在收到数据包之后,它在 Arduino 串行监视器中看起来像这样:
我发送的原始数据:
这里是接收端的代码块(esp8266):
void udp_rcv()
{
int packetSize = UDP.parsePacket();
if (packetSize) {
Serial.print("Received packet! Size: ");
Serial.println(packetSize);
int len = UDP.read(packet, 255);
if (len > 0)
{
packet[len] = '[=11=]';
}
Serial.print("Packet received: ");
Serial.println(packet[0]);
}
这是使用 python 从我的电脑发送 UDP 数据包的代码:
pygame.event.pump()
roll = mapping(joystick.get_axis(0),-1,1,1000,2000)
pitch = mapping(joystick.get_axis(1),1,-1,1000,2000)
yaw = mapping(joystick.get_axis(2),-1,1,1000,2000)
throttle = mapping(joystick.get_axis(3),1,-1,1000,2000)
mode = joystick.get_button(6)
# Be sure to always send the data as floats
# The extra zeros on the message are there in order for the other scripts to do not complain about missing information
message = [roll, pitch, yaw, throttle, mode, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
buf = struct.pack('>' + 'd' * len(message), *message)
sock.sendto(buf, (UDP_IP, UDP_PORT))
print( message)
我想做的就是使用我的操纵杆游戏手柄输入通过 UDP 协议将其发送到 esp8266
要跨平台发送和接收数据,您需要了解发送的数据类型和数据结构,以及发送方和接收方的Endianness。
关于您的 Python 代码
我不确定你为什么用 >
明确指定大端来打包数据,大多数现代计算机都使用小端而不是大端(除非你有摩托罗拉 68000 或 PowerPC 机器),而且Uno和ESP8266等所有MCU都是小端MCU。因此,使用 <
指定小端来打包数据会更有意义。
其次,您假设您的数据在 double
中,但如果您查看 message
上的屏幕截图,mode
绝对不是 double
,而是 int
(在大多数现代 PC 上,int
是 32 位长)。
所以不要用以下方式打包数据:
buf = struct.pack('>' + 'd' * len(message), *message)
你真正应该做的是:
buf = struct.pack('<ddddiddddddddd', *message)
关于您的 Arduino 代码
从 Python 代码发送的数据是一系列字节,可以用 C++ 表示为:
struct __attribute__((packed)) JoyStick {
double roll;
double pitch;
double yaw;
double throttle;
int32_t mode;
double array[9];
};
由于数据包数据是uint8_t
的数组(或者你可能声明的char
),将数据复制到JoyStick_t
类型的变量中会更容易,这样您就可以以 struct
.
的形式访问数据
int packetSize = UDP.parsePacket();
if (packetSize) {
Serial.printf("Received %d bytes\n", packetSize);
if (UDP.read(packet, packetSize) > 0)) {
JoyStick myJoystick; //create a struct
memcpy(&myJoystick, packet, packetSize); //copy packet array to the a struct
Serial.printf("%f %f %f %f %d\n",
myJoystick.roll,
myJoystick.pitch,
myJoystick.yaw,
myJoystick.throttle,
myJoystick.mode); // access the data in the struct
}
}
我正在从我的电脑发送 UDP 数据包到 esp8266,但是在收到数据包之后,它在 Arduino 串行监视器中看起来像这样:
我发送的原始数据:
这里是接收端的代码块(esp8266):
void udp_rcv()
{
int packetSize = UDP.parsePacket();
if (packetSize) {
Serial.print("Received packet! Size: ");
Serial.println(packetSize);
int len = UDP.read(packet, 255);
if (len > 0)
{
packet[len] = '[=11=]';
}
Serial.print("Packet received: ");
Serial.println(packet[0]);
}
这是使用 python 从我的电脑发送 UDP 数据包的代码:
pygame.event.pump()
roll = mapping(joystick.get_axis(0),-1,1,1000,2000)
pitch = mapping(joystick.get_axis(1),1,-1,1000,2000)
yaw = mapping(joystick.get_axis(2),-1,1,1000,2000)
throttle = mapping(joystick.get_axis(3),1,-1,1000,2000)
mode = joystick.get_button(6)
# Be sure to always send the data as floats
# The extra zeros on the message are there in order for the other scripts to do not complain about missing information
message = [roll, pitch, yaw, throttle, mode, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
buf = struct.pack('>' + 'd' * len(message), *message)
sock.sendto(buf, (UDP_IP, UDP_PORT))
print( message)
我想做的就是使用我的操纵杆游戏手柄输入通过 UDP 协议将其发送到 esp8266
要跨平台发送和接收数据,您需要了解发送的数据类型和数据结构,以及发送方和接收方的Endianness。
关于您的 Python 代码
我不确定你为什么用 >
明确指定大端来打包数据,大多数现代计算机都使用小端而不是大端(除非你有摩托罗拉 68000 或 PowerPC 机器),而且Uno和ESP8266等所有MCU都是小端MCU。因此,使用 <
指定小端来打包数据会更有意义。
其次,您假设您的数据在 double
中,但如果您查看 message
上的屏幕截图,mode
绝对不是 double
,而是 int
(在大多数现代 PC 上,int
是 32 位长)。
所以不要用以下方式打包数据:
buf = struct.pack('>' + 'd' * len(message), *message)
你真正应该做的是:
buf = struct.pack('<ddddiddddddddd', *message)
关于您的 Arduino 代码
从 Python 代码发送的数据是一系列字节,可以用 C++ 表示为:
struct __attribute__((packed)) JoyStick {
double roll;
double pitch;
double yaw;
double throttle;
int32_t mode;
double array[9];
};
由于数据包数据是uint8_t
的数组(或者你可能声明的char
),将数据复制到JoyStick_t
类型的变量中会更容易,这样您就可以以 struct
.
int packetSize = UDP.parsePacket();
if (packetSize) {
Serial.printf("Received %d bytes\n", packetSize);
if (UDP.read(packet, packetSize) > 0)) {
JoyStick myJoystick; //create a struct
memcpy(&myJoystick, packet, packetSize); //copy packet array to the a struct
Serial.printf("%f %f %f %f %d\n",
myJoystick.roll,
myJoystick.pitch,
myJoystick.yaw,
myJoystick.throttle,
myJoystick.mode); // access the data in the struct
}
}