pid吧 关注:6,200贴子:4,913
  • 1回复贴,共1

【求助】如何将pid输出的每分钟圈数改变值转化成pwm占空比数值

只看楼主收藏回复

【求助】如何将pid输出的每分钟圈数改变值转化成pwm占空比数值
float targetHeight = 150.0;//目标高度为10m
float actualHeight = 0; //实际高度
const float g = 0.98f;
float cumulativeError = 0; //累计误差
float variationError = 0; //上一次误差
const float Kp = 0.4;
const float Ki = 0.05;
const float Kd = 0.04;
int PWM = 0;
const int pulsePin = 4; // 定义要检测脉冲的引脚
volatile int pulseCount = 0; // 用于存储脉冲计数的变量
const int pulsesPerRevolution = 350; // 一圈的脉冲数
hw_timer_t * timer = NULL; // 定义硬件定时器指针
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED; // 定义互斥锁
unsigned long startTime = 0; // 开始测量时间
unsigned long endTime = 0; // 结束测量时间
void setup() {
Serial.begin(115200); // 初始化串口通信
pinMode(pulsePin, INPUT); // 将引脚设置为输入模式
pinMode(5, OUTPUT); // 将引脚设置为输入模式
attachInterrupt(digitalPinToInterrupt(pulsePin), countPulse, RISING); // 附加中断服务例程,检测上升沿
// 初始化硬件定时器
timer = timerBegin(0, 80, true); // 使用定时器0,分频系数为80,开启自动重载
timerAttachInterrupt(timer, &onTimer, true); // 附加定时器中断服务例程
timerAlarmWrite(timer, 1000000, true); // 设置定时器报警时间为1秒(1,000,000微秒)
timerAlarmEnable(timer); // 启用定时器报警
}
void loop() {
//PID();
//delay(100);
}
void PID()
{
float err = targetHeight - actualHeight;//获取当前误差
cumulativeError += err;//累计误差
int PWMA = (Kp *err + Ki *cumulativeError + Kp *(err - variationError))/160*255;
if(PWM+PWMA>=0&&PWM+PWMA<=255);
{
PWM+=PWMA;
}
analogWrite(PWM,5);
Serial.println((String)actualHeight);
variationError = err;//记录本次误差
Serial.println((String)err);
}
// 中断服务例程,当检测到上升沿时调用
void countPulse() {
pulseCount++; // 增加脉冲计数
}
// 定时器中断服务例程
void onTimer() {
hw_timer_t * theTimer = timer; // 获取定时器指针
portENTER_CRITICAL_ISR(&timerMux); // 进入临界区
endTime = micros(); // 记录当前时间
//portEXIT_CRITICAL_ISR(&timerMux); // 退出临界区
noInterrupts(); // 禁用中断,确保读取脉冲计数时不会被打断
int currentPulseCount = pulseCount; // 读取当前脉冲计数
interrupts(); // 重新启用中断
if (currentPulseCount > 0) {
// 计算每分钟转速
actualHeight = (currentPulseCount * 60.0) / pulsesPerRevolution;
/*Serial.print("RPM: ");
Serial.println(actualHeight);*/
} else {
//Serial.println("No pulse detected in the last second.");
}
// 重置脉冲计数
noInterrupts();
pulseCount = 0;
interrupts();
portEXIT_CRITICAL_ISR(&timerMux); // 退出临界区
}


IP属地:俄罗斯1楼2024-12-20 21:01回复
    不知道,但是我觉得你可以试一试能不能通过岭回归得到占空比和转速的关系,或者直接通过系统辨识得到电机的传递函数然后得到响应


    IP属地:重庆2楼2024-12-28 20:04
    回复