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

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

По sim800 хорошо описано на сайте codius, даже на ютубе у него видео выложено.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

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

в двух словах не обьясню.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

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

Один мой знакомый сказал, что поколение ............

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

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Short Circuit пишет:

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

в двух словах не обьясню.

Сама логика заключается в использовании AT-команд, описанных в даташите: формируете команду, отправляете её по UART в модем, анализируете ответ - вот и вся логика. Форматы запросов к модему и ответов от модема, вы не поверите - есть в даташите на AT-команды, ссылку на который я вам привёл.

А то, о чём вы пишете - это просто выдёргивание чужого кода, давайте будем честны. Программная логика там - простейшая, не бином Ньютона: отправили команду, получили ответ, делаем, что нужно.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

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

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

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Ну есть же даташит, блин. И ВСЕ библиотеки работают с AT-командами, которые описаны в даташите. Неужели это так сложно понять? И прочитать даташит, наконец?

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

в даташите логика работы программы не описывается :)

даташитами на модемы я пользуюсь еще до присуствия интернета в широком пользовании у нас, сети фидонет и т.д.. модемы 2400 по телефонным линиям.....  так что даташитами можно меня не пугать :)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Ясно. Той логики, что я привёл - недостаточно, оказывается. Всё, я ушёл, эту логику, когда надо содрать кусок кода - мне не понять. Это называется не разбираться - а передрать, и никак иначе.

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

sendCommand("get count of stored SMS");
int smsCount = receiveAnswerFromUART().toInt();

for(int i=0;i<smsCount;i++)
{
  SMSInfo smsInfo = sendCommand("get info about stored SMS", i);
  if(smsInfo.senderNumber == ourNumber)
  {
    doTheDirtyJob();
  }
}

Вот вся логика, в псевдокоде - несколько строчек. Это именно логика, наполнить её конкретным кодом - задача, посильная после прочтения таки даташита. А пока ваши бравирования по поводу фидонет и пр. - пустой трёп, вы даже не открывали даташит на команды SIM800 с указанной мной страницы, иначе бы уже не задавались вопросом про простейшую логику.

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

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

Один мой знакомый сказал

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

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

d13lider пишет:

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

Один мой знакомый сказал

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

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

 

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

b707 пишет:

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

ну так я это и имел ввиду, b707 вы очень опытный, и всегда готовы помочь, спасибо вам за это, и не обижайся пожалуйста когда люди вообще тупят конкретно, и не понимают простые вещи, когда вы начинали изучение МК и у вас были бы люди которые готовы были помочь, и столько информации, я думаю вы бы не упускали такю возможность, что бы посоветоватся и уточнить у других, более оптыных, так, что такова ваша "доля"))) 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Short Circuit пишет:

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

в двух словах не обьясню.

За сегодня написал логику - выложить?
Только завтра - все на работе.
Но ещё не дописано раскодировка UCS2 сообщений.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015
andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

Читал, хорошая статейка, но ничего нового. 

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

вот здесь сама идея подробно расписана, но уже вижу  что нужно менять. Например там указано остслеживать от модема +CMTI: "SM".

Этого не нужно делать, нужно переиодически опрашивать - пришло новое смс или нет.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

pasha413 пишет:

kvolk, навскидку, можно оптимизировать ваш код процентов на 5, если заменить условия:

if {
}
if {
}
if {
}

на:

if {
}
else if {
}
else if {
}

 

 

на шести ифах почти 100байт  флеша можно высвободить, никак не 5%... 

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

Здравствуйте. давно не писал.

сейчас на даче стоит сигнализация в корпусе D4MG

 

модем используется А6, стабилизатор напряжения на LM2596 5V для питания датчиков, ардуины и модема.

ну и сам код:

// 0 (основной) мастер-номер добавляется при первом звонке либо смс на систему.
// при звонке на номер сигнализации - прослушка помещения.
// при сработке датчиков- вызов (если ring on) на 0 мастер-номер и смс (если sms on) всем.
// длинна сообщения 123 символов.
/* 
 *Команды управления для 0 мастер-номера:
    "reset"                 сброс настроек и номеров на заводские.
    "master1:79112345678"   добавить номер 79112345678 в ячейку памяти 1.
    "balance:100"           номер баланса *100#.
    "dell:1"                удалить номер из ячейки 1.
    "phone"                 вывести список номеров в системе.
 *Команды управления для всех мастер-номеров:
    "info" либо "?"         инфо о состояни системы и уровня сигнала сети.
    "datchiki on\off"       вкл/выкл все датчики.
    "system on\off"         вкл/выкл охрану.
    "ring on\off"           вкл/выкл вызов при аварии или сработке сигнализации.
    "sirena on\off"         вкл/выкл сирену при сработке.
    "sms on\off"            вкл/выкл смс при аварии или сработке сигнализации.
    "door on\off"           вкл/выкл контроль датчика двери.
    "sarai on\off"          вкл/выкл контроль датчика двери сарая.
    "pir on\off"            вкл/выкл контроль датчика движения.
    "gas on\off"            вкл/выкл контроль датчика газа.
*/

#include <EEPROM.h>
#include <OneWire.h>
#include <RCSwitch.h>
#include <SoftwareSerial.h>
#include <DallasTemperature.h>
#define Ver F("Alarm  v2.1.3\n")

OneWire DS18B20(15);             // датчик температуры, подтяжка 4.7кОм на +.
DallasTemperature ds(&DS18B20);
SoftwareSerial gsm(4, 5);        // модем.
RCSwitch mySwitch = RCSwitch();  // беспроводной датчик двери, пин 2.

#define DOOR   17           // концевик двери. если сработал, на входе "+" HIGH.
#define PIR    16           // датчик движения. если сработал, на входе "+" HIGH.
#define GAS    14           // датчик дыма. если сработал, на входе "+" HIGH.
#define LED    9            // состояние системы. если "-" LOW, то горит.
#define BUZ    10           // сирена. если "-" LOW, то горит.
#define sarai 3258553       // адрес 433 передатчика геркона двери. если сработал, на пин 2 сигнал.
#define rst    3            // reset модема.

#define on  "on"            // вкл
#define off "off"           // выкл

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

boolean DOORFlag = false;       // флаг состояние датчика двери.
boolean SARAIFlag = false;      // флаг состояние датчика двери 2.
boolean PIRFlag = false;        // флаг состояние датчика движения.
boolean GASFlag = false;        // флаг состояние датчика газа.
int8_t LEDState = LOW;          // Состояние светодиода.
int8_t DOORState = LOW;         // Состояние концевика двери.
int8_t PIRState = LOW;          // Состояние датчика движения.
int8_t Smoky = LOW;             // Состояние датчика газа.

float Temp_ul = false;          // температура.                
float Temp_pom = false;         // температура.                
char CSQ[4];                    // для хранения уровня сигнала.
char Bal[4];                    // для временного хранения номера баланса.
char Phone[14];                 // для временного хранения номера телефона, номер до 14 цифр.

String bal = "";                // хранение баланса.
String RingPhone = "";          // номер звонившего.
String AlarmPhone[5];           // номера для постановки/снятии с охраны и отправки смс.
byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ.

unsigned int p = 0;
#define GASThres 400        // предельная концентрация газа
#define time_alarm 20       // Секунд до отключения "тревожного" пина. 
unsigned long lasttime_alarm = 0;
#define interval_led 1000   // для мигания LED, 1 сек.
unsigned long previousMillis_led = 0;
#define time_door 10        // секунд не смотрим на датчик двери.
unsigned long lasttime_door = 0;
#define time_sarai 10       // секунд не смотрим на датчик двери 2.
unsigned long lasttime_sarai = 0;
#define time_pir 20         // секунд не смотрим на датчик движения.
unsigned long lasttime_pir = 0;
#define time_gas 600        // секунд не смотрим на датчик газа. 10 минут
unsigned long lasttime_gas = 0;
unsigned long timer = 300000;

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

void setup() { /// === настройка программы === ///
  Serial.begin(9600);
  Serial.println(Ver);
  ds.begin();                                    // Запуск библиотеки, по умолчанию 9 бит
  pinMode(DOOR, INPUT_PULLUP);                   // вход датчика двери с подтяжкой на +.
  pinMode(PIR, INPUT);  digitalWrite(PIR, HIGH); //
  pinMode(GAS, INPUT);
  pinMode(BUZ, OUTPUT); digitalWrite(BUZ, LOW);  // сирена выкл.
  pinMode(LED, OUTPUT); 
  pinMode(rst, OUTPUT); digitalWrite(rst, LOW);  // 
  mySwitch.enableReceive(0);                     // RF433 приемник на 2 пине
  Restart();                                     // перезапускаем систему
}

void loop() {  /// === основной цикл программы === ///
  AlarmPinOff();    // выключаем сирену, если прошло  время.
  if (millis()/1000 > timer) {  // проверяем каждый час 
    TempC();
    Signal();
    timer += 360; 
  }
  if (Guard == 1) { // если на охране
    Detect();       // проверяем датчики.
    Led();          // моргаем светодиодом.
  } else digitalWrite(LED, LOW);
  if (gsm.available()) {               // Если модем что-то отправил...
    serial = false;
    String gval = "";                  // Переменная для хранения ответа модуля
      while (gsm.available()) {        
        char ch = gsm.read();
        gval += char(ch);              // сохраняем входную строку в переменную gval
        delay(3);
      }
//Serial.println("gval->" + gval);
   if (gval.indexOf(F("RING")) > -1) {        // если обнаружен вызов.
      sendATCommand(F("ATH"));                // снимаем трубку  
      for (int i = 0; i < 5; i++) {           // проверяем сохраненные номера
        if (gval.indexOf(AlarmPhone[i]) > -1 && AlarmPhone[i] != 0) {  // если он наш
          RingPhone = AlarmPhone[i];          // запоминаем номер звонящего
          RingPhone.toCharArray(Phone, 14);   
          EEPROM.put(100, Phone);             // записываем RingPhone в память. 
        } else if (Firststart) {              // если первый старт
          int ind = gval.indexOf(F("+CLIP: \""));   // обрезаем номер ... 
          ind += 8;
          String ring = gval.substring(ind, gval.indexOf("\"", ind));
          RingPhone = ring;                         // запоминаем номер звонящего 
          ring.toCharArray(Phone, 14);              // сохраняем в переменную Phone
          EEPROM.put(25, Phone);                    // пишем номер в EEPROM как основной мастер-номер
          EEPROM.put(100, Phone);                   // записываем RingPhone в память. 
          AlarmPhone[0] = Phone;                    // запишем
          Firststart = false;                       // пишем 0
          EEPROM.update(10, Firststart);            // обновляем Firststart
Serial.println(String(F("Firststart:")) + Firststart);
sms(String(F("Master0:")) + ring + " Ok", 0);       // смс на звонивший
//sms("Master0:" + ring + " Ok", 0);                  // смс на звонивший
        } 
      }
    } else if (gval.indexOf(F("+CMT")) > -1) {      // если обнаруженa СМС
      for (int i = 0; i < 5; i++) {                 // проверяем сохраненные номера
        if (gval.indexOf(AlarmPhone[i]) > -1 && AlarmPhone[i] != 0) { // если он наш 
          RingPhone = AlarmPhone[i];                // запоминаем его.
  parsesms(gval);                                   // запускаем подпрограмму парсинга сообщений
        }
      }     
    } else if (gval.indexOf(F("+CUSD:")) > -1) {  // если пришел баланс
      // анализируем строку
//      bal = "";                            // обнуляем переменную временного хранения баланса
      int p1 = gval.indexOf("\"");         // начало строки
      int p2 = gval.lastIndexOf("\"");     // конец строки
      gval = gval.substring(p1 + 1, p2);   // обрезаем строку
      Decode7bit(gval, bal);               // декодируем сообщение
Serial.println(bal);
      sendATCommand(F("AT+CUSD=0"));       
    } 
  } else if (Serial.available()) {         // если в мониторе порта что-то ввели
    String sval = "";                      // Переменная для хранения сообщения из монитора порта
    while (Serial.available()) {           
      char ch = Serial.read();
      sval += char(ch);                    // сохраняем входную строку в переменную sval.
      delay(3);
    }
    serial = true;
    Komand(sval);                          // запускаем подпрограмму распознавания команд
  }
}

void parsesms(String msg) {
  String msgheader = "";
  String msgsms    = "";
  String msgphone  = "";

  msg = msg.substring(msg.indexOf(F("+CMT: ")));
  msgheader = msg.substring(0, msg.indexOf("\r"));         

  msgsms = msg.substring(msgheader.length() + 2);
  msgsms = msgsms.substring(0, msgsms.lastIndexOf("OK"));  // Выдергиваем текст SMS
  msgsms.trim();                                           // удаляем пробелы вначале и в конце строки

  int Index = msgheader.indexOf(F("+CMT:"));
  Index += 8;                                              // Парсим строку и
  msgphone = msgheader.substring(Index, msgheader.indexOf("\"", Index)); // Выдергиваем телефон
  msgphone.trim();                                         // удаляем пробелы вначале и в конце строки

//Serial.println(String(F("Phone: ")) + msgphone);           // Выводим номер телефона
//Serial.println(String(F("Message: ")) + msgsms);           // Выводим текст SMS
  RingPhone = msgphone;
  RingPhone.toCharArray(Phone, 14);         
  EEPROM.put(100, Phone);                   // записываем номер  
  Komand(msgsms);                           // запускаем подпрограмму распознавания команд
}

void Komand(String kom) { /// === мастер смс === ///
  Serial.println("Kom->" + kom);
  kom.toLowerCase();                              // 
  if (RingPhone == AlarmPhone[0] || serial) { // команды выполняются только с 0 мастер номера
    if (kom.indexOf(F("master")) > -1) {          // добавление дополнительных мастер-номеров
      p = kom.indexOf(F("master"));
      master(kom.substring(p + 6, p + 7).toInt(), kom.substring(p + 8, kom.indexOf("\n", p + 8)));
      ///// sms типа: " master1:79111234567 " - ячейка + номер
    } else if (kom.indexOf(F("balance:")) > -1) { // добавление номера баланса
      p = kom.indexOf(F("balance:"));
      balnum(kom.substring(p + 8, p + 11));
      ///// sms типа: " balance:100 " - номер баланса
    } else if (kom.indexOf(F("dell:")) > -1) {    // удаление мастер-номера из ячейки
      p = kom.indexOf(F("dell:"));
      dellphone(kom.substring(p + 5, p + 6).toInt());
      ///// sms типа: " dell:1 " - удалить номер из ячейки 1
    } else if (kom.indexOf(F("phone")) > -1) {    // список сохраненных номеров
      //  Serial.println(eepromphone());
      sms(eepromphone(), 0); // смс на последний номер
    } else if (kom.indexOf(F("reset")) > -1) {    // полный сброс ЕЕПРОМ!
sms(F("System Full Reset!"), 0); // смс на последний номер
      EEPROM.write(0, false);
      Restart();                                  // перезапускаем 
    } 
  }
  if ((kom.indexOf(F("info")) > -1) || (kom.indexOf(F("?")) > -1)) {  // инфо о состоянии системы
    Signal();                                        // проверяем уровень сигнала сети
    eepromconfig();                                  // считывем конфигурацию системы
sms(eepromtext(), 0);                                // смс на последний номер
  } else if (kom.indexOf(F("datchiki")) > -1) {      // все датчики 
    if (kom.indexOf(on) > -1) {                      // включить все датчики одной командой
      DOORon = true;                                 // вкл датчик двери
      SARAIon = true;                                // вкл датчик двери RF433
      PIRon = true;                                  // вкл датчик движения
      GASon = true;                                  // вкл датчик газа
      EEPROM.update(4, DOORon);                      // пишем в EEPROM
      EEPROM.update(5, SARAIon);                     // пишем в EEPROM
      EEPROM.update(6, PIRon);                       // пишем в EEPROM
      EEPROM.update(7, GASon);                       // пишем в EEPROM
    } else if (kom.indexOf(off) > -1) {              // выключить все датчики
      DOORon = false;                                // выкл датчик двери
      SARAIon = false;                               // выкл датчик двери RF433
      PIRon = false;                                 // выкл датчик движения
      GASon =false;                                  // выкл датчик газа
      EEPROM.update(4, DOORon);                      // пишем в EEPROM
      EEPROM.update(5, SARAIon);                     // пишем в EEPROM
      EEPROM.update(6, PIRon);                       // пишем в EEPROM
      EEPROM.update(7, GASon);                       // пишем в EEPROM
    }
sms(eepromtext(), 1);                                // смс на последний номер
  } else if (kom.indexOf(F("system")) > -1)  {       // вкл/выкл сигнализацию
    if (kom.indexOf(on) > -1) GuardOn();             // если вкл, то включаем сигнализацию
    else if (kom.indexOf(off) > -1) GuardOff();      // если выкл, то выключаем сигнализацию
  } else if (kom.indexOf(F("sirena")) > -1) {        // вкл/выкл сирены
    if (kom.indexOf(on) > -1) {                      // вкл сирену при сработке        
      Sirena = true;    
      EEPROM.update(8, Sirena);                      // пишем в EEPROM
sms(String(F("Sirena->on")), 1);                     // смс на все номера 
    } else if (kom.indexOf(off) > -1) {              // выкл сирену при сработке
      Sirena = false; 
      EEPROM.update(8, Sirena);                      // пишем в EEPROM
sms(String(F("Sirena->off")), 1);                    // смс на все номера
    }
  } else if (kom.indexOf(F("ring")) > -1) {          // вкл/выкл вызов при сработке
    if (kom.indexOf(on) > -1)   {                    // вкл вызов при сработке
      AlarmRING = true;
      EEPROM.update(2, AlarmRING);                   // пишем в EEPROM
sms(String(F("Ring->on")), 1);                       // смс на все номера
    } else if (kom.indexOf(off) > -1) {              // выкл вызов при сработке
      AlarmRING = false;
      EEPROM.update(2, AlarmRING);                   // пишем в EEPROM
sms(String(F("Ring->off")), 1);                      // смс на все номера
    }
  } else if (kom.indexOf(F("sms")) > -1) {           // вкл/выкл смс при сработке
    if (kom.indexOf(on) > -1) {                      // вкл смс при сработке
      SendSMS = true;
      EEPROM.update(3, SendSMS);                     // пишем в EEPROM
sms(String(F("SMS->on")), 1);                        // смс на все номера
    } else if (kom.indexOf(off) > -1) {              // выкл смс при сработке
      SendSMS = false;
      EEPROM.update(3, SendSMS);                     // пишем в EEPROM
sms(String(F("SMS->off")), 1);                       // смс на все номера
    }
  } else if (kom.indexOf(F("door")) > -1) {          // вкл/выкл контроль датчика двери
    if (kom.indexOf(on) > -1) {                      // вкл контроль датчика двери
      DOORon = true;
      EEPROM.update(4, DOORon);                      // пишем в EEPROM
sms(String(F("DOOR->on")), 1);                       // смс на все номера
    } else if (kom.indexOf(off) > -1) {              // выкл контроль датчика двери
      DOORon = false;
      EEPROM.update(4, DOORon);                      // пишем в EEPROM
sms(String(F("DOOR->off")), 1);                      // смс на все номера
    }
  } else if (kom.indexOf(F("sarai")) > -1) {         // вкл/выкл контроль датчика двери RF433
    if (kom.indexOf(on) > -1) {                      // вкл контроль RF433
      SARAIon = true;
      EEPROM.update(5, SARAIon);                     // пишем в EEPROM
sms(String(F("SARAI->on")), 1);                      // смс на все номера
    } else if (kom.indexOf(off) > -1) {              // выкл контроль RF433
      SARAIon = false;
      EEPROM.update(5, SARAIon);                     // пишем в EEPROM
sms(String(F("SARAI->off")), 1);                     // смс на все номера
    }
  } else if (kom.indexOf(F("pir")) > -1) {           // вкл/выкл контроль датчика движения
    if (kom.indexOf(on) > -1) {                      // вкл контроль датчика движения
      PIRon = true;
      EEPROM.update(6, PIRon);                       // пишем в EEPROM
sms(String(F("PIR->on")), 1);                        // смс на все номера
    } else if (kom.indexOf(off) > -1) {              // выкл контроль датчика движения
      PIRon = false;
      EEPROM.update(6, PIRon);                       // пишем в EEPROM
sms(String(F("PIR->off")), 1);                       // смс на все номера
    }
  } else if (kom.indexOf(F("gas")) > -1) {           // вкл/выкл контроль датчика газа
    if (kom.indexOf(on) > -1) {                      // вкл контроль датчика газа
      GASon = true;
      EEPROM.update(7, GASon);                       // пишем в EEPROM
sms(String(F("GAS->on")), 1);                        // смс на все номера
    } else if (kom.indexOf(off) > -1) {              // выкл контроль датчика газа
      GASon = false;
      EEPROM.update(7, GASon);                       // пишем в EEPROM
sms(String(F("GAS->off")), 1);                       // смс на все номера
    }
  }
//  gsm.println(F("AT+CMGD=1,4"));                     // стираем смс
  sendATCommand(String(F("AT+CMGD=1,4")));           // стираем смс
}

void master (int i, String num) { /// === добавление мастер-номеров === ///
  if (i < 5 && i != 0) {                             // если ячейка от 1 до 4
    num.trim();                       
    num.toCharArray(Phone, 14);                      // конвертируем номер
    AlarmPhone[i] = num;                             
    EEPROM.put(Adress[i], Phone);                    // записываем массив в EEPROM
sms(String(F("Master")) + i + "->" + num + " add", 0); // смс на 0 номер.
  } 
}

void dellphone (int i) { /// === удаление мастар-номеров === ///
  if (i < 5 && i != 0) {                             // если ячейка от 1 до 4
    AlarmPhone[i] = "";                              // стираем номер
    EEPROM.put(Adress[i], 0);                        // стираем номер
sms(String(F("Master")) + i + "->" + AlarmPhone[i] + " dell", 0); // смс на 0 номер
  }
// 0 номер можно удалить только через RESET!!!
}

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

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

String eepromtext() { /// === состояние системы === ///
  String SIGN = "";         // текущее состояние системы.
  String SIRENA = "";       // сирена при сработке.
  String RING = "";         // вызов при сработке.
  String SMS = "";          // смс при сработке.
  String Door = "";         // датчика двери.
  String Sarai = "";        // датчика двери RF433.
  String Pir = "";          // датчик движения.
  String Gas = "";          // датчик газа.
  if (Guard) SIGN = F("System on\n"); else SIGN = F("System off\n");
  if (Sirena) SIRENA = F("Sirena on\n"); else SIRENA = F("Sirena off\n");
  if (AlarmRING) RING = F("Ring on\n"); else RING = F("Ring off\n");
  if (SendSMS) SMS = F("SMS on\n"); else SMS = F("SMS off\n");
  if (DOORon) Door = F("Door on\n"); else Door = F("Door off\n");
  if (SARAIon) Sarai = F("Sarai on\n"); else Sarai = F("Sarai off\n");
  if (PIRon) Pir = F("Pir on\n"); else Pir = F("Pir off\n");
  if (GASon) Gas = F("Gas on\n"); else Gas = F("Gas off");
  String LastEvent = SIGN + SIRENA + RING + SMS + Door + Sarai + Pir + Gas; // полное состояние системы и датчиков.
  return LastEvent;
}

String eepromphone() { /// === чтение мастер-номеров из EEPROM === ///
  for (int i = 0; i < 5 ; i++) {
    EEPROM.get(Adress[i], Phone);        // считываем мастер-номера
    AlarmPhone[i] = Phone;
  }
  String numbers = "[0] " + AlarmPhone[0] + "\n[1] " + AlarmPhone[1] + "\n[2] " + AlarmPhone[2] + "\n[3] " + AlarmPhone[3] + "\n[4] " + AlarmPhone[4] + "\n";
  EEPROM.get(100, Phone);                // считываем номер последнего звонившего
  RingPhone = Phone;
  String ring = String(F("Ring ")) + RingPhone + "\n";
  EEPROM.get(20, Bal);                   // считываем номер баланса
  String bal = String(F("Balance *")) + Bal + "#";
  String EEPhone = numbers + ring + bal;
  return EEPhone;
}

void Detect() { /// === чтение датчиков === ///
  DOORState = digitalRead(DOOR);
  PIRState = digitalRead(PIR);
  Smoky = analogRead(GAS);
  if (DOORon) {                                            // если датчик двери включен
    if (DOORState == HIGH && !DOORFlag) {                  // если он сработал
      lasttime_door = millis();                            // запускаем таймер
      DOORFlag = true;                                     // ставим флаг
//Serial.println(F("Dver' otkrita!"));
      Alarm();                                             // запускаем подпрограмму Alarm        
    } else if (DOORState == LOW && DOORFlag) {                       
      if (((millis() - lasttime_door)/1000 > time_door)) { // и прошел интервал
        DOORFlag = false;                                  // возвращаем флаг к начальному состоянию
//Serial.println(F("Dver' zakrita!"));
      }
    }
  }
  if (SARAIon) {
    if (mySwitch.available()) {                            // если датчик сарая включен
      unsigned long value = mySwitch.getReceivedValue();   // считываем значение с RF433
      if (value == sarai && !SARAIFlag) {                  // если он сработал
        lasttime_sarai = millis();                         // запускаем таймер
        SARAIFlag = true;                                  // ставим флаг
//Serial.println(F("Sarai otkrit!"));       
        Alarm();                                           // запускаем подпрограмму Alarm
      }
      mySwitch.resetAvailable();                          
    } 
    if (((millis() - lasttime_sarai)/1000 > time_sarai)) { // если прошол интервал
      SARAIFlag = false;                                   // возвращаем флаг к начальному состоянию
    }
  }
  if (PIRon) {                                             // если включен PIR датчик движения
    if (PIRState == HIGH && !PIRFlag) {                    // если он сработал
      lasttime_pir = millis();                             // запускаем таймер  
      PIRFlag = true;                                      // ставим флаг
//Serial.println(F("Dvizhenie u dveri!"));
      Alarm();                                             // запускаем подпрограмму Alarm
    } else if (PIRState == LOW && PIRFlag) {               // иначе если движения нет
      if (((millis() - lasttime_pir)/1000 > time_pir)) {   // и прошел интервал
        PIRFlag = false;                                   // возвращаем флаг к начальному состоянию
      }
    }
  }
  if (GASon) {                                             // если включен датчик газа
    if ((Smoky > GASThres) && !GASFlag) {                  // если он сработал
      lasttime_gas = millis();                             // запускаем таймер 
      GASFlag = true;                                      // ставим флаг
//Serial.println(F("Gas v dome!"));
      Alarm();                                             // запускаем подпрограмму Alarm 
    } else if ((Smoky < GASThres) && GASFlag) {            // иначе если газа нет
      if (((millis() - lasttime_gas)/1000 > time_gas)) {   // и прошел интервал
        GASFlag = false;                                   // возвращаем флаг к начальному состоянию
      }
    }
  }
}

void Alarm() { /// === аварийные сигналы === ///
  if (Sirena) {                              // если включена сирена при сработке
    lasttime_alarm = millis();               // запускаем таймер сирены
    digitalWrite(BUZ, HIGH);                 // запускаем ее
  }
//Serial.println(F("Alarm!!!"));
  if (SendSMS) {                             // если включена отправка смс при сработке
    if (DOORFlag) {                          // если сработал датчик двери
sms(F("Dver' otkrita!"), 1);                 // смс на все номера
    } else if (SARAIFlag) {                  // если сработал датчик двери RF433
sms(F("Sarai otkrit!"), 1);                  // смс на все номера
    } else if (PIRFlag) {                    // если сработал датчик движения
sms(F("Dvizhenie y dveri!"), 1);             // смс на все номера
    } else if (GASFlag) {                    // если сработал датчик газа
sms(F("Gas v dome!"), 1);                    // смс на все номера
    }
  }
  if (AlarmRING) {                           // если включен вызов при сработке
sendATCommand("ATD+" + String(AlarmPhone[0]) + ";"); // делаем вызов основного мастер-номера
  }
}

void AlarmPinOff() { /// === отключаем сирену === ///
  if ((millis() - lasttime_alarm)/1000 > time_alarm) digitalWrite(BUZ, LOW); // если прошло время, отключаем сирену
}

void GuardOff() { /// === выключение сигнализации === ///
  Guard = false;
  EEPROM.update(1, Guard);
sms(F("System->off"), 1);  // смс на все номера
}

void GuardOn() { /// === включение сигнализации === ///
  Guard = true;
  EEPROM.update(1, Guard);
sms(F("System->on"), 1);   // смс на все номера
}

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

void Signal() { /// === проверка уровня сигнала сети === ///
  String csq = sendATCommand(F("AT+CSQ"));           
  csq = csq.substring(csq.indexOf(":") + 2, csq.indexOf(",")); // парсим ответ об уровне сигнала
  csq.trim();                                        // удаляем пробелы вначале и в конце строки
  csq.toCharArray(CSQ, 4);                           
}

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

void TempC() { /// === измеряем температуру === ///
  ds.requestTemperatures();             // Запрос на считывание температуры
  Temp_ul = ds.getTempCByIndex(0);      // считываем температуру с первого датчика
  Temp_pom = ds.getTempCByIndex(1);     // считываем температуру со второго датчика 
}

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 Restart() { /// === рестарт системы === ///
  digitalWrite(rst, HIGH);                     // перезапускаем модем
  delay(200);
  digitalWrite(rst, LOW);         
  digitalWrite(LED, HIGH);                     // светодиод горит во время запуска
  eepromconfig();                              // читаем конфигурацию из памяти
Serial.println(String(F("MasterPhone:\n")) + eepromphone() + "\r\n");  // выводим список номеров из памяти в порт
//Serial.println(String(F("AlarmConfig:\n")) + eepromtext());            // закомментировать если смс
  TempC();                                     // читаем температуру
  Signal();                                    // читаем сигнал сети GSM
Serial.println(String(F("Firststart:")) + Firststart);
if (!Firststart) sms(String(F("Modem restart\n")) + eepromtext(), 0);  // если не первый старт смс на последний номер
  digitalWrite(LED, LOW);                      // гасим светодиод состояния сигнализации.
}

void InitModem() { /// === инициализация модема === ///
  gsm.begin(9600);                       //Скорость порта для связи Arduino с GSM модулем
  waitConnect();
  sendATCommand(F("ATE0"));              // выключить эхо
  sendATCommand(F("AT+CLIP=1"));         // включить АОН
  sendATCommand(F("AT+CMGF=1"));         // включить текстовый формат смс
  sendATCommand(F("AT+CSCS=\"GSM\""));   // включить кодировку текста gsm
  sendATCommand(F("AT+CNMI=2,2,0,0,0")); // смс прямо в порт
  sendATCommand(F("AT+CREG?"));          // регистрация в сети
  sendATCommand(F("AT+CMGD=1,4"));       // стираем смс
}

String sendATCommand(String cmd) {
  String atval = "";                             // Переменная для хранения результата
  Serial.println(cmd);                           // Дублируем команду в монитор порта
  gsm.println(cmd);                              // Отправляем команду модулю
    long _timeout = millis() + 10000;            // Переменная для отслеживания таймаута (10 секунд)
    while (!gsm.available() && millis() < _timeout) {}; // Ждем ответа 10 секунд
    if (gsm.available()) {                       // если GSM модем что-то послал.
      while (gsm.available()) {                  // сохраняем входную строку в переменную val.
        char ch = gsm.read();
        atval += char(ch);                       // собираем принятые символы в строку
        delay(3);
      }
    } else {
      Serial.println(F("Timeout..."));           // ... оповещаем об этом и...
      Restart();                                 // перезапускаем модем
    }
    Serial.println(atval);                       // Дублируем ответ в монитор порта
  return atval;
}

void waitConnect() {  // запуск модема
  uint16_t countok = 0;
  uint32_t msAT = 0;
  String str;
  while (countok < 5) {                      // ждём пять ОК
    uint32_t ms = millis();
    if (( ms - msAT ) > 500 || ms < msAT ) { // Событие срабатывающее каждые 500 мс
      msAT = ms;
      Serial.println(">>AT");
      gsm.println("AT");                     // посылаем команду
      str = "";
      delay(100);                            // ждём ответа
      while (gsm.available()) {              // сохраняем входную строку в переменную val.
        char ch = gsm.read();
        str += char(ch);                     // собираем принятые символы в строку
        delay(3);
      }
      if (str.indexOf("OK") > -1) {
        Serial.println("OK");
        countok++;
      } else countok = 0;
    }
  }
}

void sms(String text, byte sendnum) { /// === отправка СМС === ///
  String phone = "";
  text += String(F("\nTemp_ul ")) + Temp_ul;           // добавляем к тексту температуру на улице
  text += String(F("*C\nTemp_pom ")) + Temp_pom;       // добавляем к тексту температуру на в помещении
  text += String(F("*C\n")) + bal;                     // добавляем к тексту баланс sim карты
  if (!serial) {                                       // если не команда из сериала
    if (!sendnum) {                                    // отправка смс на номер звонившего
      phone = RingPhone;
      sendATCommand(String(F("AT+CMGS=\"+")) + phone + "\""); // Переходим в режим ввода текстового сообщения
      sendATCommand(text + (String)((char)26));        // отправка текста 
    } else if (sendnum) {                              // отправка смс на все номера
      for (uint8_t i = 0; i < 4 ; i++) {
        phone = AlarmPhone[i];
        if (phone != 0) {                              // если ячейка пустая - не отправлять смс
          sendATCommand(String(F("AT+CMGS=\"+")) + phone + "\""); // Переходим в режим ввода текстового сообщения
          sendATCommand(text + (String)((char)26));    // отправка текста 
        }
      }
    }
  } else Serial.println(text);                         // если команда из сериала пишем выводим результат
  if (Bal != 0) balance();                             // если есть номер баланса проверяем его
}

 

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

Как подключаются два датчика температуры и на которых пина​х?Один вижу на контакте 15, а другой?

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

Датчики Ds18B20 подключаются по шине OneWire. оба датчика на 15 пине.

чтоб узнать который со старшим адресом (улица или помещение) придется выяснять опытным путем)))

Gienekb
Offline
Зарегистрирован: 29.08.2017
OK. Я понимаю. Спасибо, за быстрый ответ.
Я буду решать остальные экспериментально.
pasha413
Offline
Зарегистрирован: 27.11.2016

попробовал голосовое меню на sim800 http://arduino.ru/forum/proekty/sim800l-dtmf-upravlenie-golosovoe-menyu

работает ведь, но на ревизии модема 1418..., а на 1308... не работает.

вот в будущем буду пепеписывать наверное на DTMF с голосовым меню)

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

ага.. а можете на сим800л  сменить прошивку ?? тотоже...

берите сим800с..

obuhanoe
Offline
Зарегистрирован: 18.05.2016

Short Circuit пишет:

ага.. а можете на сим800л  сменить прошивку ?? тотоже...

берите сим800с..

А можно подбробнее, почему нельзя сменить на L версии и Как можно на C версии.

Спасибо.

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

У меня sim800l. Есть прога для прошивки, но пока не решился. Люди шьют 800l прошивкой по-моему от 800с или h, правда светодиод потом не работает. Вообщем ещё буду разбираться

Andrey12
Andrey12 аватар
Offline
Зарегистрирован: 26.12.2014

По своему опыту скажу - после прошивки SIM800L ничего не работает.
Они может конечно разные бывают тоже, но мой после прошивки в 16Мб так и не заработал, а 24Мб программа отказалась назад прошивать. Говоритт не подходит прошивка :-( Но китайцы же ее както прошили.

Поэтому оптимальный вариант как и написали выше SIM800C

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

Сим 800l работают, но смотря с какой прошивкой китайцы поставят)

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

Все ли сигнальные компоненты питаются от + 5 В? Вы использовали аварийный источник питания? Что внутри D4MG? У вас есть электрическая схема? Я хочу немного поэкспериментировать, и поэтому так много вопросов.

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

Да, все питается от 5В.
Аварийный источник пока не используется, т.к. нет основного источника..в данный момент сигналка питается от аккумулятора 12В.
Внутри d4mg вся схема: ардуина, преобразователь 12V/5V, модем А6, 433 приемник, 1 реле для управления сиреной. печатки пока нет, схему выложу

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

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

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

вот, приближенная к оригиналу схема

12/5V разъем на конвертор с 12 на 5В.

433.3 разъем на приемник.

GSM разъем на модем.

Кстати реле 2 в данный момент не используется!!!

что за эксперименты, поделитесь?

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

Спасибо за схему. Хотя его качество очень плохое, я понял смысл. 

Мне кажется, что вы прикрепили либо не эту схему, либо не этот код. :)

У меня есть Arduino Nano и модем SIM800L, и я хотел бы общаться с вашим кодом. От и весь эксперимент. :)

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

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

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

Gienekb пишет:

Спасибо за схему. Хотя его качество очень плохое, я понял смысл. 

если нажать на картинку - она увеличится и схема станет значительно понятнее :)

Для SIM800 схема понадобится совсем другая, ибо его от 5в питать нельзя. Да и скетч несколько изменится, так как команды у модемов отличаются. В итоге  для экспериментов на Нано и СИМ800 я бы свой код написал, а не редактировал готовый...

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

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

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

ненашел я свой пример для 3х модемов с автовыбором, походу все только на работе осталось.

вот вам, думаю разберетесь:

А6 модем

  // обрезка номера звонщего для сохранения 
if (gval.indexOf(F("RING")) > -1) {        // если обнаружен вызов.
          int ind = gval.indexOf(F("+CLIP: \""));          // обрезаем номер 
          ind += 8;
          String ring = gval.substring(ind, gval.indexOf("\"", ind)); // номер звонящего
}
  
  // ответ баланса
if (gval.indexOf(F("+CUSD:")) > -1) { // если пришел баланс
      String bal = "";
      int p1 = gval.indexOf("\"");         // начало строки
      int p2 = gval.lastIndexOf("\"");     // конец строки
      gval = gval.substring(p1 + 1, p2);
      Decode7bit(gval, bal);               // конвертируем баланс
      Serial.println(bal);
}

  // проверка баланса 
  sendATCommand(String(F("AT+CUSD=1,#")) + Bal + F("#,15"), true);

  // инициализация модема 
void InitModem() { /// === инициализация модема === ///
  gsm.begin(9600);                             //Скорость порта для связи Arduino с GSM модулем
  waitConnect();                               // для автонастройки скорости модема
  sendATCommand(F("ATI"), true);
  sendATCommand(F("ATE0"), true);              // вывключить эхо
  sendATCommand(F("AT+CLIP=1"), true);         // включить АОН
  sendATCommand(F("AT+CMGF=1"), true);         // включить текстовый формат смс
  sendATCommand(F("AT+CSCS=\"GSM\""), true);   // включить кодировка текста gsm
  sendATCommand(F("AT+CNMI=2,2,0,0,0"), true); // смс прямо в порт
  sendATCommand(F("AT+CREG?"), true);          // регистрация в сети
  sendATCommand(F("AT+CMGD=1,4"), true);       // стираем смс
}

SIM800 модем


  // обрезка номера звонщего для сохранения 
if (gval.indexOf(F("+CLIP")) > -1) {        // если обнаружен вызов.
            int ind = gval.indexOf(F("+CLIP: \""));          // обрезаем номер
            ind += 9;
            String ring = gval.substring(ind, gval.indexOf("\"", ind)); // номер звонящего
}


  // ответ баланса         Decode7bit(gval, bal); - ненадо!!!

if (gval.indexOf(F("+CUSD:")) > -1) { // если пришел баланс
        String bal = gval.substring(gval.indexOf("\"") + 9, gval.indexOf("\",") - 2 ); //
        sendATCommand(F("AT+CUSD=0"), true);
        bal.trim();
        Serial.println(bal);
}

  // проверка баланса 
  sendATCommand(String(F("AT+CUSD=1,#")) + Bal + F("#;"), true);

  // инициализация модема 
void InitModem() { /// === инициализация модема === ///
  gsm.begin(9600);                             //Скорость порта для связи Arduino с GSM модулем
  waitConnect();                               // вроде можно удалить, достаточно команды  sendATCommand(F("AT+IPR=9600"), true);  
  sendATCommand(F("ATI"), true);
  sendATCommand(F("ATE0"), true);              // вывключить эхо
  sendATCommand(F("AT+CSCLK=0"), true);
  sendATCommand(F("AT+CLIP=1"), true);         // включить АОН
  sendATCommand(F("AT+CMGF=1"), true);         // включить текстовый формат смс
  sendATCommand(F("AT+CSCS=\"GSM\""), true);   // включить кодировка текста gsm
  sendATCommand(F("AT+CNMI=2,2,0,0,0"), true); // смс прямо в порт
  sendATCommand(F("AT+CREG?"), true);          // регистрация в сети
}

 

Djoin
Offline
Зарегистрирован: 04.06.2018

Здравствуйте!
Не всегда отправляются ответные СМС.
В терминале, если сделать вывод ответов от gsm модуля, не всегда корректно отправляется команда отправки смс.

Вместо "AT+CMGS=..." отправляется "MGS=....", т.е. первые символы почему-то теряются. Из-за чего это может быть?

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

Djoin пишет:

Здравствуйте!
Не всегда отправляются ответные СМС.
В терминале, если сделать вывод ответов от gsm модуля, не всегда корректно отправляется команда отправки смс.

Вместо "AT+CMGS=..." отправляется "MGS=....", т.е. первые символы почему-то теряются. Из-за чего это может быть?

Буфера не хватает?

В файл SoftwareSerial.h (C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.h) необходимо внести изменения

было так:

#define _SS_MAX_RX_BUFF 64 

тало так:

#define _SS_MAX_RX_BUFF 192
Djoin
Offline
Зарегистрирован: 04.06.2018

Спасибо! Вечером попробую.

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

Там по коду еще, надо заменить это
unsigned long timer = 300000;
if (millis()/1000 > timer) { // проверяем каждый час
TempC();
Signal();
timer += 360;
}
На
unsigned long timer = 360;
if (millis()/1000 > timer) { // проверяем каждый час
TempC();
Signal();
timer += timer;
}

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

Djoin
Offline
Зарегистрирован: 04.06.2018

kvolk пишет:

Буфера не хватает?

В файл SoftwareSerial.h (C:\Program Files (x86)\Arduino\hardware\arduino\avr\libraries\SoftwareSerial\src\SoftwareSerial.h) необходимо внести изменения

было так:

#define _SS_MAX_RX_BUFF 64 

тало так:

#define _SS_MAX_RX_BUFF 192

К сажалению не помог ваш совет.

Размер буфера поменял, но проблема не ушла.

Заметил закономерность - СМС отправляются через 1. Т.е. отправляю "info" - получаю смс, еще раз отправляю "info" - ошибка, третий раз отправляю - СМС приходит.

От команды не зависит... 

Прикладваю данные с монитора порта:
 

//// Как только загрузилась Arduino, я отправил Info ///////
+CMT: "+77057505444",,"18/06/04,22:06:20+36"
Info
Process CMT
Phone: 77057505444
Message: Info
RingPhone 77057505444
Master SMS OK!
-> Info
SMS send=>77057505444
SMS on
Rel1 off
Rel2 off
Rel3 on
////// Сам процесс отправки///////////
AT+CMGS="+77057505444"
> S⸮⸮Rel@off
Rel2 off
Rel3 on

+CMGS: 65
OK
///// СМС получил////////


//// Далее отправляю команду on1 я ее сам добавил (управление реле)///////////
+CMT: "+77057505444",,"18/06/04,22:06:46+36"
On1
Process CMT
Phone: 77057505444
Message: On1
RingPhone 77057505444
Master SMS OK!
-> On1
-> Rele 1
SMS send=>77057505444
Rele->on

////// Тут не хватает символов///////
GS="+77057505444"
////// ОШИБКА///////////
ERROR
Rele->on
AT+CMGD=1,4

OK

//////// Повторно отправляю эту команду - СМС пришла ////////////
+CMT: "+77057505444",,"18/06/04,22:07:34+36"
On1

Process CMT
Phone: 77057505444
Message: On1
RingPhone 77057505444
Master SMS OK!
-> On1
-> Rele 1
SMS send=>77057505444
Rele->on


AT+CMGS="+77057505444"

> Rele->on


+CMGS: 66

OK

/////////// Отправил еще 1 команду - опять ошибка////////////
+CMT: "+77057505444",,"18/06/04,22:07:58+36"
Off1

Process CMT
Phone: 77057505444
Message: Off1
RingPhone 77057505444
Master SMS OK!
-> Off1
-> Rele 1
SMS send=>77057505444
Rele->off


GS="+77057505444"

ERROR
Rele->off
AT+CMGD=1,4

OK

 

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

Djoin, видимо у вас длинное сообщение получилось, у меня тоже такое было...сколько у вас символов в сообщении, у меня на данный момент 137, по-моему, и норм отправляется

kot488
Offline
Зарегистрирован: 22.03.2018

Случайно никто не пробовал подключить беспроводные датчики?

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

У меня 433 датчик двери

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

Djoin, а если info посылать 3 раза сподрят, теряется что то?

и у вас теряется только на on1 и off1?

kot488
Offline
Зарегистрирован: 22.03.2018

А где можно посмотреть пример кода?

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

Пост667.
Приемник подключен ко 2 пину

kot488
Offline
Зарегистрирован: 22.03.2018

С SIM800L нормально должен работать?

Я изначально пробовал залить hex для проводной только, подвис в памяти мой номер, и сейчас нормально не стартует, вот что в мониторе порта

MasterPhone:
[0] 
[1] 
[2] ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
[3] ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
[4] ⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮⸮
Ring +38*******
Balance *#
 
AT+CSQ
Timeout...
 
pasha413
Offline
Зарегистрирован: 27.11.2016

Для сим800 нужна небольшая доработка

kot488
Offline
Зарегистрирован: 22.03.2018

Что же мне так везет (
Эта версия под M590?
А что менять нужно, или проще модуль старый взять?

Не подскажите чего номер тянется со старой прошивки и иероглифы?

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

эта версия под А6,

в ближайшее время постараюсь, переписать под сим800.

где-то посеял свои нарабтки сигнализации с автоопределением модема...