【esp8266实践记录】三、esp8266开发版PID控制SG90舵机


前言

不能只满足于简单地控制舵机,引入略显高端的做法,使用PID方法控制舵机

一、基本思路

舵机使用基础(SG90模拟舵机和MG90S数字舵机为例)

PID算法的特点及原理讲解

老规矩,首先要安装舵机相关的***<Servo.h>***库,不教安装。
先初始化PID结构体,然后传入目标值即可。

要说最难的还是调PID的参数,我是调了差不多一下午。

二、主要代码

PID函数定义,套用忘了从哪来的模板


typedef struct 
{
  float Target_value;  //目标值
  float Current_value;  //当前值
  float PWM;  //PWM
  float Err;  //目前误差
  float Last_Err;  //上一次误差
  float Kp,Ki,Kd;  //比例常数,积分常数,微分常数
  float output;  //PID输出,通常作为控制执行器的变量
  float integral;  //积分值
}PID_TypeDef;

PID_TypeDef PID;  //定义结构体变量

void PID_Init();
float PID_operation(float value);

//初始化PID各项参数
void PID_Init()
{
  PID.Target_value = 0.0;
  PID.Current_value = 0.0;
  PID.PWM = 0.0;
  PID.Err = 0.0;
  PID.Last_Err = 0.0;
  PID.output = 0.0;
  PID.integral = 0.0;
  PID.Kp = 0.4;  
  PID.Ki = 0.03;  
  PID.Kd = 0.2;     //比例常数,积分常数,微分常数的调整非常重要,这里的参数是经过几次试验得出的经验参数
}
//PID操作
float PID_operation(float value)
{
  float index;
  PID.Target_value = value;  //确定目标值
  Serial.println("Target_value:");Serial.print(PID.Target_value);Serial.println();
  PID.Err = PID.Target_value - PID.Current_value;  //计算偏差量
  if (abs(PID.Err)<value*0.01)
    return value;
  Serial.println("Err:");Serial.print(PID.Err);Serial.println();
  
      if (abs(PID.Err) > 100)
    {
        index = 0;
    }
    else
    {
        index = 1;
        PID.integral += PID.Err;  //计算和
    }
  PID.output = PID.Kp*PID.Err + index*PID.Ki*PID.integral + PID.Kd* (PID.Err-PID.Last_Err);  //PID运算


  Serial.println("output:");Serial.print(PID.output);Serial.println();

  PID.Last_Err = PID.Err;  //将当前误差值存入上一误差值
  
  PID.PWM = int(PID.Current_value+PID.output);  //将当前值更新为PID的输出值
  Serial.println("PWM:");Serial.print(PID.PWM);Serial.println();
  //PID.Current_value=int(PID.PWM);
  //Serial.println("Current_value:");Serial.print(PID.Current_value);Serial.println();
  if(PID.PWM>0&&PID.PWM<=180){


    return PID.PWM;  //返回当前值
  }
  else{
    return 0;
  }
}

分割

#include <Servo.h>

Servo myServo;  // 定义Servo对象来控制
int pos = 0,t=0;    // 角度存储变量

//这里放PID函数定义,就上面那些代码


void setup() {
  myServo.attach(D5); //D5   
  Serial.begin(9600);
}

void loop() { 
  PID_Init();
  for (pos = 0; pos <= 90; pos ++) {
  PID.Current_value = myServo.read();

  if(t=PID_operation(1)){
    
      Serial.println("Current_value45:");Serial.print(PID.Current_value);Serial.println();
      Serial.println("t45:");Serial.print(t);Serial.println();

    myServo.write(t);
    delay(15);
  }
  }

  delay(2000);//延时2s 
  PID_Init();
  for (pos = 0; pos <= 90; pos ++) {
    PID.Current_value = myServo.read();

    if(t=PID_operation(135)){
      
            Serial.println("t135:");Serial.print(PID.Current_value);Serial.println();

    myServo.write(t);
    delay(15);
  }
  }
  delay(2000);//延时2s 
  
}

三、结果展示

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

总结

舵机不舵机倒无所谓,主要是想学一下PID控制。这东西后面用处可多了。

在这里插入图片描述

“每一次相聚都将是一场离别的盛宴。”

  • 6
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值