ESP32蓝牙控制三轮小车(非自平衡、带万向辅助轮)

一、在PWM示例程序的基础上,编写moto_control.h  moto_control.cpp。

pwm.h、pwm.cpp 包含两个函数,一个是初始化,一个是设置占空比。这可以直接拿来控制电机用。

#ifndef _pwm_H
#define _pwm_H

#include "public.h"


//函数声明
void pwm_init(u8 pin,u8 chanel,u8 freq,u8 resolution);
void pwm_set_duty(u8 chanel,u16 duty);

#endif
#include "pwm.h"

//PWM初始化
//pin:引脚号
//chanel:PWM输出通道0-15
//freq:PWM输出频率,单位HZ
//resolution:PWM占空比的分辨率1-16,比如设置8,分辨率范围0-255
void pwm_init(u8 pin,u8 chanel,u8 freq,u8 resolution)
{
  ledcSetup(chanel, freq, resolution);// PWM初始化
  ledcAttachPin(pin, chanel);// 绑定PWM通道到GPIO上
}

//PWM占空比设置
void pwm_set_duty(u8 chanel,u16 duty)
{
  ledcWrite(chanel,duty);// 改变PWM的占空比
}

moto_control.h  moto_control.cpp  代码如下:

#ifndef _MOTO_CONTROL_H
#define _MOTO_CONTROL_H

#include "public.h"
#include "pwm.h"

//控制管脚定义
#define MOTO_A1  15
#define MOTO_A2  4
#define MOTO_B1  16
#define MOTO_B2  17

//PWM通道定义
#define PWM0     0
#define PWM1     1
#define PWM2     2
#define PWM3     3

//函数声明
void moto_init(void);

void turn_left(void);
void turn_right(void);
void stop_A(void);
void stop_B(void);
void stop_all(void);

void Forward(void);
void Backward(void);


#endif

#include "moto_control.h"

//led初始化
void moto_init(void)
{
  pinMode(MOTO_A1, OUTPUT);//设置引脚为输出模式
  pinMode(MOTO_A2, OUTPUT);//设置引脚为输出模式
  pinMode(MOTO_B1, OUTPUT);//设置引脚为输出模式
  pinMode(MOTO_B2, OUTPUT);//设置引脚为输出模式
}

void turn_left(void){         //左轮反转、右轮正转
  pwm_set_duty(PWM0,1000);   
  pwm_set_duty(PWM1,0);       //MOTO_A2设为低电平
  pwm_set_duty(PWM2,0);         //MOTO_B1设为低电平
  pwm_set_duty(PWM3,0);         //MOTO_B1设为低电平
  // for(int i=0;i<1000;i+=10){  //调节MOTO_A1占空比    MOTO_A1 MOTO_A2  =  10   电机反转  可变速
  //   pwm_set_duty(PWM0,i);
  //   pwm_set_duty(PWM3,i);
  //   delay(10);
  // }
  
  delay(100);//调节延时,可控制转弯角度
  stop_all();
}

void turn_right(void){        //左轮正转、右轮反转
  pwm_set_duty(PWM0,0);   
  pwm_set_duty(PWM1,0);       //MOTO_A2设为低电平
  pwm_set_duty(PWM2,1000);         //MOTO_B1设为低电平
  pwm_set_duty(PWM3,0);         //MOTO_B1设为低电平
  // for(int i=0;i<1000;i+=10){  //调节MOTO_A2占空比    MOTO_A1 MOTO_A2  =  01   电机正转  可变速
  //   pwm_set_duty(PWM1,i);
  //   pwm_set_duty(PWM2,i);
  //   delay(10);
  // }
  delay(100);//调节延时,可控制转弯角度
  stop_all();
}

void stop_A(void){
  pwm_set_duty(PWM0,0);
  pwm_set_duty(PWM1,0);
}

void stop_B(void){
  pwm_set_duty(PWM2,0);
  pwm_set_duty(PWM3,0);
}

void stop_all(){
  stop_A();
  stop_B();
}

void Forward(void){
  pwm_set_duty(PWM0,0);       //MOTO_A2设为低电平
  pwm_set_duty(PWM2,0);         //MOTO_B1设为低电平
  //MOTO_A1 MOTO_A2 & MOTO_B1  MOTO_B2 =  01   电机正转
  pwm_set_duty(PWM1,750);
  pwm_set_duty(PWM3,750);
  delay(500);
  stop_all();
}
void Backward(void){
  pwm_set_duty(PWM1,0);       //MOTO_A2设为低电平
  pwm_set_duty(PWM3,0);         //MOTO_B1设为低电平
  //MOTO_A1 MOTO_A2 & MOTO_B1  MOTO_B2 =  10   电机反转
  pwm_set_duty(PWM0,750);
  pwm_set_duty(PWM2,750);
  delay(500);
  stop_all();
}

二、测试蓝牙控制led程序,并改写为电机控制的程序。

/* 深圳市普中科技有限公司(PRECHIN 普中)
   技术支持:www.prechin.net
 * 
 * 实验名称:蓝牙实验--控制LED
 * 
 * 接线说明:LED模块-->ESP32 IO
 *          D1-->15
            
 * 
 * 实验现象:程序下载成功后,手机预先安装工程目录下“蓝牙串口调试助手.apk”,打开软件,连接蓝牙名称为“ESP32test”,然后发送字符串“on”和"off"
            开关LED指示灯。
 * 
 * 注意事项:
 */

#include "public.h"
#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif

BluetoothSerial SerialBT;

//定义LED1管脚
#define LED1 15

char buf[9];

void setup() {
  Serial.begin(115200);
  SerialBT.begin("ESP32test"); //Bluetooth device name
  Serial.println("The device started, now you can pair it with bluetooth!");
  //设置LED1引脚为输出模式
  pinMode(LED1, OUTPUT);
}

void loop() {
  if (Serial.available()) {
    SerialBT.write(Serial.read());
  }
  if (SerialBT.available()) {
    // Serial.write(SerialBT.read());
    for(u8 i=0;i<9;i++)
    {
      buf[i]=SerialBT.read();  
      Serial.print(buf[i]); //串口输出蓝牙接收数据   
    }
    if(buf[0]=='o' && buf[1]=='n') 
      digitalWrite(LED1, HIGH);//LED1引脚输出高电平,点亮
    else if(buf[0]=='o' && buf[1]=='f' && buf[2]=='f')
      digitalWrite(LED1, LOW);//LED1引脚输出低电平,熄灭                     
  }
  delay(20);
}

改写后的main.ino如下:

/* 
Gyro.h            陀螺仪
pwm.h             PWM函数
moto_control.h    电机控制
main.ino          主函数
*/

#include "public.h"
#include "moto_control.h"
#include "pwm.h"
#include "Gyro.h"

#include "oled.h"

#include "BluetoothSerial.h"

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error Bluetooth is not enabled! Please run `make menuconfig` to and enable it
#endif

#if !defined(CONFIG_BT_SPP_ENABLED)
#error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
#endif

//定义LED1管脚
#define LED1 15
BluetoothSerial SerialBT;
char buf[9];

// SSD1306Wire *disp;

//定义全局变量
Adafruit_MPU6050 mpu;//定义陀螺仪   在库管理中搜索adafruit mpu6050

/*L9110S二路电机驱动模块: 供电电压2.5-12V  最大工作电流0.8A  尺寸2.8cm*2.1cm   安装孔直径3mm
  本程序中VCC、GND分别接ESP32板VIN、GND
  MOTOA的两个接线端子:    A1-A    A1-B  :  10正转   01反转  本程序中定义为:  MOTO_A1   MOTO_A2
  MOTOB的两个接线端子:    B1-A    B2-A  :  10正转   01反转  本程序中定义为:  MOTO_B1   MOTO_B2
*/

void setup() {
  //PWM初始化
  //pin:引脚号
  //chanel:PWM输出通道0-15
  //freq:PWM输出频率,单位HZ
  //resolution:PWM占空比的分辨率1-16,比如设置8,分辨率范围0-255
  pwm_init(MOTO_A1,PWM0,1000,10);
  pwm_init(MOTO_A2,PWM1,1000,10);
  pwm_init(MOTO_B1,PWM2,1000,10);
  pwm_init(MOTO_B2,PWM3,1000,10);

  Gyro_init();//初始化陀螺仪

  SerialBT.begin("跑跑卡丁车"); //Bluetooth device name
  Serial.println("The device started, now you can pair it with bluetooth!");

  display_setup();

  Serial.println("The device started");
}


void loop() {
  /* 通过读数获取新的传感器事件 */
  sensors_event_t a, g, temp;
  mpu.getEvent(&a, &g, &temp);

  /* 打印出值 */
#if 0
  Serial.print("加速度 X: ");
  Serial.print(a.acceleration.x);
  Serial.print(", Y: ");
  Serial.print(a.acceleration.y);
  Serial.print(", Z: ");
  Serial.print(a.acceleration.z);
  Serial.println(" m/s^2");

  Serial.print("角度 X: ");
  Serial.print(g.gyro.x);
  Serial.print(", Y: ");
  Serial.print(g.gyro.y);

  Serial.print("温度: ");
  Serial.print(temp.temperature);
  Serial.println(" degC");
#endif

  Serial.print(", Z: ");
  // Serial.println(g.gyro.x);
  // SerialBT.write(g.gyro.x);
  // Serial.println(g.gyro.y);
  Serial.println(g.gyro.z);
  //Serial.println(" rad/s");


  if (Serial.available()) {
    SerialBT.write(Serial.read());
  }
  if (SerialBT.available()) {
    // Serial.write(SerialBT.read());
    for(u8 i=0;i<9;i++)
    {
      buf[i]=SerialBT.read();  
      Serial.print(buf[i]); //串口输出蓝牙接收数据   
    }

    if(buf[0]=='o' && buf[1]=='n'){
      digitalWrite(LED1, HIGH);//LED1引脚输出高电平,点亮
      Forward();
    }
    else if(buf[0]=='o' && buf[1]=='f' && buf[2]=='f'){
      digitalWrite(LED1, LOW);//LED1引脚输出低电平,熄灭   
      Backward();   
    }
    else if(buf[0]=='t' && buf[1]=='r')
    {
      digitalWrite(LED1, LOW);//LED1引脚输出低电平,熄灭   
      turn_right();
    }
    else if(buf[0]=='t' && buf[1]=='l')
    {
      digitalWrite(LED1, LOW);//LED1引脚输出低电平,熄灭   
      turn_left();   
    }
    else if(buf[0]=='s' && buf[1]=='t')
    {
      stop_all();
    }
  }

  drawFontFaceDemo();


  // delay(20);

#if 0
  //平衡控制  测试能否站住   尝试二轮平衡,简单控制效果不佳,算法暂时没搞                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        000
  if(g.gyro.z<-0.05){
    Backward();
  }
    // delay(10000);
  if(g.gyro.z>0.05){
    Forward();
  }
  delay(10);
#endif

}

以上代码中包含了oled显示的,直接注释掉即可。

三、总体测试

网上下载了蓝牙串口SSP,选择键盘模式,设置发送五个字符串:off(前进)、on(后退)、tr(turn right)、tl(turn left)、st(stop),可控制小车实现基本的运动。d0cdafc2639b4c328c0afd0e63498dff.jpg

dcf28cb20e8d4cf1a3a8dfe78b495e60.jpg 

 

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值