Всех приветствую. Сделана автоматика ТТ котла, работает 2 года постепенно совершенствуется.
После умирания очередных щеток на коллекторном двигателе, и просмотра как работать с БК моторами, был установлен двигатель для авиа моделей и блок питания мощнее, так вот заметил что при работе двигателя в странные промежутки времени есть просадка по мощности на миллисекунду, остановится двигатель не успевает, но звук который он издает при постоянной работе сменяется , затем работает на полной мощности и так все время пока нужно.
У меня подозрения что какое то действие делеит весь код на милисекунду, прошу помощи разобраться, на работу это конечно не влияет, но разобраться очень хочется дабы дальше не допускать подобных ошибок.
Буду рад если укажете на любые глупые строки не связанные с проблемой, к сожалению пока что большинство ответов по данному проекту сводятся к совету купить автоматику заводского производства и не сжечь дом.
C++:
String vers = "1.23" ; /* Версия 5декабря безколлекторный драйвер плавная остановка*/
//______________________________________________________________________________________________________________________________
#include <Servo.h> // Библиотека для работы с БК двигателем
Servo motor;
bool motor_timer_start = 0;
byte motor_vall = 0;
int motorspeed;
#include <math.h> // Библиотека для вычисления необходимой температуры котла в зависимости от уличной температуры
#include <Average.h> // Библиотека для вычисления среднего значия
#include <DHT.h> // Библиотека для подключения датчика DHT
#include "max6675.h" // Библиотека для подключения модуля термопары MAX6675
#define DHTTYPE DHT11 // Установка модели датчика DHT(11/22)
// pin 0
// pin 1
#define relmotor 2 // Пин подключения управления мотором раздува(цифровой сигнал для драйвера безколллектороного двигателя)
#define thermoDO 3 // Пин подключения MAX6675 он же SO /Пин подключения ENC28J60
// pin 4 // Пин подключения SD карты
#define thermoCS 5 // Пин подключения MAX6675 8/12
#define thermoCLK 6 // Пин подключения MAX6675 он же SCK
// pin 7 //
#define butt 8 // Пин подключения кнопки старт/стоп
#define DHTPIN 9 // Пин подключения DHT11
// pin 10 // Пин подключения Ethernet W5100 *
// pin 11 // Пин подключения Ethernet W5100 *
// pin 12 // Пин подключения Ethernet W5100 *
#define rellamp 13 //13 // Пин подключения реле отвечающей за идикатор состояния котла (работа/остановка)/Пин подключения Ethernet W5100 *
#define termistrstreet 14 //A0 // Пин подключения термистора отвечающего за температуру улицы *
#define relnasos 15 //A1 // Пин подключения реле отвечающей за работу насоса теплого пола
#define termistrkot 16 //A2 // Пин подключения термистора отвечающего за температуру котла
#define termostat 17 // A3 // Пин подключения термостата в доме
// pin 18 // A4 //
// pin 19 // A5 //
int8_t tkot = 0; // Переменная для хранения значение температуры котла с термистора termistrkot
int8_t tstreet = 0; // Переменная для хранения значение температуры улицы с термистора termistrstreet
byte tnormkot = 50; // Переменная хранящая необходимую температуру работы котла в зависимости от уличной температуры
//______________________________________________________________________________________________________________________________
MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); //
int tfire = 0; // Переменная для хранения значение температуры с термопары модуля MAX6675
Average<float> avetfire(10); // Установка количиства записей показаний температуры огня (10) для вычисления среднего значения
//______________________________________________________________________________________________________________________________
//unsigned long last_time_sms; // Переменная для хранения времени последнего отправленного SMS
float hdom = 0, tdom = 0; // Переменные для хранения информации с сенсора
int inttdom,inthdom; // нормальная температура в доме
//byte tnormdom = 26; // Переменная для хранения устанавливаемой температуры в доме
DHT dht(DHTPIN, DHTTYPE); //
Average<float> avetdom(10); // Установка количиства записей показаний (10) для вычисления среднего значения
//______________________________________________________________________________________________________________________________
unsigned long Refresh = millis(); //
unsigned long RefreshPeriod = 180000; // Время через которое опрашиваются термисторы и устанавливается нужная температура и проверяется работа/затухание котла
//long RefreshTime = millis(); // Время начала продувки котла
//long RefreshTimePeriod = 2000; // Время на которое будет включаться продув
unsigned long lastUpdateSensor = millis(); // Время последнего обновления информации с датчиков
int updatePeriodSensor = 5000; // Период обновления информации с датчиков секунд
//long lastUpdateSerial = millis(); // Время последнего обновления информации в монитор порта
//long updatePeriodSerial = 10000; // Период вывода информации в монитор порта
String fullinf = "fail"; // Переменная хранящая информацию со всех датчиков
bool relnasos_flag;
bool relmotor_flag;
bool work_flag; // Переменная флага состояния котла (старт/стоп)
bool butt_flag; // Переменная флага состояния работы котла (горение/поддержание)
bool but; // Переменная хранящая значение кноки
boolean motor_flag = 0; // Флаг работы мотора раздува
//void(* resetFunc) (void) = 0; // Объявляем функцию void (програмный reset)
double Thermister(int RawADC) {
double Temp;
Temp = log(((10240000/RawADC) - 10000));
Temp = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * Temp * Temp ))* Temp );
Temp = Temp - 273.15; // Kelvin to Celcius
return Temp;
}
void setup() {
delay(2000);
pinMode(butt,INPUT); // Настройка пина как вход
pinMode(termostat,INPUT); // Настройка пина как вход
pinMode(rellamp,OUTPUT); // Настройка пина как выход
pinMode(relnasos,OUTPUT); // Настройка пина как выход
pinMode(relmotor,OUTPUT); // Настройка пина как выход
digitalWrite(rellamp, HIGH); // Установка высокого уровня сигнала на пин реле т.к. работают в обратной полярности
digitalWrite(relnasos, HIGH); // Установка высокого уровня сигнала на пин реле т.к. работают в обратной полярности
digitalWrite(relmotor, LOW); // Установка высокого уровня сигнала на пин реле т.к. работают в обратной полярности
dht.begin(); // Запуск библиотеки для DHT22
Serial.begin(9600); // Установка скорость обмена данными с компьютером
Serial.println(vers); // Сообщение в монитор порта о версии программы
lastUpdateSensor = millis(); // Обнуляем таймер проверки
motor.attach(relmotor);
motor.writeMicroseconds(2300);
delay(2000);
motor.writeMicroseconds(800);
delay(10000);
tkot = Thermister(analogRead(termistrkot));
tstreet = Thermister(analogRead(termistrstreet));
}
void loop() {
but = digitalRead(butt); // Запись в переменную состояния пина подключенной кнопки
// Обработка кнопки включения работы котла
if(but == 1){ // Если кнопка включена то:
butt_flag = true; // Флаг работы ставим (ГОРЕНИЕ)
}
else{ // Если нет то:
butt_flag = false; // Флаг работы ставим (СТОП)
}
// Запись значений с сензоров в переменные и вывод их в монитор порта
if (lastUpdateSensor + updatePeriodSensor < millis()){ // Если просшло 5 секнуды после последнего считывания то считываем данные
hdom = dht.readHumidity(); // Запись значения влажности с датчика DHT в переменную
inthdom = int(hdom);
tdom = (1 + (dht.readTemperature())); // Запись значения температуры с датчика DHT в переменную
inttdom = int(tdom);
if(isnan(tdom)){ // Если датчик не отвечает, то:
avetdom.push(26); // Записываем для вычисления среднего значения 26, что при выходе из строя датчика оставит включеным ТП
}
else{ // Если нет, то:
avetdom.push(tdom); // Запись значения с датчика DHT, для вычисления среднего значения из последних 10 показаний
}
tfire = thermocouple.readCelsius(); // Запись значения температуры с термопары max 6675k в переменную
if(relmotor_flag == true){
tfire = tfire+50; // Компенсация помех от включенного мотора
}
avetfire.push(tfire);
lastUpdateSensor = millis();
// Запись в переменную информиации всех состояний и значений с датчиков
fullinf = "\r\nT dom = " + String(tdom, 1) +
" C \r\nH dom = " + String(hdom, 1) +
" % \r\nT kotla = " + String(tkot) +
" C \r\nT street = " + String(tstreet) +
" C \r\nT fire = " + String(tfire) +
" C \r\nwork_flag = " + String(work_flag == 0 ? "OFF" : "ON") +
" \r\nMotor = " +String(motor_flag == 0 ? "OFF" : "ON") +
" \r\nT norm = " + String(tnormkot) +
" \r\nMotor TP = " + String(relnasos_flag == 0 ? "OFF" : "ON")+
" \r\nAve T fire = "+ String(avetfire.mean());
Serial.println(fullinf); // Вывожим инфу в монитор порта
}
// Проверяем уличную температуру задаём нужную температуру работы котла(tnormkot) в зависимости от уличной
if(Refresh + RefreshPeriod < millis()){ // Если просшло 3 минуты после последнего считывания то считываем данные
tkot = Thermister(analogRead(termistrkot));
tstreet = Thermister(analogRead(termistrstreet));
// Ззадаём нужную температуру работы котла(tnormkot) в зависимости от уличной
tnormkot = ((-0.5 * tstreet) + 54);
tnormkot = constrain(tnormkot, 50, 70);
//________________________________________________проверка затухания огня______________________________________________________________
if( avetfire.mean() > 50){ // Если средняя температура огня больше 50 градусов то: (avetfire.mean() >= avesenskot.mean() &&)
work_flag = true ; // Выводим котел в состояние (Старт)
}
else{ // Если нет то:
work_flag = false ; // Выводим котел в состояние (Стоп)
}
Refresh = millis();
}
//_____________________________________________________________________________________________________________________________________
if (butt_flag == true && work_flag == true){ // Если флаг работы котла(ГОРЕНИЕ) и флага состояния котла (СТАРТ),т.е. котел РАБОТАЕТ то:
digitalWrite(rellamp, LOW); // Включаем лампу сигнализирующую РАБОТУ котла
if (tkot >= tnormkot){ // Если средняя температура котла больше или равна устанвленной то:
relmotor_flag = false; // Выключаем РАЗДУВ
motor_flag = false; // Выводим флаг работы мотора раздува в стоп
}
else{ // Если средняя температура котла меньше то:
relmotor_flag = true; // Включаем РАЗДУВ
motor_flag = true; // Выводим флаг работы мотора раздува в работа
}
if ((tkot < 40) || (tkot > 80)){ // Если средняя температура котла меньше 40 или больше 80 то:
relnasos_flag = false; // Насос ТП выключен
}
else{ // Если нет то:
if(digitalRead(termostat) == true){ // Если температура в доме меньше установленной, то:
relnasos_flag = true; //Насос ТП включен
}
else{ // Если нет то :
relnasos_flag = false; // Насос ТП выключен
}
}
}
else{ // Если нет т.е либо кнопка выключена либо котел потух, то:
digitalWrite(rellamp, HIGH); // Включаем лампу сигнализирующую ОСТАНОВКУ котла
relmotor_flag = false; // Выключаем раздув
motor_flag = false; // Выводим флаг работы мотора раздува в стоп
if(digitalRead(termostat) == true){
if((tkot - 7) > avetdom.mean()){ // Если средняя температура котла,минус потери 5 градусов по трубе больше температуры в доме, то:
relnasos_flag = true; //Насос ТП включен
}
else{ // Если нет то :
relnasos_flag = false; // Насос ТП выключен
}
}
else{ // Если нет то :
relnasos_flag = false; // Насос ТП выключен
}
}
if(relmotor_flag == true){ // Если появилась необходимость включить мотор раздува включаем плавный пуск
if( motor_vall < 100){
static uint32_t timer = 0;
if(millis() - timer >= 300){
timer = millis();
motor_vall = motor_vall + 1;
}
}
motorspeed = map(motor_vall, 0, 100, 800, 2000);
motor.writeMicroseconds(motorspeed);
}
if(relmotor_flag == false){
if( motor_vall > 0){
static uint32_t timer = 0;
if(millis() - timer >= 300){
timer = millis();
motor_vall = motor_vall - 1;
}
}
motorspeed = map(motor_vall, 0, 100, 800, 2000);
motor.writeMicroseconds(motorspeed);
}
if(relnasos_flag == false){
digitalWrite(relnasos, HIGH);
}
if(relnasos_flag == true){
digitalWrite(relnasos, LOW);
}
}
У меня подозрения что какое то действие делеит весь код на милисекунду, прошу помощи разобраться, на работу это конечно не влияет, но разобраться очень хочется дабы дальше не допускать подобных ошибок.
Буду рад если укажете на любые глупые строки не связанные с проблемой, к сожалению пока что большинство ответов по данному проекту сводятся к совету купить автоматику заводского производства и не сжечь дом.