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

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

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