Commit c63a9324 authored by Oleg Nikulin's avatar Oleg Nikulin

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

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