我是靠谱客的博主 贪玩丝袜,最近开发中收集的这篇文章主要介绍arduino环境下用ESP32通过蓝牙串口APP控制舵狗完成动作,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我使用的是Goouuu-ESP32它自带了蓝牙模块所以不用再另外购买
此蓝牙的使用程序可参考https://blog.csdn.net/m0_46139849/article/details/107441056

#include <Arduino.h>
#include <WiFi.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

#define DJ0_PWM 13
#define DJ1_PWM 12
#define DJ2_PWM 14

#define DJ3_PWM 27
#define DJ4_PWM 25
#define DJ5_PWM 26

#define DJ6_PWM 33
#define DJ7_PWM 32
#define DJ8_PWM 21

#define DJ9_PWM 19
#define DJ10_PWM 22
#define DJ11_PWM 23

BluetoothSerial SerialBT;

char BT;

double d0 = 73.3,d3 = 95.3,d6 = 76.8,d9 = 76.8;

double x,z,BD,xB,zB,L1 = 57,L2 = 50,L3 = 61;

double duty0,duty1,duty2,duty3,duty4,duty5,duty6,duty7,duty8,duty9,duty10,duty11;  // 占空比变量

//double dutyCycle0,dutyCycle1,dutyCycle2,dutyCycle3,dutyCycle4,dutyCycle5,dutyCycle6,dutyCycle7,dutyCycle8,dutyCycle9,dutyCycle10,dutyCycle11;  // 设置占空比

double Initial_Alpha0,Initial_Beta0,
       Initial_Alpha1,Initial_Beta1,
       Initial_Alpha2,Initial_Beta2,
       Initial_Alpha3,Initial_Beta3;  //设置角度

int freq = 50;

int freq0 = freq;    // 频率
int channel0 = 0;    // 通道0,共16个通道,0~15
int resolution0 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq1 = freq;    // 频率
int channel1 = 1;    // 通道1,共16个通道,0~15
int resolution1 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq2 = freq;    // 频率
int channel2 = 2;    // 通道0,共16个通道,0~15
int resolution2 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq3 = freq;    // 频率
int channel3 = 3;    // 通道0,共16个通道,0~15
int resolution3 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq4 = freq;    // 频率
int channel4 = 4;    // 通道0,共16个通道,0~15
int resolution4 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq5 = freq;    // 频率
int channel5 = 5;    // 通道0,共16个通道,0~15
int resolution5 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq6 = freq;    // 频率
int channel6 = 6;    // 通道0,共16个通道,0~15
int resolution6 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq7 = freq;    // 频率
int channel7 = 7;    // 通道0,共16个通道,0~15
int resolution7 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq8 = freq;    // 频率
int channel8 = 8;    // 通道0,共16个通道,0~15
int resolution8 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq9 = freq;    // 频率
int channel9 = 9;    // 通道0,共16个通道,0~15
int resolution9 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq10 = freq;    // 频率
int channel10 = 10;    // 通道0,共16个通道,0~15
int resolution10 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

int freq11 = freq;    // 频率
int channel11 = 11;    // 通道0,共16个通道,0~15
int resolution11 = 10;   // 分辨率,取值0~20,duty最大取值为2^resolution-1

struct ForwardKinematics  //建立一个结构体用来存储计算后的角度值
{
  double Alpha;  //角度α
  double Beta;   //角度β
}h;

void Inverse_kinematics(double x,double z)  //逆运动学计算公式
{
  xB = 0;
  zB = 1.732/2*L1;
  if(x<0)
  {
    x = -x;
    BD = sqrt(x*x+(z-zB)*(z-zB));
    h.Alpha = 60+acos((x*x+BD*BD-(z-zB)*(z-zB))/(2*x*BD))*180/PI-acos((L2*L2+BD*BD-L3*L3)/(2*L2*BD))*180/PI;
    h.Beta = acos((L2*L2+L3*L3-BD*BD)/(2*L2*L3))*180/PI;
  }else if(x>0)
  {
    BD = sqrt(x*x+(z-zB)*(z-zB));
    h.Alpha = 60+180-acos((L2*L2+BD*BD-L3*L3)/(2*L2*BD))*180/PI-acos((x*x+BD*BD-(z-zB)*(z-zB))/(2*x*BD))*180/PI;
    h.Beta = acos((L2*L2+L3*L3-BD*BD)/(2*L2*L3))*180/PI;
  }else
  {
    BD = z-zB;
    h.Alpha = 150-acos((L2*L2+BD*BD-L3*L3)/(2*L2*BD))*180/PI;
    h.Beta = acos((L2*L2+L3*L3-BD*BD)/(2*L2*L3))*180/PI;
  }
}

void ledc_Initialization()  //ledc初始化程序
{
  ledcSetup(channel0, freq0, resolution0); // 设置通道0
  ledcSetup(channel1, freq1, resolution1); // 设置通道1
  ledcSetup(channel2, freq2, resolution2); // 设置通道2
  ledcSetup(channel3, freq3, resolution3); // 设置通道3
  ledcSetup(channel4, freq4, resolution4); // 设置通道4
  ledcSetup(channel5, freq5, resolution5); // 设置通道5
  ledcSetup(channel6, freq6, resolution6); // 设置通道6
  ledcSetup(channel7, freq7, resolution7); // 设置通道7
  ledcSetup(channel8, freq8, resolution8); // 设置通道8
  ledcSetup(channel9, freq9, resolution9); // 设置通道9
  ledcSetup(channel10, freq10, resolution10); // 设置通道10
  ledcSetup(channel11, freq11, resolution11); // 设置通道11
  
  ledcAttachPin(DJ0_PWM, channel0);  // 将通道0与引脚13连接
  ledcAttachPin(DJ1_PWM, channel1);  // 将通道1与引脚12连接
  ledcAttachPin(DJ2_PWM, channel2);  // 将通道2与引脚14连接
  ledcAttachPin(DJ3_PWM, channel3);  // 将通道3与引脚27连接
  ledcAttachPin(DJ4_PWM, channel4);  // 将通道4与引脚26连接
  ledcAttachPin(DJ5_PWM, channel5);  // 将通道5与引脚25连接
  ledcAttachPin(DJ6_PWM, channel6);  // 将通道6与引脚33连接
  ledcAttachPin(DJ7_PWM, channel7);  // 将通道7与引脚32连接
  ledcAttachPin(DJ8_PWM, channel8);  // 将通道8与引脚21连接
  ledcAttachPin(DJ9_PWM, channel9);  // 将通道9与引脚19连接
  ledcAttachPin(DJ10_PWM, channel10);  // 将通道10与引脚23连接
  ledcAttachPin(DJ11_PWM, channel11);  // 将通道11与引脚22连接
}


void ledc_dutycycle0()  //比较角度设置占空比
{  
  duty1 = 102.4;  // 设置初始占空比
  duty2 = 76.8;   // 设置初始占空比
  Initial_Alpha0 = 90;  //设置初始角度
  Initial_Beta0 = 90;  //设置初始角度

  if(h.Alpha>Initial_Alpha0)
  {
    duty1=duty1-(h.Alpha-Initial_Alpha0)*0.71;  
  }
  if(h.Alpha<Initial_Alpha0)
  {
    duty1=duty1+(Initial_Alpha0-h.Alpha)*0.71;  
  }
  if(h.Beta>Initial_Beta0)
  {
    duty2=duty2+(h.Beta-Initial_Beta0)*0.71;  
  }
  if(h.Beta<Initial_Beta0)
  {
    duty2=duty2-(Initial_Beta0-h.Beta)*0.71;  
  }
}

void ledc_dutycycle1()  //比较角度设置占空比
{  
  duty4 = 83.9;  // 设置初始占空比
  duty5 = 73.3;   // 设置初始占空比
  Initial_Alpha1 = 90;  //设置初始角度
  Initial_Beta1 = 90;  //设置初始角度

  if(h.Alpha>Initial_Alpha1)
  {
    duty4=duty4+(h.Alpha-Initial_Alpha1)*0.71;  
  }
  if(h.Alpha<Initial_Alpha1)
  {
    duty4=duty4-(Initial_Alpha1-h.Alpha)*0.71;  
  }
  if(h.Beta>Initial_Beta1)
  {
    duty5=duty5-(h.Beta-Initial_Beta1)*0.71;  
  }
  if(h.Beta<Initial_Beta1)
  {
    duty5=duty5+(Initial_Beta1-h.Beta)*0.71;  
  }
}

void ledc_dutycycle2()  //比较角度设置占空比
{  
  duty7 = 66.13;  // 设置占空比
  duty8 = 76.8;  // 设置占空比
  Initial_Alpha2 = 90;  //设置初始角度
  Initial_Beta2 = 90;  //设置初始角度

  if(h.Alpha>Initial_Alpha2)
  {
    duty7=duty7-(h.Alpha-Initial_Alpha2)*0.71;  
  }
  if(h.Alpha<Initial_Alpha2)
  {
    duty7=duty7+(Initial_Alpha2-h.Alpha)*0.71;  
  }
  if(h.Beta>Initial_Beta2)
  {
    duty8=duty8+(h.Beta-Initial_Beta2)*0.71;  
  }
  if(h.Beta<Initial_Beta2)
  {
    duty8=duty8-(Initial_Beta2-h.Beta)*0.71;  
  }
}

void ledc_dutycycle3()  //比较角度设置占空比
{  
  duty10 = 76.8;  // 设置占空比
  duty11 = 76.8;  // 设置占空比
  Initial_Alpha3 = 90;  //设置初始角度
  Initial_Beta3 = 90;  //设置初始角度

  if(h.Alpha>Initial_Alpha3)
  {
    duty10=duty10+(h.Alpha-Initial_Alpha3)*0.71;  
  }
  if(h.Alpha<Initial_Alpha3)
  {
    duty10=duty10-(Initial_Alpha3-h.Alpha)*0.71;  
  }
  if(h.Beta>Initial_Beta3)
  {
    duty11=duty11-(h.Beta-Initial_Beta3)*0.71;  
  }
  if(h.Beta<Initial_Beta3)
  {
    duty11=duty11+(Initial_Beta3-h.Beta)*0.71;  
  }
}

void Write()
{
  //左前自上而下
  ledcWrite(channel0, d0);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel1, duty1);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel2, duty2);  // 输出PWM,dutyCycle为占空比
  //右前
  ledcWrite(channel3, d3);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel4, duty4);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel5, duty5);  // 输出PWM,dutyCycle为占空比
  //左后
  ledcWrite(channel6, d6);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel7, duty7);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel8, duty8);  // 输出PWM,dutyCycle为占空比
  //右后
  ledcWrite(channel9, d9);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel10, duty10);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel11, duty11);  // 输出PWM,dutyCycle为占空比
  delay(5);
  if (SerialBT.available())   //每执行一个动作都检测一次蓝牙串口是否接收到信息
  {
    BT = SerialBT.read();
  }
}

void duty_Initialization()  //动作初始化
{
  //左前腿
  ledcWrite(channel0, 73.3);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel1, 102.4);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel2, 76.8);  // 输出PWM,dutyCycle为占空比
  //右前
  ledcWrite(channel3, 95.3);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel4, 83.9);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel5, 73.3);  // 输出PWM,dutyCycle为占空比
  //左后
  ledcWrite(channel6, 73.2);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel7, 66.1);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel8, 76.8);  // 输出PWM,dutyCycle为占空比
  //右后
  ledcWrite(channel9, 73.2);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel10, 76.8);  // 输出PWM,dutyCycle为占空比
  ledcWrite(channel11, 76.8);  // 输出PWM,dutyCycle为占空比
  delay(5);
}

void setup()
{
  Serial.begin(115200);
  SerialBT.begin("ESP32test"); //设置蓝牙名称
  
  ledc_Initialization();          // ledc初始化程序
}

void loop()
{
  duty_Initialization();
  
  if (SerialBT.available()) 
  {
    BT = SerialBT.read();
  }
  delay(20);
  if(BT=='1')
  {
    forward();   //动作前进
  }
  if(BT=='2')
  {
    backoff();   //动作后退
  }
  if(BT=='3')
  {
    turnleft();  //动作左转
  }
  if(BT=='4')
  {
    turnright(); //动作右转
  }
}

相应的动作函数因为会占到大量篇幅所以程序中已经省略了
由于在执行动作的过程中需要不断检索蓝牙串口是否收到终止信息,所以需要占用一定的资源执行检索程序,很庆幸ESP32的性能足够,不过这里还是建议将检索程序写到定时器中断函数中去。

最后

以上就是贪玩丝袜为你收集整理的arduino环境下用ESP32通过蓝牙串口APP控制舵狗完成动作的全部内容,希望文章能够帮你解决arduino环境下用ESP32通过蓝牙串口APP控制舵狗完成动作所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部