ARDUINO Периодическое отключение БК мотора

Alex_Zay

✩✩✩✩✩✩✩
5 Янв 2022
3
0
Всех приветствую. Сделана автоматика ТТ котла, работает 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);
  }
}
После умирания очередных щеток на коллекторном двигателе, и просмотра как работать с БК моторами, был установлен двигатель для авиа моделей и блок питания мощнее, так вот заметил что при работе двигателя в странные промежутки времени есть просадка по мощности на миллисекунду, остановится двигатель не успевает, но звук который он издает при постоянной работе сменяется , затем работает на полной мощности и так все время пока нужно.
У меня подозрения что какое то действие делеит весь код на милисекунду, прошу помощи разобраться, на работу это конечно не влияет, но разобраться очень хочется дабы дальше не допускать подобных ошибок.
Буду рад если укажете на любые глупые строки не связанные с проблемой, к сожалению пока что большинство ответов по данному проекту сводятся к совету купить автоматику заводского производства и не сжечь дом.
 

viktor1703

★★★✩✩✩✩
9 Дек 2021
632
150
После умирания очередных щеток на коллекторном двигателе, и просмотра как работать с БК моторами, был установлен двигатель для авиа моделей
А отвечающие обязаны сами знать, что за дрыгатель и драйвер были выбраны?
Если мотор был остановлен motor_vall == 0
C++:
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);
  }
обязательно разгонять мотор очень плавно в течение 30 секунд?
при работе двигателя в странные промежутки времени есть просадка по мощности
Это може быть из-за особенности работы ESC: сначала мотор разгоняется до определенных оборотов по таблице, зашитой в регулятор, а потом переключение обмоток мотора происходит по данным (ЭДС) полученным с обмоток мотора, на которые не подаётся напряжение в данный момент времени. Вот в момент переключения режимов работы регулятора и происходят просадки. Возможно, разгон нужно начинать не с нуля, а, например, с 35-45, или время разгона сократить
C++:
if(millis() - timer >= 80)
Но это всё, конечно, гадание на кофейной гуще. Потому, что, повторюсь, никто, кроме @Alex_Zay не знает, что за мотор и регулятор установлены.
 
Изменено:

Alex_Zay

✩✩✩✩✩✩✩
5 Янв 2022
3
0
@viktor1703, Спасибо за отклик и сразу извинюсь за то что не указал характеристики и название двигателя и контроллера скорости, не думал что это важно, к сожалению не могу ссылку с алика кинуть, поэтому описание и характеристики в
Мотор бесколлекторный A2212/15T 930KV
-Режим: Western A2212
-КВ: 930
-Максимальная Эффективность: 80%
-Максимальный КПД: 4-10 А (>75%)
-Сила тока: 12А/60 с
-Ток холостого хода @ 10 В: 0,5 А
-Количество ячеек: 2-3 Li-Poly
-Размеры двигателя: Φ27,5x30 мм
-Диаметр стержня: Φ3,17 мм
-Вес: 47 г

Контроллер скорости бесщеточного двигателя, 12 В, 30 А, 3-фазовый регулятор ШИМ
Характеристика:
Благодаря микрочипсовой системе этот контроль скорости может достигать простого системного программирования, который может подойти для более быстрых бесщеточных двигателей высокой мощности.
Он имеет несколько функций:
1. Предохранительный запуск: во избежание каких-либо травм двигатель не запустится немедленно, если потенциометр контроллера скорости не находится на самой низкой скорости, что необходимо для высокоскоростного высокомощного двигателя для защиты безопасности пользователя.
2. Защита от температуры: контроль скорости имеет алюминиевый радиатор, который позволяет работать на 30 А непрерывно. Когда температура достигает 110 градусов Цельсия, система обнаружения температуры отправит сигнал защиты, и система автоматически уменьшит мощность 60% для защиты контроля скорости и двигателя. Он вернется к нормальной мощности после снижения температуры. Для защиты модуля привода, пожалуйста, рассеивайте тепло во время длительного использования.
3. Предотвращение потери сигнала: Автоматическое отключение, когда нет сигнала, обнаруженного от PWM генератор сигналов (потенциометр).
4. Система идентификации мощности: контроль скорости имеет систему идентификации мощности, которая предназначена для высокоскоростных двигателей высокой мощности, таких как в модельной плоскости. Не подходит для маломощных бесщеточных двигателей.
5. Функции программирования: с системой управления одним чипом, некоторые функции могут быть изменены:
A, запуск: гибкий Медленный запуск/прямой запуск
B, торможение: быстрое торможение с обратной нагрузкой/свободное торможение
C, регулируемая синхронизация: маленький/средний/большой
D, защита от низкого напряжения: низкий/средний/высокий
E, типы батарей: литий/никелевый хром/NIMH/лембовая кислота
6. Назад к заводским настройкам: неправильная операция может быть очищена
7. Другое Функция (пожалуйста, игнорируйте в том случае, если используется только для электродвигательного привода): внешний PWM генератор сигналов может отправить сигнал для того чтобы контролировать скорость или для того чтобы повернуть рулевой механизм, поэтому он может испытать рулевого зубчатых колес весом менее 55g.

Спецификация:
Номинальное напряжение: с источником питания от постоянного тока, 6-12,8 V
Текущий рейтинг: 32A (в течение 5s максимальный ток не может превышать 40A)
Номинальная мощность: 360 Вт
Номинальная мощность: 5 В 0.5A
Защита от температуры: 110 °C
Диапазон скорости: 8% ~ 98%
Для электродвигателей: 2-18 полюсов
Старт: гибкий старт/немедленное начало
Тормоз: обратная нагрузка/без тормоза
Сигнал скорости: 8 кГц/16 кГц фиксированная частота ШИМ
могу только закинуть.
По поводу плавного разгона, нет это не обязательно, но мне показалось так менее напряжно контроллеру скорости, если есть подозрения что в этом пробелема то спасибо за совет, попробую избавиться посмотрю на результат.
Это може быть из-за особенности работы ESC:
Тут наверное не так, если использовать код из видео Гайвера где не чего нет кроме управления двигателем , то сколько бы он не крутил, нет этих просадок по мощности, они появились именно в моём коде.
И еще раз прошу прощения за то что дал не полную инфу!
 

poty

★★★★★★✩
19 Фев 2020
3,261
948
Чтение DHT - блокирующая функция. Возможно, по этой причине имеются рывки.
Остальная часть не так часто выполняется.
 

Alex_Zay

✩✩✩✩✩✩✩
5 Янв 2022
3
0
@poty, хорошо, проверить это смогу увеличив время между запросами к DHT, соответственно частота рывков уменьшится и так я точно пойму что этот датчик виноват, решение одно в голову приходит перейти на BMP ?