Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
H
hddtempserial
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Oleg Nikulin
hddtempserial
Commits
750c1fd4
Commit
750c1fd4
authored
Nov 24, 2021
by
Oleg Nikulin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
В прошивке добавлены структуры вентиляторов и групп управления
parent
922852f7
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
141 additions
and
90 deletions
+141
-90
hddtempserial_rpm.ino
hddtempserial_rpm/hddtempserial_rpm.ino
+141
-90
No files found.
hddtempserial_rpm/hddtempserial_rpm.ino
View file @
750c1fd4
#include <Wire.h>
#define FAN_COUNT 6 //Количество вентиляторов
#define CONTROL_COUNT 3 //Количество групп управления
#define BAUDRATE 19200 //Скорость serial порта
#define CHECK_TEMP_DELAY 200 //Интервал получения температуры от пк (мс)
#define GET_TEMP_TIMEOUT 1000 //Если в течение этого времени температура не была прислана, считается что пк не отвечает (мс)
...
...
@@ -18,44 +19,107 @@
#define SOUND_PIN 10 //Номер пина пищалки
#define LED_PIN 13 //Номер пина светодиода
int
pwmPins
[
3
]
=
{
3
,
5
,
6
};
//Номера пинов ШИМ
volatile
bool
pwmState
=
0
;
//Состояние ШИМ
volatile
uint8_t
pwm_modes
[
3
]
=
{
1
,
1
,
1
};
// 0 - всегда выкл, 1 - шим, 2 - всегда вкл
float
a
;
int
tachPins
[
FAN_COUNT
]
=
{
14
,
15
,
16
,
17
,
18
,
19
};
//Номера пинов для считывания оборотов
volatile
uint16_t
tachRevs
[
FAN_COUNT
]
=
{};
//Обороты (просто сколько насчитано оборотов, а не rpm)
uint16_t
tachRpm
[
FAN_COUNT
][
RPM_VALUES_COUNT
]
=
{};
//rpm
volatile
bool
tachStates
[
FAN_COUNT
]
=
{};
//Состояния (оборот считывается только если состояние == 0, и считывается 0)
uint8_t
*
control_a_addr
=
0x88
;
//адрес сравнения А таймера 1
uint8_t
*
control_b_addr
=
0xB3
;
//адрес сравнения А таймера 2
uint8_t
*
control_c_addr
=
0xB4
;
//адрес сравнения B таймера 2
struct
control
{
//Данные о группе управления
uint8_t
pin
;
//Номер пина
volatile
uint8_t
mode
;
//Текущий режим работы. 0 - всегда выкл, 1 - шим, 2 - всегда вкл
uint8_t
&
dutyCycle
;
//Скважность ШИМ
};
control
controls
[
CONTROL_COUNT
]
=
{
{
3
,
1
,
*
control_a_addr
},
{
5
,
1
,
*
control_b_addr
},
{
6
,
1
,
*
control_c_addr
}
};
control
&
control_a
=
controls
[
0
];
control
&
control_b
=
controls
[
1
];
control
&
control_c
=
controls
[
2
];
struct
fan
{
//Данные о вентиляторе
int
pin
;
//Номер пина тахометра
bool
type
;
//Тип датчика. 0 = униполярный, 1 = биполярный
volatile
bool
state
;
//Состояние тахометра
volatile
uint16_t
revs
;
//Количество оборотов (просто, не в минуту)
uint16_t
rpm
[
RPM_VALUES_COUNT
];
//Обороты в минуту
};
fan
fans
[
FAN_COUNT
]
=
{
{
14
,
1
,
0
,
0
,
0
},
{
15
,
1
,
0
,
0
,
0
},
{
16
,
1
,
0
,
0
,
0
},
{
17
,
1
,
0
,
0
,
0
},
{
18
,
1
,
0
,
0
,
0
},
{
19
,
2
,
0
,
0
,
0
}
};
/*
struct fan { //Данные о вентиляторе
int tachPin; //Номер пина тахометра
bool tachState; //Состояние тахометра
bool tachType; //Тип датчика. 0 = униполярный, 1 = биполярный
uint16_t revs; //Количество оборотв (просто, не в минуту)
uint16_t rpm; //Обороты в минуту
uint32_t lastSignalStart; //Время начала последнего сигнала тахометра
uint32_t lastSignalEnd; //Время окончания последнего сигнала тахометра
};
fan
&
fan_1
=
fans
[
0
];
fan
&
fan_2
=
fans
[
1
];
fan
&
fan_3
=
fans
[
2
];
fan
&
fan_4
=
fans
[
3
];
fan
&
fan_5
=
fans
[
4
];
fan
&
fan_6
=
fans
[
5
];
struct control { //Данные о контроллерах вентилятора
int pwmPin; //Номер пина ШИМ
bool pwmState; //Состояние пина ШИМ
};
*/
int
temps
[
3
]
=
{};
//Температуры, полученные от пк
int
target_rpms
[
3
]
=
{};
int
target_rpms
[
3
]
=
{};
//Обороты, которые нужно держать (в этой прошивке target_rpms и temps это одно и то же)
uint32_t
last_beep_time
=
0
;
uint32_t
last_check_time
=
0
;
uint32_t
lastRpmCheck
=
0
;
uint32_t
lastRevTime
=
0
;
float
p
[
3
]
=
{};
float
i
[
3
]
=
{};
...
...
@@ -110,7 +174,7 @@ void tempFromPc()// получаем температуру от пк
uint32_t
avg_rpm
=
0
;
for
(
int
val
=
0
;
val
<
RPM_VALUES_COUNT
;
val
++
)
{
avg_rpm
+=
tachRpm
[
fan
]
[
val
];
avg_rpm
+=
fans
[
fan
].
rpm
[
val
];
}
avg_rpm
/=
RPM_VALUES_COUNT
;
...
...
@@ -125,8 +189,8 @@ void tempFromPc()// получаем температуру от пк
while
(
Serial
.
available
()
==
0
)
{
//ждем пока ответит
if
(
millis
()
>=
query_time
+
GET_TEMP_TIMEOUT
)
{
//если слишком долго не отвечает
//Венитялторы на максимум
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
OCR2B
=
254
;
for
(
int
i
=
0
;
i
<
CONTROL_COUNT
;
i
++
)
{
controls
[
i
].
dutyCycle
=
MAX_PWM_DUTY_CYCLE
;
//установка скважности по умолчанию
}
wait_for_connection
(
true
);
//снова ждем подключения
break
;
...
...
@@ -199,22 +263,23 @@ void rpm_control() {
for
(
int
fan
=
0
;
fan
<
FAN_COUNT
;
fan
++
)
{
//подсчет об/мин, обнуление насчитанных оборотов
for
(
int
val
=
0
;
val
<
RPM_VALUES_COUNT
-
1
;
val
++
)
{
tachRpm
[
fan
][
val
]
=
tachRpm
[
fan
]
[
val
+
1
];
fans
[
fan
].
rpm
[
val
]
=
fans
[
fan
].
rpm
[
val
+
1
];
}
tachRpm
[
fan
][
RPM_VALUES_COUNT
-
1
]
=
(
tachRevs
[
fan
]
*
(
60000
/
uint32_t
(
millis
()
-
lastRpmCheck
)))
/
2
;
tachRevs
[
fan
]
=
0
;
fans
[
fan
].
rpm
[
RPM_VALUES_COUNT
-
1
]
=
(
fans
[
fan
].
revs
*
(
60000
/
uint32_t
(
millis
()
-
lastRpmCheck
)))
/
(
1
+
fans
[
fan
].
type
)
;
fans
[
fan
].
revs
=
0
;
}
for
(
int
group
=
0
;
group
<
3
;
group
++
)
{
//PID управление скоростью 3-х групп вентиляторов
uint8_t
duty_cycle
=
0
;
/*
uint8_t duty_cycle = 0;
if
(
target_rpms
[
group
]
>
0
)
{
if (target_rpms[group] > 0) {
uint32_t avg_rpm = 0;
//вычисление средних rpm из нескольких значений, записанных для фильтра
for (int val = 0; val < RPM_VALUES_COUNT; val++) {
avg_rpm
+=
tachRpm
[
group
*
2
]
[
val
];
avg_rpm +=
fans[group * 2].rpm
[val];
}
avg_rpm /= RPM_VALUES_COUNT;
...
...
@@ -237,36 +302,27 @@ void rpm_control() {
duty_cycle = pwmDutyCycle;
}
}
else
{
duty_cycle
=
0
;
}
}
else {
duty_cycle = 0;
}
*/
uint8_t
duty_cycle
=
target_rpms
[
group
];
if
(
duty_cycle
<
MIN_PWM_DUTY_CYCLE
)
{
pwm_modes
[
group
]
=
0
;
//всегда выкл
digitalWrite
(
pwmPins
[
group
]
,
0
);
controls
[
group
].
mode
=
0
;
//всегда выкл
digitalWrite
(
controls
[
group
].
pin
,
0
);
}
else
if
(
duty_cycle
>
MAX_PWM_DUTY_CYCLE
)
{
pwm_modes
[
group
]
=
2
;
//всегда вкл
digitalWrite
(
pwmPins
[
group
]
,
1
);
controls
[
group
].
mode
=
2
;
//всегда вкл
digitalWrite
(
controls
[
group
].
pin
,
1
);
}
else
{
pwm_modes
[
group
]
=
1
;
//шим
controls
[
group
].
mode
=
1
;
//шим
}
switch
(
group
)
{
case
0
:
OCR1A
=
duty_cycle
;
break
;
case
1
:
OCR2A
=
duty_cycle
;
break
;
case
2
:
OCR2B
=
duty_cycle
;
break
;
}
controls
[
group
].
dutyCycle
=
duty_cycle
;
}
...
...
@@ -279,23 +335,20 @@ void rpm_control() {
ISR
(
TIMER1_COMPA_vect
)
{
//Функция, вызываемая при прерывании 1A
// digitalWrite(3, 0);
if
(
pwm_modes
[
0
]
<
2
)
{
//если не всегда вкл
if
(
control_a
.
mode
<
2
)
{
//если не всегда вкл
PORTD
&=
0
b1110111
;
//выкл питание на пине 3
}
}
ISR
(
TIMER2_COMPA_vect
)
{
//Функция, вызываемая при прерывании 2A
// digitalWrite(5, 0);
if
(
pwm_modes
[
0
]
<
2
)
{
//если не всегда вкл
if
(
control_b
.
mode
<
2
)
{
//если не всегда вкл
PORTD
&=
0
b11011111
;
//выкл питание на пине 5
}
}
ISR
(
TIMER2_COMPB_vect
)
{
//Функция, вызываемая при прерывании 2B
// digitalWrite(6, 0);
if
(
pwm_modes
[
0
]
<
2
)
{
//если не всегда вкл
if
(
control_c
.
mode
<
2
)
{
//если не всегда вкл
PORTD
&=
0
b10111111
;
//выкл питание на пине 6
}
}
...
...
@@ -303,20 +356,19 @@ ISR(TIMER2_COMPB_vect) { //Функция, вызываемая при прер
ISR
(
TIMER1_OVF_vect
)
{
//Функция, вызываемая при переполнении таймера 1
int
i
=
0
;
if
(
pwm_modes
[
i
]
>
0
)
{
//если режим шим или всегда вкл
digitalWrite
(
pwmPins
[
i
],
1
);
if
(
control_a
.
mode
>
0
)
{
//если режим шим или всегда вкл
digitalWrite
(
control_a
.
pin
,
1
);
}
delayMicroseconds
(
15
);
for
(
int
i
=
0
;
i
<
2
;
i
++
)
{
//проверка тахометров 0-1
if
(
digitalRead
(
tachPins
[
i
])
==
0
&&
tachStates
[
i
]
==
0
)
{
//сигнал тахометра появился
tachStates
[
i
]
=
1
;
if
(
digitalRead
(
fans
[
i
].
pin
)
==
0
&&
fans
[
i
].
state
==
0
)
{
//сигнал тахометра появился
fans
[
i
].
state
=
1
;
//digitalWrite(13, 1);
}
else
if
(
digitalRead
(
tachPins
[
i
])
==
1
&&
tachStates
[
i
]
==
1
)
{
//сигнал тахометра пропал
else
if
(
digitalRead
(
fans
[
i
].
pin
)
==
1
&&
fans
[
i
].
state
==
1
)
{
//сигнал тахометра пропал
//digitalWrite(13, 0);
tachStates
[
i
]
=
0
;
tachRevs
[
i
]
++
;
//засчитывается оборот
fans
[
i
].
state
=
0
;
fans
[
i
].
revs
++
;
//засчитывается оборот
}
}
}
...
...
@@ -324,22 +376,22 @@ ISR(TIMER1_OVF_vect) { //Функция, вызываемая при переп
ISR
(
TIMER2_OVF_vect
)
{
//Функция, вызываемая при переполнении таймера 2
if
(
pwm_modes
[
1
]
>
0
)
{
//если режим шим или всегда вкл
if
(
control_b
.
mode
>
0
)
{
//если режим шим или всегда вкл
PORTD
|=
0
b00100000
;
//вкл питание на пине 5
}
if
(
pwm_modes
[
2
]
>
0
)
{
//если режим шим или всегда вкл
if
(
control_c
.
mode
>
0
)
{
//если режим шим или всегда вкл
PORTD
|=
0
b01000000
;
//вкл питание на пине 6
}
//delayMicroseconds(10);
for
(
int
i
=
2
;
i
<
6
;
i
++
)
{
//проверка тахометров 2-5
if
(
digitalRead
(
tachPins
[
i
])
==
0
&&
tachStates
[
i
]
==
0
)
{
//сигнал тахометра появился
tachStates
[
i
]
=
1
;
if
(
digitalRead
(
fans
[
i
].
pin
)
==
0
&&
fans
[
i
].
state
==
0
)
{
//сигнал тахометра появился
fans
[
i
].
state
=
1
;
//digitalWrite(13, 1);
}
else
if
(
digitalRead
(
tachPins
[
i
])
==
1
&&
tachStates
[
i
]
==
1
)
{
//сигнал тахометра пропал
else
if
(
digitalRead
(
fans
[
i
].
pin
)
==
1
&&
fans
[
i
].
state
==
1
)
{
//сигнал тахометра пропал
//digitalWrite(13, 0);
tachStates
[
i
]
=
0
;
tachRevs
[
i
]
++
;
//засчитывается оборот
fans
[
i
].
state
=
0
;
fans
[
i
].
revs
++
;
//засчитывается оборот
}
}
...
...
@@ -361,12 +413,12 @@ void setup() {
pinMode
(
LED_PIN
,
OUTPUT
);
pinMode
(
SOUND_PIN
,
OUTPUT
);
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
pinMode
(
pwmPins
[
i
]
,
OUTPUT
);
for
(
int
i
=
0
;
i
<
CONTROL_COUNT
;
i
++
)
{
pinMode
(
controls
[
i
].
pin
,
OUTPUT
);
}
for
(
int
i
=
0
;
i
<
FAN_COUNT
;
i
++
)
{
pinMode
(
tachPins
[
i
]
,
INPUT_PULLUP
);
pinMode
(
fans
[
i
].
pin
,
INPUT_PULLUP
);
}
//таймер 1 сравнение A - пин 3
...
...
@@ -391,10 +443,9 @@ void setup() {
TIMSK2
|=
(
1
<<
OCIE2B
);
//вкл. вызов прерывания таймера 2 по сравнению B
TIMSK2
|=
(
1
<<
TOIE2
);
//вкл. вызов прерывания при переполнении таймера 2
OCR1A
=
DEFAULT_PWM_DUTY_CYCLE
;
//Значение для сравнения 1A (скважность ШИМ пина 3)
OCR2A
=
DEFAULT_PWM_DUTY_CYCLE
;
//Значение для сравнения 2A (скважность ШИМ пина 5)
OCR2B
=
DEFAULT_PWM_DUTY_CYCLE
;
//Значение для сравнения 2B (скважность ШИМ пина 6)
for
(
int
i
=
0
;
i
<
CONTROL_COUNT
;
i
++
)
{
controls
[
i
].
dutyCycle
=
DEFAULT_PWM_DUTY_CYCLE
;
//установка скважности по умолчанию
}
Serial
.
begin
(
BAUDRATE
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment