Arduino Pro Mini+SIM800, дополнение к авто сигнализации с автозапуском.

vic163-163
Offline
Зарегистрирован: 06.03.2018

Добрый день!

     У большинства авто сигнализаций с авто запуском (сигналок) или отдельных модулей автозапуска, имеется дополнительный вход (проводок - pin) для внешнего дистанционного автозапуска прогрева авто. Достаточно этот pin, замкнуть на массу в течении 2 сек. произойдет запуск авто (если соблюдены все условия запуска для авто сигнализации). Если еще один раз замкнуть данный проводок на массу, произойдет принудительная остановка автозапуска авто.

     К авто сигналке был добавлен блок управления из статьи, http://www.rlocman.ru/shem/schematics.html?di=66614, собранный из телефона и обычной логики.

    Было решено сменить элементную базу. За основу взяты скетч и схема, https://github.com/martinhol221/SIM800L_DTMF_control, но с сильно урезанным функционалом.

     Функции модуля Arduino Pro Mini+SIM800 в следующем.

  1. При звонке на устройство, происходит авто ответ и проигрывание Voice(1)  .arm /*жду команду*/ из памяти SIM800 модуля.
  2. При подаче DTMF команды 123 /*start*/, проигрывание Voice(7)  *все поняла завожу*,    

 опрос pin A2 (pin A2 =0, ручник, тормоз), включение pin D12, /*starter*/на время 2 сек., через развязывающий диод и управляющий транзистор (на провод сигналки).

Если запуска не произошло, на А3 не появилась 1 (не включилось зажигание авто),  то проигрывание Voice(6)  (повторный запуск). Значит авто не подготовлено к запуску.

  1. При появлении на pin A3 = 1 (зажигание от авто), проигрывание Voice(5) (*двигатель запущен*)
  2. При подаче DTMF команды 321 (stop), проигрывание Voice(6)  (*стоп прогрева*), включение pin D11=1 (OUT_4) , на время 2 сек. через развязывающий диод и управляющий транзистор (на провод сигналки).
  3. При подаче DTMF команды 789 , блокировка двигателя,  включение pin D8 (OUT_5, блокировка двигателя), проигрывание Voice(8) *двигатель блокирован *). Подача 1 с D8 на D4 (D4 организован как вход IN_7, пока так проще обрабатывать), с IN_7 -D4 на D9 выдает прерывистый сигнал на реле клаксона и дальнего света авто.
  4. При подаче DTMF команды 987 , сброс блокировки двигателя.

      В приведенном скетче никак не могу осуществить;

  Если во время прогрева от arduino, на PSO_Pin - A3 ( зажигание) переключится с 1 на 0 (по какой то причине отключилось зажигание авто или сигналка авто делает следующую попытку запуска) на время

40 сек (приблизительно, все зависит от сигналки) и Feedback_Pin == HIGH - А1 (имитация команды на запуск в arduino, есть прогрев). То нужен сброс прогрева, в скетче arduino (сброс имитации команды прогрева в arduino).

     Необходимо задать время через которое выполнится команда

99.    if (digitalRead(PSO_Pin) == LOW && digitalRead(Feedback_Pin) == HIGH) && PsoTime

и выполнится

 {heatingstop(1);}

 

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

100.    digitalRead(PSO_Pin) == HIGH && digitalRead(Feedback_Pin) == HIGH

 

  В процессе отработки скетча выяснил что millis не сбрасывается, а только останавливается, до следующего изменения на PSO_Pin

    Если можете, ЛЮДИ ДОБРЫЕ, толкните пожалуйста в нужном направлении. Или прочитать как сделать задержку на выполнение команды, приходящей в течении некоторого времени и сброс цикла если время не прошло. Для меня проще поставить внешний 555 таймер, но есть желание дописать скетч.

     Мой полный комплект по ссылке  https://yadi.sk/d/zP5XPeUt3X9qaa

#include <SoftwareSerial.h>
SoftwareSerial SIM800(7, 6);        // для новых плат начиная с версии RX,TX

#define ON           10             // иммитация команды на запуск от arduino, через диод c D10 на A1
#define STARTER      12             // через диод с 12-го пина ардуино и транзистор, на пуск автозапуска сигналки
#define OUT_4        11             // на стоп автозапуска сигналки, через диод с D11 ардуино и транзистор (доп выход для стопа авто сигналки)
#define OUT_5        8              // на реле блокировки двигателя
#define OUT_6        9              // на реле дальнего света и клаксона
#define IN_7         4              // для управления реле дальнего света и клаксона
#define BAT_Pin      A0             // на батарею, через делитель напряжения 39кОм / 11 кОм
#define Feedback_Pin A1             // на A1 через диод с D10, иммитация команды на запуск от arduino
#define STOP_Pin     A2             // на концевик педали тормоза для отключения (на нейтрали запрещения) режима прогрева
#define PSO_Pin      A3             // на провод от замка зажигания, анализ заведенного мотора
#define RESET_Pin    5
#define IN_1         3              // на кнопку обратного звонка, кнопка на массу
#define PsoTime 1000
/*  ----------------------------------------- ИНДИВИДУАЛЬНЫЕ НАСТРОЙКИ !!!---------------------------------------------------------   */
String call_phone= "+79270277340"; // телефон входящего вызова    
float Vstart = 13.50;              // порог распознавания момента запуска по напряжению
String pin = "";                   // строковая переменная набираемого пинкода 
float Vbat, VbatStart, V_min ;     // переменная хранящая напряжение бортовой сети
float m = 69.91;                   // делитель для перевода АЦП в вольты для резистров 39/11kOm
unsigned long Time1, StarterTimeON = 0;
unsigned long Time2;               //для моргания светодиодом с millis, постоянно проходят импульсы с малой скважностью на OUT_6(9pin)
//unsigned long loopTime2;           //для моргания светодиодом с millis,
//unsigned long PsoTime;
//unsigned long PsoTime = 20000;
int Timer = 0;                     // таймер времени прогрева двигателя по умолчанию = 0
int Timer2 = 0;                    // часовой таймер (60 sec. x 60 min. / 10 = 360 )
bool heating = false;              // переменная состояния режим прогрева двигателя
bool ring = false;                 // флаг момента снятия трубки

void(* resetFunc) (void) = 0;

void setup() {
  pinMode(ON,      OUTPUT); 
  pinMode(STARTER, OUTPUT);
  pinMode(OUT_4,   OUTPUT);
  pinMode(OUT_5,   OUTPUT);
  pinMode(OUT_6,   OUTPUT); 
  pinMode(RESET_Pin, OUTPUT);
  pinMode(IN_7, INPUT);     
  pinMode(IN_1, INPUT_PULLUP);        // указываем пин на вход для с внутричипной подтяжкой к +3.3V
  delay(100); 
  Serial.begin(9600);              //скорость порта
//  Serial.setTimeout(50);
  
  SIM800.begin(9600);              //скорость связи с модемом
 // SIM800.setTimeout(500);          // тайм аут ожидания ответа
  
  Serial.println("+call_phone+"); 
  SIM800_reset();
             }
/*  --------------------------------------------------- Перезагрузка МОДЕМА SIM800L ------------------------------------------------ */ 
void SIM800_reset() {  
 delay(2000); SIM800.println("AT+CMGDA=\"DEL ALL\"");  // Удаляем все СМС
}

// обратный звонок при замыкании на массу входа D3, чтобы раз в 3 месяца звонить а то отключат SIM карту
void callback() {      
  SIM800.println("ATD" + call_phone + ";"),    delay(5000);
}
             
void loop() {

if (SIM800.available())  resp_modem();                            // если что-то пришло от SIM800 в Ардуино отправляем для разбора
if (Serial.available())  resp_serial();                           // если что-то пришло от Ардуино отправляем в SIM800
if (millis()> Time1 + 10000) Time1 = millis(), detection();       // выполняем функцию detection () каждые 10 сек 
if (heating == true && digitalRead(STOP_Pin)==1)  heatingstop(1); // если нажали на педаль тормоза в режиме прогрева
if (digitalRead(STOP_Pin)==1) Timer2 = 0 ;                        // если нажали на педаль тормоза в режиме прогрева

       
/*       //моргаем реле дальнего света и клаксона 
         // хотел сделать с millis() но в этом блоке постоянно проходят импульсы с малой скважностью на OUT_6(9pin)
         // так же иногда при прогреве проходит импульс по STARTER (12pin)
 if (digitalRead(IN_7) == LOW) digitalWrite(OUT_6, LOW);  
  {  Time2 = millis();                           // считываем время, прошедшее с момента запуска программы
  if(Time2 >= (loopTime2+500)){              // сравниваем текущий таймер с переменной loopTime2 + 0,5 секунды
    digitalWrite(OUT_6, !digitalRead(OUT_6));     // включаем/выключаем LED знак ! инверсия
    loopTime2 = Time2;}                         // в loopTime записываем новое значение
  }  */
  
    //моргаем реле дальнего света и клаксона. из за delay плохо срабатывает сброс блокировки "987", приходится повторять набор команты     
  if (digitalRead(IN_7)==1) digitalWrite(OUT_6, HIGH), delay (500), digitalWrite(OUT_6, LOW), delay (500);          

}

void detection(){                                                 // условия проверяемые каждые 10 сек  
    
    Vbat = VoltRead();                                            // замеряем напряжение на батарее
    Serial.println ("");
    if (heating == true && Vbat < 11.0 )   heatingstop(1);  // остановка прогрева если напряжение просело ниже 11 вольт 

   //если (PSO_Pin, зажигание) переключился с 1 на 0 (по какой то причине отключилось зажигание авто)
   // и (Feedback_Pin) == HIGH (или heating == true, есть прогрев в arduino). на время больше 40 сек. то нужен сброс прогрева в arduino
   //нужно сбросить ( "уже прогреваюсь" Voice(5)
   
    int  PsoTime  = millis();        //время останавливается, но не сбрасывается, время не всегда одинаковое
    if ((digitalRead(PSO_Pin) == LOW && digitalRead(Feedback_Pin) == HIGH) && PsoTime >= 20000) {heatingstop(1);}
    if (digitalRead(PSO_Pin) == HIGH && digitalRead(Feedback_Pin) == HIGH) {PsoTime = 0;}


/*     if (digitalRead(PSO_Pin) == LOW && digitalRead(Feedback_Pin) == HIGH) ;     //не работает
     {millis() - Time2 > PsoTime;}; 
     if (digitalRead(PSO_Pin) == HIGH && digitalRead(Feedback_Pin) == HIGH);                   
     {Time2 = millis();} ;
 */
     
  
/*    int PsoTime = constrain(PsoTime, 20000, 20000);    
    if ((digitalRead(PSO_Pin) == LOW && digitalRead(Feedback_Pin) == HIGH) && PsoTime > 1) {heatingstop(1);}  //время срабатывания 4 сек, больше не выходит
    if ((digitalRead(PSO_Pin) == HIGH && digitalRead(Feedback_Pin) == HIGH) && PsoTime < 1) {PsoTime = 0;}
*/

}             


void resp_serial (){     // ---------------- ТРАНСЛИРУЕМ КОМАНДЫ из ПОРТА В МОДЕМ ----------------------------------
     String at = "";   
 //    while (Serial.available()) at = Serial.readString();
  int k = 0;
   while (Serial.available()) k = Serial.read(),at += char(k),delay(1);
     SIM800.println(at), at = "";   }

void resp_modem (){     //------------------ НАЛИЗИРУЕМ БУФЕР ВИРТУАЛЬНОГО ПОРТА МОДЕМА------------------------------
     String at = "";
 //    while (SIM800.available()) at = SIM800.readString();  // набиваем в переменную at
  int k = 0;
   while (SIM800.available()) k = SIM800.read(),at += char(k),delay(1);           
   Serial.println(at);  
 
if (at.indexOf("+CLIP: \""+call_phone+"\",") > -1) {delay(200), SIM800.println("ATA"), ring = true;
                                                    
     } else if (at.indexOf("+DTMF: ")  > -1)        {String key = at.substring(at.indexOf("")+9, at.indexOf("")+10);
                                                     pin = pin + key;
                                                     if (pin.indexOf("*") > -1 ) pin= ""; 
 
      } else if (at.indexOf("NO CARRIER") > -1 ) {SIM800.println("AT+CLIP=1;+DDET=1"); // Активируем АОН и декодер DTMF
  } 
    at = "";            // Возвращаем ответ можема в монитор порта , очищаем переменную

       if (pin.indexOf("789") > -1 ){ pin= "", Voice(8), digitalWrite(OUT_5, HIGH), delay (2000), heatingstop(1), SIM800.println("ATH0");  // блокировка двигателя
} else if (pin.indexOf("987") > -1 ){ pin= "", Voice(9), digitalWrite(OUT_5, LOW), delay (2000), SIM800.println("ATH0");  //снятие сблокировки двигателя 
} else if (pin.indexOf("123") > -1 ){ pin= "";
          if (digitalRead(Feedback_Pin) == HIGH)
          {false;}
          else {(digitalRead(Feedback_Pin) == LOW);
          {Voice(7), enginestart(3);}}  // запуск на сигналку  // "све поняла завожу"
} else if (pin.indexOf("321") > -1 ){ pin= "";   // стоп запуска на сигналку
         if (digitalRead(Feedback_Pin) == LOW)  //необходима что бы командой "стоп" не запустить дистанционно двигатель
         {false;}
         else {(digitalRead(Feedback_Pin) == HIGH);
         { Voice(6), digitalWrite(OUT_4, HIGH), delay(2000), heatingstop(1);}}   // "стоп прогрева"
         SIM800.println("ATH0");               
         }

      /*------голосовые сообщения при входящем звонке-----------*/
if (ring == true) { ring = false, delay (2000), pin= ""; // обнуляем пин

   //авто находится в режиме блокирови Voice(8)  
  if (digitalRead(OUT_5) == HIGH) {
    Voice(8);    // "двигатель блокирован"
    }
   //включено зажигание авто и нет прогрева от arduino, (  Voice(10)
  else if (digitalRead(Feedback_Pin) == LOW && digitalRead(PSO_Pin) == HIGH) {
    Voice(10);  // "двигатель уже запущен"
    }
   // "привет жду команду"
  else if (digitalRead(Feedback_Pin) == LOW && digitalRead(OUT_5) == LOW) {
    Voice(1);
    }
    // "уже прогреваюсь"
    else {Voice(5);}
}
}
void enginestart(int Attempts ) {                                      // программа запуска двигателя
 /*  ----------------------------------------- ПРЕДНАСТРОЙКА ПЕРЕД ЗАПУСКОМ ---------------------------------------------------------*/
//Serial.println("Предпусковая настройка");
    detachInterrupt(1);                                    // отключаем аппаратное прерывание, что бы не мешало запуску
    VbatStart = VoltRead();


// ограничиваем время сигнала запуска на сигналку ( диапазон работы стартера) от 1,5 до 1,5 сек
  int  StTime  = constrain(StTime, 1500, 1500);               
    V_min = 14;                                            // переменная хранящая минимальные напряжения в момент старта

// если напряжение АКБ больше 10 вольт, зажигание выключено
 while (Vbat > 10.00 && digitalRead(Feedback_Pin) == LOW){ 
 
 digitalWrite(ON,  HIGH),   delay (50);        // включаем виртуальное зажигание, с D10 на А1.
 
 if (digitalRead(STOP_Pin) == LOW) {         //  тормоз не нажат или в нейтрали на минус
// if (digitalRead(STOP_Pin) == HIGH) {      // в нейтрали на плюс +12
                                  StarterTimeON = millis();
                                   digitalWrite(STARTER, HIGH);  // на пуск автозапуска сигналки
                                   } else {
                                   Voice(4); // "я на передаче"
                                   heatingstop(1);
                                   break; 
                                   } 
 delay (100);
  while (millis() < (StarterTimeON + StTime) && digitalRead(PSO_Pin) == LOW)   VoltRead(), delay (50);  
 digitalWrite(STARTER, LOW), delay (1000);
// Serial.println("пуск автозапуска сигналки выключил, ожидаем 4 сек.");
 delay (4000);       // запуск выключил, ожидаем 4 сек.

 if (digitalRead(PSO_Pin)  == HIGH) {               // включилось зажигание от сигналки
                          Serial.println ("Есть запуск!"); 
                          Voice(2);      // "двигатель запущен"
                          heating = true;
                          break; }                   // считаем старт успешным, выходим из цикла запуска двигателя
   // "повторите запуск"                       
  Voice(3), heatingstop(1),SIM800.println("ATH0");   
// программный сброс если нет запуска(переход но 0 адрес)(нет + от замка зажигания(PSO_Pin) 4 сек ), перезваниваем пробуем еще раз
  void(* resetFunc) (void) = 0;
  resetFunc(); 

 
   }                             
 
Serial.println ("Выход из запуска");
 if (heating == false){ Timer = 0, Voice(6); // "стоп прогрева"
 } 
           
delay(3000), SIM800.println("ATH0");                            // вешаем трубку (для SIM800L) 
 }

float VoltRead()    {                               // замеряем напряжение на батарее и переводим значения в вольты
              float ADCC = analogRead(BAT_Pin);
                    ADCC = ADCC / m ;
                    Serial.print("Напряжение: "), Serial.print(ADCC), Serial.println("V");    
                    if (ADCC < V_min) V_min = ADCC;                   
                    return(ADCC); }                  // переводим попугаи в вольты
                    
void heatingstop(bool reset_timer) {                                 // программа остановки прогрева двигателя
    digitalWrite(ON,    LOW), delay (100);
    heating= false,           delay(2000); 
    Serial.println ("Выключить все"); 
    if (reset_timer == true) Timer = 0;
    }

void Voice(int Track){
    SIM800.print("AT+CREC=4,\"C:\\User\\"), SIM800.print(Track), SIM800.println(".amr\",0,95");}

  Arduino занялся 2 месяца, не на чем было, ну и не интересовался раньше.

     Так же где можно прочитать, что прописать в скетче что бы привязка номера телефона была не к программе, а к SIM карте.

b707
Offline
Зарегистрирован: 26.05.2017

Я бы вам советовал для начала изучить, что такое миллис и как он работает.Тогда вы не будете писать фраз типа "миллис не сбрасывается, а только останавливается".(по секрету - миллис не только не сбрасывается, но и не останавливается...)

Может тогда и задачи свои решите.

А код стоило бы сначала отформатировать, прежде чем предлагать кому-то в нем копаться. Про отступы никогда не слыхали? И операторы через запятую перечисляют только  (подставьте сами...)

vic163-163
Offline
Зарегистрирован: 06.03.2018

   Уважаемый b707, спасибо за замечания. Насчет millis, я имел в виду цикл выполнения.

Отформатировал и подчистил скетч. Изменил схему. Добавил строки 79-97, и 101-103. Удалил лишние порты, которые нужны были при отработке в железе.

  Сейчас вроде работает, но при выполнении функции (digitalRead(PSO_Pin) == LOW && digitalRead(Feedback_Pin) == HIGH), заметил что если переключить PSO_Pin,  несколько раз (например 3 раза по 20 сек) то время сброса  24_ long Time2, увеличивается на время отключения (+60 сек). С чем это связано.

  Также кто нибудь просветит неграмотного,  отчего  24_ long Time2 = 32767, и не больше.  При большем значении не происходит выполнение строк 79-97 . Происходит какоето битовое переполнение?

 

#include <SoftwareSerial.h>
SoftwareSerial SIM800(7, 6);        // для новых плат начиная с версии RX,TX

#define ON           10             // иммитация команды на запуск от arduino, через диод c D10 на A1
#define STARTER      11             // на пуск/стоп автозапуска сигналки
#define OUT_5        8              // на реле блокировки двигателя
#define OUT_6        9              // на реле дальнего света и клаксона // для програмного управления реле дальнего света и клаксона //позже убрать
#define BAT_Pin      A0             // на батарею, через делитель напряжения 39кОм / 11 кОм
#define Feedback_Pin A1             // на A1 от диода с D10, иммитация команды на запуск от arduino
#define STOP_Pin     A2             // на концевик педали тормоза для отключения (на нейтрали запрещения) режима прогрева
#define PSO_Pin      A3             // на провод от замка зажигания, анализ заведенного мотора
#define IN_1         3              // на кнопку обратного звонка, кнопка на массу
#define STOP_Head    2              // через диод с D2 на A2, для сброса прогрева ардуино
#define RESET_Pin    5
/*  ----------------------------------------- ИНДИВИДУАЛЬНЫЕ НАСТРОЙКИ !!!---------------------------------------------------------   */
String call_phone = "+79270000000"; // телефон входящего вызова
float Vstart = 13.50;              // порог распознавания момента запуска по напряжению
String pin = "";                   // строковая переменная набираемого пинкода
float Vbat, VbatStart, V_min ;     // переменная хранящая напряжение бортовой сети
float m = 69.91;                   // делитель для перевода АЦП в вольты для резистров 39/11kOm
unsigned long Time1, StarterTimeON = 0;
int STOP_Head_But = 0;             // Задаем переменную, для счетчика
long previousMillis = 0;           // Зададим начальное значение для счетчика millis
long Time2 = 32767;                // Время для сброса на STOP_Pin через диод с D2 на A2, 40 сек
int STOP_Head_Pin = LOW;           // устанавливаем начальное состояние STOP_Head
int Timer = 0;                     // таймер времени прогрева двигателя по умолчанию = 0
int Timer2 = 0;                    // часовой таймер (60 sec. x 60 min. / 10 = 360 )
bool heating = false;              // переменная состояния режим прогрева двигателя
bool ring = false;                 // флаг момента снятия трубки

void(* resetFunc) (void) = 0;

void setup() {
  pinMode(ON,      OUTPUT);
  pinMode(STARTER, OUTPUT);
  pinMode(OUT_5,   OUTPUT);
  pinMode(OUT_6,   OUTPUT);
  pinMode(Feedback_Pin, INPUT);
  pinMode(STOP_Pin, INPUT);
  pinMode(PSO_Pin,   INPUT);
  pinMode(IN_1, INPUT_PULLUP);        // указываем пин на вход для с внутричипной подтяжкой к +3.3V
  pinMode(STOP_Head, OUTPUT);

  delay(100);
  Serial.begin(9600);              //скорость порта
  //  Serial.setTimeout(50);

  SIM800.begin(9600);              //скорость связи с модемом
  // SIM800.setTimeout(500);          // тайм аут ожидания ответа

  Serial.println("+call_phone+");
  SIM800_reset();
}
/*  --------------------------------------------------- Перезагрузка МОДЕМА SIM800L ------------------------------------------------ */
void SIM800_reset() {
  delay(2000); SIM800.println("AT+CMGDA=\"DEL ALL\"");  // Удаляем все СМС
}

// обратный звонок при замыкании на массу входа D3, чтобы раз в 3 месяца звонить а то отключат SIM карту
void callback() {
  SIM800.println("ATD" + call_phone + ";"),    delay(5000);
}

void loop() {

  if (SIM800.available())  resp_modem();                            // если что-то пришло от SIM800 в Ардуино отправляем для разбора
  if (Serial.available())  resp_serial();                           // если что-то пришло от Ардуино отправляем в SIM800
  if (millis() > Time1 + 10000) Time1 = millis(), detection();      // выполняем функцию detection () каждые 10 сек
  if (heating == true && digitalRead(STOP_Pin) == 1)  heatingstop(1); // если нажали на педаль тормоза в режиме прогрева
  if (digitalRead(STOP_Pin) == 1) Timer2 = 0 ;                      // если нажали на педаль тормоза в режиме прогрева

  //моргаем реле дальнего света и клаксона. из за delay плохо срабатывает сброс блокировки "987", приходится повторять набор команты
  if (digitalRead(OUT_5) == 1) digitalWrite(OUT_6, HIGH), delay (500), digitalWrite(OUT_6, LOW), delay (500);

  //если (PSO_Pin, зажигание) переключился с 1 на 0 (по какой то причине отключилось зажигание авто)
  // и (Feedback_Pin) == HIGH (или heating == true, есть прогрев в arduino). на время больше 40 сек. то нужен сброс прогрева в arduino
  //нужно сбросить ( "уже прогреваюсь" Voice(5)

  /*------  блок добавлен для сброса прогрева ардуино через диод с D2 (STOP_Head) на A2 (STOP_Pin)--------*/
  if (digitalRead(PSO_Pin) == LOW && digitalRead(Feedback_Pin) == HIGH)  // если отключилось зажигание авто
  {
    if (millis() - previousMillis  >=  1)           // начинаем считать время нажатия
    {
      previousMillis = millis();                    //
      STOP_Head_But++;                              // с каждой миллисекундой увеличиваем значение STOP_Head_But
    }
  }
  else                                                  // если кнопку отпустили, то STOP_Head_But становится равным 0
  { // это необходимо для защиты от срабатывания при частых, многократных переключениях PSO_Pin
    STOP_Head_But = 0;                                      //
  }
  if (STOP_Head_But >= Time2)                              // как толькозначение STOP_Head_Pin становится равным Time2
  { //
    digitalWrite(STOP_Head, STOP_Head_Pin = ! STOP_Head_Pin);         // то инвертируем состояние STOP_Head
    STOP_Head_But = 0;                                     //  и устанавливаем STOP_Head_But = 0
  }
}

void detection() {                                                // условия проверяемые каждые 10 сек

  if (digitalRead(STOP_Head == HIGH)) {           // сброс выхода STOP_Head в LOW
    delay(50), digitalWrite(STOP_Head, LOW);
  }

  Vbat = VoltRead();                                            // замеряем напряжение на батарее
  Serial.println ("");
  if (heating == true && Vbat < 11.0 )   heatingstop(1);  // остановка прогрева если напряжение просело ниже 11 вольт
  if (Timer2 == 1) {
    Timer2 = 0;
    {
      enginestart(3);
    }
  }
  if (Timer2 >  1)  Timer2--;
}


void resp_serial () {    // ---------------- ТРАНСЛИРУЕМ КОМАНДЫ из ПОРТА В МОДЕМ ----------------------------------
  String at = "";
  //    while (Serial.available()) at = Serial.readString();
  int k = 0;
  while (Serial.available()) k = Serial.read(), at += char(k), delay(1);
  SIM800.println(at), at = "";
}

void resp_modem () {    //------------------ НАЛИЗИРУЕМ БУФЕР ВИРТУАЛЬНОГО ПОРТА МОДЕМА------------------------------
  String at = "";
  //    while (SIM800.available()) at = SIM800.readString();  // набиваем в переменную at
  int k = 0;
  while (SIM800.available()) k = SIM800.read(), at += char(k), delay(1);
  Serial.println(at);

  if (at.indexOf("+CLIP: \"" + call_phone + "\",") > -1) {
    delay(200), SIM800.println("ATA"), ring = true;

  } else if (at.indexOf("+DTMF: ")  > -1)        {
    String key = at.substring(at.indexOf("") + 9, at.indexOf("") + 10);
    pin = pin + key;
    if (pin.indexOf("*") > -1 ) pin = "";

  } else if (at.indexOf("NO CARRIER") > -1 ) {
    SIM800.println("AT+CLIP=1;+DDET=1"); // Активируем АОН и декодер DTMF
  }
  at = "";            // Возвращаем ответ можема в монитор порта , очищаем переменную

  if (pin.indexOf("789") > -1 ) {
    pin = "", Voice(8), digitalWrite(OUT_5, HIGH), delay (2000), heatingstop(1), SIM800.println("ATH0"); // блокировка двигателя
  } else if (pin.indexOf("987") > -1 ) {
    pin = "", Voice(9), digitalWrite(OUT_5, LOW), delay (2000), SIM800.println("ATH0"); //снятие сблокировки двигателя
  } else if (pin.indexOf("123") > -1 ) {
    pin = "";
    if (digitalRead(Feedback_Pin) == HIGH)      // false если уже прогревается
    {
      false;
    }
    else if (digitalRead(PSO_Pin) == HIGH)      // false если включено зажигание
    {
      false;
    }
    else {
      (digitalRead(Feedback_Pin) == LOW);
      {
        Voice(7), enginestart(3); // запуск на сигналку  // "все поняла завожу"
      }
    }
  } else if (pin.indexOf("321") > -1 ) {
    pin = "";  // стоп запуска на сигналку
    if (digitalRead(Feedback_Pin) == LOW)         //что бы командой "стоп" не запустить дистанционно двигатель
    {
      false;
    }
    else if (digitalRead(PSO_Pin) == HIGH)      // false если включено зажигание
    {
      false;
    }
    else {
      (digitalRead(Feedback_Pin) == HIGH);
      {
        Voice(6), digitalWrite(STARTER, HIGH), delay(2000), digitalWrite(STARTER, LOW), heatingstop(1); // "стоп прогрева"
      }
    }
    SIM800.println("ATH0");
  }

  /*------голосовые сообщения при входящем звонке-----------*/
  if (ring == true) {
    ring = false, delay (2000), pin = ""; // обнуляем пин

    //авто находится в режиме блокирови Voice(8)
    if (digitalRead(OUT_5) == HIGH) {
      Voice(8);    // "двигатель блокирован"
    }
    //включено зажигание авто и нет прогрева от arduino, (  Voice(10)
    else if (digitalRead(Feedback_Pin) == LOW && digitalRead(PSO_Pin) == HIGH) {
      Voice(10);  // "двигатель уже запущен"
    }
    // "привет жду команду"
    else if (digitalRead(Feedback_Pin) == LOW && digitalRead(OUT_5) == LOW) {
      Voice(1);
    }
    // "уже прогреваюсь"
    else {
      Voice(5);
    }
  }
}
void enginestart(int Attempts ) {                                      // программа запуска двигателя
  /*  ----------------------------------------- ПРЕДНАСТРОЙКА ПЕРЕД ЗАПУСКОМ ---------------------------------------------------------*/
  //Serial.println("Предпусковая настройка");
  detachInterrupt(1);                                    // отключаем аппаратное прерывание, что бы не мешало запуску
  VbatStart = VoltRead();

  // ограничиваем время сигнала запуска на сигналку от 2 до 2 сек (зависит от авто сигналки)
  int  StTime  = constrain(StTime, 2000, 2000);
  V_min = 14;                                            // переменная хранящая минимальные напряжения в момент старта

  // если напряжение АКБ больше 10 вольт, зажигание выключено
  while (Vbat > 10.00 && digitalRead(Feedback_Pin) == LOW) {

    digitalWrite(ON,  HIGH),   delay (50);        // включаем виртуальное зажигание, с D10 на А1.

    if (digitalRead(STOP_Pin) == LOW) {         //  тормоз не нажат или в нейтрали на минус
      // if (digitalRead(STOP_Pin) == HIGH) {      // в нейтрали на плюс +12
      StarterTimeON = millis();
      digitalWrite(STARTER, HIGH);  // на пуск автозапуска сигналки
    } else {
      Voice(4); // "я на передаче"
      heatingstop(1);
      break;
    }
    delay (100);
    while (millis() < (StarterTimeON + StTime) && digitalRead(PSO_Pin) == LOW)   VoltRead(), delay (50);
    digitalWrite(STARTER, LOW), delay (1000);
    // Serial.println("пуск автозапуска сигналки выключил, ожидаем 4 сек.");
    delay (4000);       // запуск выключил, ожидаем 4 сек.

    if (digitalRead(PSO_Pin)  == HIGH) {               // включилось зажигание от сигналки
      Serial.println ("Есть запуск!");
      Voice(2);      // "двигатель запущен"
      heating = true;
      break;
    }                   // считаем старт успешным, выходим из цикла запуска двигателя
    // "повторите запуск"
    Voice(3), heatingstop(1), SIM800.println("ATH0");
    // программный сброс если нет запуска(переход но 0 адрес)(нет + от замка зажигания(PSO_Pin) 4 сек ), перезваниваем пробуем еще раз
    void(* resetFunc) (void) = 0;
    resetFunc();
  }

  Serial.println ("Выход из запуска");
  if (heating == false) {
    Timer = 0, Voice(6); // "стоп прогрева"
  }

  delay(3000), SIM800.println("ATH0");                            // вешаем трубку (для SIM800L)
}

float VoltRead()    {                               // замеряем напряжение на батарее и переводим значения в вольты
  float ADCC = analogRead(BAT_Pin);
  ADCC = ADCC / m ;
  Serial.print("Напряжение: "), Serial.print(ADCC), Serial.println("V");
  if (ADCC < V_min) V_min = ADCC;
  return (ADCC);
}                  // переводим попугаи в вольты

void heatingstop(bool reset_timer) {                                 // программа остановки прогрева двигателя
  digitalWrite(ON,    LOW), delay (100);
  heating = false,           delay(100);
  Serial.println ("Выключить все");
  if (reset_timer == true) Timer = 0;
}

void Voice(int Track) {
  SIM800.print("AT+CREC=4,\"C:\\User\\"), SIM800.print(Track), SIM800.println(".amr\",0,95");
}

 

b707
Offline
Зарегистрирован: 26.05.2017

vic163-163 пишет:

    Также кто нибудь просветит неграмотного,  отчего  24_ long Time2 = 32767, и не больше.  При большем значении не происходит выполнение строк 79-97 .

Потому что в строке 92 вы сравниваете переменную Time2 со счетчиком STOP_Head_But, который описан как int. то есть может иметь максимальное значение не больше 32767.

Опишите все переменные, связанные с миллис, миллисекундами, счетчиками и тд - как unsigned long

b707
Offline
Зарегистрирован: 26.05.2017

del