init
This commit is contained in:
commit
327994ff36
|
@ -0,0 +1,5 @@
|
|||
.pio
|
||||
.vscode/.browse.c_cpp.db*
|
||||
.vscode/c_cpp_properties.json
|
||||
.vscode/launch.json
|
||||
.vscode/ipch
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"files.exclude": {
|
||||
"**/*.rpyc": true,
|
||||
"**/*.rpa": true,
|
||||
"**/*.rpymc": true,
|
||||
"**/cache/": true
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
This directory is intended for project header files.
|
||||
|
||||
A header file is a file containing C declarations and macro definitions
|
||||
to be shared between several project source files. You request the use of a
|
||||
header file in your project source file (C, C++, etc) located in `src` folder
|
||||
by including it, with the C preprocessing directive `#include'.
|
||||
|
||||
```src/main.c
|
||||
|
||||
#include "header.h"
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
Including a header file produces the same results as copying the header file
|
||||
into each source file that needs it. Such copying would be time-consuming
|
||||
and error-prone. With a header file, the related declarations appear
|
||||
in only one place. If they need to be changed, they can be changed in one
|
||||
place, and programs that include the header file will automatically use the
|
||||
new version when next recompiled. The header file eliminates the labor of
|
||||
finding and changing all the copies as well as the risk that a failure to
|
||||
find one copy will result in inconsistencies within a program.
|
||||
|
||||
In C, the usual convention is to give header files names that end with `.h'.
|
||||
It is most portable to use only letters, digits, dashes, and underscores in
|
||||
header file names, and at most one dot.
|
||||
|
||||
Read more about using header files in official GCC documentation:
|
||||
|
||||
* Include Syntax
|
||||
* Include Operation
|
||||
* Once-Only Headers
|
||||
* Computed Includes
|
||||
|
||||
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
This directory is intended for project specific (private) libraries.
|
||||
PlatformIO will compile them to static libraries and link into executable file.
|
||||
|
||||
The source code of each library should be placed in an own separate directory
|
||||
("lib/your_library_name/[here are source files]").
|
||||
|
||||
For example, see a structure of the following two libraries `Foo` and `Bar`:
|
||||
|
||||
|--lib
|
||||
| |
|
||||
| |--Bar
|
||||
| | |--docs
|
||||
| | |--examples
|
||||
| | |--src
|
||||
| | |- Bar.c
|
||||
| | |- Bar.h
|
||||
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
|
||||
| |
|
||||
| |--Foo
|
||||
| | |- Foo.c
|
||||
| | |- Foo.h
|
||||
| |
|
||||
| |- README --> THIS FILE
|
||||
|
|
||||
|- platformio.ini
|
||||
|--src
|
||||
|- main.c
|
||||
|
||||
and a contents of `src/main.c`:
|
||||
```
|
||||
#include <Foo.h>
|
||||
#include <Bar.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
...
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
PlatformIO Library Dependency Finder will find automatically dependent
|
||||
libraries scanning project source files.
|
||||
|
||||
More information about PlatformIO Library Dependency Finder
|
||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
|
@ -0,0 +1,14 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp32dev]
|
||||
platform = espressif32
|
||||
board = esp32dev
|
||||
framework = arduino
|
|
@ -0,0 +1,231 @@
|
|||
#include <Arduino.h>
|
||||
#include <BluetoothSerial.h>
|
||||
|
||||
// 使用 2 片 TB6612 控制 4 个电机
|
||||
// 使用差速控制转向
|
||||
|
||||
// TB6612 #1 控制 A B 电机
|
||||
#define MOTOR_AB_STBY 14 // TB6612 #1 待机控制
|
||||
|
||||
// A 电机 左前轮
|
||||
#define MOTOR_A_PWMA 25 // 电机 A PWM
|
||||
#define MOTOR_A_AIN1 26 // 电机 A 方向控制1
|
||||
#define MOTOR_A_AIN2 27 // 电机 A 方向控制2
|
||||
|
||||
// B 电机 左后轮
|
||||
#define MOTOR_B_PWMB 32 // 电机 B PWM
|
||||
#define MOTOR_B_BIN1 33 // 电机 B 方向控制1
|
||||
#define MOTOR_B_BIN2 34 // 电机 B 方向控制2
|
||||
|
||||
// TB6612 #2 控制 C D 电机
|
||||
#define MOTOR_CD_STBY 19 // TB6612 #2 待机控制
|
||||
|
||||
// C 电机 右前轮
|
||||
#define MOTOR_C_PWMA 16 // 电机 C PWM
|
||||
#define MOTOR_C_AIN1 17 // 电机 C 方向控制1
|
||||
#define MOTOR_C_AIN2 18 // 电机 C 方向控制2
|
||||
|
||||
// D 电机 右后轮
|
||||
#define MOTOR_D_PWMB 21 // 电机 D PWM
|
||||
#define MOTOR_D_BIN1 22 // 电机 D 方向控制1
|
||||
#define MOTOR_D_BIN2 23 // 电机 D 方向控制2
|
||||
|
||||
// 运动控制参数
|
||||
#define MAX_SPEED 255 // 最大速度
|
||||
#define BASE_SPEED 200 // 基础速度
|
||||
#define MIN_SPEED 50 // 最小速度
|
||||
#define TURN_RATIO 0.6 // 转向时的速度比例
|
||||
#define SPEED_INCREMENT 10 // 速度增量
|
||||
|
||||
// 全局变量
|
||||
int currentSpeed = 0; // 当前速度
|
||||
int turnOffset = 0; // 转向偏移量 (-100 到 100)
|
||||
bool isMoving = false; // 运动状态
|
||||
bool isTurning = false; // 转向状态
|
||||
|
||||
BluetoothSerial SerialBT;
|
||||
|
||||
// 电机控制函数
|
||||
void motorControl(int pwmPin, int in1Pin, int in2Pin, int speed) {
|
||||
if (speed > 0) {
|
||||
digitalWrite(in1Pin, HIGH);
|
||||
digitalWrite(in2Pin, LOW);
|
||||
} else if (speed < 0) {
|
||||
digitalWrite(in1Pin, LOW);
|
||||
digitalWrite(in2Pin, HIGH);
|
||||
speed = -speed;
|
||||
} else {
|
||||
digitalWrite(in1Pin, LOW);
|
||||
digitalWrite(in2Pin, LOW);
|
||||
}
|
||||
analogWrite(pwmPin, speed);
|
||||
}
|
||||
|
||||
// 小车运动控制函数
|
||||
void carControl(int leftSpeed, int rightSpeed) {
|
||||
motorControl(MOTOR_A_PWMA, MOTOR_A_AIN1, MOTOR_A_AIN2, leftSpeed); // 左前
|
||||
motorControl(MOTOR_B_PWMB, MOTOR_B_BIN1, MOTOR_B_BIN2, leftSpeed); // 左后
|
||||
motorControl(MOTOR_C_PWMA, MOTOR_C_AIN1, MOTOR_C_AIN2, rightSpeed); // 右前
|
||||
motorControl(MOTOR_D_PWMB, MOTOR_D_BIN1, MOTOR_D_BIN2, rightSpeed); // 右后
|
||||
}
|
||||
|
||||
// 计算左右轮速度
|
||||
void calculateWheelSpeeds(int baseSpeed, int turnOffset, int &leftSpeed, int &rightSpeed) {
|
||||
// turnOffset 范围:-100 到 100
|
||||
// 负值表示向左转,正值表示向右转
|
||||
float turnMultiplier = 1.0 - (abs(turnOffset) / 100.0) * (1.0 - TURN_RATIO);
|
||||
|
||||
if (turnOffset < 0) { // 向左转
|
||||
leftSpeed = baseSpeed * turnMultiplier;
|
||||
rightSpeed = baseSpeed;
|
||||
} else if (turnOffset > 0) { // 向右转
|
||||
leftSpeed = baseSpeed;
|
||||
rightSpeed = baseSpeed * turnMultiplier;
|
||||
} else { // 直行
|
||||
leftSpeed = baseSpeed;
|
||||
rightSpeed = baseSpeed;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新小车运动
|
||||
void updateCarMovement() {
|
||||
int leftSpeed = 0, rightSpeed = 0;
|
||||
|
||||
if (isMoving) {
|
||||
calculateWheelSpeeds(currentSpeed, turnOffset, leftSpeed, rightSpeed);
|
||||
if (!isTurning) {
|
||||
// 逐渐加速
|
||||
currentSpeed = min(currentSpeed + SPEED_INCREMENT, BASE_SPEED);
|
||||
}
|
||||
} else {
|
||||
// 逐渐减速
|
||||
currentSpeed = max(currentSpeed - SPEED_INCREMENT, 0);
|
||||
if (currentSpeed > 0) {
|
||||
calculateWheelSpeeds(currentSpeed, turnOffset, leftSpeed, rightSpeed);
|
||||
}
|
||||
}
|
||||
|
||||
carControl(leftSpeed, rightSpeed);
|
||||
}
|
||||
|
||||
// CCD 巡线相关函数
|
||||
#define CCD_PIN 35 // CCD 数据引脚
|
||||
#define CCD_CLK_PIN 36 // CCD 时钟引脚
|
||||
#define CCD_SI_PIN 39 // CCD 启动引脚
|
||||
#define CCD_PIXELS 128 // CCD 像素数
|
||||
|
||||
int ccdData[CCD_PIXELS]; // CCD 数据数组
|
||||
|
||||
// 读取 CCD 数据
|
||||
void readCCD() {
|
||||
// 启动信号
|
||||
digitalWrite(CCD_SI_PIN, HIGH);
|
||||
digitalWrite(CCD_CLK_PIN, HIGH);
|
||||
digitalWrite(CCD_SI_PIN, LOW);
|
||||
digitalWrite(CCD_CLK_PIN, LOW);
|
||||
|
||||
// 读取像素数据
|
||||
for(int i = 0; i < CCD_PIXELS; i++) {
|
||||
digitalWrite(CCD_CLK_PIN, HIGH);
|
||||
ccdData[i] = analogRead(CCD_PIN);
|
||||
digitalWrite(CCD_CLK_PIN, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
// 计算巡线偏移量
|
||||
int calculateLineOffset() {
|
||||
// 这里添加线位置检测算法
|
||||
// 返回值范围:-100 到 100
|
||||
// 0 表示线在中间,负值表示线在左边,正值表示线在右边
|
||||
return 0; // 临时返回值
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
// 初始化串口
|
||||
Serial.begin(115200);
|
||||
|
||||
// 初始化蓝牙
|
||||
SerialBT.begin("ESP32_Car"); // 蓝牙设备名称
|
||||
|
||||
// 设置引脚模式
|
||||
pinMode(MOTOR_AB_STBY, OUTPUT);
|
||||
pinMode(MOTOR_CD_STBY, OUTPUT);
|
||||
|
||||
pinMode(MOTOR_A_PWMA, OUTPUT);
|
||||
pinMode(MOTOR_A_AIN1, OUTPUT);
|
||||
pinMode(MOTOR_A_AIN2, OUTPUT);
|
||||
|
||||
pinMode(MOTOR_B_PWMB, OUTPUT);
|
||||
pinMode(MOTOR_B_BIN1, OUTPUT);
|
||||
pinMode(MOTOR_B_BIN2, OUTPUT);
|
||||
|
||||
pinMode(MOTOR_C_PWMA, OUTPUT);
|
||||
pinMode(MOTOR_C_AIN1, OUTPUT);
|
||||
pinMode(MOTOR_C_AIN2, OUTPUT);
|
||||
|
||||
pinMode(MOTOR_D_PWMB, OUTPUT);
|
||||
pinMode(MOTOR_D_BIN1, OUTPUT);
|
||||
pinMode(MOTOR_D_BIN2, OUTPUT);
|
||||
|
||||
// 启用电机驱动
|
||||
digitalWrite(MOTOR_AB_STBY, HIGH);
|
||||
digitalWrite(MOTOR_CD_STBY, HIGH);
|
||||
|
||||
// 添加 CCD 引脚初始化
|
||||
// pinMode(CCD_CLK_PIN, OUTPUT);
|
||||
// pinMode(CCD_SI_PIN, OUTPUT);
|
||||
// pinMode(CCD_PIN, INPUT);
|
||||
}
|
||||
|
||||
void loop()
|
||||
{
|
||||
if (SerialBT.available()) {
|
||||
char cmd = SerialBT.read();
|
||||
|
||||
switch(cmd) {
|
||||
case 'F': // 前进
|
||||
isMoving = true;
|
||||
turnOffset = 0;
|
||||
break;
|
||||
case 'B': // 后退
|
||||
isMoving = true;
|
||||
currentSpeed = -BASE_SPEED;
|
||||
turnOffset = 0;
|
||||
break;
|
||||
case 'L': // 左转
|
||||
isTurning = true;
|
||||
turnOffset = -100;
|
||||
break;
|
||||
case 'R': // 右转
|
||||
isTurning = true;
|
||||
turnOffset = 100;
|
||||
break;
|
||||
case 'S': // 停止
|
||||
isMoving = false;
|
||||
isTurning = false;
|
||||
turnOffset = 0;
|
||||
break;
|
||||
case 'l': // 微左转
|
||||
turnOffset = max(turnOffset - 20, -100);
|
||||
break;
|
||||
case 'r': // 微右转
|
||||
turnOffset = min(turnOffset + 20, 100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 更新小车运动
|
||||
updateCarMovement();
|
||||
|
||||
// 巡线模式代码(后续启用)
|
||||
/*
|
||||
readCCD();
|
||||
int lineOffset = calculateLineOffset();
|
||||
turnOffset = lineOffset;
|
||||
isMoving = true;
|
||||
updateCarMovement();
|
||||
*/
|
||||
|
||||
delay(20); // 控制更新频率
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
This directory is intended for PlatformIO Test Runner and project tests.
|
||||
|
||||
Unit Testing is a software testing method by which individual units of
|
||||
source code, sets of one or more MCU program modules together with associated
|
||||
control data, usage procedures, and operating procedures, are tested to
|
||||
determine whether they are fit for use. Unit testing finds problems early
|
||||
in the development cycle.
|
||||
|
||||
More information about PlatformIO Unit Testing:
|
||||
- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
|
Loading…
Reference in New Issue