nodemcu,esp8266,和 ESP32 使用UDP 数据传输

想做一个智能小车,同时小车上带有视频模块,想在室外玩,没有WIFI 覆盖的情况想
想法:
ESP32,是用于 视频传输的,
esp8266 是用来操控小车的,
操控是一个手机,通过微信小程序 来操控,同时在微信小程序上显示视频。

那么我的思路是:ESP8266 做WIFI主机, esp32 连接 esp8266的wifi , 手机 也连接 ESP8266 的wifi。

这样 手机就可以 同时操作2块芯片了。

esp8266 作为 WIFI 主机,我可以设置一个静态的ip主地址,但是 esp32 的ip 地址我就不知道了。

解决办法: esp32 在连接wifi后,通过 UDP 把自己的 ip地址发送给esp8266,在esp8266上缓存起来, 微信小程序 通过 UDP ,去esp8266上查询 esp32 的 ip地址。

先实现 esp8266 的代码

#include <WiFiUdp.h>
#include <ESP8266WiFi.h>
#include <Servo.h>
#include <stdlib.h>


WiFiUDP Udp;
unsigned int UDPPort = 8888;      //wifi端口

// 定义ESP32 缓存IP
char caminfo[255];

//检查相机是否在线超时时间
int cam_timeout = 30000;

char packetBuffer[255];  //buffer to hold incoming packet

//l298n 驱动器连接
#define d1 D1
#define d2 D2
#define d3 D3
#define d4 D4


#define BASE 10
#define DIGIT_ASCII_START '0'


//wifi udp 数据传输初始化
void wifiUdpInit() {
  Udp.begin(UDPPort);
}

//udp数据循环获取数据
void wifiUdpGetMsg() {

  //控制cam 超时时间
  if (cam_timeout > 100000) {
    cam_timeout = 100000;
  } else if (cam_timeout <= 1) {
    //已经超时了
    strcpy(caminfo, "");
  } else {
    cam_timeout--;
  }
  
  Serial.println(cam_timeout);
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remoteIp = Udp.remoteIP();
    Serial.print(remoteIp);
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    int len = Udp.read(packetBuffer, 255);
    if (len > 0) {
      packetBuffer[len] = 0;
    }
    Serial.print("Contents:");
    Serial.println(packetBuffer);

    char pre[] = "";
    left(pre, packetBuffer, strcspn(packetBuffer, ":"));
    Serial.print("pre:");
    Serial.println(pre);


    Serial.println(cam_timeout);
    if (0 == strcmp(pre, "cam")) {
      Serial.print("save camer ip:");
      //保存信息
      strcpy(caminfo,packetBuffer);
      Serial.println(caminfo);
      cam_timeout += 10000;
      Serial.print("cam_timeout:"); Serial.println(cam_timeout);
      returnUdpMsg("cam success");
      return;
    } else if (0 == strcmp(pre, "query-cam")) {
      //查询 cam 的信息,就返回ip
      returnUdpMsg(caminfo);
      return;
    }
    // send a reply, to the IP address and port that sent us the packet we received
    returnUdpMsg("success");
  }
}

void returnUdpMsg(char *msg) {
  Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
  Udp.write(msg);
  Udp.endPacket();
}




/*从字符串的右边截取n个字符*/
char * right(char *dst, char *src, int n)
{
  char *p = src;
  char *q = dst;
  int len = strlen(src);
  if (n > len) n = len;
  p += (len - n); /*从右边第n个字符开始,到0结束,很巧啊*/
  while (*(q++) = *(p++));
  return dst;
}

/*从字符串的左边截取n个字符*/
char * left(char *dst, char *src, int n)
{
  char *p = src;
  char *q = dst;
  int len = strlen(src);
  if (n > len) n = len;
  while (n--) *(q++) = *(p++);
  *(q++) = '\0'; /*有必要吗?很有必要*/
  return dst;
}

void charListToStr(const char* pChar, const int charLen, int* varName) {
  int offset;
  int baseCurrent = 1;
  int result = 0;
  for (offset = charLen - 1; offset >= 0; offset--) {
    result += (*(pChar + offset) - DIGIT_ASCII_START) * baseCurrent;
    baseCurrent *= BASE;
  }
  *varName = result;
}


void wifiInit() {
  WiFi.mode(WIFI_AP);  //设置Wi-Fi为AP模式
  IPAddress softLocal(192, 168, 1, 1); //设置内网WIFI IP地址
  IPAddress softGateway(192, 168, 1, 1); //设置网关
  IPAddress softSubnet(255, 255, 255, 0);
  WiFi.softAPConfig(softLocal, softGateway, softSubnet);

  String apName = ("ESP8266-cat-car" ); // 2 设置WIFI名称
  const char *softAPName = apName.c_str();

  WiFi.softAP(softAPName, "87654321");      // 3创建wifi  名称 +密码 adminadmin

  IPAddress myIP = WiFi.softAPIP();  // 4输出创建的WIFI IP地址

  Serial.println("");
  Serial.print("AP直链模式 网关IP: ");
  Serial.println(myIP);

  Serial.print("AP SSID: ");  // 5输出WIFI 名称
  Serial.println(apName);
  Serial.print("AP 密码: ");  // 5输出WIFI 名称
  Serial.println("12345678");  // 5输出WIFI 名称
}


void setup() {
  Serial.begin(115200);
  wifiInit();//wifi 初始化
  wifiUdpInit();//udp初始化

  pinMode(d1, OUTPUT);
  pinMode(d2, OUTPUT);
  pinMode(d3, OUTPUT);
  pinMode(d4, OUTPUT);

  digitalWrite(d1, LOW);
  digitalWrite(d2, LOW);
  digitalWrite(d3, LOW);
  digitalWrite(d4, LOW);

}


void loop() {

  wifiUdpGetMsg();//循环获取数据

}

ESP32的 代码

#include "esp_camera.h"
#include <WiFi.h>
#include "WiFiUdp.h"

#define CAMERA_MODEL_AI_THINKER

#include "camera_pins.h"

WiFiUDP Udp;

const char* ssid = "ESP8266-cat-car";
const char* password = "87654321";

//const char* ssid = "16L-YiDong";
//const char* password = "9622596225";

void startCameraServer();



void setup() {
  Serial.begin(115200);
  Serial.setDebugOutput(true);
  Serial.println();

  camera_config_t config;
  config.ledc_channel = LEDC_CHANNEL_0;
  config.ledc_timer = LEDC_TIMER_0;
  config.pin_d0 = Y2_GPIO_NUM;
  config.pin_d1 = Y3_GPIO_NUM;
  config.pin_d2 = Y4_GPIO_NUM;
  config.pin_d3 = Y5_GPIO_NUM;
  config.pin_d4 = Y6_GPIO_NUM;
  config.pin_d5 = Y7_GPIO_NUM;
  config.pin_d6 = Y8_GPIO_NUM;
  config.pin_d7 = Y9_GPIO_NUM;
  config.pin_xclk = XCLK_GPIO_NUM;
  config.pin_pclk = PCLK_GPIO_NUM;
  config.pin_vsync = VSYNC_GPIO_NUM;
  config.pin_href = HREF_GPIO_NUM;
  config.pin_sscb_sda = SIOD_GPIO_NUM;
  config.pin_sscb_scl = SIOC_GPIO_NUM;
  config.pin_pwdn = PWDN_GPIO_NUM;
  config.pin_reset = RESET_GPIO_NUM;
  config.xclk_freq_hz = 20000000;
  config.pixel_format = PIXFORMAT_JPEG;
  //init with high specs to pre-allocate larger buffers
  if(psramFound()){
    config.frame_size = FRAMESIZE_UXGA;
    config.jpeg_quality = 10;
    config.fb_count = 2;
  } else {
    config.frame_size = FRAMESIZE_SVGA;
    config.jpeg_quality = 12;
    config.fb_count = 1;
  }

#if defined(CAMERA_MODEL_ESP_EYE)
  pinMode(13, INPUT_PULLUP);
  pinMode(14, INPUT_PULLUP);
#endif

  // camera init
  esp_err_t err = esp_camera_init(&config);
  if (err != ESP_OK) {
    Serial.printf("Camera init failed with error 0x%x", err);
    return;
  }

  sensor_t * s = esp_camera_sensor_get();
  //initial sensors are flipped vertically and colors are a bit saturated
  if (s->id.PID == OV3660_PID) {
    s->set_vflip(s, 1);//flip it back
    s->set_brightness(s, 1);//up the blightness just a bit
    s->set_saturation(s, -2);//lower the saturation
  }
  //drop down frame size for higher initial frame rate
  s->set_framesize(s, FRAMESIZE_QVGA);

#if defined(CAMERA_MODEL_M5STACK_WIDE)
  s->set_vflip(s, 1);
  s->set_hmirror(s, 1);
#endif

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  startCameraServer();

  Serial.print("Camera Ready! Use 'http://");
  Serial.print(WiFi.localIP());
  Serial.println("' to connect");
  Serial.println(WiFi.gatewayIP());

  //Udp.begin(8888);
}
//核销代码,每2秒发送一次自己的IP地址
void sendLocalIp(){

    Serial.println("sendLocalIp");
    int r = Udp.beginPacket(WiFi.gatewayIP(), 8888);
    if(r < 1){
      return;
    }
    char  buf[] = "cam:";
    char loadIp[20];
    strcpy(loadIp,WiFi.localIP().toString().c_str());
    strcat(buf,loadIp);
    int  bufsize = strlen(buf);
    Serial.println(buf);
    Udp.write((const uint8_t*)buf,bufsize); //复制数据到发送缓存
    Udp.endPacket();
}

void loop() {
  // put your main code here, to run repeatedly:
  delay(2000);

  sendLocalIp();
}
上一篇:解读 ESP32 system - Application Level Tracing


下一篇:使用 ESP32 芯片,下载固件需要满足什么硬件条件?