本系列教程讲解零知小车套件以零知迷你板为主控,使用零知开源平台进行智能小车开发。
使用的硬件:零知智能小车套件-http://www.lingzhilab.com/index.php/home/goods/introduction?gid=1365
实现的功能:红外循迹、超声避障、直线运行、手机蓝牙控制等基本功能。
扩展:可以在小车上加入其它传感器模块进行扩展,比如加入摄像头模块进行监控、加入火焰传感器做灭火小车、加入更多超声波模块实现自动跟随...
零知两轮小车入门版(ESP32主控)教程1-小车组装
/lzbbs/html/car/c2/car1.html零知两轮小车入门版(ESP32主控)教程2-让小车跑起来
/lzbbs/html/car/c2/car2.html零知两轮小车入门版(ESP32主控)教程3-手机WiFi/蓝牙控制小车
/lzbbs/html/car/c2/car3.html零知两轮小车入门版(ESP32主控)教程4-超声波自动避障
/lzbbs/html/car/c2/car4.html零知两轮小车入门版(ESP32主控)教程5-红外循迹
/lzbbs/html/car/c2/car5.html零知两轮小车入门版(ESP32主控)教程6-使用PID走直线
/lzbbs/html/car/c2/car6.html(1)组装好的智能小车
(2)零知ESP32
(3)安卓手机+零知星球APP
ESP32自带WiFi和蓝牙,所以使用ESP32做为主控板无需另接WiFi或蓝牙模块用以控制。手机WiFi/蓝牙控制2轮的程序代码实现如下:
/**********************************************************
* 文件: 4WD_car.ino by 零知实验室([url=http://www.lingzhilab.com]www.lingzhilab.com[/url])
* -^^- 零知开源,让电子制作变得更简单! -^^-
* 时间: 2019/11/19 16:35
* 说明:
************************************************************/
#define Bluetooth // 若使用蓝牙连接,取消此条注释
#ifdef Bluetooth
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEServer.h>
//使用其他蓝牙软件需修改此识别码
#define SERVICE_UUID "0000ffe0-0000-1000-8000-00805f9b34fb"
#define CHARACTERISTIC_UUID "0000ffe1-0000-1000-8000-00805f9b34fb"
bool deviceConnected = false;
#else
#include <WiFi.h>
#include <WiFiMulti.h>
WiFiMulti WiFiMulti;
//修改成你的WiFi账号密码
#define SSID "xxx"
#define PASSWD "xxx"
const uint16_t port = 6666; //服务器端口号
const char *host = "192.168.0.102"; //服务器IP地址
WiFiClient ESP32CAR; //创建WiFi客户端实例
#endif
//创建字符串变量存储接收到的信息
String str;
String pitch;
String roll;
//设置电机引脚
#define LEFT_MOTO1 32
#define LEFT_MOTO2 33
#define RIGHT_MOTO1 25
#define RIGHT_MOTO2 26
//#define LEFT_MOTO1 27
//#define LEFT_MOTO2 14
//#define RIGHT_MOTO1 12
//#define RIGHT_MOTO2 13
#ifdef Bluetooth
class MyCallbacks: public BLECharacteristicCallbacks {
void onConnect(BLEServer* pServer) {
deviceConnected = true;
};
void onDisconnect(BLEServer* pServer) {
deviceConnected = false;
};
void onWrite(BLECharacteristic *pCharacteristic) {
std::string value = pCharacteristic->getValue(); //获取蓝牙发送过来的信息
//对接收到的信息进行处理
for(int i = 0;i<10;i++)
{
str += value[i];
// Serial.print(value[i]);
}
int pos1 = str.indexOf("("); //检索"("在字符串中的位置
int pos2 = str.indexOf(",");
int pos3 = str.indexOf(")");
pitch = str.substring(pos1+1,pos2); //将两个位置之间的字符串提取出来
roll = str.substring(pos2+1,pos3);
str = ""; //清空接收到的信息以存储下一次的信息
Serial.print("pitch:");
Serial.print(pitch);
Serial.print(" roll:");
Serial.println(roll);
}
};
#endif
void setup() {
Serial.begin(9600);
pinMode(LEFT_MOTO1,OUTPUT);
pinMode(LEFT_MOTO2,OUTPUT);
pinMode(RIGHT_MOTO1,OUTPUT);
pinMode(RIGHT_MOTO2,OUTPUT);
//设置引脚输出PWM的通道
ledcAttachPin(LEFT_MOTO1,1);
ledcAttachPin(LEFT_MOTO2,2);
ledcAttachPin(RIGHT_MOTO1,3);
ledcAttachPin(RIGHT_MOTO2,4);
ledcSetup(1, 12000, 8);
ledcSetup(2, 12000, 8);
ledcSetup(3, 12000, 8);
ledcSetup(4, 12000, 8);
#ifdef Bluetooth
BLEDevice::init("ESP32_car"); //初始化蓝牙,参数为蓝牙名称
BLEServer *pServer = BLEDevice::createServer(); //创建蓝牙服务器
BLEService *pService = pServer->createService(SERVICE_UUID); //创建蓝牙Service服务
//设置蓝牙功能为读/写
BLECharacteristic *pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks()); //设置回调函数
pService->start(); //启动服务
BLEAdvertising *pAdvertising = pServer->getAdvertising();
pAdvertising->start();
Serial.println("蓝牙已开启!");
#else
WiFiMulti.addAP(SSID,PASSWD); //连接WiFi
Serial.println("等待WiFi... ");
//等待wifi连接成功
while (WiFiMulti.run() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.println("WiFi连接成功");
Serial.print("IP地址: ");
Serial.println(WiFi.localIP());
while(!ESP32CAR.connect(host, port)) { //连接服务器
Serial.println("连接失败");
Serial.println("等待5秒...");
delay(5000);
}
Serial.print("成功连接到: ");
Serial.println(host);
#endif
delay(500);
}
void loop() {
#ifdef Bluetooth
carRun(pitch.toInt(),roll.toInt());
#else
if(ESP32CAR.available()){
getCommand();
carRun(pitch.toInt(),roll.toInt());
}
#endif
}
#ifndef Bluetooth
//获取WiFi发送过来的pitch,roll
void getCommand(){
str = "";
while(ESP32CAR.available()) {
char c = ESP32CAR.read();
str+=c;
}
int pos1 = str.indexOf("(");
int pos2 = str.indexOf(",");
int pos3 = str.indexOf(")");
pitch = str.substring(pos1+1,pos2);
roll = str.substring(pos2+1,pos3);
Serial.print("pitch=");
Serial.print(pitch);
Serial.print(" roll=");
Serial.println(roll);
}
#endif
void carRun(int rate,int extent){
//将接收到的pitch映射到控制电机转速的pwm值,roll映射到单个轮子的pwm值
int speed = map(rate,15,90,100,250);
int right = map(extent,15,90,speed,80);
int left = map(extent,-90,-15,80,speed);
if(extent>-15&&extent<15&&rate>15){
Serial.println("前进");
motoRun(speed,speed);
}
if((extent>165||extent<-165)&&rate>10){
Serial.println("后退");
motoRun(-speed,-speed);
}
if(extent>15&&extent<90&&rate>15){
Serial.println("右转弯");
motoRun(speed,right);
}
if(extent<-15&&extent>-90&&rate>15){
Serial.println("左转弯");
motoRun(left,speed);
}
if(rate<15){
Serial.println("停车");
motoStop();
}
}
//控制电机,正值前进,负值后退
void motoRun(int speedL,int speedR){
if(speedL>0){
ledcWrite(1,0);
ledcWrite(2,speedL);
}else{
ledcWrite(1,-speedL);
ledcWrite(2,0);
}
if(speedR>0){
ledcWrite(3,0);
ledcWrite(4,speedR);
}else{
ledcWrite(3,-speedR);
ledcWrite(4,0);
}
}
//停车
void motoStop(){
ledcWrite(1,0);
ledcWrite(2,0);
ledcWrite(3,0);
ledcWrite(4,0);
}
将以上代码验证上传至ESP32开发板上。
然后我们打开零知星球APP,找到如下页面:
点击右上角的更多,选择连接方式,若使用WiFi连接,在WiFi设置页面选择TCP服务器,填好端口号,点击连接。
若使用蓝牙连接,请打开蓝牙和定位服务扫描蓝牙
扫描到"ESP32_car"这个蓝牙后点击连接即可。
这里我们使用的操作模式是重力感应模式,选择操作模式为重力感应模式,命令设置无需填写
点击开始进入如下页面。
然后点击下面的开启命令发送,就可用手机重力感应来遥控小车了。
手机头部逐渐抬高,小车会逐渐加速;向左偏,小车就向左转弯,向右偏,即向右转弯;且偏转角度越大,转弯半径越小,完成转弯更快。