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

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2196|回复: 1

UDP双向通讯实验

[复制链接]
发表于 2019-11-18 14:02 | 显示全部楼层 |阅读模式
本帖最后由 vany5921 于 2019-11-18 14:56 编辑

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

IMG_0757.JPG

主机1
[mw_shl_code=arduino,true]#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[7] = {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[receive_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();
  }
}[/mw_shl_code]




主机2
[mw_shl_code=arduino,true]#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[7] = {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[receive_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();
  }
}[/mw_shl_code]

发表于 2019-11-22 11:26 | 显示全部楼层
感谢分享!
我记得以前写过一个udp的mpy实现例程,回头找出来看看能不能在uiflow新平台上折腾一下。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 08:31 , Processed in 0.097929 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表