Commit 0e3b10d4 authored by Oleg Nikulin's avatar Oleg Nikulin

Рефактор прошивки

parent 469d3331
...@@ -7,9 +7,12 @@ ...@@ -7,9 +7,12 @@
#define RPM_CHECK_INTERVAL 200 //Интервал подсчета rpm и обнуления tachRevs (мс) #define RPM_CHECK_INTERVAL 200 //Интервал подсчета rpm и обнуления tachRevs (мс)
#define RPM_VALUES_COUNT 5 //Количество значений RPM, которые записываются и усредняются (скользящее среднее) #define RPM_VALUES_COUNT 5 //Количество значений RPM, которые записываются и усредняются (скользящее среднее)
#define MIN_PWM_DUTY_CYCLE 2 //Минимальная скважность ШИМ #define MIN_PWM_DUTY_CYCLE 2 //Минимальная скважность ШИМ
#define MAX_PWM_DUTY_CYCLE 254 //Максимальная скважность ШИМ #define MAX_PWM_DUTY_CYCLE 254 //Максимальная скважность ШИМ
#define DEFAULT_PWM_DUTY_CYCLE MAX_PWM_DUTY_CYCLE //Скважность ШИМ по умолчанию (до подключения к пк) #define OFF_DUTY_CYCLE 0 //Условная скважность, при которой на самом деле вентиялтор выключен
#define ON_DUTY_CYCLE 255 //Условная скважность, при которой на самом деле вентиялтор постоянно включен
#define DEFAULT_PWM_DUTY_CYCLE ON_DUTY_CYCLE //Скважность ШИМ по умолчанию (до подключения к пк)
#define BEEP_INTERVAL 1000 //Интервал пищания во время потери связи или перегрева (мс) #define BEEP_INTERVAL 1000 //Интервал пищания во время потери связи или перегрева (мс)
#define BEEP_STRENGTH 100 //Уровень ШИМ для пищалки. (При 255 не работает, нужно чтобы был именно ШИМ) #define BEEP_STRENGTH 100 //Уровень ШИМ для пищалки. (При 255 не работает, нужно чтобы был именно ШИМ)
...@@ -18,16 +21,22 @@ ...@@ -18,16 +21,22 @@
#define SOUND_PIN 10 //Номер пина пищалки #define SOUND_PIN 10 //Номер пина пищалки
#define LED_PIN 13 //Номер пина светодиода #define LED_PIN 13 //Номер пина светодиода
#define OVERHEAT_TEMP 75 //Температура, при достижении которой включается пищалка #define OVERHEAT_TEMP 75 //Температура, при достижении которой включается пищалка //TODO получать при инициализации
uint16_t *control_a_addr = 0x88; //адрес сравнения А таймера 1
uint16_t *control_b_addr = 0xB3; //адрес сравнения А таймера 2
uint16_t *control_c_addr = 0xB4; //адрес сравнения B таймера 2
uint8_t *control_a_addr = 0x88; //адрес сравнения А таймера 1 enum control_pwm_mode {
uint8_t *control_b_addr = 0xB3; //адрес сравнения А таймера 2 off, //всегда выкл
uint8_t *control_c_addr = 0xB4; //адрес сравнения B таймера 2 pwm, //шим
on //всегда вкл
};
struct control {//Данные о группе управления struct control {//Данные о группе управления
uint8_t pin; //Номер пина uint8_t pin; //Номер пина
volatile uint8_t mode; //Текущий режим работы. 0 - всегда выкл, 1 - шим, 2 - всегда вкл volatile control_pwm_mode mode; //Текущий режим ШИМ
uint8_t &dutyCycle; //Скважность ШИМ uint16_t &dutyCycle; //Скважность ШИМ
int16_t temperature; //Текущая температура int16_t temperature; //Текущая температура
int16_t target_temperature; //Температура, к которой нужно стремиться int16_t target_temperature; //Температура, к которой нужно стремиться
int8_t copy_from; //Копировать скважность с другой группы управления. -1 = не копировать, 0 = с группы A, 1 = с группы B, 2 = с группы C int8_t copy_from; //Копировать скважность с другой группы управления. -1 = не копировать, 0 = с группы A, 1 = с группы B, 2 = с группы C
...@@ -36,7 +45,7 @@ struct control {//Данные о группе управления ...@@ -36,7 +45,7 @@ struct control {//Данные о группе управления
control controls[CONTROL_COUNT] = { control controls[CONTROL_COUNT] = {
{ {
3, 3,
1, control_pwm_mode::off,
*control_a_addr, *control_a_addr,
0, 0,
0, 0,
...@@ -44,7 +53,7 @@ control controls[CONTROL_COUNT] = { ...@@ -44,7 +53,7 @@ control controls[CONTROL_COUNT] = {
}, },
{ {
5, 5,
1, control_pwm_mode::off,
*control_b_addr, *control_b_addr,
0, 0,
0, 0,
...@@ -52,7 +61,7 @@ control controls[CONTROL_COUNT] = { ...@@ -52,7 +61,7 @@ control controls[CONTROL_COUNT] = {
}, },
{ {
6, 6,
1, control_pwm_mode::off,
*control_c_addr, *control_c_addr,
0, 0,
0, 0,
...@@ -65,10 +74,14 @@ control &control_b = controls[1]; ...@@ -65,10 +74,14 @@ control &control_b = controls[1];
control &control_c = controls[2]; control &control_c = controls[2];
enum rpm_sensor_type {
unipolar, //1 сигнал на оборот TODO такие вообще бывают? :)
bipolar //2 сигнала на оборот
};
struct fan { //Данные о вентиляторе struct fan { //Данные о вентиляторе
int pin; //Номер пина тахометра int pin; //Номер пина тахометра
bool type; //Тип датчика. 0 = униполярный, 1 = биполярный rpm_sensor_type type; //Тип датчика оборотов //TODO получать при инициализации
volatile bool state; //Состояние тахометра volatile bool state; //Состояние тахометра
volatile uint16_t revs; //Количество оборотов (просто, не в минуту) volatile uint16_t revs; //Количество оборотов (просто, не в минуту)
uint16_t rpm[RPM_VALUES_COUNT]; //Обороты в минуту uint16_t rpm[RPM_VALUES_COUNT]; //Обороты в минуту
...@@ -77,42 +90,42 @@ struct fan { //Данные о вентиляторе ...@@ -77,42 +90,42 @@ struct fan { //Данные о вентиляторе
fan fans[FAN_COUNT] = { fan fans[FAN_COUNT] = {
{ {
14, 14,
1, rpm_sensor_type::bipolar,
0, 0,
0, 0,
0 0
}, },
{ {
15, 15,
1, rpm_sensor_type::bipolar,
0, 0,
0, 0,
0 0
}, },
{ {
16, 16,
1, rpm_sensor_type::bipolar,
0, 0,
0, 0,
0 0
}, },
{ {
17, 17,
1, rpm_sensor_type::bipolar,
0, 0,
0, 0,
0 0
}, },
{ {
18, 18,
1, rpm_sensor_type::bipolar,
0, 0,
0, 0,
0 0
}, },
{ {
19, 19,
1, rpm_sensor_type::bipolar,
0, 0,
0, 0,
0 0
...@@ -243,9 +256,9 @@ void process_command() { ...@@ -243,9 +256,9 @@ void process_command() {
response_buffer[i*2+1] = shortMSByte(rpm); response_buffer[i*2+1] = shortMSByte(rpm);
response_buffer[i*2+2] = shortLSByte(rpm); response_buffer[i*2+2] = shortLSByte(rpm);
} }
response_buffer[13] = OCR1A; response_buffer[13] = control_a.dutyCycle;
response_buffer[14] = OCR2A; response_buffer[14] = control_b.dutyCycle;
response_buffer[15] = OCR2B; response_buffer[15] = control_c.dutyCycle;
response_length = 16; response_length = 16;
response_length = add_crc(response_buffer, response_length); response_length = add_crc(response_buffer, response_length);
...@@ -276,7 +289,11 @@ void rpm_control() { ...@@ -276,7 +289,11 @@ void rpm_control() {
for (int val = 0; val < RPM_VALUES_COUNT - 1; val++) { for (int val = 0; val < RPM_VALUES_COUNT - 1; val++) {
fans[fan].rpm[val] = fans[fan].rpm[val + 1]; fans[fan].rpm[val] = fans[fan].rpm[val + 1];
} }
fans[fan].rpm[RPM_VALUES_COUNT - 1] = (fans[fan].revs * (60000 / uint32_t(millis() - lastRpmCheck))) / (1 + fans[fan].type);
fans[fan].rpm[RPM_VALUES_COUNT - 1] = fans[fan].revs * (60000 / uint32_t(millis() - lastRpmCheck));
if (fans[fan].type == rpm_sensor_type::bipolar)
fans[fan].rpm[RPM_VALUES_COUNT - 1] /= 2;
fans[fan].revs = 0; fans[fan].revs = 0;
} }
...@@ -284,7 +301,7 @@ void rpm_control() { ...@@ -284,7 +301,7 @@ void rpm_control() {
for (int group = 0; group < 3; group++) {//управление скоростью 3-х групп вентиляторов for (int group = 0; group < 3; group++) {//управление скоростью 3-х групп вентиляторов
if (controls[group].copy_from < 0 || controls[group].copy_from > 2) { if (controls[group].copy_from < 0 || controls[group].copy_from > 2) {
uint8_t duty_cycle = 0; uint8_t duty_cycle = 0;
float pwmDutyCycle = MAX_PWM_DUTY_CYCLE; float pwmDutyCycle = ON_DUTY_CYCLE;
if (pc_respond){ if (pc_respond){
d[group] = (controls[group].temperature - controls[group].target_temperature - p[group]) / float(millis() - lastRpmCheck); d[group] = (controls[group].temperature - controls[group].target_temperature - p[group]) / float(millis() - lastRpmCheck);
...@@ -298,17 +315,7 @@ void rpm_control() { ...@@ -298,17 +315,7 @@ void rpm_control() {
pwmDutyCycle = round(p[group] * k_p + i[group] * k_i + d[group] * k_d); pwmDutyCycle = round(p[group] * k_p + i[group] * k_i + d[group] * k_d);
} }
set_duty_cycle(controls[group], round(pwmDutyCycle));
if (pwmDutyCycle < 0) {
duty_cycle = 0;
} else if (pwmDutyCycle > 255) {
duty_cycle = 255;
}
else {
duty_cycle = pwmDutyCycle;
}
set_duty_cycle(controls[group], duty_cycle);
} }
else { else {
...@@ -323,19 +330,19 @@ void rpm_control() { ...@@ -323,19 +330,19 @@ void rpm_control() {
void set_duty_cycle(control &fanControl, uint16_t duty_cycle) { void set_duty_cycle(control &fanControl, int duty_cycle) {
if (duty_cycle < MIN_PWM_DUTY_CYCLE) { if (duty_cycle < MIN_PWM_DUTY_CYCLE) {
fanControl.mode = 0; //всегда выкл fanControl.mode = control_pwm_mode::off;
digitalWrite(fanControl.pin, 0); digitalWrite(fanControl.pin, 0);
fanControl.dutyCycle = 0; fanControl.dutyCycle = OFF_DUTY_CYCLE;
} }
else if (duty_cycle > MAX_PWM_DUTY_CYCLE) { else if (duty_cycle > MAX_PWM_DUTY_CYCLE) {
fanControl.mode = 2; //всегда вкл fanControl.mode = control_pwm_mode::on; //всегда вкл
digitalWrite(fanControl.pin, 1); digitalWrite(fanControl.pin, 1);
fanControl.dutyCycle = 255; fanControl.dutyCycle = ON_DUTY_CYCLE;
} }
else { else {
fanControl.mode = 1; //шим fanControl.mode = control_pwm_mode::pwm;
fanControl.dutyCycle = duty_cycle; fanControl.dutyCycle = duty_cycle;
} }
} }
......
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