замучились с модемом М590 и новый модем А6 тоже не работает? -если читаете тем же кодом, что в сообщении #165 - не удивительно. Код чтения СМС весьма бредовый
if (mySerial.available()) { // есть данные от GSM модуля.
delay(200); // выждем, чтобы строка успела попасть в порт целиком.
while (mySerial.available()) { // сохраняем входную строку в переменную val.
ch = mySerial.read();
val += char(ch);
delay(50);
}
Обьясните, зачем нужны задержки? Первая слишком велика - буфер SoftwareSerial всего 64 байта. пока вы будете ждать 200мс, есть шанс что он переполнится. Вторая задержка еще нелепей - 50 мс ПОСЛЕ КАЖДОГО СИМВОЛА! Если у вас типичная СМС вместе с технической информацией 200 символов - вы будете читать ее 10 секунд! Да у вас половина данных должна теряться при таком темпе работы сериала.- что, собственно, у вас и происходит.
Задержки вообще удалять? Этот код чтения не раз уже попадался в интернете, ничего другого не знаю. Есть другой вариант?
Кодов чтения СМС в инете полно. С такими задержками не видел. Для примера посмотрите любую библиотеку для любого GSM-модема - код чтения СМС практически одинаков у любого модема.
Первую задержку можете оставить, но я бы снизил до 20-50мс. Больше не имеет смысла - у вас буфер приема 64 байта. посчитайте, за сколько он заполнится при скорости 9600. Вторую надо убрать ОБЯЗАТЕЛЬНО. Или, хотя бы - поставить минимальную, 2-3 (не более 5) мс.
А вообще, вам на будущее. То, что в вашем коде вы ждете фиксированное время, чтобы от модема пришла полная строка - гнилая на корню идея. Инфа из модема может приходить с перерывами, а может выплевываться по несколько сообщений разом. Надо читать и разбирать то, что пришло - и если пришло не все, ждать, пока из модема придет остальное. Опять же, примеров полно в любой подобной библиотеке.
ЗЫ собираю свой микропроект на модеме А6, если будут вопросы по этому модему - спрашивайте
разобрался с балансом (напомню, модем A6). датчики пока не проверял, но проверил все смс, всё работает.
единственное мастер номера каждый отправляет отдельным sms, как их объединить чтоб приходило в одном смс и выглядело так:
master0:79111234567
master1:79112645321
так считываю номера:
for (int i = 0; i < 5 ; i++) { // считываем все ячейки памяти номеров
EEPROM.get(Adress[i], Phone); // считываем массив символов по адресу
AlarmPhone[i] = Phone;
if (AlarmPhone[i] != 0) { // если ячейка пустая, не пишем ее
Serial.println(String(F("Phone[")) + i + String(F("]:")) + AlarmPhone[i]);
}
Phone[12] = " "; // обнулим, больше не нужен
}
А вот весь код:
#include <EEPROM.h>
#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
#define DOOR 4 // концевик двери.
#define PIR 6 // датчик движения.
#define GAS A0 // датчик дыма.
#define BUZ 11 // сирена.
#define Led 12 // состояние системы, моргает - норма.
// DOOR - если сработал, на входе "+" HIGH.
// PIR - если сработал, на входе "+" HIGH.
// GAS - если сработал, на входе "+" HIGH.
// BUZ - если "-" LOW, то горит.
// Led - если "-" LOW, то горит.
int8_t Guard = 0; // 1. охрана: 1 - вкл, 0 - выкл.
int8_t AlarmRING = 1; // 2. вызов: 1 - вкл, 0 - выкл.
int8_t SendSMS = 1; // 3. отправка смс: 1 - вкл, 0 - выкл.
int8_t DOORon = 1; // 4. контроль концевиков дверей: 1 - вкл, 0 - выкл.
int8_t PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл.
int8_t GASon = 1; // 6. контроль датчика дыма: 1 - вкл, 0 - выкл.
int8_t DOORFlag = 1;
int8_t PIRFlag = 1;
int8_t GASFlag = 1;
int8_t DOORState = LOW; // Состояние концевика двери.
int8_t PIRState = LOW; // Состояние датчика движения.
int8_t LedState = HIGH; // Состояние светодиода.
int8_t Firststart; // первый старт.
uint8_t PIRcount = 3; // Кол-во срабатываний PIR - 3 до тревоги.
uint32_t msAT = 0;
char Bal[4] = ""; // для временного хранения номера баланса
char Phone[12] = ""; // для временного хранения номера телефона
byte Adress[5] = {25, 40, 55, 70, 85}; //занимаем ячейки для пяти номеров.
String val; // переменная для хранения данных
String LastEvent; // полное состояние системы.
String RingPhone; // номер звонившего.
String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс.
int GASThres = 400; // предельная концентрация газа
uint8_t PIRDetectCount = 0; // обнуление счетчика PIR датчика.
uint8_t AlarmInterval = 10; // Секунд до отключения "тревожного" пина.
uint8_t interval = 100; // для мигания BLed
uint16_t previousMillis = 0;
uint16_t previousAlarmMillis = 0;
/* EEPROM Data:
№ ячейки - значение;
0 - если записана не 1, то необходимо затереть eeprom и восстановить стандартную конфигурацию.
1 - Guard = 0; // охрана: 1 - вкл, 0 - выкл.
2 - AlarmRING = 1; // звонок: 1 - вкл, 0 - выкл.
3 - SendSMS = 1; // отправка смс: 1 - вкл, 0 - выкл.
4 - DOORon = 1; // концевик двери: 1 - вкл, 0 - выкл.
5 - PIRon = 1; // датчик движения: 1 - вкл, 0 - выкл.
6 - GASon = 1; // датчик дыма: 1 - вкл, 0 - выкл.
7 -
8 -
9 - PIRcount = 2; // количество срабатываний PIR датчика = 3.
10 - Firststars = 1; // первый запуск = 1;
20 - ячейка памяти баланса,
25, 40, 55, 70, 85 - ячейки памяти телефонов.
100 - ячейка памяти RingPhone.
*/
void setup() {
Serial.begin(9600);
pinMode(DOOR, INPUT_PULLUP);
pinMode(PIR, INPUT);
pinMode(GAS, INPUT);
pinMode(BUZ, OUTPUT);
pinMode(Led, OUTPUT);
digitalWrite(BUZ, HIGH);
InitModem();
eepromconfig();
digitalWrite(Led, HIGH);
}
void loop() {
LED();
AlarmPinOff();
Detect();
if (val.indexOf(F("+PBREADY")) > -1) InitModem(); // если модем перезапустился запускаем инициализацию.
if (mySerial.available()) { // если GSM модем что-то послал.
while (mySerial.available()) { // сохраняем входную строку в переменную val.
char ch = mySerial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
if (val.indexOf(F("+CLIP")) > -1) { //// если обнаружен вызов.
Serial.println(F("Process RING"));
mySerial.println(F("ATH")); // сбрасываем вызов.
if (CheckPhone() == 1) { // проверяем номер, если наш.
Serial.println(F("Master Ring OK!"));
MasterRing(); // меняем состояние охраны
} else Serial.println(F("No Master Ring!"));
} else if (val.indexOf(F("+CMT")) > -1) { //// если обнаруженa СМС
Serial.println(F("Process CMT"));
if (CheckPhone() == 1) { // если СМС от хозяина
Serial.println(F("Master SMS OK!"));
Serial.println(String(F("SMS->")) + val); // что пришло в смс
MasterSMS();
} else Serial.println(F("No Master SMS!"));
} else if(val.indexOf(F("+CUSD:"))>-1) { //// если пришел баланс
// команда проверки баланса AT+CUSD=1,#105#,15
// анализируем строку
int p1 = val.indexOf(F("\"")); // начало строки
int p2 = val.lastIndexOf(F("\"")); // конец строки
val = val.substring(p1+1,p2);
Serial.println("");
Serial.println(F("Input string:")); // пишем в порт пришедшую строку
Serial.println(val);
String decodestr;
Decode7bit(val, decodestr);
Serial.println("");
Serial.println(F("Decode string:")); // пишем в порт конвертированную строку
Serial.println(decodestr);
sms(String("Balance SIM: " + decodestr), String("+" + RingPhone)); // смс на последний звонивший
} val = "";
} if (Serial.available()) { // если в мониторе порта что-то ввели
while (Serial.available()) { // сохраняем входную строку в переменную val.
char ch = Serial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
ConsolePrint(); // запускаем консольную программу
val = "";
}
}
int CheckPhone() { /// === проверка телефона === ///
if (Firststart == 0) { // если не первый старт
for (int i = 0; i < 5; i++) {
if (val.indexOf(AlarmPhone[i]) > -1 && val.indexOf(AlarmPhone[i]) != 0) { // если есть вызов, и он наш
RingPhone = AlarmPhone[i]; // запоминаем его.
RingPhone.toCharArray(Phone, 12);
EEPROM.put(100, Phone); // записываем RingPhone в память.
// Serial.println(String(F("RingPhone ")) + RingPhone);
return 1; // возвращаем 1 - номер наш!
}
} Phone[12] = "";
return 0; // возвращаем 0 - номер не наш!
} else if (Firststart == 1) { // иначе (если первый старт)
int ind = val.indexOf("+CLIP:") + 8; // обрезаем номер
String num = val.substring(ind, ind + 11);
num.toCharArray(Phone, 12);
EEPROM.put(25, Phone); // пишем номер в EEPROM
AlarmPhone[0] = Phone; // запишем
EEPROM.update(10, 0); // обновляем Firststart
Firststart = 0; // пишем 0
Serial.println(String(F("Master0:")) + AlarmPhone[0]);
Serial.println(String(F("Firststart:")) + Firststart);
sms(String("Master0:" + num + " Ok"), String("+" + num)); // смс на звонивший
Phone[12] = "";
}
}
void eepromconfig() {
pinMode(13, OUTPUT);
if (EEPROM.read(0) != 1) { // если записана не 1
for (int i = 0 ; i < 512 ; i++) { // переписываем все ячейки
EEPROM.write(i, 0);
} // и записываем:
EEPROM.update(1, 0); // Guard охрана выкл.
EEPROM.update(2, 1); // AlarmRING вызов вкл.
EEPROM.update(3, 1); // SendSMS смс вкл.
EEPROM.update(4, 1); // DOORon датчики дверей вкл.
EEPROM.update(5, 1); // PIRon датчик движения вкл.
EEPROM.update(6, 1); // GASon датчик газа вкл.
EEPROM.update(9, 2); // PIRcount. 2 повторных срабатывания.
EEPROM.update(10, 1); // Firststart первый старт!.
EEPROM.update(20, 0); // баланс, записываем массив в EEPROM
EEPROM.update(0, 1); //
digitalWrite(13, HIGH);
Serial.println(F("EEPROM != 1/ RESET!"));
}
if (EEPROM.read(0) == 1) {
Guard = EEPROM.read(1); // Охрана
AlarmRING = EEPROM.read(2); // Вызов
SendSMS = EEPROM.read(3); // Отправка смс
DOORon = EEPROM.read(4); // Датчик двери
PIRon = EEPROM.read(5); // Датчик движения
GASon = EEPROM.read(6); // Датчик газа/дыма
// = EEPROM.read(7); //
// = EEPROM.read(8); //
PIRcount = EEPROM.read(9); //
Firststart = EEPROM.read(10); //
Masterphone();
}
String SIGN = ""; // текущее состояние системы.
String RING = ""; // текущее состояние вызов.
String SMS = ""; // текущее состояние смс.
String Door = ""; // текущее состояние датчика двери.
String Pir = ""; // текущее состояние датчика движения.
String Gas = ""; // текущее состояние датчика газа.
if (Guard == 1) SIGN = String(F("System -> on;\n"));
if (Guard == 0) SIGN = String(F("System -> off;\n"));
if (AlarmRING == 1) RING = String(F("Ring -> on;\n"));
if (AlarmRING == 0) RING = String(F("Ring -> off;\n"));
if (SendSMS == 1) SMS = String(F("SMS -> on;\n"));
if (SendSMS == 0) SMS = String(F("SMS -> off;\n"));
if (PIRon == 1) Pir = String(F("Pir -> on;\n"));
if (PIRon == 0) Pir = String(F("Pir -> off;\n"));
if (DOORon == 1) Door = String(F("Door -> on;\n"));
if (DOORon == 0) Door = String(F("Door -> off;\n"));
if (GASon == 1) Gas = String(F("Gas -> on;\n"));
if (GASon == 0) Gas = String(F("Gas -> off;\n"));
String System = SIGN + RING + SMS; // состояние (вкл/выкл) системы.
String Sensors = Pir + Door + Gas; // состояние (вкл/выкл) датчиков.
LastEvent = System + Sensors; // полное состояние системы и датчиков.
Serial.println(LastEvent);
}
void Detect() { /// === чтение датчиков === ///
DOORState = digitalRead(DOOR);
PIRState = digitalRead(PIR);
int Smoky = analogRead(GAS);
if (DOORState == HIGH && DOORFlag == 0 && DOORon == 1) { // если датчик двери сработал
DOORFlag = 1;
Serial.println(F("Dver' otkrita!"));
Alarm();
}
if (DOORState == LOW && DOORFlag == 1) { // Датчик успокоился
DOORFlag = 0;
}
if (PIRState == HIGH && PIRon == 1) { // если датчик движения сработал
PIRDetectCount ++;
Serial.println(F("Dvizhenie!"));
if (Guard == 1 && PIRDetectCount < 2) { // если первый раз
digitalWrite(BUZ, LOW); // отпугиваем сиреной
delay(250);
digitalWrite(BUZ, HIGH);
}
if (Guard == 1 && PIRDetectCount == PIRcount) { //
Serial.println(F("Dvizhenie!!!"));
PIRFlag = 1;
Alarm(); // включаем сирену сигнализация!
PIRDetectCount == 0;
}
}
if (PIRState == LOW && PIRFlag == 1) { // Датчик успокоился
PIRFlag = 0;
digitalWrite(13, LOW);
}
/* if (Smoky > GASThres && GASFlag == 0 && GASon == 1) { // датчик сработал
GASFlag = 1;
Serial.println(F("Srabotal datchik gasa!"));
Alarm();
}
if (Smoky < GASThres && GASFlag == 1) { // Датчик успокоился
GASFlag = 0;
}*/
}
void Alarm() {
if (Guard == 1) {
previousAlarmMillis = millis();
digitalWrite(BUZ, LOW);
Serial.println(F("Alarm!!!"));
if (SendSMS == 1) {
for (int i = 0; i < 5; i++) {
if (DOORFlag == 1 && AlarmPhone[i] != 0) {
sms(String("Dver' otkrita!"), String("+" + String(AlarmPhone[i]))); // смс на все номера
}
if (PIRFlag == 1 && AlarmPhone[i] != 0) {
sms(String("Dvizhenie y dveri!"), String("+" + String(AlarmPhone[i]))); // смс на все номера
}
if (GASFlag == 1 && AlarmPhone[i] != 0) {
sms(String("Gas v dome!"), String("+" + String(AlarmPhone[i]))); // смс на все номера
}
// delay(1000);
}
}
if (AlarmRING == 1) {
mySerial.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру
// delay(1000); // ????? не решил дождаться отбоя или положить трубку.
}
}
}
void AlarmPinOff() {
uint16_t currentAlarmMillis = millis();
if (currentAlarmMillis - previousAlarmMillis > AlarmInterval * 1000) {
digitalWrite(BUZ, HIGH);
}
}
void MasterRing() {
if (Guard == 1) GuardOff();
else if (Guard == 0) GuardOn();
}
void GuardOff() {
Guard = 0;
EEPROM.update(1, Guard);
Serial.println(String(F("System -> off. Ring:")) + RingPhone);
for (int i = 0; i < 5; i++) {
if (AlarmPhone != 0) {
// sms(String("System -> off"), String("+" + AlarmPhone[i])); // смс на все номера
}
}
PIRDetectCount = 0; // сбрасываем счетчик срабатываний PIR датчика.
}
void GuardOn() {
Guard = 1;
EEPROM.update(1, Guard);
Serial.println(String(F("System -> on. Ring:")) + RingPhone);
for (int i = 0; i < 5; i++) {
if (AlarmPhone != 0) {
// sms(String("System -> on"), String("+" + AlarmPhone[i])); // смс на все номера
}
}
}
void LED() { /// === состояние светодиодов === ///
if (Guard == 0) { // если снят с охраны
digitalWrite(Led, HIGH); // светодиод не горит
}
if (Guard == 1) { // если на охране
uint16_t currentMillis = millis(); // светодиод моргает
//проверяем не прошел ли нужный интервал, если прошел то
if (currentMillis - previousMillis > interval) {
// сохраняем время последнего переключения
previousMillis = currentMillis;
// если светодиод не горит, то зажигаем, и наоборот
if (LedState == HIGH) LedState = LOW;
else LedState = HIGH;
digitalWrite(Led, LedState);
}
}
}
void ConsolePrint() {
val.toLowerCase();
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
master(val.substring(6, 7).toInt(), val.substring(8, 19));
// sms типа: " master1:79111386232 " - номер в ячейку "1", куда записать номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
balnum(val.substring(8, 13));
// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
dellphone(val.substring(5, 6).toInt());
// sms типа: " dell:1 " - удалить номер из ячейки 1
}
if (val.indexOf(F("reset")) > -1) { // сброс ЕЕПРОМ
Serial.println(F("Reset System!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
eepromconfig();
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("guardon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("guardoff")) > -1) { // выкл сигнализации
GuardOff();
}
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring -> on"));
// sms(String("Ring -> on"), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring -> off"));
// sms(String("Ring -> off"), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS -> on"));
// sms(String("SMS -> on"), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS -> off"));
// sms(String("SMS -> off"), String("+" + RingPhone)); // смс на последний номер
}
}
void MasterSMS() { /// === мастер смс === ///
val.toLowerCase();
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
int tel(val.indexOf(F("master")));
master(val.substring(tel + 6, tel + 7).toInt(), val.substring(tel + 8, tel + 19));
///// sms типа: " master1:79111234567 " - ячейка + номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
int bal(val.indexOf(F("balance:")));
balnum(val.substring(bal + 8, bal + 11));
///// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
int del(val.indexOf(F("dell:")));
dellphone(val.substring(del + 5, del + 6).toInt());
///// sms типа: " dell:1 " - удалить номер из ячейки 1
}
if (val.indexOf(F("phone")) > -1) { // инфо о состоянии системы
Masterphone();
for (int i = 0; i < 5 ; i++) {
if (AlarmPhone[i] != 0) {
sms(String(String("Master[") + i + String("]:") + AlarmPhone[i]), String("+" + RingPhone)); // смс на последний номер
}
}
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
// Serial.println(RingPhone + String(F("->SMS")));
eepromconfig();
sms(String(LastEvent), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("reset")) > -1) { // полный сброс ЕЕПРОМ
sms(String("Reset system!!!"), String("+" + RingPhone)); // смс на последний номер
Serial.println(F("Reset System!!!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
delay(500);
balance();
}
if (val.indexOf(F("guardon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("guardoff")) > -1) { // выкл сигнализации
GuardOff();
}
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing -> on"));
sms(String("Ring -> on"), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing -> off"));
sms(String("Ring -> off"), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS -> on"));
sms(String("SMS -> on"), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS -> off"));
sms(String("SMS -> off"), String("+" + RingPhone)); // смс на последний номер
}
}
void balance() { /// === проверка баланса сим-карты === ///
EEPROM.get(20, Bal); // считываем массив символов
mySerial.println(String(F("AT+CUSD=1,#")) + Bal + String(F("#,15")));
delay(100);
}
void Masterphone() { /// === чтение мастер-номеров из EEPROM === ///
for (int i = 0; i < 5 ; i++) {
EEPROM.get(Adress[i], Phone); // считываем массив символов
AlarmPhone[i] = Phone;
if (AlarmPhone[i] != 0) {
Serial.println(String(F("Phone[")) + i + String(F("]:")) + AlarmPhone[i]);
}
Phone[12] = ""; // обнулим, больше не нужен
}
EEPROM.get(100, Phone); // считываем массив символов
RingPhone = Phone;
Serial.println(String(F("Ring [ ]:")) + RingPhone);
Phone[12] = ""; // обнулим, больше не нужен
EEPROM.get(20, Bal); // считываем массив символов
Serial.println(String(F("Balance:")) + Bal);
Firststart = EEPROM.read(10); // cчитаем из EEPROM
Serial.println(String(F("Firststart:")) + Firststart);
}
int master (int i, String num) { /// === добавление мастер-номеров === ///
if (i < 5 && i != 0) {
num.toCharArray(Phone, 12); // конвертируем
AlarmPhone[i] = num; // пишем номер
Serial.println(String(F("Master[")) + i + String(F("]:")) + num);
EEPROM.put(Adress[i], Phone); // записываем массив в EEPROM
sms(String(String("Master") + i + ":" + num + " add"), String("+" + RingPhone)); // смс на последний номер.
sms(String("Tell " + AlarmPhone[i] + " add"), String("+" + AlarmPhone[i])); // смс на добавленный номер.
Phone[12] = "";
} else Serial.println(F("MAX number 4!")); // 4 номера максимум!
// 0 номер можно удалить только очисткой, первый старт
}
int dellphone (int i) { /// === удаление мастар-номеров === ///
if (i < 5 && i != 0) {
Serial.println(String(F("Master")) + i + String(F(" dell")));
EEPROM.put(Adress[i], 0);
sms(String(String("Master") + i + ":" + AlarmPhone[i] + " dell"), String("+" + RingPhone)); // смс на последний номер
sms(String("Tell " + AlarmPhone[i] + " dell"), String("+" + AlarmPhone[i])); // смс на добавленный номер.
AlarmPhone[i] = ""; // обнулим номер
}
}
int balnum (String num) { /// === добавляем номер баланса === ///
num.toCharArray(Bal, 4); // конвертируем
Serial.println(String(F("Balance:")) + Bal);
EEPROM.put(20, Bal); // записываем массив в EEPROM
sms(String("Balance: #" + num + "# Ok"), String("+" + RingPhone)); // смс на последний номер
}
void Decode7bit(String &instr, String &outstr)
{
byte reminder = 0;
int bitstate = 7;
for(int i=0; i<instr.length(); i++)
{
byte b = instr[i];
byte bb = b << (7 - bitstate);
char c = (bb + reminder) & 0x7F;
outstr += c;
reminder = b >> bitstate;
bitstate--;
if(bitstate == 0)
{
char c = reminder;
outstr += c;
reminder = 0;
bitstate = 7;
}
}
}
void InitModem() {
Serial.println(F("Start module"));
mySerial.begin(9600); //Скорость порта для связи Arduino с GSM модулем
waitConnect();
Serial.println(F("GSM connected"));
waitRegistration();
delay(1000);
}
void waitConnect() { // запуск модема
int countok = 0;
String str;
while(countok < 5) { //ждём пять ОК
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) {// Событие срабатывающее каждые 500 мс
msAT = ms;
// Serial.println(">>AT");
mySerial.println(F("AT")); // посылаем команду
str = "";
delay(100); // ждём ответа
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
// Serial.println("C>");
// Serial.println(str);
if(str.indexOf(F("OK")) > -1)
countok++;
else
countok = 0;
}
}
Serial.println(F("Turn on AOH:"));
mySerial.println(F("AT+CLIP=1")); // включить АОН
delay(200);
Serial.println(F("GSM registration"));
mySerial.println(F("AT+CMGF=1"));
delay(200);
Serial.println(F("Mode GSM:"));
mySerial.println(F("AT+CSCS=GSM")); // кодировка текста - GSM
delay(300);
mySerial.println(F("AT+CNMI=2,2,0,0,0"));
delay(300);
}
void waitRegistration() { // регистрация модема в сети
bool ok = 0;
String str;
while(!ok) {
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) { // Событие срабатывающее каждые 500 мс
msAT = ms;
Serial.println(F(">>AT+CREG?"));
mySerial.println(F("AT+CREG?")); //посылаем команду
delay(100); //Ждём ответа
str = "";
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
Serial.println(F("R>"));
Serial.println(str);
if(str.indexOf(F("+CREG:"))>-1)
ok = 1;
}
}
}
void sms(String text, String phone) { /// === отправка СМС === ///
Serial.println(F("Start SMS send"));
mySerial.println(String(F("AT+CMGS=\"")) + phone + String(F("\"")));
delay(300);
mySerial.print(text);
delay(300);
mySerial.print((char)26);
delay(300);
Serial.println(String(F("SMS sended! Phone: ")) + phone + String(F("; Message: ")) + text);
delay(4000);
}
в каком режиме должен работать датчик движения? там два режима: Н и L. При Н датчик дает сигнал постоянно пока есть движение в зоне обнаружения. При режиме L обнаружение движение регистрируется задержкой выставленной подстроечником. после срабатывания сигнал прерывается и датчик переходит в режим калибровки примерно 3 секунды. дальше по новой. Вы в "натуре" откатывали программу? просто у меня почему то датчик тупо вешает программу после 2-3 срабатываний. после датчик вообще не как не реагирует на движение. Программный сброс счетчика
PIRDetectCount = 0; // сбрасываем счетчик срабатываний PIR датчика.
я человек не жадный, и поэтому вот моя протестированная в домашних условия версия (на макетке), все работает, глюков нет, буду паять на плату и в корпус для полевых испытаний. Arduino nano 328p + Ai-Thinker A6.
#include <EEPROM.h>
#include <OneWire.h>
#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
OneWire ds(12); // датчик температуры подключен к 9 пину, подтяжка 4.7кОм на +.
#define DOOR 4 // концевик двери.
#define PIR 5 // датчик движения.
#define Led 8 // состояние системы. моргает - на охране.
#define BUZ 10 // сирена.
#define GAS A0 // датчик дыма.
// DOOR - если сработал, на входе "+" HIGH.
// PIR - если сработал, на входе "+" HIGH.
// GAS - если сработал, на входе "+" HIGH.
// BUZ - если "-" LOW, то горит.
// Led - если "-" LOW, то горит.
int8_t Guard = 0; // 1. охрана: 1 - вкл, 0 - выкл.
int8_t AlarmRING = 1; // 2. вызов при сработке: 1 - вкл, 0 - выкл.
int8_t SendSMS = 1; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл.
int8_t DOORon = 1; // 4. контроль концевиков дверей: 1 - вкл, 0 - выкл.
int8_t PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл.
int8_t GASon = 1; // 6. контроль датчика дыма: 1 - вкл, 0 - выкл.
int8_t DOORFlag = 0; // флаг состояние датчика двери.
int8_t PIRFlag = 0; // флаг состояние датчика движения.
int8_t GASFlag = 0; // флаг состояние датчика газа.
int8_t DOORState = LOW; // Состояние концевика двери.
int8_t PIRState = LOW; // Состояние датчика движения.
int8_t LedState = HIGH; // Состояние светодиода.
int8_t Firststart; // первый старт.
uint32_t msAT = 0;
char Bal[4] = ""; // для временного хранения номера баланса.
char Phone[12] = ""; // для временного хранения номера телефона.
byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ.
String val; // переменная для хранения пришедших данных.
String temp; // переменная для хранения температуры.
String LastEvent; // полное состояние системы.
String RingPhone; // номер звонившего.
String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс.
int Smoky = LOW; // Состояние датчика газа.
int GASThres = 400; // предельная концентрация газа
int AlarmInterval = 10; // Секунд до отключения "тревожного" пина.
int interval = 1000; // для мигания Led
int previousMillis = 0;
int previousAlarmMillis = 0;
/* EEPROM Data:
№ ячейки - значение:
0 - если записана не 1, то необходимо затереть eeprom и восстановить стандартную конфигурацию.
1 - Guard = 0; // охрана: 0 - выкл.
2 - AlarmRING = 1; // звонок: 1 - вкл.
3 - SendSMS = 1; // отправка смс: 1 - вкл.
4 - DOORon = 1; // концевик двери: 1 - вкл.
5 - PIRon = 1; // датчик движения: 1 - вкл.
6 - GASon = 1; // датчик дыма: 1 - вкл.
7 -
8 -
9 -
10 - Firststars = 1; // первый запуск 1.
15 - AlarmInterval = 10 // время сирены
20 - ячейка памяти баланса,
25, 40, 55, 70, 85 - ячейки памяти телефонов.
100 - ячейка памяти номера последнего звонившего RingPhone.
*/
void setup() { /// настройка программы
Serial.begin(9600);
pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +.
pinMode(PIR, INPUT);
pinMode(GAS, INPUT);
pinMode(BUZ, OUTPUT);
pinMode(Led, OUTPUT);
digitalWrite(BUZ, HIGH); // сирена выкл.
digitalWrite(PIR, HIGH); // игнорируем при включении.
InitModem(); // запускаем инициализация модема.
eepromconfig();
digitalWrite(Led, HIGH); // гасим светодиод состояния сигнализации, сигнализация готова к работе.
}
void loop() { /// основной цикл программы.
LED(); // моргаем светодиодом.
AlarmPinOff(); // выключаем сирену, если прошло время.
Detect(); // проверяем датчики.
if (mySerial.available()) { // если GSM модем что-то послал.
while (mySerial.available()) { // сохраняем входную строку в переменную val.
char ch = mySerial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
if (val.indexOf(F("+CLIP")) > -1) { // если обнаружен вызов.
Serial.println(F("Process RING"));
delay(2000); // дадим гудок
mySerial.println(F("ATH")); // сбрасываем вызов.
if (CheckPhone() == 1) { // проверяем номер, если наш.
Serial.println(F("Master Ring OK!"));
MasterRing(); // меняем состояние охраны
} else Serial.println(F("No Master Ring!"));
} else if (val.indexOf(F("+CMT")) > -1) { // если обнаруженa СМС
Serial.println(F("Process CMT"));
Serial.println(String(F("SMS->")) + val); // что пришло в смс
if (CheckPhone() == 1) { // если СМС от хозяина
Serial.println(F("Master SMS OK!"));
MasterSMS();
} else Serial.println(F("No Master SMS!"));
} else if(val.indexOf(F("+CUSD:"))>-1) { // если пришел баланс
// команда проверки баланса AT+CUSD=1,#105#,15
// анализируем строку
int p1 = val.indexOf(F("\"")); // начало строки
int p2 = val.lastIndexOf(F("\"")); // конец строки
val = val.substring(p1+1,p2);
Serial.println("");
Serial.println(F("Input string:")); // пишем в порт пришедшую строку
Serial.println(val);
String decodestr;
Decode7bit(val, decodestr);
Serial.println("");
Serial.println(F("Decode string:")); // пишем в порт конвертированную строку
Serial.println(decodestr);
sms(String("SIM " + decodestr), String("+" + RingPhone)); // смс на последний звонивший
} val = "";
} if (Serial.available()) { // если в мониторе порта что-то ввели
while (Serial.available()) { // сохраняем входную строку в переменную val.
char ch = Serial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
ConsolePrint(); // запускаем консольную программу
val = "";
}
}
int CheckPhone() { /// === проверка телефона === ///
if (Firststart == 0) { // если не первый старт
for (int i = 0; i < 5; i++) {
if (val.indexOf(AlarmPhone[i]) > -1 && val.indexOf(AlarmPhone[i]) != 0) { // если есть вызов, и он наш
RingPhone = AlarmPhone[i]; // запоминаем его.
RingPhone.toCharArray(Phone, 12);
EEPROM.put(100, Phone); // записываем RingPhone в память.
// Serial.println(String(F("RingPhone ")) + RingPhone);
return 1; // возвращаем 1 - номер наш!
}
} Phone[12] = "";
return 0; // возвращаем 0 - номер не наш!
} else if (Firststart == 1) { // иначе (если первый старт)
// первый звонивший добавляется как основной мастер номер для управления сигнализацией
int ind = val.indexOf("+CLIP:") + 8; // обрезаем номер
String num = val.substring(ind, ind + 11);
num.toCharArray(Phone, 12);
EEPROM.put(25, Phone); // пишем номер в EEPROM
EEPROM.put(100, Phone); // записываем RingPhone в память.
AlarmPhone[0] = Phone; // запишем
RingPhone = Phone; // запоминаем его.
EEPROM.update(10, 0); // обновляем Firststart
Firststart = 0; // пишем 0
Serial.println(String(F("Master0:")) + AlarmPhone[0]);
Serial.println(String(F("Firststart:")) + Firststart);
sms(String("Master0:" + num + " Ok"), String("+" + num)); // смс на звонивший
// приходит смс в виде: " Master0:79111234567 Ok "
Phone[12] = "";
}
}
void eepromconfig() { /// === конфигурирование сигнализации === ///
pinMode(13, OUTPUT);
if (EEPROM.read(0) != 1) { // если записана не 1
for (int i = 0 ; i < 512 ; i++) { // переписываем все ячейки
EEPROM.write(i, 0);
} // и записываем:
EEPROM.update(1, 0); // Guard охрана выкл.
EEPROM.update(2, 1); // AlarmRING вызов вкл.
EEPROM.update(3, 1); // SendSMS смс вкл.
EEPROM.update(4, 1); // DOORon датчики дверей вкл.
EEPROM.update(5, 1); // PIRon датчик движения вкл.
EEPROM.update(6, 1); // GASon датчик газа вкл.
EEPROM.update(10, 1); // Firststart первый старт!.
EEPROM.update(15, 10); // время сирены.
EEPROM.update(20, 0); // баланс, записываем массив в EEPROM
EEPROM.update(0, 1); //
digitalWrite(13, HIGH);
Serial.println(F("EEPROM != 1/ RESET!"));
}
if (EEPROM.read(0) == 1) {
Guard = EEPROM.read(1); // Охрана
AlarmRING = EEPROM.read(2); // Вызов
SendSMS = EEPROM.read(3); // Отправка смс
DOORon = EEPROM.read(4); // Датчик двери
PIRon = EEPROM.read(5); // Датчик движения
GASon = EEPROM.read(6); // Датчик газа/дыма
Firststart = EEPROM.read(10); //
EEPROM.get(15, AlarmInterval); // время сирены.
Masterphone();
}
TempC();
String SIGN = ""; // текущее состояние системы.
String RING = ""; // текущее состояние вызов.
String SMS = ""; // текущее состояние смс.
String Door = ""; // текущее состояние датчика двери.
String Pir = ""; // текущее состояние датчика движения.
String Gas = ""; // текущее состояние датчика газа.
if (Guard == 1) SIGN = String(F("System ->on\n")); else (SIGN = String(F("System->off\n")));
if (AlarmRING == 1) RING = String(F("Ring->on\n")); else (RING = String(F("Ring->off\n")));
if (SendSMS == 1) SMS = String(F("SMS->on\n")); else (SMS = String(F("SMS->off\n")));
if (PIRon == 1) Pir = String(F("Pir->on\n")); else (Pir = String(F("Pir->off\n")));
if (DOORon == 1) Door = String(F("Door->on\n")); else (Door = String(F("Door->off\n")));
if (GASon == 1) Gas = String(F("Gas->on\n")); else (Gas = String(F("Gas->off\n")));
String AlarmBuz = String("Sirena: ") + AlarmInterval + "sec\n";
String System = SIGN + RING + SMS; // состояние (вкл/выкл) системы.
String Sensors = Pir + Door + Gas; // состояние (вкл/выкл) датчиков.
LastEvent = System + Sensors + AlarmBuz + temp; // полное состояние системы и датчиков.
Serial.println(LastEvent);
}
void Detect() { /// === чтение датчиков === ///
DOORState = digitalRead(DOOR);
PIRState = digitalRead(PIR);
Smoky = analogRead(GAS);
if (DOORon == 1) {
if (DOORState == HIGH && DOORFlag == 0) {
DOORFlag = 1;
Alarm(); //
}
if (DOORState == LOW && DOORFlag == 1) {
DOORFlag = 0;
}
}
if (PIRon == 1) {
if (PIRState == HIGH && PIRFlag == 0) {
PIRFlag = 1;
Alarm(); //
}
if (PIRState == LOW && PIRFlag == 1) {
PIRFlag = 0;
}
}
if (GASon == 1) {
if ((Smoky > GASThres) && GASFlag == 0) {
GASFlag = 1;
Alarm(); //
}
if ((Smoky < GASThres) && GASFlag == 1) {
GASFlag = 0;
}
}
}
void Alarm() { /// === запускаем сирену и отправку смс === ///
if (Guard == 1) {
previousAlarmMillis = millis();
digitalWrite(BUZ, LOW);
Serial.println(F("Alarm!!!"));
if (SendSMS == 1) {
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
if (DOORFlag == 1) {
Serial.println(F("Dver' otkrita!"));
sms(String("Dver' otkrita!"), String("+" + String(AlarmPhone[i]))); // смс на все номера
DOORFlag == 0;
}
if (PIRFlag == 1) {
Serial.println(F("Dvizhenie u dveri!"));
sms(String("Dvizhenie y dveri!"), String("+" + String(AlarmPhone[i])));
}
if (GASFlag == 1) {
Serial.println(F("Gas v dome!"));
sms(String("Gas v dome!"), String("+" + String(AlarmPhone[i]))); // смс на все номера
}
}
}
if (AlarmRING == 1) {
mySerial.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру
}
}
}
void AlarmPinOff() { /// === если прошло время, отключаем сирену === ///
uint16_t currentAlarmMillis = millis();
//if ((currentAlarmMillis - previousAlarmMillis > AlarmInterval * 1000)) {//Orig!
if (((currentAlarmMillis - previousAlarmMillis) / 1000 > AlarmInterval) || Guard == 0) {
digitalWrite(BUZ, HIGH);
// DOORFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
// PIRFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
// GASFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
}
}
void MasterRing() { /// === мастер звонков === //
if (Guard == 1) GuardOff(); // меняем состояние
else if (Guard == 0) GuardOn(); // меняем состояние
}
void GuardOff() { /// === выключение сигнализации === ///
Guard = 0;
EEPROM.update(1, Guard);
Serial.println(String(F("System->off. Ring:")) + RingPhone);
TempC();
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
sms(String("System->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
}
void GuardOn() { /// === включение сигнализации === ///
Guard = 1;
EEPROM.update(1, Guard);
Serial.println(String(F("System->on. Ring:")) + RingPhone);
TempC();
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
sms(String("System->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
}
void LED() { /// === состояние светодиода === ///
if (Guard == 1) { // если на охране
uint16_t currentMillis = millis(); // светодиод моргает
//проверяем не прошел ли нужный интервал, если прошел то
if (currentMillis - previousMillis > interval) {
// сохраняем время последнего переключения
previousMillis = currentMillis;
// если светодиод не горит, то зажигаем, и наоборот
if (LedState == HIGH) LedState = LOW;
else LedState = HIGH;
digitalWrite(Led, LedState);
}
} else digitalWrite(Led, HIGH); // иначе гасим его
}
void ConsolePrint() { /// === кончсольная программа === ///
val.toLowerCase();
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
master(val.substring(6, 7).toInt(), val.substring(8, 19));
// sms типа: " master1:79111234567 " - номер в ячейку "1", куда записать номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
balnum(val.substring(8, 13));
// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
dellphone(val.substring(5, 6).toInt());
// sms типа: " dell:1 " - удалить номер из ячейки 1
}
if (val.indexOf(F("reset")) > -1) { // сброс ЕЕПРОМ
Serial.println(F("Reset System!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
eepromconfig();
}
if (val.indexOf(F("sirena:")) > -1) {
sirena(val.substring(7, 10).toInt());
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("systemon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("systemoff")) > -1) { // выкл сигнализации
GuardOff();
}
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring->on"));
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring->off"));
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS->on"));
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS->off"));
}
if (val.indexOf(F("dooron")) > -1) { // выкл вызов при сработке
DOORon = 1;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->on"));
}
if (val.indexOf(F("dooroff")) > -1) { // выкл вызов при сработке
DOORon = 0;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->off"));
}
if (val.indexOf(F("piron")) > -1) { // выкл вызов при сработке
PIRon = 1;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->on"));
}
if (val.indexOf(F("piroff")) > -1) { // выкл вызов при сработке
PIRon = 0;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->off"));
}
if (val.indexOf(F("gason")) > -1) { // выкл вызов при сработке
GASon = 1;
EEPROM.update(6, GASon);
Serial.println(F("GAS->on"));
}
if (val.indexOf(F("gasoff")) > -1) { // выкл вызов при сработке
GASon = 0;
EEPROM.update(6, GASon);
Serial.println(F("GAS->off"));
}
}
void MasterSMS() { /// === мастер смс === ///
val.toLowerCase();
if (RingPhone == AlarmPhone[0]) { // команды выполняются только с 0 мастер номера
if (val.indexOf(F("reset")) > -1) { // полный сброс ЕЕПРОМ
sms(String("All System Reset!!!"), String("+" + RingPhone)); // смс на последний номер
Serial.println(F("Reset System!!!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
int tel(val.indexOf(F("master")));
master(val.substring(tel + 6, tel + 7).toInt(), val.substring(tel + 8, tel + 19));
///// sms типа: " master1:79111234567 " - ячейка + номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
int bal(val.indexOf(F("balance:")));
balnum(val.substring(bal + 8, bal + 11));
///// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
int del(val.indexOf(F("dell:")));
dellphone(val.substring(del + 5, del + 6).toInt());
///// sms типа: " dell:1 " - удалить номер из ячейки 1
}
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
eepromconfig();
sms(String(LastEvent), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("phone")) > -1) { // инфо о состоянии системы
Masterphone();
for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) {
sms(String(String("Master") + i + String(":") + AlarmPhone[i]), String("+" + RingPhone)); // смс на последний номер
}
}
if (val.indexOf(F("sirena:")) > -1) {
int buz(val.indexOf(F("sirena")));
sirena(val.substring(buz + 7, buz + 10).toInt());
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("systemon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("systemoff")) > -1) { // выкл сигнализации
GuardOff();
}
for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) { // смс на все номера
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing->on"));
sms(String("Ring->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing->off"));
sms(String("Ring->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS->on"));
sms(String("SMS->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS->off"));
sms(String("SMS->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("dooron")) > -1) { // выкл вызов при сработке
DOORon = 1;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->on"));
sms(String("DOOR->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("dooroff")) > -1) { // выкл вызов при сработке
DOORon = 0;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->off"));
sms(String("DOOR->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("piron")) > -1) { // выкл вызов при сработке
PIRon = 1;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->on"));
sms(String("PIR->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("piroff")) > -1) { // выкл вызов при сработке
PIRon = 0;
EEPROM.update(5, PIRon);
Serial.println(F("PIR -> off"));
sms(String("PIR -> off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("gason")) > -1) { // выкл вызов при сработке
GASon = 1;
EEPROM.update(6, GASon);
Serial.println(F("GAS->on"));
sms(String("GAS->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("gasoff")) > -1) { // выкл вызов при сработке
GASon = 0;
EEPROM.update(6, GASon);
Serial.println(F("GAS->off"));
sms(String("GAS->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
}
}
void balance() { /// === проверка баланса сим-карты === ///
EEPROM.get(20, Bal); // считываем массив символов
delay(1000);
mySerial.println(String(F("AT+CUSD=1,#")) + Bal + String(F("#,15")));
Serial.println(String("Balance#") + Bal + "#");
}
void Masterphone() { /// === чтение мастер-номеров из EEPROM === ///
for (int i = 0; i < 5 ; i++) {
EEPROM.get(Adress[i], Phone); // считываем массив символов
AlarmPhone[i] = Phone;
if (AlarmPhone[i] != 0) {
Serial.println(String(F("Phone[")) + i + String(F("]:")) + AlarmPhone[i]);
}
Phone[12] = ""; // обнулим, больше не нужен
}
EEPROM.get(100, Phone); // считываем массив символов
RingPhone = Phone;
Serial.println(String(F("Ring [ ]:")) + RingPhone);
Phone[12] = ""; // обнулим, больше не нужен
EEPROM.get(20, Bal); // считываем массив символов
Serial.println(String(F("Balance:")) + Bal);
Firststart = EEPROM.read(10); // cчитаем из EEPROM
Serial.println(String(F("Firststart:")) + Firststart);
}
int sirena (int x) {
if (x < 601) { // если менее 10 мин, пишем
EEPROM.put(15, x);
Serial.println(String("Buz: ") + x + "sec");
sms(String(String("Sirena ") + x + "sec, ok"), String("+" + RingPhone)); // смс на 0 номер.
} else Serial.println("Max 600sec!");
}
int master (int i, String num) { /// === добавление мастер-номеров === ///
if (i < 5 && i != 0) {
num.toCharArray(Phone, 12); // конвертируем
AlarmPhone[i] = num; // пишем номер
Serial.println(String(F("Master[")) + i + String(F("]:")) + num);
EEPROM.put(Adress[i], Phone); // записываем массив в EEPROM
sms(String(String("Master") + i + ":" + num + " add"), String("+" + RingPhone)); // смс на 0 номер.
sms(String("Master: " + AlarmPhone[i]), String("+" + AlarmPhone[i])); // смс на добавленный номер.
Phone[12] = "";
} else Serial.println(F("MAX number 4!")); // 4 номера максимум!
// 0 номер можно удалить только через RESET!!!
}
int dellphone (int i) { /// === удаление мастар-номеров === ///
if (i < 5 && i != 0) {
Serial.println(String(F("Master")) + i + String(F(" dell")));
sms(String(String("Master") + i + ":" + AlarmPhone[i] + " dell"), String("+" + RingPhone)); // смс на 0 номер
sms(String("Dell: " + AlarmPhone[i]), String("+" + AlarmPhone[i])); // смс на удаленный номер.
EEPROM.put(Adress[i], 0);
AlarmPhone[i] = ""; // обнулим номер
}
}
int balnum (String num) { /// === добавляем номер баланса === ///
num.toCharArray(Bal, 4); // конвертируем
Serial.println(String(F("Balance:")) + Bal);
EEPROM.put(20, Bal); // записываем массив в EEPROM
sms(String("Balance:*" + num + "# Ok"), String("+" + RingPhone)); // смс на 0 номер
}
void TempC() { /// === измеряем температуру === ///
byte data[2];
ds.reset();
ds.write(0xCC);
ds.write(0x44);
delay(750);
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
data[0] = ds.read();
data[1] = ds.read();
int Temp = (data[1] << 8) + data[0];
Temp = Temp >> 4;
temp = String(F("Temp: ")) + Temp + String(F("*C."));
}
void Decode7bit(String &instr, String &outstr) { /// === декодирование баланса === ///
byte reminder = 0;
int bitstate = 7;
for (int i=0; i<instr.length(); i++) {
byte b = instr[i];
byte bb = b << (7 - bitstate);
char c = (bb + reminder) & 0x7F;
outstr += c;
reminder = b >> bitstate;
bitstate--;
if (bitstate == 0) {
char c = reminder;
outstr += c;
reminder = 0;
bitstate = 7;
}
}
}
void InitModem() { /// === инициализация модема === ///
Serial.println(F("Start GSM"));
mySerial.begin(9600); //Скорость порта для связи Arduino с GSM модулем
waitConnect();
Serial.println(F("GSM connected"));
waitRegistration();
delay(1000);
}
void waitConnect() { /// === запуск модема === ///
int countok = 0;
String str;
while(countok < 5) { //ждём пять ОК
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) {// Событие срабатывающее каждые 500 мс
msAT = ms;
// Serial.println(">>AT");
mySerial.println(F("AT")); // посылаем команду
str = "";
delay(100); // ждём ответа
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
// Serial.println("C>");
// Serial.println(str);
if(str.indexOf(F("OK")) > -1)
countok++;
else
countok = 0;
}
}
Serial.println(F("Turn on AOH:"));
mySerial.println(F("AT+CLIP=1")); // включить АОН
delay(200);
Serial.println(F("GSM registration"));
mySerial.println(F("AT+CMGF=1"));
delay(200);
Serial.println(F("Mode GSM:"));
mySerial.println(F("AT+CSCS=GSM")); // кодировка текста - GSM
delay(300);
mySerial.println(F("AT+CNMI=2,2,0,0,0"));
delay(300);
}
void waitRegistration() { /// === регистрация модема в сети === ///
bool ok = 0;
String str;
while(!ok) {
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) { // Событие срабатывающее каждые 500 мс
msAT = ms;
Serial.println(F(">>AT+CREG?"));
mySerial.println(F("AT+CREG?")); //посылаем команду
delay(100); //Ждём ответа
str = "";
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
Serial.println(F("R>"));
Serial.println(str);
if(str.indexOf(F("+CREG:"))>-1)
ok = 1;
}
}
}
void sms(String text, String phone) { /// === отправка СМС === ///
Serial.println(F("Start SMS send"));
mySerial.println(String(F("AT+CMGS=\"")) + phone + String(F("\"")));
delay(300);
mySerial.print(text);
delay(300);
mySerial.print((char)26);
delay(300);
Serial.println(String(F("SMS sended! Phone: ")) + phone + String(F("; Message: ")) + text);
delay(5000);
}
SMS команды управления:
reset - сброс на заводские (стираются все телл номера, номер баланса и сброс настроек).
master - добавление мастер номеров, имеет право добавить только мастер номер 0.
мастер номер 0 - первый позвонивший на сигнализацию.
пример: master1:79111234567 сохранить мастер номер 79111234567 в ячейку 1.
balance - номер баланса симкарты, имеет право добавить только мастер номер 0.
пример: balance:100 номер баланса *100#.
dell - удаление мастер номеров, кроме 0, имеет право добавить только мастер номер 0.
Эта ошибка выходит при компиляции последнего скетчя от pasha413. Непонимаю каким образом автор этого скетча скомпилировал его рас говорит (все работает, глюков нет)?
#include <EEPROM.h>
#include <OneWire.h>
#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
OneWire ds(12); // датчик температуры подключен к 9 пину, подтяжка 4.7кОм на +.
#define DOOR 4 // концевик двери.
#define PIR 5 // датчик движения.
#define Led 8 // состояние системы. моргает - на охране.
#define BUZ 10 // сирена.
#define GAS A0 // датчик дыма.
// DOOR - если сработал, на входе "+" HIGH.
// PIR - если сработал, на входе "+" HIGH.
// GAS - если сработал, на входе "+" HIGH.
// BUZ - если "-" LOW, то горит.
// Led - если "-" LOW, то горит.
int8_t Guard = 0; // 1. охрана: 1 - вкл, 0 - выкл.
int8_t AlarmRING = 1; // 2. вызов при сработке: 1 - вкл, 0 - выкл.
int8_t SendSMS = 1; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл.
int8_t DOORon = 1; // 4. контроль концевиков дверей: 1 - вкл, 0 - выкл.
int8_t PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл.
int8_t GASon = 1; // 6. контроль датчика дыма: 1 - вкл, 0 - выкл.
int8_t DOORFlag = 0; // флаг состояние датчика двери.
int8_t PIRFlag = 0; // флаг состояние датчика движения.
int8_t GASFlag = 0; // флаг состояние датчика газа.
int8_t DOORState = LOW; // Состояние концевика двери.
int8_t PIRState = LOW; // Состояние датчика движения.
int8_t LedState = HIGH; // Состояние светодиода.
int8_t Firststart; // первый старт.
uint32_t msAT = 0;
char Bal[4] = ""; // для временного хранения номера баланса.
char Phone[12] = ""; // для временного хранения номера телефона.
byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ.
String val; // переменная для хранения пришедших данных.
String temp; // переменная для хранения температуры.
String LastEvent; // полное состояние системы.
String RingPhone; // номер звонившего.
String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс.
int Smoky = LOW; // Состояние датчика газа.
int GASThres = 400; // предельная концентрация газа
int AlarmInterval = 10; // Секунд до отключения "тревожного" пина.
int interval = 1000; // для мигания Led
int previousMillis = 0;
int previousAlarmMillis = 0;
/* EEPROM Data:
№ ячейки - значение:
0 - если записана не 1, то необходимо затереть eeprom и восстановить стандартную конфигурацию.
1 - Guard = 0; // охрана: 0 - выкл.
2 - AlarmRING = 1; // звонок: 1 - вкл.
3 - SendSMS = 1; // отправка смс: 1 - вкл.
4 - DOORon = 1; // концевик двери: 1 - вкл.
5 - PIRon = 1; // датчик движения: 1 - вкл.
6 - GASon = 1; // датчик дыма: 1 - вкл.
7 -
8 -
9 -
10 - Firststars = 1; // первый запуск 1.
15 - AlarmInterval = 10 // время сирены
20 - ячейка памяти баланса,
25, 40, 55, 70, 85 - ячейки памяти телефонов.
100 - ячейка памяти номера последнего звонившего RingPhone.
*/
void setup() { /// настройка программы
Serial.begin(9600);
pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +.
pinMode(PIR, INPUT);
pinMode(GAS, INPUT);
pinMode(BUZ, OUTPUT);
pinMode(Led, OUTPUT);
digitalWrite(BUZ, HIGH); // сирена выкл.
digitalWrite(PIR, HIGH); // игнорируем при включении.
InitModem(); // запускаем инициализация модема.
eepromconfig();
digitalWrite(Led, HIGH); // гасим светодиод состояния сигнализации, сигнализация готова к работе.
}
void loop() { /// основной цикл программы.
LED(); // моргаем светодиодом.
AlarmPinOff(); // выключаем сирену, если прошло время.
Detect(); // проверяем датчики.
if (mySerial.available()) { // если GSM модем что-то послал.
while (mySerial.available()) { // сохраняем входную строку в переменную val.
char ch = mySerial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
if (val.indexOf(F("+CLIP")) > -1) { // если обнаружен вызов.
Serial.println(F("Process RING"));
delay(2000); // дадим гудок
mySerial.println(F("ATH")); // сбрасываем вызов.
if (CheckPhone() == 1) { // проверяем номер, если наш.
Serial.println(F("Master Ring OK!"));
MasterRing(); // меняем состояние охраны
} else Serial.println(F("No Master Ring!"));
} else if (val.indexOf(F("+CMT")) > -1) { // если обнаруженa СМС
Serial.println(F("Process CMT"));
Serial.println(String(F("SMS->")) + val); // что пришло в смс
if (CheckPhone() == 1) { // если СМС от хозяина
Serial.println(F("Master SMS OK!"));
MasterSMS();
} else Serial.println(F("No Master SMS!"));
} else if(val.indexOf(F("+CUSD:"))>-1) { // если пришел баланс
// команда проверки баланса AT+CUSD=1,#105#,15
// анализируем строку
int p1 = val.indexOf(F("\"")); // начало строки
int p2 = val.lastIndexOf(F("\"")); // конец строки
val = val.substring(p1+1,p2);
Serial.println("");
Serial.println(F("Input string:")); // пишем в порт пришедшую строку
Serial.println(val);
String decodestr;
Decode7bit(val, decodestr);
Serial.println("");
Serial.println(F("Decode string:")); // пишем в порт конвертированную строку
Serial.println(decodestr);
sms(String("SIM " + decodestr), String("+" + RingPhone)); // смс на последний звонивший
} val = "";
} if (Serial.available()) { // если в мониторе порта что-то ввели
while (Serial.available()) { // сохраняем входную строку в переменную val.
char ch = Serial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
ConsolePrint(); // запускаем консольную программу
val = "";
}
}
int CheckPhone() { /// === проверка телефона === ///
if (Firststart == 0) { // если не первый старт
for (int i = 0; i < 5; i++) {
if (val.indexOf(AlarmPhone[i]) > -1 && val.indexOf(AlarmPhone[i]) != 0) { // если есть вызов, и он наш
RingPhone = AlarmPhone[i]; // запоминаем его.
RingPhone.toCharArray(Phone, 12);
EEPROM.put(100, Phone); // записываем RingPhone в память.
// Serial.println(String(F("RingPhone ")) + RingPhone);
return 1; // возвращаем 1 - номер наш!
}
} Phone[12] = "";
return 0; // возвращаем 0 - номер не наш!
} else if (Firststart == 1) { // иначе (если первый старт)
// первый звонивший добавляется как основной мастер номер для управления сигнализацией
int ind = val.indexOf("+CLIP:") + 8; // обрезаем номер
String num = val.substring(ind, ind + 11);
num.toCharArray(Phone, 12);
EEPROM.put(25, Phone); // пишем номер в EEPROM
EEPROM.put(100, Phone); // записываем RingPhone в память.
AlarmPhone[0] = Phone; // запишем
RingPhone = Phone; // запоминаем его.
EEPROM.update(10, 0); // обновляем Firststart
Firststart = 0; // пишем 0
Serial.println(String(F("Master0:")) + AlarmPhone[0]);
Serial.println(String(F("Firststart:")) + Firststart);
sms(String("Master0:" + num + " Ok"), String("+" + num)); // смс на звонивший
// приходит смс в виде: " Master0:79111234567 Ok "
Phone[12] = "";
}
}
void eepromconfig() { /// === конфигурирование сигнализации === ///
pinMode(13, OUTPUT);
if (EEPROM.read(0) != 1) { // если записана не 1
for (int i = 0 ; i < 512 ; i++) { // переписываем все ячейки
EEPROM.write(i, 0);
} // и записываем:
EEPROM.update(1, 0); // Guard охрана выкл.
EEPROM.update(2, 1); // AlarmRING вызов вкл.
EEPROM.update(3, 1); // SendSMS смс вкл.
EEPROM.update(4, 1); // DOORon датчики дверей вкл.
EEPROM.update(5, 1); // PIRon датчик движения вкл.
EEPROM.update(6, 1); // GASon датчик газа вкл.
EEPROM.update(10, 1); // Firststart первый старт!.
EEPROM.update(15, 10); // время сирены.
EEPROM.update(20, 0); // баланс, записываем массив в EEPROM
EEPROM.update(0, 1); //
digitalWrite(13, HIGH);
Serial.println(F("EEPROM != 1/ RESET!"));
}
if (EEPROM.read(0) == 1) {
Guard = EEPROM.read(1); // Охрана
AlarmRING = EEPROM.read(2); // Вызов
SendSMS = EEPROM.read(3); // Отправка смс
DOORon = EEPROM.read(4); // Датчик двери
PIRon = EEPROM.read(5); // Датчик движения
GASon = EEPROM.read(6); // Датчик газа/дыма
Firststart = EEPROM.read(10); //
EEPROM.get(15, AlarmInterval); // время сирены.
Masterphone();
}
TempC();
String SIGN = ""; // текущее состояние системы.
String RING = ""; // текущее состояние вызов.
String SMS = ""; // текущее состояние смс.
String Door = ""; // текущее состояние датчика двери.
String Pir = ""; // текущее состояние датчика движения.
String Gas = ""; // текущее состояние датчика газа.
if (Guard == 1) SIGN = String(F("System ->on\n")); else (SIGN = String(F("System->off\n")));
if (AlarmRING == 1) RING = String(F("Ring->on\n")); else (RING = String(F("Ring->off\n")));
if (SendSMS == 1) SMS = String(F("SMS->on\n")); else (SMS = String(F("SMS->off\n")));
if (PIRon == 1) Pir = String(F("Pir->on\n")); else (Pir = String(F("Pir->off\n")));
if (DOORon == 1) Door = String(F("Door->on\n")); else (Door = String(F("Door->off\n")));
if (GASon == 1) Gas = String(F("Gas->on\n")); else (Gas = String(F("Gas->off\n")));
String AlarmBuz = String("Sirena: ") + AlarmInterval + "sec\n";
String System = SIGN + RING + SMS; // состояние (вкл/выкл) системы.
String Sensors = Pir + Door + Gas; // состояние (вкл/выкл) датчиков.
LastEvent = System + Sensors + AlarmBuz + temp; // полное состояние системы и датчиков.
Serial.println(LastEvent);
}
void Detect() { /// === чтение датчиков === ///
DOORState = digitalRead(DOOR);
PIRState = digitalRead(PIR);
Smoky = analogRead(GAS);
if (DOORon == 1) {
if (DOORState == HIGH && DOORFlag == 0) {
DOORFlag = 1;
Alarm(); //
}
if (DOORState == LOW && DOORFlag == 1) {
DOORFlag = 0;
}
}
if (PIRon == 1) {
if (PIRState == HIGH && PIRFlag == 0) {
PIRFlag = 1;
Alarm(); //
}
if (PIRState == LOW && PIRFlag == 1) {
PIRFlag = 0;
}
}
if (GASon == 1) {
if ((Smoky > GASThres) && GASFlag == 0) {
GASFlag = 1;
Alarm(); //
}
if ((Smoky < GASThres) && GASFlag == 1) {
GASFlag = 0;
}
}
}
void Alarm() { /// === запускаем сирену и отправку смс === ///
if (Guard == 1) {
previousAlarmMillis = millis();
digitalWrite(BUZ, LOW);
Serial.println(F("Alarm!!!"));
if (SendSMS == 1) {
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
if (DOORFlag == 1) {
Serial.println(F("Dver' otkrita!"));
sms(String("Dver' otkrita!"), String("+" + String(AlarmPhone[i]))); // смс на все номера
DOORFlag == 0;
}
if (PIRFlag == 1) {
Serial.println(F("Dvizhenie u dveri!"));
sms(String("Dvizhenie y dveri!"), String("+" + String(AlarmPhone[i])));
}
if (GASFlag == 1) {
Serial.println(F("Gas v dome!"));
sms(String("Gas v dome!"), String("+" + String(AlarmPhone[i]))); // смс на все номера
}
}
}
if (AlarmRING == 1) {
mySerial.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру
}
}
}
void AlarmPinOff() { /// === если прошло время, отключаем сирену === ///
uint16_t currentAlarmMillis = millis();
//if ((currentAlarmMillis - previousAlarmMillis > AlarmInterval * 1000)) {//Orig!
if (((currentAlarmMillis - previousAlarmMillis) / 1000 > AlarmInterval) || Guard == 0) {
digitalWrite(BUZ, HIGH);
// DOORFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
// PIRFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
// GASFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
}
}
void MasterRing() { /// === мастер звонков === //
if (Guard == 1) GuardOff(); // меняем состояние
else if (Guard == 0) GuardOn(); // меняем состояние
}
void GuardOff() { /// === выключение сигнализации === ///
Guard = 0;
EEPROM.update(1, Guard);
Serial.println(String(F("System->off. Ring:")) + RingPhone);
TempC();
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
sms(String("System->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
}
void GuardOn() { /// === включение сигнализации === ///
Guard = 1;
EEPROM.update(1, Guard);
Serial.println(String(F("System->on. Ring:")) + RingPhone);
TempC();
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
sms(String("System->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
}
void LED() { /// === состояние светодиода === ///
if (Guard == 1) { // если на охране
uint16_t currentMillis = millis(); // светодиод моргает
//проверяем не прошел ли нужный интервал, если прошел то
if (currentMillis - previousMillis > interval) {
// сохраняем время последнего переключения
previousMillis = currentMillis;
// если светодиод не горит, то зажигаем, и наоборот
if (LedState == HIGH) LedState = LOW;
else LedState = HIGH;
digitalWrite(Led, LedState);
}
} else digitalWrite(Led, HIGH); // иначе гасим его
}
void ConsolePrint() { /// === кончсольная программа === ///
val.toLowerCase();
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
master(val.substring(6, 7).toInt(), val.substring(8, 19));
// sms типа: " master1:79111234567 " - номер в ячейку "1", куда записать номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
balnum(val.substring(8, 13));
// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
dellphone(val.substring(5, 6).toInt());
// sms типа: " dell:1 " - удалить номер из ячейки 1
}
if (val.indexOf(F("reset")) > -1) { // сброс ЕЕПРОМ
Serial.println(F("Reset System!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
eepromconfig();
}
if (val.indexOf(F("sirena:")) > -1) {
sirena(val.substring(7, 10).toInt());
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("systemon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("systemoff")) > -1) { // выкл сигнализации
GuardOff();
}
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring->on"));
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring->off"));
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS->on"));
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS->off"));
}
if (val.indexOf(F("dooron")) > -1) { // выкл вызов при сработке
DOORon = 1;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->on"));
}
if (val.indexOf(F("dooroff")) > -1) { // выкл вызов при сработке
DOORon = 0;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->off"));
}
if (val.indexOf(F("piron")) > -1) { // выкл вызов при сработке
PIRon = 1;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->on"));
}
if (val.indexOf(F("piroff")) > -1) { // выкл вызов при сработке
PIRon = 0;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->off"));
}
if (val.indexOf(F("gason")) > -1) { // выкл вызов при сработке
GASon = 1;
EEPROM.update(6, GASon);
Serial.println(F("GAS->on"));
}
if (val.indexOf(F("gasoff")) > -1) { // выкл вызов при сработке
GASon = 0;
EEPROM.update(6, GASon);
Serial.println(F("GAS->off"));
}
}
void MasterSMS() { /// === мастер смс === ///
val.toLowerCase();
if (RingPhone == AlarmPhone[0]) { // команды выполняются только с 0 мастер номера
if (val.indexOf(F("reset")) > -1) { // полный сброс ЕЕПРОМ
sms(String("All System Reset!!!"), String("+" + RingPhone)); // смс на последний номер
Serial.println(F("Reset System!!!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
int tel(val.indexOf(F("master")));
master(val.substring(tel + 6, tel + 7).toInt(), val.substring(tel + 8, tel + 19));
///// sms типа: " master1:79111234567 " - ячейка + номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
int bal(val.indexOf(F("balance:")));
balnum(val.substring(bal + 8, bal + 11));
///// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
int del(val.indexOf(F("dell:")));
dellphone(val.substring(del + 5, del + 6).toInt());
///// sms типа: " dell:1 " - удалить номер из ячейки 1
}
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
eepromconfig();
sms(String(LastEvent), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("phone")) > -1) { // инфо о состоянии системы
Masterphone();
for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) {
sms(String(String("Master") + i + String(":") + AlarmPhone[i]), String("+" + RingPhone)); // смс на последний номер
}
}
if (val.indexOf(F("sirena:")) > -1) {
int buz(val.indexOf(F("sirena")));
sirena(val.substring(buz + 7, buz + 10).toInt());
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("systemon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("systemoff")) > -1) { // выкл сигнализации
GuardOff();
}
for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) { // смс на все номера
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing->on"));
sms(String("Ring->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing->off"));
sms(String("Ring->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS->on"));
sms(String("SMS->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS->off"));
sms(String("SMS->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("dooron")) > -1) { // выкл вызов при сработке
DOORon = 1;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->on"));
sms(String("DOOR->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("dooroff")) > -1) { // выкл вызов при сработке
DOORon = 0;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->off"));
sms(String("DOOR->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("piron")) > -1) { // выкл вызов при сработке
PIRon = 1;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->on"));
sms(String("PIR->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("piroff")) > -1) { // выкл вызов при сработке
PIRon = 0;
EEPROM.update(5, PIRon);
Serial.println(F("PIR -> off"));
sms(String("PIR -> off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("gason")) > -1) { // выкл вызов при сработке
GASon = 1;
EEPROM.update(6, GASon);
Serial.println(F("GAS->on"));
sms(String("GAS->on " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("gasoff")) > -1) { // выкл вызов при сработке
GASon = 0;
EEPROM.update(6, GASon);
Serial.println(F("GAS->off"));
sms(String("GAS->off " + RingPhone + "\n " + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
}
}
void balance() { /// === проверка баланса сим-карты === ///
EEPROM.get(20, Bal); // считываем массив символов
delay(1000);
mySerial.println(String(F("AT+CUSD=1,#")) + Bal + String(F("#,15")));
Serial.println(String("Balance#") + Bal + "#");
}
void Masterphone() { /// === чтение мастер-номеров из EEPROM === ///
for (int i = 0; i < 5 ; i++) {
EEPROM.get(Adress[i], Phone); // считываем массив символов
AlarmPhone[i] = Phone;
if (AlarmPhone[i] != 0) {
Serial.println(String(F("Phone[")) + i + String(F("]:")) + AlarmPhone[i]);
}
Phone[12] = ""; // обнулим, больше не нужен
}
EEPROM.get(100, Phone); // считываем массив символов
RingPhone = Phone;
Serial.println(String(F("Ring [ ]:")) + RingPhone);
Phone[12] = ""; // обнулим, больше не нужен
EEPROM.get(20, Bal); // считываем массив символов
Serial.println(String(F("Balance:")) + Bal);
Firststart = EEPROM.read(10); // cчитаем из EEPROM
Serial.println(String(F("Firststart:")) + Firststart);
}
int sirena (int x) {
if (x < 601) { // если менее 10 мин, пишем
EEPROM.put(15, x);
Serial.println(String("Buz: ") + x + "sec");
sms(String(String("Sirena ") + x + "sec, ok"), String("+" + RingPhone)); // смс на 0 номер.
} else Serial.println("Max 600sec!");
}
int master (int i, String num) { /// === добавление мастер-номеров === ///
if (i < 5 && i != 0) {
num.toCharArray(Phone, 12); // конвертируем
AlarmPhone[i] = num; // пишем номер
Serial.println(String(F("Master[")) + i + String(F("]:")) + num);
EEPROM.put(Adress[i], Phone); // записываем массив в EEPROM
sms(String(String("Master") + i + ":" + num + " add"), String("+" + RingPhone)); // смс на 0 номер.
sms(String("Master: " + AlarmPhone[i]), String("+" + AlarmPhone[i])); // смс на добавленный номер.
Phone[12] = "";
} else Serial.println(F("MAX number 4!")); // 4 номера максимум!
// 0 номер можно удалить только через RESET!!!
}
int dellphone (int i) { /// === удаление мастар-номеров === ///
if (i < 5 && i != 0) {
Serial.println(String(F("Master")) + i + String(F(" dell")));
sms(String(String("Master") + i + ":" + AlarmPhone[i] + " dell"), String("+" + RingPhone)); // смс на 0 номер
sms(String("Dell: " + AlarmPhone[i]), String("+" + AlarmPhone[i])); // смс на удаленный номер.
EEPROM.put(Adress[i], 0);
AlarmPhone[i] = ""; // обнулим номер
}
}
int balnum (String num) { /// === добавляем номер баланса === ///
num.toCharArray(Bal, 4); // конвертируем
Serial.println(String(F("Balance:")) + Bal);
EEPROM.put(20, Bal); // записываем массив в EEPROM
sms(String("Balance:*" + num + "# Ok"), String("+" + RingPhone)); // смс на 0 номер
}
void TempC() { /// === измеряем температуру === ///
byte data[2];
ds.reset();
ds.write(0xCC);
ds.write(0x44);
delay(750);
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
data[0] = ds.read();
data[1] = ds.read();
int Temp = (data[1] << 8) + data[0];
Temp = Temp >> 4;
temp = String(F("Temp: ")) + Temp + String(F("*C."));
}
void Decode7bit(String &instr, String &outstr) { /// === декодирование баланса === ///
byte reminder = 0;
int bitstate = 7;
for (int i=0; i<instr.length(); i++) {
byte b = instr[i];
byte bb = b << (7 - bitstate);
char c = (bb + reminder) & 0x7F;
outstr += c;
reminder = b >> bitstate;
bitstate--;
if (bitstate == 0) {
char c = reminder;
outstr += c;
reminder = 0;
bitstate = 7;
}
}
}
void InitModem() { /// === инициализация модема === ///
Serial.println(F("Start GSM"));
mySerial.begin(9600); //Скорость порта для связи Arduino с GSM модулем
waitConnect();
Serial.println(F("GSM connected"));
waitRegistration();
delay(1000);
}
void waitConnect() { /// === запуск модема === ///
int countok = 0;
String str;
while(countok < 5) { //ждём пять ОК
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) {// Событие срабатывающее каждые 500 мс
msAT = ms;
// Serial.println(">>AT");
mySerial.println(F("AT")); // посылаем команду
str = "";
delay(100); // ждём ответа
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
// Serial.println("C>");
// Serial.println(str);
if(str.indexOf(F("OK")) > -1)
countok++;
else
countok = 0;
}
}
Serial.println(F("Turn on AOH:"));
mySerial.println(F("AT+CLIP=1")); // включить АОН
delay(200);
Serial.println(F("GSM registration"));
mySerial.println(F("AT+CMGF=1"));
delay(200);
Serial.println(F("Mode GSM:"));
mySerial.println(F("AT+CSCS=GSM")); // кодировка текста - GSM
delay(300);
mySerial.println(F("AT+CNMI=2,2,0,0,0"));
delay(300);
}
void waitRegistration() { /// === регистрация модема в сети === ///
bool ok = 0;
String str;
while(!ok) {
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) { // Событие срабатывающее каждые 500 мс
msAT = ms;
Serial.println(F(">>AT+CREG?"));
mySerial.println(F("AT+CREG?")); //посылаем команду
delay(100); //Ждём ответа
str = "";
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
Serial.println(F("R>"));
Serial.println(str);
if(str.indexOf(F("+CREG:"))>-1)
ok = 1;
}
}
}
void sms(String text, String phone) { /// === отправка СМС === ///
Serial.println(F("Start SMS send"));
mySerial.println(String(F("AT+CMGS=\"")) + phone + String(F("\"")));
delay(300);
mySerial.print(text);
delay(300);
mySerial.print((char)26);
delay(300);
Serial.println(String(F("SMS sended! Phone: ")) + phone + String(F("; Message: ")) + text);
delay(5000);
}
То, что разработчики IDE выставили идиотские опции не означает, что это не ошибка. В строках 148 и 165 идёт распашка памяти. Можете не исправлять, если не хотите, но будьте готовы к необъяснимым глюкам программы.
В смысле. распашка?
В этих строках хотел обнулить переменную для временного хранения номера.
И, вообще, был бы благодарен за предложения по оптимизации кода с примерами.
прикручиваю ещё lcd 5110 для вывода информации.
Запомните, конструкция "Phone[12] = "";" Неправильна в принципе. При нормальных опциях компилятора - он выдал ошибку и был прав. В восьмых IDE разработчики задушили ошибки, чтобы типа лоха-юзера не беспокоить. Но, Вы хотя бы предупреждения включите! Зайдите в "Настройки", там есть "Предупреждения компилятора". По умолчанию стоит "None" или "Нет". Такая настройка только для страусов - чтоб голову в песок прятать. Включите. Читайте предупрежденя и думайте.
pasha413 пишет:
И, вообще, был бы благодарен за предложения по оптимизации кода с примерами.
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino: In function 'void Alarm()':
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino:265:20: warning: statement has no effect [-Wunused-value]
DOORFlag == 0;
^
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino: In function 'void AlarmPinOff()':
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino:286:58: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (((currentAlarmMillis - previousAlarmMillis) / 1000 > AlarmInterval) || Guard == 0) {
^
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino: In function 'void LED()':
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino:323:40: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
if (currentMillis - previousMillis > interval) {
^
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino: In function 'int sirena(int)':
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino:564:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino: In function 'int master(int, String)':
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino:577:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino: In function 'int dellphone(int)':
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino:587:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino: In function 'int balnum(String)':
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino:594:1: warning: no return statement in function returning non-void [-Wreturn-type]
}
^
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino: In function 'void Decode7bit(String&, String&)':
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino:615:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i=0; i<instr.length(); i++) {
^
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino: In function 'int CheckPhone()':
C:\Users\pzhukov\Documents\Arduino\projekt\arduino\GSM\Alarm\+Alarm eeprom\GSM-alarm_no_TEMP\GSM-alarm_no_TEMP.ino:169:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
Скетч использует 21142 байт (68%) памяти устройства. Всего доступно 30720 байт.
Глобальные переменные используют 773 байт (37%) динамической памяти, оставляя 1275 байт для локальных переменных. Максимум: 2048 байт.
закоментировал строки Phone[12] = "". все норм работает. в принципе смысла нет обнулять Phone[12]. т.к она по идее перезаписывается.
Ну, вот, видите. Большинство сообщений выглядит вполне себе тревожно и, скорее всего, говорят об ошибках. Не знаю, какой Вы код компилировали, так что посмотреть не могу. В л.бом случае такая портянка очень полезна. Это профессиональный подход, а не страусиный, который навязывают разработчики IDE.
А про "обнуление" мой пример попробовали? Не обнуляется? Вот, как-то так. Если Вам нужно "обнулить" строку, надо присвоить 0 её нулевому элементу (Phone[0] = 0; или, чуть более "кошерно" Phone[0] = '\0';). Попробуйте.
#include "Nokia_5110.h"
#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
Nokia_5110 lcd = Nokia_5110(8, 9, 10, 11, 12);
String val; // переменная для хранения пришедших данных.
void setup() {
mySerial.begin(9600); //Скорость порта для связи Arduino с GSM модулем
lcd.setContrast(50); // 60 is the default value set by the driver
lcd.clear();
lcd.print("boot...");
delay(3000);
}
void loop() {
lcd.clear();
lcd.print("waiting ring...");
delay(2000);
if (mySerial.available()) { // если GSM модем что-то послал.
while (mySerial.available()) { // сохраняем входную строку в переменную val.
char ch = mySerial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
if (val.indexOf(F("+CLIP")) > -1) { // если обнаружен вызов.
delay(2000); // дадим гудок
mySerial.println(F("ATH")); // сбрасываем вызов.
int ind = val.indexOf("+CLIP:"); // обрезаем номер
String num = val.substring(ind + 8, ind + 19);
lcd.clear();
lcd.print(num);
delay(2000);
}
} val = "";
}
а если вставить в мой код, то код перестает работать, смс не читает, и не отправляет
#include <EEPROM.h>
#include <OneWire.h>
#include "Nokia_5110.h"
#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
Nokia_5110 lcd = Nokia_5110(8, 9, 10, 11, 12);
OneWire ds(13); // датчик температуры подключен к 9 пину, подтяжка 4.7кОм на +.
#define DOOR 4 // концевик двери.
#define PIR 5 // датчик движения.
#define Led 6 // состояние системы. моргает - на охране.
#define BUZ 7 // сирена.
#define GAS A0 // датчик дыма.
// DOOR - если сработал, на входе "+" HIGH.
// PIR - если сработал, на входе "+" HIGH.
// GAS - если сработал, на входе "+" HIGH.
// BUZ - если "-" LOW, то горит.
// Led - если "-" LOW, то горит.
int8_t Guard = 0; // 1. охрана: 1 - вкл, 0 - выкл.
int8_t AlarmRING = 1; // 2. вызов при сработке: 1 - вкл, 0 - выкл.
int8_t SendSMS = 1; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл.
int8_t DOORon = 1; // 4. контроль концевиков дверей: 1 - вкл, 0 - выкл.
int8_t PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл.
int8_t GASon = 1; // 6. контроль датчика дыма: 1 - вкл, 0 - выкл.
int8_t DOORFlag = 0; // флаг состояние датчика двери.
int8_t PIRFlag = 0; // флаг состояние датчика движения.
int8_t GASFlag = 0; // флаг состояние датчика газа.
int8_t DOORState = LOW; // Состояние концевика двери.
int8_t PIRState = LOW; // Состояние датчика движения.
int8_t LedState = HIGH; // Состояние светодиода.
int8_t Firststart; // первый старт.
uint32_t msAT = 0;
char Bal[4] = ""; // для временного хранения номера баланса.
char Phone[12] = ""; // для временного хранения номера телефона.
byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ.
String val; // переменная для хранения пришедших данных.
String temp; // переменная для хранения температуры.
String LastEvent; // полное состояние системы.
String RingPhone; // номер звонившего.
String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс.
int Smoky = LOW; // Состояние датчика газа.
int GASThres = 400; // предельная концентрация газа
int AlarmInterval = 10; // Секунд до отключения "тревожного" пина.
int interval = 1000; // для мигания Led
int previousMillis = 0;
int previousAlarmMillis = 0;
extern uint8_t SmallFont[]; // малый шрифт (из библиотеки)
extern uint8_t MediumNumbers[]; // средний шрифт для цифр (из библиотеки)
int seconds = 0; // счётчик секунд
/* EEPROM Data:
№ ячейки - значение:
0 - если записана не 1, то необходимо затереть eeprom и восстановить стандартную конфигурацию.
1 - Guard = 0; // охрана: 0 - выкл.
2 - AlarmRING = 1; // звонок: 1 - вкл.
3 - SendSMS = 1; // отправка смс: 1 - вкл.
4 - DOORon = 1; // концевик двери: 1 - вкл.
5 - PIRon = 1; // датчик движения: 1 - вкл.
6 - GASon = 1; // датчик дыма: 1 - вкл.
7 -
8 -
9 -
10 - Firststars = 1; // первый запуск 1.
15 - AlarmInterval = 10 // время сирены
20 - ячейка памяти баланса,
25, 40, 55, 70, 85 - ячейки памяти телефонов.
100 - ячейка памяти номера последнего звонившего RingPhone.
*/
void setup() { /// настройка программы
Serial.begin(9600);
lcd.setContrast(50); // 60 is the default value set by the driver
lcd.clear();
lcd.print("boot...");
pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +.
pinMode(PIR, INPUT);
pinMode(GAS, INPUT);
pinMode(BUZ, OUTPUT);
pinMode(Led, OUTPUT);
digitalWrite(BUZ, HIGH); // сирена выкл.
digitalWrite(PIR, HIGH); // игнорируем при включении.
InitModem(); // запускаем инициализация модема.
eepromconfig();
digitalWrite(Led, HIGH); // гасим светодиод состояния сигнализации, сигнализация готова к работе.
}
void loop() { /// основной цикл программы.
lcd.clear();
lcd.print("waiting ring...");
delay(1000);
LED(); // моргаем светодиодом.
AlarmPinOff(); // выключаем сирену, если прошло время.
Detect(); // проверяем датчики.
if (mySerial.available()) { // если GSM модем что-то послал.
while (mySerial.available()) { // сохраняем входную строку в переменную val.
char ch = mySerial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
if (val.indexOf(F("+CLIP")) > -1) { // если обнаружен вызов.
Serial.println(F("Process RING"));
delay(2000); // дадим гудок
mySerial.println(F("ATH")); // сбрасываем вызов.
if (CheckPhone() == 1) { // проверяем номер, если наш.
Serial.println(F("Master Ring OK!"));
MasterRing(); // меняем состояние охраны
} else Serial.println(F("No Master Ring!"));
} else if (val.indexOf(F("+CMT")) > -1) { // если обнаруженa СМС
Serial.println(F("Process CMT"));
Serial.println(String(F("SMS->")) + val); // что пришло в смс
if (CheckPhone() == 1) { // если СМС от хозяина
Serial.println(F("Master SMS OK!"));
MasterSMS();
} else Serial.println(F("No Master SMS!"));
} else if(val.indexOf(F("+CUSD:"))>-1) { // если пришел баланс
// команда проверки баланса AT+CUSD=1,#105#,15
// анализируем строку
int p1 = val.indexOf(F("\"")); // начало строки
int p2 = val.lastIndexOf(F("\"")); // конец строки
val = val.substring(p1+1,p2);
Serial.println("");
Serial.println(F("Input string:")); // пишем в порт пришедшую строку
Serial.println(val);
String decodestr;
Decode7bit(val, decodestr);
Serial.println("");
Serial.println(F("Decode string:")); // пишем в порт конвертированную строку
Serial.println(decodestr);
sms(String("SIM " + decodestr), String("+" + RingPhone)); // смс на последний звонивший
} val = "";
} if (Serial.available()) { // если в мониторе порта что-то ввели
while (Serial.available()) { // сохраняем входную строку в переменную val.
char ch = Serial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
ConsolePrint(); // запускаем консольную программу
val = "";
}
}
int CheckPhone() { /// === проверка телефона === ///
if (Firststart == 0) { // если не первый старт
for (int i = 0; i < 5; i++) {
if (val.indexOf(AlarmPhone[i]) > -1 && val.indexOf(AlarmPhone[i]) != 0) { // если есть вызов, и он наш
RingPhone = AlarmPhone[i]; // запоминаем его.
RingPhone.toCharArray(Phone, 12);
EEPROM.put(100, Phone); // записываем RingPhone в память.
lcd.clear();
lcd.print(RingPhone);
delay(2000);
Serial.println(String(F("RingPhone ")) + RingPhone);
return 1; // возвращаем 1 - номер наш!
}
} Phone[12] = "";
return 0; // возвращаем 0 - номер не наш!
} else if (Firststart == 1) { // иначе (если первый старт)
// первый звонивший добавляется как основной мастер номер для управления сигнализацией
if (val.indexOf("+CLIP: \"7") > -1) {
int ind = val.indexOf("+CLIP:"); // обрезаем номер
String num = val.substring(ind + 8, ind + 19);
num.toCharArray(Phone, 12);
EEPROM.put(25, Phone); // пишем номер в EEPROM
EEPROM.put(100, Phone); // записываем RingPhone в память.
AlarmPhone[0] = Phone; // запишем
RingPhone = Phone; // запоминаем его.
EEPROM.update(10, 0); // обновляем Firststart
Firststart = 0; // пишем 0
Serial.println(String(F("Master0:")) + AlarmPhone[0]);
Serial.println(String(F("Firststart:")) + Firststart);
sms(String("Master0:" + num + " Ok"), String("+" + num)); // смс на звонивший
// приходит смс в виде: " Master0:79111234567 Ok "
Phone[12] = "";
}
}
}
void eepromconfig() { /// === конфигурирование сигнализации === ///
pinMode(13, OUTPUT);
if (EEPROM.read(0) != 1) { // если записана не 1
for (int i = 0 ; i < 512 ; i++) { // переписываем все ячейки
EEPROM.write(i, 0);
} // и записываем:
EEPROM.update(1, 0); // Guard охрана выкл.
EEPROM.update(2, 1); // AlarmRING вызов вкл.
EEPROM.update(3, 1); // SendSMS смс вкл.
EEPROM.update(4, 1); // DOORon датчики дверей вкл.
EEPROM.update(5, 1); // PIRon датчик движения вкл.
EEPROM.update(6, 1); // GASon датчик газа вкл.
EEPROM.update(10, 1); // Firststart первый старт!.
EEPROM.update(15, 10); // время сирены.
EEPROM.update(20, 0); // баланс, записываем массив в EEPROM
EEPROM.update(0, 1); //
digitalWrite(13, HIGH);
Serial.println(F("EEPROM != 1/ RESET!"));
}
if (EEPROM.read(0) == 1) {
Guard = EEPROM.read(1); // Охрана
AlarmRING = EEPROM.read(2); // Вызов
SendSMS = EEPROM.read(3); // Отправка смс
DOORon = EEPROM.read(4); // Датчик двери
PIRon = EEPROM.read(5); // Датчик движения
GASon = EEPROM.read(6); // Датчик газа/дыма
Firststart = EEPROM.read(10); //
EEPROM.get(15, AlarmInterval); // время сирены.
Masterphone();
}
TempC();
String SIGN = ""; // текущее состояние системы.
String RING = ""; // текущее состояние вызов.
String SMS = ""; // текущее состояние смс.
String Door = ""; // текущее состояние датчика двери.
String Pir = ""; // текущее состояние датчика движения.
String Gas = ""; // текущее состояние датчика газа.
if (Guard == 1) SIGN = String(F("System on\n")); else (SIGN = String(F("System off\n")));
if (AlarmRING == 1) RING = String(F("Ring on\n")); else (RING = String(F("Ring off\n")));
if (SendSMS == 1) SMS = String(F("SMS on\n")); else (SMS = String(F("SMS off\n")));
if (PIRon == 1) Pir = String(F("Pir on\n")); else (Pir = String(F("Pir off\n")));
if (DOORon == 1) Door = String(F("Door on\n")); else (Door = String(F("Door off\n")));
if (GASon == 1) Gas = String(F("Gas on\n")); else (Gas = String(F("Gas off\n")));
String AlarmBuz = String("Sirena: ") + AlarmInterval + "sec\n";
String System = SIGN + RING + SMS; // состояние (вкл/выкл) системы.
String Sensors = Pir + Door + Gas; // состояние (вкл/выкл) датчиков.
LastEvent = System + Sensors + AlarmBuz + temp; // полное состояние системы и датчиков.
Serial.println(LastEvent);
}
void Detect() { /// === чтение датчиков === ///
DOORState = digitalRead(DOOR);
PIRState = digitalRead(PIR);
Smoky = analogRead(GAS);
if (DOORon == 1) {
if (DOORState == HIGH && DOORFlag == 0) {
DOORFlag = 1;
Alarm(); //
}
if (DOORState == LOW && DOORFlag == 1) {
DOORFlag = 0;
}
}
if (PIRon == 1) {
if (PIRState == HIGH && PIRFlag == 0) {
PIRFlag = 1;
Alarm(); //
}
if (PIRState == LOW && PIRFlag == 1) {
PIRFlag = 0;
}
}
if (GASon == 1) {
if ((Smoky > GASThres) && GASFlag == 0) {
GASFlag = 1;
Alarm(); //
}
if ((Smoky < GASThres) && GASFlag == 1) {
GASFlag = 0;
}
}
}
void Alarm() { /// === запускаем сирену и отправку смс === ///
if (Guard == 1) {
previousAlarmMillis = millis();
digitalWrite(BUZ, LOW);
Serial.println(F("Alarm!!!"));
if (SendSMS == 1) {
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
if (DOORFlag == 1) {
Serial.println(F("Dver' otkrita!"));
sms(String("Dver' otkrita!"), String("+" + String(AlarmPhone[i]))); // смс на все номера
DOORFlag == 0;
}
if (PIRFlag == 1) {
Serial.println(F("Dvizhenie u dveri!"));
sms(String("Dvizhenie y dveri!"), String("+" + String(AlarmPhone[i])));
}
if (GASFlag == 1) {
Serial.println(F("Gas v dome!"));
sms(String("Gas v dome!"), String("+" + String(AlarmPhone[i]))); // смс на все номера
}
}
}
if (AlarmRING == 1) {
mySerial.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру
}
}
}
void AlarmPinOff() { /// === если прошло время, отключаем сирену === ///
uint16_t currentAlarmMillis = millis();
//if ((currentAlarmMillis - previousAlarmMillis > AlarmInterval * 1000)) {//Orig!
if (((currentAlarmMillis - previousAlarmMillis) / 1000 > AlarmInterval) || Guard == 0) {
digitalWrite(BUZ, HIGH);
// DOORFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
// PIRFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
// GASFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
}
}
void MasterRing() { /// === мастер звонков === //
if (Guard == 1) GuardOff(); // меняем состояние
else if (Guard == 0) GuardOn(); // меняем состояние
}
void GuardOff() { /// === выключение сигнализации === ///
Guard = 0;
EEPROM.update(1, Guard);
Serial.println(String(F("System->off. Ring:")) + RingPhone);
TempC();
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
sms(String("System->off " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
}
void GuardOn() { /// === включение сигнализации === ///
Guard = 1;
EEPROM.update(1, Guard);
Serial.println(String(F("System->on. Ring:")) + RingPhone);
TempC();
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
sms(String("System->on " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
}
void LED() { /// === состояние светодиода === ///
if (Guard == 1) { // если на охране
uint16_t currentMillis = millis(); // светодиод моргает
//проверяем не прошел ли нужный интервал, если прошел то
if (currentMillis - previousMillis > interval) {
// сохраняем время последнего переключения
previousMillis = currentMillis;
// если светодиод не горит, то зажигаем, и наоборот
if (LedState == HIGH) LedState = LOW;
else LedState = HIGH;
digitalWrite(Led, LedState);
}
} else digitalWrite(Led, HIGH); // иначе гасим его
}
void ConsolePrint() { /// === кончсольная программа === ///
val.toLowerCase();
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
master(val.substring(6, 7).toInt(), val.substring(8, 19));
// sms типа: " master1:79111234567 " - номер в ячейку "1", куда записать номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
balnum(val.substring(8, 13));
// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
dellphone(val.substring(5, 6).toInt());
// sms типа: " dell:1 " - удалить номер из ячейки 1
}
if (val.indexOf(F("reset")) > -1) { // сброс ЕЕПРОМ
Serial.println(F("Reset System!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
eepromconfig();
}
if (val.indexOf(F("sirena:")) > -1) {
sirena(val.substring(7, 10).toInt());
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("systemon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("systemoff")) > -1) { // выкл сигнализации
GuardOff();
}
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring->on"));
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring->off"));
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS->on"));
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS->off"));
}
if (val.indexOf(F("dooron")) > -1) { // выкл вызов при сработке
DOORon = 1;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->on"));
}
if (val.indexOf(F("dooroff")) > -1) { // выкл вызов при сработке
DOORon = 0;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->off"));
}
if (val.indexOf(F("piron")) > -1) { // выкл вызов при сработке
PIRon = 1;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->on"));
}
if (val.indexOf(F("piroff")) > -1) { // выкл вызов при сработке
PIRon = 0;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->off"));
}
if (val.indexOf(F("gason")) > -1) { // выкл вызов при сработке
GASon = 1;
EEPROM.update(6, GASon);
Serial.println(F("GAS->on"));
}
if (val.indexOf(F("gasoff")) > -1) { // выкл вызов при сработке
GASon = 0;
EEPROM.update(6, GASon);
Serial.println(F("GAS->off"));
}
}
void MasterSMS() { /// === мастер смс === ///
val.toLowerCase();
if (RingPhone == AlarmPhone[0]) { // команды выполняются только с 0 мастер номера
if (val.indexOf(F("reset")) > -1) { // полный сброс ЕЕПРОМ
sms(String("All System Reset!!!"), String("+" + RingPhone)); // смс на последний номер
Serial.println(F("Reset System!!!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
int tel(val.indexOf(F("master")));
master(val.substring(tel + 6, tel + 7).toInt(), val.substring(tel + 8, tel + 19));
///// sms типа: " master1:79111234567 " - ячейка + номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
int bal(val.indexOf(F("balance:")));
balnum(val.substring(bal + 8, bal + 11));
///// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
int del(val.indexOf(F("dell:")));
dellphone(val.substring(del + 5, del + 6).toInt());
///// sms типа: " dell:1 " - удалить номер из ячейки 1
}
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
eepromconfig();
sms(String(LastEvent), String("+" + RingPhone)); // смс на последний номер
}
if (val.indexOf(F("phone")) > -1) { // инфо о состоянии системы
Masterphone();
for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) {
sms(String(String("Master") + i + String(":") + AlarmPhone[i]), String("+" + RingPhone)); // смс на последний номер
}
}
if (val.indexOf(F("sirena:")) > -1) {
int buz(val.indexOf(F("sirena")));
sirena(val.substring(buz + 7, buz + 10).toInt());
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("systemon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("systemoff")) > -1) { // выкл сигнализации
GuardOff();
}
for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) { // смс на все номера
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing->on"));
sms(String("Ring->on " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing->off"));
sms(String("Ring->off " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS->on"));
sms(String("SMS->on " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS->off"));
sms(String("SMS->off " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("dooron")) > -1) { // выкл вызов при сработке
DOORon = 1;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->on"));
sms(String("DOOR->on " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("dooroff")) > -1) { // выкл вызов при сработке
DOORon = 0;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->off"));
sms(String("DOOR->off " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("piron")) > -1) { // выкл вызов при сработке
PIRon = 1;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->on"));
sms(String("PIR->on " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("piroff")) > -1) { // выкл вызов при сработке
PIRon = 0;
EEPROM.update(5, PIRon);
Serial.println(F("PIR -> off"));
sms(String("PIR -> off " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("gason")) > -1) { // выкл вызов при сработке
GASon = 1;
EEPROM.update(6, GASon);
Serial.println(F("GAS->on"));
sms(String("GAS->on " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
if (val.indexOf(F("gasoff")) > -1) { // выкл вызов при сработке
GASon = 0;
EEPROM.update(6, GASon);
Serial.println(F("GAS->off"));
sms(String("GAS->off " + RingPhone + "\n" + temp), String("+" + AlarmPhone[i])); // смс на все номера
}
}
}
void balance() { /// === проверка баланса сим-карты === ///
EEPROM.get(20, Bal); // считываем массив символов
delay(1000);
mySerial.println(String(F("AT+CUSD=1,#")) + Bal + String(F("#,15")));
Serial.println(String("Balance#") + Bal + "#");
}
void Masterphone() { /// === чтение мастер-номеров из EEPROM === ///
for (int i = 0; i < 5 ; i++) {
EEPROM.get(Adress[i], Phone); // считываем массив символов
AlarmPhone[i] = Phone;
if (AlarmPhone[i] != 0) {
Serial.println(String(F("Phone[")) + i + String(F("]:")) + AlarmPhone[i]);
}
Phone[12] = ""; // обнулим, больше не нужен
}
EEPROM.get(100, Phone); // считываем массив символов
RingPhone = Phone;
Serial.println(String(F("Ring [ ]:")) + RingPhone);
Phone[12] = ""; // обнулим, больше не нужен
EEPROM.get(20, Bal); // считываем массив символов
Serial.println(String(F("Balance:")) + Bal);
Firststart = EEPROM.read(10); // cчитаем из EEPROM
Serial.println(String(F("Firststart:")) + Firststart);
}
int sirena (int x) {
if (x < 601) { // если менее 10 мин, пишем
EEPROM.put(15, x);
Serial.println(String("Buz: ") + x + "sec");
sms(String(String("Sirena ") + x + "sec, ok"), String("+" + RingPhone)); // смс на 0 номер.
} else Serial.println("Max 600sec!");
}
int master (int i, String num) { /// === добавление мастер-номеров === ///
if (i < 5 && i != 0) {
num.toCharArray(Phone, 12); // конвертируем
AlarmPhone[i] = num; // пишем номер
Serial.println(String(F("Master[")) + i + String(F("]:")) + num);
EEPROM.put(Adress[i], Phone); // записываем массив в EEPROM
sms(String(String("Master") + i + ":" + num + " add"), String("+" + RingPhone)); // смс на 0 номер.
sms(String("Master: " + AlarmPhone[i]), String("+" + AlarmPhone[i])); // смс на добавленный номер.
Phone[12] = "";
} else Serial.println(F("MAX number 4!")); // 4 номера максимум!
// 0 номер можно удалить только через RESET!!!
}
int dellphone (int i) { /// === удаление мастар-номеров === ///
if (i < 5 && i != 0) {
Serial.println(String(F("Master")) + i + String(F(" dell")));
sms(String(String("Master") + i + ":" + AlarmPhone[i] + " dell"), String("+" + RingPhone)); // смс на 0 номер
sms(String("Dell: " + AlarmPhone[i]), String("+" + AlarmPhone[i])); // смс на удаленный номер.
EEPROM.put(Adress[i], 0);
AlarmPhone[i] = ""; // обнулим номер
}
}
int balnum (String num) { /// === добавляем номер баланса === ///
num.toCharArray(Bal, 4); // конвертируем
Serial.println(String(F("Balance:")) + Bal);
EEPROM.put(20, Bal); // записываем массив в EEPROM
sms(String("Balance:*" + num + "# Ok"), String("+" + RingPhone)); // смс на 0 номер
}
void TempC() { /// === измеряем температуру === ///
byte data[2];
ds.reset();
ds.write(0xCC);
ds.write(0x44);
delay(750);
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
data[0] = ds.read();
data[1] = ds.read();
int Temp = (data[1] << 8) + data[0];
Temp = Temp >> 4;
temp = String(F("Temp: ")) + Temp + String(F("*C."));
}
void Decode7bit(String &instr, String &outstr) { /// === декодирование баланса === ///
byte reminder = 0;
int bitstate = 7;
for (int i=0; i<instr.length(); i++) {
byte b = instr[i];
byte bb = b << (7 - bitstate);
char c = (bb + reminder) & 0x7F;
outstr += c;
reminder = b >> bitstate;
bitstate--;
if (bitstate == 0) {
char c = reminder;
outstr += c;
reminder = 0;
bitstate = 7;
}
}
}
void InitModem() { /// === инициализация модема === ///
Serial.println(F("Start GSM"));
mySerial.begin(9600); //Скорость порта для связи Arduino с GSM модулем
waitConnect();
Serial.println(F("GSM connected"));
waitRegistration();
delay(1000);
}
void waitConnect() { /// === запуск модема === ///
int countok = 0;
String str;
while(countok < 5) { //ждём пять ОК
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) {// Событие срабатывающее каждые 500 мс
msAT = ms;
// Serial.println(">>AT");
mySerial.println(F("AT")); // посылаем команду
str = "";
delay(100); // ждём ответа
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
// Serial.println("C>");
// Serial.println(str);
if(str.indexOf(F("OK")) > -1)
countok++;
else
countok = 0;
}
}
Serial.println(F("Turn on AOH:"));
mySerial.println(F("AT+CLIP=1")); // включить АОН
delay(200);
Serial.println(F("GSM registration"));
mySerial.println(F("AT+CMGF=1"));
delay(200);
Serial.println(F("Mode GSM:"));
mySerial.println(F("AT+CSCS=GSM")); // кодировка текста - GSM
delay(300);
mySerial.println(F("AT+CNMI=2,2,0,0,0"));
delay(300);
}
void waitRegistration() { /// === регистрация модема в сети === ///
bool ok = 0;
String str;
while(!ok) {
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) { // Событие срабатывающее каждые 500 мс
msAT = ms;
Serial.println(F(">>AT+CREG?"));
mySerial.println(F("AT+CREG?")); //посылаем команду
delay(100); //Ждём ответа
str = "";
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
Serial.println(F("R>"));
Serial.println(str);
if(str.indexOf(F("+CREG:"))>-1)
ok = 1;
}
}
}
void sms(String text, String phone) { /// === отправка СМС === ///
Serial.println(F("Start SMS send"));
mySerial.println(String(F("AT+CMGS=\"")) + phone + String(F("\"")));
delay(300);
mySerial.print(text);
delay(300);
mySerial.print((char)26);
delay(300);
Serial.println(String(F("SMS sended! Phone: ")) + phone + String(F("; Message: ")) + text);
delay(5000);
}
И, вообще, был бы благодарен за предложения по оптимизации кода
Паша, в качестве оптимизации кода - надо обязательно исправить ВСЕ! все ошибки из сообщения #279, ну и проверьте, не налепили ли новых, добавляя дисплей.
In function 'int sirena(int)':
.ino:566:1: warning: no return statement in function returning non-void [-Wreturn-type]
In function 'void Decode7bit(String&, String&)':
.ino:617:21: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
for (int i = 0; i < instr.length(); i++) {
вот код:
#include <EEPROM.h>
#include <OneWire.h>
#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
OneWire ds(12); // датчик температуры подключен к 9 пину, подтяжка 4.7кОм на +.
#define DOOR 4 // концевик двери.
#define PIR 5 // датчик движения.
#define Led 8 // состояние системы. моргает - на охране.
#define BUZ 10 // сирена.
#define GAS A0 // датчик дыма.
// DOOR - если сработал, на входе "+" HIGH.
// PIR - если сработал, на входе "+" HIGH.
// GAS - если сработал, на входе "+" HIGH.
// BUZ - если "-" LOW, то горит.
// Led - если "-" LOW, то горит.
int8_t Guard = 0; // 1. охрана: 1 - вкл, 0 - выкл.
int8_t AlarmRING = 1; // 2. вызов при сработке: 1 - вкл, 0 - выкл.
int8_t SendSMS = 1; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл.
int8_t DOORon = 1; // 4. контроль концевиков дверей: 1 - вкл, 0 - выкл.
int8_t PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл.
int8_t GASon = 1; // 6. контроль датчика дыма: 1 - вкл, 0 - выкл.
int8_t DOORFlag = 0; // флаг состояние датчика двери.
int8_t PIRFlag = 0; // флаг состояние датчика движения.
int8_t GASFlag = 0; // флаг состояние датчика газа.
int8_t DOORState = LOW; // Состояние концевика двери.
int8_t PIRState = LOW; // Состояние датчика движения.
int8_t LedState = HIGH; // Состояние светодиода.
int8_t Firststart; // первый старт.
uint32_t msAT = 0;
char Bal[4]; // для временного хранения номера баланса.
char Phone[12]; // для временного хранения номера телефона.
byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ.
String val; // переменная для хранения пришедших данных.
String temp; // переменная для хранения температуры.
String LastEvent; // полное состояние системы.
String RingPhone; // номер звонившего.
String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс.
int8_t Smoky = LOW; // Состояние датчика газа.
int GASThres = 400; // предельная концентрация газа
int8_t AlarmInterval = 10; // Секунд до отключения "тревожного" пина.
int interval = 1000; // для мигания Led
int8_t previousMillis = 0;
int8_t previousAlarmMillis = 0;
/* EEPROM Data:
№ ячейки - значение:
0 - если записана не 1, то необходимо затереть eeprom и восстановить стандартную конфигурацию.
1 - Guard = 0; // охрана: 0 - выкл.
2 - AlarmRING = 1; // звонок: 1 - вкл.
3 - SendSMS = 1; // отправка смс: 1 - вкл.
4 - DOORon = 1; // концевик двери: 1 - вкл.
5 - PIRon = 1; // датчик движения: 1 - вкл.
6 - GASon = 1; // датчик дыма: 1 - вкл.
7 -
8 -
9 -
10 - Firststars = 1; // первый запуск 1.
15 - AlarmInterval = 10 // время сирены
20 - ячейка памяти баланса,
25, 40, 55, 70, 85 - ячейки памяти телефонов.
100 - ячейка памяти номера последнего звонившего RingPhone.
*/
void setup() { /// настройка программы
Serial.begin(9600);
Serial.println(F("Alarm v1.2"));
pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +.
pinMode(PIR, INPUT);
pinMode(GAS, INPUT);
pinMode(BUZ, OUTPUT);
pinMode(Led, OUTPUT);
digitalWrite(BUZ, HIGH); // сирена выкл.
digitalWrite(PIR, HIGH); // игнорируем при включении.
InitModem(); // запускаем инициализация модема.
eepromconfig();
digitalWrite(Led, HIGH); // гасим светодиод состояния сигнализации, сигнализация готова к работе.
}
void loop() { /// основной цикл программы.
LED(); // моргаем светодиодом.
AlarmPinOff(); // выключаем сирену, если прошло время.
Detect(); // проверяем датчики.
if (mySerial.available()) { // если GSM модем что-то послал.
while (mySerial.available()) { // сохраняем входную строку в переменную val.
char ch = mySerial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
if (val.indexOf(F("+CLIP")) > -1) { // если обнаружен вызов.
Serial.println(F("Process RING"));
delay(2000); // дадим гудок
mySerial.println(F("ATH")); // сбрасываем вызов.
if (CheckPhone() == 1) { // проверяем номер, если наш.
Serial.println(F("Master Ring OK!"));
MasterRing(); // меняем состояние охраны
} else Serial.println(F("No Master Ring!"));
} else if (val.indexOf(F("+CMT")) > -1) { // если обнаруженa СМС
Serial.println(F("Process CMT"));
Serial.println(String(F("SMS->")) + val); // что пришло в смс
if (CheckPhone() == 1) { // если СМС от хозяина
Serial.println(F("Master SMS OK!"));
MasterSMS();
} else Serial.println(F("No Master SMS!"));
} else if(val.indexOf(F("+CUSD:"))>-1) { // если пришел баланс
// команда проверки баланса AT+CUSD=1,#105#,15
// анализируем строку
int p1 = val.indexOf(F("\"")); // начало строки
int p2 = val.lastIndexOf(F("\"")); // конец строки
val = val.substring(p1+1,p2);
Serial.println("");
Serial.println(F("Input string:")); // пишем в порт пришедшую строку
Serial.println(val);
String decodestr;
Decode7bit(val, decodestr);
Serial.println("");
Serial.println(F("Decode string:")); // пишем в порт конвертированную строку
Serial.println(decodestr);
sms(("SIM " + decodestr), RingPhone); // смс на последний звонивший
} val = "";
} if (Serial.available()) { // если в мониторе порта что-то ввели
while (Serial.available()) { // сохраняем входную строку в переменную val.
char ch = Serial.read();
val += char(ch); // собираем принятые символы в строку
delay(3);
}
ConsolePrint(); // запускаем консольную программу
val = "";
}
}
int CheckPhone() { /// === проверка телефона === ///
if (Firststart == 0) { // если не первый старт
for (int i = 0; i < 5; i++) {
if (val.indexOf(AlarmPhone[i]) > -1 && val.indexOf(AlarmPhone[i]) != 0) { // если есть вызов, и он наш
RingPhone = AlarmPhone[i]; // запоминаем его.
RingPhone.toCharArray(Phone, 12);
EEPROM.put(100, Phone); // записываем RingPhone в память.
// Serial.println(String(F("RingPhone ")) + RingPhone);
return 1; // возвращаем 1 - номер наш!
}
} // Phone[12] = "";
return 0; // возвращаем 0 - номер не наш!
} else if (Firststart == 1) { // иначе (если первый старт)
// первый звонивший добавляется как основной мастер номер для управления сигнализацией
if (val.indexOf("+CLIP: \"7") > -1) {
int ind = val.indexOf("+CLIP:") + 8; // обрезаем номер
String num = val.substring(ind, ind + 11);
num.toCharArray(Phone, 12);
EEPROM.put(25, Phone); // пишем номер в EEPROM
EEPROM.put(100, Phone); // записываем RingPhone в память.
AlarmPhone[0] = Phone; // запишем
RingPhone = Phone; // запоминаем его.
EEPROM.update(10, 0); // обновляем Firststart
Firststart = 0; // пишем 0
Serial.println(String(F("Master0:")) + AlarmPhone[0]);
Serial.println(String(F("Firststart:")) + Firststart);
sms(("Master0:" + RingPhone + " Ok"), RingPhone); // смс на звонивший
// приходит смс в виде: " Master0:79111234567 Ok "
// Phone[12] = "";
}
}
}
void eepromconfig() { /// === конфигурирование сигнализации === ///
pinMode(13, OUTPUT);
if (EEPROM.read(0) != 1) { // если записана не 1
for (int i = 0 ; i < 512 ; i++) { // переписываем все ячейки
EEPROM.write(i, 0);
} // и записываем:
EEPROM.update(1, 0); // Guard охрана выкл.
EEPROM.update(2, 1); // AlarmRING вызов вкл.
EEPROM.update(3, 1); // SendSMS смс вкл.
EEPROM.update(4, 1); // DOORon датчики дверей вкл.
EEPROM.update(5, 1); // PIRon датчик движения вкл.
EEPROM.update(6, 1); // GASon датчик газа вкл.
EEPROM.update(10, 1); // Firststart первый старт!.
EEPROM.update(15, 10); // время сирены.
EEPROM.update(20, 0); // баланс, записываем массив в EEPROM
EEPROM.update(0, 1); //
digitalWrite(13, HIGH);
Serial.println(F("EEPROM != 1/ RESET!"));
}
if (EEPROM.read(0) == 1) {
Guard = EEPROM.read(1); // Охрана
AlarmRING = EEPROM.read(2); // Вызов
SendSMS = EEPROM.read(3); // Отправка смс
DOORon = EEPROM.read(4); // Датчик двери
PIRon = EEPROM.read(5); // Датчик движения
GASon = EEPROM.read(6); // Датчик газа/дыма
Firststart = EEPROM.read(10); //
EEPROM.get(15, AlarmInterval); // время сирены.
Masterphone();
}
TempC();
String SIGN = ""; // текущее состояние системы.
String RING = ""; // текущее состояние вызов.
String SMS = ""; // текущее состояние смс.
String Door = ""; // текущее состояние датчика двери.
String Pir = ""; // текущее состояние датчика движения.
String Gas = ""; // текущее состояние датчика газа.
if (Guard == 1) SIGN = String(F("System ->on\n")); else (SIGN = String(F("System->off\n")));
if (AlarmRING == 1) RING = String(F("Ring->on\n")); else (RING = String(F("Ring->off\n")));
if (SendSMS == 1) SMS = String(F("SMS->on\n")); else (SMS = String(F("SMS->off\n")));
if (PIRon == 1) Pir = String(F("Pir->on\n")); else (Pir = String(F("Pir->off\n")));
if (DOORon == 1) Door = String(F("Door->on\n")); else (Door = String(F("Door->off\n")));
if (GASon == 1) Gas = String(F("Gas->on\n")); else (Gas = String(F("Gas->off\n")));
String AlarmBuz = String("Sirena: ") + AlarmInterval + "sec\n";
String System = SIGN + RING + SMS; // состояние (вкл/выкл) системы.
String Sensors = Pir + Door + Gas; // состояние (вкл/выкл) датчиков.
LastEvent = System + Sensors + AlarmBuz + temp; // полное состояние системы и датчиков.
Serial.println(LastEvent);
}
void Detect() { /// === чтение датчиков === ///
DOORState = digitalRead(DOOR);
PIRState = digitalRead(PIR);
Smoky = analogRead(GAS);
if (DOORon == 1) {
if (DOORState == HIGH && DOORFlag == 0) {
DOORFlag = 1;
Alarm(); //
}
if (DOORState == LOW && DOORFlag == 1) {
DOORFlag = 0;
}
}
if (PIRon == 1) {
if (PIRState == HIGH && PIRFlag == 0) {
PIRFlag = 1;
Alarm(); //
}
if (PIRState == LOW && PIRFlag == 1) {
PIRFlag = 0;
}
}
if (GASon == 1) {
if ((Smoky > GASThres) && GASFlag == 0) {
GASFlag = 1;
Alarm(); //
}
if ((Smoky < GASThres) && GASFlag == 1) {
GASFlag = 0;
}
}
}
void Alarm() { /// === запускаем сирену и отправку смс === ///
if (Guard == 1) {
previousAlarmMillis = millis();
digitalWrite(BUZ, LOW);
Serial.println(F("Alarm!!!"));
if (SendSMS == 1) {
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
if (DOORFlag == 1) {
Serial.println(F("Dver' otkrita!"));
sms("Dver' otkrita!", AlarmPhone[i]); // смс на все номера
////// DOORFlag == 0;
}
if (PIRFlag == 1) {
Serial.println(F("Dvizhenie u dveri!"));
sms("Dvizhenie y dveri!", AlarmPhone[i]);
}
if (GASFlag == 1) {
Serial.println(F("Gas v dome!"));
sms("Gas v dome!", AlarmPhone[i]); // смс на все номера
}
}
}
if (AlarmRING == 1) {
mySerial.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру
}
}
}
void AlarmPinOff() { /// === если прошло время, отключаем сирену === ///
int8_t currentAlarmMillis = millis();
//if ((currentAlarmMillis - previousAlarmMillis > AlarmInterval * 1000)) {//Orig!
if (((currentAlarmMillis - previousAlarmMillis) / 1000 > AlarmInterval) || Guard == 0) {
digitalWrite(BUZ, HIGH);
// DOORFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
// PIRFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
// GASFlag = 0; //?????? чтоб не отправлять лишних смс о ложных срабатываниях
}
}
void MasterRing() { /// === мастер звонков === //
if (Guard == 1) GuardOff(); // меняем состояние
else if (Guard == 0) GuardOn(); // меняем состояние
}
void GuardOff() { /// === выключение сигнализации === ///
Guard = 0;
EEPROM.update(1, Guard);
Serial.println(String(F("System->off. Ring:")) + RingPhone);
TempC();
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
sms(("System->off " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
}
void GuardOn() { /// === включение сигнализации === ///
Guard = 1;
EEPROM.update(1, Guard);
Serial.println(String(F("System->on. Ring:")) + RingPhone);
TempC();
for (int i = 0; i < 5; i++) if (AlarmPhone[i] != 0) {
sms(("System->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
}
void LED() { /// === состояние светодиода === ///
if (Guard == 1) { // если на охране
int8_t currentMillis = millis(); // светодиод моргает
//проверяем не прошел ли нужный интервал, если прошел то
if (currentMillis - previousMillis > interval) {
// сохраняем время последнего переключения
previousMillis = currentMillis;
// если светодиод не горит, то зажигаем, и наоборот
if (LedState == HIGH) LedState = LOW;
else LedState = HIGH;
digitalWrite(Led, LedState);
}
} else digitalWrite(Led, HIGH); // иначе гасим его
}
void ConsolePrint() { /// === кончсольная программа === ///
val.toLowerCase();
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
master(val.substring(6, 7).toInt(), val.substring(8, 19));
// sms типа: " master1:79111234567 " - номер в ячейку "1", куда записать номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
balnum(val.substring(8, 13));
// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
dellphone(val.substring(5, 6).toInt());
// sms типа: " dell:1 " - удалить номер из ячейки 1
}
if (val.indexOf(F("reset")) > -1) { // сброс ЕЕПРОМ
Serial.println(F("Reset System!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
eepromconfig();
}
if (val.indexOf(F("sirena:")) > -1) {
sirena(val.substring(7, 10).toInt());
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("systemon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("systemoff")) > -1) { // выкл сигнализации
GuardOff();
}
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring->on"));
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("Ring->off"));
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS->on"));
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SMS->off"));
}
if (val.indexOf(F("dooron")) > -1) { // выкл вызов при сработке
DOORon = 1;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->on"));
}
if (val.indexOf(F("dooroff")) > -1) { // выкл вызов при сработке
DOORon = 0;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->off"));
}
if (val.indexOf(F("piron")) > -1) { // выкл вызов при сработке
PIRon = 1;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->on"));
}
if (val.indexOf(F("piroff")) > -1) { // выкл вызов при сработке
PIRon = 0;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->off"));
}
if (val.indexOf(F("gason")) > -1) { // выкл вызов при сработке
GASon = 1;
EEPROM.update(6, GASon);
Serial.println(F("GAS->on"));
}
if (val.indexOf(F("gasoff")) > -1) { // выкл вызов при сработке
GASon = 0;
EEPROM.update(6, GASon);
Serial.println(F("GAS->off"));
}
}
void MasterSMS() { /// === мастер смс === ///
val.toLowerCase();
if (RingPhone == AlarmPhone[0]) { // команды выполняются только с 0 мастер номера
if (val.indexOf(F("reset")) > -1) { // полный сброс ЕЕПРОМ
sms("All System Reset!!!", RingPhone); // смс на последний номер
Serial.println(F("Reset System!!!"));
EEPROM.write(0, 0);
eepromconfig();
}
if (val.indexOf(F("master")) > -1) { // добавление мастер-номера
int tel(val.indexOf(F("master")));
master(val.substring(tel + 6, tel + 7).toInt(), val.substring(tel + 8, tel + 19));
///// sms типа: " master1:79111234567 " - ячейка + номер
}
if (val.indexOf(F("balance:")) > -1) { // добавление номера баланса
int bal(val.indexOf(F("balance:")));
balnum(val.substring(bal + 8, bal + 11));
///// sms типа: " balance:100 " - номер баланса
}
if (val.indexOf(F("dell:")) > -1) { // удаление номера из ячейки
int del(val.indexOf(F("dell:")));
dellphone(val.substring(del + 5, del + 6).toInt());
///// sms типа: " dell:1 " - удалить номер из ячейки 1
}
}
if (val.indexOf(F("info")) > -1) { // инфо о состоянии системы
eepromconfig();
sms(LastEvent, RingPhone); // смс на последний номер
}
if (val.indexOf(F("phone")) > -1) { // инфо о состоянии системы
Masterphone();
for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) {
sms((("Master") + i + String(":") + AlarmPhone[i]), RingPhone); // смс на последний номер
}
}
if (val.indexOf(F("sirena:")) > -1) {
int buz(val.indexOf(F("sirena")));
sirena(val.substring(buz + 7, buz + 10).toInt());
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("systemon")) > -1) { // вкл сигнализации
GuardOn();
}
if (val.indexOf(F("systemoff")) > -1) { // выкл сигнализации
GuardOff();
}
for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) { // смс на все номера
if (val.indexOf(F("ringon")) > -1) { // вкл вызов при сработке
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing->on"));
sms(("Ring->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
if (val.indexOf(F("ringoff")) > -1) { // выкл вызов при сработке
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
Serial.println(F("AlarmRing->off"));
sms(("Ring->off " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
if (val.indexOf(F("smson")) > -1) { // вкл смс при сработке
SendSMS = 1;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS->on"));
sms(("SMS->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
if (val.indexOf(F("smsoff")) > -1) { // выкл смс при сработке
SendSMS = 0;
EEPROM.update(3, SendSMS);
Serial.println(F("SendSMS->off"));
sms(("SMS->off " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
if (val.indexOf(F("dooron")) > -1) { // выкл вызов при сработке
DOORon = 1;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->on"));
sms(("DOOR->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
if (val.indexOf(F("dooroff")) > -1) { // выкл вызов при сработке
DOORon = 0;
EEPROM.update(4, DOORon);
Serial.println(F("DOOR->off"));
sms(("DOOR->off " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
if (val.indexOf(F("piron")) > -1) { // выкл вызов при сработке
PIRon = 1;
EEPROM.update(5, PIRon);
Serial.println(F("PIR->on"));
sms(("PIR->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
if (val.indexOf(F("piroff")) > -1) { // выкл вызов при сработке
PIRon = 0;
EEPROM.update(5, PIRon);
Serial.println(F("PIR -> off"));
sms(("PIR -> off " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
if (val.indexOf(F("gason")) > -1) { // выкл вызов при сработке
GASon = 1;
EEPROM.update(6, GASon);
Serial.println(F("GAS->on"));
sms(("GAS->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
if (val.indexOf(F("gasoff")) > -1) { // выкл вызов при сработке
GASon = 0;
EEPROM.update(6, GASon);
Serial.println(F("GAS->off"));
sms(("GAS->off " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
////sms((val + RingPhone + "\n " + temp), AlarmPhone[i]); // смс на все номера
}
}
}
void balance() { /// === проверка баланса сим-карты === ///
EEPROM.get(20, Bal); // считываем массив символов
delay(1000);
mySerial.println(String(F("AT+CUSD=1,#")) + Bal + String(F("#,15")));
Serial.println(String("Balance#") + Bal + "#");
}
void Masterphone() { /// === чтение мастер-номеров из EEPROM === ///
for (int i = 0; i < 5 ; i++) {
EEPROM.get(Adress[i], Phone); // считываем массив символов
AlarmPhone[i] = Phone;
if (AlarmPhone[i] != 0) {
Serial.println(String(F("Phone[")) + i + String(F("]:")) + AlarmPhone[i]);
}
// Phone[12] = ""; // обнулим, больше не нужен
}
EEPROM.get(100, Phone); // считываем массив символов
RingPhone = Phone;
Serial.println(String(F("Ring [ ]:")) + RingPhone);
// Phone[12] = ""; // обнулим, больше не нужен
EEPROM.get(20, Bal); // считываем массив символов
Serial.println(String(F("Balance:")) + Bal);
Firststart = EEPROM.read(10); // cчитаем из EEPROM
Serial.println(String(F("Firststart:")) + Firststart);
}
int sirena (int x) {
if (x < 601) { // если менее 10 мин, пишем
EEPROM.put(15, x);
Serial.println(String("Buz: ") + x + "sec");
sms((String("Sirena ") + x + "sec, ok"), RingPhone); // смс на 0 номер.
} else Serial.println("Max 600sec!");
}
int master (int i, String num) { /// === добавление мастер-номеров === ///
if (i < 5 && i != 0) {
num.toCharArray(Phone, 12); // конвертируем
AlarmPhone[i] = num; // пишем номер
Serial.println(String(F("Master[")) + i + String(F("]:")) + num);
EEPROM.put(Adress[i], Phone); // записываем массив в EEPROM
sms((String("Master") + i + ":" + num + " add"), RingPhone); // смс на 0 номер.
sms(("Master: " + AlarmPhone[i]), AlarmPhone[i]); // смс на добавленный номер.
// Phone[12] = "";
} else Serial.println(F("MAX number 4!")); // 4 номера максимум!
// 0 номер можно удалить только через RESET!!!
}
int dellphone (int i) { /// === удаление мастар-номеров === ///
if (i < 5 && i != 0) {
Serial.println(String(F("Master")) + i + String(F(" dell")));
sms((String("Master") + i + ":" + AlarmPhone[i] + " dell"), RingPhone); // смс на 0 номер
sms(("Dell: " + AlarmPhone[i]), AlarmPhone[i]); // смс на удаленный номер.
EEPROM.put(Adress[i], 0);
AlarmPhone[i] = ""; // обнулим номер
}
}
int balnum (String num) { /// === добавляем номер баланса === ///
num.toCharArray(Bal, 4); // конвертируем
Serial.println(String(F("Balance:")) + Bal);
EEPROM.put(20, Bal); // записываем массив в EEPROM
sms(("Balance:*" + num + "# Ok"), RingPhone); // смс на 0 номер
}
void TempC() { /// === измеряем температуру === ///
byte data[2];
ds.reset();
ds.write(0xCC);
ds.write(0x44);
delay(750);
ds.reset();
ds.write(0xCC);
ds.write(0xBE);
data[0] = ds.read();
data[1] = ds.read();
int Temp = (data[1] << 8) + data[0];
Temp = Temp >> 4;
temp = String(F("Temp: ")) + Temp + String(F("*C."));
}
void Decode7bit(String &instr, String &outstr) { /// === декодирование баланса === ///
byte reminder = 0;
int bitstate = 7;
for (int i = 0; i < instr.length(); i++) {
byte b = instr[i];
byte bb = b << (7 - bitstate);
char c = (bb + reminder) & 0x7F;
outstr += c;
reminder = b >> bitstate;
bitstate--;
if (bitstate == 0) {
char c = reminder;
outstr += c;
reminder = 0;
bitstate = 7;
}
}
}
void InitModem() { /// === инициализация модема === ///
Serial.println(F("Start GSM"));
mySerial.begin(9600); //Скорость порта для связи Arduino с GSM модулем
waitConnect();
Serial.println(F("GSM connected"));
waitRegistration();
delay(1000);
}
void waitConnect() { /// === запуск модема === ///
int countok = 0;
String str;
while(countok < 5) { //ждём пять ОК
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) {// Событие срабатывающее каждые 500 мс
msAT = ms;
// Serial.println(">>AT");
mySerial.println(F("AT")); // посылаем команду
str = "";
delay(100); // ждём ответа
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
// Serial.println("C>");
// Serial.println(str);
if(str.indexOf(F("OK")) > -1)
countok++;
else
countok = 0;
}
}
Serial.println(F("Turn on AOH:"));
mySerial.println(F("AT+CLIP=1")); // включить АОН
delay(200);
Serial.println(F("GSM registration"));
mySerial.println(F("AT+CMGF=1"));
delay(200);
Serial.println(F("Mode GSM:"));
mySerial.println(F("AT+CSCS=GSM")); // кодировка текста - GSM
delay(300);
mySerial.println(F("AT+CNMI=2,2,0,0,0"));
delay(300);
}
void waitRegistration() { /// === регистрация модема в сети === ///
bool ok = 0;
String str;
while(!ok) {
uint32_t ms = millis();
if( ( ms - msAT ) > 500 || ms < msAT ) { // Событие срабатывающее каждые 500 мс
msAT = ms;
Serial.println(F(">>AT+CREG?"));
mySerial.println(F("AT+CREG?")); //посылаем команду
delay(100); //Ждём ответа
str = "";
while(mySerial.available()) {
char ch = mySerial.read();
str += ch;
}
Serial.println(F("R>"));
Serial.println(str);
if(str.indexOf(F("+CREG:"))>-1)
ok = 1;
}
}
}
void sms(String text, String phone) { /// === отправка СМС === ///
phone = "+" + phone;
Serial.println(F("Start SMS send"));
mySerial.println(String(F("AT+CMGS=\"")) + phone + String(F("\"")));
delay(300);
mySerial.print(text);
delay(300);
mySerial.print((char)26);
delay(300);
Serial.println(String(F("SMS sended! Phone: ")) + phone + String(F("; Message: ")) + text);
delay(5000);
}
Я посмотрел ваш код. Довольно таки не плохо получается. Есть один затык в коде. Отсутствует проверка на обнуление милис нужно одну строчку добавить. Могу подсказать какую если хотите... И ещё возможно не заметил удаление входящих смс, память у модема не безразмерная, там одной командой делается...
И кстати я не совсем понял на каком модеме вы настраиваете? Ссылочку если можно)))
модем Ai-Thinker A6, заметил что у него лучше сигнал. Сейчас пришел A6C с камерой.
про удаление смс знаю. команда AT+CMGD=1,4 , но смс не сохраняются в память, а сразу выводятся в терминал. В любом случае подтверждение смс команд с ответным смс от сигнализации.
Вот тот первая строчка проверка на сброс милис http://arduino.ru/forum/programmirovanie/millis-sbrasyvaetsya-na-nol-pri...
У меня без проверки чуть котел зимой не разорвало, насос не включился..
И да по поводу сохранённых смс там есть команда вывести цыфру количества смс-ок, у меня на sim800 она почему-то постоянно увеличивается )))
Вот тот первая строчка проверка на сброс милис http://arduino.ru/forum/programmirovanie/millis-sbrasyvaetsya-na-nol-pri...
У меня без проверки чуть котел зимой не разорвало, насос не включился..
И да по поводу сохранённых смс там есть команда вывести цыфру количества смс-ок, у меня на sim800 она почему-то постоянно увеличивается )))
Real Time Clock считаю что не подходит так как модуль может глюкануть и каким будет реакция на это у ардуинки трудно предусмотреть.
По прерыванию я не советчик особо не пользовался этим, но можно почитать на форуме много тем по прерыванию.
b707 если подскажете как написать проверку времени чтобы не проверять обнуление буду тоже использовать а сам до сих пор пользовался проверкой. Не утверждаю что это правильно но знаю что это точно помогает...
замучились с модемом М590 и новый модем А6 тоже не работает? -если читаете тем же кодом, что в сообщении #165 - не удивительно. Код чтения СМС весьма бредовый
Обьясните, зачем нужны задержки? Первая слишком велика - буфер SoftwareSerial всего 64 байта. пока вы будете ждать 200мс, есть шанс что он переполнится. Вторая задержка еще нелепей - 50 мс ПОСЛЕ КАЖДОГО СИМВОЛА! Если у вас типичная СМС вместе с технической информацией 200 символов - вы будете читать ее 10 секунд! Да у вас половина данных должна теряться при таком темпе работы сериала.- что, собственно, у вас и происходит.
Задержки вообще удалять? Этот код чтения не раз уже попадался в интернете, ничего другого не знаю. Есть другой вариант?
Кодов чтения СМС в инете полно. С такими задержками не видел. Для примера посмотрите любую библиотеку для любого GSM-модема - код чтения СМС практически одинаков у любого модема.
Первую задержку можете оставить, но я бы снизил до 20-50мс. Больше не имеет смысла - у вас буфер приема 64 байта. посчитайте, за сколько он заполнится при скорости 9600. Вторую надо убрать ОБЯЗАТЕЛЬНО. Или, хотя бы - поставить минимальную, 2-3 (не более 5) мс.
А вообще, вам на будущее. То, что в вашем коде вы ждете фиксированное время, чтобы от модема пришла полная строка - гнилая на корню идея. Инфа из модема может приходить с перерывами, а может выплевываться по несколько сообщений разом. Надо читать и разбирать то, что пришло - и если пришло не все, ждать, пока из модема придет остальное. Опять же, примеров полно в любой подобной библиотеке.
ЗЫ собираю свой микропроект на модеме А6, если будут вопросы по этому модему - спрашивайте
b707, спасибо, в выходные займусь проектом.
как проверить баланс на А6? никак не получается. на команду "ATD#105#;" (теле2) выдает +CME ERROR:500
на команду AT+CUSD=1,"*101#",15 приходит ответ
на модеме А6mini работает.
добавление/удаление номера отрабатывает. смс проверял не все, не разобрался с запросом баланса. если кто знает как, подскажите.
как проверить баланс на А6?
на команду AT+CUSD=1,"*101#",15 приходит ответ
Это и есть ответ, только он хитро закодирован.
Посмотрите вот эту тему начиная с 13 сообщения
http://arduino.ru/forum/apparatnye-voprosy/gsm-a6-vopros-pro-ring
Спасибо, почитаю
разобрался с балансом (напомню, модем A6). датчики пока не проверял, но проверил все смс, всё работает.
единственное мастер номера каждый отправляет отдельным sms, как их объединить чтоб приходило в одном смс и выглядело так:
master0:79111234567
master1:79112645321
так считываю номера:
А вот весь код:
замечания и предложения приветствуются!
в каком режиме должен работать датчик движения? там два режима: Н и L. При Н датчик дает сигнал постоянно пока есть движение в зоне обнаружения. При режиме L обнаружение движение регистрируется задержкой выставленной подстроечником. после срабатывания сигнал прерывается и датчик переходит в режим калибровки примерно 3 секунды. дальше по новой. Вы в "натуре" откатывали программу? просто у меня почему то датчик тупо вешает программу после 2-3 срабатываний. после датчик вообще не как не реагирует на движение. Программный сброс счетчика
не срабатывает.
Ещё вопрос по поводу PIN13- Зачем он нужен?
кусок программы с датчиками проверял около месяца назад - все работало. сейчас все собрать в кучу нехватает датчика движения.
PIN13 в принципе незнаю зачем я его использовал при записи/чтении из ЕЕПРОМ. в ближайшее время попробую все собрать в кучу
Ruslan_Kulibin.
у меня PIR датчик в режиме L, оба подстроечника в 0, влево.
решил убрать из ЕЕПРОМ "PIRDetectCount", оставил только:
необходимо поудалять везде где он использовался,
и попробуйте заменить кусок кода:
и добавьте в конец процедуры void GuardOff() строку:
Тема заглоха или как, просто давно небыло комментариев. pasha413 скажите есть ли модихикация, или оптимизация в Вашем коде?
Пока тестирую, нашел ещё несколько косяков в скетче. единственное не разобрался по поводу отправки всех мастер номеров в одном смс?
я человек не жадный, и поэтому вот моя протестированная в домашних условия версия (на макетке), все работает, глюков нет, буду паять на плату и в корпус для полевых испытаний. Arduino nano 328p + Ai-Thinker A6.
SMS команды управления:
reset - сброс на заводские (стираются все телл номера, номер баланса и сброс настроек).
master - добавление мастер номеров, имеет право добавить только мастер номер 0.
мастер номер 0 - первый позвонивший на сигнализацию.
пример: master1:79111234567 сохранить мастер номер 79111234567 в ячейку 1.
balance - номер баланса симкарты, имеет право добавить только мастер номер 0.
пример: balance:100 номер баланса *100#.
dell - удаление мастер номеров, кроме 0, имеет право добавить только мастер номер 0.
пример: dell:2 удалить номер в ячейке 0.
info - информация о состоянии системы.
phone - информация о прописанных мастер номерах.
sirena - время сирены при сработке
пример: sirena:60 время звучания сирены 1мин
money - проверка баланса SIM
systemon / systemoff - вкл/выкл сигнализации.
ringon / ringoff - вкл/выкл вызова при сработке сигнализации.
smson / smsoff - вкл/выкл смс информирования при сработке сигнализации, инфо смс доступны.
dooron / dooroff - вкл/выкл контроля датчика двери.
piron / piroff - вкл/выкл контроля датчика движения.
gason / gasoff - вкл/выкл контроля датчика дыма/газа.
команды в консоли аналогичны смс командам.
Что не так? Где ошибка? Arduino IDE 1.6.6
функцию sms можно посмотреть?
Что не так? Где ошибка? Arduino IDE 1.6.6
Phone[12] - одиночный символ, а Вы пытаетесь ему присвоить строку "". В этом и ошибка.
Эта ошибка выходит при компиляции последнего скетчя от pasha413. Непонимаю каким образом автор этого скетча скомпилировал его рас говорит (все работает, глюков нет)?
Ну, это к автору. Суть ошибки я Вам объяснил, исправлять её Вы, как я понял, самостоятельно не планируете. Тогда к автору.
Благодарю за ответ. Попробую исправить сам!
У меня норм компиллируется, 1.8.2 версия ide
Компиляция прошла
Подтверждаю на ide 1.8.2 всё откомпилировалось. Странно почему на версиях 1.6.5 и 16.6 выдаёт ошибку при компиляции.
То, что разработчики IDE выставили идиотские опции не означает, что это не ошибка. В строках 148 и 165 идёт распашка памяти. Можете не исправлять, если не хотите, но будьте готовы к необъяснимым глюкам программы.
В смысле. распашка?
В этих строках хотел обнулить переменную для временного хранения номера.
И, вообще, был бы благодарен за предложения по оптимизации кода с примерами.
прикручиваю ещё lcd 5110 для вывода информации.
И Вы, конечно, проверяли обнуляется она или нет? Попробуйте запустить вот такой скетч
Как видите, ни хрена не обнуляется.
Запомните, конструкция "Phone[12] = "";" Неправильна в принципе. При нормальных опциях компилятора - он выдал ошибку и был прав. В восьмых IDE разработчики задушили ошибки, чтобы типа лоха-юзера не беспокоить. Но, Вы хотя бы предупреждения включите! Зайдите в "Настройки", там есть "Предупреждения компилятора". По умолчанию стоит "None" или "Нет". Такая настройка только для страусов - чтоб голову в песок прятать. Включите. Читайте предупрежденя и думайте.
Спасибо.
включил подробные сообщения компиллятора. выдало:
закоментировал строки Phone[12] = "". все норм работает. в принципе смысла нет обнулять Phone[12]. т.к она по идее перезаписывается.
Ну, вот, видите. Большинство сообщений выглядит вполне себе тревожно и, скорее всего, говорят об ошибках. Не знаю, какой Вы код компилировали, так что посмотреть не могу. В л.бом случае такая портянка очень полезна. Это профессиональный подход, а не страусиный, который навязывают разработчики IDE.
А про "обнуление" мой пример попробовали? Не обнуляется? Вот, как-то так. Если Вам нужно "обнулить" строку, надо присвоить 0 её нулевому элементу (Phone[0] = 0; или, чуть более "кошерно" Phone[0] = '\0';). Попробуйте.
не складывается в LCD5110. пример работает:
а если вставить в мой код, то код перестает работать, смс не читает, и не отправляет
вроде как подружил LCD5110, но наворотил конечно....
переназначил порты.
Паша, в качестве оптимизации кода - надо обязательно исправить ВСЕ! все ошибки из сообщения #279, ну и проверьте, не налепили ли новых, добавляя дисплей.
остались только
вот код:
Так исправьте, чего сюда-то вываливать.
Молодцы ребята, схему не скиньте как и что подключали?
#define DOOR 4 // концевик двери. Какой геркон тут используете? Питание 5 вольт на них или 12 и через промежуточное реле?
#define PIR 5 // датчик движения. Какой датчик используете ? Ссылочку можно?
#define Led 8 // состояние системы. моргает - на охране. Это обычный светодиод ?
#define BUZ 10 // сирена. Активный или пассивный буззер?
#define GAS A0 // датчик дыма. Какой датчик задымления? Тоже бы ссылочка не помешала.
датчик двери - геркон нормально замкнутый, одним концом на "-" второй на 4pin.
PIR датчик движения - HC-SR501 с установкой потенциометров в минимум.
сечас пришел PIRmini.
работает на расстоянии до 3м,
для моих нужн самое то.
Led - светодиод через резистор 330 Ом на "+5V", вторым концом 8pin.
BUZ - сирена, на время теста стоит светодиод через резистор 330 Ом на "+5V", вторым концом 10pin,
далее будет 5V реле, контакты реле подают 12V на сирену.
GAS - датчик широкого спектра газов MQ-2, подключен аналоговый пин, цифровой не используется.
со ссылками пока не могу помочь. все бралось давно, найти по названию проще некуда
схему постараюсь чуть позже накидать.
Я посмотрел ваш код. Довольно таки не плохо получается. Есть один затык в коде. Отсутствует проверка на обнуление милис нужно одну строчку добавить. Могу подсказать какую если хотите... И ещё возможно не заметил удаление входящих смс, память у модема не безразмерная, там одной командой делается...
И кстати я не совсем понял на каком модеме вы настраиваете? Ссылочку если можно)))
конечно. подскажите.
модем Ai-Thinker A6, заметил что у него лучше сигнал. Сейчас пришел A6C с камерой.
про удаление смс знаю. команда
AT+CMGD=1,4
, но
смс не сохраняются в память, а сразу выводятся в терминал. В любом случае подтверждение смс команд с ответным смс от сигнализации.Вот тот первая строчка проверка на сброс милис http://arduino.ru/forum/programmirovanie/millis-sbrasyvaetsya-na-nol-pri...
У меня без проверки чуть котел зимой не разорвало, насос не включился..
И да по поводу сохранённых смс там есть команда вывести цыфру количества смс-ок, у меня на sim800 она почему-то постоянно увеличивается )))
Вот тот первая строчка проверка на сброс милис http://arduino.ru/forum/programmirovanie/millis-sbrasyvaetsya-na-nol-pri...
У меня без проверки чуть котел зимой не разорвало, насос не включился..
И да по поводу сохранённых смс там есть команда вывести цыфру количества смс-ок, у меня на sim800 она почему-то постоянно увеличивается )))
Кто-нибудь, когда-нибудь запретит заменять батарейки?
на модеме А6 по умолчанию смс не сохраняются в память
есть интересная штука "Real Time Clock", как раз можно работать без millis(). но пока не разобрался...
А если сделать прерывание для мигания и сирены:
Real Time Clock считаю что не подходит так как модуль может глюкануть и каким будет реакция на это у ардуинки трудно предусмотреть.
По прерыванию я не советчик особо не пользовался этим, но можно почитать на форуме много тем по прерыванию.
Не тиражируйте бред, если правильно написать проверку времени, "сброс millis" проверять не нужно.
на модеме А6 по умолчанию смс не сохраняются в память
Паша, это легко настраивается. Я вам уже писал - у меня на А6 СМС отлично сохраняются.
есть интересная штука "Real Time Clock", как раз можно работать без millis(). но пока не разобрался...
где, в А6? - да есть. Но у нее время при ресете сбрасывается, так что за ним нужно следить. А так да, удобная вещь, у меня в коде используется.
Вот по RTC почитать.
http://microsin.net/programming/avr/avr134-real-time-clock-with-asynchro...
b707 если подскажете как написать проверку времени чтобы не проверять обнуление буду тоже использовать а сам до сих пор пользовался проверкой. Не утверждаю что это правильно но знаю что это точно помогает...
Dell