当前位置: 首页 > web >正文

ESP32-C3_SMARTCAR

前言:
前面用stm32f103c8t6 rt-thread 写了个智能小车程序
这章用esp32-c3 重新来遍

1:环境
vscode+idf5.4
esp32-3c
找到一块MIN的底板 凑合用(138 cm左右)
一个L298N
一个船型开关,
一个6
65mm 2脚按钮
锂电池 18650
2 及电池盒(串联)
一个HC-RS04 超声波

2:接线及GPIO
超声波
#define TRIG_GPIO GPIO_NUM_6
#define ECHO_GPIO GPIO_NUM_7

PWM //如果接反,自行 修改 IN1 到IN4的 引脚 序号就可以,
这里已经用盖冒使能了,所以只要4个GPIO作为 PWM,.
也可以用 2个GPIO EN PWM ,再用4个GPIO 作为输出
#define IN1 GPIO_NUM_5
#define IN2 GPIO_NUM_4

#define IN3 GPIO_NUM_3
#define IN4 GPIO_NUM_2

// 按键引脚定义
#define KEY_GPIO GPIO_NUM_8

2节锂电池 直接 给L298N VS: 电机电压供应引脚,注意不是逻辑引脚,(逻辑引脚靠近 IN1-IN4)
接7-12V 电池,刚好 逻辑引脚可以输出 给MCU 供电,省了一个降压模块

超声波支架断了,用绳子绑下 凑合下
在这里插入图片描述

在这里插入图片描述

3:上代码

#include <stdio.h>
#include "driver/gpio.h"
#include "esp_timer.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_rom_sys.h"  // 添加此头文件以使用 esp_rom_delay_us()//pwm
#include "driver/ledc.h"//wifi
// WiFi配置
#include "esp_wifi.h"
#include "esp_event.h"
#include "nvs_flash.h"
#define WIFI_SSID "*****"
#define WIFI_PASSWORD "*******"
#define SERVER_HOST "192.168.1.3"
static EventGroupHandle_t s_wifi_event_group;
const int WIFI_CONNECTED_BIT = BIT0;// 引脚定义
// #define TRIG_GPIO  GPIO_NUM_0
// #define ECHO_GPIO  GPIO_NUM_1#define TRIG_GPIO  GPIO_NUM_6
#define ECHO_GPIO  GPIO_NUM_7// 超时时间(毫秒),对应约5米距离
#define MEASURE_TIMEOUT_MS 300  //50m 左右,足够足够了// 超声波测量距离阈值(cm)
#define OBSTACLE_THRESHOLD 20
//#define TAG "test_sr04"
// 增加超时时间(对应约10米)// L298N电机驱动引脚定义
// #define IN1 GPIO_NUM_12
// #define IN2 GPIO_NUM_13
// #define IN3 GPIO_NUM_19
// #define IN4 GPIO_NUM_18
// #define IN1 GPIO_NUM_4
// #define IN2 GPIO_NUM_5
// #define IN3 GPIO_NUM_2
// #define IN4 GPIO_NUM_3#define IN1 GPIO_NUM_5
#define IN2 GPIO_NUM_4#define IN3 GPIO_NUM_3
#define IN4 GPIO_NUM_2// 按键引脚定义
#define KEY_GPIO GPIO_NUM_8// PWM配置参数
#define PWM_FREQ_HZ       1000    // 电机PWM频率(1kHz)
#define PWM_RESOLUTION    LEDC_TIMER_8_BIT  // 8位分辨率(0-255)
#define PWM_TIMER         LEDC_TIMER_0      // 定时器编号
#define PWM_CH_IN1        LEDC_CHANNEL_0
#define PWM_CH_IN2        LEDC_CHANNEL_1
#define PWM_CH_IN3        LEDC_CHANNEL_2
#define PWM_CH_IN4        LEDC_CHANNEL_3// 任务句柄
static TaskHandle_t auto_nav_task_handle = NULL;// 状态变量
static volatile bool is_running = false;
static volatile bool key_pressed = false;// 日志标签
static const char *TAG = "esp32c3_car";// 事件队列
QueueHandle_t ultrasonic_event_queue = NULL;// 测量状态
typedef enum {MEASURE_IDLE,WAITING_ECHO_START,WAITING_ECHO_END
} measure_state_t;// 事件类型
typedef enum {ECHO_RISING_EDGE,ECHO_FALLING_EDGE,MEASURE_TIMEOUT
} ultrasonic_event_t;typedef struct 
{int64_t  curtick;ultrasonic_event_t  event;}ultrasonic_queue_t;// 测量数据结构
typedef struct {int64_t start_time;int64_t end_time;measure_state_t state;esp_timer_handle_t timeout_timer;
} ultrasonic_measure_t;// 全局测量实例
ultrasonic_measure_t measure;volatile bool     g_carstate = false; // false 停止  true 运行
//////PWM///////////////////////////////////////////////////////
// PWM初始化函数
void motor_pwm_init() {{gpio_config_t motor_lock_conf = {.pin_bit_mask = (1ULL << IN1) | (1ULL << IN2) | (1ULL << IN3) | (1ULL << IN4),.mode = GPIO_MODE_OUTPUT,.pull_up_en = GPIO_PULLUP_DISABLE,.pull_down_en = GPIO_PULLDOWN_ENABLE,  // 启用内部下拉.intr_type = GPIO_INTR_DISABLE};gpio_config(&motor_lock_conf);// 强制拉低所有引脚gpio_set_level(IN1, 0);gpio_set_level(IN2, 0);gpio_set_level(IN3, 0);gpio_set_level(IN4, 0);// 添加硬件级延时(不可中断)esp_rom_delay_us(5000);  // 5ms延时确保电平稳定ESP_LOGI(TAG, "IN1-IN4 LOW FINISH");}//LEDC_TIMER_13_BIT// 配置PWM定时器ledc_timer_config_t timer_cfg = {.speed_mode       = LEDC_LOW_SPEED_MODE,//高速模式-LEDC_LOW_SPEED_MODE,低速模式-LEDC_SPEED_MODE_MAX.timer_num        = PWM_TIMER,  //通道的定时器源(0 -> LEDC_TIMER_MAX - 1).duty_resolution  = PWM_RESOLUTION, // LEDC通道占空比分辨率.freq_hz          = PWM_FREQ_HZ,    //LEDC定时器频率(赫兹)0到2^(8)-1 =>0->255 // 0->(2^(PWM_RESOLUTION) -1).clk_cfg          = LEDC_AUTO_CLK};ESP_ERROR_CHECK(ledc_timer_config(&timer_cfg));// 配置4个PWM通道(IN1-IN4)ledc_channel_config_t ch_cfg[] = {{.gpio_num   = IN1,.speed_mode = LEDC_LOW_SPEED_MODE,.channel    = PWM_CH_IN1,.timer_sel  = PWM_TIMER, //选择通道的定时器源(0 - LEDC_TIMER_MAX - 1).duty       = 0, //LEDC通道占空比,占空比设置范围是[0, (2^占空比分辨率)].hpoint     = 0},{.gpio_num   = IN2,.speed_mode = LEDC_LOW_SPEED_MODE,.channel    = PWM_CH_IN2,.timer_sel  = PWM_TIMER,.duty       = 0,.hpoint     = 0},{.gpio_num   = IN3,.speed_mode = LEDC_LOW_SPEED_MODE,.channel    = PWM_CH_IN3,.timer_sel  = PWM_TIMER,.duty       = 0,.hpoint     = 0},{.gpio_num   = IN4,.speed_mode = LEDC_LOW_SPEED_MODE,.channel    = PWM_CH_IN4,.timer_sel  = PWM_TIMER,.duty       = 0,.hpoint     = 0}};for (int i = 0; i < 4; i++) {ESP_ERROR_CHECK(ledc_channel_config(&ch_cfg[i]));}ESP_LOGI(TAG, "电机PWM初始化完成");
}// 设置PWM占空比
static void set_pwm_duty(ledc_channel_t ch, uint8_t duty) {// duty=0;ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, ch, duty));ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, ch));
}// 电机控制函数(带PWM调速)
void motor_forward(uint8_t speed) {g_carstate  = true;set_pwm_duty(PWM_CH_IN1, speed);set_pwm_duty(PWM_CH_IN2, 0);set_pwm_duty(PWM_CH_IN3, speed);set_pwm_duty(PWM_CH_IN4, 0);
}void motor_backward(uint8_t speed) {g_carstate  = true;set_pwm_duty(PWM_CH_IN1, 0);set_pwm_duty(PWM_CH_IN2, speed);set_pwm_duty(PWM_CH_IN3, 0);set_pwm_duty(PWM_CH_IN4, speed);
}void motor_turn_left(uint8_t speed) {g_carstate  = true;// set_pwm_duty(PWM_CH_IN1, 0);// set_pwm_duty(PWM_CH_IN2, 0);// set_pwm_duty(PWM_CH_IN3, speed);// set_pwm_duty(PWM_CH_IN4, 0);set_pwm_duty(PWM_CH_IN1, 0);set_pwm_duty(PWM_CH_IN2, 0);set_pwm_duty(PWM_CH_IN3, speed);set_pwm_duty(PWM_CH_IN4, 0);}void motor_turn_spin_eft(uint8_t speed) {g_carstate  = true;set_pwm_duty(PWM_CH_IN1, 0);set_pwm_duty(PWM_CH_IN2, speed);set_pwm_duty(PWM_CH_IN3, speed);set_pwm_duty(PWM_CH_IN4, 0);
}void motor_turn_right(uint8_t speed) {g_carstate  = true;// set_pwm_duty(PWM_CH_IN1, speed);// set_pwm_duty(PWM_CH_IN2, 0);// set_pwm_duty(PWM_CH_IN3, 0);// set_pwm_duty(PWM_CH_IN4, 0);set_pwm_duty(PWM_CH_IN1, speed);set_pwm_duty(PWM_CH_IN2, 0);set_pwm_duty(PWM_CH_IN3, 0);set_pwm_duty(PWM_CH_IN4, 0);
}void motor_turn_spin_right(uint8_t speed) {g_carstate  = true;set_pwm_duty(PWM_CH_IN1, speed);set_pwm_duty(PWM_CH_IN2, 0);set_pwm_duty(PWM_CH_IN3, 0);set_pwm_duty(PWM_CH_IN4, speed);
}void motor_stop() {g_carstate  = false;set_pwm_duty(PWM_CH_IN1, 0);set_pwm_duty(PWM_CH_IN2, 0);set_pwm_duty(PWM_CH_IN3, 0);set_pwm_duty(PWM_CH_IN4, 0);
}
///////////////////////////////////////////////////////////////
//按键
// 按键中断处理
static QueueHandle_t gpio_evt_queue = NULL;
static bool  b_keypress = false;
//static volatile bool is_running = false;
static void IRAM_ATTR key_isr_handler(void* arg) {uint32_t gpio_num = (uint32_t) arg;int level = gpio_get_level(gpio_num);if (level == 0) {b_keypress = true;} else {if (b_keypress) {b_keypress = false;xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL);}}
}// 按键处理任务
static void key_task(void* arg) {uint32_t io_num;while (1) {if (xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) {if (io_num == KEY_GPIO) {is_running = !is_running;if (!is_running) {// motor_stop();} else {vTaskResume(auto_nav_task_handle);}ESP_LOGI(TAG, "statechange: %s", is_running ? "running" : "stop");}}}
}/////////////////////////////////////////////////////////////
// 中断服务程序
static void IRAM_ATTR echo_isr_handler(void* arg) {BaseType_t xHigherPriorityTaskWoken = pdFALSE;// ultrasonic_event_t event;ultrasonic_queue_t  event;// 获取准确的边缘类型uint32_t gpio_num = (uint32_t)arg;int level = gpio_get_level(gpio_num);event.curtick = esp_timer_get_time();if (level) {event.event = ECHO_RISING_EDGE;} else {event.event = ECHO_FALLING_EDGE;}// 发送事件到队列xQueueSendFromISR(ultrasonic_event_queue, &event, &xHigherPriorityTaskWoken);if (xHigherPriorityTaskWoken) {portYIELD_FROM_ISR();}
}// 超时定时器回调
static void timer_timeout_callback(void* arg) {BaseType_t xHigherPriorityTaskWoken = pdFALSE;ultrasonic_queue_t event ;event.event = MEASURE_TIMEOUT;event.curtick = esp_timer_get_time();// 发送超时事件xQueueSendFromISR(ultrasonic_event_queue, &event, &xHigherPriorityTaskWoken);if (xHigherPriorityTaskWoken) {portYIELD_FROM_ISR();}
}// 初始化超声波模块
void ultrasonic_init() {// 配置Trig为输出gpio_config_t trig_conf = {.pin_bit_mask = (1ULL << TRIG_GPIO),.mode = GPIO_MODE_OUTPUT,.pull_up_en = GPIO_PULLUP_DISABLE,.pull_down_en = GPIO_PULLDOWN_DISABLE,.intr_type = GPIO_INTR_DISABLE};gpio_config(&trig_conf);gpio_set_level(TRIG_GPIO, 0);// 配置Echo为输入,启用双边沿中断gpio_config_t echo_conf = {.pin_bit_mask = (1ULL << ECHO_GPIO),.mode = GPIO_MODE_INPUT,.pull_up_en = GPIO_PULLUP_DISABLE,.pull_down_en = GPIO_PULLDOWN_ENABLE,.intr_type = GPIO_INTR_ANYEDGE};gpio_config(&echo_conf);// 创建事件队列ultrasonic_event_queue = xQueueCreate(10, sizeof(ultrasonic_queue_t));// 安装GPIO中断服务(使用特定核心)gpio_install_isr_service(ESP_INTR_FLAG_IRAM);// 配置中断处理程序(传递GPIO编号作为参数)gpio_isr_handler_add(ECHO_GPIO, echo_isr_handler, (void*)ECHO_GPIO);// 初始化测量状态measure.state = MEASURE_IDLE;measure.timeout_timer = NULL;
}// 启动一次测量
void ultrasonic_start_measurement() {if (measure.state != MEASURE_IDLE) {printf("Measurement already in progress\n");return;}// 确保ECHO引脚空闲(低电平)if (gpio_get_level(ECHO_GPIO) != 0) {printf("WARNING: ECHO not idle before measurement!\n");return;}// 发送10us脉冲gpio_set_level(TRIG_GPIO, 1);esp_rom_delay_us(15);gpio_set_level(TRIG_GPIO, 0);// 设置测量状态measure.state = WAITING_ECHO_START;// 创建超时定时器const esp_timer_create_args_t timeout_timer_args = {.callback = &timer_timeout_callback,.arg = NULL,.name = "timeout_timer"};ESP_ERROR_CHECK(esp_timer_create(&timeout_timer_args, &measure.timeout_timer));ESP_ERROR_CHECK(esp_timer_start_once(measure.timeout_timer, MEASURE_TIMEOUT_MS * 1000));
}// 处理超声波事件
float ultrasonic_process_events() {ultrasonic_event_t event;ultrasonic_queue_t eventmain ;float distance = -1.0;// 等待事件(最多100ms)if (xQueueReceive(ultrasonic_event_queue, &eventmain, pdMS_TO_TICKS(100))) {event = eventmain.event ;switch (measure.state) {case WAITING_ECHO_START:if (event == ECHO_RISING_EDGE) {measure.start_time = eventmain.curtick;//esp_timer_get_time();measure.state = WAITING_ECHO_END;//  ESP_LOGI(TAG,"Rising edge detected[%lld]",eventmain.curtick);} else if (event == MEASURE_TIMEOUT) {ESP_LOGI(TAG,"Timeout waiting for rising edge. Echo level: %d->%lld", gpio_get_level(ECHO_GPIO),eventmain.curtick);measure.state = MEASURE_IDLE;//这里可能是空旷地,声波返回不了distance = 99;//默认99cm //给个默认距离好了}break;case WAITING_ECHO_END:if (event == ECHO_FALLING_EDGE) {measure.end_time = eventmain.curtick;//esp_timer_get_time();uint32_t duration = measure.end_time - measure.start_time;//us 1s=340 1ms=0.34m  1us// 有效距离检查(2cm - 4m)if (duration > 117 && duration < 23529) {distance = (duration * 0.034) / 2.0; //(因为1米=100厘米,所以340米/秒 = 34000厘米/秒 = 34厘米/毫秒 = 0.034厘米/微秒)//   ESP_LOGI(TAG,"Falling edge detected[%lld]",eventmain.curtick);} else {ESP_LOGI(TAG,"Invalid duration: %d us\n",(int) duration);}measure.state = MEASURE_IDLE;} else if (event == MEASURE_TIMEOUT) {ESP_LOGI(TAG,"Timeout waiting for falling edge. Echo level: %d->%lld", gpio_get_level(ECHO_GPIO),eventmain.curtick);measure.state = MEASURE_IDLE;}break;default:ESP_LOGI(TAG,"Unexpected event in state: %d\n", (int)(measure.state));break;}// 清理定时器if (measure.timeout_timer && (event == ECHO_FALLING_EDGE || event == MEASURE_TIMEOUT)) {esp_timer_stop(measure.timeout_timer);esp_timer_delete(measure.timeout_timer);measure.timeout_timer = NULL;}} else {ESP_LOGI(TAG,"No event received in ultrasonic_process_events\n");}return distance;
}// 诊断函数:检查GPIO状态
void check_gpio_states() {ESP_LOGI(TAG,"TRIG state: %d, ECHO state: %d\n", gpio_get_level(TRIG_GPIO),gpio_get_level(ECHO_GPIO));
}// 手动触发中断(用于测试)
void simulate_echo_signal() {ESP_LOGI(TAG,"Simulating ECHO signal...\n");// 模拟上升沿gpio_set_level(ECHO_GPIO, 1);vTaskDelay(pdMS_TO_TICKS(1));// 模拟下降沿(实际距离对应5cm)gpio_set_level(ECHO_GPIO, 0);
}//const float  u8_Percent = 100/80 ;
//3.7*2  锂电池  空占比 要少小点,不然速度太快了,速度可以自行调整
const uint8_t NORMAL_SPEED = 100;    // 正常速度(~60%)150
const uint8_t TURN_SPEED = 100;      // 转向速度(~40%)100
const uint8_t BACK_SPEED = 120;      // 后退速度(~50%)120
// 自动寻路任务
static void auto_navigation_task(void* arg) {int16_t measured_distance = 0;int16_t  flag_run = 0;int64_t  loop_start =0;int64_t  loop_end =0;#define  CHECK_STATE()  if(!is_running) continue;while (1) {if (is_running) {flag_run=0;loop_start = esp_timer_get_time();ultrasonic_start_measurement();// 等待测量完成// vTaskDelay(pdMS_TO_TICKS(30)); //额外增加的 34厘米/毫秒 //30ms = 30 *34 = 1m //不要加,要实时取消息处理//     // 处理事件直到测量完成或超时float distance = -1.0;while (measure.state != MEASURE_IDLE) {distance = ultrasonic_process_events();vTaskDelay(pdMS_TO_TICKS(1)); // 防止任务阻塞}if(distance >0.0001f){measured_distance =  distance ;}else{measured_distance = 0;}//   measured_distance =30;//   ESP_LOGI(TAG,"Distance: %d cm\n", measured_distance);//  measured_distance =0;if (measured_distance <= 0 ) {//|| measured_distance > 5000// 测量错误,停止flag_run =1;motor_stop();vTaskDelay(pdMS_TO_TICKS(500));} else if (measured_distance < OBSTACLE_THRESHOLD) {if(g_carstate){motor_stop();vTaskDelay(pdMS_TO_TICKS(500));}CHECK_STATE()// 检测到障碍物,后退并转向motor_backward(BACK_SPEED);vTaskDelay(pdMS_TO_TICKS(500));CHECK_STATE()motor_stop();vTaskDelay(pdMS_TO_TICKS(500));CHECK_STATE()// 随机转向if (rand() % 2 == 0) {flag_run =2;motor_turn_left(TURN_SPEED);} else {flag_run =3;motor_turn_right(TURN_SPEED);}vTaskDelay(pdMS_TO_TICKS(500));CHECK_STATE()//////////////////////////////////////motor_stop();vTaskDelay(pdMS_TO_TICKS(500));} else {// 无障碍物,前进flag_run =4;motor_forward(NORMAL_SPEED);vTaskDelay(pdMS_TO_TICKS(10)); //额外增加的}loop_end = esp_timer_get_time();//  motor_stop();// vTaskDelay(pdMS_TO_TICKS(500));ESP_LOGI(TAG,"Distance: %d cm %d(%lld->%lld)", measured_distance,flag_run,loop_start,loop_end);} else if(g_carstate){motor_stop();vTaskDelay(pdMS_TO_TICKS(500)); //}else{vTaskSuspend(NULL);vTaskDelay(pdMS_TO_TICKS(100));}}
}
//wifi
// WiFi事件处理函数
static void event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data) {if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {esp_wifi_connect();} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {esp_wifi_connect();xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT);ESP_LOGW(TAG, "WiFi disconnect,try again...");} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;ESP_LOGI(TAG, "get IP address: " IPSTR, IP2STR(&event->ip_info.ip));xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);}
}// WiFi初始化////////////////////////////////////////////////////////
void wifi_init_sta(void) {s_wifi_event_group = xEventGroupCreate();ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());esp_netif_create_default_wifi_sta();wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));wifi_config_t wifi_config = {.sta = {.ssid = WIFI_SSID,.password = WIFI_PASSWORD,},};ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));ESP_ERROR_CHECK(esp_wifi_start());ESP_LOGI(TAG, "WiFi init finish,connect %s...", WIFI_SSID);
}void init_wifi(){esp_err_t ret = nvs_flash_init();if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {ESP_ERROR_CHECK(nvs_flash_erase());ret = nvs_flash_init();}ESP_ERROR_CHECK(ret);wifi_init_sta();xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT,pdFALSE, pdTRUE, portMAX_DELAY);
}
/////////////////////////////////////////////////////////////////////////////
void  test_ultrasonic(){// int64_t  loop_start = esp_timer_get_time();ultrasonic_start_measurement();// 等待测量完成// vTaskDelay(pdMS_TO_TICKS(30)); //额外增加的 34厘米/毫秒 //30ms = 30 *34 = 1m //不要加,要实时取消息处理//     // 处理事件直到测量完成或超时float distance = -1.0;while (measure.state != MEASURE_IDLE) {distance = ultrasonic_process_events();vTaskDelay(pdMS_TO_TICKS(1)); // 防止任务阻塞} ESP_LOGI(TAG,"test_ultrasonic: %.2f cm", distance);
}//
void test_montor(){{test_ultrasonic();}//测试小车状态for(int i=0;i<2;i++){ESP_LOGI(TAG, "motor_forward");for(int j=0;j<10;j++){motor_forward(NORMAL_SPEED);vTaskDelay(pdMS_TO_TICKS(500)); //motor_stop();vTaskDelay(pdMS_TO_TICKS(1500)); //}ESP_LOGI(TAG, "motor_backward");for(int j=0;j<3;j++){motor_backward(BACK_SPEED);vTaskDelay(pdMS_TO_TICKS(500)); //motor_stop();vTaskDelay(pdMS_TO_TICKS(1500)); //}ESP_LOGI(TAG, "motor_turn_left");for(int j=0;j<3;j++){motor_turn_left(TURN_SPEED);vTaskDelay(pdMS_TO_TICKS(500)); //motor_stop();vTaskDelay(pdMS_TO_TICKS(1500)); //}ESP_LOGI(TAG, "motor_turn_right");for(int j=0;j<3;j++){motor_turn_right(TURN_SPEED);vTaskDelay(pdMS_TO_TICKS(500)); //motor_stop();vTaskDelay(pdMS_TO_TICKS(1500)); //}{test_ultrasonic();}}}
////////////////////////////////////////////////////////////////////////////////
void app_main() {// 1. 初始化PWM并立即停止电机motor_pwm_init();motor_stop();   // 确保所有占空比为0// 2. 初始化WiFi(如果不需要可以去掉)init_wifi();// 3. 初始化超声波ultrasonic_init();// 4. 配置按键引脚(非PWM的GPIO)// 配置按键引脚为输入,并设置中断gpio_config_t key_conf = {.pin_bit_mask = (1ULL << KEY_GPIO),.mode = GPIO_MODE_INPUT,.pull_up_en = GPIO_PULLUP_ENABLE,.pull_down_en = GPIO_PULLDOWN_DISABLE,.intr_type = GPIO_INTR_ANYEDGE};gpio_config(&key_conf);// 5. 创建按键事件队列并添加中断处理gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));gpio_isr_handler_add(KEY_GPIO, key_isr_handler, (void*)KEY_GPIO);// 6. 创建任务xTaskCreate(key_task, "key_task", 2048, NULL, 5, NULL);if(0){vTaskDelay(pdMS_TO_TICKS(2000)); //
//          const uint8_t NORMAL_SPEED = 150;    // 正常速度(~60%)
// const uint8_t TURN_SPEED = 100;      // 转向速度(~40%)
// const uint8_t BACK_SPEED = 120;      // 后退速度(~50%)test_montor();}xTaskCreate(auto_navigation_task, "auto_nav_task", 4096, NULL, 4, &auto_nav_task_handle);ESP_LOGI(TAG, "System initialization complete");
}

4: 测试结果 如果对你又帮助,麻烦点个赞,加个关注
问题,挂电池的那边 重,有点不平衡,电池没地方装了,没办法了
其他的 传感器度没地方装啊,底板太小了
在这里插入图片描述

测试视频

esp3c-c3_smartcar

http://www.xdnf.cn/news/18024.html

相关文章:

  • AI客户维护高效解决方案
  • Matlab利用系统辨识工具箱辨识自带数据集的控制系统参数(传递函数篇)
  • 【web自动化】-8-EXCEL数据驱动
  • Web攻防-大模型应用LLM搭建接入第三方内容喂养AI插件安全WiKI库技术赋能
  • (自用)console.log怎么上色
  • Linux————网络基础
  • Kafka生产者原理深度解析
  • 晶振电路的负载电容、电阻参数设计
  • 力扣 hot100 Day74
  • 读《精益数据分析》:黏性(Stickiness)—— 验证解决方案是否留住用户
  • MySQL 关键字总结,并结合 SQL 类型(DDL / DML / DQL / DCL / TCL) 说明每类关键字的作用、使用场景和示例
  • Pr cs6安装教程
  • 标题:移动端安全加固:发散创新,筑牢安全防线引言:随着移动互联网
  • 【多模态大模型】--BLIP3
  • 集成电路学习:什么是Object Detection目标检测
  • Apache 如何支持SHTML(SSI)的配置方法
  • DAY41打卡
  • 高等数学 8.3 平面及其方程
  • 力扣top100(day04-04)--栈
  • 结构体(Struct)、枚举(Enum)的使用
  • MySQL的学习笔记
  • 基于Spring Boot的智能民宿预订与游玩系统设计与实现 民宿管理系统 民宿预订系统 民宿订房系统
  • Fiddler 实用指南,让网络调试更直观、更高效
  • 【秋招笔试】2025.08.15饿了么秋招机考-第三题
  • 4.3 computed watch watchEffect
  • 日本CN2服务器租用多少钱
  • sqli-labs通关笔记-第50关 GET数值型order by堆叠注入(手工注入+脚本注入两种方法)
  • Redis 缓存和 Redis 分布式锁
  • Java 大视界 -- 基于 Java 的大数据可视化在城市交通拥堵治理与出行效率提升中的应用(398)
  • 嵌入式硬件篇---电容滤波