Охранная система на Arduino

Тема в разделе "Arduino & Shields", создана пользователем Amidey, 15 апр 2017.

  1. Slavdej

    Slavdej Нерд

    Проблему обнаружил в железе, плохая пропайка 2 го пина RX на шилде.
    Ща подпаяю и всё зацокает)
     
  2. Slavdej

    Slavdej Нерд

    Не зацокало(
    Походу никак(((
    Если будут предложения или мысли у Вас, я с нетерпением буду ждать.
    Спасибо.
     
  3. Slavdej

    Slavdej Нерд

    Победааааа!
    Я победил хардвар сериал, заменил булевы константы на сработку только по уровню( как Вы меня и учили)
    ТЕперь можно двигаться далее.
    ЗА частый монолог простите, мне так проще разбираться)
     
  4. Slavdej

    Slavdej Нерд

    А вот что получилось дальше:
    Код (C++):
    #include <Wire.h>
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(2, 3, 4, 5, 11, 12);

    int analogInput = 0;               // переменная для удобства инициализации и работы с аналог. портом 0
    float vout = 0.0;                  // переменная с значением выходного напряжения
    float vin = 0.0;                   // переменная с результатом измерений
    float R1 = 100000.0;               // сопротивление R1
    float R2 = 10000.0;                // сопротивление R2
    int value = 0;                     // переменная хранения данных
    int btnPin = 10;                   // переменная прерывателя
    void setup()
    {
     
      Serial.begin(19200);          
      pinMode(btnPin, INPUT);
      //Включаем GPRS Shield, эмулируя нажатие кнопки POWER
      pinMode(9, OUTPUT);
      digitalWrite(9, HIGH);    // Подаем High на пин 9
      delay(1000);              // на 3 секунды
      digitalWrite(9, LOW);     // и отпускаем в Low.
      delay(3000);              // Ждём 5 секунд для старта шилда
      {
        pinMode(analogInput, INPUT);    // инициализируем аналоговый порт 0, как вход
       lcd.begin(16, 2);
       lcd.print("DC VOLTMETER");
      }
    }

    void loop()                                                                                                                                                                                                                                                                                            
       {
     
        if (digitalRead(btnPin) == HIGH) {
            //сразу после нажатия кнопки начинаем звонить по заданному номеру
            Serial.println("ATD +380686617468;");
            delay(10000);
           
    }   if(vin<=12.65)
       {
        // Устанавливает текстовый режим для SMS-сообщений
        Serial.print("AT+CMGF=1\r");
        delay(100); // даём время на усваивание команды
        // Устанавливаем адресата: телефонный номер в международном формате
        Serial.println("AT + CMGS = \"+380686617468\"");
        delay(100);
        // Пишем текст сообщения
        Serial.println("Alarm Low Bat Voltage!!!");
        Serial.println(vin);
        delay(30000);
        // Отправляем Ctrl+Z, обозначая, что сообщение готово
        Serial.println((char)26);
    }
       
    {
       value = analogRead(analogInput);// читаем аналоговый сигнал, с аналог. порта - 0
       vout = (value * 4.95) / 1024.0;  // не забываем про внесение поправки (5.0 - это идеальный вариант,хотя все возможно)
       vin = vout / (R2/(R1+R2));      // в переменной будет значение входного напряжения
    } if (vin<0.09)                   // проверка, для получ. 0
      {   vin=0.0;                        // обнуляем нежелательное значение
    }
    lcd.setCursor(0, 1);
    lcd.print("INPUT V= ");
    lcd.print(vin);
    delay(500);
    }
     

    Код работает и всё бы ничего, да вот delay тут уже не свистит.
    Он всю работы своими прерываниями на 10-30 секунд блокирует, а это полный провал.
    Пожалуйста, подскажите-научите пользоваться Millis
    Иначе мои недосыпания в последнее время совершенно напрасны)
     
    Airbus нравится это.
  5. Slavdej

    Slavdej Нерд

    Сам себя похвалю, иначе брошу всё к жукам майским)
    Довольно неплохо для начинающего я разобрался за первую неделю, но ещё многому предстоит научиться.)))
     
  6. Slavdej

    Slavdej Нерд

    А вообще, неплохо было бы использовать вообще время внутреннего RTC в GSM шилде для определения интервалов в командах.
    Как Вы думаете?
     
  7. Slavdej

    Slavdej Нерд

    ТАкой вариант бы был вообще идеальным.
     
  8. Airbus

    Airbus Радиохулиган Модератор

    Отличная работа!Я бы ещё кое что немного переделал чуть позже посмотрю ОК?Только прилетел.А насчёт delay почему нет?В этом случае как раз да-здесь именно delay останавливает цикл на время чтоб не пулять лишние СМС и не доставать частыми дозвонами. А время не нужно-зачем?У нас здесь время относительно только для пауз в командах не надо утяжелять код.
    Ну да это про меня вчера ночью вспомнил когда взлетал в красноярске - улыбнуло. :) Спасибо!
    Ну да так и есть командир Арбуза-319;)
     
    Slavdej нравится это.
  9. Slavdej

    Slavdej Нерд

    Но delay останавливает все процессы на время выдержки паузы, а это не допустимо ибо при исходящем звонке например не отправляется смс о состоянии АКБ , так же невозможно отправить команду на действие входящим смс, ну и наоборот, при низком разряде АКБ всё блокируется и выполняется только отправка смс с заданным delay интервалом.
    ЩА попробую обмануть судьбу, я всё таки понемногу уже начинаю понимать коды и операторы, инфы перелопатил за последнюю неделю не мало и что то уже запомнилось.
    Но без Вас мне не разобраться, я очень жду Ваших ответов всегда и надеюсь по прошествию энного количества времени я тоже стану Вам интересен как специалист и тоже смогу помогать в чём либо.
    Спасибо что отзываетесь, я Вам очень признателен.
     
  10. Airbus

    Airbus Радиохулиган Модератор

    Смотрите у Вас код написан так что нет паралельных действий и нет прерываний.то есть считал напряжение сравнил если всё ОК пошли дальше считали PIN всё ок пошли на начало.Если напряжение меньше-отправили СМС-разово ведь больше не надо так?пошли дальше опросили PIN если он сработал позвонили сделали небольшую паузу и ничего больше и снова по кругу.Цикл выполняется очень быстро за секунду около 1000 раз разве этого недостаточно чтоб словить нажатие и провал напряжения?Более чем.ОК нажатие можно словить из прерывания тогда даже при замере напряжения процесс прервётся и будет выполнен дозвон.
    Millis я не особо пользуюсь так как пишу в основном на чистом Си или Ассемблере а тут просто так иногда развлекаюсь.Но в целом как то так
    Код (C++):

    /* Blink without Delay
     2005
     by David A. Mellis
     modified 8 Feb 2010
     by Paul Stoffregen
     */

     
    const int ledPin =  13;  // номер выхода, подключенного к светодиоду
    // Variables will change:
    int ledState = LOW;  // этой переменной устанавливаем состояние светодиода
    long previousMillis = 0;  // храним время последнего переключения светодиода
     
    long interval = 1000;  // интервал между включение/выключением светодиода (1 секунда)
     
    void setup() {
     // задаем режим выхода для порта, подключенного к светодиоду
     pinMode(ledPin, OUTPUT);
    }
     
    void loop()
    {
     // здесь будет код, который будет работать постоянно
     // и который не должен останавливаться на время между переключениями свето
     unsigned long currentMillis = millis();
     
     //проверяем не прошел ли нужный интервал, если прошел то
     if(currentMillis - previousMillis > interval) {
     // сохраняем время последнего переключения
     previousMillis = currentMillis;
     
     // если светодиод не горит, то зажигаем, и наоборот
     if (ledState == LOW)
     ledState = HIGH;
     else
     ledState = LOW;
     
     // устанавливаем состояния выхода, чтобы включить или выключить светодиод
     digitalWrite(ledPin, ledState);
     }
    }
     
    Вы большой Молодец у Вас светлый ум и всё получиться.Вечером погоняю Ваш скетч и внесу свои 5 копеек ОК?
     
    Slavdej нравится это.
  11. Slavdej

    Slavdej Нерд

    Конечно, спасибо за помощь, я буду стараться...
    Вечером думаю будут тоже интересные результаты.
     
  12. Slavdej

    Slavdej Нерд

    Проблема то в том, что смс не разово отправляется, а валит с интервалом заданным delay
    Возможно ли как то ограничить к примеру смс разовой отправкой один раз в сутки привязавшись к дате и времени RTC внутри GSM шилда, ну и ограничиться определённым количеством звонков в случае срабатывания концевика.
    Проблема в том что если он наяривает постоянно, сбрасываю он снова наяривает, мешает даже скомандовать по СМС включить сирену или задействовать ГПУ установленный под капотом.
    * ГПУ- Установка газовый патрон "Терен 5" с соленоидом для срабатывания.
    2 АКБ уже потерял, теперь щадить не стану, сначала ГПУ, потом сигнал клаксона, ну и потом тумаки естественно)
     
  13. Slavdej

    Slavdej Нерд


    Когда я так увлечён чем то как в данном случае, Pentobarbital натрия отдыхает))
    Но всё равно, спасибо за предложение и заботу!))
     
  14. Slavdej

    Slavdej Нерд

    А вот и фото сего нехитрого пока девайса, впереди ещё много работы по отладке кода и изготовлению платы...
    А вот код который дорабатывается в режиме реального времени)
    Есть вопрос дорогие форумчане: Как заставить дату и время с RTS на GSM шилде выводиться на экран в соответствующие строки...?

    Код (C++):
    #include <Wire.h>
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(2, 3, 4, 5, 11, 12);
    int analogInput = 0;               // переменная для удобства инициализации и работы с аналог. портом 0
    float vout = 0.0;                  // переменная с значением выходного напряжения
    float vin = 0.0;                   // переменная с результатом измерений
    float R1 = 100000.0;               // сопротивление R1
    float R2 = 10000.0;                // сопротивление R2
    int value = 0;                     // переменная хранения данных
    int btnPin = 10;                   // переменная прерывателя
    void setup()
    {
     
      Serial.begin(19200);          
      pinMode(btnPin, INPUT);
      //Включаем GPRS Shield, эмулируя нажатие кнопки POWER
      pinMode(9, OUTPUT);
      digitalWrite(9, HIGH);    // Подаем High на пин 9
      delay(1000);              // на 3 секунды
      digitalWrite(9, LOW);     // и отпускаем в Low.
      delay(3000);              // Ждём 5 секунд для старта шилда
      {
        pinMode(analogInput, INPUT);    // инициализируем аналоговый порт 0, как вход
      }
    }

    void loop()                                                                                                                                                                                                                                                                                            
       {
            Serial.println("AT+CCLK?");
        if (digitalRead(btnPin) == HIGH) {
            //сразу после нажатия кнопки начинаем звонить по заданному номеру
            Serial.println("ATD +380686617468;");
            delay(10000);
           
    }   if(vin<=12.65)
       {
        // Устанавливает текстовый режим для SMS-сообщений
        Serial.print("AT+CMGF=1\r");
        delay(100); // даём время на усваивание команды
        // Устанавливаем адресата: телефонный номер в международном формате
        Serial.println("AT + CMGS = \"+380686617468\"");
        delay(100);
        // Пишем текст сообщения
        Serial.println("Alarm Low Bat Voltage!!!");
        Serial.println(vin);
        delay(1000);
        // Отправляем Ctrl+Z, обозначая, что сообщение готово
        Serial.println((char)26);
    }
       
    {
       value = analogRead(analogInput);// читаем аналоговый сигнал, с аналог. порта - 0
       vout = (value * 4.95) / 1024.0;  // не забываем про внесение поправки (5.0 - это идеальный вариант,хотя все возможно)
       vin = vout / (R2/(R1+R2));      // в переменной будет значение входного напряжения
    } if (vin<0.09)                   // проверка, для получ. 0
      {   vin=0.0;                        // обнуляем нежелательное значение
    }
    lcd.begin(16, 2);
    lcd.command(0b101000);
    lcd.setCursor(0,0);
    lcd.print("DC VOLTMETER:");
    lcd.setCursor(0, 1);
    lcd.print("INPUT V= ");
    lcd.print(vin);
    delay(10000);
    lcd.clear();
    lcd.command(0b101010);
    lcd.setCursor(0,0);
    lcd.print("Date:");
    lcd.setCursor(0,1);
    lcd.print("Time:");
    delay(10000);
    lcd.clear();

    }
     
     

    Вложения:

    • NVDXod8yZ1c.jpg
      NVDXod8yZ1c.jpg
      Размер файла:
      516,8 КБ
      Просмотров:
      724
    • LqbyCmgiH10.jpg
      LqbyCmgiH10.jpg
      Размер файла:
      532,8 КБ
      Просмотров:
      729
  15. Airbus

    Airbus Радиохулиган Модератор

    Немного доработал Ваш код убрав всё лишнее и сделав так что СМС приходит 1 раз при снижении напряжения ниже 12 вольт и дозвон будет 1 раз при сработке концевика.всё остальное время программа крутиться в цикле и можно напихать в неё что то ещё например как Вы хотите СМС управление.При желании флаг дозвона можно вновь установить для повторных сработок тем же delay или millis.Код
    Код (C++):
     
    #include <LiquidCrystal.h>
        LiquidCrystal lcd(2, 3, 4, 5, 11, 12);
        int analogInput = 0;            // переменная для удобства инициализации и работы с аналог. портом 0
        float vout = 0.0;               // переменная с значением выходного напряжения
        float vin = 0.0;                // переменная с результатом измерений
        int R1 = 100000;                // сопротивление R1
        int R2 = 10000;                 // сопротивление R2
        int value = 0;                  // переменная хранения данных
        int btnPin = 10;                // переменная прерывателя
        int state = 1 ;                 // статус СМС
        int flag = 1 ;                  // флаг дозвона
        void setup()
      {
        Serial.begin(9600);        
        pinMode(btnPin, INPUT);
        //Включаем GPRS Shield, эмулируя нажатие кнопки POWER
        pinMode(9, OUTPUT);
        digitalWrite(9, HIGH);    // Подаем High на пин 9
        delay(1000);              // на 3 секунды
        digitalWrite(9, LOW);     // и отпускаем в Low.
        delay(3000);              // Ждём 5 секунд для старта шилда
        lcd.begin(16, 2);
        lcd.print("DC VOLTMETER");
             }
        void loop()                                                                                                                                                                                                                                                                                          
         {
         //Serial.println("start");  // чисто для отладки
         if (digitalRead(btnPin) == HIGH) // если сработал контакт
           {
             if (flag == 1)                 //и флаг поставлен
             {
            //сразу после нажатия кнопки начинаем звонить по заданному номеру
            Serial.println("ATD +380686617468;");
            delay(100);
            flag = 0;    //блокируем повторные дозвоны    
              }
                       }
         // измеряем напряжение
         value = analogRead(analogInput);// читаем аналоговый сигнал, с аналог. порта - 0
         vout = (value * 4.95) / 1024.0;  // не забываем про внесение поправки (5.0 - это идеальный вариант,хотя все возможно)
         vin = vout / (R2/(R1+R2));      // в переменной будет значение входного напряжения
         //Serial.println(vout);
         if(vin < 12)      // если меньше 12 вольт
       {
         if (state == 1)           // и флаг поставлен
           {
                   
        Serial.println("AT+CMGF=1\r"); // Устанавливает текстовый режим для SMS-сообщений
        delay(100);                // даём время на усваивание команды
                                   // Устанавливаем адресата: телефонный номер в международном формате
        Serial.println("AT + CMGS = \"+380686617468\"");
        delay(100);
        // Пишем текст сообщения
        Serial.println("Alarm Low Bat Voltage!!!");
        delay(100);
        Serial.println(vin);
        delay(300);
                                   // Отправляем Ctrl+Z, обозначая, что сообщение готово
        Serial.println((char)26);
        state = 0;                 //блокируем повторные отправки
               }
             }
        lcd.setCursor(0, 1);       //выводим на LCD
        lcd.print("INPUT V= ");
        lcd.print(vin);           // значение напряжения
        //Serial.println(vin);      // чисто для отладки
        delay(500);
      }
    Что именно убрал
    1-#include <Wire.h> для чего оно?
    2-pinMode(btnPin, INPUT); вход не обьявляем они и так входы по умолчанию.
    3-Serial.println("AT+CCLK?"); убрал что оно даёт?
    4-if (vin<0.09) // проверка, для получ. 0
    vin=0.0; // обнуляем нежелательное значение
    это ни о чём поэтому убрал.
    5-сначала измеряем напряжение а потом если оно ниже 12 вольт посылаем СМС логично?Поэтому поменял блоки.
    Если будет время и желание проверьте как работает в железе ОК?
     
    Последнее редактирование: 27 апр 2017
    Slavdej нравится это.
  16. Airbus

    Airbus Радиохулиган Модератор

    По поводу СМС управления был в ВИКИ хороший скетч много много лет назад но уже убрали.Управляет двумя светодиодами-можно сделать больше можно поменять текс команд можно засунуть в первый Скетч вобщем творите!У Вас всё получиться!
    Код (C++):
       //для зелёного светодиода будем использовать второй цифровой вход,
    //а для жёлтого - третий
    int greenPin = 2;
    int redPin = 3;
    void setup()
    {
        Serial.begin(9600);
        pinMode(greenPin, OUTPUT);
        pinMode(redPin, OUTPUT);
        // Настраиваем приём сообщений с других устройств
        // Между командами даём время на их обработку
        Serial.print("AT+CMGF=1\r");
        delay(300);
        Serial.print("AT+IFC=1, 1\r");
        delay(300);
        Serial.print("AT+CPBS=\"SM\"\r");
        delay(300);
        Serial.print("AT+CNMI=1,2,2,1,0\r");
        delay(500);
    }
    String currStr = "";
    // Переменная принимает значение True, если текущая строка является сообщением
    boolean isStringMessage = false;
    void loop()
    {
        if (!Serial.available())
            return;
        char currSymb = Serial.read();  
        if ('\r' == currSymb) {
            if (isStringMessage) {
                //если текущая строка - SMS-сообщение,
                //отреагируем на него соответствующим образом
                if (!currStr.compareTo("Green on")) {
                    digitalWrite(greenPin, HIGH);
                } else if (!currStr.compareTo("Green off"))  {
                    digitalWrite(greenPin, LOW);
                } else if (!currStr.compareTo("Red on"))  {
                    digitalWrite(redPin, HIGH);
                } else if (!currStr.compareTo("Red off")) {
                    digitalWrite(redPin, LOW);
                }
                isStringMessage = false;
            } else {
                if (currStr.startsWith("+CMT")) {
                    //если текущая строка начинается с "+CMT",
                    //то следующая строка является сообщением
                    isStringMessage = true;
                }
            }
            currStr = "";
        } else if ('\n' != currSymb) {
            currStr += String(currSymb);
        }
    }
     
    Slavdej и Tomasina нравится это.
  17. Slavdej

    Slavdej Нерд

    Спасибо большое, буду пробовать сейчас,
    На счёт этого
    if (vin<0.09) // проверка, для получ. 0
    vin=0.0; // обнуляем нежелательное значение
    Это у вольтметра погрешность есть на 0.09 и тут на неё в коде такая ссылка.
    ТАк что верну на место, а в целом ща попробую , ещё раз огромное спасибо, за то что уделили время моему проекту.
    Как только будут результаты я опишу их.
     
  18. Airbus

    Airbus Радиохулиган Модератор

    Мне и самому интересно.Я уже сделал 1000 сигнализаций эта будет 1001 :):):) Интересно с Вами работать вместе. К сожалению времени совсем нет началось летнее расписание люди полетели в отпуска поэтому в железе проверить не всегда смогу но при возможности проверю. Так как Вы всё быстро осваиваете Вам скоро будет тесно в пределах Ардуино Вам вскоре понадобиться настоящий/чистый/голый Си.Там много интересных вещей таких как прерывания цикл можно вообще сделать пустой а всё что нужно будет вызываться из прерываний. напряжение упало сработал компаратор-пошла СМС изменилось состояние пина-пошла СМС/дозвон пришла СМС в УСАРТ-пошла движуха.Все выполнено и проц ушёл спать.В Ардуино к сожалению такие штучки не возможны. как то так. удачи!
    if (vin<0.09) // проверка, для получ. 0
    vin=0.0; // обнуляем нежелательное значение

    А вот это реальный тупик кода он никуда не идёт и ни на что не влияет.
     
    Cynep и Slavdej нравится это.
  19. Slavdej

    Slavdej Нерд

    Всё понял), уяснил.
    А вот в скетче ошибка, сейчас поищу где, вместо значения V= 0.00 , выдаёт inf
    Х.з почему так, ща вот вычисляю.
     
  20. Slavdej

    Slavdej Нерд

    Добрый вечер
    Airbus

    На данном этапе мой код такой, Ваши прошлые изменения пришлось откатить т.к. перестал работать вольтметр.

    Код (C++):
    #include <LiquidCrystal.h>
    LiquidCrystal lcd(2, 3, 4, 5, 11, 12);


    int analogInput = 0; // переменная для удобства инициализации и работы с аналог. портом 0
    float vout = 0.0; // переменная с значением выходного напряжения
    float vin = 0.0; // переменная с результатом измерений
    float R1 = 100000.0; // сопротивление R1
    float R2 = 10000.0; // сопротивление R2
    int value = 0; // переменная хранения данных
    int btnPin = 10; // переменная прерывателя
    int state = 1 ; // статус СМС
    int flag = 1 ; // флаг дозвона
    void setup()
    {

    Serial.begin(19200);
    pinMode(btnPin, INPUT);
    //Включаем GPRS Shield, эмулируя нажатие кнопки POWER
    pinMode(9, OUTPUT);
    digitalWrite(9, HIGH); // Подаем High на пин 9
    delay(500); // на 3 секунды
    digitalWrite(9, LOW); // и отпускаем в Low.
    delay(5000); // Ждём 5 секунд для старта шилда
    {
    lcd.begin(16, 2);
    lcd.print("DC VOLTMETER");

    }
    }

    void loop()
    {
    //Serial.println("start"); // чисто для отладки
    if (digitalRead(btnPin) == HIGH)
    {
    if (flag == 1) //и флаг поставлен

    //сразу после нажатия кнопки начинаем звонить по заданному номеру
    Serial.println("ATD +380686617468;");
    delay(100);
    flag = 0; //блокируем повторные дозвоны
    }
    {
    value = analogRead(analogInput);// читаем аналоговый сигнал, с аналог. порта - 0
    vout = (value * 4.95) / 1024.0; // не забываем про внесение поправки (5.0 - это идеальный вариант,хотя все возможно)
    vin = vout / (R2/(R1+R2)); // в переменной будет значение входного напряжения
    }
    if (vin<0.09) // проверка, для получ. 0
    { vin=0.0; // обнуляем нежелательное значение

    } if(vin<=12.65)

    {
    if (state == 1) // и флаг поставлен
    {
    // Устанавливает текстовый режим для SMS-сообщений
    Serial.print("AT+CMGF=1\r");
    delay(100); // даём время на усваивание команды
    // Устанавливаем адресата: телефонный номер в международном формате
    Serial.println("AT + CMGS = \"+***********\"");
    delay(100);
    // Пишем текст сообщения
    Serial.println("Alarm Low Bat Voltage!!!");
    Serial.println(vin);
    delay(100);
    // Отправляем Ctrl+Z, обозначая, что сообщение готово
    Serial.println((char)26);
    state = 0; //блокируем повторные отправки
    }

    {
    lcd.setCursor(0, 1);
    lcd.print("INPUT V= ");
    lcd.print(vin);
    //Serial.println(vin); // чисто для отладки
    delay(500);
    }

    }
    }


    Я вычитал что ардуино уно не использует порт приёма с шилда в режиме хардвар т.к. он занят приёмом с компа, что то вроде этого.
    И по этому для меня усложняется написание кода.Я его не пнимаю, не вижу ответа в ком порту.
    Могу ли я Вас попросить помочь мне уже доработать этот код с максимальными комментариями. Меня конкретно интересует как можно закольцевать дозвон т. е. если кнопка нажата срабатывает разовый звонок, если снова разомкнута, всё в исходную позицию.
    И второй момент в том что я совершенно не могу понять как вставить сюда обратную связь, т.е. к примеру вставить функцию проверки готовности мой номер звонит на шилд , шилд сбрасывает и перезванивает или выполняет какую либо команду.
    Вы человек занятой, у меня же такая куча вопросов и просьб, я прошу не беспокойтесь об этом, это если будет желание в свободное время.
    Заранее благодарен, с уважением
    Slavdej