Поправить скетч

xellow
Offline
Зарегистрирован: 12.03.2016
Добрый день уважаемые гуру программирования. Собрал устройство для дистанционного запуска автомобиля на Ардуино мини, взял здесь http://suzuki-club.ru/threads/54145/. Однако скетч автора не совсем удовлетворяет особенностям моего автомобиля. В исходном варианте запуск схемы происходит при при появлении уровня High на входе Ардуино и дальше схема работает по алгоритму. Мне нужно изменить скетч таким образом, что бы при 1-м появлении уровня High на входе Ардуино начинался запуск, а при 2-м нажатии происходил останов двигателя. К сожалению моих скромных способностей пока хватает только на понимание уже написанных программ, да и то не в полной мере, по-этому прошу помощи.... Заранее Спасибо всем откликнувшимся))
Исходный код...

//v 22
//Настройки 
unsigned long ENGINE_WARM_TIME = 900000; //В миллисекундах время работы мотора после запуска 900000 миллисекунд = 15 минут
int ENGINE_START_MAX_TIME = 5; //В секундах масимальное время работы стартера типично 3 -10 сек




// select pins for input
const int hand_brake_in  = 3;  //d3 adruino Контакт стояночного тормоза "-"
const int start_in  = 4;  //d4 adruino Сигнал команды на старт от мобильного телефона вибра звонка
const int sharging_in  = 5;  //d5 adruino
 
const int sharging_on = 1; // 0 когда во время работы генератора или от датчика давления масла на этом входе низкое состояние , 1 когда на лампе генератора при работе генератора высокое состояние
const int hand_brake_on = 0; //  0= поднятый датчик ручника замыкает на массу тормоз активен (жигули), 1= датчик ручника в поднятом состоянии выдает высокий уровень напряжения 
 
// select pins for output
const int starter_out  = 6;  //d6 adruino реле стартера
const int engine_out  = 7;  //d7 adruino зажигание
const int secpower_out  = 8;  //d8 цепи вторичного питания печка, фары итд
const int status_out  = 9;  //d9 светодиод статуса системы  горит = система готова к работе(включена, ручник стоит). одно мигание запущен с первой попытки 2 со второй 3 с третьей 
                            //светодиод подключать с этого пина на массу

 
 
// variable for actual mode
int actual_mode = 0; //  2 engine started  
int left_start_try = 0;  // переменная для хранения остатка числа попыток запуска 
 
unsigned long last_start_time = 0; //время в тысячных секунды когда был запущен движок 
 
 
 
 
 
void setup() {
  
  //---- настройка входов и выходов контроллера --------------  
// init selected pins
  pinMode(hand_brake_in, INPUT); // enable input 
  pinMode(start_in, INPUT); // enable input 
  pinMode(sharging_in, INPUT); // enable input 
 
// init outputs
  pinMode(starter_out, OUTPUT); // enable output
  digitalWrite(starter_out, LOW); //set digital 0
 
  pinMode(engine_out, OUTPUT); // enable output
  digitalWrite(engine_out, LOW); //set digital 0
 
  pinMode(secpower_out, OUTPUT); // enable output
  digitalWrite(secpower_out, LOW); //set digital 0 

  pinMode(status_out, OUTPUT); // enable output
  digitalWrite(status_out, LOW); //set digital 0 
  
 }
 
 
void loop()
{
  
if (actual_mode < 2 )    //если двигатель не запущен
        check_start();  //Управляем режимом запуска
//код условия обязательно включать в фигурные скобки если должно быть выполнено несколько инструкций, в данном случае одна, поэтому скобки опущены        
      
else   // иначе
        {
        check_for_shutdown(); //Управляем режимом ожидания окончания прогрева
        } //но хорошая привычка фигурные скобки ставить всегда
 
      
 set_status_led(); //независимо от режима Управляем светодиодом статуса

  //------------------конец основного кода -----------------
 }
 
 
 
 
 
  //---- а дальше идут используемые функции и подфункции -------------- 
 
void check_start() 
{
if (digitalRead(start_in) == 0 && left_start_try == 0) // 1 is command for start  - 1  значит импульс старта пришел с дистанционного управления <--- тут определяется полярность импульса запуска
  {
   left_start_try = 3;   // указываем что нужно попытаться трижды запустить движок
  } 

 
 if ( left_start_try > 0 )   
 {
    digitalWrite(engine_out, HIGH);   //включаем зажигание 
    digitalWrite(secpower_out, HIGH); //включаем печку фары итд
    delay(3000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление, все датчики включились
    
    if (digitalRead(hand_brake_in) != hand_brake_on) //без ручника не делаем запуск
    {
      actual_mode = 2; // заканчиваем попытки запустить движок
      left_start_try = 0; //без ручника другие попытки бесполезны
      return;  
    }
    
  
   if (digitalRead(sharging_in) != sharging_on  )    // проверяем что генератор не работает 
   {
      do_start(); // пытаемся запустить движок
      left_start_try = left_start_try - 1 ; //уменьшаем число попыток

        if (left_start_try == 0 ) 
          actual_mode = 2; // заканчиваем попытки запустить движок
    } // конец проверки что ручник стоит а генератор не работает
}   

      
} // конец процедуры старта
 
 
void do_start()
{
    
    digitalWrite(secpower_out, LOW); //выключаем печку фары итд
    digitalWrite(starter_out, HIGH); //включаем стартер 
    for (int secs=0; secs <= ENGINE_START_MAX_TIME ; secs++) // 
      {
      delay(3000); // и продолжаем его держать включенным 3 секунды
      if (digitalRead(sharging_in) == sharging_on) //если зарядка пошла то 
               break;  // прерываем цикл
      }
//----------------------------------------------------------------------------------- 
    digitalWrite(starter_out, LOW); //отключаем стартер 
  
    {
      actual_mode = 2; //Запоминаем что движок запущен
      last_start_time = millis(); // запоминаем время запуска движка
    }
    else
    {
      digitalWrite(engine_out, LOW);   //выключаем зажигание чтбы разблокировать реле стартера
      digitalWrite(secpower_out, LOW); //выключаем печку фары итд
      delay(5000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление
    }
    
    
} 
 
void check_for_shutdown() 
{
//сюда мы попадаем когда контроллер считает что движок работает
 
    
    if (digitalRead(hand_brake_in) != hand_brake_on  ) //проверяем что если злодеи сняли с ручника то глушим мотор
      {
         do_shutdown();
         left_start_try =0; // и больше не заводим
      }
  
//тут будем контролировать чтоб если забыли машинку заведенной она не молотила до скончания бензобака а выключалась через какоето время
 
 
    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; // и больше не заводим
         }
    }
 }



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


void set_status_led()
{
if (digitalRead(hand_brake_in) != hand_brake_on  ) //Если ручник не стоит то выкл светодиод нечего ему в пути мигать попусту
  {
  digitalWrite(status_out, LOW);
  return; //прерываем выполнение функции
  }
  
if (actual_mode ==  2) //Движок запущен
     status_led_flash(); // показываем с какой попытки был прошлый запуск
else
     digitalWrite(status_out, HIGH); // постоянное свечение - показываем что готов к следующему запуску

}



void status_led_flash()
{
static unsigned long big_interval = 0;
static unsigned long flash_interval = 0;
unsigned long flash_count = 0;
flash_count = 3 - left_start_try;  //сколько раз мигать


//1 секндный интервал
if (millis() > flash_interval + 1000L)
      flash_interval = millis() ; //задаем счетчие от 0 до 1 секунды

//задаем 6 секунд 
if (millis() > big_interval + 6000L)
     {
      big_interval = millis() ;  //задаем счетчие от 0 до 10секунд
      flash_interval = big_interval;
     }  



if (millis() <  big_interval +  flash_count * 1000L) // делим 6 секндный интервал на два периода, в первый мигаем количество раз соответствующее числу израсходованных попыток
  { //мигает 
    if (millis() > flash_interval + 500L) 
      digitalWrite(status_out, HIGH);
    else
      digitalWrite(status_out, LOW);

  } 
else 
  { // негорит
    digitalWrite(status_out, LOW); //set digital 0 
  }
}

 

Andy
Andy аватар
Offline
Зарегистрирован: 01.01.2016

Коммент в строках 168-170 не оставляет шансов на успех.

xellow
Offline
Зарегистрирован: 12.03.2016

Печально(

xellow
Offline
Зарегистрирован: 12.03.2016

Извиняюсь за назойливость, нашёл судя по описанию автора скетч выполняющий мои требования(выполненный на основе выложенного мною ранее), но не уверен в его работоспособности именно в части запуска-останова двигателя. Не пойму как это реализовано...  Напомню необходимо при подаче команды на один из входов Ардуино - поочерёдно запускать - останавливать двигатель авто. Если не сложно посмотрите скетч... Взял здесьhttp://arduino.ru/forum/proekty/avtozapusk-pervyi-proekt у пользователя Pnewmoslon.

//авто запуск по звонку мобильного телефона или от дополнительного выхода автосигнаизвции с функцией автоматической и безопасной зарядки аккумулятора телефона
//Настройки

#include <Servo.h>                                    //библиотека серво
#include <PID_v1.h>                                   //библиотека ПИД-ругулятора
double Setpoint, Input, Output;                       //переменные пид регулятора
Servo myservo;                                        //серво привод
PID myPID(&Input, &Output, &Setpoint, 3, 0.5, 1, DIRECT); //создаем ПИД-регулятор
boolean revers;                                       //переменная ПИД-регулятора
int val = 0;                                          //переменная для хранения состояния датчика темппературы
unsigned long micros_th = 0;                          //переменная изменяемая для хранения значений прерываний
volatile int th;                                      //переменная для хранения значений в об/мин
volatile int tz;                                      //переменная для сброса значений тахометра


unsigned long ENGINE_WARM_TIME = 1200000; //В миллисекундах время работы мотора после запуска 1200000 миллисекунд = 20 минут
int ENGINE_START_MAX_TIME = 10; //В секундах масимальное время работы стартера типично 3 -10 сек




// select pins for input
const int sensorPin = A0;        //объявляем аналоговый вход А0 для подключения датчика температуры
const int sensorZarad = A1; //А1 заряд акб телефона
const int knopkaPusk = A3;//а3 кнопка запуска двигателя
const int hand_brake_in  = 3;  //d3 adruino Контакт стояночного тормоза "-"
const int start_in  = 4;  //d4 adruino Сигнал команды на старт от мобильного телефона вибра звонка
const int sharging_in  = 5;  //d5 adruino сигнал от лампы заряда или давления масла

const int sharging_on = 0; // 0 когда во время работы генератора или от датчика давления масла на этом входе низкое состояние , 1 когда на лампе генератора при работе генератора высокое состояние
const int hand_brake_on = 0; //  0= поднятый датчик ручника замыкает на массу тормоз активен (жигули), 1= датчик ручника в поднятом состоянии выдает высокий уровень напряжения

// select pins for output
const int ledPin = 12;      //объявляем цифровой выход 13 для индикации включения автоподсоса
const int pech = 10;        //объявляем цифровой выход 8 для подключения печки
const int outpinZarad = 16;//А2 пин подключение реле заряда акб телефона
//------------------------выходы управления сигналкой-------------------------
//const int outpinSigOff = 18;//А4 пин подключение реле отключения сигналки
//const int outpinSigOn = 19;//А5 пин подключение реле включения сигналки
//---------------------------------------------------------------------------
const int starter_out  = 7;  //d6 adruino реле стартера
const int engine_out  = 6;  //d7 adruino зажигание
const int secpower_out  = 8;  //d8 цепи вторичного питания печка, фары итд
const int status_out  = 11;  //d9 светодиод статуса системы  горит = система готова к работе(включена, ручник стоит). одно мигание запущен с первой попытки 2 со второй 3 с третьей
//светодиод подключать с этого пина на массу



// variable for actual mode
int actual_mode = 0; //  2 engine started
int left_start_try = 0;  // переменная для хранения остатка числа попыток запуска
int knopkaPuskState = 0;//переменная для хранения положения кнопки запуска двигателя
unsigned long last_start_time = 0; //время в тысячных секунды когда был запущен движок





void setup() {

  //---- настройка входов и выходов контроллера --------------
  // init selected pins
  // init inputs
  pinMode(knopkaPusk, INPUT);
  // digitalWrite(knopkaPusk, LOW);
  pinMode(sensorPin, INPUT);
  //  digitalWrite(sensorPin, HIGH);
  pinMode(sensorZarad, INPUT);
  //  digitalWrite(sensorZarad, HIGH);
  pinMode(hand_brake_in, INPUT); // enable input
  digitalWrite(hand_brake_in, HIGH); //если подтяжка реализована аппаратно то тут ненадо
  pinMode(start_in, INPUT); // enable input
  // digitalWrite(start_in, LOW); //pullup resustor enable
  pinMode(sharging_in, INPUT); // enable input
  //  digitalWrite(sharging_in, LOW); //generator LOW normaly
  
  // init outputs
  //-------------------управление сигналкой---------------------------
 //  pinMode(outpinSigOff, OUTPUT); // enable output
 // digitalWrite(outpinSigOff, LOW); //set digital 0
  
  // pinMode(outpinSigOn, OUTPUT); // enable output
 // digitalWrite(outpinSigOn, LOW); //set digital 0
 //------------------------------------------------------------------ 
  pinMode(outpinZarad, OUTPUT); // enable output
  digitalWrite(outpinZarad, LOW); //set digital 0

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

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

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

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

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

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

  Serial.begin(115200);                                 //включаем передачу по сериал монитор
  attachInterrupt(0, tahometr,   RISING);               //включаем прерывание по фронтам импульса и запускаем функцию тахометра
  Setpoint = 1500;                                      //здесь мы устанавливаем заданные обороты прогрева двигателя
  Input = th;                                           //присваиваем входу ПИД-регулятора значение тахометра в об/мин
  myPID.SetOutputLimits(0, 180);                        //устанавливаем границы выходного сигнала для ПИД-регулятора
  if (Setpoint < Input)                                 //если начальные обороты больше заданных
  {
    revers = true;                                   //
    myPID.SetControllerDirection(REVERSE);           //ПИД-регулятор используем обратный
  }
  myPID.SetMode(AUTOMATIC);                             //включаем ПИД-регулятор
  //---- конец настройки входов и выходов контроллера --------------
}


void loop()
{
  //---- собственно это и есть весь код программы --------------

  // Serial.println(th);   //печатаем в монитор значение тахоьетра в об/мин

  tz = tz - 1;                                        //арифметические операции для тахометра
  if (tz == 0) {
    th = 0; //если переменная тз равна нулю, переменная th обнуляется
  }
  val = analogRead(sensorPin);
  zaradAkkum();  //контроль заряда аккумулятора телефона
  //*********************************запуск от кнопки********************************************
  knopkaPuskState = digitalRead(knopkaPusk);
  if (knopkaPuskState != 0)
  {
    zapuskKnopka();
  }
  else {
    knopkaPuskState = 0;
  }
  if (digitalRead(sharging_in) != sharging_on  )    // проверяем что генератор не работает
  {
    digitalWrite(secpower_out, LOW);                 //выключаем  фары итд
    delay(1);
    digitalWrite(pech, LOW);                         //выключаем печку
    delay(1);
    digitalWrite(ledPin, LOW);                       //выключаем светодиод индикации режима включения автоподсоса
    delay(1);
    digitalWrite(engine_out, LOW);                   //выключаем зажигание
  }
  if (actual_mode < 2 ) {  //если двигатель не запущен
    check_start();  //Управляем режимом запуска
  }
  else   // иначе
  {
    check_for_shutdown(); //Управляем режимом ожидания окончания прогрева
  } //но хорошая привычка фигурные скобки ставить всегда


  set_status_led(); //независимо от режима Управляем светодиодом статуса


  //------------------конец основного кода -----------------
}





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

void check_start()
{
  if (digitalRead(start_in) == 1 && left_start_try == 0) // 1 is command for start  - 1  значит импульс старта пришел с дистанционного управления <--- тут определяется полярность импульса запуска
  {
    left_start_try = 3;   // указываем что нужно попытаться трижды запустить движок
  }


  if ( left_start_try > 0 )
  {  //------------------------------отключение сигналки----------------------------
	//digitalWrite(outpinSigOff, HIGH);//сигнал на отключение сигналки
   // delay(1000);                    //удержание 1 сек
	//digitalWrite(outpinSigOff, LOW);//сброс сигнала
	//delay(500);
	//-------------------------------------------------------------------------------
    digitalWrite(engine_out, HIGH);   //включаем зажигание
    // digitalWrite(secpower_out, HIGH); //включаем печку фары итд
    delay(3000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление

    if (digitalRead(hand_brake_in) != hand_brake_on) //без ручника не делаем запуск
    {
      actual_mode = 2; // заканчиваем попытки запустить движок
      left_start_try = 0; //без ручника другие попытки бесполезны
      return;
    }


    if (digitalRead(sharging_in) != sharging_on  )    // проверяем что генератор не работает
    {
      do_start(); // пытаемся запустить движок
      left_start_try = left_start_try - 1 ; //уменьшаем число попыток

      if (left_start_try == 0 )
        actual_mode = 2; // заканчиваем попытки запустить движок
    } // конец проверки что ручник стоит а генератор не работает
  }


} // конец процедуры старта


void do_start()//тут будет запуск движка
{
  digitalWrite(engine_out, HIGH);   //включаем зажигание
  digitalWrite(secpower_out, HIGH); //включаем печку фары итд
  ataches();
  servo_start();
  digitalWrite(secpower_out, LOW); //выключаем печку фары итд
  delay(1000);
  //----------------------------------------------------------------------------------- цикл стартера
  digitalWrite(starter_out, HIGH); //включаем стартер
  for (int secs = 0; secs <= ENGINE_START_MAX_TIME ; secs++) //
  {
    delay(1000); // и продолжаем его держать включенным 1 секунду
    if (digitalRead(sharging_in) == sharging_on) //если зарядка пошла то
      break;  // прерываем цикл
  }
  //-----------------------------------------------------------------------------------
  digitalWrite(starter_out, LOW); //отключаем стартер

  if (digitalRead(sharging_in) == sharging_on) //еще раз смотрим что  зарядка пошла
  {
    actual_mode = 2; //Запоминаем что движок запущен
    last_start_time = millis(); // запоминаем время запуска движка
  }
  else
  {
    ataches();                                        //
    otkluchenie();
    digitalWrite(secpower_out, LOW); //выключаем печку фары итд
    digitalWrite(ledPin, LOW);                      //выключаем светодиод индикации режима включения автоподсоса
    delay(1000);
    digitalWrite(engine_out, LOW);   //выключаем зажигание чтбы разблокировать реле стартера
    delay(5000); // останавливаем код на 5 секунд
  }


}








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


  if (val >= 1000 && th >= 0 )                         //если температура более 85 и обороты более или ровны 0 то,
  {
    ataches();                                        //
    otkluchenie();
  }

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

  if (digitalRead(hand_brake_in) != hand_brake_on  ) //проверяем что если злодеи сняли с ручника то глушим мотор
  {
    digitalWrite(ledPin, LOW);                      //выключаем светодиод индикации режима включения автоподсоса
    do_shutdown();
    left_start_try = 0; // и больше не заводим
  }

  if (val < 1000 && th >= 750)                         //если темп менее 85 и обороты более или ровны 750, запускаем ПИД-регулятор
  {
    ataches();                                          //звпускаем функцию
    pid();
  }

  if (digitalRead(start_in) == 1 ) // 1команда на отключение движка - 1  значит импульс старта пришел с дистанционного управления <--- тут определяется полярность импульса запуска
  {
    do_shutdown();
    digitalWrite(ledPin, LOW);                      //выключаем светодиод индикации режима включения автоподсоса
  }


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


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

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


    if (millis() > last_start_time + ENGINE_WARM_TIME) // если текущее время больше чем время старта + время прогрева
    {
      digitalWrite(ledPin, LOW);                      //выключаем светодиод индикации режима включения автоподсоса
      do_shutdown();
      left_start_try = 0; // и больше не заводим
    }
  }
}



void do_shutdown()
{
  ataches();
  otkluchenie();
  digitalWrite(secpower_out, LOW); //выключаем печку фары итд
  delay(1000);
  digitalWrite(ledPin, LOW);                      //выключаем светодиод индикации режима включения автоподсоса
  digitalWrite(engine_out, LOW); //вырубаем зажигание
  actual_mode = 0;  // движок выключили запомним это
  last_start_time = 0; // ну и забудем о том что он был включен
  //---------------------------управление сигналкой при активации раскомментировать-----------------------
 // digitalWrite(outpinSigOn, HIGH);//сигнал включения сигналки
  //delay(1000);//удержание 1 сек
 // digitalWrite(outpinSigOn, LOW);// сброс сигнала включения
 //------------------------------------------------------------------------------------------------------
  delay(3000);
  
}


void set_status_led()
{
  if (digitalRead(hand_brake_in) != hand_brake_on  ) //Если ручник не стоит то выкл светодиод нечего ему в пути мигать попусту
  {
    digitalWrite(status_out, LOW);
    return; //прерываем выполнение функции
  }

  if (actual_mode ==  2) //Движок запущен
    status_led_flash(); // показываем с какой попытки был прошлый запуск
  else
    digitalWrite(status_out, HIGH); // постоянное свечение - показываем что готов к следующему запуску

}



void status_led_flash()
{
  static unsigned long big_interval = 0;
  static unsigned long flash_interval = 0;
  unsigned long flash_count = 0;
  flash_count = 3 - left_start_try;  //сколько раз мигать


  //1 секндный интервал
  if (millis() > flash_interval + 1000L)
    flash_interval = millis() ; //задаем счетчие от 0 до 1 секунды

  //задаем 6 секунд
  if (millis() > big_interval + 6000L)
  {
    big_interval = millis() ;  //задаем счетчие от 0 до 10секунд
    flash_interval = big_interval;
  }



  if (millis() <  big_interval +  flash_count * 1000L) // делим 6 секндный интервал на два периода, в первый мигаем количество раз соответствующее числу израсходованных попыток
  { //мигает
    if (millis() > flash_interval + 500L)
      digitalWrite(status_out, HIGH);
    else
      digitalWrite(status_out, LOW);

  }
  else
  { // негорит
    digitalWrite(status_out, LOW); //set digital 0
  }
}

//************************************измеряем частоту на входе тахометра по прерыванию***********
void tahometr()
{
  th = ((60000000 / ( micros() - micros_th)) / 2);   //считаем об/мин
  micros_th = micros();                             // присваиваем новое значение от пришедшего импульса
  tz = 10;                                         //
}

void ataches()   //**********************функция отключения и повторного включения сервопривода***************************
{
  myservo.detach();                                 //отключаемся
  delay(3);                                        //ждем 3 мс
  myservo.attach(9);                             //подключаемся
  delay(3);                                     //ждем 3 мс
}

void servo_start() {
  val = analogRead(sensorPin);
  myservo.attach(9, 630, 2500);                     //подключаем серву на 9 цифровом пине с заданным  углом концевых положений
  val = map(val, 0, 1023, 0, 180);                 //устанавливаем серво в положение соответствующее температуре двигателя.преобразуем темпер в положение сервы
  myservo.write(val);                             //              поворачиваем серву в расчинанное положение
  delay(2000);                                   //задерка 3 секунды для стабилизации сервы.
  digitalWrite(ledPin, HIGH);        //подаем на 12 цифровой пин +5 и включаем светодиод режима включения автоподсоса
  myservo.detach();
}


void pid() {
  digitalWrite(ledPin, HIGH);                        //зажигаем светодиод индикации автоподсоса
  Input = th;                                       //читаем на вход ПИД-регулятора обороты двигателя
  myPID.Compute();                                 //считаем выходной сигнал ПИД-регулятора
  myservo.attach(9, 630, 2500);                   //включаем серву на 3 цифровом пине, с длинной импульса от 630 до 2540(указываем границы поворота сервы)
  delay(10);                                   //задержка 10 мс
  if (revers)                                    //если пид регулятор обратный, то сервой управляем также относительно противоположной крайней точки
    myservo.write(180 - Output);                  //
  else                                         //если регулятор прямой то,
    myservo.write(Output);                      //крутим серву от 0 до 180
  delay(10);                                 //ждем серву 10 мс
  myservo.detach();                         //отключаемся от сервы
  if (val < 1000 && val > 750 && th >= 750) //если температура менее 85 но более 60 и обороты больше или ровны 750 об/мин то,
  {
    digitalWrite(pech, HIGH);               //включаем на пине 8 печку автомобиля
  }

}

void otkluchenie() {
  digitalWrite(pech, LOW);                         //выключаем печку
  digitalWrite(ledPin, LOW);                      //выключаем светодиод индикации режима включения автоподсоса
  myservo.write(180);                         //
  {
    delay(5);
  }                                   //замедляем серву
  delay(1500);
  myservo.detach();                         //отключаемся от сервы
  delay(10);                              //задержка0,001 секунда

}
//**************************контроль заряда аккумулятора телефона***********************
void zaradAkkum() {
  float sensorVoltage = analogRead(sensorZarad);
  sensorVoltage = sensorVoltage * 0.0048828125;
  if (sensorVoltage <= 3.40) {
    digitalWrite(outpinZarad, HIGH);
  }
  if (sensorVoltage >= 4.20) {
    digitalWrite(outpinZarad, LOW);
  }
  delay(1);
  // Serial.println(sensorVoltage);//для тестов. вывод напряжения акб на монитор
}


void zapuskKnopka() {
  if (digitalRead(sharging_in) != sharging_on  )           // проверяем что генератор не работает
  {
    digitalWrite(engine_out, HIGH);                        //включаем зажигание
    delay(10);
    ataches();
    servo_start();

    //----------------------------------------------------------------------------------- цикл стартера
    digitalWrite(starter_out, HIGH);                      //включаем стартер
    for (int secs = 0; secs <= ENGINE_START_MAX_TIME ; secs++) //
    {
      delay(1000);                                        // и продолжаем его держать включенным 1 секунду
      if (digitalRead(sharging_in) == sharging_on)        //если зарядка пошла то
        break;                                     // прерываем цикл
    }
    //-----------------------------------------------------------------------------------
    digitalWrite(starter_out, LOW);                       //отключаем стартер
    delay(1000); //временно
    if (digitalRead(sharging_in) == sharging_on)          //еще раз смотрим что  зарядка пошла
    {

      ataches();
      myservo.write(180);                            //
      {
        delay(5);
      }                                 //замедляем серву
      delay(1500);
      myservo.detach();                             //отключаемся от сервы
      delay(10);                                    //задержка0,001 секунда
      digitalWrite(secpower_out, HIGH);             //включаем  фары итд

    }
    else {
      digitalWrite(secpower_out, LOW);             //выключаем  фары
      digitalWrite(engine_out, LOW);               //выключаем зажигание
    }

  }
  else {
    digitalWrite(secpower_out, LOW);                 //выключаем  фары итд
    delay(1000);
    digitalWrite(pech, LOW);                         //выключаем печку
    delay(1000);
    digitalWrite(ledPin, LOW);                       //выключаем светодиод индикации режима включения автоподсоса
    delay(1000);
    digitalWrite(engine_out, LOW);                   //выключаем зажигание
  }
}