Я вначале писал: "у меня Arduino nano v3 (ATmega168), поэтому как ни крути а все не вместишь в него. Для моих нужд самое то, тем более цена вопроса в итоге проучается около 300р. За эти деньги ничего похожего не купишь.
Новая железка на руках, взял тоже Arduino nano v3. У Вас она питается как и модем, от 4.2В?
Подключил по схеме, команды отрабатывает на ура. Но все равно не работает.
Если всеже вернуться к A6, какое на него питание нужно подавать, он ведь нормально отрабатывает команды.
Вот так сеть отрабатывает отлично
#include <SoftwareSerial.h>
SoftwareSerial SIM800(8, 9); // 8 - RX Arduino (TX SIM800L), 9 - TX Arduino (RX SIM800L)
void setup() {
Serial.begin(9600); // Скорость обмена данными с компьютером
Serial.println("Start!");
SIM800.begin(9600); // Скорость обмена данными с модемом
SIM800.println("AT");
}
long lastcmd = millis();
void loop() {
if (SIM800.available()) // Ожидаем прихода данных (ответа) от модема...
Serial.write(SIM800.read()); // ...и выводим их в Serial
if (Serial.available()) // Ожидаем команды по Serial...
SIM800.write(Serial.read()); // ...и отправляем полученную команду модему
if (millis() - lastcmd > 5000) { // Прошло ли 5 секунд
lastcmd = millis(); // Фиксируем время
SIM800.println("AT+CSQ"); // Запрашиваем информацию о качестве сигнала
}
}
Благодаря martinholс drive2, на данный момент бьюсь над GPRS версией:
#include <EEPROM.h>
#include <RCSwitch.h>
#include <SoftwareSerial.h>
#include <DallasTemperature.h> // подключаем библиотеку чтения датчиков температуры
SoftwareSerial SIM800(7, 6); // для новых плат начиная с версии RX,TX
OneWire oneWire(4); // и настраиваем пин 4 как шину подключения датчиков DS18B20
DallasTemperature sensors(&oneWire);
RCSwitch mySwitch = RCSwitch(); // беспроводной датчик двери, пин 2.
#define LED 13 // на светодиод (моргалку)
#define BAT 15 // на батарею, через делитель напряжения 39кОм / 11 кОм
/* ------------------------------------- ДАТЧИКИ ------------------------*/
#define DOOR 8 // концевик двери. если сработал, на входе "+" HIGH.
#define PIR 9 // датчик движения. если сработал, на входе "+" HIGH.
#define BUZ 10 // сирена. если "-" LOW, то горит.
#define GAS 14 // датчик дыма. если сработал, на входе "+" HIGH.
#define sarai 3258553 // адрес 433 передатчика геркона двери. если сработал, на пин 2 сигнал.
boolean DOORFlag = false; // флаг состояние датчика двери.
boolean SARAYFlag = false; // флаг состояние датчика двери 2.
boolean PIRFlag = false; // флаг состояние датчика движения.
boolean GASFlag = false; // флаг состояние датчика газа.
int8_t LEDState = LOW; // Состояние светодиода.
int8_t DOORState = LOW; // Состояние концевика двери.
int8_t PIRState = LOW; // Состояние датчика движения.
int8_t Smoky = LOW; // Состояние датчика газа.
#define on "on" // вкл
#define off "off" // выкл
unsigned int p = 0;
#define GASThres 400 // предельная концентрация газа
#define time_sarai 10 // секунд не смотрим на датчик двери 2.
unsigned long lasttime_sarai = 0;
#define interval_led 1000 // для мигания LED, 1 сек.
unsigned long previousMillis_led = 0;
/* ----------------------------------------- НАСТРОЙКИ MQTT брокера--------------------------------------------------------- */
const char *MQTT_user = "****"; // api.cloudmqtt.com > Details > User
const char *MQTT_pass = "*****"; // api.cloudmqtt.com > Details > Password
const char *MQTT_type = "****"; // тип протокола
const char *MQTT_CID = "Home Alarm"; // уникальное имя устройства в сети MQTT
const char *MQTT_SERVER = "******"; // api.cloudmqtt.com > Details > Server сервер MQTT брокера
const char *PORT = "******4"; // api.cloudmqtt.com > Details > Port порт MQTT брокера
/* ----------------------------------------- ИНДИВИДУАЛЬНЫЕ НАСТРОЙКИ !!!--------------------------------------------------------- */
const char *APN = "internet.tele2.ru"; // тчка доступа выхода в интернет вашего сотового оператора
//String USER = ""; // имя выхода в интернет вашего сотового оператора
//String PASS = ""; // пароль доступа выхода в интернет вашего сотового оператора
/* ----------------------------------------- ДАЛЕЕ НЕ ТРОГАЕМ --------------------------------------------------------------- */
bool broker = false; // статус подклюлючения к брокеру
bool Firststart = true; // первый старт.
bool Guard = false; // состояние охраны после подачи питания
bool Buzer = false; // состояние охраны после подачи питания
bool Ring = false; // состояние охраны после подачи питания
bool Sms = false; // состояние охраны после подачи питания
bool Door = false; // состояние охраны после подачи питания
bool Saray = false; // состояние охраны после подачи питания
bool Pir = false; // состояние охраны после подачи питания
bool Gas = false; // состояние охраны после подачи питания
int interval = 3; // интервал отправки данных на сервер после загрузки ардуино
int Timer = 10; // Секунд до отключения "тревожного" пина.
unsigned long lasttimer = 0;
int inDS = 0;
float m = 68.01; // делитель для перевода АЦП в вольты для резистров 39/11kOm
float TempDS[11]; // массив хранения температуры c рахных датчиков
float Vbat, V_min; // переменная хранящая напряжение бортовой сети
unsigned long Time1, Time2 = 0;
char CSQ[4]; // для хранения уровня сигнала.
char MONEY[5]; // хранение баланса.
char Phone[14]; // для временного хранения номера телефона, номер до 14 цифр.
String RingPhone = ""; // номер звонившего.
String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс.
byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ.
char Bal[4]; // для хранения номера баланса.
void setup() {
Serial.begin(9600); //скорость порта
SIM800.begin(9600); //скорость связи с модемом
SIM800_reset();
pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +.
pinMode(PIR, INPUT); digitalWrite(PIR, HIGH); //
mySwitch.enableReceive(0); // RF433 приемник на 2 пине
pinMode(GAS, INPUT);
pinMode(BUZ, OUTPUT); digitalWrite(BUZ, LOW); // сирена выкл.
pinMode(LED, OUTPUT); // указываем пин на выход (светодиод)
Serial.println(F("MQTT alarm\n"));
Serial.println(eepromphone());
Serial.println("");
eepromconfig();
Serial.println(eepromtext());
Serial.println("");
}
void loop() {
AlarmPinOff();
if (SIM800.available()) resp_modem(); // если что-то пришло от SIM800 в Ардуино отправляем для разбора
if (Serial.available()) resp_serial(); // если что-то пришло от Ардуино отправляем в SIM800
if (millis()> Time1 + 10000) Time1 = millis(), detection(); // выполняем функцию detection () каждые 10 сек
if (millis()> Time2 + 3600000) { // каждый час
Time2 = millis();
Signal();
SIM800.println("AT+CIPSEND"), delay (200);
MQTT_PUB ("home/signal", CSQ);
MQTT_PUB ("home/balance", MONEY);
SIM800.write(0x1A);
}
}
void resp_serial() { // ---------------- ТРАНСЛИРУЕМ КОМАНДЫ из ПОРТА В МОДЕМ ----------------------------------
String at = "";
int k = 0;
while (Serial.available()) {
k = Serial.read();
at += char(k);
delay(1);
}
Komand(at); // запускаем подпрограмму распознавания команд
}
float VoltRead() { // замеряем напряжение на батарее и переводим значения в вольты
float ADCC = analogRead(BAT);
ADCC = ADCC / m ;
Serial.println(String(F("Напряжение: ")) + ADCC + "V");
if (ADCC < V_min) V_min = ADCC;
return(ADCC); // переводим попугаи в вольты
}
void detection() { // условия проверяемые каждые 10 сек
Detect();
Vbat = VoltRead(); // замеряем напряжение на батарее
Serial.println(String(F("Интервал: ")) + interval);
inDS = 0;
sensors.requestTemperatures(); // читаем температуру с трех датчиков
while (inDS < 10) {
TempDS[inDS] = sensors.getTempCByIndex(inDS); // читаем температуру
if (TempDS[inDS] == -127.00) {
TempDS[inDS]= 80;
break; // пока не доберемся до неподключенного датчика
}
inDS++;
}
for (int i=0; i < inDS; i++) {
Serial.println(String(F("Temp")) + i + "= " + TempDS[i]);
}
Serial.println("");
interval--;
if (interval < 1) {
interval = 6;
if (broker == true) {
eepromconfig();
eepromtext();
SIM800.println("AT+CIPSEND"), delay (200);
/////////////------состояние датчиков----------/////////////
MQTT_FloatPub ("home/ds0", TempDS[0],2);
MQTT_FloatPub ("home/ds1", TempDS[1],2);
MQTT_FloatPub ("home/vbat", Vbat,2);
/////////////------состояние системы----------/////////////
MQTT_PUB ("home/guard", Guard ? "lock" : "unlock");
MQTT_PUB ("home/buzer", Buzer ? "buzeron" : "buzeroff");
MQTT_PUB ("home/ring", Ring ? "ringon" : "ringoff");
MQTT_PUB ("home/sms", Sms ? "smson" : "smsoff");
MQTT_PUB ("home/door", Door ? "dooron" : "dooroff");
MQTT_PUB ("home/saray", Saray ? "sarayon" : "sarayoff");
MQTT_PUB ("home/pir", Pir ? "piron" : "piroff");
MQTT_PUB ("home/gas", Gas ? "gason" : "gasoff");
MQTT_FloatPub ("home/timer", Timer, 0);
MQTT_FloatPub ("home/uptime", millis()/3600000,0);
SIM800.write(0x1A);
} else SIM800.println(F("AT+SAPBR=3,1,\"Contype\",\"GPRS\"")); // подключаемся к GPRS
}
}
void MQTT_FloatPub(const char topic[15], float val, int x) {char st[10]; dtostrf(val,0, x, st), MQTT_PUB (topic, st);}
void MQTT_PUB(const char MQTT_topic[15], const char MQTT_messege[15]) { // пакет на публикацию
SIM800.write(0x30), SIM800.write(strlen(MQTT_topic)+strlen(MQTT_messege)+2);
SIM800.write((byte)0), SIM800.write(strlen(MQTT_topic)), SIM800.write(MQTT_topic); // топик
SIM800.write(MQTT_messege); // сообщение
}
void MQTT_SUB(const char MQTT_topic[15]) { // пакет подписки на топик
SIM800.write(0x82), SIM800.write(strlen(MQTT_topic)+5); // сумма пакета
SIM800.write((byte)0), SIM800.write(0x01), SIM800.write((byte)0); // просто так нужно
SIM800.write(strlen(MQTT_topic)), SIM800.write(MQTT_topic); // топик
SIM800.write((byte)0);
}
void MQTT_SEND(const char MQTT_topic[15], const char MQTT_messege[15]) {
SIM800.println("AT+CIPSEND"), delay (200);
SIM800.write(0x30), SIM800.write(strlen(MQTT_topic)+strlen(MQTT_messege)+2);
SIM800.write((byte)0), SIM800.write(strlen(MQTT_topic)), SIM800.write(MQTT_topic); // топик
SIM800.write(MQTT_messege); // сообщение
SIM800.write(0x1A);
}
void resp_modem() { //------------------ АНЛИЗИРУЕМ БУФЕР ВИРТУАЛЬНОГО ПОРТА МОДЕМА------------------------------
String at = "";
int k = 0;
while (SIM800.available()) {
k = SIM800.read();
at += char(k);
delay(1);
}
Serial.println(at);
if (at.indexOf(F("SMS Ready")) > -1 || at.indexOf(F("NO CARRIER")) > -1 ) {
SIM800.println(F("AT+IPR=9600;E1+DDET=1;+CMGF=1;+CSCS=\"gsm\";+CNMI=2,2,0,0,0;+VTD=1;+CMEE=1;&W")); // Активируем АОН и декодер DTMF
Signal();
/* -------------------------------------- проверяем соеденеиние с ИНТЕРНЕТ, конектимся к серверу------------------------------------------------------- */
} else if (at.indexOf(F("+CME ERROR:")) > -1 ) {
broker = false, delay (50), SIM800.println("AT+CFUN=1,1"), interval = 6 ;
} else if (at.indexOf(F("AT+SAPBR=3,1,\"Contype\",\"GPRS\"\r\r\nOK")) > -1 ) {
SIM800.println(String(("AT+SAPBR=3,1,\"APN\",\"")) + APN + "\"");
} else if (at.indexOf(String(("AT+SAPBR=3,1,\"APN\",\"")) + APN + "\"\r\r\nOK") > -1 ) {
SIM800.println(F("AT+SAPBR=1,1")), delay (1000); // устанавливаем соеденение
} else if (at.indexOf(F("AT+SAPBR=1,1\r\r\nOK")) > -1 ) {
SIM800.println(F("AT+SAPBR=2,1")),delay (1000); // проверяем статус соединения
} else if (at.indexOf(F("+SAPBR: 1,1")) > -1 ) {
SIM800.println(String(("AT+CIPSTART=\"TCP\",\"")) + MQTT_SERVER + "\",\"" + PORT + "\"");
/* -------------------------------------- команды управления ------------------------------------------*/
} else if (at.indexOf(F("home/comandlock"),4) > -1 ) guard(1), MQTT_SEND ("home/send", "lock");
else if (at.indexOf(F("home/comandunlock"),4) > -1 ) guard(0), MQTT_SEND ("home/send", "unlock");
else if (at.indexOf(F("home/comandbuzeron"),4) > -1 ) buzer(1), MQTT_SEND ("home/send", "buzeron");
else if (at.indexOf(F("home/comandbuzeroff"),4) > -1 ) buzer(0), MQTT_SEND ("home/send", "buzeroff");
else if (at.indexOf(F("home/comandringon"),4) > -1 ) ring(1), MQTT_SEND ("home/send", "ringon");
else if (at.indexOf(F("home/comandringoff"),4) > -1 ) ring(0), MQTT_SEND ("home/send", "ringoff");
else if (at.indexOf(F("home/comandsmson"),4) > -1 ) sms(1), MQTT_SEND ("home/send", "smson");
else if (at.indexOf(F("home/comandsmsoff"),4) > -1 ) sms(0), MQTT_SEND ("home/send", "smsoff");
else if (at.indexOf(F("home/comanddooron"),4) > -1 ) door(1), MQTT_SEND ("home/send", "dooron");
else if (at.indexOf(F("home/comanddooroff"),4) > -1 ) door(0), MQTT_SEND ("home/send", "dooroff");
else if (at.indexOf(F("home/comandpiron"),4) > -1 ) pir(1), MQTT_SEND ("home/send", "piron");
else if (at.indexOf(F("home/comandpiroff"),4) > -1 ) pir(0), MQTT_SEND ("home/send", "piroff");
else if (at.indexOf(F("home/comandgason"),4) > -1 ) gas(1), MQTT_SEND ("home/send", "gason");
else if (at.indexOf(F("home/comandgasoff"),4) > -1 ) gas(0), MQTT_SEND ("home/send", "gasoff");
else if (at.indexOf(F("home/comandsarayon"),4) > -1 ) saray(1), MQTT_SEND ("home/send", "sarayon");
else if (at.indexOf(F("home/comandsarayoff"),4) > -1 ) saray(0), MQTT_SEND ("home/send", "sarayoff");
else if (at.indexOf(F("home/settimer"),4) > -1 ) {
Timer = at.substring(at.indexOf("") + 17, at.indexOf("") + 20).toInt();
EEPROM.put(10, Timer);
} else if (at.indexOf(F("home/comandrefresh"),4) > -1 ) {
//Serial.println(F("Команда обновления"));
Serial.println(eepromphone());
Serial.println("");
eepromconfig();
eepromtext();
Serial.println("");
SIM800.println("AT+CIPSEND"), delay (200);
/////////////------состояние датчиков----------/////////////
MQTT_FloatPub ("home/ds0", TempDS[0],2);
MQTT_FloatPub ("home/ds1", TempDS[1],2);
MQTT_FloatPub ("home/vbat", Vbat,2);
MQTT_PUB ("home/door", DOORFlag ? "dooropen" : "doorclose");
MQTT_PUB ("home/pir", PIRFlag ? "piropen" : "pirclose");
MQTT_PUB ("home/saray", SARAYFlag ? "sarayopen" : "sarayclose");
MQTT_PUB ("home/gas", GASFlag ? "gasopen" : "gasclose");
/////////////------состояние системы----------/////////////
MQTT_PUB ("home/guard", Guard ? "lock" : "unlock");
MQTT_PUB ("home/buzer", Buzer ? "buzeron" : "buzeroff");
MQTT_PUB ("home/ring", Ring ? "ringon" : "ringoff");
MQTT_PUB ("home/sms", Sms ? "smson" : "smsoff");
MQTT_PUB ("home/door", Door ? "dooron" : "dooroff");
MQTT_PUB ("home/saray", Saray ? "sarayon" : "sarayoff");
MQTT_PUB ("home/pir", Pir ? "piron" : "piroff");
MQTT_PUB ("home/gas", Gas ? "gason" : "gasoff");
MQTT_PUB ("home/signal", CSQ);
MQTT_PUB ("home/balance", MONEY);
MQTT_FloatPub ("home/timer", Timer, 0);
MQTT_FloatPub ("home/uptime", millis()/3600000,0);
SIM800.write(0x1A);
interval = 6; // швырнуть данные на сервер и ждать 60 сек
} else if (at.indexOf(F("CONNECT OK\r\n")) > -1 ) MQTT_CONNECT (); // после соединения с сервером отправляем пакет авторизации, публикации и пдписки у брокера
else if (at.indexOf(F("+CLIP: ")) > -1) { // если обнаружен вызов.
SIM800.println(F("ATH")); // снимаем трубку
for (int i = 0; i < 5; i++) { // проверяем сохраненные номера
if (at.indexOf(AlarmPhone[i]) > -1 && AlarmPhone[i] != 0) { // если он наш
RingPhone = AlarmPhone[i]; // запоминаем номер звонящего
RingPhone.toCharArray(Phone, 14);
EEPROM.put(100, Phone); // записываем RingPhone в память.
} else if (Firststart) { // если первый старт
int ind = at.indexOf(F("+CLIP: \"")); // обрезаем номер ...
ind += 8;
String ring = at.substring(ind, at.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 (at.indexOf(F("+CSQ:")) > -1) { // если пришел уровень сигнала
at = at.substring(at.indexOf(":") + 2, at.indexOf(",")); // парсим ответ об уровне сигнала
at.trim(); // удаляем пробелы вначале и в конце строки
at.toCharArray(CSQ, 4);
Balance();
} else if (at.indexOf(F("+CUSD:")) > -1) { // если пришел баланс
int p1 = at.indexOf("\""); // начало строки
int p2 = at.lastIndexOf("\""); // конец строки
at = at.substring(p1 + 1, p2); // обрезаем строку
String money = getBalFromString(at); // обрезаем числовые
money.toCharArray(MONEY, 10); // конвертируем
SIM800.println(F("AT+CUSD=0"));
}
}
void MQTT_CONNECT() {
SIM800.println("AT+CIPSEND"), delay (100);
SIM800.write(0x10); // маркер пакета на установку соединения
SIM800.write(strlen(MQTT_type)+strlen(MQTT_CID)+strlen(MQTT_user)+strlen(MQTT_pass)+12);
SIM800.write((byte)0),SIM800.write(strlen(MQTT_type)),SIM800.write(MQTT_type); // тип протокола
SIM800.write(0x03), SIM800.write(0xC2),SIM800.write((byte)0),SIM800.write(0x3C); // просто так нужно
SIM800.write((byte)0), SIM800.write(strlen(MQTT_CID)), SIM800.write(MQTT_CID); // MQTT идентификатор устройства
SIM800.write((byte)0), SIM800.write(strlen(MQTT_user)), SIM800.write(MQTT_user); // MQTT логин
SIM800.write((byte)0), SIM800.write(strlen(MQTT_pass)), SIM800.write(MQTT_pass); // MQTT пароль
MQTT_PUB ("home/status", "Подключено"); // пакет публикации
MQTT_SUB ("home/comand"); // пакет подписки на присылаемые команды
MQTT_SUB ("home/settimer"); // пакет подписки на присылаемые команды
MQTT_PUB ("home/signal", CSQ);
MQTT_PUB ("home/balance", MONEY);
MQTT_FloatPub ("home/timer", Timer, 0);
SIM800.write(0x1A), broker = true; // маркер завершения пакета
}
void Signal() {
SIM800.println(F("AT+CSQ")); // проверяем уровень сигнала сети
}
void Balance() {
SIM800.println(String(F("AT+CUSD=1,\"#")) + Bal + ("#\",15")); // проверяем баланс на симкарте
}
void guard (bool st) {
Guard = st;
EEPROM.write(1, st); // пишем в EEPROM
}
void buzer(bool st) {
Buzer = st;
EEPROM.write(2, st); // пишем в EEPROM
}
void ring(bool st) {
Ring = st;
EEPROM.write(3, st); // пишем в EEPROM
}
void sms(bool st) {
Sms = st;
EEPROM.write(4, st); // пишем в EEPROM
}
void door(bool st) {
Door = st;
EEPROM.write(5, st); // пишем в EEPROM
}
void saray(bool st) {
Saray = st;
EEPROM.write(6, st); // пишем в EEPROM
}
void pir(bool st) {
Pir = st;
EEPROM.write(7, st); // пишем в EEPROM
}
void gas(bool st) {
Gas = st;
EEPROM.write(8, st); // пишем в EEPROM
}
String getBalFromString(String str) { // Функция извлечения цифр из сообщения - для парсинга баланса из USSD-запроса
bool flag = false;
String result = "";
str.replace(",", "."); // Если в качестве разделителя десятичных используется запятая - меняем её на точку.
for (int i = 0; i < str.length(); i++) {
if (isDigit(str[i]) || (str[i] == (char)46 && flag)) { // Если начинается группа цифр (при этом, на точку без цифр не обращаем внимания),
if (result == "" && i > 0 && (String)str[i - 1] == "-") { // Нельзя забывать, что баланс может быть отрицательным
result += "-"; // Добавляем знак в начале
}
result += str[i]; // начинаем собирать их вместе
if (!flag) flag = true; // Выставляем флаг, который указывает на то, что сборка числа началась.
}
else { // Если цифры закончились и флаг говорит о том, что сборка уже была,
if (str[i] != (char)32) { // Если порядок числа отделен пробелом - игнорируем его, иначе...
if (flag) break; // ...считаем, что все.
}
}
}
return result; // Возвращаем полученное число.
}
void SIM800_reset() { // перезагрузка модема
SIM800.println("AT+CFUN=1,1");
}
void eepromconfig() { /// === конфигурирование сигнализации === ///
if (EEPROM.read(0) != 1) { // если по 0 адресу записана не 1, переписываем в память 000
for (int i = 0 ; i < 512 ; i++) { // переписываем все ячейки
EEPROM.write(i, 0);
} // и записываем:
EEPROM.update(0, 1); // пишем 1 в 0 адрес
EEPROM.update(1, 0); // Guard охрана выкл.
EEPROM.update(2, 0); // Sirena сирена при сработке вкл.
EEPROM.update(3, 0); // RING вызов при сработке вкл.
EEPROM.update(4, 0); // SMS смс при сработке вкл.
EEPROM.update(5, 0); // DOOR датчики дверей вкл.
EEPROM.update(6, 0); // SARAI датчики дверей вкл.
EEPROM.update(7, 0); // PIR датчик движения вкл.
EEPROM.update(8, 0); // GAS датчик газа вкл.
EEPROM.update(9, 1); // Firststart первый старт!
Serial.println(F("EEPROM != 1/ RESET!"));
} if (EEPROM.read(0) == 1) { // если в 0 записана 1, считываем конфигурацию
Guard = EEPROM.read(1); // Охрана
Buzer = EEPROM.read(2); // Сирена
Ring = EEPROM.read(3); // Вызов
Sms = EEPROM.read(4); // Отправка смс
Door = EEPROM.read(5); // Датчик двери
Saray = EEPROM.read(6); // Датчик двери
Pir = EEPROM.read(7); // Датчик движения
Gas = EEPROM.read(8); // Датчик газа/дыма
Firststart = EEPROM.read(9); // Первый старт
EEPROM.get(10, Timer);
}
}
String eepromtext() { /// === состояние системы === ///
String SIGN = ""; // текущее состояние системы.
String sirena = ""; // сирена при сработке.
String ring = ""; // вызов при сработке.
String sms = ""; // смс при сработке.
String door = ""; // датчика двери.
String saray = ""; // датчика двери RF433.
String pir = ""; // датчик движения.
String gas = ""; // датчик газа.
if (Guard) SIGN = F("System on\n"); else SIGN = F("System off\n");
if (Buzer) sirena = F("Sirena on\n"); else sirena = F("Sirena off\n");
if (Ring) ring = F("Ring on\n"); else ring = F("Ring off\n");
if (Sms) sms = F("SMS on\n"); else sms = F("SMS off\n");
if (Door) door = F("Door on\n"); else door = F("Door off\n");
if (Saray) saray = F("Sarai on\n"); else saray = F("Sarai off\n");
if (Pir) pir = F("Pir on\n"); else pir = F("Pir off\n");
if (Gas) gas = F("Gas on\n"); else gas = F("Gas off");
String LastEvent = SIGN + sirena + ring + sms + door + saray + 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 sms(String text, byte sendnum) { /// === отправка СМС === ///
String phone = "";
text += String(F("\nTemp_ul ")) + TempDS[0]; // добавляем к тексту температуру на улице
text += String(F("*C\nTemp_pom ")) + TempDS[1]; // добавляем к тексту температуру на в помещении
text += String(F("*C\n")) + MONEY; // добавляем к тексту баланс sim карты
if (!sendnum) { // отправка смс на номер звонившего
phone = RingPhone;
SIM800.println(String(F("AT+CMGS=\"+")) + phone + "\""); // Переходим в режим ввода текстового сообщения
SIM800.println(text + (String)((char)26)); // отправка текста
} else if (sendnum) { // отправка смс на все номера
for (uint8_t i = 0; i < 4 ; i++) {
phone = AlarmPhone[i];
if (phone != 0) { // если ячейка пустая - не отправлять смс
SIM800.println(String(F("AT+CMGS=\"+")) + phone + "\""); // Переходим в режим ввода текстового сообщения
SIM800.println(text + (String)((char)26)); // отправка текста
}
}
}
}
void Komand(String kom) { /// === мастер смс === ///
Serial.println("Kom->" + kom);
kom.toLowerCase(); //
if (RingPhone == AlarmPhone[0]) { // команды выполняются только с 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);
SIM800_reset(); // перезапускаем модем
}
}
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) { // включить все датчики одной командой
Door = true; // вкл датчик двери
Saray = true; // вкл датчик двери RF433
Pir = true; // вкл датчик движения
Gas = true; // вкл датчик газа
EEPROM.update(4, Door); // пишем в EEPROM
EEPROM.update(5, Saray); // пишем в EEPROM
EEPROM.update(6, Pir); // пишем в EEPROM
EEPROM.update(7, Gas); // пишем в EEPROM
} else if (kom.indexOf(off) > -1) { // выключить все датчики
Door = false; // выкл датчик двери
Saray = false; // выкл датчик двери RF433
Pir = false; // выкл датчик движения
Gas =false; // выкл датчик газа
EEPROM.update(4, Door); // пишем в EEPROM
EEPROM.update(5, Saray); // пишем в EEPROM
EEPROM.update(6, Pir); // пишем в EEPROM
EEPROM.update(7, Gas); // пишем в 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) { // вкл сирену при сработке
Buzer = true;
EEPROM.update(8, Buzer); // пишем в EEPROM
sms(String(F("Sirena->on")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл сирену при сработке
Buzer = false;
EEPROM.update(8, Buzer); // пишем в EEPROM
sms(String(F("Sirena->off")), 1); // смс на все номера
}
} else if (kom.indexOf(F("ring")) > -1) { // вкл/выкл вызов при сработке
if (kom.indexOf(on) > -1) { // вкл вызов при сработке
Ring = true;
EEPROM.update(2, Ring); // пишем в EEPROM
sms(String(F("Ring->on")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл вызов при сработке
Ring = false;
EEPROM.update(2, Ring); // пишем в EEPROM
sms(String(F("Ring->off")), 1); // смс на все номера
}
} else if (kom.indexOf(F("sms")) > -1) { // вкл/выкл смс при сработке
if (kom.indexOf(on) > -1) { // вкл смс при сработке
Sms = true;
EEPROM.update(3, Sms); // пишем в EEPROM
sms(String(F("SMS->on")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл смс при сработке
Sms = false;
EEPROM.update(3, Sms); // пишем в EEPROM
sms(String(F("SMS->off")), 1); // смс на все номера
}
} else if (kom.indexOf(F("door")) > -1) { // вкл/выкл контроль датчика двери
if (kom.indexOf(on) > -1) { // вкл контроль датчика двери
Door = true;
EEPROM.update(4, Door); // пишем в EEPROM
sms(String(F("DOOR->on")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл контроль датчика двери
Door = false;
EEPROM.update(4, Door); // пишем в EEPROM
sms(String(F("DOOR->off")), 1); // смс на все номера
}
} else if (kom.indexOf(F("sarai")) > -1) { // вкл/выкл контроль датчика двери RF433
if (kom.indexOf(on) > -1) { // вкл контроль RF433
Saray = true;
EEPROM.update(5, Saray); // пишем в EEPROM
sms(String(F("SARAI->on")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл контроль RF433
Saray = false;
EEPROM.update(5, Saray); // пишем в EEPROM
sms(String(F("SARAI->off")), 1); // смс на все номера
}
} else if (kom.indexOf(F("pir")) > -1) { // вкл/выкл контроль датчика движения
if (kom.indexOf(on) > -1) { // вкл контроль датчика движения
Pir = true;
EEPROM.update(6, Pir); // пишем в EEPROM
sms(String(F("PIR->on")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл контроль датчика движения
Pir = false;
EEPROM.update(6, Pir); // пишем в EEPROM
sms(String(F("PIR->off")), 1); // смс на все номера
}
} else if (kom.indexOf(F("gas")) > -1) { // вкл/выкл контроль датчика газа
if (kom.indexOf(on) > -1) { // вкл контроль датчика газа
Gas = true;
EEPROM.update(7, Gas); // пишем в EEPROM
sms(String(F("GAS->on")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл контроль датчика газа
Gas = false;
EEPROM.update(7, Gas); // пишем в EEPROM
sms(String(F("GAS->off")), 1); // смс на все номера
}
}
SIM800.println(F("AT+CMGD=1,4")); // стираем смс
}
void GuardOn() { /// === включение сигнализации === ///
Guard = true;
EEPROM.update(1, Guard);
sms(F("System->on"), 1); // смс на все номера
}
void GuardOff() { /// === выключение сигнализации === ///
Guard = false;
EEPROM.update(1, Guard);
sms(F("System->off"), 1); // смс на все номера
}
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 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 Detect() { /// === чтение датчиков === ///
DOORState = digitalRead(DOOR);
PIRState = digitalRead(PIR);
Smoky = analogRead(GAS);
if (DOORState == HIGH && !DOORFlag) { // если он сработал
DOORFlag = true; // ставим флаг
Serial.println(F("Dver' otkrita!"));
MQTT_SEND ("home/door", "dooropen");
if (Door) Alarm(); // запускаем подпрограмму Alarm
} else if (DOORState == LOW && DOORFlag) {
DOORFlag = false; // возвращаем флаг к начальному состоянию
Serial.println(F("Dver' zakrita!"));
MQTT_SEND ("home/door", "doorclose");
}
if (mySwitch.available()) { // если датчик сарая включен
unsigned long value = mySwitch.getReceivedValue(); // считываем значение с RF433
if (value == sarai && !SARAYFlag) { // если он сработал
lasttime_sarai = millis(); // запускаем таймер
SARAYFlag = true; // ставим флаг
Serial.println(F("Sarai otkrit!"));
// MQTT_SEND ("home/saray", "sarayopen");
if (Saray) Alarm(); // запускаем подпрограмму Alarm
}
mySwitch.resetAvailable();
}
if (((millis() - lasttime_sarai)/1000 > time_sarai)) { // если прошол интервал
SARAYFlag = false; // возвращаем флаг к начальному состоянию
// MQTT_SEND ("home/saray", "sarayclose");
}
if (PIRState == HIGH && !PIRFlag) { // если он сработал
PIRFlag = true; // ставим флаг
Serial.println(F("Dvizhenie u dveri!"));
MQTT_SEND ("home/pir", "piropen");
if (Pir) Alarm(); // запускаем подпрограмму Alarm
} else if (PIRState == LOW && PIRFlag) { // иначе если движения нет
PIRFlag = false; // возвращаем флаг к начальному состоянию
MQTT_SEND ("home/pir", "pirclose");
}
if ((Smoky > GASThres) && !GASFlag) { // если он сработал
GASFlag = true; // ставим флаг
Serial.println(F("Gas v dome!"));
MQTT_SEND ("home/gas", "gasopen");
if (Gas) Alarm(); // запускаем подпрограмму Alarm
} else if ((Smoky < GASThres) && GASFlag) { // иначе если газа нет
GASFlag = false; // возвращаем флаг к начальному состоянию
MQTT_SEND ("home/gas", "gasclose");
}
}
void Alarm() { /// === аварийные сигналы === ///
if (Buzer) { // если включена сирена при сработке
lasttimer = millis(); // запускаем таймер сирены
digitalWrite(BUZ, HIGH); // запускаем ее
}
Serial.println(F("Alarm!!!"));
if (DOORFlag) { // если сработал датчик двери
}
if (SARAYFlag) { // если сработал датчик двери RF433
}
if (PIRFlag) { // если сработал датчик движения
}
if (GASFlag) { // если сработал датчик газа
}
}
void AlarmPinOff() { /// === отключаем сирену === ///
if ((millis() - lasttimer)/1000 > Timer) digitalWrite(BUZ, LOW); // если прошло время, отключаем сирену
}
смс пока не проверял, еще не все добавил, но работает. использую приложение MQTT dash, но оно не устраивает отсутствием уведомлений и виджета.
подскажите есть ли какое приложение. чтоб можно было добавить виджет и уведомления по изменения статуса устройств, т.к. смс уже не устраивает?
AleksandrM, про MQTT_type позже напишу.
А6 не подойдёт, хотя если можете переписать под под него, то не проблема (у меня завести gprs на А6 была проблема)
AleksandrM, про MQTT_type позже напишу. А6 не подойдёт, хотя если можете переписать под под него, то не проблема (у меня завести gprs на А6 была проблема)
Паша. я на А6 в инет выходил без проблем, Яндекс скачивался. Дальше правда не копал, проект с А6 пока заброшен, отодвинут более актуальными задачками :)
Short Circuit, у меня 2 модема, один с версией 1308, другой 1418., Вот первый не пошел по gprs, а второй норм. Завтра скину ссылку что я нашел по прошивке (смене по модема)
В loop() {
if (millis()/1000 > timer) { // проверяем каждый час
Signal(); // проверяем уровень сигнала
timer += 360;
} Пост 667 смотрите, не могу с телефона писать...до компа доберусь только в четверг))
Проверяем уровень сигнала и тем самым убиваем 2х зайцев (можно заменить на регистрацию в сети). В подпрограмме sendATcomand(): если не придет ответ на команду, дергаем ногу модема reset. Но это для А6го.
Для sim800 можно программно перезагружать: в 705 посте посмотрите)
В loop() { if (millis()/1000 > timer) { // проверяем каждый час Signal(); // проверяем уровень сигнала timer += 360; } Пост 667 смотрите, не могу с телефона писать...до компа доберусь только в четверг)) Проверяем уровень сигнала и тем самым убиваем 2х зайцев (можно заменить на регистрацию в сети). В подпрограмме sendATcomand(): если не придет ответ на команду, дергаем ногу модема reset. Но это для А6го. Для sim800 можно программно перезагружать: в 705 посте посмотрите)
Мучался на коленке собирать, сделал плату и заказал в китае.
Питание как видите, одна понижайка на 5в (ардуино, реле, часы) и вторая на 3.3в на GSM. с другой стороны преобразователь уровней с 3.3 на 5в. Кстате после всякого навесного монтажа работать стало стабильнее, всяких проблем с модемом не стало. Правда есть кое какие косяки по разводке но это выяснилось потом при монтаже уже.
А так это система полива и контроля состояния воды в баке, на этой же печатке сделали контроль отопительной системы в доме зимой.
Так что код универсален и подстраивается как надо
п.с. в коде #705 ошибка (у меня не захотел работать как надо)
153 ind += 8;
заменить на ind+=9, а то получается не состыковка по номерам, записывается в памяти как +79123456789 а последний звонивший отображается 79123456789 т.е. без +, и ардуинка не понимает
smesharik, это, как выяснилось, с разными операторами необходимо менять (Теле2 и МТС номер возвращается с + и без). Насколько помню у сим800 питание от 3.6В-4.2В.
smesharik, это, как выяснилось, с разными операторами необходимо менять (Теле2 и МТС номер возвращается с + и без). Насколько помню у сим800 питание от 3.6В-4.2В.
Ну вы меня поняли :) По мануалу 3,4-4,4в. Я где то 3.8 поставил
4.25 много, снижайте, стабильное напряжение надо
это не мусор!
если постоянно
12Call Ready1314SMS Readyзначит модем постоянно перезагружается, что-то нето с питанием!!!
Ходит на на ногах модем от 4.0 до 4.25.
Исправил, но нечего не меняется.
4.25 много, снижайте, стабильное напряжение надо
на данном напряжении модем начал греться
Тоже долгодмусился sim800, сделал так и теперь проблем нет,
Преобразователь dc/dc360, вместо потенциометра, резак на 27к. Как раз 4.0В
Я использую HW-411.
Нашел Б.П. 5В, попробую с него подать питание. Отпишу когда подам
Тоже долгодмусился sim800, сделал так и теперь проблем нет,
Преобразователь dc/dc360, вместо потенциометра, резак на 27к. Как раз 4.0В
Эксперимент приостанавливается, поехал за новой ардуиной, что то померла эта(
ужас, а из-за чего?
:=(
ужас, а из-за чего?
:=(
Ничего не делал, выключил потом включил, чип горячий, нечего не шьет. Если питание только по USB то горит on и L. Если питание 5В то только L
Теперь ты знаешь, что такое тиристорный эффект.
Теперь ты знаешь, что такое тиристорный эффект.
Всмысле?)
В самом прямом смысле: http://www.chipinfo.ru/literature/compeljournal/2005/200502/p8.html
В самом прямом смысле: http://www.chipinfo.ru/literature/compeljournal/2005/200502/p8.html
Ну то что плату в мусор то понятно)
Судя по статье, первое это подаем 5V, потом USB. 5V не отключал, только USB)
Спасибо этой теме и людям в ней!
Все что мне было надо - у меня заработало.
На основе ваших скетчев я сделал GSM реле в 3 канала...
С памятью последних положений ну и со всем остальным что тут есть.
Спасибо этой теме и людям в ней!
Все что мне было надо - у меня заработало.
На основе ваших скетчев я сделал GSM реле в 3 канала...
С памятью последних положений ну и со всем остальным что тут есть.
пожалуйста :)
Новая железка на руках, взял тоже Arduino nano v3. У Вас она питается как и модем, от 4.2В?
Новая железка на руках, взял тоже Arduino nano v3. У Вас она питается как и модем, от 4.2В?
не, ардуина питается от usb, а для питания модема нужно 4.2В (отдельное питание). вот для вас схема:
я вместо отдельного источника питания использую второй USB
Подключил по схеме, команды отрабатывает на ура. Но все равно не работает.
Если всеже вернуться к A6, какое на него питание нужно подавать, он ведь нормально отрабатывает команды.
Вот так сеть отрабатывает отлично
#include <SoftwareSerial.h> SoftwareSerial SIM800(8, 9); // 8 - RX Arduino (TX SIM800L), 9 - TX Arduino (RX SIM800L) void setup() { Serial.begin(9600); // Скорость обмена данными с компьютером Serial.println("Start!"); SIM800.begin(9600); // Скорость обмена данными с модемом SIM800.println("AT"); } long lastcmd = millis(); void loop() { if (SIM800.available()) // Ожидаем прихода данных (ответа) от модема... Serial.write(SIM800.read()); // ...и выводим их в Serial if (Serial.available()) // Ожидаем команды по Serial... SIM800.write(Serial.read()); // ...и отправляем полученную команду модему if (millis() - lastcmd > 5000) { // Прошло ли 5 секунд lastcmd = millis(); // Фиксируем время SIM800.println("AT+CSQ"); // Запрашиваем информацию о качестве сигнала } }A6 питание 5V. читайте pdf на модем
A6 питание 5V. читайте pdf на модем
И на А6 так же тишина(
Благодаря martinhol с drive2, на данный момент бьюсь над GPRS версией:
#include <EEPROM.h> #include <RCSwitch.h> #include <SoftwareSerial.h> #include <DallasTemperature.h> // подключаем библиотеку чтения датчиков температуры SoftwareSerial SIM800(7, 6); // для новых плат начиная с версии RX,TX OneWire oneWire(4); // и настраиваем пин 4 как шину подключения датчиков DS18B20 DallasTemperature sensors(&oneWire); RCSwitch mySwitch = RCSwitch(); // беспроводной датчик двери, пин 2. #define LED 13 // на светодиод (моргалку) #define BAT 15 // на батарею, через делитель напряжения 39кОм / 11 кОм /* ------------------------------------- ДАТЧИКИ ------------------------*/ #define DOOR 8 // концевик двери. если сработал, на входе "+" HIGH. #define PIR 9 // датчик движения. если сработал, на входе "+" HIGH. #define BUZ 10 // сирена. если "-" LOW, то горит. #define GAS 14 // датчик дыма. если сработал, на входе "+" HIGH. #define sarai 3258553 // адрес 433 передатчика геркона двери. если сработал, на пин 2 сигнал. boolean DOORFlag = false; // флаг состояние датчика двери. boolean SARAYFlag = false; // флаг состояние датчика двери 2. boolean PIRFlag = false; // флаг состояние датчика движения. boolean GASFlag = false; // флаг состояние датчика газа. int8_t LEDState = LOW; // Состояние светодиода. int8_t DOORState = LOW; // Состояние концевика двери. int8_t PIRState = LOW; // Состояние датчика движения. int8_t Smoky = LOW; // Состояние датчика газа. #define on "on" // вкл #define off "off" // выкл unsigned int p = 0; #define GASThres 400 // предельная концентрация газа #define time_sarai 10 // секунд не смотрим на датчик двери 2. unsigned long lasttime_sarai = 0; #define interval_led 1000 // для мигания LED, 1 сек. unsigned long previousMillis_led = 0; /* ----------------------------------------- НАСТРОЙКИ MQTT брокера--------------------------------------------------------- */ const char *MQTT_user = "****"; // api.cloudmqtt.com > Details > User const char *MQTT_pass = "*****"; // api.cloudmqtt.com > Details > Password const char *MQTT_type = "****"; // тип протокола const char *MQTT_CID = "Home Alarm"; // уникальное имя устройства в сети MQTT const char *MQTT_SERVER = "******"; // api.cloudmqtt.com > Details > Server сервер MQTT брокера const char *PORT = "******4"; // api.cloudmqtt.com > Details > Port порт MQTT брокера /* ----------------------------------------- ИНДИВИДУАЛЬНЫЕ НАСТРОЙКИ !!!--------------------------------------------------------- */ const char *APN = "internet.tele2.ru"; // тчка доступа выхода в интернет вашего сотового оператора //String USER = ""; // имя выхода в интернет вашего сотового оператора //String PASS = ""; // пароль доступа выхода в интернет вашего сотового оператора /* ----------------------------------------- ДАЛЕЕ НЕ ТРОГАЕМ --------------------------------------------------------------- */ bool broker = false; // статус подклюлючения к брокеру bool Firststart = true; // первый старт. bool Guard = false; // состояние охраны после подачи питания bool Buzer = false; // состояние охраны после подачи питания bool Ring = false; // состояние охраны после подачи питания bool Sms = false; // состояние охраны после подачи питания bool Door = false; // состояние охраны после подачи питания bool Saray = false; // состояние охраны после подачи питания bool Pir = false; // состояние охраны после подачи питания bool Gas = false; // состояние охраны после подачи питания int interval = 3; // интервал отправки данных на сервер после загрузки ардуино int Timer = 10; // Секунд до отключения "тревожного" пина. unsigned long lasttimer = 0; int inDS = 0; float m = 68.01; // делитель для перевода АЦП в вольты для резистров 39/11kOm float TempDS[11]; // массив хранения температуры c рахных датчиков float Vbat, V_min; // переменная хранящая напряжение бортовой сети unsigned long Time1, Time2 = 0; char CSQ[4]; // для хранения уровня сигнала. char MONEY[5]; // хранение баланса. char Phone[14]; // для временного хранения номера телефона, номер до 14 цифр. String RingPhone = ""; // номер звонившего. String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс. byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ. char Bal[4]; // для хранения номера баланса. void setup() { Serial.begin(9600); //скорость порта SIM800.begin(9600); //скорость связи с модемом SIM800_reset(); pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +. pinMode(PIR, INPUT); digitalWrite(PIR, HIGH); // mySwitch.enableReceive(0); // RF433 приемник на 2 пине pinMode(GAS, INPUT); pinMode(BUZ, OUTPUT); digitalWrite(BUZ, LOW); // сирена выкл. pinMode(LED, OUTPUT); // указываем пин на выход (светодиод) Serial.println(F("MQTT alarm\n")); Serial.println(eepromphone()); Serial.println(""); eepromconfig(); Serial.println(eepromtext()); Serial.println(""); } void loop() { AlarmPinOff(); if (SIM800.available()) resp_modem(); // если что-то пришло от SIM800 в Ардуино отправляем для разбора if (Serial.available()) resp_serial(); // если что-то пришло от Ардуино отправляем в SIM800 if (millis()> Time1 + 10000) Time1 = millis(), detection(); // выполняем функцию detection () каждые 10 сек if (millis()> Time2 + 3600000) { // каждый час Time2 = millis(); Signal(); SIM800.println("AT+CIPSEND"), delay (200); MQTT_PUB ("home/signal", CSQ); MQTT_PUB ("home/balance", MONEY); SIM800.write(0x1A); } } void resp_serial() { // ---------------- ТРАНСЛИРУЕМ КОМАНДЫ из ПОРТА В МОДЕМ ---------------------------------- String at = ""; int k = 0; while (Serial.available()) { k = Serial.read(); at += char(k); delay(1); } Komand(at); // запускаем подпрограмму распознавания команд } float VoltRead() { // замеряем напряжение на батарее и переводим значения в вольты float ADCC = analogRead(BAT); ADCC = ADCC / m ; Serial.println(String(F("Напряжение: ")) + ADCC + "V"); if (ADCC < V_min) V_min = ADCC; return(ADCC); // переводим попугаи в вольты } void detection() { // условия проверяемые каждые 10 сек Detect(); Vbat = VoltRead(); // замеряем напряжение на батарее Serial.println(String(F("Интервал: ")) + interval); inDS = 0; sensors.requestTemperatures(); // читаем температуру с трех датчиков while (inDS < 10) { TempDS[inDS] = sensors.getTempCByIndex(inDS); // читаем температуру if (TempDS[inDS] == -127.00) { TempDS[inDS]= 80; break; // пока не доберемся до неподключенного датчика } inDS++; } for (int i=0; i < inDS; i++) { Serial.println(String(F("Temp")) + i + "= " + TempDS[i]); } Serial.println(""); interval--; if (interval < 1) { interval = 6; if (broker == true) { eepromconfig(); eepromtext(); SIM800.println("AT+CIPSEND"), delay (200); /////////////------состояние датчиков----------///////////// MQTT_FloatPub ("home/ds0", TempDS[0],2); MQTT_FloatPub ("home/ds1", TempDS[1],2); MQTT_FloatPub ("home/vbat", Vbat,2); /////////////------состояние системы----------///////////// MQTT_PUB ("home/guard", Guard ? "lock" : "unlock"); MQTT_PUB ("home/buzer", Buzer ? "buzeron" : "buzeroff"); MQTT_PUB ("home/ring", Ring ? "ringon" : "ringoff"); MQTT_PUB ("home/sms", Sms ? "smson" : "smsoff"); MQTT_PUB ("home/door", Door ? "dooron" : "dooroff"); MQTT_PUB ("home/saray", Saray ? "sarayon" : "sarayoff"); MQTT_PUB ("home/pir", Pir ? "piron" : "piroff"); MQTT_PUB ("home/gas", Gas ? "gason" : "gasoff"); MQTT_FloatPub ("home/timer", Timer, 0); MQTT_FloatPub ("home/uptime", millis()/3600000,0); SIM800.write(0x1A); } else SIM800.println(F("AT+SAPBR=3,1,\"Contype\",\"GPRS\"")); // подключаемся к GPRS } } void MQTT_FloatPub(const char topic[15], float val, int x) {char st[10]; dtostrf(val,0, x, st), MQTT_PUB (topic, st);} void MQTT_PUB(const char MQTT_topic[15], const char MQTT_messege[15]) { // пакет на публикацию SIM800.write(0x30), SIM800.write(strlen(MQTT_topic)+strlen(MQTT_messege)+2); SIM800.write((byte)0), SIM800.write(strlen(MQTT_topic)), SIM800.write(MQTT_topic); // топик SIM800.write(MQTT_messege); // сообщение } void MQTT_SUB(const char MQTT_topic[15]) { // пакет подписки на топик SIM800.write(0x82), SIM800.write(strlen(MQTT_topic)+5); // сумма пакета SIM800.write((byte)0), SIM800.write(0x01), SIM800.write((byte)0); // просто так нужно SIM800.write(strlen(MQTT_topic)), SIM800.write(MQTT_topic); // топик SIM800.write((byte)0); } void MQTT_SEND(const char MQTT_topic[15], const char MQTT_messege[15]) { SIM800.println("AT+CIPSEND"), delay (200); SIM800.write(0x30), SIM800.write(strlen(MQTT_topic)+strlen(MQTT_messege)+2); SIM800.write((byte)0), SIM800.write(strlen(MQTT_topic)), SIM800.write(MQTT_topic); // топик SIM800.write(MQTT_messege); // сообщение SIM800.write(0x1A); } void resp_modem() { //------------------ АНЛИЗИРУЕМ БУФЕР ВИРТУАЛЬНОГО ПОРТА МОДЕМА------------------------------ String at = ""; int k = 0; while (SIM800.available()) { k = SIM800.read(); at += char(k); delay(1); } Serial.println(at); if (at.indexOf(F("SMS Ready")) > -1 || at.indexOf(F("NO CARRIER")) > -1 ) { SIM800.println(F("AT+IPR=9600;E1+DDET=1;+CMGF=1;+CSCS=\"gsm\";+CNMI=2,2,0,0,0;+VTD=1;+CMEE=1;&W")); // Активируем АОН и декодер DTMF Signal(); /* -------------------------------------- проверяем соеденеиние с ИНТЕРНЕТ, конектимся к серверу------------------------------------------------------- */ } else if (at.indexOf(F("+CME ERROR:")) > -1 ) { broker = false, delay (50), SIM800.println("AT+CFUN=1,1"), interval = 6 ; } else if (at.indexOf(F("AT+SAPBR=3,1,\"Contype\",\"GPRS\"\r\r\nOK")) > -1 ) { SIM800.println(String(("AT+SAPBR=3,1,\"APN\",\"")) + APN + "\""); } else if (at.indexOf(String(("AT+SAPBR=3,1,\"APN\",\"")) + APN + "\"\r\r\nOK") > -1 ) { SIM800.println(F("AT+SAPBR=1,1")), delay (1000); // устанавливаем соеденение } else if (at.indexOf(F("AT+SAPBR=1,1\r\r\nOK")) > -1 ) { SIM800.println(F("AT+SAPBR=2,1")),delay (1000); // проверяем статус соединения } else if (at.indexOf(F("+SAPBR: 1,1")) > -1 ) { SIM800.println(String(("AT+CIPSTART=\"TCP\",\"")) + MQTT_SERVER + "\",\"" + PORT + "\""); /* -------------------------------------- команды управления ------------------------------------------*/ } else if (at.indexOf(F("home/comandlock"),4) > -1 ) guard(1), MQTT_SEND ("home/send", "lock"); else if (at.indexOf(F("home/comandunlock"),4) > -1 ) guard(0), MQTT_SEND ("home/send", "unlock"); else if (at.indexOf(F("home/comandbuzeron"),4) > -1 ) buzer(1), MQTT_SEND ("home/send", "buzeron"); else if (at.indexOf(F("home/comandbuzeroff"),4) > -1 ) buzer(0), MQTT_SEND ("home/send", "buzeroff"); else if (at.indexOf(F("home/comandringon"),4) > -1 ) ring(1), MQTT_SEND ("home/send", "ringon"); else if (at.indexOf(F("home/comandringoff"),4) > -1 ) ring(0), MQTT_SEND ("home/send", "ringoff"); else if (at.indexOf(F("home/comandsmson"),4) > -1 ) sms(1), MQTT_SEND ("home/send", "smson"); else if (at.indexOf(F("home/comandsmsoff"),4) > -1 ) sms(0), MQTT_SEND ("home/send", "smsoff"); else if (at.indexOf(F("home/comanddooron"),4) > -1 ) door(1), MQTT_SEND ("home/send", "dooron"); else if (at.indexOf(F("home/comanddooroff"),4) > -1 ) door(0), MQTT_SEND ("home/send", "dooroff"); else if (at.indexOf(F("home/comandpiron"),4) > -1 ) pir(1), MQTT_SEND ("home/send", "piron"); else if (at.indexOf(F("home/comandpiroff"),4) > -1 ) pir(0), MQTT_SEND ("home/send", "piroff"); else if (at.indexOf(F("home/comandgason"),4) > -1 ) gas(1), MQTT_SEND ("home/send", "gason"); else if (at.indexOf(F("home/comandgasoff"),4) > -1 ) gas(0), MQTT_SEND ("home/send", "gasoff"); else if (at.indexOf(F("home/comandsarayon"),4) > -1 ) saray(1), MQTT_SEND ("home/send", "sarayon"); else if (at.indexOf(F("home/comandsarayoff"),4) > -1 ) saray(0), MQTT_SEND ("home/send", "sarayoff"); else if (at.indexOf(F("home/settimer"),4) > -1 ) { Timer = at.substring(at.indexOf("") + 17, at.indexOf("") + 20).toInt(); EEPROM.put(10, Timer); } else if (at.indexOf(F("home/comandrefresh"),4) > -1 ) { //Serial.println(F("Команда обновления")); Serial.println(eepromphone()); Serial.println(""); eepromconfig(); eepromtext(); Serial.println(""); SIM800.println("AT+CIPSEND"), delay (200); /////////////------состояние датчиков----------///////////// MQTT_FloatPub ("home/ds0", TempDS[0],2); MQTT_FloatPub ("home/ds1", TempDS[1],2); MQTT_FloatPub ("home/vbat", Vbat,2); MQTT_PUB ("home/door", DOORFlag ? "dooropen" : "doorclose"); MQTT_PUB ("home/pir", PIRFlag ? "piropen" : "pirclose"); MQTT_PUB ("home/saray", SARAYFlag ? "sarayopen" : "sarayclose"); MQTT_PUB ("home/gas", GASFlag ? "gasopen" : "gasclose"); /////////////------состояние системы----------///////////// MQTT_PUB ("home/guard", Guard ? "lock" : "unlock"); MQTT_PUB ("home/buzer", Buzer ? "buzeron" : "buzeroff"); MQTT_PUB ("home/ring", Ring ? "ringon" : "ringoff"); MQTT_PUB ("home/sms", Sms ? "smson" : "smsoff"); MQTT_PUB ("home/door", Door ? "dooron" : "dooroff"); MQTT_PUB ("home/saray", Saray ? "sarayon" : "sarayoff"); MQTT_PUB ("home/pir", Pir ? "piron" : "piroff"); MQTT_PUB ("home/gas", Gas ? "gason" : "gasoff"); MQTT_PUB ("home/signal", CSQ); MQTT_PUB ("home/balance", MONEY); MQTT_FloatPub ("home/timer", Timer, 0); MQTT_FloatPub ("home/uptime", millis()/3600000,0); SIM800.write(0x1A); interval = 6; // швырнуть данные на сервер и ждать 60 сек } else if (at.indexOf(F("CONNECT OK\r\n")) > -1 ) MQTT_CONNECT (); // после соединения с сервером отправляем пакет авторизации, публикации и пдписки у брокера else if (at.indexOf(F("+CLIP: ")) > -1) { // если обнаружен вызов. SIM800.println(F("ATH")); // снимаем трубку for (int i = 0; i < 5; i++) { // проверяем сохраненные номера if (at.indexOf(AlarmPhone[i]) > -1 && AlarmPhone[i] != 0) { // если он наш RingPhone = AlarmPhone[i]; // запоминаем номер звонящего RingPhone.toCharArray(Phone, 14); EEPROM.put(100, Phone); // записываем RingPhone в память. } else if (Firststart) { // если первый старт int ind = at.indexOf(F("+CLIP: \"")); // обрезаем номер ... ind += 8; String ring = at.substring(ind, at.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 (at.indexOf(F("+CSQ:")) > -1) { // если пришел уровень сигнала at = at.substring(at.indexOf(":") + 2, at.indexOf(",")); // парсим ответ об уровне сигнала at.trim(); // удаляем пробелы вначале и в конце строки at.toCharArray(CSQ, 4); Balance(); } else if (at.indexOf(F("+CUSD:")) > -1) { // если пришел баланс int p1 = at.indexOf("\""); // начало строки int p2 = at.lastIndexOf("\""); // конец строки at = at.substring(p1 + 1, p2); // обрезаем строку String money = getBalFromString(at); // обрезаем числовые money.toCharArray(MONEY, 10); // конвертируем SIM800.println(F("AT+CUSD=0")); } } void MQTT_CONNECT() { SIM800.println("AT+CIPSEND"), delay (100); SIM800.write(0x10); // маркер пакета на установку соединения SIM800.write(strlen(MQTT_type)+strlen(MQTT_CID)+strlen(MQTT_user)+strlen(MQTT_pass)+12); SIM800.write((byte)0),SIM800.write(strlen(MQTT_type)),SIM800.write(MQTT_type); // тип протокола SIM800.write(0x03), SIM800.write(0xC2),SIM800.write((byte)0),SIM800.write(0x3C); // просто так нужно SIM800.write((byte)0), SIM800.write(strlen(MQTT_CID)), SIM800.write(MQTT_CID); // MQTT идентификатор устройства SIM800.write((byte)0), SIM800.write(strlen(MQTT_user)), SIM800.write(MQTT_user); // MQTT логин SIM800.write((byte)0), SIM800.write(strlen(MQTT_pass)), SIM800.write(MQTT_pass); // MQTT пароль MQTT_PUB ("home/status", "Подключено"); // пакет публикации MQTT_SUB ("home/comand"); // пакет подписки на присылаемые команды MQTT_SUB ("home/settimer"); // пакет подписки на присылаемые команды MQTT_PUB ("home/signal", CSQ); MQTT_PUB ("home/balance", MONEY); MQTT_FloatPub ("home/timer", Timer, 0); SIM800.write(0x1A), broker = true; // маркер завершения пакета } void Signal() { SIM800.println(F("AT+CSQ")); // проверяем уровень сигнала сети } void Balance() { SIM800.println(String(F("AT+CUSD=1,\"#")) + Bal + ("#\",15")); // проверяем баланс на симкарте } void guard (bool st) { Guard = st; EEPROM.write(1, st); // пишем в EEPROM } void buzer(bool st) { Buzer = st; EEPROM.write(2, st); // пишем в EEPROM } void ring(bool st) { Ring = st; EEPROM.write(3, st); // пишем в EEPROM } void sms(bool st) { Sms = st; EEPROM.write(4, st); // пишем в EEPROM } void door(bool st) { Door = st; EEPROM.write(5, st); // пишем в EEPROM } void saray(bool st) { Saray = st; EEPROM.write(6, st); // пишем в EEPROM } void pir(bool st) { Pir = st; EEPROM.write(7, st); // пишем в EEPROM } void gas(bool st) { Gas = st; EEPROM.write(8, st); // пишем в EEPROM } String getBalFromString(String str) { // Функция извлечения цифр из сообщения - для парсинга баланса из USSD-запроса bool flag = false; String result = ""; str.replace(",", "."); // Если в качестве разделителя десятичных используется запятая - меняем её на точку. for (int i = 0; i < str.length(); i++) { if (isDigit(str[i]) || (str[i] == (char)46 && flag)) { // Если начинается группа цифр (при этом, на точку без цифр не обращаем внимания), if (result == "" && i > 0 && (String)str[i - 1] == "-") { // Нельзя забывать, что баланс может быть отрицательным result += "-"; // Добавляем знак в начале } result += str[i]; // начинаем собирать их вместе if (!flag) flag = true; // Выставляем флаг, который указывает на то, что сборка числа началась. } else { // Если цифры закончились и флаг говорит о том, что сборка уже была, if (str[i] != (char)32) { // Если порядок числа отделен пробелом - игнорируем его, иначе... if (flag) break; // ...считаем, что все. } } } return result; // Возвращаем полученное число. } void SIM800_reset() { // перезагрузка модема SIM800.println("AT+CFUN=1,1"); } void eepromconfig() { /// === конфигурирование сигнализации === /// if (EEPROM.read(0) != 1) { // если по 0 адресу записана не 1, переписываем в память 000 for (int i = 0 ; i < 512 ; i++) { // переписываем все ячейки EEPROM.write(i, 0); } // и записываем: EEPROM.update(0, 1); // пишем 1 в 0 адрес EEPROM.update(1, 0); // Guard охрана выкл. EEPROM.update(2, 0); // Sirena сирена при сработке вкл. EEPROM.update(3, 0); // RING вызов при сработке вкл. EEPROM.update(4, 0); // SMS смс при сработке вкл. EEPROM.update(5, 0); // DOOR датчики дверей вкл. EEPROM.update(6, 0); // SARAI датчики дверей вкл. EEPROM.update(7, 0); // PIR датчик движения вкл. EEPROM.update(8, 0); // GAS датчик газа вкл. EEPROM.update(9, 1); // Firststart первый старт! Serial.println(F("EEPROM != 1/ RESET!")); } if (EEPROM.read(0) == 1) { // если в 0 записана 1, считываем конфигурацию Guard = EEPROM.read(1); // Охрана Buzer = EEPROM.read(2); // Сирена Ring = EEPROM.read(3); // Вызов Sms = EEPROM.read(4); // Отправка смс Door = EEPROM.read(5); // Датчик двери Saray = EEPROM.read(6); // Датчик двери Pir = EEPROM.read(7); // Датчик движения Gas = EEPROM.read(8); // Датчик газа/дыма Firststart = EEPROM.read(9); // Первый старт EEPROM.get(10, Timer); } } String eepromtext() { /// === состояние системы === /// String SIGN = ""; // текущее состояние системы. String sirena = ""; // сирена при сработке. String ring = ""; // вызов при сработке. String sms = ""; // смс при сработке. String door = ""; // датчика двери. String saray = ""; // датчика двери RF433. String pir = ""; // датчик движения. String gas = ""; // датчик газа. if (Guard) SIGN = F("System on\n"); else SIGN = F("System off\n"); if (Buzer) sirena = F("Sirena on\n"); else sirena = F("Sirena off\n"); if (Ring) ring = F("Ring on\n"); else ring = F("Ring off\n"); if (Sms) sms = F("SMS on\n"); else sms = F("SMS off\n"); if (Door) door = F("Door on\n"); else door = F("Door off\n"); if (Saray) saray = F("Sarai on\n"); else saray = F("Sarai off\n"); if (Pir) pir = F("Pir on\n"); else pir = F("Pir off\n"); if (Gas) gas = F("Gas on\n"); else gas = F("Gas off"); String LastEvent = SIGN + sirena + ring + sms + door + saray + 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 sms(String text, byte sendnum) { /// === отправка СМС === /// String phone = ""; text += String(F("\nTemp_ul ")) + TempDS[0]; // добавляем к тексту температуру на улице text += String(F("*C\nTemp_pom ")) + TempDS[1]; // добавляем к тексту температуру на в помещении text += String(F("*C\n")) + MONEY; // добавляем к тексту баланс sim карты if (!sendnum) { // отправка смс на номер звонившего phone = RingPhone; SIM800.println(String(F("AT+CMGS=\"+")) + phone + "\""); // Переходим в режим ввода текстового сообщения SIM800.println(text + (String)((char)26)); // отправка текста } else if (sendnum) { // отправка смс на все номера for (uint8_t i = 0; i < 4 ; i++) { phone = AlarmPhone[i]; if (phone != 0) { // если ячейка пустая - не отправлять смс SIM800.println(String(F("AT+CMGS=\"+")) + phone + "\""); // Переходим в режим ввода текстового сообщения SIM800.println(text + (String)((char)26)); // отправка текста } } } } void Komand(String kom) { /// === мастер смс === /// Serial.println("Kom->" + kom); kom.toLowerCase(); // if (RingPhone == AlarmPhone[0]) { // команды выполняются только с 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); SIM800_reset(); // перезапускаем модем } } 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) { // включить все датчики одной командой Door = true; // вкл датчик двери Saray = true; // вкл датчик двери RF433 Pir = true; // вкл датчик движения Gas = true; // вкл датчик газа EEPROM.update(4, Door); // пишем в EEPROM EEPROM.update(5, Saray); // пишем в EEPROM EEPROM.update(6, Pir); // пишем в EEPROM EEPROM.update(7, Gas); // пишем в EEPROM } else if (kom.indexOf(off) > -1) { // выключить все датчики Door = false; // выкл датчик двери Saray = false; // выкл датчик двери RF433 Pir = false; // выкл датчик движения Gas =false; // выкл датчик газа EEPROM.update(4, Door); // пишем в EEPROM EEPROM.update(5, Saray); // пишем в EEPROM EEPROM.update(6, Pir); // пишем в EEPROM EEPROM.update(7, Gas); // пишем в 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) { // вкл сирену при сработке Buzer = true; EEPROM.update(8, Buzer); // пишем в EEPROM sms(String(F("Sirena->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл сирену при сработке Buzer = false; EEPROM.update(8, Buzer); // пишем в EEPROM sms(String(F("Sirena->off")), 1); // смс на все номера } } else if (kom.indexOf(F("ring")) > -1) { // вкл/выкл вызов при сработке if (kom.indexOf(on) > -1) { // вкл вызов при сработке Ring = true; EEPROM.update(2, Ring); // пишем в EEPROM sms(String(F("Ring->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл вызов при сработке Ring = false; EEPROM.update(2, Ring); // пишем в EEPROM sms(String(F("Ring->off")), 1); // смс на все номера } } else if (kom.indexOf(F("sms")) > -1) { // вкл/выкл смс при сработке if (kom.indexOf(on) > -1) { // вкл смс при сработке Sms = true; EEPROM.update(3, Sms); // пишем в EEPROM sms(String(F("SMS->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл смс при сработке Sms = false; EEPROM.update(3, Sms); // пишем в EEPROM sms(String(F("SMS->off")), 1); // смс на все номера } } else if (kom.indexOf(F("door")) > -1) { // вкл/выкл контроль датчика двери if (kom.indexOf(on) > -1) { // вкл контроль датчика двери Door = true; EEPROM.update(4, Door); // пишем в EEPROM sms(String(F("DOOR->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл контроль датчика двери Door = false; EEPROM.update(4, Door); // пишем в EEPROM sms(String(F("DOOR->off")), 1); // смс на все номера } } else if (kom.indexOf(F("sarai")) > -1) { // вкл/выкл контроль датчика двери RF433 if (kom.indexOf(on) > -1) { // вкл контроль RF433 Saray = true; EEPROM.update(5, Saray); // пишем в EEPROM sms(String(F("SARAI->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл контроль RF433 Saray = false; EEPROM.update(5, Saray); // пишем в EEPROM sms(String(F("SARAI->off")), 1); // смс на все номера } } else if (kom.indexOf(F("pir")) > -1) { // вкл/выкл контроль датчика движения if (kom.indexOf(on) > -1) { // вкл контроль датчика движения Pir = true; EEPROM.update(6, Pir); // пишем в EEPROM sms(String(F("PIR->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл контроль датчика движения Pir = false; EEPROM.update(6, Pir); // пишем в EEPROM sms(String(F("PIR->off")), 1); // смс на все номера } } else if (kom.indexOf(F("gas")) > -1) { // вкл/выкл контроль датчика газа if (kom.indexOf(on) > -1) { // вкл контроль датчика газа Gas = true; EEPROM.update(7, Gas); // пишем в EEPROM sms(String(F("GAS->on")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл контроль датчика газа Gas = false; EEPROM.update(7, Gas); // пишем в EEPROM sms(String(F("GAS->off")), 1); // смс на все номера } } SIM800.println(F("AT+CMGD=1,4")); // стираем смс } void GuardOn() { /// === включение сигнализации === /// Guard = true; EEPROM.update(1, Guard); sms(F("System->on"), 1); // смс на все номера } void GuardOff() { /// === выключение сигнализации === /// Guard = false; EEPROM.update(1, Guard); sms(F("System->off"), 1); // смс на все номера } 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 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 Detect() { /// === чтение датчиков === /// DOORState = digitalRead(DOOR); PIRState = digitalRead(PIR); Smoky = analogRead(GAS); if (DOORState == HIGH && !DOORFlag) { // если он сработал DOORFlag = true; // ставим флаг Serial.println(F("Dver' otkrita!")); MQTT_SEND ("home/door", "dooropen"); if (Door) Alarm(); // запускаем подпрограмму Alarm } else if (DOORState == LOW && DOORFlag) { DOORFlag = false; // возвращаем флаг к начальному состоянию Serial.println(F("Dver' zakrita!")); MQTT_SEND ("home/door", "doorclose"); } if (mySwitch.available()) { // если датчик сарая включен unsigned long value = mySwitch.getReceivedValue(); // считываем значение с RF433 if (value == sarai && !SARAYFlag) { // если он сработал lasttime_sarai = millis(); // запускаем таймер SARAYFlag = true; // ставим флаг Serial.println(F("Sarai otkrit!")); // MQTT_SEND ("home/saray", "sarayopen"); if (Saray) Alarm(); // запускаем подпрограмму Alarm } mySwitch.resetAvailable(); } if (((millis() - lasttime_sarai)/1000 > time_sarai)) { // если прошол интервал SARAYFlag = false; // возвращаем флаг к начальному состоянию // MQTT_SEND ("home/saray", "sarayclose"); } if (PIRState == HIGH && !PIRFlag) { // если он сработал PIRFlag = true; // ставим флаг Serial.println(F("Dvizhenie u dveri!")); MQTT_SEND ("home/pir", "piropen"); if (Pir) Alarm(); // запускаем подпрограмму Alarm } else if (PIRState == LOW && PIRFlag) { // иначе если движения нет PIRFlag = false; // возвращаем флаг к начальному состоянию MQTT_SEND ("home/pir", "pirclose"); } if ((Smoky > GASThres) && !GASFlag) { // если он сработал GASFlag = true; // ставим флаг Serial.println(F("Gas v dome!")); MQTT_SEND ("home/gas", "gasopen"); if (Gas) Alarm(); // запускаем подпрограмму Alarm } else if ((Smoky < GASThres) && GASFlag) { // иначе если газа нет GASFlag = false; // возвращаем флаг к начальному состоянию MQTT_SEND ("home/gas", "gasclose"); } } void Alarm() { /// === аварийные сигналы === /// if (Buzer) { // если включена сирена при сработке lasttimer = millis(); // запускаем таймер сирены digitalWrite(BUZ, HIGH); // запускаем ее } Serial.println(F("Alarm!!!")); if (DOORFlag) { // если сработал датчик двери } if (SARAYFlag) { // если сработал датчик двери RF433 } if (PIRFlag) { // если сработал датчик движения } if (GASFlag) { // если сработал датчик газа } } void AlarmPinOff() { /// === отключаем сирену === /// if ((millis() - lasttimer)/1000 > Timer) digitalWrite(BUZ, LOW); // если прошло время, отключаем сирену }смс пока не проверял, еще не все добавил, но работает. использую приложение MQTT dash, но оно не устраивает отсутствием уведомлений и виджета.
подскажите есть ли какое приложение. чтоб можно было добавить виджет и уведомления по изменения статуса устройств, т.к. смс уже не устраивает?
pasha413 Что должно быть в строке : MQTT_type ?
A6 mini подойдет для проэкта?
AleksandrM, про MQTT_type позже напишу.
А6 не подойдёт, хотя если можете переписать под под него, то не проблема (у меня завести gprs на А6 была проблема)
Паша. я на А6 в инет выходил без проблем, Яндекс скачивался. Дальше правда не копал, проект с А6 пока заброшен, отодвинут более актуальными задачками :)
У меня 2 А6, один трудится на даче - сигналка, второй лежит в запасе.
И 2 сим800 (один не поддерживает gprs - выйду с отпуска буду прошивать)
сим800Н у вас? и как вы его прошьете??
смс пока не проверял, еще не все добавил, но работает. использую приложение MQTT dash, но оно не устраивает отсутствием уведомлений и виджета.
подскажите есть ли какое приложение. чтоб можно было добавить виджет и уведомления по изменения статуса устройств, т.к. смс уже не устраивает?
блинк пробовали? у меня пока чтото не получилось тесты через него, хотя там много чего есть для обратной связи с устройством и прочего.
SIM800l. Где-то ссылку сохранял, завтра кину, все на работе, отпуск же)))
Что-то типа этого
https://elementztechblog.wordpress.com/2016/08/02/updating-firmware-of-s...
Не, завтра выйду с отпуска, начну вливаться))
вот этот модуль хотите перешить?? именно перешить а не файлы в него прописать??
а вы сначала поинтересуйтесь, те пины что вам нужны доступны на этом модуле на фото??
там специальные контакты под прошивку новой версии, и включаются они в юсб разьем!!
так что перешить насколько я понимаю вы этот модуль не сможете.
вот на сим800С там требуемые контакты по любому доступны будут.
Short Circuit, у меня 2 модема, один с версией 1308, другой 1418., Вот первый не пошел по gprs, а второй норм. Завтра скину ссылку что я нашел по прошивке (смене по модема)
еще раз - должны быть доступны специальные контакты на модуле.. иначе никак.
через порт рхтх не прошивается.
по поводу прошивки sim800 вот в этой теме писалось. с поста #9
http://arduino.ru/forum/apparatnye-voprosy/sim800l-ne-mozhet-zaregistrirovat-sim
pasha413 Что должно быть в строке : MQTT_type ?
A6 mini подойдет для проэкта?
MQIsdp
Вот столкнулся с такой проблемой....
Пол года все было нормально а за последнюю неделю 2 раза такая ситуация...
Модем зарегестрирован в сети, звонки на него идут но реакции 0.Модем А6 mini
Прога на ардуине крутиться, светодиод мигает , но при сработке- реакции ноль.
Скетч из этой темы, допиленый под себя.
Как с этой бедой справиться?
Может периодически спрашивать что-то у оператора и если нет ответа- сброс?
Вот столкнулся с такой проблемой....
Может периодически спрашивать что-то у оператора и если нет ответа- сброс?
Я периодически спрашиваю регистрацию в сети, если нет то перезагружаю модем
Можна кусочек кода для примера?
В loop() {
if (millis()/1000 > timer) { // проверяем каждый час
Signal(); // проверяем уровень сигнала
timer += 360;
} Пост 667 смотрите, не могу с телефона писать...до компа доберусь только в четверг))
Проверяем уровень сигнала и тем самым убиваем 2х зайцев (можно заменить на регистрацию в сети). В подпрограмме sendATcomand(): если не придет ответ на команду, дергаем ногу модема reset. Но это для А6го.
Для sim800 можно программно перезагружать: в 705 посте посмотрите)
если он в состоянии воспринимать команды и не завис
Можно также ногой, там есть RST
Можно также ногой, там есть RST
если он в состоянии воспринимать команды и не завис
по сравнению с сим300 800й как небо и земля..
виснет крайне редко.
НО!! производитель рекомендует снимать питание с модуля для перезагрузки зависшего модуля. Так что по питанию - это самый верный вариант.
хрен... проверять нужно каждые 3 минуты..
Здравствуйте.
Никто не пробовал запустить телеграмбота на arduino + SIM800?
Я вот нашел код
#define TINY_GSM_MODEM_SIM800 #include <TinyGsmClient.h> #include <ArduinoHttpClient.h> #include <UniversalTelegramBot.h> #include <SoftwareSerial.h> SoftwareSerial SerialAT(7, 6); // RX, TX //#define DUMP_AT_COMMANDS #define SerialMon Serial #ifdef DUMP_AT_COMMANDS #include <StreamDebugger.h> StreamDebugger debugger(SerialAT, SerialMon); TinyGsm modem(debugger); #else TinyGsm modem(SerialAT); #endif const char apn[] = "*****"; //apn const char user[] = ""; //username const char pass[] = ""; //pass // Initialize Telegram BOT #define BOTtoken "*******" // int Bot_mtbs = 1000; //mean time between scan messages long Bot_lasttime; //last time messages' scan has been done TinyGsmClientSecure client(modem); UniversalTelegramBot bot(BOTtoken, client); void setup() { Serial.begin(9600); SerialAT.begin(9600); delay(3000); modem.sendAT(GF("+HTTPS=1")); //enable ssl. maybe don't need modem.waitResponse(); if (!modem.hasSSL()) { Serial.println(F("SSL is not supported by this modem")); return; } Serial.print(F("Waiting for network...")); if (!modem.waitForNetwork()) { Serial.println(" fail"); // delay(10000); return; } Serial.println(" OK"); Serial.print(F("Connecting to ")); Serial.print(apn); if (!modem.gprsConnect(apn, user, pass)) { Serial.println(" fail"); // delay(10000); return; } else {Serial.println(" OK");} IPAddress local = modem.localIP(); modem.waitResponse(); Serial.println(local); } void loop() { String chat_id = F("*****"); String text = "HELLO!"; String parses = ""; Serial.println(F("Send message")); Serial.println(bot.sendMessage(chat_id, text, parses)); delay(60000); }, но долго мучил его (не отправлялось сообщение), нашел все-таки ошибку, оказалось в строке 35 необходимо изменить на
modem.sendAT(GF("+HTTPSSL=1")); //enable ssl. maybe don't needсообщение от бота приходит, а вот как получить сообщение ботом, никак не смог понять,
может у кого есть идеи?
вставлю свои 5 копеек.
Мучался на коленке собирать, сделал плату и заказал в китае.
Питание как видите, одна понижайка на 5в (ардуино, реле, часы) и вторая на 3.3в на GSM. с другой стороны преобразователь уровней с 3.3 на 5в. Кстате после всякого навесного монтажа работать стало стабильнее, всяких проблем с модемом не стало. Правда есть кое какие косяки по разводке но это выяснилось потом при монтаже уже.
А так это система полива и контроля состояния воды в баке, на этой же печатке сделали контроль отопительной системы в доме зимой.
Так что код универсален и подстраивается как надо
п.с. в коде #705 ошибка (у меня не захотел работать как надо)
заменить на ind+=9, а то получается не состыковка по номерам, записывается в памяти как +79123456789 а последний звонивший отображается 79123456789 т.е. без +, и ардуинка не понимает
smesharik, это, как выяснилось, с разными операторами необходимо менять (Теле2 и МТС номер возвращается с + и без). Насколько помню у сим800 питание от 3.6В-4.2В.
Ну вы меня поняли :) По мануалу 3,4-4,4в. Я где то 3.8 поставил
У меня МТС идет с +
Использовали код из #705 поста?
50/50, код создавался параллельно с темой, с 705 взята только работа с GSM модемом
Такая проблема нарисовалась: При добавлении мастер-номеров приходит сообщение /master1 add/.
Призвонке с добавленного номера 0 реакции как и на SMS. По команде PHONE показывает 1мастер и добавленный номер.
при звонке с добавленного номера в монитор порта пишет "No Master Ring!" Где я что напутал?
/* SMS команды управления Звонок на устройство ставит на охрану - снимает с охраны z1on Разрешение контроля Зоны 1 z1off Запрет контроля Зоны1 z2on Разрешение контроля Зоны 2 z2off Запрет контроля Зоны2 z3on Разрешение контроля Зоны 3 z3off Запрет контроля Зоны3 z4on Разрешение контроля Зоны 4 z4off Запрет контроля Зоны4 out1on Включение нагрузки 1 канала out1off Выключение нагрузки 1 канала out2on Включение нагрузки 2 канала out2off Выключение нагрузки 2 канала out3on Включение нагрузки 3 канала out3off Выключение нагрузки 3 канала out4on Включение нагрузки 4 канала out4off Выключение нагрузки 4 канала money Запрос баланса info Состояние системы reset Полный сброс системы. Первый позвонившый станет супермастером, Ввести номер баланса balance:101 Для ввода номера баланса smson Разрешение отправки sirena:60 при сработке smsoff Запрет отправки sirena:60 при сработке ringon Разрешение звонка при сработке ringoff Запрет звонка при сработке master1:+380********* добавить мастер номер sirenaon Разрешить сирену при сработке sirena0ff Запретить сирену при сработке phone Список мастер номеров dell:1 Удаление мастер номеров systemon Включить охрану systemoff Выключить охрану */ // max длинна сообщения в данный момент 135 символов. #include <EEPROM.h> #include <OneWire.h> #include <SoftwareSerial.h> #define Ver F("Alarm v4.3.4\n") OneWire ds(13); // датчик температуры подключен к 6 пину, подтяжка 4.7кОм на +. SoftwareSerial gsm(8, 9); // модем подключен к 7 и 8 пинам. //RCSwitch mySwitch = RCSwitch(); // беспроводной датчик двери, пин 2. //#define 0 //UART //#define 1 //UART #define DOOR 2 // пин 2. концевик двери. #define PIR 3 // пин 3. датчик движения. //#define PIN4 //#define PIN5 #define GAS 6 // пин 6. датчик дыма. #define SARAI 4 //#define PIN8 //UART_GSM //#define PIN9 //UART_GSM #define BUZ 7 // пин 10. сирена. #define LED 11 // пин 11. состояние системы. #define REG 12 // Выход регулятора температуры //#define PIN13//DS18B20 #define rst A0 #define OUT1 A1 #define OUT2 A2 #define OUT3 A3 #define OUT4 A4 #define POWER A5 // DOOR - если сработал, на входе "+" HIGH. // SARAI - если сработал, на пин 2 сигнал. // PIR - если сработал, на входе "+" HIGH. // GAS - если сработал, на входе "+" HIGH. // BUZ - если "-" LOW, то горит. // LED - если "-" LOW, то горит. #define on "on" // вкл #define off "off" // выкл int8_t ModemID = 3; // тип модема int8_t Guard = 0; // 1. охрана: 1 - вкл, 0 - выкл. int8_t AlarmRING = 1; // 2. вызов при сработке: 1 - вкл, 0 - выкл. int8_t SendSMS = 1; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл. int8_t DOORon = 1; // 4. контроль концевика двери: 1 - вкл, 0 - выкл. int8_t SARAIon = 1; // 4. контроль концевика двери 2: 1 - вкл, 0 - выкл. int8_t PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл. int8_t GASon = 1; // 6. контроль датчика дыма: 1 - вкл, 0 - выкл. int8_t Sirena = 1; // 7. сирена: 1 - вкл, 0 - выкл. int8_t Firststart = 1; // первый старт. int8_t POWERFlag =1; int8_t DOORFlag = 0; // флаг состояние датчика двери. int8_t SARAIFlag = 0; // флаг состояние датчика двери 2. int8_t PIRFlag = 0; // флаг состояние датчика движения. int8_t GASFlag = 0; // флаг состояние датчика газа. int8_t POWERState= LOW; int8_t SARAIState = LOW; int8_t DOORState = LOW; // Состояние концевика двери. int8_t PIRState = LOW; // Состояние датчика движения. int8_t LEDState = HIGH; // Состояние светодиода. int8_t Smoky = LOW; // Состояние датчика газа. int8_t sendsmscaller = 1; // разрешение отправки смс. uint32_t msAT = 0; int tr; char CSQ[4]; char Bal[4]; // для временного хранения номера баланса. char Phone[14]; // для временного хранения номера телефона, номер до 14 цифр. String AT[] = {"AT+CLIP=1", "AT+CMGF=1", "AT+CSCS=\"GSM\"", "AT+CNMI=2,2,0,0,0", "AT+CREG?"}; // общие АТ команды #define AT_M590 F("AT+CUSD=1") // баланс для М590 #define AT_SIM800_A6 F("AT+CUSD=1,#") // баланс для А6 и СИМ800 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_power 10 // секунд не смотрим на питание. int previousMillis_power = 0; #define interval_pir 20 // секунд не смотрим на датчик движения. int previousMillis_pir = 0; #define interval_gas 20 // секунд не смотрим на датчик газа. 10минут int previousMillis_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); pinMode(DOOR, INPUT_PULLUP); pinMode(SARAI, INPUT_PULLUP); // вход датчика двери с подтяжкой на +. pinMode(PIR, INPUT_PULLUP); pinMode(GAS, INPUT_PULLUP); pinMode(BUZ, OUTPUT); pinMode(OUT1, OUTPUT); pinMode(OUT2, OUTPUT); pinMode(OUT3, OUTPUT); pinMode(OUT4, OUTPUT); pinMode(REG, OUTPUT); pinMode(LED, OUTPUT); // светодиод горит во время запуска. digitalWrite(BUZ, LOW); // сирена выкл. digitalWrite(PIR, HIGH); // игнорируем при включении. digitalWrite(OUT1, LOW); digitalWrite(OUT2, LOW); digitalWrite(OUT3, LOW); digitalWrite(OUT4, LOW); digitalWrite(REG, LOW); pinMode(rst, OUTPUT); digitalWrite(rst, LOW); // // mySwitch.enableReceive(0); // 433 приемник на 2 пине InitModem(); // запускаем инициализация модема. eepromconfig(); Serial.println(eepromtext()); Serial.println(eepromphone()); digitalWrite(LED, HIGH); // гасим светодиод состояния сигнализации. } void loop() { /// === основной цикл программы === /// AlarmPinOff(); // выключаем сирену, если прошло время. if (millis()/1000 > timer) { // проверяем каждый час TempC(); Signal(); timer += 60; } if (Guard == 1) { // если на охране Detect(); // проверяем датчики. Led(); // моргаем светодиодом. regtemp(); } if (gsm.available()) { // Если модем, что-то отправил... String val = ""; // Переменная для хранения ответа модуля val = waitgsm(); // Получаем ответ от модема для анализа // Serial.println(val); // Если нужно выводим в монитор порта if (val.indexOf(F("+PBREADY")) > -1) InitModem(); else if (val.indexOf(F("+CLIP: ")) > -1) { // если обнаружен вызов. Serial.println(F("Process RING")); // delay(2000); // дадим гудок int ind = val.indexOf(F("+CLIP: \"")); // обрезаем номер // if (ind >= 0) { // Если информация была найдена ind += 8; // Парсим строку и val = val.substring(ind, val.indexOf("\"", ind)); // } Serial.println("ring: " + val); gsm.println(F("ATH")); // сбрасываем вызов. if (CheckPhone(val) == 1) { // проверяем номер, если наш. Serial.println(F("Master Ring OK!")); MasterRing(); // меняем состояние охраны } else Serial.println(F("No Master Ring!")); } else if (val.indexOf(F("+CMT")) > -1) { // если обнаруженa СМС Serial.println(F("Process CMT")); parsesms(val); } else if (val.indexOf(F("+CUSD:")) > -1) { // если пришел баланс String bal = ""; if (ModemID == 3) { // команда проверки баланса AT+CUSD=1,#105#,15 // анализируем строку int p1 = val.indexOf("\""); // начало строки int p2 = val.lastIndexOf("\""); // конец строки // val = val.substring(p1,p2); val = val.substring(p1 + 1, p2); Serial.println(F("Input string:")); // пишем в порт пришедшую строку Serial.println(val); Decode7bit(val, bal); Serial.println(F("Decode string:")); // пишем в порт конвертированную строку } else if (ModemID == 1 || 2) { bal = String(val.substring(val.indexOf(",\"") + 2, val.indexOf("\","))); // } bal = bal.substring(1, 27);//26 Serial.println(bal); sms(" SIM" "\n" " Na" + bal + "\n", 0); // смс на последний звонивший gsm.println(F("AT+CUSD=0")); } } else if (Serial.available()) { // если в мониторе порта что-то ввели String serialval = ""; while (Serial.available()) { // сохраняем входную строку в переменную val. char ch = Serial.read(); serialval += char(ch); // собираем принятые символы в строку delay(3); } sendsmscaller = 0; Komand(serialval); // запускаем консольную программу sendsmscaller = 1; } } String waitgsm() { // Функция ожидания ответа и возврата полученного результата String gsmval = ""; // Переменная для хранения результата uint32_t _timeout = millis() + 5000; // Переменная для отслеживания таймаута (10 секунд) while (!gsm.available() && (millis() < _timeout)) {}; // Ждем ответа5 секунд, если пришел ответ или наступил таймаут, то... if (gsm.available()) { // если GSM модем что-то послал. while (gsm.available()) { // сохраняем входную строку в переменную val. char ch = gsm.read(); gsmval += char(ch); // собираем принятые символы в строку delay(5); } } else { // Если пришел таймаут, то... Serial.println(F("Timeout...")); // ... оповещаем об этом и... } return gsmval; // ... возвращаем результат. Пусто, если проблема } void Signal() { /// === проверка уровня сигнала сети === /// String csq = sendATCommand(F("AT+CSQ")); csq = csq.substring(csq.indexOf(":") + 2, csq.indexOf(",")); // парсим ответ об уровне сигнала csq.trim(); // удаляем пробелы вначале и в конце строки csq.toCharArray(CSQ, 4); } void parsesms(String msg) { String msgheader = ""; String msgsms = ""; String msgphone = ""; msg = msg.substring(msg.indexOf("+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("+CMT:"); Index += 8; // Парсим строку и msgphone = msgheader.substring(Index, msgheader.indexOf("\"", Index)); Serial.println("Phone: " + msgphone); // Выводим номер телефона Serial.println("Message: " + msgsms); // Выводим текст SMS if (CheckPhone(msgphone) == 1) { // если СМС от хозяина Serial.println(F("Master SMS OK!")); Komand(msgsms); } else Serial.println(F("No Master SMS!")); } int CheckPhone(String phone) { /// === проверка телефона === /// if (Firststart == 0) { // если не первый старт for (int 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 в память. Serial.println(String(F("RingPhone ")) + RingPhone); return 1; // возвращаем 1 - номер наш! } } return 0; // возвращаем 0 - номер не наш! } else if (Firststart == 1) { // иначе (если первый старт) // первый звонивший добавляется как основной мастер номер для управления сигнализацией 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 + " Ok\n", 0); // смс на звонивший // приходит смс в виде: " Master0:79111234567 Ok " } return 1; } 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("Zona1 on\n"); else Door = F("Zona1 off\n"); if (SARAIon == 1) Sarai = F("Zona4 on\n"); else Sarai = F("Zona4 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\n"); String LastEvent = SIGN + RING + SMS + SIRENA + Door +Pir + Gas+ Sarai; // полное состояние системы и датчиков. 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 + "#\n"; String EEPhone = numbers + ring + bal; return EEPhone; } void Detect() { /// === чтение датчиков === /// DOORState = digitalRead(DOOR); PIRState = digitalRead(PIR); Smoky = digitalRead(GAS); SARAIState = digitalRead(SARAI); POWERState= digitalRead(POWER); 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 (POWERState == HIGH && POWERFlag == 0) { previousMillis_power = millis(); POWERFlag = 1; //Serial.println(F("POWER OFF!")); Serial.println(F("POWER LOW!!!")); sms(F("POWER LOW!!!!\n"), 1); // смс на все номера Alarm(); // } else if (POWERState == LOW && POWERFlag == 1) { int currentMillis_power = millis(); if (((currentMillis_power - previousMillis_power) / 1000 > interval_power)) { POWERFlag = 0; // Serial.println(F("POWER LOW!!!")); sms(F("POWER Normal\n"), 1); // смс на все номера } } //////////////////////////////////////////////////////////////////////////////////// if (PIRon == 1) { if (PIRState == LOW && PIRFlag == 0) { previousMillis_pir = millis(); PIRFlag = 1; Serial.println(F("PIR!")); Alarm(); // } else if (PIRState == HIGH && PIRFlag == 1) { int currentMillis_pir = millis(); if (((currentMillis_pir - previousMillis_pir) / 1000 > interval_pir)) { PIRFlag = 0; } } } ///////////////////////////////////////////////////////////////// if (GASon == 1) { if (Smoky == LOW && GASFlag == 0) { previousMillis_gas = millis(); GASFlag = 1; Serial.println(F("GAS!")); Alarm(); // } else if (Smoky == HIGH && GASFlag == 1) { int currentMillis_gas = millis(); if (((currentMillis_gas - previousMillis_gas) / 1000 > interval_gas)) { GASFlag = 0; } } } ////////////////////////////////////////////////////// if (SARAIon == 1) { if (SARAIState == HIGH && SARAIFlag == 0) { previousMillis_sarai = millis(); SARAIFlag = 1; Serial.println(F("SARAI!")); Alarm(); // } else if (SARAIon == LOW && SARAIFlag == 1) { int currentMillis_sarai = millis(); if (((currentMillis_sarai - previousMillis_sarai) / 1000 > interval_sarai)) { SARAIFlag = 0; } } } } void Alarm() { /// === запускаем сирену и отправку смс === /// previousMillis_alarm = millis(); if (Sirena == 1) digitalWrite(BUZ, HIGH); Serial.println(F("Alarm!!!")); if (SendSMS == 1) { if (DOORFlag == 1) { Serial.println(F("Dver' otkrita")); sms(F("Dver'Zona1 otkrita!\n"), 1); // смс на все номера } else if (SARAIFlag == 1) { Serial.println(F("Sarai")); sms(F("Dver'Zona4 otkrita!\n"), 1); // смс на все номера } else if (PIRFlag == 1) { Serial.println(F("PIR")); sms(F("POGAR !!!!!\n"), 1); // смс на все номера } else if (POWERFlag == 1) { Serial.println(F("POWER LOW!!!")); sms(F("POWER LOW!!!!\n"), 1); // смс на все номера } else if (GASFlag == 1) { Serial.println(F("GAS")); sms(F("GASSS!\n"), 1); // смс на все номера } } if (AlarmRING == 1) { gsm.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру } } void AlarmPinOff() { /// === если прошло время, отключаем сирену === /// int currentMillis_alarm = millis(); if (((currentMillis_alarm - previousMillis_alarm) / 1000 > interval_alarm) || Guard == 0) { digitalWrite(BUZ, LOW); } } void MasterRing() { /// === мастер звонков === // if (Guard == 1) GuardOff(); // меняем состояние else if (Guard == 0) GuardOn(); // меняем состояние } void GuardOff() { /// === выключение сигнализации === /// Guard = 0; EEPROM.update(1, Guard); sms(String(F("System->off\n")), 1); // смс на все номера } void GuardOn() { /// === включение сигнализации === /// Guard = 1; EEPROM.update(1, Guard); sms(String(F("System->on\n")), 1); // смс на все номера } void Led() { /// === состояние светодиода === /// // if (Guard == 1) { // если на охране int currentMillis_led = millis(); // светодиод моргает //проверяем не прошел ли нужный интервал, если прошел то if (currentMillis_led - previousMillis_led > interval_led) { // сохраняем время последнего переключения previousMillis_led = currentMillis_led; // если светодиод не горит, то зажигаем, и наоборот if (LEDState == HIGH) LEDState = LOW; else LEDState = HIGH; digitalWrite(LED, LEDState); } // } else digitalWrite(LED, HIGH); // иначе гасим его } void Komand(String kom) { /// === мастер смс === /// Serial.println("-> " + kom); kom.toLowerCase(); if (RingPhone == AlarmPhone[0] || sendsmscaller == 0) { // команды выполняются только с 0 мастер номера if (kom.indexOf(F("reset")) > -1) { // полный сброс ЕЕПРОМ sms(F("System Reset!\n"), 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("out1on"))) > -1) { // Включение канала 1 digitalWrite(OUT1, HIGH);sms(F("OUT1 ON!!\n"), 1); } else if ((p = kom.indexOf(F("out1off"))) > -1) { // Выключение канала 1 digitalWrite(OUT1, LOW);sms(F("OUT1 OFF!!\n"), 1); } else if ((p = kom.indexOf(F("out2on"))) > -1) { // Включение канала 2 digitalWrite(OUT1, HIGH);sms(F("OUT2 ON!!\n"), 1); } else if ((p = kom.indexOf(F("out2off"))) > -1) { // Выключение канала 2 digitalWrite(OUT1, LOW);sms(F("OUT2 OFF!!\n"), 1); } else if ((p = kom.indexOf(F("out3on"))) > -1) { // Включение канала 3 digitalWrite(OUT1, HIGH);sms(F("OUT3 ON!!\n"), 1); } else if ((p = kom.indexOf(F("out3off"))) > -1) { // Выключение канала 3 digitalWrite(OUT1, LOW);sms(F("OUT3 OFF!!\n"), 1); } else if ((p = kom.indexOf(F("out4on"))) > -1) { // Включение канала 4 digitalWrite(OUT1, HIGH);sms(F("OUT4 ON!!\n"), 1); } else if ((p = kom.indexOf(F("out4off"))) > -1) { // Выключение канала 4 digitalWrite(OUT1, LOW);sms(F("OUT4 OFF!!\n"), 1); ////////////****************************************************************************** } 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)) { // инфо о состоянии системы eepromconfig(); sms(eepromtext(), 0); // смс на последний номер } else if (kom.indexOf(F("temp")) > -1) { // вкл sms(TempC(), 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\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл Sirena = 0; EEPROM.update(8, Sirena); sms(String(F("Sirena->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("ring")) > -1) { // вкл/выкл вызов при сработке if (kom.indexOf(on) > -1) { // вкл AlarmRING = 1; EEPROM.update(2, AlarmRING); sms(String(F("Ring->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл AlarmRING = 0; EEPROM.update(2, AlarmRING); sms(String(F("Ring->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("sms")) > -1) { // вкл/выкл смс при сработке if (kom.indexOf(on) > -1) { // вкл SendSMS = 1; EEPROM.update(3, SendSMS); sms(String(F("SMS->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл SendSMS = 0; EEPROM.update(3, SendSMS); sms(String(F("SMS->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("z1")) > -1) { // вкл/выкл контроль датчика двери if (kom.indexOf(on) > -1) { // выкл DOORon = 1; EEPROM.update(4, DOORon); sms(String(F("Zona1->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл контроль датчика двери DOORon = 0; EEPROM.update(4, DOORon); sms(String(F("Zona1->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("z4")) > -1) { // вкл/выкл контроль датчика двери 2 if (kom.indexOf(on) > -1) { // вкл SARAIon = 1; EEPROM.update(5, SARAIon); sms(String(F("Zona4->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл SARAIon = 0; EEPROM.update(5, SARAIon); sms(String(F("Zona4->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("z2")) > -1) { // вкл/выкл контрол датчика движения if (kom.indexOf(on) > -1) { // вкл PIRon = 1; EEPROM.update(6, PIRon); sms(String(F("PIR->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл PIRon = 0; EEPROM.update(6, PIRon); sms(String(F("PIR->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("z3")) > -1) { // вкл/выкл контроль датчика газа if (kom.indexOf(on) > -1) { // вкл GASon = 1; EEPROM.update(7, GASon); sms(String(F("GAS->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл GASon = 0; EEPROM.update(7, GASon); sms(String(F("GAS->off\n")), 1); // смс на все номера } } gsm.println(F("AT+CMGD=1,4")); // стираем смс } void balance() { /// === проверка баланса сим-карты === /// EEPROM.get(20, Bal); // считываем массив символов delay(100); if (ModemID == 1) { gsm.println(AT_M590); delay(100); gsm.println(String("ATD#") + Bal + String("#;")); } else if (ModemID == 2 || ModemID == 3) gsm.println(String(AT_SIM800_A6) + Bal + "#,15"); Serial.println(String(F("Balance#")) + Bal + "#"); } int 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\n", 0); // смс на 0 номер. }// else Serial.println(F("MAX number 4!")); // 4 номера максимум! // 0 номер можно удалить только через RESET!!! return 1; } int dellphone (int i) { /// === удаление мастар-номеров === /// if (i < 5 && i != 0) { sms(String(F("Master")) + i + ":" + AlarmPhone[i] + " dell\n", 0); // смс на 0 номер EEPROM.put(Adress[i], 0); AlarmPhone[i] = ""; // обнулим номер } return 1; } int balnum (String num) { /// === добавляем номер баланса === /// num.toCharArray(Bal, 4); // конвертируем EEPROM.put(20, Bal); // записываем массив в EEPROM sms(String(F("Balance:*")) + num + F("# Ok\n"), 0); // смс на 0 номер return 1; } String 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(); int Temp = (data[1] << 8) + data[0]; Temp = Temp >> 4; tr=Temp; temp = String(F("Temp ")) + Temp + "*C"; return temp; } 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(); 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() { // запуск модема 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()) { char ch = gsm.read(); str += ch; } if (str.indexOf("OK") > -1) { Serial.println("OK"); countok++; } else countok = 0; } } } void sms(String text, byte sendnum) { /// === отправка СМС === /// String phone = ""; if (sendsmscaller == 1 && sendnum == 0) { // отправка смс на номер звонившего phone = RingPhone; Serial.println(String(F("SMS send=>")) + phone); gsm.println(String(F("AT+CMGS=\"+")) + phone + "\""); delay(100); gsm.print(text + TempC()); delay(100); gsm.print((char)26); delay(2000); } else if (sendsmscaller == 1 && sendnum == 1) { // отправка смс на все номера for (int i = 0; i < 4 ; i++) { phone = AlarmPhone[i]; if (phone != 0) { Serial.println(String(F("SMS send=>")) + phone); gsm.println(String(F("AT+CMGS=\"+")) + phone + "\""); delay(100); gsm.print(text + TempC()); delay(100); gsm.print((char)26); delay(4000); } } } Serial.println(text + TempC() + "\n"); } void regtemp() { TempC(); if (tr>=30 )digitalWrite(REG,LOW); else digitalWrite(REG,LOW); } void Restart() { /// === рестарт системы === /// digitalWrite(rst, HIGH); // перезапускаем модем delay(200); digitalWrite(rst, LOW); digitalWrite(LED, HIGH); // светодиод горит во время запуска eepromconfig(); // читаем конфигурацию из памяти Serial.println(String(F("MasterPhone:\n")) + eepromphone() + "\r\n"); // выводим список номеров из памяти в порт //Serial.println(String(F("AlarmConfig:\n")) + eepromtext()); // закомментировать если смс TempC(); // читаем температуру Signal(); // читаем сигнал сети GSM Serial.println(String(F("Firststart:")) + Firststart); if (!Firststart) sms(String(F("Modem restart\n")) + eepromtext(), 0); // если не первый старт смс на последний номер digitalWrite(LED, LOW); // гасим светодиод состояния сигнализации. }Номер обрезает нормально:?
"RingPhone ......"