【项目背景】
一直我都想自制一辆遥控车,自己打板制作遥控器,自制车身框架。这段时间正在试用Esp32-c6,手上还有一块Esp32-c3,两者都支持ESP-NOW通信。使用佳立创画板,焊接元器件,打造自己的遥控车。
【佳立创画板】
1.摇杆VRx接esp32-c3的0引脚(A0),VRy接esp32-c3的4引脚(A4),按键分别接esp32-c3的2、8、9、21引脚(编程引脚初始化时设置为上拉输入模式)
2.车身电路esp32-c6与电机驱动,esp32-c6的4、5、23、22引脚用来向电机驱动输入控制信号。
【组装】
1.遥控器
2.车
【编写程序】
使用Arduino IDE 编写。
1.esp32-c3遥控器程序
-
-
- #include <esp_now.h>
- #include <WiFi.h>
- #include <esp_wifi.h> // only for esp_wifi_set_channel()
-
- // Global copy of slave
- esp_now_peer_info_t slave;
- #define CHANNEL 1
- #define PRINTSCANRESULTS 0
- #define DELETEBEFOREPAIR 0
-
- // Init ESP Now with fallback
- void InitESPNow() {
- WiFi.disconnect();
- if (esp_now_init() == ESP_OK) {
- Serial.println("ESPNow Init Success");
- }
- else {
- Serial.println("ESPNow Init Failed");
- // Retry InitESPNow, add a counte and then restart?
- // InitESPNow();
- // or Simply Restart
- ESP.restart();
- }
- }
-
- // Scan for slaves in AP mode
- void ScanForSlave() {
- int16_t scanResults = WiFi.scanNetworks(false, false, false, 300, CHANNEL); // Scan only on one channel
- // reset on each scan
- bool slaveFound = 0;
- memset(&slave, 0, sizeof(slave));
-
- Serial.println("");
- if (scanResults == 0) {
- Serial.println("No WiFi devices in AP Mode found");
- } else {
- Serial.print("Found "); Serial.print(scanResults); Serial.println(" devices ");
- for (int i = 0; i < scanResults; ++i) {
- // Print SSID and RSSI for each device found
- String SSID = WiFi.SSID(i);
- int32_t RSSI = WiFi.RSSI(i);
- String BSSIDstr = WiFi.BSSIDstr(i);
-
- if (PRINTSCANRESULTS) {
- Serial.print(i + 1);
- Serial.print(": ");
- Serial.print(SSID);
- Serial.print(" (");
- Serial.print(RSSI);
- Serial.print(")");
- Serial.println("");
- }
- delay(10);
- // Check if the current device starts with `Slave`
- if (SSID.indexOf("Slave") == 0) {
- // SSID of interest
- Serial.println("Found a Slave.");
- Serial.print(i + 1); Serial.print(": "); Serial.print(SSID); Serial.print(" ["); Serial.print(BSSIDstr); Serial.print("]"); Serial.print(" ("); Serial.print(RSSI); Serial.print(")"); Serial.println("");
- // Get BSSID => Mac Address of the Slave
- int mac[6];
- if ( 6 == sscanf(BSSIDstr.c_str(), "%x:%x:%x:%x:%x:%x", &mac[0], &mac[1], &mac[2], &mac[3], &mac[4], &mac[5] ) ) {
- for (int ii = 0; ii < 6; ++ii ) {
- slave.peer_addr[ii] = (uint8_t) mac[ii];
- }
- }
-
- slave.channel = CHANNEL; // pick a channel
- slave.encrypt = 0; // no encryption
-
- slaveFound = 1;
- // we are planning to have only one slave in this example;
- // Hence, break after we find one, to be a bit efficient
- break;
- }
- }
- }
-
- if (slaveFound) {
- Serial.println("Slave Found, processing..");
- } else {
- Serial.println("Slave Not Found, trying again.");
- }
-
- // clean up ram
- WiFi.scanDelete();
- }
-
- // Check if the slave is already paired with the master.
- // If not, pair the slave with master
- bool manageSlave() {
- if (slave.channel == CHANNEL) {
- if (DELETEBEFOREPAIR) {
- deletePeer();
- }
-
- Serial.print("Slave Status: ");
- // check if the peer exists
- bool exists = esp_now_is_peer_exist(slave.peer_addr);
- if ( exists) {
- // Slave already paired.
- Serial.println("Already Paired");
- return true;
- } else {
- // Slave not paired, attempt pair
- esp_err_t addStatus = esp_now_add_peer(&slave);
- if (addStatus == ESP_OK) {
- // Pair success
- Serial.println("Pair success");
- return true;
- } else if (addStatus == ESP_ERR_ESPNOW_NOT_INIT) {
- // How did we get so far!!
- Serial.println("ESPNOW Not Init");
- return false;
- } else if (addStatus == ESP_ERR_ESPNOW_ARG) {
- Serial.println("Invalid Argument");
- return false;
- } else if (addStatus == ESP_ERR_ESPNOW_FULL) {
- Serial.println("Peer list full");
- return false;
- } else if (addStatus == ESP_ERR_ESPNOW_NO_MEM) {
- Serial.println("Out of memory");
- return false;
- } else if (addStatus == ESP_ERR_ESPNOW_EXIST) {
- Serial.println("Peer Exists");
- return true;
- } else {
- Serial.println("Not sure what happened");
- return false;
- }
- }
- } else {
- // No slave found to process
- Serial.println("No Slave found to process");
- return false;
- }
- }
-
- void deletePeer() {
- esp_err_t delStatus = esp_now_del_peer(slave.peer_addr);
- Serial.print("Slave Delete Status: ");
- if (delStatus == ESP_OK) {
- // Delete success
- Serial.println("Success");
- } else if (delStatus == ESP_ERR_ESPNOW_NOT_INIT) {
- // How did we get so far!!
- Serial.println("ESPNOW Not Init");
- } else if (delStatus == ESP_ERR_ESPNOW_ARG) {
- Serial.println("Invalid Argument");
- } else if (delStatus == ESP_ERR_ESPNOW_NOT_FOUND) {
- Serial.println("Peer not found.");
- } else {
- Serial.println("Not sure what happened");
- }
- }
-
- // 发送结构体类型
- typedef struct struct_message {
- char a;
- int b;
-
- } struct_message;
- // 创建一个结构体变量
- struct_message data;
- // send data
- void sendData() {
-
- const uint8_t *peer_addr = slave.peer_addr;
-
- esp_err_t result = esp_now_send(peer_addr,(uint8_t *) &data, sizeof(data));
- Serial.print("Send Status: ");
- if (result == ESP_OK) {
- Serial.println("Success");
- } else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
- // How did we get so far!!
- Serial.println("ESPNOW not Init.");
- } else if (result == ESP_ERR_ESPNOW_ARG) {
- Serial.println("Invalid Argument");
- } else if (result == ESP_ERR_ESPNOW_INTERNAL) {
- Serial.println("Internal Error");
- } else if (result == ESP_ERR_ESPNOW_NO_MEM) {
- Serial.println("ESP_ERR_ESPNOW_NO_MEM");
- } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
- Serial.println("Peer not found.");
- } else {
- Serial.println("Not sure what happened");
- }
- }
-
- // callback when data is sent from Master to Slave
- void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
- char macStr[18];
- 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.print("Last Packet Sent to: "); Serial.println(macStr);
- Serial.print("Last Packet Send Status: "); Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
- }
-
- void setup() {
- Serial.begin(115200);
- //Set device in STA mode to begin with
- WiFi.mode(WIFI_STA);
- esp_wifi_set_channel(CHANNEL, WIFI_SECOND_CHAN_NONE);
- Serial.println("ESPNow/Basic/Master Example");
- // This is the mac address of the Master in Station Mode
- Serial.print("STA MAC: "); Serial.println(WiFi.macAddress());
- Serial.print("STA CHANNEL "); Serial.println(WiFi.channel());
- // Init ESPNow with a fallback logic
- InitESPNow();
- // Once ESPNow is successfully Init, we will register for Send CB to
- // get the status of Trasnmitted packet
- esp_now_register_send_cb(OnDataSent);
- pinMode(2,INPUT_PULLUP); //配置按键所在端口为上拉输入模式
- pinMode(8,INPUT_PULLUP); //配置按键所在端口为上拉输入模式
- pinMode(9,INPUT_PULLUP); //配置按键所在端口为上拉输入模式
- pinMode(21,INPUT_PULLUP); //配置按键所在端口为上拉输入模式
- }
- bool i=1;
- int xValue;
- int yValue;
- int bs=0;
- void loop() {
- // In the loop we scan for slave
- if (i) {
- ScanForSlave();
- }
- // If Slave is found, it would be populate in `slave` variable
- // We will check if `slave` is defined and then we proceed further
- if (slave.channel == CHANNEL) { // check if slave channel is defined
- // `slave` is defined
- // Add slave as peer if it has not been added already
- bool isPaired = manageSlave();
- if (isPaired) {
- i=0;
- // pair success or already paired
- // Send data to device
- if(!digitalRead(9)) //如果按键按下,即GPIO9的端口状态为低电平
- {
- data.a='y';
- data.b=4000;
- sendData();
- delay(500);
- }
- if(!digitalRead(8)) //如果按键按下,即GPIO9的端口状态为低电平
- {
- data.a='y';
- data.b=500;
- sendData();
- delay(500);
- }
- if(!digitalRead(2)) //如果按键按下,即GPIO2的端口状态为低电平
- {
- data.a='x';
- data.b=4000;
- sendData();
- delay(500);
- }
- if(!digitalRead(21)) //如果按键按下,即GPIO21的端口状态为低电平
- {
- data.a='x';
- data.b=500;
- sendData();
- delay(500);
- }
- xValue = analogRead(4);//获取摇杆的x值,连接在主板A4接口
- yValue = analogRead(0);//获取摇杆的y值,连接在主板A0接口
- Serial.println(xValue);
- Serial.println(yValue);
- delay(100);
- if(xValue>4000 || xValue<500)
- {
- bs=1;
- data.a='x';
- data.b=xValue;
- sendData();
- Serial.println('x');
- }
- else{
- if(yValue>4000 || yValue<500)
- { bs=1;
- data.a='y';
- data.b=yValue;
- sendData();
- Serial.println('y');
- }
- else{
- if(bs==1){
- bs=0;
- data.a='s';
- sendData();
- Serial.println('s');
- }
- }
- }
- } else {
- // slave pair failed
- Serial.println("Slave pair failed!");
- }
- }
- else {
- // No slave found to process
- }
-
- // wait for 3seconds to run the logic again
-
- }
-
复制代码
2.esp32-c6 车程序-
-
-
- #include <esp_now.h>
- #include <WiFi.h>
-
-
- #define CHANNEL 1
- //设置PWM参数
-
- // Init ESP Now with fallback
- void InitESPNow() {
- WiFi.disconnect();
- if (esp_now_init() == ESP_OK) {
- Serial.println("ESPNow Init Success");
- }
- else {
- Serial.println("ESPNow Init Failed");
- // Retry InitESPNow, add a counte and then restart?
- // InitESPNow();
- // or Simply Restart
- ESP.restart();
- }
- }
-
- // config AP SSID
- void configDeviceAP() {
- const char *SSID = "Slave_1";
- bool result = WiFi.softAP(SSID, "Slave_1_Password", CHANNEL, 0);
- if (!result) {
- Serial.println("AP Config failed.");
- } else {
- Serial.println("AP Config Success. Broadcasting with AP: " + String(SSID));
- Serial.print("AP CHANNEL "); Serial.println(WiFi.channel());
- }
- }
- const int IA1=4;
- const int IA2=5;
- const int IB1=23;
- const int IB2=22;
- void setup() {
- Serial.begin(115200);
-
- pinMode(IA1, OUTPUT);
- pinMode(IA2, OUTPUT);
- pinMode(IB1, OUTPUT);
- pinMode(IB2, OUTPUT);
-
- Serial.println("ESPNow/Basic/Slave Example");
- //Set device in AP mode to begin with
- WiFi.mode(WIFI_AP);
- // configure device AP mode
- configDeviceAP();
- // This is the mac address of the Slave in AP Mode
- Serial.print("AP MAC: "); Serial.println(WiFi.softAPmacAddress());
- // Init ESPNow with a fallback logic
- InitESPNow();
- // Once ESPNow is successfully Init, we will register for recv CB to
- // get recv packer info.
- esp_now_register_recv_cb(OnDataRecv);
- }
- // 创建一个结构体接收数据
- typedef struct struct_message {
- char a;
- int b;
-
- } struct_message;
-
- // 创建一个结构体变量
- struct_message myData;
-
-
-
- // callback when data is recv from Master
- void OnDataRecv(const esp_now_recv_info_t * info, const uint8_t *data, int data_len) {
- memcpy(&myData, data, sizeof(myData));
- char macStr[18];
- snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
- info->src_addr[0], info->src_addr[1], info->src_addr[2], info->src_addr[3], info->src_addr[4], info->src_addr[5]);
- Serial.print("Last Packet Recv from: "); Serial.println(macStr);
- Serial.print("Last Packet Recv Data a: "); Serial.println(myData.a);
- Serial.print("Last Packet Recv Data b: "); Serial.println(myData.b);
- if(myData.a=='x')
- {
- int v1=int(myData.b)-2400;
- if(v1>0)
- {
-
- MA2_Backward();
- MB1_Forward();
-
- }
- else{
-
- MA1_Forward();
- MB2_Backward();
- }
- }
- else{
- if(myData.a=='y')
- {
- int v1=int(myData.b)-2600;
- if(v1>0)
- {
- MA1_Forward();
- MB1_Forward();
-
- }
- else{
- MA2_Backward();
- MB2_Backward();
- }
- }
- else{
- if(myData.a=='s')
- {
- stop();
-
- }
- }
- }
- }
- void MA1_Forward()
- {
- digitalWrite(IA1,HIGH);
- digitalWrite(IA2,LOW);
- }
-
- void MA2_Backward()
- {
- digitalWrite(IA2,HIGH);
- digitalWrite(IA1,LOW);
- }
-
- void MB1_Forward()
- {
- digitalWrite(IB2,HIGH);
- digitalWrite(IB1,LOW);
- }
-
- void MB2_Backward()
- {
- digitalWrite(IB1,HIGH);
- digitalWrite(IB2,LOW);
- }
- void stop()
- {
- digitalWrite(IA1,LOW);
- digitalWrite(IA2,LOW);
- digitalWrite(IB1,LOW);
- digitalWrite(IB2,LOW);
- }
- void loop() {
- // Chill
- }
-
复制代码
【演示视频】
|