В данный момент стоит задача поддержания заданного давления с помощью регулятора давления по сигналу с датчика давления, используется Arduino ATmega 324. Загвоздка в том, что я не силён в написании программ и интегральная составляющая ПИД-регулятора у меня не прописана, потому как не могу сообразить как правильно её прописать. Также не уверен, что всё остальное прописано правильно. В данный момент работаю с двумя коэффициентами и вроде всё работает, но для каждого заданного давления нужно подбирать свои коэффициенты, чего быть не должно. Прошу помочь разобраться с правильностью написания программы. Код (C++): #include <Wire.h> int averFact = 10; uint16_t sampleTime = 10; unsigned long endMillis=0; double setPoint = 500; //заданное давление double Input; //давление расчитанное double Input2; //давление расчитанное на предыдущем шаге int pressurePin = A6; //давление полученное с датчика давления float kp=0.25; //коэффициент пропорциональный float kd=0.004; //коэффициент дифференциальный float ki= 0.04; //коэффициент интегральный int pulsePin2 =11; //ШИМ сигнал на регулятор давления void setup() { //Инициализация таймера pinMode(pulsePin2, OUTPUT); TCCR2A=0b10000011; // режим фаст pwm TCCR2B=0b00000100; // 960 Hz OCR2A = 0; } void loop() { Input = analogRead(pressurePin); if (millis()-endMillis>sampleTime){ OCR2A = OCR2A + kp*(setPoint - Input) + ki*(Input2 - Input); //формула ПИД-регулятора } endMillis = millis(); double Input2 = Input; }
У овеяна в ассортименте в районе 4-5 рублей есть пид регуляторы. Законченный вид, приемлемая цена. У китайцев можно и дешевле подобрать.
Progress, А откуда этот код? - Похоже, что это код откуда-то бездумно скопирован. Вы пишете, что интегральная составляющая "не прописана", а в коде она как раз есть. Для давления зачем-то использован тип double, которого в Атмеге вообще нет. Да и не ясно, зачем для переменной давления использовать плавающую точку, если вы читаете его (давление) с analogRead() - который оперирует только целыми. Ну и в формуле похоже ошибка - если я не ошибаюсь, ваша интегральная составляющая работает ПРОТИВ регулятора
Код писал сам, ещё раз уточню, что не силён в написании программ, поэтому и обратился сюда за помощью. Мне получается тип double нужно заменить на float? И если у Вас есть замечания по формуле, то скажите пожалуйста, я приму к сведению и исправлю ошибки.
float нет смысла, вы ж его с analogRead() читаете. Используйте обычное целое - int В формуле, вторая скобка, мне кажется надо операторы местами поменять: ki*(Input - Input2)
А если есть интегральная составляющая и интегральная, то мне нужно прописать дифференциальную. У Вас есть идеи по этому поводу?
Код (C++): if (millis()-endMillis>sampleTime){ // double Input2 = Input; float iMin=-0.2; // Минимальное значение интегратора float iMax=0.2; // Максимальное значение интегратора // Интегральная компонента iSum = iSum+(setPoint - Input); // Накапливаем (суммируем) if(iSum<iMin) iSum = iMin; // Проверяем граничные значение if(iSum>iMax) iSum = iMax; double ui = ki*iSum; OCR2A = OCR2A + kp*(setPoint - Input) + kd*(Input2 - Input) + ui; Была идея прописать вот таким образом