//Чтобы при его помощи вручную управлять шимом (это позволит точно знать время его включения, при этом иметь шим нормальной частоты)
//И чтобы чтобы через прерывания чекать тахометры.
//Можно еще попробовать реализовать вариант, когда для измерения оборотв на короткое время на питание подается постоянное напряжение вместо шима, и нужно успеть измерить обороты за это время.
#include <Wire.h>
#define BAUDRATE 57600 //Скорость serial порта
#define FAN_COUNT 6 //Количество вентиляторов
#define BAUDRATE 19200 //Скорость serial порта
#define BEEP_INTERVAL 1000 //Частота пищания во время потери связи или перегрева
#define BEEP_STRENGTH 100 //Уровень шима для пищалки. (При 255 не работает)
#define BLINK_INTERVAL 200 //Частота мигания светодиода во время ожидания ответа от пк
#define CHECK_TEMP_DELAY 500 //Задержка перед очередным получением температуры от пк
#define GET_TEMP_TIMEOUT 1000 //таймаут получения температуры от пк
#define ZERO_RPM_TIMEOUT 500 //таймаут обнуления RPM при отсутствии сигналов от вентилятора
#define DEFAULT_RPM_VALUE 255 //Величина которая устанавливается сразу после загрузки (до подключения к пк)
#define CHECK_TEMP_DELAY 1000 //Задержка перед очередным получением температуры от пк
#define GET_TEMP_TIMEOUT 500 //Если в течение этого времени температура не была прислана, считается что пк не отвечает
#define RPM_CHECK_INTERVAL 1000 //Частота подсчета rpm и обнуления tachRevs
#define DEFAULT_TACT 1 //Величина которая устанавливается сразу после загрузки (до подключения к пк)
#define SOUND_PIN 10
#define LED_PIN 13
#define pwmpinA 3 //Выход ШИМ 1
#define pwmpinB 5 //Выход ШИМ 2
#define pwmpinC 6 //Выход ШИМ 3
inttachPins[6]={14,15,16,17,18,19};
intrpms[6]={};
uint32_tlastSignalTimes[6]={};
boolrpm_states[6]={};
intpwmPins[3]={3,5,6};//Номера пинов ШИМа
uint16_tpwr_tacts[3]={1,5,10};//питание будет включаться каждый n-ный такт
uint16_tcounters[3]={1,1,1};//счетчики тактов
uint32_tlast_power_starts[3]={};//времена начала импульсов питания
uint32_tlast_power_ends[3]={};//времена окончания импульсов питания
uint32_tlast_signal_starts[FAN_COUNT]={};//времена начала импульсов сигнала
uint32_tlast_signal_ends[FAN_COUNT]={};//времена окончания окончания питания
inttachPins[FAN_COUNT]={14,15,16,17,18,19};//Номера пинов для считывания оборотов
uint16_ttachRevs[FAN_COUNT]={};//Обороты (просто сколько насчитано оборотов, а не rpm)
uint16_ttachRpm[FAN_COUNT]={};//rpm
booltachStates[FAN_COUNT]={};//Состояния (оборот считывается только если состояние == 0, и считывается 0)
uint32_tlastRpmCheck=0;
intprev_pwr_tact_value=0;
inttemp,rpmValue;//целочисленные переменные для расчетов
uint32_tlastSignalTime;
typedefstruct{// Вводим новый тип переменных для вентиляторов
charfantype;
unsignedintfandiv;
}fanspec;
fanspecfanspace[3]={{0,1},{1,2},{2,8}};//Массив переменных нового типа
structfan{//Данные о вентиляторе
inttachPin;//Номер пина для считывания оборотов
booltachState;//Состояние датчика оборотов
uint16_trevs;//Количество оборотв (просто, не в минуту)
uint16_trpm;//Обороты в минуту
uint32_tlastSignalStart;//Время начала последнего сигнала тахометра
uint32_tlastSignalEnd;//Время окончания последнего сигнала тахометра
};
//fanspec fanspace[3] = {{0, 1}, {1, 2}, {2, 8}}; //Массив переменных нового типа
charfan=1;//Переменная, отвечающая за выбор типа датчика вентилятора (1 – униполярный датчик Холла, 2 –биполярный датчик Холла)
uint32_tlast_beep_time=0;
uint32_tlast_check_time=0;
voidrpm_interrupt(){
if(rpm_states[1]==0){
rpm_states[1]=1;
}
else{
rpm_states[1]=0;
return;
}
rpms[1]=60000000/(micros()-lastSignalTimes[1]);
lastSignalTimes[1]=micros();
}
voidrpmcalc(){//Считывание оборотов
for(inti=0;i<6;i++){
if(digitalRead(tachPins[i])==0){
if(rpm_states[i]==0){
rpm_states[i]=1;
}
else{
rpm_states[i]=0;
continue;
}
if(millis()-lastSignalTimes[i]!=0){
rpms[i]=60000/(millis()-lastSignalTimes[i]);
}
else{
rpms[i]=9999;
voidrpmcalc(){//Считывание оборотов и подсчет rpm
for(inti=0;i<FAN_COUNT;i++){
if(digitalRead(tachPins[i])==0&&tachStates[i]==0){//сигнал тахометра появился
if((last_power_ends[i]-last_signal_starts[i])-(last_signal_ends[i]-last_signal_starts[i])>2){//оборот засчитывается только если длина сигнала тахометра меньше длины включения питания. В противном случае это фейковый сигнал