目录
时间来到了引航计划第三天,今天的主要任务是小车的调试和小车遥控的实现。
小车赛道调试
经过多轮调试,最终确定小车绕赛道转弯时间为14600ms,运行的代码如下:
#include "driver/mcpwm.h"
esp_err_t esp_err;
void setup() {
Serial.begin(115200);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0A, 26);
mcpwm_gpio_init(MCPWM_UNIT_0, MCPWM0B, 27);
mcpwm_gpio_init(MCPWM_UNIT_1, MCPWM1A, 13);
mcpwm_config_t motor_pwm_config = {
.frequency = 1000,
.cmpr_a = 0,
.cmpr_b = 0,
.duty_mode = MCPWM_DUTY_MODE_0,
.counter_mode = MCPWM_UP_COUNTER,
};
esp_err = mcpwm_init(MCPWM_UNIT_0, MCPWM_TIMER_0, &motor_pwm_config);
Serial.println(esp_err);
mcpwm_config_t servo_pwm_config;
servo_pwm_config.frequency = 50;
servo_pwm_config.cmpr_a = 0;
servo_pwm_config.duty_mode = MCPWM_DUTY_MODE_0;
servo_pwm_config.counter_mode = MCPWM_UP_COUNTER;
esp_err = mcpwm_init(MCPWM_UNIT_1, MCPWM_TIMER_1, &servo_pwm_config);
if (esp_err == 0)
Serial.println("Setting motor pwm success!");
else {
Serial.print("Setting motor pwm fail, error code: ");
Serial.println(esp_err);
}
mcpwm_start(MCPWM_UNIT_1, MCPWM_TIMER_1);
}
void loop() {
// PWM
// mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, 60);
// mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B, 0);
// mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);
// delay(2000);
mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_A, 0);
mcpwm_set_duty(MCPWM_UNIT_0, MCPWM_TIMER_0, MCPWM_OPR_B, 70);
mcpwm_start(MCPWM_UNIT_0, MCPWM_TIMER_0);
mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_1, MCPWM_OPR_A, 7.5);
delay(8700);
mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_1, MCPWM_OPR_A, 2.5);
delay(14600);
mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_1, MCPWM_OPR_A, 7.5);
delay(7700);
mcpwm_set_duty(MCPWM_UNIT_1, MCPWM_TIMER_1, MCPWM_OPR_A, 2.5);
delay(14600);
mcpwm_stop(MCPWM_UNIT_0, MCPWM_TIMER_0);
}
实现效果视频如下:
小车一周
小车遥控实现
接下来实现小车的遥控功能,即将小车作为一个热点,用可以连接网络的设备搜索到小车的局域网连接即可。首先进行小车的亮灯小程序。
亮灯小程序
设置用户名为guozichang,密码为220729,代码如下:
/*********
Rui Santos
Complete instructions at https://RandomNerdTutorials.com/esp32-cam-projects-ebook/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*********/
// https://randomnerdtutorials.com/esp32-esp8266-input-data-html-form/
//
#include "WiFi.h"
#include "esp_timer.h"
#include "img_converters.h"
#include "Arduino.h"
#include "soc/soc.h" // Disable brownour problems
#include "soc/rtc_cntl_reg.h" // Disable brownour problems
#include "driver/rtc_io.h"
#include <ESPAsyncWebServer.h>
#include <StringArray.h>
#include <FS.h>
// LED pin
const int white_led_pin = 32;
const int yellow_led_pin = 33;
// Set your access point network credentials
const char* ssid = "guozichang";
const char* password = "123456789";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
const char* PARAM_INPUT_1 = "white_light";
const char* PARAM_INPUT_2 = "yellow_light";
void toggle_light(int color);
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
<title>Mini-Car Controller</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
body { text-align:center; }
.vert { margin-bottom: 10%; }
.hori{ margin-bottom: 0%; }
</style>
</head>
<body>
<div align="center">
<button type="button" name="white_light" id="white_light">White Light</button>
<button type="button" name="yellow_light" id="yellow_light">Yellow Light</button>
</div>
<script>
var xhttp = new XMLHttpRequest();
var white_light_botton = document.getElementById('white_light');
var yellow_light_botton = document.getElementById('yellow_light');
white_light_botton.onclick = function() {
xhttp.open("POST", "/toggle_white_light");
xhttp.send();
console.log('toggle_white_light');
}
yellow_light_botton.onclick = function() {
xhttp.open("POST", "/toggle_yellow_light");
xhttp.send();
console.log('toggle_yellow_light');
}
</script>
</body>
</html>)rawliteral";
void setup() {
// Serial port for debugging purposes
Serial.begin(115200);
WiFi.mode(WIFI_AP);
if(!WiFi.softAPConfig(IPAddress(192, 168, 4, 1), IPAddress(192, 168, 4, 1), IPAddress(255, 255, 0, 0))){
Serial.println("AP Config Failed");
}
WiFi.softAP(ssid, password);
IPAddress IP = WiFi.softAPIP();
Serial.print("AP IP address: ");
Serial.println(IP);
// Turn-off the 'brownout detector'
WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0);
// set led pinmode
pinMode(white_led_pin, OUTPUT);
pinMode(yellow_led_pin, OUTPUT);
digitalWrite(white_led_pin, HIGH);
digitalWrite(yellow_led_pin, HIGH);
// Route for root / web page
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
request->send_P(200, "text/html", index_html); //完全可用
});
server.on("/toggle_white_light", HTTP_POST, [](AsyncWebServerRequest * request) { //用户发送
toggle_light(1);
});
server.on("/toggle_yellow_light", HTTP_POST, [](AsyncWebServerRequest * request) {
toggle_light(2);
});
// Start server
server.begin();
}
void loop() {
delay(1);
}
void toggle_light(int color) {
if (color == 1) {
bool state = digitalRead(white_led_pin);
digitalWrite(white_led_pin, !state);
}
else if (color == 2) {
bool state = digitalRead(yellow_led_pin);
digitalWrite(yellow_led_pin, !state);
}
}
在手机搜索到名称名为"guozichang"的局域网并连接后,在safari搜索网址198.168.4.1即可连接:
点击white light,结果如下:
再点击yellow light,效果如下:
点击开发板上的RST(复位)按钮,出现如下代码:
小车遥控实现
同样的操作,界面如下:
遥控小车倒库视频如下:
遥控倒库
总结
在经过昨天忙碌的拼小车过程后,今天很重要的一项就是熟悉自己的小车,一个是对小车进行调试,主要就是调整转弯以及直行时间,使其与小车速率互相配合来跑好地图路线;另一个是在进行遥控小车的配置后熟悉小车的遥控技术,以为明天的带摄像头无人驾驶项目做准备。在一次次参数微调中,小车跑的路线越来越好,越来越如我所愿,我在其中获得的成就感不言而喻。
缺点是由于放置方向、人为误差等原因,小车经常会压线,但老师说这也是无法避免的,因为它没有传感器,就只是自己在跑。期待明天的带传感器的实验。