Помощь с кодом: запуск котла автомобильного подогревателя с помощью SIM800L

antolich
Offline
Зарегистрирован: 04.02.2016

Уже недель бьюсь, никак не могу понять где загвоздка (работает как хочет, только не так как нужно).


//Настройки
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2, 3); // RX, TX
int ch = 0;
String val = "";
unsigned long ENGINE_WARM_TIME = 30000; //В миллисекундах время работы подогревателя после запуска 1200000 миллисекунд = 20 минут

// select pins for input

const int sharging_in  = 5;  //d5 запустилась помпа
const int power_in  = 6; //d6 когда повернул ключ
// select pins for output
const int engine_out  = 12;  //d12 пуск подогревателя
const int pechka_out  = 8;  //d8 цепи вторичного питания печка, фары итд



// variable for actual mode
int actual_mode = 0; //  2-подогреватель запущен
int left_start_try = 0;  // переменная для хранения остатка числа попыток запуска

unsigned long last_start_time = 0; //время в тысячных секунды когда был запущен подогреватель





void setup() {

  delay(2000);  //время на инициализацию модуля
  Serial.begin(9600);  //скорость порта
  mySerial.begin(9600);
  mySerial.println("AT+CLIP=1");  //включаем АОН
  delay(100);
  mySerial.println("AT+CMGF=1");  //режим кодировки СМС - обычный (для англ.)
  delay(100);
  mySerial.println("AT+CSCS=\"GSM\"");  //режим кодировки текста
  delay(100);
  mySerial.println("AT+CNMI=2,2");      //отображение смс в терминале сразу после приема (без этого сообщения молча падают в память)

  pinMode(sharging_in, INPUT); // enable input
  digitalWrite(sharging_in, LOW); //generator LOW normaly
  
  pinMode(power_in, INPUT);
  digitalWrite (power_in, LOW);

  pinMode(engine_out, OUTPUT); // enable output
  digitalWrite(engine_out, LOW); //set digital 0

  pinMode(pechka_out, OUTPUT); // enable output
  digitalWrite(pechka_out, LOW); //set digital 0
  //---- конец настройки входов и выходов контроллера --------------


}


void loop()
{
  if (mySerial.available())   //если GSM модуль что-то послал нам, то
   {
       while (mySerial.available()) {  //сохраняем входную строку в переменную val
      ch = mySerial.read();
      val += char(ch);
      delay(10);    }
 
  if (val.indexOf("RING") > -1) {  //если звонок обнаружен, то проверяем номер
    if ((val.indexOf("79202600606") > -1) && (actual_mode < 2 )) 
    {  //если номер звонящего наш и  если двигатель не запущен. Укажите свой номер без "+"
      mySerial.println("ATH0");  //разрываем связь
      val = "";
      check_start();  //Управляем режимом запуска
    }}

      
      else   // иначе
      {
        val = "";
        check_for_shutdown(); //Управляем режимом ожидания окончания прогрева
      }}}
      //------------------конец основного кода -----------------





    //---- а дальше идут используемые функции и подфункции --------------

    void check_start()
    {
      if (sharging_in == LOW && left_start_try == 0)
      {
        left_start_try = 3;   // указываем что нужно попытаться трижды запустить подогреватель
      }

      if ( left_start_try > 0 )
      {
        do_start(); // пытаемся запустить подогреватель
        left_start_try = left_start_try - 1; //уменьшаем число попыток
        if (left_start_try == 0 )
          actual_mode = 2; // заканчиваем попытки запустить движок
      }
    }
     // конец процедуры старта


    void do_start()
    {
      //тут будет запуск подогревателя
      //   delay(3000); // останавливаем код на 3 секунды чтобы помпа включилась
      //-----------------------------------------------------------------------------------
      digitalWrite(engine_out, HIGH);
      delay(5000);
      if (digitalRead(sharging_in) == HIGH) //еще раз смотрим что  зарядка пошла
      {
        actual_mode = 2; //Запоминаем что движок запущен
        last_start_time = millis(); // запоминаем время запуска движка
      }
      else
      {
        digitalWrite(engine_out, LOW);   //выключаем зажигание чтбы разблокировать реле стартера
        digitalWrite(pechka_out, LOW); //выключаем печку фары итд
        delay (3000);

      }


    }

    void check_for_shutdown()
    {
      //сюда мы попадаем когда контроллер считает что движок работает

      if (digitalRead(sharging_in) == LOW) //проверяем что движок случайно не заглох
        do_shutdown();
      else
        digitalWrite(pechka_out, HIGH); //включаем печку фары итд



      //тут будем контролировать чтоб если забыли машинку заведенной она не молотила до скончания бензобака а выключалась через какоето время


      if (actual_mode != 0) //значит не выключили заглохший двигатель только что
      {

        // милисекунды в ардуино обнуляются каждые 49 суток
        // для того чтобы в случае если запуск произошел в течении последних 20 минут до обнуления мотор не молотил еще 49 суток
        //  нужно обнулить и время старта, при этом мотор максимум будет прогреваться вдвое больше обычного
        if (millis() < last_start_time)
        {
          last_start_time = 0;
        }


        if (millis() > last_start_time + ENGINE_WARM_TIME) // если текущее время больше чем время старта + время прогрева
        {
          do_shutdown();
          left_start_try = 0; // и больше не заводим
        }
        
        if (digitalRead (power_in) == HIGH)
        {
          do_shutdown();
          left_start_try = 0; // и больше не заводим
        }
      }
    }


    void do_shutdown()
    {
      digitalWrite(pechka_out, LOW); //выключаем печку фары итд
      digitalWrite(engine_out, LOW); //вырубаем зажигание
      actual_mode = 0;  // движок выключили запомним это
      last_start_time = 0; // ну и забудем о том что он был включен
    }

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Как нужно? Как хочет? "Догадайся мол сама"! Не буду догадываться - мне не нужно!

Если Вам нужно, будьте добры описать чего Вы хотите, и что реально получаете.

antolich
Offline
Зарегистрирован: 04.02.2016

Извините пожалуйста.

Хотел бы, что бы при звонке и определении номера шел запуск котла (при условии что он уже не запущен и что не включено зажигание) и последующее включение печки. Число попыток запуска котла 3. Если они израсходуются то попытки прекращаются. Контроль запуска котла осуществляется + от помпы (возможно что кончится топливо, или акб разрядится, тогда контроллер котла сам отключит подогреватель), ардуино при этом должна сбрасывать число попыток. 

Забыл еще. Когда я прихожу в авто, а котел еще запущен, то при повороте ключа (т.е. включении зажигания), котел должен выключаться.

В общем как то так, еще раз прошу прощения.

Gres
Gres аватар
Offline
Зарегистрирован: 26.03.2013

Позвольте маленько покритикую:

Для того, чтоб не путаться где и что, весь код всегда отрабатывается отдельными модулями, если это необходимо, используются вставки вывода отладочной информации, причем индикация может быть какой угодно, сериал, светодиод и т.д. Сложно сразу весь код в целом проверить на ошибки, тем более, что его выполнение зависит от внешних сигналов.

Помпа управляется ШИМом, что означает не просто взяла и включилась, а идет последовательность импульсов с изменяющейся при необходимости скважностью.

Вот это включилась помпа:?

const int sharging_in  = 5;  //d5 запустилась помпа

Или пошла зарядка:?

if (digitalRead(sharging_in) == HIGH) //еще раз смотрим что  зарядка пошла

Выключение котла при повороте ключа зажигания: тут возможны проблемы, например Бинар(думаю и Вэбасто так же), полсе нажатия кнопки стоп, останавливает подачу топлива и начинает продув камеры сгорания, это длится какое то время, до минуты, может и больше, не помню точно. Дак вот особенность именно Бинара, при остановке котла, активируется панель его управления и начинает моргать индикатор сигнализирующий об остановке, если в момент отображения индикации завести авто, все настройки сбрасываются, как при отключении питания. Аппаратный косяк Бинара, может в последних версиях его уже устранили.