Commit 922852f7 authored by Oleg Nikulin's avatar Oleg Nikulin

Теперь задается не скважность ШИМ, а частота вращения вентилятора, которая поддерживается через PID

parent f32efecc
......@@ -22,6 +22,8 @@ int pwmPins[3] = {3, 5, 6}; //Номера пинов ШИМ
volatile bool pwmState = 0; //Состояние ШИМ
volatile uint8_t pwm_modes[3] = {1, 1, 1}; // 0 - всегда выкл, 1 - шим, 2 - всегда вкл
float a;
int tachPins[FAN_COUNT] = {14, 15, 16, 17, 18, 19}; //Номера пинов для считывания оборотов
volatile uint16_t tachRevs[FAN_COUNT] = {}; //Обороты (просто сколько насчитано оборотов, а не rpm)
......@@ -55,14 +57,15 @@ uint32_t last_check_time = 0;
uint32_t lastRpmCheck = 0;
uint32_t lastRevTime = 0;
float p = 0;
float i = 0;
float d = 0;
float p[3] = {};
float i[3] = {};
float d[3] = {};
float k_p = 0.3;
float k_i = 0.0004;
float k_d = 160;
float k_p = 0.03;
float k_i = 0.0002;
float k_d = 20;
float i_max = 255;
bool flag = 0;
......@@ -184,9 +187,9 @@ void autocontrol()//Автоконтроль температуры
{
tempFromPc();//получаем температуру от пк
// for(int i = 0; i < 3; i++){
// target_rpms[i] = temps[i];
// }
for (int i = 0; i < 3; i++) {
target_rpms[i] = temps[i];
}
}
......@@ -194,75 +197,66 @@ void autocontrol()//Автоконтроль температуры
void rpm_control() {
for (int fan = 0; fan < FAN_COUNT; fan++) {
for (int fan = 0; fan < FAN_COUNT; fan++) { //подсчет об/мин, обнуление насчитанных оборотов
for (int val = 0; val < RPM_VALUES_COUNT - 1; val++) {
tachRpm[fan][val] = tachRpm[fan][val + 1];
}
tachRpm[fan][RPM_VALUES_COUNT - 1] = (tachRevs[fan] * (60000 / uint32_t(millis() - lastRpmCheck))) / 2;
tachRevs[fan] = 0;
}
/*
for (int group = 0; group < 3; group++) { //PID управление скоростью 3-х групп вентиляторов
uint8_t duty_cycle = 0;
if (target_rpms[group] > 0) {
uint32_t avg_rpm = 0;
const int fan = 0;
//вычисление средних rpm из нескольких значений, записанных для фильтра
for (int val = 0; val < RPM_VALUES_COUNT; val++) {
avg_rpm += tachRpm[fan][val];
avg_rpm += tachRpm[group * 2][val];
}
avg_rpm /= RPM_VALUES_COUNT;
d[group] = (target_rpms[group] - int(avg_rpm) - p[group]) / float(millis() - lastRpmCheck);
p[group] = target_rpms[group] - int(avg_rpm);
i[group] = i[group] + p[group] * (millis() - lastRpmCheck);
float pwmDutyCycle = 0;
uint8_t byte_pwmDutyCycle = 0;
d = (target_rpm - int(avg_rpm) - p) / float(millis() - lastRpmCheck);
p = target_rpm - int(avg_rpm);
i = i + p * (millis() - lastRpmCheck);
if (fabs(i[group] * k_i) >= i_max) {
i[group] = i_max / k_i;
}
pwmDutyCycle = round(p * k_p + i * k_i + d * k_d);
float pwmDutyCycle = round(p[group] * k_p + i[group] * k_i + d[group] * k_d);
if (pwmDutyCycle <= 1) {
byte_pwmDutyCycle = 1;
}
else if (pwmDutyCycle >= MAX_PWM_DUTY_CYCLE) {
byte_pwmDutyCycle = MAX_PWM_DUTY_CYCLE;
if (pwmDutyCycle < 0) {
duty_cycle = 0;
} else if (pwmDutyCycle > 255) {
duty_cycle = 255;
}
else {
byte_pwmDutyCycle = pwmDutyCycle;
duty_cycle = pwmDutyCycle;
}
byte_pwmDutyCycle = 255 - byte_pwmDutyCycle;
}
else {
duty_cycle = 0;
}
if (byte_pwmDutyCycle == 0) {
if (pwm_on == 1) {
pwm_on = 0; //выкл ШИМ
for (int i = 0; i < 3; i++) {//выкл пины ШИМ
digitalWrite(pwmPins[i], 0);
}
}
}
else {
if (pwm_on == 0) {
pwm_on = 1; //вкл ШИМ
}
OCR2B = byte_pwmDutyCycle; //установка скважности
}
*/
lastRpmCheck = millis();
for (int i = 0; i < 3; i++) {
if (temps[i] < MIN_PWM_DUTY_CYCLE) {
pwm_modes[i] = 0; //всегда выкл
if (duty_cycle < MIN_PWM_DUTY_CYCLE) {
pwm_modes[group] = 0; //всегда выкл
digitalWrite(pwmPins[group], 0);
}
else if (temps[i] > MAX_PWM_DUTY_CYCLE) {
pwm_modes[i] = 2; //всегда вкл
else if (duty_cycle > MAX_PWM_DUTY_CYCLE) {
pwm_modes[group] = 2; //всегда вкл
digitalWrite(pwmPins[group], 1);
}
else {
pwm_modes[i] = 1; //шим
pwm_modes[group] = 1; //шим
}
uint8_t duty_cycle = constrain(temps[i], 0, 255);
switch (i) {
switch (group) {
case 0:
OCR1A = duty_cycle;
break;
......@@ -276,6 +270,8 @@ void rpm_control() {
}
lastRpmCheck = millis();
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment