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

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

parent f32efecc
...@@ -22,6 +22,8 @@ int pwmPins[3] = {3, 5, 6}; //Номера пинов ШИМ ...@@ -22,6 +22,8 @@ int pwmPins[3] = {3, 5, 6}; //Номера пинов ШИМ
volatile bool pwmState = 0; //Состояние ШИМ volatile bool pwmState = 0; //Состояние ШИМ
volatile uint8_t pwm_modes[3] = {1, 1, 1}; // 0 - всегда выкл, 1 - шим, 2 - всегда вкл volatile uint8_t pwm_modes[3] = {1, 1, 1}; // 0 - всегда выкл, 1 - шим, 2 - всегда вкл
float a;
int tachPins[FAN_COUNT] = {14, 15, 16, 17, 18, 19}; //Номера пинов для считывания оборотов int tachPins[FAN_COUNT] = {14, 15, 16, 17, 18, 19}; //Номера пинов для считывания оборотов
volatile uint16_t tachRevs[FAN_COUNT] = {}; //Обороты (просто сколько насчитано оборотов, а не rpm) volatile uint16_t tachRevs[FAN_COUNT] = {}; //Обороты (просто сколько насчитано оборотов, а не rpm)
...@@ -55,14 +57,15 @@ uint32_t last_check_time = 0; ...@@ -55,14 +57,15 @@ uint32_t last_check_time = 0;
uint32_t lastRpmCheck = 0; uint32_t lastRpmCheck = 0;
uint32_t lastRevTime = 0; uint32_t lastRevTime = 0;
float p = 0; float p[3] = {};
float i = 0; float i[3] = {};
float d = 0; float d[3] = {};
float k_p = 0.3; float k_p = 0.03;
float k_i = 0.0004; float k_i = 0.0002;
float k_d = 160; float k_d = 20;
float i_max = 255;
bool flag = 0; bool flag = 0;
...@@ -184,9 +187,9 @@ void autocontrol()//Автоконтроль температуры ...@@ -184,9 +187,9 @@ void autocontrol()//Автоконтроль температуры
{ {
tempFromPc();//получаем температуру от пк tempFromPc();//получаем температуру от пк
// for(int i = 0; i < 3; i++){ for (int i = 0; i < 3; i++) {
// target_rpms[i] = temps[i]; target_rpms[i] = temps[i];
// } }
} }
...@@ -194,75 +197,66 @@ void autocontrol()//Автоконтроль температуры ...@@ -194,75 +197,66 @@ void autocontrol()//Автоконтроль температуры
void rpm_control() { 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++) { for (int val = 0; val < RPM_VALUES_COUNT - 1; val++) {
tachRpm[fan][val] = tachRpm[fan][val + 1]; tachRpm[fan][val] = tachRpm[fan][val + 1];
} }
tachRpm[fan][RPM_VALUES_COUNT - 1] = (tachRevs[fan] * (60000 / uint32_t(millis() - lastRpmCheck))) / 2; tachRpm[fan][RPM_VALUES_COUNT - 1] = (tachRevs[fan] * (60000 / uint32_t(millis() - lastRpmCheck))) / 2;
tachRevs[fan] = 0; 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; uint32_t avg_rpm = 0;
const int fan = 0;
//вычисление средних rpm из нескольких значений, записанных для фильтра
for (int val = 0; val < RPM_VALUES_COUNT; val++) { 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; 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; if (fabs(i[group] * k_i) >= i_max) {
uint8_t byte_pwmDutyCycle = 0; i[group] = i_max / k_i;
}
d = (target_rpm - int(avg_rpm) - p) / float(millis() - lastRpmCheck);
p = target_rpm - int(avg_rpm);
i = i + p * (millis() - lastRpmCheck);
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) { if (pwmDutyCycle < 0) {
byte_pwmDutyCycle = 1; duty_cycle = 0;
} } else if (pwmDutyCycle > 255) {
else if (pwmDutyCycle >= MAX_PWM_DUTY_CYCLE) { duty_cycle = 255;
byte_pwmDutyCycle = MAX_PWM_DUTY_CYCLE;
} }
else { 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 (duty_cycle < MIN_PWM_DUTY_CYCLE) {
if (temps[i] < MIN_PWM_DUTY_CYCLE) { pwm_modes[group] = 0; //всегда выкл
pwm_modes[i] = 0; //всегда выкл digitalWrite(pwmPins[group], 0);
} }
else if (temps[i] > MAX_PWM_DUTY_CYCLE) { else if (duty_cycle > MAX_PWM_DUTY_CYCLE) {
pwm_modes[i] = 2; //всегда вкл pwm_modes[group] = 2; //всегда вкл
digitalWrite(pwmPins[group], 1);
} }
else { else {
pwm_modes[i] = 1; //шим pwm_modes[group] = 1; //шим
} }
uint8_t duty_cycle = constrain(temps[i], 0, 255); switch (group) {
switch (i) {
case 0: case 0:
OCR1A = duty_cycle; OCR1A = duty_cycle;
break; break;
...@@ -276,6 +270,8 @@ void rpm_control() { ...@@ -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