//Чтобы при его помощи вручную управлять шимом (это позволит точно знать время его включения, при этом иметь шим нормальной частоты)
//И чтобы чтобы через прерывания чекать тахометры.
//Можно еще попробовать реализовать вариант, когда для измерения оборотв на короткое время на питание подается постоянное напряжение вместо шима, и нужно успеть измерить обороты за это время.
#include <Wire.h>
#include <Wire.h>
#define FAN_COUNT 6 //Количество вентиляторов
#define FAN_COUNT 6 //Количество вентиляторов
#define BAUDRATE 19200 //Скорость serial порта
#define BAUDRATE 19200 //Скорость serial порта
#define CHECK_TEMP_DELAY 200 //Интервал получения температуры от пк (мс)
#define CHECK_TEMP_DELAY 1000 //Интервал получения температуры от пк (мс)
#define GET_TEMP_TIMEOUT 1000 //Если в течение этого времени температура не была прислана, считается что пк не отвечает (мс)
#define GET_TEMP_TIMEOUT 1000 //Если в течение этого времени температура не была прислана, считается что пк не отвечает (мс)
#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, которые записываются и усредняются (скользящее среднее)
uint16_t revs; //Количество оборотв (просто, не в минуту)
uint16_t rpm; //Обороты в минуту
uint32_t lastSignalStart; //Время начала последнего сигнала тахометра
uint32_t lastSignalEnd; //Время окончания последнего сигнала тахометра
};
struct control { //Данные о контроллерах вентилятора
int pwmPin; //Номер пина ШИМ
bool pwmState; //Состояние пина ШИМ
};
*/
inttemp;//Температура, полученная от пк
inttarget_rpm=0;
uint32_tlast_beep_time=0;
uint32_tlast_check_time=0;
uint32_tlastRpmCheck=0;
uint32_tlastRevTime=0;
floatp=0;
floati=0;
floatd=0;
floatk_p=0.3;
floatk_i=0.0004;
floatk_d=160;
voidwait_for_connection(boolbeep){//функция, которая мигает светодиодом и пищит (если beep == true) до тех пор, пока не будет установлено соединение с ПК
Serial.println("start_transmission");
digitalWrite(LED_PIN,1);
unsignedlonglast_blink_time=millis();
while(Serial.available()==0){//ждем ответа
if(millis()>=last_blink_time+BLINK_INTERVAL*2){
digitalWrite(LED_PIN,1);
last_blink_time=millis();
}
elseif(millis()>=last_blink_time+BLINK_INTERVAL){
digitalWrite(LED_PIN,0);
}
if(beep){
if(millis()>=last_beep_time+BEEP_INTERVAL*2){
analogWrite(SOUND_PIN,BEEP_STRENGTH);
last_beep_time=millis();
}
elseif(millis()>=last_beep_time+BEEP_INTERVAL){
analogWrite(SOUND_PIN,0);
}
}
}
digitalWrite(LED_PIN,0);//гасим светодиод
analogWrite(SOUND_PIN,0);//и выключаем пищалку
while(Serial.available()){// очистка буфера
Serial.readString();
}
}
voidtempFromPc()// получаем температуру от пк
{
Stringrpm_string="send_rpm_";
for(intfan=0;fan<FAN_COUNT;fan++){
uint32_tavg_rpm=0;
for(intval=0;val<RPM_VALUES_COUNT;val++){
avg_rpm+=tachRpm[fan][val];
}
avg_rpm/=RPM_VALUES_COUNT;
rpm_string+=String(avg_rpm);
if(fan<5){
rpm_string+="_";
}
}
Serial.println("req_temperature_"+rpm_string+"_debug_"+String(OCR2A));//запрос к пк
unsignedlongquery_time=millis();
while(Serial.available()==0){//ждем пока ответит
if(millis()>=query_time+GET_TEMP_TIMEOUT){//если слишком долго не отвечает
//Почему-то иногда может заглючить: скважность стоит 254, pwm_on равно 1, но вентилятор не крутится (но пищит). Похоже каким-то образом меняется pwmState, когда не надо