Автозапуск, первый проект

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Первый проект на Ардуино Автозапуск

Здравствуйте.

Первый боле-мене серьезный проект на Ардуино, слизанный на http://compcar.ru/forum/showthread.php?t=9812&highlight=%C0%E2%F2%EE%E7%E0%EF%F3%F1%EA+%E0%F0%E4%F3%E8%ED%EE+nano  и доработанный под свои требования. Ардуино появилась недавно …. Програмированием ни когда не занимался. Потихоньку разобрался с примерами из учебника. И вот что получилось (сильно не пинайте).Из оригинала удалено все относящееся к запуску по температуре (я не сторонник этого). На макетке заработало. Размышляя над помехозащишенностью сотовой связи, вспомнил о DTMF. На просторах интернета можно найти что угодно. Пошныряв по форумам понял что самостоятельно програмно этот вопрос не решу. DTMF-декодеров в нашем стольном граде Тамбовской губернии отродясь ни кто не видел. Схема нарисована для МТ8870 но применять наверное буду готовый http://ru.aliexpress.com/item/Free-shipping-1pcs-MT8870-DTMF-Voice-decoding-module-phone-module/32275055977.html (была распродажа, обошелся на порядок дедешевле). После вечера за компьютером скеч заработал на макетке. Алгоритм постановки на автозапуск описан в вышеупомянутой теме форума "компкара" Улучшать вроде есть что …… и добавлять тоже ……. Схема не очень то получилась ...... Но я первый раз на этом форуме ....... Научусь....

//Настройки 
unsigned long ENGINE_WARM_TIME = 600000; //В миллисекундах время работы мотора после запуска 600000 миллисекунд = 10 минут
int ENGINE_START_MAX_TIME = 2; //В секундах масимальное время работы стартера
//--------------выбор пинов ардуины по входу---------------------------------------------
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 = 1; //  0= поднятый датчик ручника замыкает на массу тормоз активен (жигули), 1= датчик ручника в поднятом состоянии выдает высокий уровень напряжения 
// --------------выбор пинов ардуины по выходу---------------------------------------------
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 с третьей int valu = 0;  // переменные состояния входов сигнала DTMF
//переменные входов двоичного сигнала DTMF
int valu = 0;
int vali = 0;
int valo = 0;
int valp = 0; 
//переменная для фактического режима
int actual_mode = 0; //  2 двигатель начал работать 
int left_start_try = 0;  // переменная для хранения остатка числа попыток запуска 
unsigned long last_start_time = 0; //время в тысячных секунды когда был запущен движок 
void setup() {
//---- настройка входов и выходов контроллера --------------  
// init selected pins
  pinMode(hand_brake_in, INPUT); // enable input 
  digitalWrite(hand_brake_in, HIGH); //если подтяжка реализована аппаратно то тут ненадо
 pinMode(start_in, INPUT); // enable input 
//  digitalWrite(start_in, HIGH); //pullup resustor enable
  pinMode(sharging_in, INPUT); // enable input 
//  digitalWrite(sharging_in, LOW); //generator LOW normaly
//     это для DTMF
  pinMode(10, OUTPUT);   // 10 пин  -  выход команды старта
  pinMode(A0, INPUT);  // пины  - вход с декодера DTMF
  pinMode(A1, INPUT); // подтянуть к "-" 10кОм (ежели треба)
  pinMode(A2, INPUT);
  pinMode(A3, INPUT); 
// init outputs
pinMode(11, OUTPUT); // enable output
  digitalWrite(11, LOW); //set digital 0
//************реле обходчика***************  
 pinMode(12, OUTPUT); // enable output
 digitalWrite(12,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(9600);
}
void loop()
{
  //---- собственно это и есть весь код программы --------------
if (actual_mode < 2 )    //если двигатель не запущен
    {
        check_start();  //Управляем режимом запуска
           }
//код условия обязательно включать в фигурные скобки если должно быть выполнено несколько инструкций, в данном случае одна, поэтому скобки опущены            
else   // иначе
        {
        check_for_shutdown(); //Управляем режимом ожидания окончания прогрева
        } //но хорошая привычка фигурные скобки ставить всегда     
 set_status_led(); //независимо от режима Управляем светодиодом статуса 
  //------------------конец основного кода -----------------
 }
  //---- дальше идут используемые функции и подфункции -------------- 
void check_start() 
{
// опрашиваем входы 
  vali = digitalRead(A0);
  valu = digitalRead(A1);
  valo = digitalRead(A2);
  valp = digitalRead(A3);
  if ((vali == 0)&&(valu == 0)&&(valo == 1)&&(valp == 1)){ //цифра старта в двоичном коде
    digitalWrite(10, 1);  //при высоком уровне даём команду на старт 
  } else 
    {digitalWrite(10, 0);
    delay(1000);
    }
 if (digitalRead(hand_brake_in) != hand_brake_on) //без ручника не делаем запуск
    {
      actual_mode = 2; // заканчиваем попытки запустить движок
      left_start_try = 0; //без ручника другие попытки бесполезны
      return;  
    }
 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(12,HIGH);//включаем реле обходчика
    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); //включаем печку фары итд
 //   delay(3000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление 
    digitalWrite(secpower_out, LOW); //выключаем печку фары итд
//----------------------------------------------------------------------------------- цикл стартера 
    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
    {
      digitalWrite(engine_out, LOW);   //выключаем зажигание чтбы разблокировать реле стартера
      digitalWrite(secpower_out, LOW); //выключаем печку фары итд
      delay(5000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление
    }
} 
void check_for_shutdown() 
{
//сюда мы попадаем когда контроллер считает что движок работает
    if (digitalRead(sharging_in) != sharging_on  ) //проверяем что движок случайно не заглох
          do_shutdown();
    else 
{
          digitalWrite(secpower_out, HIGH); //включаем печку фары итд
    digitalWrite(11,LOW);
    digitalWrite(12,LOW);
}
    if (digitalRead(hand_brake_in) != hand_brake_on  ) //проверяем что если злодеи сняли с ручника то глушим мотор
      {
         do_shutdown();
         left_start_try =0; // и больше не заводим
      }
//тут будем контролировать чтоб если забыли машинку заведенной она не молотила до скончания бензобака а выключалась через какоето время
    if (actual_mode != 0  ) //значит не выключили заглохший двигатель только что 
    {
      if (millis() > last_start_time+ENGINE_WARM_TIME)  // если текущее время больше чем время старта + время прогрева
         {
         do_shutdown();
         left_start_try =0; // и больше не заводим
         }
    }
 }

void do_shutdown()
{
        digitalWrite(secpower_out, LOW); //выключаем печку фары итд 
        digitalWrite(11,LOW);
        digitalWrite(12,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 
  }
}

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Обработал немного схему

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

А чего строб с 8870 не используется? Как определить, что пришёл код DTMF?

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015
  Выходы декодера отслеживаются постоянно. А дальше  
  / опрашиваем входы 
  vali = digitalRead(A0);
  valu = digitalRead(A1);
  valo = digitalRead(A2);
  valp = digitalRead(A3);
  if ((vali == 0)&&(valu == 0)&&(valo == 1)&&(valp == 1)){ //цифра старта в двоичном коде
    digitalWrite(10, 1);  //при высоком уровне даём команду на старт 
  } else 
    {digitalWrite(10, 0);
    delay(1000);
    }
 if (digitalRead(hand_brake_in) != hand_brake_on) //без ручника не делаем запуск
    {
      actual_mode = 2; // заканчиваем попытки запустить движок
      left_start_try = 0; //без ручника другие попытки бесполезны
      return;  
    }
 if (digitalRead(start_in) == 1 && left_start_try == 0) // 1 is command for start  - 1  значит импульс старта пришел с дистанционного управления <--- тут определяется полярность импульса запуска
  {
 
Я ж в програмировании пока дуб дубом...... Это слеплено из двух исходников .....
kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Дело Ваше, куда проще по стробу считать полученный код. Надёжно и без зависимости от цикла опроса, который будет плавать. Плюс надежное считывание.

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Понял . Спасибо. Буду в этом напрвлении упрощать-улучшать.

Прошу прощения . Нашел "оригинал" на этом форуме .   http://arduino.ru/forum/proekty/kotntroller-distantsionnogo-progreva-avt... .  Как перебраться в тему не знаю.

verxniy
Offline
Зарегистрирован: 25.01.2015

подскажите, пожайлуйста, форумчане, как реализрвать контроль запуска двигателя от сигнала тахометра или от датчика положения коленвала? в -17 заряд от генератора поступает схема считает запустился, а двигатель не успевает схватывать!

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

Лампочка  заряда гаснет ещё при стартере? А  давление масла ? Самое простое - переключиться к той лампочке которая гарантировано гаснет только после пуска двигателя. Тахометр - интересно, но времени пока нет заниматься...... 

verxniy
Offline
Зарегистрирован: 25.01.2015

стартер в мороз крутит так, что поднимается давление и начинает идти заряд аккумулятора. двигатель соответственно не заводится , а схема считает, что запуск произошел!

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

прикольненько, а что на счет того чтоб еще и сигналку оттключать во время пуска. датчик удара то еще никто не отменял? да и реле блокировки не у всех одно установленно, у кого то и 2 и три. кстати, есть и готовый скетч оттестированный и специально заточенный под карбюраторные авто с управлением заслонкой сервой и управлением ей же посредством пид

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

#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);                   //выключаем зажигание
  }
}

собственно основа кода взята там же))) 

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

verxniy пишет:

стартер в мороз крутит так, что поднимается давление и начинает идти заряд аккумулятора. двигатель соответственно не заводится , а схема считает, что запуск произошел!

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

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

кстати в этом скетче имеется и запуск и глушение с кнопки. и отключение и включение сиги также посредством телефона. плюс ко всему после поворота ключа и выключения ручнтка включаются ДХО

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

И снова здравствуйте.

Следующий промежуточный скеч. С телефоном обкатал. И завожу и глушу. Шилд DTMF-декодера не дождался. Посему - решено програмно. Блокировка по импульсам датчика скорости примитивная. Пауза на 3600000. На нейтраль геркон прицепится . 

Вроде всё в кучку собралось ....... Осталось звуковую индикацию влепить (на d11) для обратной связи..... Может что нибуть ещё придумать на аналоговые входы ........


Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015
#include <DTMF.h>

//Настройки 
unsigned long ENGINE_WARM_TIME = 600000; //В миллисекундах время работы мотора после запуска 600000 миллисекунд = 10 минут
int ENGINE_START_MAX_TIME = 2; //В секундах масимальное время работы стартера
//--------------выбор пинов ардуины по входу---------------------------------------------
const int speed_sensor_in  = 10;  // датчик скорости
const int speed_sensor_on = 0; 
const int netral_in  = 2;  // контроль нейтрали
const int netral_on = 0;  // при нейтрали замкнуто на массу. 
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= датчик ручника в поднятом состоянии выдает высокий уровень напряжения 
// --------------выбор пинов ардуины по выходу---------------------------------------------
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 с третьей int valu = 0;  // переменные состояния входов сигнала DTMF
// DTMF
int sensorPin = A0; //вход аудио 47кОм на "+" и "-" и 0,1мКФ к телефону
	int start = 13;// пин13-старт
	float n=128.0;
	float sampling_rate=8926.0;
	DTMF dtmf = DTMF(n,sampling_rate);
int nochar_count = 0;
	float d_mags[8];
//переменная для фактического режима
int actual_mode = 0; //  2 двигатель начал работать 
int left_start_try = 0;  // переменная для хранения остатка числа попыток запуска 
unsigned long last_start_time = 0; //время в тысячных секунды когда был запущен движок 
void setup() {
//---- настройка входов и выходов контроллера --------------  
// init selected pins
  pinMode(speed_sensor_in, INPUT);
  digitalWrite(speed_sensor_in, HIGH);  //если подтяжка реализована аппаратно то тут ненадо
  pinMode(netral_in, INPUT);
  digitalWrite(netral_in, HIGH);  //если подтяжка реализована аппаратно то тут ненадо
  pinMode(hand_brake_in, INPUT); // enable input 
  digitalWrite(hand_brake_in, HIGH); //если подтяжка реализована аппаратно то тут ненадо
  pinMode(start_in, INPUT); // enable input 
//  digitalWrite(start_in, HIGH); //pullup resustor enable
  pinMode(sharging_in, INPUT); // enable input 
//  digitalWrite(sharging_in, LOW); //generator LOW normaly
//     это для DTMF
  pinMode(start, OUTPUT);
	//  pinMode(stopp, OUTPUT); 
int nochar_count = 0;
	float d_mags[8];
// init outputs
//pinMode(11, OUTPUT); // enable output
 // digitalWrite(11, LOW); //set digital 0
//************реле обходчика***************  
 pinMode(12, OUTPUT); // enable output
 digitalWrite(12,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(9600);
}
void loop()
{
  //---- собственно это и есть весь код программы --------------
  {
	  char thischar;
	  /* while(1) */dtmf.sample(sensorPin);
	  dtmf.detect(d_mags,506);
	  thischar = dtmf.button(d_mags,1800.);
	  if(thischar) {
	    if(thischar=='5')digitalWrite(start, HIGH); // доп.5 набора - стартуем
	    if(thischar=='9')(ENGINE_WARM_TIME = 0); // доп.9 набора -  время работы мотора "0"
	  } 
  }
if (actual_mode < 2 )    //если двигатель не запущен
    {
        check_start();  //Управляем режимом запуска
           }          
else   // иначе
        {
        check_for_shutdown(); //Управляем режимом ожидания окончания прогрева
        }      
 set_status_led(); //независимо от режима Управляем светодиодом статуса 
  //------------------конец основного кода -----------------
 }
  //---- дальше идут используемые функции и подфункции -------------- 
void check_start() 

 { 
 if (digitalRead(hand_brake_in) != hand_brake_on) //без ручника не делаем запуск
      {
      actual_mode = 2; // заканчиваем попытки запустить движок
      left_start_try = 0; //без ручника другие попытки бесполезны
      return;  
    }
  if (digitalRead(netral_in) != netral_on) // без нейтрали - тоже
    {
      actual_mode = 2; // заканчиваем попытки запустить движок
      left_start_try = 0; //без ручника другие попытки бесполезны
      return;  
    }
 if (digitalRead(start_in) == 1 && left_start_try == 0) // 1 is command for start  - 1  значит импульс старта пришел с дистанционного управления <--- тут определяется полярность импульса запуска
  {
   left_start_try = 3;   // указываем что нужно попытаться трижды запустить движок
  } 
  digitalWrite(start, LOW);
 if ( left_start_try > 0 )   
 {  digitalWrite(12,HIGH);//включаем реле обходчика
    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(netral_in) != netral_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); //включаем печку фары итд
 //   delay(3000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление 
    digitalWrite(secpower_out, LOW); //выключаем печку фары итд
//----------------------------------------------------------------------------------- цикл стартера 
    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
    {
      digitalWrite(engine_out, LOW);   //выключаем зажигание чтбы разблокировать реле стартера
      digitalWrite(secpower_out, LOW); //выключаем печку фары итд
      delay(2000); // останавливаем код на 2 секунды 
    }
}
void check_for_shutdown() 
{
//сюда мы попадаем когда контроллер считает что движок работает
    if (digitalRead(sharging_in) != sharging_on  ) //проверяем что движок случайно не заглох
          do_shutdown();
    else 
{
          digitalWrite(secpower_out, HIGH); //включаем печку фары итд
    digitalWrite(12,LOW);
}
     if (digitalRead(speed_sensor_in) != speed_sensor_on  ) //по первому импульсу датчика скорости глушим мотор
    {
         do_shutdown();
         left_start_try =0; // и больше не заводиv
           delay(3600000); //и ВААЩЕ не скоро заведёшь.....
      }
    if (digitalRead(hand_brake_in) != hand_brake_on  ) //проверяем что если злодеи сняли с ручника то глушим мотор
    {
         do_shutdown();
         left_start_try =0; // и больше не заводим
      }
    if (digitalRead(netral_in) != netral_on) // если скорость включили - тоже
      {
         do_shutdown();
         left_start_try =0; // и больше не заводим
      }
    
//тут будем контролировать чтоб если забыли машинку заведенной она не молотила до скончания бензобака а выключалась через какоето время
    if (actual_mode != 0  ) //значит не выключили заглохший двигатель только что
    {
      if (millis() > last_start_time+ENGINE_WARM_TIME) // если текущее время больше чем время старта + время прогрева
         {
         do_shutdown();
         ENGINE_WARM_TIME = 600000; // после команды остановки востанавливаем время работы мотора(для пследующих запусков)
         left_start_try =0; // и больше не заводим
         }
    }
 }

void do_shutdown()
{
        digitalWrite(secpower_out, LOW); //выключаем печку фары итд 
        digitalWrite(12,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
     //в противном случае моргаем раз в 4 сек.- гоовность к запуску
{
static unsigned long big_interval = 0;
static unsigned long flash_interval = 0;
//задаем 4 секунды 
if (millis() > big_interval + 4000L)
     {
      big_interval = millis() ;  //задаем счетчие от 0 до 4секунд
      flash_interval = big_interval;
     }
  { //мигает 
    if (millis() > flash_interval + 500L) 
      digitalWrite(status_out, LOW);
    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 
  }
}

 

verxniy
Offline
Зарегистрирован: 25.01.2015

Нужна помощь! Какой код необходимо и в каком месте прописать , чтобы когда запускался код поступал сигнал на один из выходов и по окончании как двигло прогрелось- пропадал? Очень нужно!

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

"чтобы когда запускался код поступал сигнал на один из выходов и по окончании как двигло прогрелось- пропадал? Очень нужно!"

Непонятно......  

Что бы запускался код? ....Или когда запуститься двигатель?.... Двигатель прогрелся ?...... Или выключился (по истечении заданного времени) ?......

Если очень нужно - возьмите с одного из сигналов включения зажигания.  Появляется по команде запуска , пропадает при выключении двигателя.

Температура двигателя в вышеприведенных скетчах не контролируется.

jonili70
Offline
Зарегистрирован: 24.02.2015

Здравсвтуйте, помогите новичку, как вписать в код программы, чтобы перед тем как завестись, авто синмалось с охраны, а потом обратно после того как заведется?  И как это все оформить в электронике авто?

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

jonili70 пишет:

Здравсвтуйте, помогите новичку, как вписать в код программы, чтобы перед тем как завестись, авто синмалось с охраны, а потом обратно после того как заведется?  И как это все оформить в электронике авто?

ответ в 10 посте в готовом виде. подключение посредством двух реле и лишнего пульта брелока.

 

Pnewmoslon
Offline
Зарегистрирован: 26.07.2014

Андрей1963 пишет:

"чтобы когда запускался код поступал сигнал на один из выходов и по окончании как двигло прогрелось- пропадал? Очень нужно!"

Непонятно......  

Что бы запускался код? ....Или когда запуститься двигатель?.... Двигатель прогрелся ?...... Или выключился (по истечении заданного времени) ?......

Если очень нужно - возьмите с одного из сигналов включения зажигания.  Появляется по команде запуска , пропадает при выключении двигателя.

Температура двигателя в вышеприведенных скетчах не контролируется.

не

"Температура двигателя в вышеприведенных скетчах не контролируется." не могу согласиться. изучите так же скетч из 10 поста.

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

В коде http://arduino.ru/forum/proekty/kotntroller-distantsionnogo-progreva-avt...  контролируется . В Вашем наверное тоже(на досуге посмотрю). В моих  -  нет.

Пост 1 -  "....Из оригинала удалено все относящееся к запуску по температуре (я не сторонник этого)......".

Пост 19 - Прошу прощения   -   "..... Температура двигателя в вышеприведенных МОИХ скетчах не контролируется....."

intek
Offline
Зарегистрирован: 03.11.2014

Здравствуйте форрумчане, собираюсь сделать что-то вроде такого же. Каким образом ардуинка понимает, что двигатель завелся?

 

intek
Offline
Зарегистрирован: 03.11.2014

Написал корявенький алгоритм, но не знаю как реализовать некоторые функции

алгоритм должен проверять датчик скорости и таходатчик, сигнал с которых идет импульсныйю Если есть какие предложения, как это  в коде можно это сделать или аппаратно посоветуйте.

 

intek
Offline
Зарегистрирован: 03.11.2014

Андрей1963
Андрей1963 аватар
Offline
Зарегистрирован: 24.01.2015

 

Здравствуйте форрумчане, собираюсь сделать что-то вроде такого же. Каким образом ардуинка понимает, что двигатель завелся?

   155 |  if (digitalRead(sharging_in) == sharging_on) //если зарядка пошла то

 

intek
Offline
Зарегистрирован: 03.11.2014

Спасибо, а по остальному может есть у кого предложения?

 

Controler
Offline
Зарегистрирован: 08.05.2015

А как добавить функцию питстопа?

Можно также добавить функцию, если машина завелась, то происходит дозвон на сотку.

pony
Offline
Зарегистрирован: 11.09.2015

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

сильно не пинайте, в коде пока не особо,учусь изучаю. 

 

 


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

//--------------выбор пинов ардуины по входу---------------------------------------------
const int netral_in  = 7;  // контроль нейтрали
const int hand_brake_in  = 6;  // adruino Контакт стояночного тормоза "-"
const int start_in  = 16;  // adruino Сигнал команды на старт от мобильного телефона вибра звонка
const int startstop_in  = 15;  //запуск двигателя при нажатии педали тормоз
const int sharging_in  = 10;  // adruino индикатор работы двигателя

const int netral_on = 0;  // при нейтрали замкнуто на массу.
const int sharging_on = 0; // 0 когда во время работы генератора или от датчика давления масла на этом входе низкое состояние , 1 когда на лампе генератора при работе генератора высокое состояние
const int hand_brake_on = 0; //  0= поднятый датчик ручника замыкает на массу тормоз активен (жигули), 1= датчик ручника в поднятом состоянии выдает высокий уровень напряжения 
const int startstop_on  = 0;  // 0= при нажатии педали тормоз замкнуто на массу, 1 при нажатии пллюс
// --------------выбор пинов ардуины по выходу---------------------------------------------
const int obhodchik_out  = 5;  // adruino реле обходчика
const int engine_out  = 3;  // adruino зажигание
const int starter_out  = 2;  // adruino реле стартера
const int secpower_out  = 4;  // цепи вторичного питания печка, фары итд
const int status_out  = 14;  // светодиод статуса системы  горит = система готова к работе(включена, ручник стоит). одно мигание запущен с первой попытки 2 со второй 3 с третьей 
                            //светодиод подключать с этого пина на массу
//переменная для фактического режима
int actual_mode = 0; //  2 двигатель начал работать
int left_start_try = 0;  // переменная для хранения остатка числа попыток запуска
unsigned long last_start_time = 0; //время в тысячных секунды когда был запущен движок
void setup() {

//---- настройка входов и выходов контроллера -------------- 
// настраиваем входы
pinMode(netral_in, INPUT); // enable input
digitalWrite(netral_in, HIGH); //если подтяжка реализована аппаратно то тут ненадо

pinMode(hand_brake_in, INPUT); // enable input
digitalWrite(hand_brake_in, HIGH); //если подтяжка реализована аппаратно то тут ненадо


pinMode(start_in, INPUT); // enable input
//  digitalWrite(start_in, HIGH); //pullup resustor enable

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

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


// настраиваем выходы
//************реле обходчика***************
pinMode(obhodchik_out, OUTPUT); // enable output
digitalWrite(obhodchik_out,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(9600);
}
void loop()
{
//---- собственно это и есть весь код программы --------------
if (actual_mode < 2 )    //если двигатель не запущен
{
check_start();  //Управляем режимом запуска
}
//код условия обязательно включать в фигурные скобки если должно быть выполнено несколько инструкций, в данном случае одна, поэтому скобки опущены
else   // иначе
{
check_for_shutdown(); //Управляем режимом ожидания окончания прогрева
} //но хорошая привычка фигурные скобки ставить всегда 
set_status_led(); //независимо от режима Управляем светодиодом статуса
//------------------конец основного кода -----------------
}
//---- дальше идут используемые функции и подфункции --------------
void check_start()

{
if (digitalRead(hand_brake_in) != hand_brake_on) //без ручника не делаем запуск
{
actual_mode = 2; // заканчиваем попытки запустить движок
left_start_try = 0; //без ручника другие попытки бесполезны
return;
}
if (digitalRead(netral_in) != netral_on) // без нейтрали - тоже
{
actual_mode = 2; // заканчиваем попытки запустить движок
left_start_try = 0; //без ручника другие попытки бесполезны
return;
}
if (digitalRead(start_in) == 1 && left_start_try == 0) // 1 is command for start  - 1  значит импульс старта пришел с дистанционного управления <--- тут определяется полярность импульса запуска
{
left_start_try = 3;   // указываем что нужно попытаться трижды запустить движок
}
digitalWrite(start_in, LOW);
if ( left_start_try > 0 )
{  
digitalWrite(obhodchik_out,HIGH);//включаем реле обходчика
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(netral_in) != netral_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); //включаем печку фары итд
//   delay(3000); // останавливаем код на 3 секунды чтобы бензонасос набрал давление
digitalWrite(secpower_out, LOW); //выключаем печку фары итд
//----------------------------------------------------------------------------------- цикл стартера
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
{
digitalWrite(engine_out, LOW);   //выключаем зажигание чтбы разблокировать реле стартера
digitalWrite(secpower_out, LOW); //выключаем печку фары итд
delay(2000); // останавливаем код на 2 секунды
}
}
void check_for_shutdown()
{
//сюда мы попадаем когда контроллер считает что движок работает
if (digitalRead(sharging_in) != sharging_on  ) //проверяем что движок случайно не заглох
do_shutdown();
else
{
digitalWrite(secpower_out, HIGH); //включаем печку фары итд
digitalWrite(obhodchik_out,LOW);
}
if (digitalRead(hand_brake_in) != hand_brake_on  ) //проверяем что если злодеи сняли с ручника то глушим мотор
{
do_shutdown();
left_start_try =0; // и больше не заводим
}
if (digitalRead(netral_in) != netral_on) // если скорость включили - тоже
{
do_shutdown();
left_start_try =0; // и больше не заводим
}

//тут будем контролировать чтоб если забыли машинку заведенной она не молотила до скончания бензобака а выключалась через какоето время
if (actual_mode != 0  ) //значит не выключили заглохший двигатель только что
{
if (millis() > last_start_time+ENGINE_WARM_TIME) // если текущее время больше чем время старта + время прогрева
{
do_shutdown();
ENGINE_WARM_TIME = 600000; // после команды остановки востанавливаем время работы мотора(для пследующих запусков)
left_start_try =0; // и больше не заводим
}
}
}

void do_shutdown()
{
digitalWrite(secpower_out, LOW); //выключаем печку фары итд
digitalWrite(obhodchik_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
//в противном случае моргаем раз в 4 сек.- гоовность к запуску
{
static unsigned long big_interval = 0;
static unsigned long flash_interval = 0;
//задаем 4 секунды
if (millis() > big_interval + 4000L)
{
big_interval = millis() ;  //задаем счетчие от 0 до 4секунд
flash_interval = big_interval;
}
{ //мигает
if (millis() > flash_interval + 500L)
digitalWrite(status_out, LOW);
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
}
}


 

 

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

Pnewmoslon пишет:

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

#
    digitalWrite(engine_out, LOW);                   //выключаем зажигание
  }
}

собственно основа кода взята там же))) 

он не обработает такое количество информации. CPU загружается и умирает на первой секунде когда ставишь на ручник))) ну это симулировал в ПРОТЕУСе. может в реале справится.  

constantinoff
Offline
Зарегистрирован: 27.12.2015

Я собираюсь делать то же самое. Заказал Арду нано, стабилизатор и блок реле из четырёх реле. Но у моего телефона не будет батарейки, от сюда вопрос как добавить в скетч и куда строку в которой Андуин будет включать телефон по средством включения реле на 2 секунды?

constantinoff
Offline
Зарегистрирован: 27.12.2015

И ещё вопрос про DTMF. В предложенной вами схеме процесс будет выглядеть так- звонишьтна телефон, на нем срабатывает автоподнятие, дальше набираешь комбинацию клавишь, и декодер разбирает тональности и при правильной тональности, а следовательно правильной последовательности нажатия кнопок, даёт команду на запуск? Я правильно все понял?

Slavyanin55
Slavyanin55 аватар
Offline
Зарегистрирован: 01.06.2014

Такое устройство есть у старлайна называется Starline M21 стоит сейчас правда 5900р.

constantinoff
Offline
Зарегистрирован: 27.12.2015

На Али экспрессе модуль dtmf для ардуино стоит 200 рублей.

constantinoff
Offline
Зарегистрирован: 27.12.2015

5900 и 200 почувствуйте разницу

constantinoff
Offline
Зарегистрирован: 27.12.2015
constantinoff
Offline
Зарегистрирован: 27.12.2015

есть тут знающие люди, которые могу допилть код? Кто нибудь уже собираль натуральную модель с DTMF?

constantinoff
Offline
Зарегистрирован: 27.12.2015

пока жду от вас ответов дорогие форумчане, напишу о своих представлениях по поводу работы данного девайса.

1. Необходимо прикрутить DTMF к нему и аппаратно и програмно, с возможностью, при нажатии к примеру кнопки 1 во всемя разговора, завести двигатель, а нажатием кнопки 2 заглушить. Сейчас есть у каждого оператора тарифы с бесплатными исходящими внутрисетевыми звоками.

http://ru.aliexpress.com/item/wholesale-1pcs-MT8870-DTMF-Voice-decoding-...

2. Готовить релейный блок самому смысла не вижу, на алиэкспресе за 200 рублей есть готовый релейный модуль с 4 реле на борту, которые вполне подойдут для включения двух положений зажигания, стартера и имобилайзера.

http://ru.aliexpress.com/item/Free-Shipping-1PCS-LOT-5V-4-Channel-Relay-...

3. GSM модуль покупать смысла не вижу, так как у каждого дома есть какой нибудь старый телефон который не жалко использовать под эти цели.

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

http://ru.aliexpress.com/item/New-Arrival-LM2596-Power-Module-DC-DC-Buck...

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

fyodor.m
Offline
Зарегистрирован: 28.12.2015

Здравствуйте, Хотел бы предостеречь Вас от использования релейного блока с али.

Я пробовал использовать такой на предыдущей своей версии автозавода. 

Эти реле  оказались слабоваты.  На моем солярисе  фары ключаются сразу.

Вот и посчитайте фары, печка, уменя еще обогрев сидений был задействован. ампер 20-30 спокойно наберется.

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

http://ru.aliexpress.com/item/NEW-6PCS-Relay-T91-SLC-12VDC-SL-C-relay-12V-30A-250V/1848191813.html

Можете посмотреть в моей теме здесь.

 

constantinoff
Offline
Зарегистрирован: 27.12.2015

Спасибо за совет. У меня проблема. Пока я жду все запчасти, я прибывал запустить виртуальный Арду нано на протеусе. Но почему то у меня не работают скетчи которые тут выложены. После команды на старт только зажигание включается и все. Не могли бы вы свой скетч мне скинуть. Заранее спасибо.

fyodor.m
Offline
Зарегистрирован: 28.12.2015

Так вот же мой  скетч в этой теме http://arduino.ru/forum/proekty/avtomaticheskii-zapusk-dvigatelya-avtomobilya

Только у меня не используются DTFM команды.  Запуск происходит по звонку. Логика такая позвонил автомобилю он трубку не берет, после второго гудка сбрасываешь, машина начинает пытаться заводиться, если завелась, отзванивается. Хозяин по желанию может взять трубку и послушать, а может не брать, а просто сбросить. Чтобы заглушить двигатель звонишь и  после первого гудка машина глохнет и берет трубку. Сбрасываешь и все. Так же машина отзванивается когда глохнет по времени прогрева. Еще она отзванивается по сигналу от вибродатчика. На протеусе скетч не проверял.

Работает уже два месяца на машине.

 

constantinoff
Offline
Зарегистрирован: 27.12.2015

Спасибо. Буду изучать ваш проект. Если возникнут вопросы можно как то связаться с вами по почте или ватсап? Моя почта. Constantinoff@list.ru. буду признателен если отправите пустое тестовое письмо, для того что бы когда у меня возникнет к вам вопрос я смог связаться с вами.

constantinoff
Offline
Зарегистрирован: 27.12.2015

пытаюсь компелировать ваш скетч и выдает ошибку. У вас не осталось файла скетча? Если вам не трудно не могли бы вы выложить его куда нибудь на файлообменник? Хочу попробывать его на эмуляторе.

Dedushkaserg
Offline
Зарегистрирован: 21.01.2016

Доброго времени суток.

По Вашему коду возник вопрос. Какой датчик температуры Вы использовали?

virskiy
Offline
Зарегистрирован: 08.05.2015

fyodor.m пишет:

Здравствуйте, Хотел бы предостеречь Вас от использования релейного блока с али.

Я пробовал использовать такой на предыдущей своей версии автозавода. 

Эти реле  оказались слабоваты.  На моем солярисе  фары ключаются сразу.

Вот и посчитайте фары, печка, уменя еще обогрев сидений был задействован. ампер 20-30 спокойно наберется.

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

http://ru.aliexpress.com/item/NEW-6PCS-Relay-T91-SLC-12VDC-SL-C-relay-12V-30A-250V/1848191813.html

Можете посмотреть в моей теме здесь.

дешевле в магазине автомобильное реле взять