跟站长阿张折腾硬件之第三版本 esp32控+esp32接收端 (esp

您所在的位置:网站首页 arduino闪灯代码 跟站长阿张折腾硬件之第三版本 esp32控+esp32接收端 (esp

跟站长阿张折腾硬件之第三版本 esp32控+esp32接收端 (esp

2023-04-14 04:19| 来源: 网络整理| 查看: 265

第三个版本,使用espnow模式(wifi broadcast)传输信号,使用esp32遥控端读取摇杆中的电位器信号,通过espnow 广播遥控信号。esp32接收端接收到信号包,转换成pwm控制信号,分别控制舵机和电调控制小车。

跟站长阿张折腾硬件之第三版本 esp32控+esp32接收端 (esp-now,Arduino IDE)

这个视频中有一部分讲代码中要调整的部分

https://www.bilibili.com/video/BV1pM411H7KS/?vd_source=5112aa86344ed83491a31bc47f2b5e76

接线方式

接线方式同 第二版本一致

https://www.xiwnn.com/article/a_64318283a086df73c41a3ff6.html

代码部分发送端 (ESP32 摇杆端)

记得改一下这份代码中的接收端MAC地址,不然连接不上。先刷接收端,运行之后,在串口监视器中有打出。

// 参考自此文章 https://zhuanlan.zhihu.com/p/344109867 #include #include //Are we currently connected? boolean connected = false; // 设置遥控数据结构体 typedef struct rc_struct_message { int ch1; int ch2; } rc_struct_message; rc_struct_message rcData; int LED_BUILTIN = 2; bool ledShow = false; int baseX = 0; int baseY = 0; // 100的间隙 int gap = 100; // 接收设备的 MAC 地址,运行接收端的esp32后,从串口监视器中获得 uint8_t broadcastAddress[] = {0xE0, 0x5A, 0x1B, 0xA0, 0x04, 0xB4}; unsigned long timeNow = 0; // 上一次发送数据的成功时间 unsigned long lastTickTime = millis(); // 数据发送回调函数 void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) { if (status == ESP_NOW_SEND_SUCCESS) { lastTickTime = millis(); } // char macStr[18]; // Serial.print("Packet to: "); // snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x", // mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); // Serial.println(macStr); // Serial.print("Send status: "); // Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail"); // Serial.println(); } void setup() { Serial.begin(9600); baseX = analogRead(35); // X 读取35针脚 baseY = analogRead(34); // Y 读取34针脚 WiFi.mode(WIFI_MODE_STA); Serial.print("ESP32 RC TX MAC Address: "); Serial.println(WiFi.macAddress()); if (esp_now_init() != ESP_OK) { Serial.println("Error initializing ESP-NOW"); return; } // 设置发送数据回调函数 esp_now_register_send_cb(OnDataSent); // 绑定数据接收端 esp_now_peer_info_t peerInfo; memcpy(peerInfo.peer_addr, broadcastAddress, 6); peerInfo.channel = 0; peerInfo.encrypt = false; // 检查设备是否配对成功 if (esp_now_add_peer(&peerInfo) != ESP_OK) { Serial.println("Failed to add peer"); return; } pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output } int MAX = 4096; int vx = 0; int vy = 0; int sendMax = 1024; int sendHaf = sendMax / 2; // 输出到频道值 0 - 1024; int ch1Value = 0; int ch2Value = 0; int ledLoopTick = -1; void loop() { timeNow = millis(); vx = analogRead(35); vy = analogRead(34); ch1Value = sendHaf; ch2Value = sendHaf; if (vx > baseX) { if (vx > baseX + gap) { ch1Value = int(float(vx - baseX - gap) / (MAX - baseX - gap) * sendHaf) + sendHaf; } } else { if (vx < baseX - gap) { ch1Value = int(float(vx) / float(baseX - gap) * sendHaf); } } if (vy > baseY) { if (vy > baseY + gap) { ch2Value = int(float(vy - baseY - gap) / (MAX - baseY - gap) * sendHaf) + sendHaf; } } else { if (vy < baseY - gap) { ch2Value = int(float(vy) / float(baseY - gap) * sendHaf); } } rcData.ch1 = ch1Value; rcData.ch2 = ch2Value; // 发送数据 esp_now_send(broadcastAddress, (uint8_t *) &rcData, sizeof(rcData)); if (timeNow - lastTickTime > 1000) { // 没发送成功,进行闪烁 ledLoopTick += 1; if (ledLoopTick >= 50) { // 闪太快看不清,隔50帧闪一次 ledLoopTick = 0; } if (ledLoopTick == 0) { if (ledShow) { digitalWrite(LED_BUILTIN, LOW); ledShow = false; } else { digitalWrite(LED_BUILTIN, HIGH); ledShow = true; } } delay(10); } else { ledShow = true; digitalWrite(LED_BUILTIN, HIGH); } delay(1); // 去掉 } 接收端(ESP32 车上端)#include "WiFi.h" #include #include // 设置遥控数据结构体 typedef struct rc_struct_message { int ch1; int ch2; } rc_struct_message; rc_struct_message rcData; /** * 封装舵机的控制类 */ class LedcServo { public: float freq = 50; int resolution = 8; float pwmBaseScale; float pwmMin; float pwmMax; int channel; int scale = 1; void setup(float freq, int resolution, int channel); /* 0 < scale freq = f; this->resolution = r; this->pwmBaseScale = this->freq * pow(2, this->resolution) / 1000; this->pwmMin = 1 * this->pwmBaseScale; this->pwmMax = 2 * this->pwmBaseScale; this->channel = c; ledcSetup(this->channel, this->freq, this->resolution); } void LedcServo:: setScale(float s) { if (s 1) throw "s 不能大于1"; this->scale = s; this->pwmMin = (1.5 - s) * this->pwmBaseScale; this->pwmMax = (1.5 + s) * this->pwmBaseScale; } void LedcServo:: attachPin(int p) { ledcAttachPin(p, this->channel); } void LedcServo:: write(float v, float min, float max) { ledcWrite(this->channel, map(v, min, max, this->pwmMin, this->pwmMax)); // Serial.println(this->channel); // Serial.println(v); } int sendMin = 0; int sendMax = 1024; int sendHaf = sendMax / 2; int rxC1 = sendHaf; int rxC2 = sendHaf; int lastRxC1 = sendHaf; int lastRxC2 = sendHaf; LedcServo rxC1Servo; LedcServo rxC1ServoHaf; LedcServo rxC2Servo; LedcServo rxC2ServoHaf; unsigned long timeNow = 0; unsigned long lastDataTickTime = 0; int LED_BUILTIN = 2; bool ledShow = false; int ledLoopTick = -1; // 数据接收回调函数 void OnDataRecv(const uint8_t * mac, const uint8_t *incomingData, int len) { memcpy(&rcData, incomingData, sizeof(rcData)); rxC1 = rcData.ch1; rxC2 = rcData.ch2; lastDataTickTime = millis(); } void setup() { pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN pin as an output digitalWrite(LED_BUILTIN, LOW); rxC1Servo.setup(100, 10, 8); rxC1Servo.attachPin(23); // 动力电机控制信号全强度,动力会很猛 rxC1Servo.setScale(0.8); // 全强度 rxC1ServoHaf.setup(100, 10, 9); rxC1ServoHaf.attachPin(22); // 动力电机控制信号一半强度,动力会可控一些 rxC1ServoHaf.setScale(0.3); // 半强度 rxC2Servo.setup(500, 10, 10); rxC2Servo.attachPin(26); // 方向舵机信号全强度, 容易侧翻 rxC2Servo.setScale(0.7); // 半角度 rxC2ServoHaf.setup(500, 10, 11); rxC2ServoHaf.attachPin(25); // 方向舵机信号一半强度,防止转弯过度 rxC2ServoHaf.setScale(0.3); // 小角度 Serial.begin(9600); Serial.println(); Serial.print("Configuring access point..."); // 初始化 ESP-NOW WiFi.mode(WIFI_STA); Serial.print("ESP32 RC RX MAC Address: "); Serial.println(WiFi.macAddress()); if (esp_now_init() != 0) { Serial.println("Error initializing ESP-NOW"); return; } // 设置接收数据回调函数 esp_now_register_recv_cb(OnDataRecv); } void updateServo() { if (lastRxC1 != rxC1) { rxC1Servo.write(rxC1, sendMin, sendMax); rxC1ServoHaf.write(rxC1, sendMin, sendMax); lastRxC1 = rxC1; } if (lastRxC2 != rxC2) { rxC2Servo.write(rxC2, sendMax, sendMin); // 反向 rxC2ServoHaf.write(rxC2, sendMax, sendMin); // 反向 lastRxC2 = rxC2; } } void loop() { timeNow = millis(); if (timeNow > lastDataTickTime && timeNow - lastDataTickTime > 1000) { // 超过1秒未收到数据,自动归中,开始闪灯 rxC1 = sendHaf; rxC2 = sendHaf; ledLoopTick += 1; if (ledLoopTick >= 50) { // 闪太快看不清,隔50帧闪一次 ledLoopTick = 0; } if (ledLoopTick == 0) { if (ledShow) { digitalWrite(LED_BUILTIN, LOW); ledShow = false; } else { digitalWrite(LED_BUILTIN, HIGH); ledShow = true; } } delay(10); } else { // 有数据,就常亮 digitalWrite(LED_BUILTIN, HIGH); ledShow = true; } updateServo(); }



【本文地址】


今日新闻


    推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3