使用PID控制器设计基于Arduino的编码器电机--文章当中的代码更正

https://www.yiboard.com/thread-1575-1-1.html
使用PID控制器设计基于Arduino的编码器电机
如果你看到了上面这篇文章,当你想要运行上面的代码的时,会有一些错误,我没有yiboard的帐号,我不知怎样联系作者,我把改过后的代码放在这里了!

//https://www.yiboard.com/thread-1575-1-1.html

#include <PIDController.h>
/* ENCODER_A and ENCODER_B pins are used to read the encoder 
 * Data from the microcontroller, the data from the encoder
 * comes very fast so these two pins have to be interrupt enabled 
 * pins
*/
#define ENCODER_A 2 
#define ENCODER_B 3
/* the MOTOR_CW and MOTOR_CCW pins are used to drive the H-bridge
 * the H-bridge then drives the motors, These two pins must have to 
 * be PWM enabled, otherwise the code will not work.
*/
#define MOTOR_CW 9
#define MOTOR_CCW 10

/*In this section we have defined the gain values for the 
 * proportional, integral, and derivative controller I have set
 * the gain values with the help of trial and error methods.
*/ 
#define __Kp 60 // Proportional constant
#define __Ki 0 // Integral Constant
#define __Kd 0 // Derivative Constant

volatile long int Encoder_count = 0; // stores the current encoder count
unsigned int integerValue = 0; // stores the incoming serial value. Max value is 65535
char incomingByte; // parses and stores each character one by one
int motor_pwm_value = 255; // after PID computation data is stored in this variable.
PIDController pidcontroller;

void setup() {
  Serial.begin(9600); // Serial for Debugging
  pinMode(ENCODER_A, INPUT); // ENCODER_A as Input
  pinMode(ENCODER_B, INPUT); // ENCODER_B as Input
  pinMode(MOTOR_CW, OUTPUT); // MOTOR_CW as Output
  pinMode(MOTOR_CCW, OUTPUT); // MOTOR_CW as Output
/* attach an interrupt to pin ENCODER_A of the Arduino, and when the pulse is in the RISING edge called the function encoder().
*/
  attachInterrupt(digitalPinToInterrupt(ENCODER_A), encoder, RISING);
  pidcontroller.begin(); // initialize the PID instance
  pidcontroller.tune(__Kp , __Ki , __Kd); // Tune the PID, arguments: kP, kI, kD
  pidcontroller.limit(-255, 255); // Limit the PID output between -255 to 255, this is important to get rid of integral windup!
}

void loop() {
  while (Serial.available() > 0) {
    integerValue = Serial.parseInt(); // stores the integerValue
    incomingByte = Serial.read(); // stores the /n character
    pidcontroller.setpoint(integerValue); // The "goal" the PID controller tries to "reach",
    Serial.println(integerValue); // print the incoming value for debugging
    if (incomingByte == '\n') // if we receive a newline character we will continue in the loop
      continue;
  }
  motor_pwm_value = pidcontroller.compute(Encoder_count);  //Let the PID compute the value, returns the calculated optimal output
  Serial.print(motor_pwm_value); // print the calculated value for debugging
  Serial.print("   ");
  if (motor_pwm_value > 0) // if the motor_pwm_value is greater than zero we rotate the  motor in clockwise direction
    motor_ccw(motor_pwm_value);
  else // else, we move it in a counter-clockwise direction
    motor_cw(abs(motor_pwm_value));
  Serial.println(Encoder_count);// print the final encoder count.
}

void encoder() {
  if (digitalRead(ENCODER_B) == HIGH) // if ENCODER_B is high increase the count
    Encoder_count++; // increment the count
  else // else decrease the count
    Encoder_count--; // decrement the count
}

void motor_cw(int power) {
  if (power > 100) {
    analogWrite(MOTOR_CW, power);
    digitalWrite(MOTOR_CCW, LOW);
  }
// both of the pins are set to low
  else {
    digitalWrite(MOTOR_CW, LOW);
    digitalWrite(MOTOR_CCW, LOW);
  }
}

void motor_ccw(int power) {
  if (power > 100) {
    analogWrite(MOTOR_CCW, power);
    digitalWrite(MOTOR_CW, LOW);
  }
  else {
    digitalWrite(MOTOR_CW, LOW);
    digitalWrite(MOTOR_CCW, LOW);
  }
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!要使用Arduino控制JGB37-520编码器电机,您需要将编码器连接到Arduino,并使用适当的代码来控制它。以下是一些基本步骤: 1. 确保您有一个JGB37-520编码器电机和一个Arduino板。 2. 连接编码器的电源和地线到Arduino的5V和GND引脚。 3. 将编码器的A相和B相输出连接到Arduino的两个数字引脚。可以选择任何可用的数字引脚,但最好选择支持外部中断的引脚。 4. 在Arduino上编写代码来读取编码器的输出并控制电机。 以下是一个示例代码,可以用作起点: ```arduino // 定义编码器的引脚 const int encoderPinA = 2; // A相 const int encoderPinB = 3; // B相 // 定义电机驱动引脚 const int motorPin1 = 4; // 电机控制引脚1 const int motorPin2 = 5; // 电机控制引脚2 // 定义编码器计数值和方向 volatile long encoderCount = 0; volatile int encoderDirection = 0; void setup() { // 配置引脚模式 pinMode(encoderPinA, INPUT_PULLUP); pinMode(encoderPinB, INPUT_PULLUP); pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); // 配置编码器中断 attachInterrupt(digitalPinToInterrupt(encoderPinA), updateEncoder, CHANGE); } void loop() { // 在这里实现您的控制逻辑 // 例如,可以根据编码器计数值来控制电机的转动方向和速度 // 注意:在这个示例中,我只是简单地改变电机的方向,您可能需要根据实际需求进行更复杂的控制 if (encoderDirection == 1) { // 顺时针方向 digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, LOW); } else if (encoderDirection == -1) { // 逆时针方向 digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, HIGH); } else { // 停止 digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, LOW); } } // 编码器中断处理函数 void updateEncoder() { // 读取A相和B相的状态 int encoderStateA = digitalRead(encoderPinA); int encoderStateB = digitalRead(encoderPinB); // 根据状态改变计数值和方向 if (encoderStateA == encoderStateB) { encoderDirection = -1; } else { encoderDirection = 1; } encoderCount += encoderDirection; } ``` 这只是一个简单的示例代码,您可以根据您的需求对其进行修改和调整。请确保仔细阅读JGB37-520编码器电机的规格和连接方式,并根据需要进行相应的调整。 希望这可以帮助到您!如有任何问题,请随时提问。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值