что-то не до конца допилил, сегодня уже некогда...
двойное приглашение на отправку, не победил....
// 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(4); // датчик температуры, подтяжка 4.7кОм на +.
DallasTemperature ds(&DS18B20);
SoftwareSerial gsm(7, 6); // модем.
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 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);
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) { // если пришел баланс
// анализируем строку
int p1 = gval.indexOf("\""); // начало строки
int p2 = gval.lastIndexOf("\""); // конец строки
gval = gval.substring(p1 + 1, p2); // обрезаем строку
// Decode7bit(gval, bal); // декодируем сообщение
bal = gval;
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 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(2000); // ждем секунду, т.к. вылетает с ошибкой
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 Restart() { /// === рестарт системы === ///
gsm.println(F("AT+CFUN=1,1"));
delay(2000);
Serial.println(String(F("Modem restart!")));
InitModem();
eepromconfig(); // читаем конфигурацию из памяти
Serial.println(String(F("MasterPhone:\n")) + eepromphone()); // выводим список номеров из памяти в порт
TempC(); // читаем температуру
Signal(); // читаем сигнал сети GSM
Serial.println(String(F("Firststart:")) + Firststart);
if (!Firststart) sms(String(F("Modem restart\n")) + eepromtext(), 0); // если не первый старт смс на последний номер
else Serial.println(String(F("\nSystem config:\n")) + eepromtext() + "\r\n");
digitalWrite(LED, LOW); // гасим светодиод состояния сигнализации.
}
void InitModem() { /// === инициализация модема === ///
gsm.begin(9600); //Скорость порта для связи Arduino с GSM модулем
sendATCommand(F("AT")); // выключить эхо
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 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 + ((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 + ((char)26)); // отправка текста
delay(200);
}
}
}
} else Serial.println(text); // если команда из сериала пишем выводим результат
if (Bal != 0) balance(); // если есть номер баланса проверяем его
}
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); // если прошло время, отключаем сирену
}
Alarm v2.1.3
Modem restart!
AT
OK
ATE0
OK
AT+CLIP=1
OK
AT+CMGF=1
OK
AT+CSCS="GSM"
OK
AT+CNMI=2,2,0,0,0
OK
AT+CREG?
+CREG: 0,2
OK
AT+CMGD=1,4
OK
MasterPhone:
[0] *************
[1]
[2]
[3]
[4]
Ring ***************
Balance *105#
AT+CSQ
+CSQ: 16,0
OK
Firststart:0
Modem restart
System off
Sirena off
Ring off
SMS off
Door off
Sarai off
Pir off
Gas off
Temp_ul 25.00*C
Temp_pom 25.06*C
AT+CUSD=1,"#105#",15
OK
gval->
+CUSD: 0, "OCTATOK 87.50 p.", 1
OCTATOK 87.50 p.
AT+CUSD=0
OK
gval->
+CMT: "+**********","","18/06/05,19:31:15+12"
Info
Kom->Info
AT+CSQ
+CSQ: 13,0
OK
AT+CMGS="+***************"
>
System off
Sirena off
Ring off
SMS off
Door off
Sarai off
Pir off
Gas off
Temp_ul 25.00*C
Temp_pom 25.06*C
OCTATOK 87.50 p.
> здесь не должно быть приглашения, это окончание отправки
AT+CUSD=1,"#105#",15
Timeout...
Modem restart!
AT
Спасибо, завтра попробую, оставил все на работе .
Если никакие датчики не подключать, то тоже должна запустится?
За автозапуск прикольно, но как по мне только на автомате. Я например всегда сцепление выжимаю перед запуском, да и зимой так механике полезно. У друга хундай, так пока педальку не нажмешь не заведешь
Djoin, а если info посылать 3 раза сподрят, теряется что то?
и у вас теряется только на on1 и off1?
Если 3 раза подряд отправить info придет 2 смс.
1 и 3.
2 будет в ошибке.
Т.е. смс уходят через одну.
pasha413 пишет:
Djoin, видимо у вас длинное сообщение получилось, у меня тоже такое было...сколько у вас символов в сообщении, у меня на данный момент 137, по-моему, и норм отправляется
Смс короткие, можете сами убедиться - я выложил лог с порта монитора.
Rele->on
Rele->off
С обычного info текст длиннее.
Проблема в том, что команда отправки СМС передается раньше самого текста, и она через раз передается не полностью.
Тут длина смс сообщение не может никак влиять.
Может сделать проверку ответа от модема: если получили ERROR - повторно попытаться отправить смс... пытаться 3 раза например...
Может в этом проблема? Подключил модем на прямую через usb-uart, на первой же команде ошибка. Потом ее повторяю все нормально. Через монитор порта не реагирует.
Может в этом проблема? Подключил модем на прямую через usb-uart, на первой же команде ошибка. Потом ее повторяю все нормально. Через монитор порта не реагирует.
Скорми модему команду
AT+CMEE=2
И будут тебе описания ошибок, вместо непонятных кодов.
Может в этом проблема? Подключил модем на прямую через usb-uart, на первой же команде ошибка. Потом ее повторяю все нормально. Через монитор порта не реагирует.
модем А6 ? у него проблемы с USSD в зависимости от прошивки, может не заработать. Мне например на SIM 800 пришлось переходить
Извиняюсь, ничего не успел на работе...пишу с телефона...
Для применения кода из #667 на сим800 замените:
093 unsigned long timer = 3600; // каждый час
131 timer += timer;
155 ind += 9;
176 if (gval.indexOf(F("+CUSD:")) > -1) { // если пришел баланс
177 int p1 = gval.indexOf("\""); // начало строки
180 int p2 = gval.lastIndexOf("\""); // конец строки
181 gval = gval.substring(p1 + 1, p2); // обрезаем строку
182 bal = gval;
183 Serial.println(bal);
184 sendATCommand(F("AT+CUSD=0"));
185 }
Далее внимательнее номера строк не будут совпадать, пишу как могу)))
211 Index += 9;
560 sendATCommand(String(F("AT+CUSD=1,#\"")) + Bal + F("\"#,15")); //на сим 800 нужны кавычки, на А6 нет...
571 void Decode7bit(){} удаляем функцию
591 digitalWrite(rst, LOW); // перезапускаем модем
592 delay(200);
593 digitalWrite(rst, HIGH);
Фух, вроде так, у меня на сим800 почему то не вышло с отправкой смс, попробуйте и пришлите данные из монитора порта
А6 у меня дефектных не попадалось, 2шт А6 и один А6С (с камерой был).
М590 3шт и все разные по АТ командам и току потребления.
SIM800l 2шт с разными прошивками отличия пока что увидел: gprs не завелся на одном, и голосовые команды на нём же не завелись
// 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 dvizhenie 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 DVIZHENIEon = 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 DVIZHENIEFlag = 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_dvizhenie 10 // секунд не смотрим на датчик двери 2.
unsigned long lasttime_dvizhenie = 0;
#define time_pir 20 // секунд не смотрим на датчик движения.
unsigned long lasttime_pir = 0;
#define time_gas 600 // секунд не смотрим на датчик газа. 10 минут
unsigned long lasttime_gas = 0;
unsigned long timer = 3600;
/* 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 += timer;
}
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 += 9;
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) { // если пришел баланс
int p1 = gval.indexOf("\""); // начало строки
int p2 = gval.lastIndexOf("\""); // конец строки
gval = gval.substring(p1 + 1, p2); // обрезаем строку
bal = gval;
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 += 9; // Парсим строку и
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
DVIZHENIEon = 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 Restart() { /// === рестарт системы === ///
digitalWrite(rst, LOW); // перезапускаем модем
delay(200);
digitalWrite(rst, HIGH);
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(); // если есть номер баланса проверяем его
}
по коду есть ребут модема, на sim800 не нашел контакта rst
Вообщем я походу баран и нашел проблему, симка которая стоит в модуле проверяет баланс через *111#, в этом судя по всему и вся проблема. Можно на програмной уровне заменить номер? Ведь через терминал не реагирует на команды, пока не загрузится нормально(
AT
OK
AT&F
OK
AT+IPR=9600;E1+DDET=1;+CMGF=1;+CSCS=\"gsm\";+CNMI=2,1,0,0,0;+VTD=1;+CMEE=1;&W
ERROR
AT+IPR=9600;E1+DDET=1;+CMGF=1;+CSCS=\"gsm\";+CNMI=2,1,0,0,0;+VTD=1;+CMEE=1;&W
ERROR
С SIM800L нормально должен работать?
Я изначально пробовал залить hex для проводной только, подвис в памяти мой номер, и сейчас нормально не стартует, вот что в мониторе порта
если это мой код, то выполните команду reset
эта версия под А6,
в ближайшее время постараюсь, переписать под сим800.
где-то посеял свои нарабтки сигнализации с автоопределением модема...
Буду очень ждать)
Пока попробую поискать A6. По совету в проводной теме специально покупал sim800
[/quote] Буду очень ждать) Пока попробую поискать A6. По совету в проводной теме специально покупал sim800[/quote]
что за проводная тема?
Насколько понял, то вот эта взята за прототип, или не прав?
https://mysku.ru/blog/ebay/43282.html
что-то не до конца допилил, сегодня уже некогда...
двойное приглашение на отправку, не победил....
// 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(4); // датчик температуры, подтяжка 4.7кОм на +. DallasTemperature ds(&DS18B20); SoftwareSerial gsm(7, 6); // модем. 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 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); 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) { // если пришел баланс // анализируем строку int p1 = gval.indexOf("\""); // начало строки int p2 = gval.lastIndexOf("\""); // конец строки gval = gval.substring(p1 + 1, p2); // обрезаем строку // Decode7bit(gval, bal); // декодируем сообщение bal = gval; 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 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(2000); // ждем секунду, т.к. вылетает с ошибкой 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 Restart() { /// === рестарт системы === /// gsm.println(F("AT+CFUN=1,1")); delay(2000); Serial.println(String(F("Modem restart!"))); InitModem(); eepromconfig(); // читаем конфигурацию из памяти Serial.println(String(F("MasterPhone:\n")) + eepromphone()); // выводим список номеров из памяти в порт TempC(); // читаем температуру Signal(); // читаем сигнал сети GSM Serial.println(String(F("Firststart:")) + Firststart); if (!Firststart) sms(String(F("Modem restart\n")) + eepromtext(), 0); // если не первый старт смс на последний номер else Serial.println(String(F("\nSystem config:\n")) + eepromtext() + "\r\n"); digitalWrite(LED, LOW); // гасим светодиод состояния сигнализации. } void InitModem() { /// === инициализация модема === /// gsm.begin(9600); //Скорость порта для связи Arduino с GSM модулем sendATCommand(F("AT")); // выключить эхо 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 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 + ((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 + ((char)26)); // отправка текста delay(200); } } } } else Serial.println(text); // если команда из сериала пишем выводим результат if (Bal != 0) balance(); // если есть номер баланса проверяем его } 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); // если прошло время, отключаем сирену }Подправленый код в том же посте?
да это подправленный код для сим800, пробуйте, может у меня какой параметр в модеме не так стоит
сейчас занялся доработкой кода под GPRS с управление по MQTT, за основу взял https://www.drive2.ru/c/499270089304965988/, спасибо martinhol за проделанную работу.
Спасибо, завтра попробую, оставил все на работе .
Если никакие датчики не подключать, то тоже должна запустится?
За автозапуск прикольно, но как по мне только на автомате. Я например всегда сцепление выжимаю перед запуском, да и зимой так механике полезно. У друга хундай, так пока педальку не нажмешь не заведешь
без датчиков запустится, все датчики по умолчанию выключены, кроме температуры.
для этого и есть дополнительные каналы, чтоб имитировать присутствие)
без датчиков запустится, все датчики по умолчанию выключены, кроме температуры.
для этого и есть дополнительные каналы, чтоб имитировать присутствие.
на 3 мондео был автозапуск так зимой самое то сел и поехал (греть мерзнуть не надо), а здесь еще и бонус в виде gsm/
Djoin, а если info посылать 3 раза сподрят, теряется что то?
и у вас теряется только на on1 и off1?
Если 3 раза подряд отправить info придет 2 смс.
1 и 3.
2 будет в ошибке.
Т.е. смс уходят через одну.
Djoin, видимо у вас длинное сообщение получилось, у меня тоже такое было...сколько у вас символов в сообщении, у меня на данный момент 137, по-моему, и норм отправляется
Смс короткие, можете сами убедиться - я выложил лог с порта монитора.
Rele->on
Rele->off
С обычного info текст длиннее.
Проблема в том, что команда отправки СМС передается раньше самого текста, и она через раз передается не полностью.
Тут длина смс сообщение не может никак влиять.
Может сделать проверку ответа от модема: если получили ERROR - повторно попытаться отправить смс... пытаться 3 раза например...
ну у меня таких проблем небыло с А6, с сим800 вот что-то заступорился. но завтра попробую разобраться
уже почти 2 месяца стоит на даче блочек, пока норм работает
ну у меня таких проблем небыло с А6, с сим800 вот что-то заступорился. но завтра попробую разобраться
уже почти 2 месяца стоит на даче блочек, пока норм работает
Если вы мне - у меня M590E
ну у меня таких проблем небыло с А6, с сим800 вот что-то заступорился. но завтра попробую разобраться
уже почти 2 месяца стоит на даче блочек, пока норм работает
Если вы мне - у меня M590E
понятно, на 590 давно не проверял.
вот отрыл код с определением модема, вроде был рабочий, проверьте как это работать будет:
// 0 (основной) мастер-номер добавляется при первом звонке либо смс на систему. /* Команды управления для 0 мастер-номера: "reset" сброс настроек и номеров на заводские. "master1:79112345678" добавить номер 79112345678 в ячейку памяти 1. "balance:100" номер баланса *100#. "dell:1" удалить номер из ячейки 1. "phone" вывести список номеров в системе. */ /* Команды управления для всех мастер-номеров: "info" либо "?" инфо о состояни системы и уровня сигнала сети. "money" проверка баланса. "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" вкл/выкл контроль датчика газа. */ // при звонке на номер сигнализации - прослушка помещения. // при сработке датчиков вызов (если ring on) на 0 мастер-номер и смс (если sms on) всем. // длинна сообщения символов. #include <EEPROM.h> #include <OneWire.h> #include <RCSwitch.h> #include <SoftwareSerial.h> #define Ver F("Alarm v2.1.0\n") OneWire ds(5); // датчик температуры подключен к 5 пину, подтяжка 4.7кОм на +. SoftwareSerial gsm(6, 7); // модем подключен к 7 и 8 пинам. RCSwitch mySwitch = RCSwitch(); // беспроводной датчик двери, пин 2. #define DOOR 3 // пин 4. концевик двери. #define PIR 4 // пин 5. датчик движения. #define LED 8 // пин 13. состояние системы. #define GAS 9 // пин A0. датчик дыма. #define BUZ 10 // пин A1. сирена. #define sarai 3258553 // адрес 433 передатчика геркона двери // DOOR - если сработал, на входе "+" HIGH. // SARAI - если сработал, на пин 2 сигнал. // PIR - если сработал, на входе "+" HIGH. // GAS - если сработал, на входе "+" HIGH. // BUZ - если "-" LOW, то горит. // LED - если "-" LOW, то горит. #define on "on" // вкл #define off "off" // выкл int8_t ModemID = 0; // тип модема boolean Guard = 0; // 1. охрана: 1 - вкл, 0 - выкл. boolean AlarmRING = 1; // 2. вызов при сработке: 1 - вкл, 0 - выкл. boolean SendSMS = 1; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл. boolean DOORon = 1; // 4. контроль концевика двери: 1 - вкл, 0 - выкл. boolean SARAIon = 1; // 4. контроль концевика двери 2: 1 - вкл, 0 - выкл. boolean PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл. boolean GASon = 1; // 6. контроль датчика дыма: 1 - вкл, 0 - выкл. boolean Sirena = 1; // 7. сирена: 1 - вкл, 0 - выкл. boolean Firststart = 1; // первый старт. boolean DOORFlag = 0; // флаг состояние датчика двери. boolean SARAIFlag = 0; // флаг состояние датчика двери 2. boolean PIRFlag = 0; // флаг состояние датчика движения. boolean GASFlag = 0; // флаг состояние датчика газа. int8_t DOORState = LOW; // Состояние концевика двери. int8_t PIRState = LOW; // Состояние датчика движения. int8_t LEDState = HIGH; // Состояние светодиода. int8_t Smoky = LOW; // Состояние датчика газа. boolean sendsmscaller = 1; // разрешение отправки смс. int Temp = 0; char CSQ[4]; // для хранения уровня сигнала char Bal[4]; // для временного хранения номера баланса. char Phone[14]; // для временного хранения номера телефона, номер до 14 цифр. String RingPhone = ""; // номер звонившего. String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс. byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ. int p = 0; #define GASThres 400 // предельная концентрация газа #define interval_alarm 20 // Секунд до отключения "тревожного" пина. int previousMillis_alarm = 0; #define interval_led 1000 // для мигания LED, 1 сек. int previousMillis_led = 0; #define interval_door 10 // секунд не смотрим на датчик двери. int previousMillis_door = 0; #define interval_sarai 10 // секунд не смотрим на датчик двери 2. int previousMillis_sarai = 0; #define interval_pir 20 // секунд не смотрим на датчик движения. int previousMillis_pir = 0; #define interval_gas 600 // секунд не смотрим на датчик газа. 10минут 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 - 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); pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +. pinMode(PIR, INPUT); pinMode(GAS, INPUT); pinMode(BUZ, OUTPUT); pinMode(LED, OUTPUT); // светодиод горит во время запуска. digitalWrite(BUZ, HIGH); // сирена выкл. digitalWrite(PIR, HIGH); // игнорируем при включении. mySwitch.enableReceive(0); // 433 приемник на 2 пине InitModem(); // запускаем инициализация модема. eepromconfig(); Serial.println(eepromphone()); TempC(); Signal(); Serial.println(eepromtext() + F("\nSignal seti: ") + CSQ + F("%\nTemp ") + Temp + "*C"); // закомментировать если смс sms(eepromtext() + F("\nSignal seti: ") + CSQ + "%", 0); // смс на последний номер digitalWrite(LED, HIGH); // гасим светодиод состояния сигнализации. } void loop() { /// === основной цикл программы === /// AlarmPinOff(); // выключаем сирену, если прошло время. if (Guard == 1) { // если на охране Detect(); // проверяем датчики. Led(); // моргаем светодиодом. } if (gsm.available()) { // Если модем, что-то отправил... sendsmscaller = 1; String gval = ""; // Переменная для хранения ответа модуля if (gsm.available()) { // если GSM модем что-то послал. while (gsm.available()) { // сохраняем входную строку в переменную val. char ch = gsm.read(); gval += char(ch); // собираем принятые символы в строку delay(3); } } if (gval.indexOf(F("+PBREADY")) > -1) InitModem(); else if (gval.indexOf(F("+CLIP")) > -1) { // если обнаружен вызов. Serial.println(F("Process RING")); int ind = gval.indexOf(F("+CLIP: \"")); // обрезаем номер ind += 8; // Парсим строку и String ring = gval.substring(ind, gval.indexOf("\"", ind)); Serial.println(String(F("RingPhone->")) + ring); if (CheckPhone(ring) == 1) sendATCommand("ATA", true); // снимаем трубку else sendATCommand("ATH", true); } else if (gval.indexOf(F("+CMT")) > -1) { // если обнаруженa СМС Serial.println(F("Process CMT")); parsesms(gval); } else if(gval.indexOf(F("+CUSD:")) > -1) { // если пришел баланс Serial.println(F("Process USD")); Serial.println("gval1 " + gval); String bal = ""; if (ModemID == 3) { int p1 = gval.indexOf("\""); // начало строки int p2 = gval.lastIndexOf("\""); // конец строки gval = gval.substring(p1 + 1, p2); Decode7bit(gval, bal); sendATCommand(F("AT+CUSD=0"), true); } else if (ModemID == 1 || 2) { bal = String(gval.substring(gval.indexOf("\"") + 1,gval.indexOf("\","))); // } sendATCommand(F("AT+CUSD=0"), true); sms(String(F("Sim ")) + bal, 0); } } else if (Serial.available()) { // если в мониторе порта что-то ввели String sval = ""; while (Serial.available()) { // сохраняем входную строку в переменную val. char ch = Serial.read(); sval += char(ch); // собираем принятые символы в строку delay(3); } sendsmscaller = 0; Komand(sval); // запускаем консольную программу // sendsmscaller = 1; } } 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 if (CheckPhone(msgphone) == 1) Komand(msgsms); } int CheckPhone(String phone) { /// === проверка телефона === /// if (Firststart == 0) { // если не первый старт for (uint8_t i = 0; i < 5; i++) { if (phone == AlarmPhone[i] && phone != 0) { // если есть вызов, и он наш phone = AlarmPhone[i]; // запоминаем его. RingPhone = AlarmPhone[i]; // запоминаем его. RingPhone.toCharArray(Phone, 14); EEPROM.put(100, Phone); // записываем RingPhone в память. return 1; // возвращаем 1 - номер наш! } } return 0; // возвращаем 0 - номер не наш! } else if (Firststart == 1) { // иначе (если первый старт) // первый звонивший добавляется как основной мастер номер для управления сигнализацией sendATCommand("ATH", true); // кладем трубку phone.toCharArray(Phone, 14); 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("Firststart:")) + Firststart); sms(String(F("Master0->")) + phone + " Add", 0); // смс на звонивший // приходит смс в виде: " Master0:79111234567 Ok " } return 0; } void eepromconfig() { /// === конфигурирование сигнализации === /// 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); // SARAIon датчики дверей вкл. EEPROM.update(6, 1); // PIRon датчик движения вкл. EEPROM.update(7, 1); // GASon датчик газа вкл. EEPROM.update(8, 1); // Sirena сирена вкл. EEPROM.update(10, 1); // Firststart первый старт!. EEPROM.update(20, 0); // баланс, записываем массив в EEPROM EEPROM.update(0, 1); // 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); // Датчик двери 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 = ""; // текущее состояние датчика двери. String Pir = ""; // текущее состояние датчика движения. String Gas = ""; // текущее состояние датчика газа. if (Guard == 1) SIGN = F("System on\n"); else SIGN = F("System off\n"); if (Sirena == 1) SIRENA = F("Sirena on\n"); else SIRENA = F("Sirena off\n"); if (AlarmRING == 1) RING = F("Ring on\n"); else RING = F("Ring off\n"); if (SendSMS == 1) SMS = F("SMS on\n"); else SMS = F("SMS off\n"); if (DOORon == 1) Door = F("Door on\n"); else Door = F("Door off\n"); if (SARAIon == 1) Sarai = F("Sarai on\n"); else Sarai = F("Sarai off\n"); if (PIRon == 1) Pir = F("Pir on\n"); else Pir = F("Pir off\n"); if (GASon == 1) Gas = F("Gas on\n"); else Gas = F("Gas off"); String LastEvent = SIGN + RING + SMS + Door + Sarai + SIRENA + 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 == 1) { if (DOORState == HIGH && DOORFlag == 0) { previousMillis_door = millis(); DOORFlag = 1; // Serial.println(F("Dver' otkrita!")); Alarm(); // } else if (DOORState == LOW && DOORFlag == 1) { int currentMillis_door = millis(); if (((currentMillis_door - previousMillis_door) / 1000 > interval_door)) { DOORFlag = 0; } } } if (SARAIon == 1) { if (mySwitch.available()) { unsigned long value = mySwitch.getReceivedValue(); if (value == sarai && SARAIFlag == 0) { previousMillis_sarai = millis(); SARAIFlag = 1; // Serial.println(F("Sarai otkrit!")); Alarm(); // } mySwitch.resetAvailable(); } int currentMillis_sarai = millis(); if (((currentMillis_sarai - previousMillis_sarai) / 1000 > interval_sarai)) { SARAIFlag = 0; } } if (PIRon == 1) { if (PIRState == HIGH && PIRFlag == 0) { previousMillis_pir = millis(); PIRFlag = 1; // Serial.println(F("Dvizhenie u dveri!")); Alarm(); // } else if (PIRState == LOW && PIRFlag == 1) { int currentMillis_pir = millis(); if (((currentMillis_pir - previousMillis_pir) / 1000 > interval_pir)) { PIRFlag = 0; } } } if (GASon == 1) { if ((Smoky > GASThres) && GASFlag == 0) { previousMillis_gas = millis(); GASFlag = 1; delay(100); // Serial.println(F("Gas v dome!")); Alarm(); // } else if ((Smoky < GASThres) && GASFlag == 1) { int currentMillis_gas = millis(); if (((currentMillis_gas - previousMillis_gas) / 1000 > interval_gas)) { GASFlag = 0; } } } } void Alarm() { /// === запускаем сирену и отправку смс === /// previousMillis_alarm = millis(); if (Sirena == 1) digitalWrite(BUZ, LOW); Serial.println(F("Alarm!!!")); if (SendSMS == 1) { if (DOORFlag == 1) { sms(F("Dver' otkrita!"), 1); // смс на все номера } else if (SARAIFlag == 1) { sms(F("Sarai otkrit!"), 1); // смс на все номера } else if (PIRFlag == 1) { sms(F("Dvizhenie y dveri!"), 1); // смс на все номера } else if (GASFlag == 1) { sms(F("Gas v dome!"), 1); // смс на все номера } } if (AlarmRING == 1) { sendATCommand("ATD+" + String(AlarmPhone[0]) + ";", true); // вывключить эхо } } void AlarmPinOff() { /// === если прошло время, отключаем сирену === /// int currentMillis_alarm = millis(); if (((currentMillis_alarm - previousMillis_alarm) / 1000 > interval_alarm) || Guard == 0) { digitalWrite(BUZ, HIGH); } } void GuardOff() { /// === выключение сигнализации === /// Guard = 0; EEPROM.update(1, Guard); sms(String(F("System->off")), 1); // смс на все номера } void GuardOn() { /// === включение сигнализации === /// Guard = 1; EEPROM.update(1, Guard); sms(String(F("System->on")), 1); // смс на все номера } void Led() { /// === состояние светодиода === /// 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); } } void Komand(String kom) { /// === мастер смс === /// Serial.println("Kom->" + kom); kom.toLowerCase(); if (RingPhone == AlarmPhone[0] || sendsmscaller == 0) { // команды выполняются только с 0 мастер номера if (kom.indexOf(F("reset")) > -1) { // полный сброс ЕЕПРОМ sms(F("System Reset!"), 0); // смс на последний номер EEPROM.write(0, 0); eepromconfig(); Serial.println(eepromtext()); Serial.println(eepromphone()); } else if ((p = kom.indexOf(F("master"))) > -1) { // добавление мастер-номера master(kom.substring(p + 6, p + 7).toInt(), kom.substring(p + 8, kom.indexOf("\n", p + 8))); ///// sms типа: " master1:79111234567 " - ячейка + номер } else if ((p = kom.indexOf(F("balance:"))) > -1) { // добавление номера баланса balnum(kom.substring(p + 8, p + 11)); ///// sms типа: " balance:100 " - номер баланса } else if ((p = kom.indexOf(F("dell:"))) > -1) { // удаление номера из ячейки dellphone(kom.substring(p + 5, p + 6).toInt()); ///// sms типа: " dell:1 " - удалить номер из ячейки 1 } else if (kom.indexOf(F("phone")) > -1) { // инфо о номерах системы sms(eepromphone(), 0); // смс на последний номер } } if ((kom.indexOf(F("info")) > -1) || (kom.indexOf(F("?")) > -1)) { // инфо о состоянии системы Signal(); sms(eepromtext() + F("\nSignal seti: ") + CSQ + "%", 0); // смс на последний номер } else if (kom.indexOf(F("money")) > -1) { // запрос баланса balance(); } else if (kom.indexOf(F("datchiki")) > -1) { if (kom.indexOf(on) > -1) { // вкл DOORon = 1; SARAIon = 1; PIRon = 1; GASon = 1; EEPROM.update(4, DOORon); EEPROM.update(5, SARAIon); EEPROM.update(6, PIRon); EEPROM.update(7, GASon); } else if (kom.indexOf(off) > -1) { // выкл DOORon = 0; SARAIon = 0; PIRon = 0; GASon = 0; EEPROM.update(4, DOORon); EEPROM.update(5, SARAIon); EEPROM.update(6, PIRon); EEPROM.update(7, GASon); } 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 = 1; EEPROM.update(8, Sirena); sms(String(F("Sirena->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл Sirena = 0; EEPROM.update(8, Sirena); sms(String(F("Sirena->off")), 1); // смс на все номера } } else if (kom.indexOf(F("ring")) > -1) { // вкл/выкл вызов при сработке if (kom.indexOf(on) > -1) { // вкл AlarmRING = 1; EEPROM.update(2, AlarmRING); sms(String(F("Ring->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл AlarmRING = 0; EEPROM.update(2, AlarmRING); sms(String(F("Ring->off")), 1); // смс на все номера } } else if (kom.indexOf(F("sms")) > -1) { // вкл/выкл смс при сработке if (kom.indexOf(on) > -1) { // вкл SendSMS = 1; EEPROM.update(3, SendSMS); sms(String(F("SMS->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл SendSMS = 0; EEPROM.update(3, SendSMS); sms(String(F("SMS->off")), 1); // смс на все номера } } else if (kom.indexOf(F("door")) > -1) { // вкл/выкл контроль датчика двери if (kom.indexOf(on) > -1) { // выкл DOORon = 1; EEPROM.update(4, DOORon); sms(String(F("DOOR->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл контроль датчика двери DOORon = 0; EEPROM.update(4, DOORon); sms(String(F("DOOR->off")), 1); // смс на все номера } } else if (kom.indexOf(F("sarai")) > -1) { // вкл/выкл контроль датчика двери 2 if (kom.indexOf(on) > -1) { // вкл SARAIon = 1; EEPROM.update(5, SARAIon); sms(String(F("SARAI->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл SARAIon = 0; EEPROM.update(5, SARAIon); sms(String(F("SARAI->off")), 1); // смс на все номера } } else if (kom.indexOf(F("pir")) > -1) { // вкл/выкл контрол датчика движения if (kom.indexOf(on) > -1) { // вкл PIRon = 1; EEPROM.update(6, PIRon); sms(String(F("PIR->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл PIRon = 0; EEPROM.update(6, PIRon); sms(String(F("PIR->off")), 1); // смс на все номера } } else if (kom.indexOf(F("gas")) > -1) { // вкл/выкл контроль датчика газа if (kom.indexOf(on) > -1) { // вкл GASon = 1; EEPROM.update(7, GASon); sms(String(F("GAS->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл GASon = 0; EEPROM.update(7, GASon); sms(String(F("GAS->off")), 1); // смс на все номера } } gsm.println(F("AT+CMGD=1,4")); // стираем смс } void Signal() { String csq = sendATCommand(F("AT+CSQ"), true); // csq = csq.substring(csq.indexOf(":") + 2, csq.indexOf(",")); csq.trim(); csq.toCharArray(CSQ, 4); } void balance() { /// === проверка баланса сим-карты === /// EEPROM.get(20, Bal); // считываем массив символов delay(1000); // ждем секунду, т.к. вылетает с ошибкой if (ModemID == 1 || ModemID == 2) { sendATCommand(F("AT+CUSD=1"), true); // вывключить эхо sendATCommand(String(F("ATD#")) + Bal + "#;", true); // gsm.println(String(F("ATD#")) + Bal + "#;"); } else if (ModemID == 3) sendATCommand(String(F("AT+CUSD=1")) + ",#" + Bal + F("#,15"), true); gsm.println(String(F("AT+CUSD=1,#")) + Bal + "#,15"); Serial.println(String(F("Balance#")) + Bal + "#"); } void master (int i, String num) { /// === добавление мастер-номеров === /// if (i < 5 && i != 0) { num.toCharArray(Phone, 14); // конвертируем AlarmPhone[i] = num; // пишем номер EEPROM.put(Adress[i], Phone); // записываем массив в EEPROM sms(String(F("Master")) + i + ":" + num + " add", 0); // смс на 0 номер. }// else Serial.println(F("MAX number 4!")); // 4 номера максимум! // 0 номер можно удалить только через RESET!!! } void dellphone (int i) { /// === удаление мастар-номеров === /// if (i < 5 && i != 0) { sms(String(F("Master")) + i + ":" + AlarmPhone[i] + " dell", 0); // смс на 0 номер EEPROM.put(Adress[i], 0); AlarmPhone[i] = ""; // обнулим номер } } void balnum (String num) { /// === добавляем номер баланса === /// num.toCharArray(Bal, 4); // конвертируем EEPROM.put(20, Bal); // записываем массив в EEPROM sms(String(F("Balance:*")) + num + F("# Ok"), 0); // смс на 0 номер } void TempC() { /// === измеряем температуру === /// String temp; 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(); Temp = (data[1] << 8) + data[0]; Temp = Temp >> 4; } 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() { /// === инициализация модема === /// gsm.begin(9600); //Скорость порта для связи Arduino с GSM модулем waitConnect(); String val = sendATCommand(F("ATI"), true); if (val.indexOf(F("M590")) > -1) ModemID = 1; else if (val.indexOf(F("SIM800")) > -1) ModemID = 2; else if (val.indexOf("A6C") > -1) ModemID = 3; Serial.println(String(F("ModemID ")) + ModemID + "\n"); 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); // регистрация в сети } String sendATCommand(String cmd, bool waiting) { String atval = ""; // Переменная для хранения результата Serial.println(cmd); // Дублируем команду в монитор порта gsm.println(cmd); // Отправляем команду модулю if (waiting) { // Если необходимо дождаться ответа... 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...")); // ... оповещаем об этом и... Serial.println(atval); // Дублируем ответ в монитор порта } return atval; } void waitConnect() { // запуск модема int 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) { /// === отправка СМС === /// TempC(); String phone = ""; if (sendsmscaller == 1 && sendnum == 0) { // отправка смс на номер звонившего phone = RingPhone; sendATCommand("AT+CMGS=\"" + phone + "\"", true); // Переходим в режим ввода текстового сообщения sendATCommand(text + F("\nTemp ") + Temp + "*C" + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z Serial.println(String(F("SMS send=>")) + phone); } else if (sendsmscaller == 1 && sendnum == 1) { // отправка смс на все номера for (uint8_t i = 0; i < 4 ; i++) { phone = AlarmPhone[i]; if (phone != 0) { sendATCommand("AT+CMGS=\"" + phone + "\"", true); // Переходим в режим ввода текстового сообщения sendATCommand(text + F("\nTemp ") + Temp + "*C" + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z Serial.println(String(F("SMS send=>")) + phone); } } } else if (sendsmscaller == 0) Serial.println(text + F("\nTemp ") + Temp + "*C\n"); }без датчиков запустится, все датчики по умолчанию выключены, кроме температуры.
Взял подправленый код с 667 поста, в мониторе порта нечего не поменялось(
kot488, гляну через часик
Нашел сегодня А6, тот же результат.
Может в этом проблема? Подключил модем на прямую через usb-uart, на первой же команде ошибка. Потом ее повторяю все нормально. Через монитор порта не реагирует.
kot488, попробуйте команду настройки скорости AT+IPR=0, затем АТ.
Сегодня в ночь на работе, буду проверять коды
Может в этом проблема? Подключил модем на прямую через usb-uart, на первой же команде ошибка. Потом ее повторяю все нормально. Через монитор порта не реагирует.
Скорми модему команду
И будут тебе описания ошибок, вместо непонятных кодов.
Может в этом проблема? Подключил модем на прямую через usb-uart, на первой же команде ошибка. Потом ее повторяю все нормально. Через монитор порта не реагирует.
модем А6 ? у него проблемы с USSD в зависимости от прошивки, может не заработать. Мне например на SIM 800 пришлось переходить
Да, А6. Не подскажешь какие изменения нужно внести для перехода на SIM800?
Сейчас на руках sim800l, a590 и A6
данную сигнализацию не делал, пробовал на совсем других проектах, поэтому конкретно подсказать не смогу.
при переходе взял готовый проект с модемом A6, запустил его на sim800 и после каждой команды смотрел будет ошибка или нет,
в основном отличия в применении кавычек, и USSD баланс на A6 я так и не смог запустить.
Извиняюсь, ничего не успел на работе...пишу с телефона...
Для применения кода из #667 на сим800 замените:
093 unsigned long timer = 3600; // каждый час
131 timer += timer;
155 ind += 9;
176 if (gval.indexOf(F("+CUSD:")) > -1) { // если пришел баланс
177 int p1 = gval.indexOf("\""); // начало строки
180 int p2 = gval.lastIndexOf("\""); // конец строки
181 gval = gval.substring(p1 + 1, p2); // обрезаем строку
182 bal = gval;
183 Serial.println(bal);
184 sendATCommand(F("AT+CUSD=0"));
185 }
Далее внимательнее номера строк не будут совпадать, пишу как могу)))
211 Index += 9;
560 sendATCommand(String(F("AT+CUSD=1,#\"")) + Bal + F("\"#,15")); //на сим 800 нужны кавычки, на А6 нет...
571 void Decode7bit(){} удаляем функцию
591 digitalWrite(rst, LOW); // перезапускаем модем
592 delay(200);
593 digitalWrite(rst, HIGH);
Фух, вроде так, у меня на сим800 почему то не вышло с отправкой смс, попробуйте и пришлите данные из монитора порта
А6 у меня дефектных не попадалось, 2шт А6 и один А6С (с камерой был).
М590 3шт и все разные по АТ командам и току потребления.
SIM800l 2шт с разными прошивками отличия пока что увидел: gprs не завелся на одном, и голосовые команды на нём же не завелись
Изменил, ситуация та ж line
вот такой код вышел
// 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 dvizhenie 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 DVIZHENIEon = 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 DVIZHENIEFlag = 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_dvizhenie 10 // секунд не смотрим на датчик двери 2. unsigned long lasttime_dvizhenie = 0; #define time_pir 20 // секунд не смотрим на датчик движения. unsigned long lasttime_pir = 0; #define time_gas 600 // секунд не смотрим на датчик газа. 10 минут unsigned long lasttime_gas = 0; unsigned long timer = 3600; /* 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 += timer; } 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 += 9; 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) { // если пришел баланс int p1 = gval.indexOf("\""); // начало строки int p2 = gval.lastIndexOf("\""); // конец строки gval = gval.substring(p1 + 1, p2); // обрезаем строку bal = gval; 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 += 9; // Парсим строку и 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 DVIZHENIEon = 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 Restart() { /// === рестарт системы === /// digitalWrite(rst, LOW); // перезапускаем модем delay(200); digitalWrite(rst, HIGH); 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(); // если есть номер баланса проверяем его }по коду есть ребут модема, на sim800 не нашел контакта rst
RST после Vcc перед Rx
Извините пожалуйста не досмотрел.
Вообщем я походу баран и нашел проблему, симка которая стоит в модуле проверяет баланс через *111#, в этом судя по всему и вся проблема. Можно на програмной уровне заменить номер? Ведь через терминал не реагирует на команды, пока не загрузится нормально(
Так загрузится должна и так потом выполните команду reset
и добавьте номер баланса.
Там же в коде читал, пока 5 Ок не получит то не запустится. По коду на команду баланс нет ответа, вроде изза этого повторяется попытка
Alarm v2.1.3
загрузите такой код:
#include <SoftwareSerial.h> SoftwareSerial mySerial(7, 6); // модем подключен к 7 и 8 пинам. void setup(){ Serial.begin(9600); mySerial.begin(9600); } void loop() { if (mySerial.available()) Serial.write(mySerial.read()); if (Serial.available()) mySerial.write(Serial.read()); }и вводите в сериал поочередно команды, ответ сюда:
AT
ATE1
ATI
AT+CSQ
AT+CREG?
посмотрим что отвечает модем
Бывает ошибка на первой команде и на последней, если повторить то все ок
сделайте сброс до заводских AT&F
настройка модема, необходимы команды: AT+IPR=9600;E1+DDET=1;+CMGF=1;+CSCS=\"gsm\";+CNMI=2,1,0,0,0;+VTD=1;+CMEE=1;&W
да, если AT+CMEE=2 то выдаст описание ошибки
сделайте сброс до заводских AT&F
настройка модема, необходимы команды: AT+IPR=9600;E1+DDET=1;+CMGF=1;+CSCS=\"gsm\";+CNMI=2,1,0,0,0;+VTD=1;+CMEE=1;&W
да, если AT+CMEE=2 то выдаст описание ошибки
A6 нормально отработал команды.
кстати что у вас с питанием SIM800 4V?
кстати что у вас с питанием SIM800 4V?
Arduino UNO, в контакт 5V подключен. Так же и А6 подключал
Сейчас по такой же схеме подключен, на команды ответ дает
питание sim800 от 3.7В до 4.2В! если только у вас не v2. ну и тока на uno не хватит. я подключаю через dc\dc преобразователь в отдельный USB.
Я uno запитал от доп БП питания 5V.
На ногах 5V
sim800 нестабильно работает от 5V, если вообще работает...питание sim800 от 3.7В до 4.2В!
sim800 нестабильно работает от 5V, если вообще работает...питание sim800 от 3.7В до 4.2В!
Подал 4.1В, все по прежнему, Но команды как и раньше через putty вводятся только
AT&F делали?
AT&F делали?
Да
Вот так запустил строку
хм, я с таким не сталкивался, даже не знаю чем помочь... симка стоит? после AT&F снимите и подайте питание на модем. земля модема и uno соединены?
хм, я с таким не сталкивался, даже не знаю чем помочь... симка стоит? после AT&F снимите и подайте питание на модем. земля модема и uno соединены?
GND Uno идет на GND SIM800, через понижалку.
После сброса модем мусор постоянно начал кидать
это не мусор!
если постоянно
12Call Ready1314SMS Readyзначит модем постоянно перезагружается, что-то нето с питанием!!!
это не мусор!
если постоянно
12Call Ready1314SMS Readyзначит модем постоянно перезагружается, что-то нето с питанием!!!
Ходит на на ногах модем от 4.0 до 4.25
это не мусор!
если постоянно
12Call Ready1314SMS Readyзначит модем постоянно перезагружается, что-то нето с питанием!!!
Ходит на на ногах модем от 4.0 до 4.25
это не мусор!
если постоянно
12Call Ready1314SMS Readyзначит модем постоянно перезагружается, что-то нето с питанием!!!
Ходит на на ногах модем от 4.0 до 4.25
это не мусор!
если постоянно
12Call Ready1314SMS Readyзначит модем постоянно перезагружается, что-то нето с питанием!!!
Ходит на на ногах модем от 4.0 до 4.25
это не мусор!
если постоянно
12Call Ready1314SMS Readyзначит модем постоянно перезагружается, что-то нето с питанием!!!
Ходит на на ногах модем от 4.0 до 4.25