一.功能概述
摄像头的画面可以实时的传输到,点灯科技APP的手机端,这样可以实时查看周围环境的状况,灯光不足,画面不清晰时可以打开灯光照明。手机端有左转、右转、前进、后退、停止的按钮。可以根据自己需要,来控制小车。手机APP端还设有模式切换的按钮,可以根据需要进行避障和手动模式的切换。
二、项目模块
小车套件,舵机、esp32-cam、稳压模块、电机驱动模块、超声波模块、开光按钮
三、代码演示
#define BLINKER_WIFI
#include <Blinker.h>
#include "ESP32_CAM_SERVER.h"#define LED 4
#define DriveLeft_A 13 //控制左轮转动方向
#define DriveLeft_B 15
#define DriveRight_A 14 //控制右轮转动方向
#define DriveRight_B 2
#define ServoPin 12 //舵机的引脚
#define Echo 3 //超声波echo
#define Trig 1 //超声波trigconst char* ssid = "nova7"; //wifi账号
const char* password = "66666666"; //wifi密码
char auth[] = "5e3ebc64737f";
int modeflag;
int Wave_len_R;
int Wave_len_L;
bool setup_camera = false;//摄像头默认不开启BlinkerButton Button1("GoForward"); //前进按键
BlinkerButton Button2("GoBack"); //后退按键
BlinkerButton Button3("Left"); //左转按键
BlinkerButton Button4("Right"); //右转按键
BlinkerButton Button5("Stop"); //停车按键
BlinkerButton Button6("led"); //led灯
BlinkerButton Button7("mode"); //模式切换按钮
BlinkerSlider Slider1("duoji"); //舵机滑块//****定义运动函数***********************************//
void Go_Forward( ) // 前进
{digitalWrite(DriveLeft_A, HIGH);digitalWrite(DriveRight_A, HIGH);digitalWrite(DriveLeft_B, LOW); digitalWrite(DriveRight_B, LOW);
}void Go_Back( ) //后退
{ digitalWrite(DriveLeft_A, LOW);digitalWrite(DriveRight_A, LOW); digitalWrite(DriveLeft_B, HIGH);digitalWrite(DriveRight_B, HIGH);
}
void Stop_Car( ) //停止
{digitalWrite(DriveLeft_A, LOW);digitalWrite(DriveLeft_B, LOW);digitalWrite(DriveRight_A, LOW);digitalWrite(DriveRight_B, LOW);
}void Turn_Left( )// 左转
{digitalWrite(DriveLeft_A, LOW);digitalWrite(DriveRight_A, HIGH);//左轮后退digitalWrite(DriveLeft_B, HIGH);//右轮前进digitalWrite(DriveRight_B, LOW);
}void Turn_Right( )// 右转
{digitalWrite(DriveLeft_A, HIGH);//左轮前进digitalWrite(DriveRight_A, LOW);digitalWrite(DriveLeft_B, LOW);digitalWrite(DriveRight_B, HIGH);//右轮后退}//超声波计算距离函数
long getTime()
{digitalWrite(Trig, HIGH);delayMicroseconds(10); //发送10us的高电平 让超声波工作digitalWrite(Trig, LOW);return pulseIn(Echo, HIGH); //返回接收到高电平时的时间
}//舵机的旋转函数
void Myservo(int angle)
{for (int i = 0; i < 5; i++) {int pulsewidth = (angle * 11) + 500; //将角度转化为500-2480的脉宽值digitalWrite(ServoPin, HIGH); //将舵机接口电平至高delayMicroseconds(pulsewidth); //延时脉宽值的微秒数digitalWrite(ServoPin, LOW); //将舵机接口电平至低delayMicroseconds(20000 - pulsewidth); //延时脉宽值的微秒数}delay(10);
}void button1_callback(const String & state) //定义前进按钮
{BLINKER_LOG("get button state: ", state);if (state == "press" || state == "tap") { //判断按键是否被按下Go_Forward(); }else if (state == "pressup") { //判断按键是否松开Stop_Car( );}
}void button2_callback(const String & state) //定义后退按钮
{BLINKER_LOG("get button state: ", state);if (state == "press" || state == "tap") { //判断按键是否按下 或者按下但没有松手Go_Back( );}else if (state == "pressup") {Stop_Car( );}
}void button3_callback(const String & state) //定义左转按钮
{BLINKER_LOG("get button state: ", state);if (state == "press" || state == "tap") {Turn_Left( );delay(100);Stop_Car( );}else if (state == "pressup") {Stop_Car( );}
}void button4_callback(const String & state) //定义右转按钮
{BLINKER_LOG("get button state: ", state);if (state == "press" || state == "tap") {Turn_Right( );delay(100);Stop_Car( );}else if (state == "pressup") {Stop_Car( );}
}void button5_callback(const String & state) //定义停止按钮
{BLINKER_LOG("get button state: ", state);Stop_Car( );
}// 按下LED按键即会执行该函数
void button6_callback(const String & state) //定义LED灯开关按钮
{BLINKER_LOG("get button state: ", state);digitalWrite(LED, !digitalRead(LED));}// // 切换模式的按键
void button7_callback(const String & state)
{BLINKER_LOG("get button state: ", state);if(state=="on"){modeflag = 1;Button7.print("on");Blinker.notify("开启避障模式"); Stop_Car(); }else if(state == "off") {modeflag = 0;Button7.print("off");Blinker.notify("遥控模式");Stop_Car();}Blinker.vibrate(); //手机震动}
//滑动滑块就要执行的函数
void slider1_callback(int32_t value)
{int val = value;Myservo(val); //转动多少度
}//反馈点灯科技平台的状态
void dataRead(const String & data)
{BLINKER_LOG("Blinker readString: ", data);Blinker.vibrate();uint32_t BlinkerTime = millis();Blinker.print("millis", BlinkerTime);
}void setup()
{// //超声波的初始化pinMode(Trig,OUTPUT);pinMode(Echo,INPUT);//led灯的初始化pinMode(LED,OUTPUT);digitalWrite(LED,LOW);pinMode(ServoPin,OUTPUT);Myservo(90); //小车电机引脚设置pinMode(DriveLeft_A, OUTPUT); pinMode(DriveLeft_B, OUTPUT);pinMode(DriveRight_A, OUTPUT);pinMode(DriveRight_B, OUTPUT);// Serial.begin(115200);//esp32-cam的连接到点灯科技平台BLINKER_DEBUG.stream(Serial);//点灯科技串口的debugBlinker.begin(auth,ssid,password);//通过wifi,密钥,密码连接平台Blinker.attachData(dataRead);//反馈点灯科技的状态//**********注册App按钮对应动作函数********************************//Button1.attach(button1_callback);Button2.attach(button2_callback);Button3.attach(button3_callback);Button4.attach(button4_callback);Button5.attach(button5_callback);Button6.attach(button6_callback);//起到关联处理按键控制函数的作用Button7.attach(button7_callback);//模式切换按键的关联Slider1.attach(slider1_callback);//滑块的关联函数
}void loop()
{Blinker.run();//连接点灯科技int Wave_len = 0;if(modeflag == 0){//获取超声波的数据Wave_len = getTime()/58;if((Wave_len > 1) && (Wave_len < 25)){Stop_Car(); //停车digitalWrite(LED,HIGH);//开灯Go_Back(); //后退delay(100);Stop_Car(); //停车digitalWrite(LED,LOW);//关灯}}//避障模式else if(modeflag == 1){Go_Forward();//获取超声波的数据Wave_len = getTime()/58;if((Wave_len > 1) && (Wave_len < 25)){Stop_Car(); //停车digitalWrite(LED,HIGH);//开灯Wave_len = getTime()/58;if(Wave_len >1 && Wave_len <15){digitalWrite(LED,HIGH);//开灯Go_Back(); //后退delay(100);Stop_Car(); //停车digitalWrite(LED,LOW);//关灯}else{Stop_Car();Myservo(135);Wave_len_L = getTime()/58;delay(1000);Myservo(45);Wave_len_R = getTime()/58;delay(1000);Myservo(90);delay(100);if(Wave_len_R >= Wave_len_L)//右边的距离大于左边{do{Turn_Right();delay(100);Wave_len_R = getTime()/58;}while((Wave_len_R > 1) && (Wave_len_R < 25));}else if(Wave_len_R < Wave_len_L){do{Turn_Left();delay(100);Wave_len_L = getTime()/58;}while((Wave_len_L > 1) && (Wave_len_L <25));}}}}if (Blinker.connected() && !setup_camera){setupCamera();setup_camera = true;Blinker.printObject("video", "{\"str\":\"mjpg\",\"url\":\"http://"+ WiFi.localIP().toString() + "\"}");}
}
四、视频演示
视频地址:https://live.csdn.net/v/382534?spm=1001.2014.3001.5501https://live.csdn.net/v/382534?spm=1001.2014.3001.5501