GSM сигнализация M590+Arduino

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

Если пить по утрам кофе, то руки не отвалятся

Baks пишет:
Не утверждаю что это правильно но знаю что это точно помогает...
 - я вот пью и руки до сих пор на месте :))))

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

Baks пишет:
b707 если подскажете как написать проверку времени чтобы не проверять обнуление буду тоже использовать

да ровно так же, как в том примере, на который Вы ссылались

unsigned long prev_ms=0;
// if (millis() < prev_ms) {prev_ms = millis();} //это проверка обнуления миллисекунд
if ((millis() - prev_ms) >= 60000) { //отбивка интервала в 1 минуту
	prev_ms = millis(); //засекаем когда сработал интервал
//сюда какую-то обработку, которая будет срабатывать каждую минуту
}

только строка 2 не нужна(поэтому я ее закомментировал), так как никакая проверка не требуется. Условие в строке 3 будет работать даже тогда , когда millis() обнулится. Не верите - напишите простеньку программку, сами задайте счетчик вблизи переполнения - и подождите, пока он перейдет через ноль.

 

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

Паша, не обижайтесь, но это для вас пока рано. мне кажется. Вам будет проще воспользоваться встроенным RTC модема А6 или купить внешний RTC модуль (стоит вообще-то, копейки)

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

Обязательно все проверю как с моря доберусь домой )))
А по логике не получается
(5-9999999999) >= 6000
( -999999994)>=6000 почему это должно сработать?

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

Dell

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

Baks пишет:
Обязательно все проверю как с моря доберусь домой ))) А по логике не получается (5-9999999999) >= 6000 ( -999999994)>=6000 почему это должно сработать?

Тема обсасывалась на форуме 100500 раз. Ищите и обрящете.

Если хотите использовать проверки - ради Бога. мне не жалко, только не пишите пожалуйста здесь про них с умным видом, ладно?

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

Baks пишет:
( -999999994)>=6000 почему это должно сработать?

не забываем, что все ваши величины - unsigned, поэтому никаких отрицательных чисел там быть не может.

На этом заканчиваем, тема действительно обсуждалась многократно, все уже давно обсуждено до вас

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

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

pasha413
Offline
Зарегистрирован: 27.11.2016

Да, симка с пакетом смс (хотя это и не надо), всегда можно отключить датчик движения.
Что можете предложить?

Gienekb
Offline
Зарегистрирован: 29.08.2017
pasha413 когда то вы написали „схему постараюсь чуть позже накидать”. Вы найдете время?
Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

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

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

если не ошибаюсь такая кнопка у знакомого киповца называется квитировка

ну вот както так я изложил свои мысли ;)

pasha413
Offline
Зарегистрирован: 27.11.2016

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

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

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

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

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

да наверное вариант b707 даже лучше!

есть еще одна идея что не плохо было бы добавить, это справку по камандам.

к примеру пишем в смс "help" и в обратном смс выдает все возможные команды, можно и в  нескольких смсках

в памяти держать их сложновато... да и жена их не запомнит, 

я кстати тоже буду собирать вашу сигналку как прийдет все из китая

pasha413
Offline
Зарегистрирован: 27.11.2016

Хорошо, Baks, памяти ещё хватает, в выходные попробую вывести справку по командам и с датчиками подумаю

smesharik
Offline
Зарегистрирован: 31.01.2016

Я вот так реализовал

У меня 2 обьемника и 2 геркона

1. При разрывании герконов сразу сирена и отправка смс

2. При сработке обьемника включается счетчик, и сразу отправляется смс что первая сработка, по достижению time_summa включается сирена и смс + звонок, если time_summa не достигается в течении  timer_speed_one_off то обнуляется счетчик.

Это хорошо когда есть ложные сработки, не относящиеся к проникновению. 

3. Если сработала сирена то работает timer_sirena времени и отрубается, но система не восстанавливается, а смысл если обьект уже бомбанули

void security() {
  text();
  if (oxpana == true && (digitalRead(gerkon_1) == LOW || digitalRead(gerkon_2) == LOW)) trevoga = true;   //срабатывание герконов
 
  //===========================Первое срабатывание датчика движения
  if ((digitalRead(alarm_speed_1) == HIGH || digitalRead(alarm_speed_2) == HIGH) && oxpana == true && trevoga == false) {
    speed_on = 1;
  }
  else {
    speed_on = 0;
  }
    
  if (speed_on == 1) {                         // условие при первом срабатывании датчика движения
    speed_summa++;
    if (sms_1 == true) {
      startsms();
      gprsSerial.print(String(F("ALARM !!! One srabotka: ")) + zone_speed + String(F("  ")) + time.gettime("d-m-Y, H:i:s, D"));
      endsms();
      sms_1 = false;
    }
  }

  if (speed_summa >= time_summa && (digitalRead(alarm_speed_1) == LOW || digitalRead(alarm_speed_2) == LOW)) {   //время для сброса ложных срабатываний датчиков движения
    if (millis() - previousMillisC > 1000)
    { previousMillisC = millis();
      valC++;
    }
    if (valC >= timer_speed_one_off)
    {
      speed_summa = 0;
      valC = 0;
      sms_1 = true;
    }
  }

  //===========================Повторное срабатывание датчика движения
  if (oxpana == true){  
  if ((digitalRead(alarm_speed_1) == HIGH || digitalRead(alarm_speed_2) == HIGH) && speed_summa >= time_alarm) {
    trevoga = true;
  }}
  
  if (sirena_on == true && trevoga == true) {
    digitalWrite(sirena, HIGH);
    if (zvonok_1 == true) {
      zvonok_1 = false;
      startsms();
      gprsSerial.print(String(F("ALARM !!! ")) + zone_gerkon + String(F("  ")) + zone_speed + String(F("  ")) + time.gettime("d-m-Y, H:i:s, D"));
      endsms();
      delay(10000);
      gprsSerial.println("ATD" + master_phone + ";");
    }
    if (millis() - previousMillisB > 1000)
    { previousMillisB = millis();
      valB++;
    }
    if (valB >= timer_sirena)
    {
      digitalWrite(sirena, LOW);
      valB = 0;
      sirena_on = false;
    }
  }
}

 

pasha413
Offline
Зарегистрирован: 27.11.2016

smesharik, благодарю за пример кода. У вас ethernet шилд, или GPRS модем?

smesharik
Offline
Зарегистрирован: 31.01.2016

pasha413 пишет:
smesharik, благодарю за пример кода. У вас ethernet шилд, или GPRS модем?

sim800l

всегда пожалуйста, код немного сыроват, но выполняется что на него возложено

если что пишите остальное кину

pasha413
Offline
Зарегистрирован: 27.11.2016

smesharik, тоже планирую перейти на управление по gprs, но пока не очень понимаю как, был бы благодарен за пример. Сайт создавали, или через народдом?
Сейчас имеется А6С с камерой, было бы интересно при сработки PIR датчика фото на сервер (ммс не поддерживает)

smesharik
Offline
Зарегистрирован: 31.01.2016

pasha413 пишет:
smesharik, тоже планирую перейти на управление по gprs, но пока не очень понимаю как, был бы благодарен за пример. Сайт создавали, или через народдом? Сейчас имеется А6С с камерой, было бы интересно при сработки PIR датчика фото на сервер (ммс не поддерживает)

у меня только чисто пока смс, вкл/выкл охраны и прочее, gprs нет

инет только планирую, жду когда мега2560 придет, на нано ничего уже не влазит

а для инета планирую w5100 (есть модули не шилды), и в связке с роутером к которому или кабель или 3G/LTE

Почему так?!  Пока незнаю сам, читал что стабильность gprs не очень и зависания имеют место, но вроде с этим борются. А роутер со свистком/кабелем, сам организовывает переподключения и если что можно инет брать с него. И если что, ну вдруг, зависает роутер, есть модуль смс можно перезагрузку организовать

Вообщем салянка та еще, и как будет это все работать, одному ... 

pasha413
Offline
Зарегистрирован: 27.11.2016

Скинете проект, посмотреть, для саморазвития?)

smesharik
Offline
Зарегистрирован: 31.01.2016
#include <EEPROM.h>
#include <Wire.h>
#include <SoftwareSerial.h>
#include <iarduino_RTC.h>
#include <LiquidCrystal_I2C.h>
iarduino_RTC time(RTC_DS1307);
LiquidCrystal_I2C lcd(0x27, 20, 4);
SoftwareSerial gprsSerial(7, 8);

#include "DHT.h"
#define DHTPINa 11
#define DHTPINb 12
#define DHTTYPE DHT22   // DHT 22  (AM2302)
DHT dhta(DHTPINa, DHTTYPE); // Создаем объект dhta датчик 1
DHT dhtb(DHTPINb, DHTTYPE); // Создаем объект dhtb датчик 2
int ha;
int hb;
int ta;
int tb;

// Команды для отправки смс:
// timeron - включает таймер
// timeroff - выключает таймер
// info - состояние системы
// date0 - полив каждый день
// date1 - полив пон, ср, пят
// date2 - полив пон, пят
// date3 - полив в будни
// polivXX - включение клапана полива на ХХ минут
// teploon / teplooff - включение/выключение реле обогрева
// oxpanaon / oxpanaoff - постановка/снятие с охраны

String timer = "";
String poliv_relay = "";
String oxpana_text = "";
String teplo_text = "";
String poliv_text = "";

int nedela[4][7] = {{0, 1, 2, 3, 4, 5, 6 }, {1, 1, 1, 1, 1, 3, 5}, {1, 1, 1, 1, 1, 1, 5}, {1, 1, 1, 2, 3, 4, 5}};
byte kapla[8] = {0b00100, 0b00100, 0b01110, 0b01110, 0b11111, 0b11111, 0b01110, 0b00100};
int i;
int p = 0;
String master_phone = "+79xxxxxxxx";

byte setSecClockOn; //
byte setMinClockOn; //
byte setHorClockOn;
byte setSecClockOff;
byte setMinClockOff; //
byte setHorClockOff;
byte settimer;
byte setdate;
const byte outPin = 4;             // выход на реле клапана
const byte outLedRelay = 5;        // выход на реле обогрева
boolean on_led = true; // разрешение включение экрана по времени
boolean flag = false; // разрешение режима Poliv 

/////////////////////// пины охраны ///////////

byte gerkon_1 = 6; //геркон будка
byte gerkon_2 = 2; //геркон гараж
byte sirena = 3; //выход сирены
boolean oxpana = false; //постановка на охрану
boolean sirena_on = true; //разрешение сирены
boolean trevoga = false; //сработка
boolean zvonok_1 = true; //переменная для разового звонка
boolean sms_1 = true; //переменная для разового звонка
String zone_gerkon = "";
String zone_speed = "";
byte alarm_speed_1 = 9; //датчик движения 1
byte alarm_speed_2 = 10; //датчик движения 2
int speed_summa = 0;  //количество сработок
int speed_on = 0;

/////////////////////Время /////////////////////////////
int timer_sirena = 60; //время работы сирены
int timer_on; //время в режиме POLIV сек
int time_led = 2000; //время на гашение экрана

int timer_speed_one_off = 20; //сброс таймера первой сработки
byte time_summa = 20; //счетчик для включения режима сброса ложных срабатываний датчиков движения 
byte time_alarm = 60; //счетчик для включения ALARM

int valA; //переменная времени
long previousMillisA = 0;
byte valB; //переменная времени
long previousMillisB = 0;
byte valC; //переменная времени
long previousMillisC = 0;
byte val_led; //переменная времени
long previousMillis_led = 0;

const byte PIN_BUTTON_SELECT = 0;
const byte PIN_ANALOG_X = 6;
const byte PIN_ANALOG_Y = 7;
const int X_THRESHOLD_LOW = 518;
const int X_THRESHOLD_HIGH = 530;
const int Y_THRESHOLD_LOW = 505;
const int Y_THRESHOLD_HIGH = 520;
int x_position;
int y_position;
int x_direction;
int y_direction;

byte key() { //// для кнопок ЛСДшилда
  x_direction = 0;
  y_direction = 0;
  x_position = analogRead(PIN_ANALOG_X);
  y_position = analogRead(PIN_ANALOG_Y);
  if (digitalRead(PIN_BUTTON_SELECT) == LOW) return 1;

  if (x_position > X_THRESHOLD_HIGH) {
    x_direction = 1;
    return 5;
  }
  else if (x_position < X_THRESHOLD_LOW) {
    x_direction = -1;
    return 2;
  }
  if (y_position > Y_THRESHOLD_HIGH) {
    y_direction = 1;
    return 3;
  }
  else if (y_position < Y_THRESHOLD_LOW) {
    y_direction = -1;
    return 4;
  } else return 0;
}

/////////// часы ..
void setClock() { // установка часов
  byte pos = 1;
  lcd.clear();
  lcd.blink();
  while (key() != 1) { // крутим   цикл
    byte KEY = key(); // читаем состояние кнопок
    delay(200);
    lcd.setCursor(1, 1);
    lcd.print("set to save");
    lcd.setCursor(0, 0);     // выводим инфу
    if (time.Hours < 10) lcd.print("0");
    lcd.print(time.Hours);
    lcd.print(":");
    if (time.minutes < 10) lcd.print("0");
    lcd.print(time.minutes);
    lcd.print(" ");
    if (time.day < 10) lcd.print("0");
    lcd.print(time.day);
    lcd.print("/");
    if (time.month < 10) lcd.print("0");
    lcd.print(time.month);
    lcd.print("/");
    lcd.print(time.year);

    lcd.setCursor(pos, 0); // устанавливаем курсор согласно позиции
    if (KEY == 5 && pos < 13) pos += 3; // крутим позицию
    else if (KEY == 2 && pos > 1) pos -= 3;

    else if (pos == 1 && KEY == 3) time.Hours++ ; // крутим значения
    else if (pos == 1 && KEY == 4) time.Hours--;
    else if (pos == 4 && KEY == 3) time.minutes++;
    else if (pos == 4 && KEY == 4) time.minutes--;
    else if (pos == 7 && KEY == 3) time.day++;
    else if (pos == 7 && KEY == 4) time.day--;
    else if (pos == 10 && KEY == 3) time.month++;
    else if (pos == 10 && KEY == 4) time.month--;
    else if (pos == 13 && KEY == 3) time.year++;
    else if (pos == 13 && KEY == 4) time.year--;

    if (time.Hours > 23) time.Hours = 0;
    else if (time.minutes > 59) time.minutes = 0;
    else if (time.day > 31) time.day = 0;
    else if (time.month > 12) time.month = 1;
    else if (time.year > 99) time.year = 0;
  }// конец цикла

  time.settime(-1, time.minutes, time.Hours, time.day, time.month, time.year, -1);
  lcd.noBlink();
  lcd.clear();
  lcd.print("     Saved");
  delay(1500);
}///

void setOnOff() {
  delay(200);
  byte pos = 6;
  lcd.clear();
  lcd.blink();

  while (key() != 1) { // крутим   цикл
    byte KEY = key(); // читаем состояние кнопок
    delay(200);
    lcd.setCursor(0, 0);     // выводим инфу
    lcd.print("On:  ");
    if (setHorClockOn < 10) lcd.print("0");
    lcd.print(setHorClockOn);
    lcd.print(":");
    if (setMinClockOn < 10) lcd.print("0");
    lcd.print(setMinClockOn);
    lcd.print(":");
    if (setSecClockOn < 10) lcd.print("0");
    lcd.print(setSecClockOn);

    // просто вторая строка начало
    lcd.setCursor(0, 1);
    lcd.print("Off: ");
    if (setHorClockOff < 10) lcd.print("0");
    lcd.print(setHorClockOff);
    lcd.print(":");
    if (setMinClockOff < 10) lcd.print("0");
    lcd.print(setMinClockOff);
    lcd.print(":");
    if (setSecClockOff < 10) lcd.print("0");
    lcd.print(setSecClockOff);
    // просто вторая строка конец

    lcd.setCursor(pos, 0); // устанавливаем курсор согласно позиции

    if (KEY == 5 && pos < 12) pos += 3; // крутим позицию
    else if (KEY == 2 && pos > 6) pos -= 3;

    else if (pos == 6 && KEY == 3) setHorClockOn++; // крутим значения
    else if (pos == 6 && KEY == 4) setHorClockOn--;
    else if (pos == 9 && KEY == 3) setMinClockOn++;
    else if (pos == 9 && KEY == 4) setMinClockOn--;
    else if (pos == 12 && KEY == 3) setSecClockOn++;
    else if (pos == 12 && KEY == 4) setSecClockOn--;
    if (setHorClockOn > 23) setHorClockOn = 0;

    else if (setMinClockOn > 59) setMinClockOn = 0;
    else if (setSecClockOn > 59) setSecClockOn = 0;

  }
  delay(700);
  on_sec();
}
void on_sec() { //цикл второй строки для выключения таймера
  byte pos = 6;
  while (key() != 1) { // крутим   цикл
    byte KEY = key(); // читаем состояние кнопок
    delay(200);
    lcd.setCursor(0, 1);     // выводим инфу
    lcd.print("Off: ");
    if (setHorClockOff < 10) lcd.print("0");
    lcd.print(setHorClockOff);
    lcd.print(":");
    if (setMinClockOff < 10) lcd.print("0");
    lcd.print(setMinClockOff);
    lcd.print(":");
    if (setSecClockOff < 10) lcd.print("0");
    lcd.print(setSecClockOff);

    lcd.setCursor(pos, 1); // устанавливаем курсор согласно позиции

    if (KEY == 5 && pos < 12) pos += 3; // крутим позицию
    else if (KEY == 2 && pos > 6) pos -= 3;

    else if (pos == 6 && KEY == 3) setHorClockOff++;
    else if (pos == 6 && KEY == 4) setHorClockOff--;
    else if (pos == 9 && KEY == 3) setMinClockOff++;
    else if (pos == 9 && KEY == 4) setMinClockOff--;
    else if (pos == 12 && KEY == 3) setSecClockOff++;
    else if (pos == 12 && KEY == 4) setSecClockOff--;


    if (setHorClockOff > 23) setHorClockOff = 0;
    else if (setMinClockOff > 59) setMinClockOff = 0;
    else if (setSecClockOff > 59) setSecClockOff = 0;

  }// конец цикла
  lcd.noBlink();
  lcd.clear();

  EEPROM.write(0, setMinClockOn);
  EEPROM.write(1, setHorClockOn);
  EEPROM.write(3, setMinClockOff);
  EEPROM.write(4, setHorClockOff);
  EEPROM.write(5, setSecClockOn);
  EEPROM.write(6, setSecClockOff);


  lcd.print("     Saved");
  delay(1500);
}///

void constant () {
  delay(200);
  byte pos = 7;
  lcd.clear();
  lcd.blink();
  while (key() != 1) { // крутим   цикл
    byte KEY = key(); // читаем состояние кнопок
    delay(200);
    lcd.setCursor(0, 0);
    lcd.print("timer= ");
    lcd.print(settimer);

    lcd.setCursor(pos, 0); // устанавливаем курсор согласно позиции
    if (pos == 7 && KEY == 3) settimer++;
    else if (pos == 7 && KEY == 4) settimer--;
    if (settimer > 1) settimer = 1;
  }
  lcd.noBlink();
  lcd.clear();
  EEPROM.write(7, settimer);
  lcd.print("     Saved");
  delay(1500);
}

void menu() {
  delay(200);
  lcd.clear();
  char menuTxt[3][14] = {"set ON/OFF >>", "set clock  >>", "Constant >>"};
  byte pos = 0;

  while (key() != 1) {
    delay(200);
    byte KEY = key();


    lcd.setCursor(0, 0);
    lcd.print(pos + 1);
    lcd.print(".");
    lcd.print(menuTxt[pos]);

    if (KEY == 3 && pos != 0) pos--;
    else if (KEY == 4 && pos < 2) pos++;

    if (KEY == 5 && pos == 0) setOnOff();
    else if (KEY == 5 && pos == 1) setClock();
    else if (KEY == 5 && pos == 2) constant();
  }
  lcd.clear();
}

void poliv() {    //полив по времени polivXXX

  if (flag == true)
  {
    digitalWrite(outPin, LOW);
    if (millis() - previousMillisA > 1000)
    {
      previousMillisA = millis();
      valA++;
    }
    if ((valA / 60) >= timer_on) //в минутах
    {
      if (digitalRead(outPin) == LOW) digitalWrite(outPin, HIGH);
      valA = 0;
      flag = false;

    }
  }
}

void on_led_off()  //подсветка дисплея
{
  if (key() > 0) {
    on_led = true;
  }
  if (on_led == true)
  {
    lcd.backlight();// Включаем подсветку дисплея
    if (millis() - previousMillis_led > 1000)
    {
      previousMillis_led = millis();
      val_led++;
      if (key() > 0) {
        val_led = 0;
      }
    }
    if (val_led >= time_led)
    {
      val_led = 0;
      on_led = false;
      lcd.noBacklight();// Включаем подсветку дисплея
    }
  }
}

void phone() {
if(gprsSerial.available()) //если модуль что-то послал
  {  
    char ch = ' ';
    String val = "";
    
    while(gprsSerial.available()) 
     {  
       ch = gprsSerial.read();
       val += char(ch); //собираем принятые символы в строку
       }
     val.toLowerCase();
     
if ( (p = val.indexOf(F("poliv"))) > -1)    {
        flag = true;
        timer_on = val.substring(p+5, p+8).toInt();
      }

    if (val.indexOf(F("timeron")) > -1)    { // включение таймера
        settimer = 1;
        EEPROM.update(7, settimer);
      }
      if (val.indexOf(F("timeroff")) > -1)   { // выключение таймера
        settimer = 0;
        EEPROM.update(7, settimer);
      }
      if (val.indexOf(F("date0")) > -1)    { // каждый день
        setdate = 0;
        EEPROM.write(8, setdate);
      }
      if (val.indexOf(F("date1")) > -1)    { // пон, ср, пятн
        setdate = 1;
        EEPROM.write(8, setdate);
      }
      if (val.indexOf(F("date2")) > -1)   { // пон, пят
        setdate = 2;
        EEPROM.write(8, setdate);
      }
     if (val.indexOf(F("date3")) > -1)     { // будни
        setdate = 3;
        EEPROM.write(8, setdate);
      }

      if (val.indexOf(F("teploon")) > -1)     { // будни
        digitalWrite(outLedRelay, LOW);
        startsms();
        gprsSerial.print(String(F("Obogrev: ON")));
        endsms();
      }
      if (val.indexOf(F("teplooff")) > -1)     { // будни
        digitalWrite(outLedRelay, HIGH);
        startsms();
        gprsSerial.print(String(F("Obogrev: OFF")));
        endsms();
      }

       if (val.indexOf(F("info")) > -1) {
        startsms();
        gprsSerial.print(String(F("Oxpana: ")) + oxpana_text + String(F("\n")) + String(F("Budka: ")) + ta + String(F(" C / ")) + ha + String(F(" %")) + String(F("\n")) + String(F("Teplisa: ")) + tb + String(F(" C / ")) + hb + String(F(" %")) + String(F("\n")) + String(F("Poliv: ")) + poliv_relay + String(F(" / ")) + poliv_text + String(F("\n")) + String(F("Obogrev: ")) + teplo_text);
        endsms();
      }
      if (val.indexOf(F("oxpanaon")) > -1) {
        oxpana = true;
        zvonok_1 = true;
        sirena_on = true;
        trevoga = false;
        sms_1 = true;
        startsms();
        gprsSerial.print(String(F("Oxpana: ON  ")) + time.gettime("d-m-Y, H:i:s"));
        endsms();
      }
       if (val.indexOf(F("oxpanaoff")) > -1) {
        oxpana = false;
        sirena_on = false;
        digitalWrite(sirena, LOW);
        valB = 0;
        trevoga = false;
        startsms();
        gprsSerial.print(String(F("Oxpana: OFF  ")) + time.gettime("d-m-Y, H:i:s"));
        endsms();
      }
 if (val.indexOf(F("ring")) > -1) {                 // если обнаружен вызов.
      if (val.indexOf(master_phone) > -1) {                        // проверяем номер, если наш.
        gprsSerial.println(F("ATH0"));                  // сбрасываем вызов.
    } else {  
        gprsSerial.println(F("ATH0"));                  // если не наш, сбрасываем его.
        } } 
        }
   }

void startsms() {
  delay(500);
  gprsSerial.println("AT+CMGS=\"" + master_phone + "\"");
  delay(500);
}
void endsms() {
  delay(500);
  gprsSerial.print((char)26);
  }

void security() {
  text();
  if (oxpana == true && (digitalRead(gerkon_1) == LOW || digitalRead(gerkon_2) == LOW)) trevoga = true;   //срабатывание герконов
 
  //===========================Первое срабатывание датчика движения
  if ((digitalRead(alarm_speed_1) == HIGH || digitalRead(alarm_speed_2) == HIGH) && oxpana == true && trevoga == false) {
    speed_on = 1;
  }
  else {
    speed_on = 0;
  }
    
  if (speed_on == 1) {                         // условие при первом срабатывании датчика движения
    speed_summa++;
    if (sms_1 == true) {
      startsms();
      gprsSerial.print(String(F("ALARM !!! One srabotka: ")) + zone_speed + String(F("  ")) + time.gettime("d-m-Y, H:i:s, D"));
      endsms();
      sms_1 = false;
    }
  }

  if (speed_summa >= time_summa && (digitalRead(alarm_speed_1) == LOW || digitalRead(alarm_speed_2) == LOW)) {   //время для сброса ложных срабатываний датчиков движения
    if (millis() - previousMillisC > 1000)
    { previousMillisC = millis();
      valC++;
    }
    if (valC >= timer_speed_one_off)
    {
      speed_summa = 0;
      valC = 0;
      sms_1 = true;
    }
  }

  //===========================Повторное срабатывание датчика движения
  if (oxpana == true){  
  if ((digitalRead(alarm_speed_1) == HIGH || digitalRead(alarm_speed_2) == HIGH) && speed_summa >= time_alarm) {
    trevoga = true;
  }}
  
  if (sirena_on == true && trevoga == true) {
    digitalWrite(sirena, HIGH);
    if (zvonok_1 == true) {
      zvonok_1 = false;
      startsms();
      gprsSerial.print(String(F("ALARM !!! ")) + zone_gerkon + String(F("  ")) + zone_speed + String(F("  ")) + time.gettime("d-m-Y, H:i:s, D"));
      endsms();
      delay(10000);
      gprsSerial.println("ATD" + master_phone + ";");
    }
    if (millis() - previousMillisB > 1000)
    { previousMillisB = millis();
      valB++;
    }
    if (valB >= timer_sirena)
    {
      digitalWrite(sirena, LOW);
      valB = 0;
      sirena_on = false;
    }
  }
}

void text(){
  if (oxpana == false) oxpana_text = "OFF"; else oxpana_text = "ON ";
  if (digitalRead(gerkon_1) == LOW && digitalRead(gerkon_2) == LOW) zone_gerkon = "GARAGE and HOUSE DOOR OPEN";
  if (digitalRead(gerkon_1) == LOW && digitalRead(gerkon_2) == HIGH) zone_gerkon = "HOUSE DOOR OPEN";
  if (digitalRead(gerkon_1) == HIGH && digitalRead(gerkon_2) == LOW) zone_gerkon = "GARAGE DOOR OPEN";
  if (digitalRead(alarm_speed_1) == HIGH && digitalRead(alarm_speed_2) == LOW) zone_speed = "HOUSE MOVE";
  if (digitalRead(alarm_speed_1) == LOW && digitalRead(alarm_speed_2) == HIGH) zone_speed = "GARAGE MOVE";
  if (digitalRead(alarm_speed_1) == LOW && digitalRead(alarm_speed_2) == LOW) zone_speed = "";

  if (digitalRead(outLedRelay) == HIGH) teplo_text = "OFF"; else teplo_text = "ON ";
  if (digitalRead(outPin) == HIGH) poliv_relay = "OFF"; else poliv_relay = "ON ";
  if (settimer == 0) timer = "OFF"; else timer = "ON ";
   
   if (flag == true) { poliv_text = "GSM ";  }
  else if (settimer == true) {  poliv_text = "time"; }
  else if (settimer == false && flag == false) {  poliv_text = "Ryka"; }  
}

void setup() {
  delay(2000);
  Wire.begin();
  time.begin();
  lcd.init();   // initialize the lcd
  lcd.begin(20, 4);
  //Serial.begin(9600);
  gprsSerial.begin(9600);

  gprsSerial.println("AT+CLIP=1");
  delay(300);
  gprsSerial.print("AT+CMGF=1\r");
  delay(300);
  gprsSerial.print("AT+CMGDA=DEL ALL\r");
  delay(300);
  gprsSerial.println("AT+CSCS=\"GSM\"");
  delay(300);
  gprsSerial.print("AT+CNMI=2,2\r");

  dhta.begin(); // Инициализируем датчик 1
  dhtb.begin(); // Инициализируем датчик 2

  lcd.clear();
  lcd.createChar(1, kapla);

  pinMode(gerkon_1, INPUT);
  digitalWrite(gerkon_1, LOW);
  pinMode(gerkon_2, INPUT);
  digitalWrite(gerkon_2, LOW);
  pinMode(alarm_speed_1, INPUT);
  digitalWrite(alarm_speed_1, LOW);
  pinMode(alarm_speed_2, INPUT);
  digitalWrite(alarm_speed_2, LOW);
  pinMode(sirena, OUTPUT);
  digitalWrite(sirena, LOW);
  digitalWrite(outPin, HIGH);
  pinMode(outPin, OUTPUT);
  digitalWrite(outPin, HIGH);
  pinMode(outLedRelay, OUTPUT);
  digitalWrite(outLedRelay, HIGH);
  pinMode(PIN_BUTTON_SELECT, INPUT);
  digitalWrite(PIN_BUTTON_SELECT, HIGH);
  pinMode(alarm_speed_1, INPUT);

  setMinClockOn = EEPROM.read(0);
  setHorClockOn = EEPROM.read(1);
  setSecClockOn = EEPROM.read(5);
  setMinClockOff = EEPROM.read(3);
  setHorClockOff = EEPROM.read(4);
  setSecClockOff = EEPROM.read(6);
  settimer = EEPROM.read(7);
  setdate = EEPROM.read(8);
}

void loop()
{
  on_led_off();
  poliv();
  security();
  text();
  
 // обработка кнопок
  if (key() == 1) menu(); // если нажата селект
  else if (key() == 3) digitalWrite(outPin, LOW);
  else if (key() == 4) {
    digitalWrite(outPin, HIGH);
    flag = false;
  }

  else if (key() == 2) digitalWrite(outLedRelay, LOW);
  else if (key() == 5) digitalWrite(outLedRelay, HIGH);

  // сравниваем время и управляем выходом//
  if (settimer == 1) {
    for (i = 0; i < 7; i++) {
      if (nedela[setdate][i] == time.weekday) {

        if (setMinClockOn == time.minutes && setHorClockOn == time.Hours
            && setSecClockOn == time.seconds) digitalWrite(outPin, LOW);
      }
    }
  }
  if (setMinClockOff == time.minutes && setHorClockOff == time.Hours
      && setSecClockOff == time.seconds) digitalWrite(outPin, HIGH);
      
  ha = dhta.readHumidity(); // Считываем влажность датчика 1
  hb = dhtb.readHumidity(); // Считываем влажность датчика 2
  ta = dhta.readTemperature(); // Считываем температуру датчика 1
  tb = dhtb.readTemperature(); // Считываем температуру датчика 2
 
  lcd.setCursor(0, 0); lcd.print("\1 ");
   lcd.setCursor(2, 0);  lcd.print(poliv_text);

  lcd.setCursor(7, 0); lcd.print(poliv_relay);
  lcd.setCursor(12, 0); lcd.print(time.gettime("H:i:s"));
  lcd.setCursor(0, 1); lcd.print("Teplo: ");
 lcd.setCursor(7, 1); lcd.print(teplo_text);
  lcd.setCursor(12, 1); lcd.print("Oxp: "); lcd.setCursor(17, 1); lcd.print(oxpana_text);
 lcd.setCursor(0, 3); lcd.print("Dom: "); lcd.print(ta); lcd.print(" C");
lcd.setCursor(11, 3); lcd.print("Tep: "); lcd.print(tb); lcd.print(" C");
 

  // delay(50); // нужно для нормальной работы кнопок
  phone(); //должен стоять в самом конце перед --- > }
}

 

Gienekb
Offline
Зарегистрирован: 29.08.2017

 pasha413 пишет: "Схемы сфоткал, как доберусь до компа скину."  Мы с нетерпением ждем (думаю, что не только я).

pasha413
Offline
Зарегистрирован: 27.11.2016

да, вот схема и внешний вид, больше не грузит фото.

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

Схема

внешний вид

 

pasha413
Offline
Зарегистрирован: 27.11.2016

немного доработал и облегчик скетч:

теперь если сработал датчик отправляем смс и ждем определенное кол-во секунд (правится в скетче) до  нового считывания этого датчика;

добавлен уровень сигнала в смс о статусе системы;

добавлена команда "info" список команд, можно ее удалить.

 

#include <EEPROM.h> 
#include <OneWire.h>
#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);

OneWire ds(6);             // датчик температуры подключен к 9 пину, подтяжка 4.7кОм на +.
#define DOOR 4             // концевик двери.
#define PIR 5              // датчик движения.
#define Led 13             // состояние системы. моргает - на охране.
#define GAS 14             // A0. датчик дыма.
#define BUZ 16             // A2. сирена.

// DOOR     - если сработал, на входе "+" HIGH.
// PIR      - если сработал, на входе "+" HIGH.
// GAS      - если сработал, на входе "+" HIGH.
// BUZ      - если "-" LOW, то горит. 
// Led      - если "-" LOW, то горит.

int8_t Guard = 0;          // 1. охрана:                         1 - вкл, 0 - выкл.
int8_t AlarmRING = 1;      // 2. вызов при сработке:             1 - вкл, 0 - выкл.
int8_t SendSMS = 1;        // 3. отправка смс при сработке:      1 - вкл, 0 - выкл.
int8_t DOORon = 1;         // 4. контроль концевиков дверей:     1 - вкл, 0 - выкл.    
int8_t PIRon = 1;          // 5. контроль датчика движения:      1 - вкл, 0 - выкл.
int8_t GASon = 1;          // 6. контроль датчика дыма:          1 - вкл, 0 - выкл.
int8_t Sirena = 1;         // 7. сирена:                         1 - вкл, 0 - выкл. 

int8_t DOORFlag = 0;       // флаг состояние датчика двери.
int8_t PIRFlag = 0;        // флаг состояние датчика движения.
int8_t GASFlag = 0;        // флаг состояние датчика газа.
int8_t DOORState = LOW;    // Состояние концевика двери.
int8_t PIRState = LOW;     // Состояние датчика движения.
int8_t LedState = HIGH;    // Состояние светодиода.
int8_t Smoky = LOW;        // Состояние датчика газа.
int8_t Firststart;         // первый старт.
uint32_t msAT = 0;

char Bal[4] = "";          // для временного хранения номера баланса.   
char Phone[12];            // для временного хранения номера телефона.      
byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ.

String val;                // переменная для хранения пришедших данных.   
String temp;               // переменная для хранения температуры.
String CSQ;                // переменная для хранения пришедших данных уровня сигнала.   
String LastEvent;          // полное состояние системы.
String RingPhone;          // номер звонившего.
String AlarmPhone[5];      // номера для постановки/снятии с охраны и отправки смс.
String Info1 = "Kommanda - deistvie:\nstatus - sostoyanie\nmoney - balance\n";
String Info2 = "sirenaon/off\nsistemon/off\nringon/off\nsmson/off\n";
String Info3 = "dooron/off\npiron/off\ngason/off";

int p = 0;
int GASThres = 400;           // предельная концентрация газа
int interval_alarm = 20;      // Секунд до отключения "тревожного" пина, max 300сек 
int previousMillis_alarm = 0;
int interval_led = 1000;      // для мигания Led
int previousMillis_led = 0;
int interval_door = 10;       // секунд не смотрим на датчик двери
int previousMillis_door = 0;
int interval_pir = 10;        // секунд не смотрим на датчик движения
int previousMillis_pir = 0;
int interval_gas = 60;        // секунд не смотрим на датчик газа
int previousMillis_gas = 0;

/* EEPROM Data:
  № ячейки - значение:
  0 - если записана не 1, то необходимо затереть eeprom и восстановить стандартную конфигурацию.
  1 - Guard = 0;       // охрана:             0 - выкл.
  2 - AlarmRING = 1;   // звонок:             1 - вкл. 
  3 - SendSMS = 1;     // отправка смс:       1 - вкл.
  4 - DOORon = 1;      // концевик двери:     1 - вкл.
  5 - PIRon = 1;       // датчик движения:    1 - вкл.
  6 - GASon = 1;       // датчик дыма:        1 - вкл.
  7 - Sirena = 1;      // сирена:             1 - вкл.
  10 - Firststars = 1;    // первый запуск       1.
  20 - ячейка памяти баланса,
  25, 40, 55, 70, 85 - ячейки памяти телефонов.
  100 - ячейка памяти номера последнего звонившего RingPhone.
*/

void setup() { /// === настройка программы === ///
  Serial.begin(9600); 
  Serial.println(F("Alarm  v3.2"));
  pinMode(DOOR, INPUT_PULLUP);      // вход датчика двери с подтяжкой на +.
  pinMode(PIR, INPUT);           
  pinMode(GAS, INPUT);           
  pinMode(BUZ, OUTPUT);
  pinMode(Led, OUTPUT);             // светодиод горит во время запуска.
    digitalWrite(BUZ, HIGH);        // сирена выкл.
    digitalWrite(PIR, HIGH);        // игнорируем при включении.
//  InitModem();                      // запускаем инициализация модема.
  eepromconfig();
  eepromtext();
  eepromphone();
    digitalWrite(Led, HIGH);        // гасим светодиод состояния сигнализации. 
}                                   
void loop() {  /// === основной цикл программы === ///
  AlarmPinOff();    // выключаем сирену, если прошло  время.
  if (Guard == 1) { // если на охране
    Detect();       // проверяем датчики.
    LED();          // моргаем светодиодом.
  }
  if (mySerial.available()) {     // если GSM модем что-то послал.
    while (mySerial.available()) {  // сохраняем входную строку в переменную val.
      char ch = mySerial.read();
      val += char(ch);              // собираем принятые символы в строку
      delay(3);
    } 
    if (val.indexOf(F("+CLIP")) > -1) {        // если обнаружен вызов.
  Serial.println(F("Process RING"));                              
      delay(2000);                             // дадим гудок
      mySerial.println(F("ATH"));              // сбрасываем вызов.
      if (CheckPhone() == 1) {                 // проверяем номер, если наш.
  Serial.println(F("Master Ring OK!"));
  MasterRing();                                // меняем состояние охраны
      } else  Serial.println(F("No Master Ring!"));  
    } else if (val.indexOf(F("+CMT")) > -1) {  // если обнаруженa СМС
  Serial.println(F("Process CMT"));                            
  Serial.println(String(F("SMS->")) + val);    // что пришло в смс
        if (CheckPhone() == 1) {               // если СМС от хозяина
  Serial.println(F("Master SMS OK!"));
  MasterSMS();
        } else  Serial.println(F("No Master SMS!"));
      } else if(val.indexOf(F("+CUSD:")) > -1) { // если пришел баланс 
        // команда проверки баланса  AT+CUSD=1,#105#,15
        // анализируем строку 
        int p1 = val.indexOf(F("\""));         // начало строки
        int p2 = val.lastIndexOf(F("\""));     // конец строки
        val = val.substring(p1+1,p2);
        Serial.println("");
        Serial.println(F("Input string:"));    // пишем в порт пришедшую строку
        Serial.println(val);
        String decodestr;
        Decode7bit(val, decodestr);
        Serial.println("");
        Serial.println(F("Decode string:"));   // пишем в порт конвертированную строку
        Serial.println(decodestr);
sms(String("SIM " + decodestr), RingPhone);    // смс на последний звонивший
         } else if (val.indexOf(F("+CSQ:")) > -1) { // пришел уровень сигнала сети
          int x = val.indexOf("+CSQ:");
          CSQ = "Signal " + val.substring(x+5, x+7) + "%";
           } val = ""; 
  } if (Serial.available()) {           // если в мониторе порта что-то ввели
        while (Serial.available()) {         // сохраняем входную строку в переменную val.
        char ch = Serial.read();
        val += char(ch);                   // собираем принятые символы в строку
        delay(3);
        } 
  ConsolePrint();                        // запускаем консольную программу
        val = "";  
    }
}

int CheckPhone() { /// === проверка телефона === ///
  if (Firststart == 0) {                        // если не первый старт
    for (int i = 0; i < 5; i++) {
      if (val.indexOf(AlarmPhone[i]) > -1) {    // && val.indexOf(AlarmPhone[i]) != 0) { // если есть вызов, и он наш
        RingPhone = AlarmPhone[i];              // запоминаем его.
        RingPhone.toCharArray(Phone, 12);   
        EEPROM.put(100, Phone);                 // записываем RingPhone в память. 
  Serial.println(String(F("RingPhone ")) + RingPhone);          
        return 1;                               // возвращаем 1 - номер наш!
      } 
    } return 0;                                 // возвращаем 0 - номер не наш!
  } else if (Firststart == 1) {                 // иначе (если первый старт)
// первый звонивший добавляется как основной мастер номер для управления сигнализацией
      if (val.indexOf("+CLIP: \"7") > -1) {
      int ind = val.indexOf("+CLIP:");          // обрезаем номер 
      String num = val.substring(ind + 8, ind + 19); 
      num.toCharArray(Phone, 12);
      EEPROM.put(25, Phone);                    // пишем номер в EEPROM
      EEPROM.put(100, Phone);                   // записываем RingPhone в память. 
      AlarmPhone[0] = Phone;                    // запишем
      RingPhone = Phone;                        // запоминаем его.
      EEPROM.update(10, 0);                     // обновляем Firststart
      Firststart = 0;                           // пишем 0
  Serial.println(String(F("Master0:")) + AlarmPhone[0]); 
  Serial.println(String(F("Firststart:")) + Firststart);
sms(String("Master0:" + num + " Ok"), num);     // смс на звонивший
//  приходит смс в виде: " Master0:79111234567 Ok "
      }
    } return 1;                               
}

void eepromconfig() { /// === конфигурирование сигнализации === ///
    pinMode(13, OUTPUT);
    if (EEPROM.read(0) != 1) {           // если записана не 1
      for (int i = 0 ; i < 512 ; i++) {  // переписываем все ячейки
        EEPROM.write(i, 0);
      }                      // и записываем:
      EEPROM.update(1, 0);   // Guard       охрана выкл.
      EEPROM.update(2, 1);   // AlarmRING   вызов вкл.
      EEPROM.update(3, 1);   // SendSMS     смс вкл.
      EEPROM.update(4, 1);   // DOORon      датчики дверей вкл.
      EEPROM.update(5, 1);   // PIRon       датчик движения вкл.
      EEPROM.update(6, 1);   // GASon       датчик газа вкл.
      EEPROM.update(7, 1);   // Sirena      сирена вкл.
      EEPROM.update(10, 1);  // Firststart  первый старт!.
      EEPROM.update(20, 0);  // баланс, записываем массив в EEPROM 
      EEPROM.update(0, 1);   // 
      digitalWrite(13, HIGH);
  Serial.println(F("EEPROM != 1/ RESET!")); 
    }
    if (EEPROM.read(0) == 1) {
      Guard      = EEPROM.read(1);   // Охрана
      AlarmRING  = EEPROM.read(2);   // Вызов
      SendSMS    = EEPROM.read(3);   // Отправка смс
      DOORon     = EEPROM.read(4);   // Датчик двери
      PIRon      = EEPROM.read(5);   // Датчик движения
      GASon      = EEPROM.read(6);   // Датчик газа/дыма
      Sirena     = EEPROM.read(7);   // сирена
      Firststart = EEPROM.read(10);  //
    }
}

void eepromtext() { /// === состояние системы === ///
   mySerial.println("AT+CSQ");
   TempC();
   delay(250);
   String SIGN = "";         // текущее состояние системы.
   String SIRENA = "";       // аварийная сирена.
   String RING = "";         // текущее состояние вызов.
   String SMS = "";          // текущее состояние смс.
   String Door = "";         // текущее состояние датчика двери.
   String Pir = "";          // текущее состояние датчика движения.
   String Gas = "";          // текущее состояние датчика газа.
   if (Guard == 1) SIGN = String(F("System on\n")); else (SIGN = String(F("System off\n")));
   if (Sirena == 1) SIRENA = String(F("Sirena on\n")); else (SIRENA = String(F("Sirena off\n")));
   if (AlarmRING == 1) RING = String(F("Ring on\n")); else (RING = String(F("Ring off\n")));
   if (SendSMS == 1) SMS = String(F("SMS on\n")); else (SMS = String(F("SMS off\n")));
   if (PIRon == 1) Pir = String(F("Pir on\n")); else (Pir = String(F("Pir off\n")));
   if (DOORon == 1) Door = String(F("Door on\n")); else (Door = String(F("Door off\n")));
   if (GASon == 1) Gas = String(F("Gas on\n")); else (Gas = String(F("Gas off\n")));
    String System = SIGN + SIRENA + RING + SMS;     // состояние (вкл/выкл) системы.
    String Sensors = Pir + Door + Gas + temp;       // состояние (вкл/выкл) датчиков.
    LastEvent = System + Sensors + CSQ;             // полное состояние системы и датчиков.
  Serial.println(LastEvent);
}

void eepromphone() { /// === чтение мастер-номеров из EEPROM === ///
    for (int i = 0; i < 5 ; i++) {
      EEPROM.get(Adress[i], Phone);        // считываем мастер-номера 
      if (Phone != 0) AlarmPhone[i] = Phone;
  Serial.println(String(F("Phone[")) + i + String(F("]:")) + AlarmPhone[i]); 
    }
    EEPROM.get(100, Phone);                // считываем номер последнего звонившего
    RingPhone = Phone;
  Serial.println(String(F("Ring [ ]:")) + RingPhone);
    EEPROM.get(20, Bal);                   // считываем номер баланса
  Serial.println(String(F("Balance:")) + Bal);
    Firststart = EEPROM.read(10);          // cчитаем первый старт
  Serial.println(String(F("Firststart:")) + Firststart);
}

void Detect() { /// === чтение датчиков === ///
  DOORState = digitalRead(DOOR);
  PIRState = digitalRead(PIR);
  Smoky = analogRead(GAS);
  
  if (DOORon == 1) {
    if (DOORState == HIGH && DOORFlag == 0) {
      previousMillis_door = millis();
      DOORFlag = 1;
  Serial.println(F("Dver' otkrita!"));
  Alarm();                                // 
    }
    if (DOORState == LOW && DOORFlag == 1) {
      int currentMillis_door = millis();
      if (((currentMillis_door - previousMillis_door) / 1000 > interval_door)) {
        DOORFlag = 0;
      }
    }
  }
  if (PIRon == 1) {
    if (PIRState == HIGH && PIRFlag == 0) {
      previousMillis_pir = millis();
      PIRFlag = 1;
  Serial.println(F("Dvizhenie u dveri!"));
  Alarm();                                // 
    }
    if (PIRState == LOW && PIRFlag == 1) {
      int currentMillis_pir = millis();
      if (((currentMillis_pir - previousMillis_pir) / 1000 > interval_door)) {
        PIRFlag = 0; 
      }
    }
  }
  if (GASon == 1) {
    if ((Smoky > GASThres) && GASFlag == 0) {
      previousMillis_gas = millis();
      GASFlag = 1;
      delay(100);
  Serial.println(F("Gas v dome!"));
  Alarm();                                // 
    }
    if ((Smoky < GASThres) && GASFlag == 1) {
      int currentMillis_gas = millis();
      if (((currentMillis_gas - previousMillis_gas) / 1000 > interval_door)) {
        GASFlag = 0; 
      }
    }
  }
}

void Alarm() { /// === запускаем сирену и отправку смс === ///
  if (Guard == 1) {
    previousMillis_alarm = millis();
    if (Sirena == 1) digitalWrite(BUZ, LOW);
    Serial.println(F("Alarm!!!"));  
    if (SendSMS == 1) {
      for (int i = 0; i < 5; i++) {           // if (AlarmPhone[i] != 0)  {
        if (DOORFlag == 1) {
sms(String("Dver' otkrita!"), AlarmPhone[i]); // смс на все номера
        }
        if (PIRFlag == 1) {
sms(String("Dvizhenie y dveri!"), AlarmPhone[i]); // смс на все номера
        }
        if (GASFlag == 1) {
sms(String("Gas v dome!"), AlarmPhone[i]); // смс на все номера
        }
      }
    }
    if (AlarmRING == 1) {
      mySerial.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру
    }
  }
}

void AlarmPinOff() { /// === если прошло время, отключаем сирену === ///      
  int currentMillis_alarm = millis();
  if (((currentMillis_alarm - previousMillis_alarm) / 1000 > interval_alarm) || Guard == 0) {
    digitalWrite(BUZ, HIGH);
  } 
}

void MasterRing() { /// === мастер звонков === //
  if (Guard == 1) GuardOff();     // меняем состояние
  else if (Guard == 0) GuardOn(); // меняем состояние
}

void GuardOff() { /// === выключение сигнализации === ///
    Guard = 0;
    EEPROM.update(1, Guard);
  Serial.println(String(F("System->off. Ring:")) + RingPhone);
    for (int i = 0; i < 5; i++) {                                     // if (AlarmPhone[i] != 0)  {
sms(String("System->off " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
}

void GuardOn() { /// === включение сигнализации === ///       
    Guard = 1;
    EEPROM.update(1, Guard);
  Serial.println(String(F("System->on. Ring:")) + RingPhone);
    for (int i = 0; i < 5; i++) {                                    // if (AlarmPhone[i] != 0)  {
sms(String("System->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
}

void LED() { /// === состояние светодиода === ///
  if (Guard == 1) {                   // если на охране
  int currentMillis_led = millis();  // светодиод моргает
  //проверяем не прошел ли нужный интервал, если прошел то
    if (currentMillis_led - previousMillis_led > interval_led) {
      // сохраняем время последнего переключения
      previousMillis_led = currentMillis_led;
      // если светодиод не горит, то зажигаем, и наоборот
      if (LedState == HIGH) LedState = LOW;
      else LedState = HIGH;
      digitalWrite(Led, LedState);
    }
  } else digitalWrite(Led, HIGH); // иначе гасим его
}

void ConsolePrint() { /// === кончсольная программа === ///
    val.toLowerCase();
  if (val.indexOf(F("reset")) > -1) {    // сброс ЕЕПРОМ
  Serial.println(F("Reset System!"));  
    EEPROM.write(0, 0);
  eepromconfig();
  }
  if (val.indexOf(F("master")) > -1) {   // добавление мастер-номера
    master(val.substring(6, 7).toInt(), val.substring(8, 19));
// sms типа: " master1:79111234567 " - номер в ячейку "1", куда записать номер
  }
  if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
    balnum(val.substring(8, 13));
// sms типа: " balance:100 " - номер баланса
  }
  if (val.indexOf(F("dell:")) > -1) {    // удаление номера из ячейки     
    dellphone(val.substring(5, 6).toInt());
// sms типа: " dell:1 " - удалить номер из ячейки 1
  }
  if (val.indexOf(F("phone")) > -1)     { // инфо о состоянии системы
  eepromphone();
  }
  if (val.indexOf(F("status")) > -1) {     // инфо о состоянии системы
  eepromconfig();
  eepromtext();
  }
  if (val.indexOf(F("info")) > -1)    {   // запрос баланса
  Serial.println(Info1 + Info2 + Info3);  // 
  }
  if (val.indexOf(F("money")) > -1) {    // запрос баланса
  balance();
  }
  if (val.indexOf(F("sirenaon")) > -1) {
    EEPROM.update(7, 1);   // Sirena      сирена вкл.
  }
  if (val.indexOf(F("sirenaoff")) > -1) {
    EEPROM.update(7, 0);   // Sirena      сирена выкл.
  }
  if (val.indexOf(F("systemon")) > -1) {  // вкл сигнализации
  GuardOn();
  }
  if (val.indexOf(F("systemoff")) > -1) { // выкл сигнализации
  GuardOff();
  }
  if (val.indexOf(F("ringon")) > -1) {   // вкл вызов при сработке
    AlarmRING = 1;
    EEPROM.update(2, AlarmRING);
  Serial.println(F("Ring->on"));      
  }
  if (val.indexOf(F("ringoff")) > -1) {  // выкл вызов при сработке
    AlarmRING = 0;
    EEPROM.update(2, AlarmRING);
  Serial.println(F("Ring->off"));  
  }
  if (val.indexOf(F("smson")) > -1) {    // вкл смс при сработке
    SendSMS = 1;
    EEPROM.update(3, SendSMS);
  Serial.println(F("SMS->on"));  
  }
  if (val.indexOf(F("smsoff")) > -1) {   // выкл смс при сработке
    SendSMS = 0;
    EEPROM.update(3, SendSMS);
  Serial.println(F("SMS->off"));  
  }
  if (val.indexOf(F("dooron")) > -1) {  // выкл вызов при сработке
    DOORon = 1;
    EEPROM.update(4, DOORon);
  Serial.println(F("DOOR->on"));  
  }
  if (val.indexOf(F("dooroff")) > -1) {  // выкл вызов при сработке
    DOORon = 0;
    EEPROM.update(4, DOORon);
  Serial.println(F("DOOR->off"));  
  }
  if (val.indexOf(F("piron")) > -1) {  // выкл вызов при сработке
    PIRon = 1;
    EEPROM.update(5, PIRon);
  Serial.println(F("PIR->on"));  
  }
  if (val.indexOf(F("piroff")) > -1) {  // выкл вызов при сработке
    PIRon = 0;
    EEPROM.update(5, PIRon);
  Serial.println(F("PIR->off"));  
  }
  if (val.indexOf(F("gason")) > -1) {  // выкл вызов при сработке
    GASon = 1;
    EEPROM.update(6, GASon);
  Serial.println(F("GAS->on"));  
  }
  if (val.indexOf(F("gasoff")) > -1) {  // выкл вызов при сработке
    GASon = 0;
    EEPROM.update(6, GASon);
  Serial.println(F("GAS->off"));  
  }
}

void MasterSMS() { /// === мастер смс === ///
    val.toLowerCase();
  if (RingPhone == AlarmPhone[0]) {        // команды выполняются только с 0 мастер номера
    if (val.indexOf(F("reset")) > -1)    { // полный сброс ЕЕПРОМ
sms(String("All System Reset!!!"), RingPhone); // смс на последний номер
  Serial.println(F("Reset System!!!"));          
      EEPROM.write(0, 0);
  eepromconfig();
    }
    if ((p = val.indexOf(F("master"))) > -1)  { // добавление мастер-номера
      master(val.substring(p + 6, p + 7).toInt(), val.substring(p + 8, p + 19));
///// sms типа: " master1:79111234567 " - ячейка + номер
    }
    if ((p = val.indexOf(F("balance:"))) > -1) { // добавление номера баланса
      balnum(val.substring(p + 8, p + 11));
///// sms типа: " balance:100 " - номер баланса
    } 
    if ((p = val.indexOf(F("dell:"))) > -1) { // удаление номера из ячейки     
      dellphone(val.substring(p + 5, p + 6).toInt());
///// sms типа: " dell:1 " - удалить номер из ячейки 1
    } 
    if (val.indexOf(F("phone")) > -1)     { // инфо о состоянии системы
  eepromphone();
      for (int i = 0; i < 5 ; i++)  if (AlarmPhone[i] != 0) {
sms(String(String("Master") + i + String(":") + AlarmPhone[i]), RingPhone); // смс на последний номер
      }
    }
  }  
  if (val.indexOf(F("info")) > -1)    {   // запрос баланса
sms(Info1 + Info2 + Info3, RingPhone); // смс на последний номер
  }
  if (val.indexOf(F("status")) > -1) { // инфо о состоянии системы
  eepromconfig();
  eepromtext();
sms(String(LastEvent), RingPhone); // смс на последний номер
  }
  if (val.indexOf(F("money")) > -1)    {   // запрос баланса
  balance();
  }
  if (val.indexOf(F("sirenaon")) > -1) {
    EEPROM.update(7, 1);                   // сирена вкл.
  }
  if (val.indexOf(F("sirenaoff")) > -1) {
    EEPROM.update(7, 0);                   // сирена выкл.
  }
  if (val.indexOf(F("systemon")) > -1)  {  // вкл сигнализации
  GuardOn();
  }
  if (val.indexOf(F("systemoff")) > -1) {  // выкл сигнализации
  GuardOff();
  }
  for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) { // смс на все номера          
    if (val.indexOf(F("ringon")) > -1)   { // вкл вызов при сработке
      AlarmRING = 1;
      EEPROM.update(2, AlarmRING);
  Serial.println(F("AlarmRing->on"));      
sms(String("Ring->on" + RingPhone  + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
    if (val.indexOf(F("ringoff")) > -1)  { // выкл вызов при сработке
      AlarmRING = 0;
      EEPROM.update(2, AlarmRING);
  Serial.println(F("AlarmRing->off"));  
sms(String("Ring->off" + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
    if (val.indexOf(F("smson")) > -1)    { // вкл смс при сработке
      SendSMS = 1;
      EEPROM.update(3, SendSMS);
  Serial.println(F("SendSMS->on"));  
sms(String("SMS->on" + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
    if (val.indexOf(F("smsoff")) > -1)   { // выкл смс при сработке
      SendSMS = 0;
      EEPROM.update(3, SendSMS);
  Serial.println(F("SendSMS->off"));  
sms(String("SMS->off" + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
    if (val.indexOf(F("dooron")) > -1) {  // выкл вызов при сработке
    DOORon = 1;
    EEPROM.update(4, DOORon);
  Serial.println(F("DOOR->on"));  
sms(String("DOOR->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
    if (val.indexOf(F("dooroff")) > -1) {  // выкл вызов при сработке
    DOORon = 0;
    EEPROM.update(4, DOORon);
  Serial.println(F("DOOR->off"));  
sms(String("DOOR->off" + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
    if (val.indexOf(F("piron")) > -1) {  // выкл вызов при сработке
    PIRon = 1;
    EEPROM.update(5, PIRon);
  Serial.println(F("PIR->on"));  
sms(String("PIR->on" + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
    if (val.indexOf(F("piroff")) > -1) {  // выкл вызов при сработке
    PIRon = 0;
    EEPROM.update(5, PIRon);
  Serial.println(F("PIR -> off"));  
sms(String("PIR -> off" + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
    if (val.indexOf(F("gason")) > -1) {  // выкл вызов при сработке
    GASon = 1;
    EEPROM.update(6, GASon);
  Serial.println(F("GAS->on"));  
sms(String("GAS->on" + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
    if (val.indexOf(F("gasoff")) > -1) {  // выкл вызов при сработке
    GASon = 0;
    EEPROM.update(6, GASon);
  Serial.println(F("GAS->off"));  
sms(String("GAS->off" + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
    }
  } 
}

void balance() { /// === проверка баланса сим-карты === ///
  EEPROM.get(20, Bal);        // считываем массив символов
  delay(1000);
  mySerial.println(String(F("AT+CUSD=1,#")) + Bal + String(F("#,15")));
  Serial.println(String("Balance#") + Bal + "#"); 
}

int master (int i, String num) { /// === добавление мастер-номеров === ///
    if (i < 5 && i != 0) {
      num.toCharArray(Phone, 12); // конвертируем
      AlarmPhone[i] = num;        // пишем номер  
  Serial.println(String(F("Master[")) + i + String(F("]:")) + num);
      EEPROM.put(Adress[i], Phone);           // записываем массив в EEPROM 
sms(String(String("Master") + i + ":" + num + " add"), RingPhone); // смс на 0 номер.
sms(String("Master: " + AlarmPhone[i]), AlarmPhone[i]); // смс на добавленный номер.
    } else Serial.println(F("MAX number 4!"));          // 4 номера максимум! 
    // 0 номер можно удалить только через RESET!!!
    return 1;                             
}                              

int dellphone (int i) { /// === удаление мастар-номеров === ///
     if (i < 5 && i != 0) {
  Serial.println(String(F("Master")) + i + String(F(" dell")));
sms(String(String("Master") + i + ":" + AlarmPhone[i] + " dell"), RingPhone); // смс на 0 номер
sms(String("Dell: " + AlarmPhone[i]), AlarmPhone[i]); // смс на удаленный номер.
       EEPROM.put(Adress[i], 0);
       AlarmPhone[i] = "";   // обнулим номер
  } return 1;                          
}

int balnum (String num) { /// === добавляем номер баланса === ///
    num.toCharArray(Bal, 4);   // конвертируем
  Serial.println(String(F("Balance:")) + Bal);
    EEPROM.put(20, Bal);           // записываем массив в EEPROM 
sms(String("Balance:*" + num + "# Ok"), RingPhone); // смс на 0 номер
    return 1;                             
}

void TempC() {      /// === измеряем температуру === ///
  byte data[2];
  ds.reset();
  ds.write(0xCC);
  ds.write(0x44);
  delay(750);
  ds.reset();
  ds.write(0xCC);
  ds.write(0xBE);
  data[0] = ds.read();
  data[1] = ds.read();
  int Temp = (data[1] << 8) + data[0];
  Temp = Temp >> 4;
  temp = String(F("Temp: ")) + Temp + String(F("*C\n"));
}

void Decode7bit(String &instr, String &outstr) { /// === декодирование баланса === ///
  byte reminder = 0;
  int bitstate = 7;
  for (unsigned int i = 0; i < instr.length(); i++) {
    byte b = instr[i];
    byte bb = b << (7 - bitstate);
    char c = (bb + reminder) & 0x7F;
    outstr += c;
    reminder = b >> bitstate;
    bitstate--;
    if (bitstate == 0) {
      char c = reminder;
      outstr += c;
      reminder = 0;
      bitstate = 7;
    }
  }
}

void InitModem() { /// === инициализация модема === ///
  Serial.println(F("Start GSM"));
  mySerial.begin(9600);  //Скорость порта для связи Arduino с GSM модулем
  waitConnect();
  Serial.println(F("GSM connected"));
  waitRegistration();
  delay(1000); 
}

void waitConnect() { /// === запуск модема === ///
  int countok = 0;
  String str; 
  while(countok < 5) {                   //ждём пять ОК  
    uint32_t ms = millis();
    if( ( ms - msAT ) > 500 || ms < msAT ) {// Событие срабатывающее каждые 500 мс 
      msAT = ms;
//      Serial.println(">>AT");
      mySerial.println(F("AT"));          // посылаем команду
      str = "";
      delay(100);                      // ждём ответа
      while(mySerial.available()) {
        char ch = mySerial.read();
        str += ch;
      } 
//      Serial.println("C>");
//      Serial.println(str);
      if(str.indexOf(F("OK")) > -1)
        countok++;
      else
        countok = 0;
    }
  }  
  Serial.println(F("Turn on AOH:"));
  mySerial.println(F("AT+CLIP=1"));  // включить АОН
  delay(200);
  Serial.println(F("GSM registration"));
  mySerial.println(F("AT+CMGF=1"));
  delay(200); 
  Serial.println(F("Mode GSM:"));
  mySerial.println(F("AT+CSCS=GSM"));  // кодировка текста - GSM
  delay(300);
  mySerial.println(F("AT+CNMI=2,2,0,0,0"));
  delay(300); 
}

void waitRegistration() { /// === регистрация модема в сети === ///
  bool ok = 0;
  String str;
  while(!ok) {  
    uint32_t ms = millis();
    if( ( ms - msAT ) > 500 || ms < msAT ) { // Событие срабатывающее каждые 500 мс
      msAT = ms;
      Serial.println(F(">>AT+CREG?"));
      mySerial.println(F("AT+CREG?"));      //посылаем команду
      delay(100);                           //Ждём ответа
      str = "";
      while(mySerial.available()) {
           char ch = mySerial.read();
           str += ch;
      } 
      Serial.println(F("R>"));
      Serial.println(str);
      if(str.indexOf(F("+CREG:"))>-1)
        ok = 1;
    }
  }  
}

void sms(String text, String phone) { /// === отправка СМС === ///
  if (phone != 0) {
    phone = "+" + phone;
    Serial.println(F("Start SMS send")); 
    mySerial.println(String(F("AT+CMGS=\"")) + phone + String(F("\"")));
    delay(300);
    mySerial.print(text);
    delay(300);
    mySerial.print((char)26);
    delay(300);
    Serial.println(String(F("SMS sended! Phone: ")) + phone + String(F("; Message: ")) + text);
    delay(5000);
  }
}

у кого есть беспроводной датчик двери,

читаем его код:


#include <RCSwitch.h>

RCSwitch mySwitch = RCSwitch();

void setup() {
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // 433 приемник на 2 цифровом пине

}

void loop() {
  if (mySwitch.available()) {
    
    int value = mySwitch.getReceivedValue();
    
    if (value == 0) {
      Serial.print("Unknown encoding");
    } else {
      Serial.print("Received ");
      Serial.print( mySwitch.getReceivedValue() );   // здесь код датчика
      Serial.print(" / ");
      Serial.print( mySwitch.getReceivedBitlength() );
      Serial.print("bit ");
      Serial.print("Protocol: ");
      Serial.println( mySwitch.getReceivedProtocol() );
    }

    mySwitch.resetAvailable();
  }
}

поправляем его в коде, и реагируем на открытие двери, можно добавить в мой код, работает аналогично датчику открытия - геркона, только вот столкнулся с проблемой: он работает только на 2 или 3 ноге, а вот как заставить его работать на другой, немогу понять

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
int interval_door2 = 10;        // секунд не смотрим на датчик газа
int previousMillis_door2 = 0;
int8_t DOOR2Flag = 0;       // флаг состояние датчика двери.
#define Led 13             // состояние системы. моргает - на охране.

void setup() {
  Serial.begin(9600);
  pinMode(Led, OUTPUT);             // светодиод горит во время запуска.
  digitalWrite(Led, LOW);        // гасим светодиод состояния сигнализации. 
  mySwitch.enableReceive(0);     // 433 приемник на 2 цифровом пине  
}

void loop() {
  if (mySwitch.available()) {
    unsigned long value = mySwitch.getReceivedValue();
    if (value == 3258553 && DOOR2Flag == 0) {   // вместо 3258553 пишем код вашего датчика

      previousMillis_door2 = millis();
      DOOR2Flag = 1;
      Serial.println("Detected");
  digitalWrite(Led, HIGH);        // гасим светодиод состояния сигнализации. 
    }
    mySwitch.resetAvailable();
  }
  int currentMillis_door2 = millis();
  if (((currentMillis_door2 - previousMillis_door2) / 1000 > interval_door2)) {
    DOOR2Flag = 0;
    digitalWrite(Led, LOW);        // гасим светодиод состояния сигнализации. 
  }
}

 

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Прерывание наверное используется?

pasha413
Offline
Зарегистрирован: 27.11.2016

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

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Конечно можно и даже нужно. Зачем же пины аппаратного прерывания под порт занимать? Я бы и датчики посоветовал на прерывания пересадить. Так удобнее, чем постоянно состояние пина проверять.

pasha413
Offline
Зарегистрирован: 27.11.2016

А вы с TFT 1.8" 128х160 не занимались? Посоветуете что-нибудь, не могу справиться...
http://arduino.ru/forum/apparatnye-voprosy/tft-18-128x160

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

http://robocraft.ru/blog/arduino/45.html что-то попалось интересное про прерывания, посмотрите первый комментарий... Что-то мало верится что любой пин ардуинкии может работать с прерыванием... Сейчас не могу проверить

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Увы, с TFT дела не имел. OLED или LCD это пожалуйста! Могу только Nextion посоветовать. Мощная штука с собственными мозгами и тачпадом! С Ардуино взаимодействует тоже через uart. 

pasha413
Offline
Зарегистрирован: 27.11.2016

Спасибо, Umka. Как-нибудь закажу и себе такой

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Можно Ваш код использовать для своей сигналки? Тут заумак интересная, могу поделиться в лс проектом.

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

Baks пишет:
Что-то мало верится что любой пин ардуинкии может работать с прерыванием...
Пазве это объект веры? Верить или не верить можно в Бога, а тут-то чего?

Конечно, не все. Vcc, например, не может, ARef с Gnd  - тоже. Если это Нано, то и A6 с A7 не могут. А нормальные пины могут, конечно, если с умом и умеючи.

pasha413
Offline
Зарегистрирован: 27.11.2016

Да, конечно, Umka.
Буду благодарен за ваш проект, как образец для своих.

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Работают, я проверял.

Павел, напишите что-нибудь мне в электропочту mailumka2@gmail.com

pasha413
Offline
Зарегистрирован: 27.11.2016

Umka, написал

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

ЕвгенийП пишет:

Baks пишет:
Что-то мало верится что любой пин ардуинкии может работать с прерыванием...
Пазве это объект веры? Верить или не верить можно в Бога, а тут-то чего?

Конечно, не все. Vcc, например, не может, ARef с Gnd  - тоже. Если это Нано, то и A6 с A7 не могут. А нормальные пины могут, конечно, если с умом и умеючи.

спасибо за подсказку, я читал на сайте 

вот цитата  http://arduino.ru/hardware/arduinoboardnano

 Большинство контроллеров Arduino умеют обрабатывать до двух внешних прерываний, 
пронумерованных так: 0 (на цифровом порту 2) и 1 (на цифровом порту 3). 
Arduino Mega обрабатывает дополнительно еще четыра прерывания: 2 (порт 21), 3 (порт 20), 4 (порт 19) и 5 (порт 18).

Внешнее прерывание: 2 и 3. Данные выводы могут быть сконфигурированы на вызов прерывания либо на младшем значении,
 либо на переднем или заднем фронте, или при изменении значения. 
Подробная информация находится в описании функции attachInterrupt().

поэтому так и отложилось в голове, а не подскажете где можно почитать как повесить прерывание на другие пины?

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Дали же ссылку на библиотеку https://code.google.com/archive/p/arduino-pinchangeint/

Ясное дело что внешние прерывания просто так можно подключить к специально-обученным пинам внешних прерываний. Как и serial доступен на своих пинах. Но есть хитрые библиотеки!

kvolk
Offline
Зарегистрирован: 12.06.2017

ЕвгенийП пишет:

Baks пишет:
Что-то мало верится что любой пин ардуинкии может работать с прерыванием...
Пазве это объект веры? Верить или не верить можно в Бога, а тут-то чего?

Конечно, не все. Vcc, например, не может, ARef с Gnd  - тоже. Если это Нано, то и A6 с A7 не могут. А нормальные пины могут, конечно, если с умом и умеючи.

Только D2 и D3 пины у нано могут обрабатывать внешнее прерывание, не вводите людей в заблуждение.

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

Только с ограничением.

// Do not use any Serial.print() in interrupt subroutines. Serial.print() uses interrupts,
// and by default interrupts are off in interrupt subroutines.
// Here we update a counter corresponding to whichever pin interrupted.

 

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

Речь идёт о т.н. прерываниях по изменению пина - Pin Change Interrupts (PCINT). Разработчики Arduino не стали включать в IDE никаких облегчалок для работы с ними, т.е. надо конфигурить всё самому (ну, или библиотекой пользоваться). Почитать можно в разделе 13 даташита. Наверняка есть какие-то статьи и книги, но я не знаю. Вообще, по поводу кннил, у меня есть большая коллекция литературы по различным МК, вот здесь посмотрите, поройтесь и ссылку сохраните.

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

kvolk пишет:

Только D2 и D3 пины у нано могут обрабатывать внешнее прерывание

Правильно было сказано

kvolk пишет:

не вводите людей в заблуждение.

 

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

проверил библиотеку, реально работает)))) пробовал пины 7 и А4

это меня очень вдохновило на кучу поделок))))

#include <PinChangeInt.h>

// Modify this at your leisure.
#define ARDUINOPIN A4

// Notice that values that get modified inside an interrupt, that I wish to access
// outside the interrupt, are marked "volatile". It tells the compiler not to optimize
// the variable.
volatile uint16_t interruptCount=0; // The count will go back to 0 after hitting 65535.

// Do not use any Serial.print() in interrupt subroutines. Serial.print() uses interrupts,
// and by default interrupts are off in interrupt subroutines. Interrupt routines should also
// be as fast as possible. Here we just increment a counter.
void interruptFunction() {
  interruptCount++;
}

// Attach the interrupt in setup()
void setup() {
  pinMode(ARDUINOPIN, INPUT_PULLUP);  // Configure the pin as an input, and turn on the pullup resistor.
                                      // See http://arduino.cc/en/Tutorial/DigitalPins
  attachPinChangeInterrupt(ARDUINOPIN, interruptFunction, FALLING);
  Serial.begin(115200);
  Serial.println("---------------------------------------");
}

// In the loop, we just check to see where the interrupt count is at. The value gets updated by the
// interrupt routine.
void loop() {
  delay(1000);                            // Every second,
  Serial.print("Pin was interrupted: ");
  Serial.print(interruptCount, DEC);      // print the interrupt count.
  Serial.println(" times so far.");
}

 

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

Baks пишет:

проверил библиотеку, реально работает)))) пробовал пины 7 и А4

это меня очень вдохновило на кучу поделок))))

Вы там поосторожнее, сначала как следует почитайте даташит и погуглите умные статьи. Там есть некоторые ограничения и правила, которые надо соблюдать (например, если Вы используете PCINT прерывание на каком-то пине, то все пины из той же PCINT группы должны бы иметь определённые значения и т.п.). А то будете потом необъяснимые глюки вылавливать и нам всем мозг ими выносить :)

Baks
Baks аватар
Offline
Зарегистрирован: 11.01.2016

хорошо, обязательно почитаю

спасибо за совет!

pasha413
Offline
Зарегистрирован: 27.11.2016

как разделить пришедшую строку

+CPBF: 1,"79111234567",129,"number1"
 +CPBF: 2,"79112345678",129,"number2"
 +CPBF: 3,"79113456789",129,"number3"

на несколько? это номера с СИМ карты, команда AT+CPBF=""

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

А разве нельзя их по одному читать? Выбирать по порядку и читать. Я с телефона не найду, но точно видел команду выбора ячейки номера.

pasha413
Offline
Зарегистрирован: 27.11.2016

Это если знаешь сколько ячеек занято, и какие номера где. Пробовал перебирать ячейки, но не вышло. А вот считывание всей памяти, как я считаю, вариант, но вот не могу разбить строку на количество n -строк, в зависимости от кол-ва пришедших +CPBF

Umka
Umka аватар
Offline
Зарегистрирован: 19.10.2012

А если брать первые 2-5 номеров, остальные игнорить? Первый - мастер.