commit 327994ff361a1bfd5e182dd9cec9f42a51644d6e Author: 玖叁 Date: Thu Dec 12 15:38:11 2024 +0800 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..89cc49c --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..080e70d --- /dev/null +++ b/.vscode/extensions.json @@ -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" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6c8638f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "files.exclude": { + "**/*.rpyc": true, + "**/*.rpa": true, + "**/*.rpymc": true, + "**/cache/": true + } +} \ No newline at end of file diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -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 diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..2593a33 --- /dev/null +++ b/lib/README @@ -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 +#include + +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 diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..4b30716 --- /dev/null +++ b/platformio.ini @@ -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 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..85cb83a --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,231 @@ +#include +#include + +// 使用 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); // 控制更新频率 +} diff --git a/test/README b/test/README new file mode 100644 index 0000000..9b1e87b --- /dev/null +++ b/test/README @@ -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