完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
请教各位大佬,我的项目是100多台分布设备,都采用ESP32-S3作为STA,然后他们之间通过UDP广播来无线通讯。
但是我参照《ESP32-C3物联网工程开发实战》里面的“broadcast_discovery”项目例程来改造的程序,接收和发送都保持同一个端口。却总是发送和接收不能同时存在。一旦先发送了,就再也接收不到广播了。而相反,如果先接收了数据,就不能再发送了。 请教各位,我应该怎么做,才能做到同时收发UDP广播呀?有什么方法能类似以前用AT指令的时候那样,设置多链接,然后用两个链接分别配置接收和发送呀?(AT+CIPSTART=0,"UDP","192.168.6.111",6000,3333 AT+CIPSTART=1,"UDP","255.255.255.255",3333,6000) 谢谢大家! 代码如下: static esp_err_t esp_send_broadcast( uint8_t *sendBuf, uint8_t len ) { int opt_val = 1; esp_err_t err = ESP_FAIL; struct sockaddr_in from_addr = {0}; socklen_t from_addr_len = sizeof(struct sockaddr_in); char udp_recv_buf[64 + 1] = {0}; // 创建 IPv4 UDP 套接字 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { return err; } // 设置 SO_BROADCAST 套接字选项, 使能该套接字支持广播发送 int ret = setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &opt_val, sizeof(int)); if (ret < 0) { goto exit; } // 设置广播目的地址和端口 struct sockaddr_in dest_addr = { .sin_family = AF_INET, .sin_port = htons(3333), .sin_addr.s_addr = htonl(INADDR_BROADCAST), }; // 调用 sendto 接口发送广播数据 ret = sendto(sockfd, sendBuf, len, 0, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr)); exit: close(sockfd); return err; } void app_main(void) { uartInit(); esp_err_t err = ESP_FAIL; struct sockaddr_in from_addr = {0}; socklen_t from_addr_len = sizeof(struct sockaddr_in); uint8_t udp_server_buf[64 + 1] = {0}; char *udp_server_send_buf = "ESP32-C3 Smart Light https 443"; int sockfd = 0;//IPv4 UDP 套接字 int ret = 0; // 设置广播目的地址和端口 struct sockaddr_in server_addr = { .sin_family = AF_INET, .sin_port = htons(6000), .sin_addr.s_addr = htonl(INADDR_ANY), }; while(1) { // 调用 recvfrom 接口接收广播数据 ret = recvfrom(sockfd, udp_server_buf, sizeof(udp_server_buf) - 1, 0, (struct sockaddr *)&from_addr, (socklen_t *)&from_addr_len); if (ret > 0) { uartSend(udp_server_buf, ret); } int res = uartReadData(); if(res == 1)//连接WIFI { //Initialize NVS esp_err_t ret = nvs_flash_init(); if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { ESP_ERROR_CHECK(nvs_flash_erase()); ret = nvs_flash_init(); } ESP_ERROR_CHECK(ret); ESP_LOGI(TAG, "ESP_WIFI_MODE_STA"); int a = wifi_init_sta(); if(a == 1) { uint8_t buf[3] = {01,02,03}; uartSend(buf, sizeof(buf)); //ret = esp_send_broadcast_Init(); } else { uint8_t buf[3] = {01,03,04}; uartSend(buf, sizeof(buf)); } } else if(res == 2)//建立UDP服务 { //uint8_t buf[3] = {03,03,06}; //uartSend(buf, sizeof(buf)); // 创建 IPv4 UDP 套接字 sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd == -1) { uartSendData("socket error!"); } ret = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)); if (ret < 0) { uartSendData("bind error!"); close(sockfd); } } else if(res == 5)//配置UDP发送套接字 { //ret = esp_send_broadcast_Init(); if(!ret) { uint8_t buf[3] = {03,03,06}; //uartSend(buf, sizeof(buf)); } else { uint8_t buf[3] = {03,04,07}; uartSend(buf, sizeof(buf)); } } else if(res == 3)//test { uint8_t buf[9] = {8,8,6,6,7,6,6,8,8}; //uartSend(buf, sizeof(buf)); esp_send_broadcast(buf, 9); } else if(res == 4)//test2 { uint8_t buf[10] = {1,2,3,4,5,6,7,8,9,0}; esp_send_broadcast(buf, 10); } else if(res == 6)//正常命令 { esp_send_broadcast(uartRXBuf, uartRXBufLen); } } } |
|
相关推荐
1个回答
|
|
要解决ESP32-S3作为STA无法同时进行UDP广播发送和接收的问题,可以尝试以下几种方法:
1. **使用两个不同的端口**:在ESP32-S3上创建两个UDP套接字,一个用于发送,另一个用于接收。这样,发送和接收操作可以同时进行,而不会发生冲突。 2. **使用非阻塞模式**:在ESP32-S3上使用非阻塞模式进行UDP通信。这样,即使在发送数据时,接收操作也不会被阻塞。可以通过设置套接字选项来实现非阻塞模式。 3. **使用任务调度**:在ESP32-S3上创建两个任务,一个用于发送数据,另一个用于接收数据。通过任务调度,可以确保发送和接收操作可以同时进行。 4. **使用中断或事件驱动**:在ESP32-S3上使用中断或事件驱动机制来处理UDP通信。当接收到数据时,触发一个事件或中断,然后进行处理。这样可以确保发送和接收操作可以同时进行。 5. **使用第三方库**:可以尝试使用一些第三方库,如LwIP,来实现更高级的UDP通信功能。这些库可能提供了一些内置的解决方案,可以解决发送和接收冲突的问题。 以下是使用两个不同端口的示例代码: ```c #include #include const char* ssid = "your_ssid"; const char* password = "your_password"; WiFiUDP udpBroadcast; WiFiUDP udpReceive; void setup() { Serial.begin(115200); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.println("Connecting to WiFi..."); } Serial.println("Connected to WiFi"); // 创建两个UDP套接字,一个用于发送,一个用于接收 udpBroadcast.begin(8000); udpReceive.begin(8001); } void loop() { // 发送UDP广播 sendUDPBroadcast(); // 接收UDP广播 receiveUDPBroadcast(); } void sendUDPBroadcast() { String message = "Hello, this is a broadcast message!"; udpBroadcast.beginPacket(IPAddress(255, 255, 255, 255), 8001); udpBroadcast.println(message); udpBroadcast.endPacket(); } void receiveUDPBroadcast() { int packetSize = udpReceive.parsePacket(); if (packetSize) { String receivedMessage = udpReceive.readString(); Serial.println("Received message: " + receivedMessage); } } ``` 这个示例代码创建了两个UDP套接字,一个用于发送(端口8000),另一个用于接收(端口8001)。这样,发送和接收操作可以同时进行,而不会发生冲突。 |
|
|
|
只有小组成员才能发言,加入小组>>
343 浏览 0 评论
1192 浏览 1 评论
587浏览 6评论
484浏览 5评论
有没有办法在不使用混杂模式的情况下实现Wifi驱动程序接收缓冲区访问中断呢?
468浏览 5评论
467浏览 4评论
443浏览 4评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-28 13:11 , Processed in 0.920347 second(s), Total 100, Slave 83 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号