Commit c63a9324 authored by Oleg Nikulin's avatar Oleg Nikulin

Улучшена работа ШИМ по таймеру

parent e4351837
...@@ -46,7 +46,7 @@ volatile bool tachStates[FAN_COUNT] = {}; //Состояния (оборот с ...@@ -46,7 +46,7 @@ volatile bool tachStates[FAN_COUNT] = {}; //Состояния (оборот с
*/ */
int temp; //Температура, полученная от пк int temp; //Температура, полученная от пк
int target_temp = 33; int target_temp = 37;
uint32_t last_beep_time = 0; uint32_t last_beep_time = 0;
uint32_t last_check_time = 0; uint32_t last_check_time = 0;
...@@ -57,10 +57,12 @@ float p = 0; ...@@ -57,10 +57,12 @@ float p = 0;
float i = 0; float i = 0;
float d = 0; float d = 0;
float k_p = 30; float k_p = 40;
float k_i = 0.005; float k_i = 0.005;
float k_d = 0; float k_d = 0;
float i_max = 210;
...@@ -116,13 +118,13 @@ void tempFromPc()// получаем температуру от пк ...@@ -116,13 +118,13 @@ void tempFromPc()// получаем температуру от пк
} }
} }
Serial.println("req_temperature_" + rpm_string + "_debug_" + String(OCR2A)); //запрос к пк Serial.println("req_temperature_" + rpm_string + "_debug_" + String(OCR2B)); //запрос к пк
unsigned long query_time = millis(); unsigned long query_time = millis();
while (Serial.available() == 0) { //ждем пока ответит while (Serial.available() == 0) { //ждем пока ответит
if (millis() >= query_time + GET_TEMP_TIMEOUT) { //если слишком долго не отвечает if (millis() >= query_time + GET_TEMP_TIMEOUT) { //если слишком долго не отвечает
//Венитялторы на максимум //Венитялторы на максимум
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
OCR2A = 254; OCR2B = 254;
} }
wait_for_connection(true);//снова ждем подключения wait_for_connection(true);//снова ждем подключения
break; break;
...@@ -179,8 +181,9 @@ void rpm_control() { ...@@ -179,8 +181,9 @@ void rpm_control() {
d = (temp - target_temp - p) / float(millis() - lastRpmCheck); d = (temp - target_temp - p) / float(millis() - lastRpmCheck);
p = temp - target_temp; p = temp - target_temp;
i = i + p * (millis() - lastRpmCheck); i = i + p * (millis() - lastRpmCheck);
if (fabs(i * k_i) >= MAX_PWM_DUTY_CYCLE){
i = MAX_PWM_DUTY_CYCLE / k_i; if (fabs(i * k_i) >= i_max){
i = i_max / k_i;
} }
...@@ -208,7 +211,7 @@ void rpm_control() { ...@@ -208,7 +211,7 @@ void rpm_control() {
if (pwm_on == 0) { if (pwm_on == 0) {
pwm_on = 1; //вкл ШИМ pwm_on = 1; //вкл ШИМ
} }
OCR2A = byte_pwmDutyCycle; //установка скважности OCR2B = byte_pwmDutyCycle; //установка скважности
} }
//Почему-то иногда может заглючить: скважность стоит 254, pwm_on равно 1, но вентилятор не крутится (но пищит). Похоже каким-то образом меняется pwmState, когда не надо //Почему-то иногда может заглючить: скважность стоит 254, pwm_on равно 1, но вентилятор не крутится (но пищит). Похоже каким-то образом меняется pwmState, когда не надо
//Serial.println("debug_" + String(byte_pwmDutyCycle)); //Serial.println("debug_" + String(byte_pwmDutyCycle));
...@@ -221,36 +224,30 @@ void rpm_control() { ...@@ -221,36 +224,30 @@ void rpm_control() {
ISR(TIMER2_COMPA_vect) { //Эта функия вызывается при прерывании по таймеру 2 ISR(TIMER2_COMPA_vect) { //Функция, вызываемая при прерывании A
for (int i = 0; i < 3; i++) { //Вкл. питание
if (pwmState == 1) { digitalWrite(pwmPins[i], 1);
pwmState = 0;
}
else {
pwmState = 1;
} }
for (int i = 0; i < 3; i++) {//управление пинами ШИМ //Проверка тахометров
digitalWrite(pwmPins[i], pwmState); for (int i = 0; i < FAN_COUNT; i++) {
if (digitalRead(tachPins[i]) == 0 && tachStates[i] == 0) { //сигнал тахометра появился
tachStates[i] = 1;
//digitalWrite(13, 1);
}
else if (digitalRead(tachPins[i]) == 1 && tachStates[i] == 1) { //сигнал тахометра пропал
//digitalWrite(13, 0);
tachStates[i] = 0;
tachRevs[i]++; //засчитывается оборот
}
} }
}
ISR(TIMER2_COMPB_vect) { //Функция, вызываемая при прерывании B
for (int i = 0; i < 3; i++) { //Выкл. питание
if (pwmState == 1) { //Если питание включилось, то проверяем состояния тахометров digitalWrite(pwmPins[i], 0);
for (int i = 0; i < FAN_COUNT; i++) {
if (digitalRead(tachPins[i]) == 0 && tachStates[i] == 0) { //сигнал тахометра появился
tachStates[i] = 1;
//digitalWrite(13, 1);
}
else if (digitalRead(tachPins[i]) == 1 && tachStates[i] == 1) { //сигнал тахометра пропал
//digitalWrite(13, 0);
tachStates[i] = 0;
tachRevs[i]++; //засчитывается оборот
}
}
} }
} }
...@@ -259,7 +256,6 @@ ISR(TIMER2_COMPA_vect) { //Эта функия вызывается при пр ...@@ -259,7 +256,6 @@ ISR(TIMER2_COMPA_vect) { //Эта функия вызывается при пр
void setup() { void setup() {
pinMode(LED_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT);
pinMode(SOUND_PIN, OUTPUT); pinMode(SOUND_PIN, OUTPUT);
...@@ -272,11 +268,14 @@ void setup() { ...@@ -272,11 +268,14 @@ void setup() {
pinMode(tachPins[i], INPUT_PULLUP); pinMode(tachPins[i], INPUT_PULLUP);
} }
//запуск таймера в режиме fast pwm
TCCR2A |= (1 << WGM21);
TCCR2A |= (1 << WGM20);
TCCR2A |= (1 << WGM20); //запуск таймера TIMSK2 |= (1 << OCIE2A); //вкл. вызов прерывания по сравнению A
OCR2A = DEFAULT_PWM_DUTY_CYCLE; //скважность TIMSK2 |= (1 << OCIE2B); //вкл. вызов прерывания по сравнению B
TIMSK2 |= (1 << OCIE2A); //вкл. вызов прерывания
OCR2B = DEFAULT_PWM_DUTY_CYCLE; //Прерывание B происходит, когда значение таймера совпадает с этим. (По сути это скважность ШИМ)
Serial.begin(BAUDRATE); Serial.begin(BAUDRATE);
......
...@@ -115,13 +115,13 @@ void tempFromPc()// получаем температуру от пк ...@@ -115,13 +115,13 @@ void tempFromPc()// получаем температуру от пк
} }
} }
Serial.println("req_temperature_" + rpm_string + "_debug_" + String(OCR2A)); //запрос к пк Serial.println("req_temperature_" + rpm_string + "_debug_" + String(OCR2B)); //запрос к пк
unsigned long query_time = millis(); unsigned long query_time = millis();
while (Serial.available() == 0) { //ждем пока ответит while (Serial.available() == 0) { //ждем пока ответит
if (millis() >= query_time + GET_TEMP_TIMEOUT) { //если слишком долго не отвечает if (millis() >= query_time + GET_TEMP_TIMEOUT) { //если слишком долго не отвечает
//Венитялторы на максимум //Венитялторы на максимум
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
OCR2A = 254; OCR2B = 254;
} }
wait_for_connection(true);//снова ждем подключения wait_for_connection(true);//снова ждем подключения
break; break;
...@@ -193,7 +193,7 @@ void rpm_control() { ...@@ -193,7 +193,7 @@ void rpm_control() {
if (pwm_on == 0) { if (pwm_on == 0) {
pwm_on = 1; //вкл ШИМ pwm_on = 1; //вкл ШИМ
} }
OCR2A = byte_pwmDutyCycle; //установка скважности OCR2B = byte_pwmDutyCycle; //установка скважности
} }
//Почему-то иногда может заглючить: скважность стоит 254, pwm_on равно 1, но вентилятор не крутится (но пищит). Похоже каким-то образом меняется pwmState, когда не надо //Почему-то иногда может заглючить: скважность стоит 254, pwm_on равно 1, но вентилятор не крутится (но пищит). Похоже каким-то образом меняется pwmState, когда не надо
//Serial.println("debug_" + String(byte_pwmDutyCycle)); //Serial.println("debug_" + String(byte_pwmDutyCycle));
...@@ -206,36 +206,30 @@ void rpm_control() { ...@@ -206,36 +206,30 @@ void rpm_control() {
ISR(TIMER2_COMPA_vect) { //Эта функия вызывается при прерывании по таймеру 2 ISR(TIMER2_COMPA_vect) { //Функция, вызываемая при прерывании A
for (int i = 0; i < 3; i++) { //Вкл. питание
if (pwmState == 1) { digitalWrite(pwmPins[i], 1);
pwmState = 0;
}
else {
pwmState = 1;
} }
for (int i = 0; i < 3; i++) {//управление пинами ШИМ //Проверка тахометров
digitalWrite(pwmPins[i], pwmState); for (int i = 0; i < FAN_COUNT; i++) {
if (digitalRead(tachPins[i]) == 0 && tachStates[i] == 0) { //сигнал тахометра появился
tachStates[i] = 1;
//digitalWrite(13, 1);
}
else if (digitalRead(tachPins[i]) == 1 && tachStates[i] == 1) { //сигнал тахометра пропал
//digitalWrite(13, 0);
tachStates[i] = 0;
tachRevs[i]++; //засчитывается оборот
}
} }
}
ISR(TIMER2_COMPB_vect) { //Функция, вызываемая при прерывании B
for (int i = 0; i < 3; i++) { //Выкл. питание
if (pwmState == 1) { //Если питание включилось, то проверяем состояния тахометров digitalWrite(pwmPins[i], 0);
for (int i = 0; i < FAN_COUNT; i++) {
if (digitalRead(tachPins[i]) == 0 && tachStates[i] == 0) { //сигнал тахометра появился
tachStates[i] = 1;
//digitalWrite(13, 1);
}
else if (digitalRead(tachPins[i]) == 1 && tachStates[i] == 1) { //сигнал тахометра пропал
//digitalWrite(13, 0);
tachStates[i] = 0;
tachRevs[i]++; //засчитывается оборот
}
}
} }
} }
...@@ -244,7 +238,6 @@ ISR(TIMER2_COMPA_vect) { //Эта функия вызывается при пр ...@@ -244,7 +238,6 @@ ISR(TIMER2_COMPA_vect) { //Эта функия вызывается при пр
void setup() { void setup() {
pinMode(LED_PIN, OUTPUT); pinMode(LED_PIN, OUTPUT);
pinMode(SOUND_PIN, OUTPUT); pinMode(SOUND_PIN, OUTPUT);
...@@ -257,11 +250,14 @@ void setup() { ...@@ -257,11 +250,14 @@ void setup() {
pinMode(tachPins[i], INPUT_PULLUP); pinMode(tachPins[i], INPUT_PULLUP);
} }
//запуск таймера в режиме fast pwm
TCCR2A |= (1 << WGM21);
TCCR2A |= (1 << WGM20);
TCCR2A |= (1 << WGM20); //запуск таймера TIMSK2 |= (1 << OCIE2A); //вкл. вызов прерывания по сравнению A
OCR2A = DEFAULT_PWM_DUTY_CYCLE; //скважность TIMSK2 |= (1 << OCIE2B); //вкл. вызов прерывания по сравнению B
TIMSK2 |= (1 << OCIE2A); //вкл. вызов прерывания
OCR2B = DEFAULT_PWM_DUTY_CYCLE; //Прерывание B происходит, когда значение таймера совпадает с этим. (По сути это скважность ШИМ)
Serial.begin(BAUDRATE); Serial.begin(BAUDRATE);
......
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