UDP双向通讯实验-Arduino中文社区 - Powered by Discuz! Archiver

vany5921 发表于 2019-11-18 14:02

UDP双向通讯实验

本帖最后由 vany5921 于 2019-11-18 14:56 编辑

   UDP使用较为简单,相较于TCP/IP来说,不需要验证发送的数据是否被接收,通常用于对数据结果时效性和准确性不敏感的场合,减轻系统数据传输负担。下列代码将使用FreeRTOS来实现双核工作,核心1用于UDP数据收发,核心0用于屏幕显示。按键A控制对方移动方向,按键B控制对方颜色,长按C控制对方停止。



主机1
#include <M5Stack.h> //ver 0.2.9
#include <WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "M5-2.4G"; //建立wifi-AP
const char* password = "88888888"; //设置密码

const char * to_udp_address = "192.168.4.2"; //IP地址
const int to_udp_port = 55556; //UDP发送端口
const int my_server_udp_port = 55555; //UDP接收端口

WiFiUDP udp;//引用udp
TaskHandle_t task_handl; //

uint8_t receive_position_data = 0; //接收坐标信息
uint8_t receive_direction = 0; //接收移动方向
uint8_t receive_color_data = 0; //接收颜色
uint8_t old_line_data = 0; //
uint8_t old_color_data = 0;//
boolean isDisp_ok = false; //确认显示状态
boolean isSet_send_data = false;//
boolean isSend_rect_move = false; //确认方块移动
int16_t send_position = 0; //发送对方坐标
uint8_t send_direction = 0; //发送对方移动方向
uint8_t send_color_num = 0; //发送对方颜色
uint32_t now_time = 0;
int16_t interval = 100; //设置时间间隔
uint8_t rect_width = 63; //方块宽度
uint8_t rect_height = 100; //方块高度
uint32_t color_data = {TFT_WHITE,   
                        TFT_RED,
                        TFT_GREEN,
                        TFT_BLUE,
                        TFT_YELLOW,
                        TFT_MAGENTA,
                        TFT_CYAN};

//********* core 1 task ************
void setup() {
Serial.begin(115200);
delay(1000);
setupWiFiUDPserver(); 开启UDP服务
xTaskCreatePinnedToCore(&taskDisplay, "taskDisplay", 8192, NULL, 10, &task_handl, 0); 创建多任务
delay(500); //
}

void loop() {
receiveUDP();
if(isSend_rect_move) autoIncDec(interval);
sendUDP();
}
//******** core 0 task *************
void taskDisplay(void *pvParameters){
M5.begin();
M5.Lcd.fillScreen(TFT_BLACK);
M5.Lcd.fillRect(0, 50, rect_width, rect_height, TFT_WHITE);
while(true){
    M5.update(); //Update M5Stack button state
    if(isDisp_ok){
      if(old_line_data != receive_position_data || old_color_data != receive_color_data){
      if(receive_direction){
          M5.Lcd.fillRect(old_line_data, 50, receive_position_data - old_line_data, rect_height, TFT_BLACK);
      }else{
          M5.Lcd.fillRect(receive_position_data + rect_width, 50, old_line_data + rect_width, rect_height, TFT_BLACK);
      }
      M5.Lcd.fillRect(receive_position_data, 50, rect_width, rect_height, color_data);
      old_line_data = receive_position_data;
      old_color_data = receive_color_data;
      }
      isDisp_ok = false;
    }
    button_action();
    delay(1);
}
}
//************************************
void receiveUDP(){    //定义接收UDP包函数
if(!isDisp_ok){      
    int packetSize = udp.parsePacket();//接收数据包
    if(packetSize > 0){   //读出数据
      receive_position_data = udp.read();
      receive_direction = udp.read();
      receive_color_data = udp.read();
      //Serial.println(receive_position_data);
      //Serial.printf("receive_position_data=%d, receive_color_data=%d\r\n", receive_position_data, receive_color_data);
      isDisp_ok = true;
    }
}
}

void sendUDP(){    //定义发送UDP包函数
if(isSet_send_data){
    udp.beginPacket(to_udp_address, to_udp_port); //向指定IP端口发送数据
    udp.write((uint8_t)send_position);
    udp.write(send_direction);
    udp.write(send_color_num);
    //Serial.printf("send_position=%d, send_color_num=%d\r\n", send_position, send_color_num);
    udp.endPacket();
    isSet_send_data = false;
}
}

void autoIncDec(int16_t interval) {    //自动移动
if(millis() - now_time > interval){
    if(send_direction){
      send_position++;
      if(send_position > 255) {
      send_position = 255;
      send_direction = 0;
      }
    }else{
      send_position--;
      if(send_position < 0) {
      send_position = 0;
      send_direction = 1;
      }
    }
    isSet_send_data = true;
    now_time = millis();
}
}

void setupWiFiUDPserver(){   //定义UDP服务
Serial.println("Connecting to WiFi network: " + String(ssid));
WiFi.disconnect(true, true); //WiFi config
WiFi.softAP(ssid, password);
IPAddress myIP = WiFi.softAPIP();
Serial.println("WiFi connected!");
Serial.print("My IP address: ");
Serial.println(myIP);
udp.begin(myIP, my_server_udp_port);
delay(1000);
}

void button_action(){       //判断按键动作
if (M5.BtnA.wasReleased()) {
    if(send_direction) {
      send_direction = 0;
    }else{
      send_direction = 1;
    }
    isSend_rect_move = true;
} else if (M5.BtnB.wasReleased()) {
    send_color_num++;
    if(send_color_num > 6) send_color_num = 0;
    isSet_send_data = true;
} else if (M5.BtnC.wasReleased()) {
    interval = interval - 5;
    if(interval < 0) interval = 0;
    Serial.printf("interval=%d\r\n", interval);
} else if (M5.BtnC.pressedFor(500)) {
    interval = 100;
    Serial.printf("interval=%d\r\n", interval);
    now_time = millis();
}
}




主机2
#include <M5Stack.h> //ver 0.2.9
#include <WiFi.h>
#include <WiFiUdp.h>

const char* ssid = "M5-2.4G"; //
const char* password = "88888888"; //
const char * to_udp_address = "192.168.4.1"; //
const int to_udp_port = 55555; //
const int my_server_udp_port = 55556; //

WiFiUDP udp;
TaskHandle_t task_handl; //

boolean connected = false;
uint8_t receive_position_data = 0; //
uint8_t receive_direction = 0; //
uint8_t receive_color_data = 0; //
uint8_t old_line_data = 0;
uint8_t old_color_data = 0;
boolean isDisp_ok = false; //
boolean isSet_send_data = false;
boolean isSend_rect_move = false; //
int16_t send_position = 0; //
uint8_t send_direction = 0; //
uint8_t send_color_num = 0; //
uint32_t now_time = 0;
int16_t interval = 100; //
uint8_t rect_width = 63; //
uint8_t rect_height = 100; //
uint32_t color_data = {TFT_WHITE,
                        TFT_RED,
                        TFT_GREEN,
                        TFT_BLUE,
                        TFT_YELLOW,
                        TFT_MAGENTA,
                        TFT_CYAN};

//********* core 1 task ***************
void setup(){
Serial.begin(115200);
delay(1000);
connectToWiFi();
while(!connected){
    delay(1);
}
xTaskCreatePinnedToCore(&taskDisplay, "taskDisplay", 8192, NULL, 10, &task_handl, 0);
delay(500); //
}

void loop(){
receiveUDP();
if(isSend_rect_move) autoIncDec(interval);
sendUDP();
}
//******** core 0 task *************
void taskDisplay(void *pvParameters){
M5.begin();
M5.Lcd.fillScreen(TFT_BLACK);
M5.Lcd.fillRect(0, 50, rect_width, rect_height, TFT_WHITE);
while(true){
    M5.update(); //Update M5Stack button state
    if(isDisp_ok){
      if(old_line_data != receive_position_data || old_color_data != receive_color_data){
      if(receive_direction){
          M5.Lcd.fillRect(old_line_data, 50, receive_position_data - old_line_data, rect_height, TFT_BLACK);
      }else{
          M5.Lcd.fillRect(receive_position_data + rect_width, 50, old_line_data + rect_width, rect_height, TFT_BLACK);
      }
      M5.Lcd.fillRect(receive_position_data, 50, rect_width, rect_height, color_data);
      old_line_data = receive_position_data;
      old_color_data = receive_color_data;
      }
      isDisp_ok = false;
    }
    button_action();
    delay(1);
}
}
//***********************************
void receiveUDP(){
if(!isDisp_ok){
    if(connected){
      int packetSize = udp.parsePacket();
      if(packetSize > 0){
      receive_position_data = udp.read();
      receive_direction = udp.read();
      receive_color_data = udp.read();
      //Serial.printf("receive_position_data=%d, receive_direction=%d, receive_color_data=%d\r\n", receive_position_data, receive_direction, receive_color_data);
      isDisp_ok = true;
      }
    }
}
}

void sendUDP(){
if(isSet_send_data){
    udp.beginPacket(to_udp_address, to_udp_port);
    udp.write((uint8_t)send_position);
    udp.write(send_direction);
    udp.write(send_color_num);
    //Serial.printf("send_position=%d, send_color_num=%d\r\n", send_position, send_color_num);
    udp.endPacket();
    isSet_send_data = false;
}
}

void autoIncDec(int16_t interval) {
if(millis() - now_time > interval){
    if(send_direction){
      send_position++;
      if(send_position > 255) {
      send_position = 255;
      send_direction = 0;
      }
    }else{
      send_position--;
      if(send_position < 0) {
      send_position = 0;
      send_direction = 1;
      }
    }
    isSet_send_data = true;
    now_time = millis();
}
}

void connectToWiFi(){   //定义wifi连接
Serial.println("Connecting to WiFi network: " + String(ssid));
WiFi.disconnect(true, true);
delay(1000);
WiFi.onEvent(WiFiEvent);
WiFi.begin(ssid, password);
Serial.println("Waiting for WIFI connection...");
}

void WiFiEvent(WiFiEvent_t event){
IPAddress myIP = WiFi.localIP();
switch(event) {
    case SYSTEM_EVENT_STA_GOT_IP:
      Serial.println("WiFi connected!");
      Serial.print("My IP address: ");
      Serial.println(myIP);
      udp.begin(myIP, my_server_udp_port);
      delay(1000);
      connected = true;
      break;
    case SYSTEM_EVENT_STA_DISCONNECTED:
      Serial.println("WiFi lost connection");
      connected = false;
      break;
    default:
      break;
}
}

void button_action(){
if (M5.BtnA.wasReleased()) {
    if(send_direction) {
      send_direction = 0;
    }else{
      send_direction = 1;
    }
    isSend_rect_move = true;
} else if (M5.BtnB.wasReleased()) {
    send_color_num++;
    if(send_color_num > 6) send_color_num = 0;
    isSet_send_data = true;
} else if (M5.BtnC.wasReleased()) {
    interval = interval - 5;
    if(interval < 0) interval = 0;
    Serial.printf("interval=%d\r\n", interval);
} else if (M5.BtnC.pressedFor(500)) {
    interval = 100;
    Serial.printf("interval=%d\r\n", interval);
    now_time = millis();
}
}

沧海笑1122 发表于 2019-11-22 11:26

感谢分享!
我记得以前写过一个udp的mpy实现例程,回头找出来看看能不能在uiflow新平台上折腾一下。:lol
页: [1]
查看完整版本: UDP双向通讯实验