Добрый день. Программирование только начал осваивать, потому может допустил где-то ошибки. На основе вашего скетча, с использованием примеров и других проэктов, немного переделал сигналку.
Добавлено следующее:
- кнопка вкл/выкл охраны;
- кнопка откл датчиков на 25 минут, если на охране;
- двохцветный светодиод: индикация контроля датчиков в режиме охраны - зеленый; контроль отключен на охране - красный; контроль срабатывания датчиков не на охране - оранжевый;
- контроль питающего напряжения сети с смс уведомлением.
Если есть ошибки, ткните носом где и желательно пояснить почему и в какую сторону грести.
#include <EEPROM.h>
#include <SoftwareSerial.h>
#define Ver F("Alarm v4.3.3_UK_Phone[12]\n")
SoftwareSerial gsm(2, 3); // модем подключен к 7 и 8 пинам.
#define DOOR 4 // пин 4. концевик двери.
#define PIR 5 // пин 5. датчик движения.
#define LED 6 // пин 6. состояние системы.
#define Ac_pin A0 // пин А0. контроль 220
#define BUZ 7 // пин 7. сирена.
#define LEDDetect 11 // пин 11. контроль датчиков вкл.
#define LEDTimer 10 // пин 10. контроль датчиков откл.
#define BUTTON1 8 // пин 8. кнопка постановки/снятия с охраны
#define BUTTON2 9 // пин 9. кнопка откл датчиков на 25 мин
#define on "on" // вкл
#define off "off" // выкл
int8_t ModemID = 0; // тип модема
boolean Guard = 0; // 1. охрана: 1 - вкл, 0 - выкл.
boolean AlarmRING = 1; // 2. вызов при сработке: 1 - вкл, 0 - выкл.
boolean SendSMS = 1; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл.
boolean DOORon = 1; // 4. контроль концевика двери: 1 - вкл, 0 - выкл.
boolean PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл.
boolean Sirena = 1; // 7. сирена: 1 - вкл, 0 - выкл.
boolean Firststart = 1; // первый старт.
boolean DOORFlag = 0; // флаг состояние датчика двери.
boolean PIRFlag = 0; // флаг состояние датчика движения.
int8_t DOORState = HIGH; // Состояние концевика двери.
int8_t PIRState = HIGH; // Состояние датчика движения.
int8_t LEDState = LOW; // Состояние светодиода.
boolean sendsmscaller = 1; // разрешение отправки смс.
int ac_sended = 0; // Отправлено сообщение о пропадании напряжения
int ac_sended_on = 0; //Отправлено сообщение о появлении напряжения
int acv = 200; // Пороговое напряжение питания 220В
int buttonState; // текущее состояние кнопки
int lastButtonState = LOW; // предыдущее состояние кнопки
unsigned long lastDebounceTime = 0; // время последнего переключения
unsigned long debounceDelay = 50;
unsigned long time;
uint32_t msAT = 0;
char CSQ[4]; // для хранения уровня сигнала
char Bal[4]; // для временного хранения номера баланса.
char Phone[13]; // для временного хранения номера телефона.
String AT[] = {"AT+CLIP=1", "AT+CMGF=1", "AT+CSCS=\"GSM\"", "AT+CNMI=2,2,0,0,0", "AT+CREG?"}; // общие АТ команды
#define AT_M590 F("AT+CUSD=1") // баланс для М590
#define AT_SIM800_A6 F("AT+CUSD=1,#") // баланс для А6 и СИМ800
String RingPhone = ""; // номер звонившего.
String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс.
byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ.
int p = 0;
#define interval_alarm 20 // Секунд до отключения "тревожного" пина.
int previousMillis_alarm = 0;
#define interval_led 1000 // для мигания LED, 1 сек.
int previousMillis_led = 0;
#define interval_door 10 // секунд не смотрим на датчик двери.
int previousMillis_door = 0;
#define interval_pir 20 // секунд не смотрим на датчик движения.
int previousMillis_pir = 0;
void setup() { /// === настройка программы === ///
Serial.begin(9600);
Serial.println(Ver);
pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +.
pinMode(PIR, INPUT_PULLUP); // вход датчика движения с подтяжкой на +.
pinMode(BUZ, OUTPUT);
pinMode(LED, OUTPUT);
pinMode(LEDTimer, OUTPUT);
pinMode(LEDDetect, OUTPUT);
pinMode(BUTTON1, INPUT); // кнопка1
pinMode(BUTTON2, INPUT); // кнопка2
digitalWrite(BUZ, LOW); // сирена выкл.
digitalWrite(PIR, LOW); // игнорируем при включении.
digitalWrite(LEDTimer, LOW);
digitalWrite(LEDDetect, LOW);
InitModem(); // запускаем инициализация модема.
eepromconfig();
Serial.println(eepromphone());
Signal();
Serial.println(eepromtext() + F("\nSignal seti: ") + CSQ ); // закомментировать если смс
sms(eepromtext() + F("\nSignal seti: ") + CSQ + "%", 0); // смс на последний номер
digitalWrite(LED, LOW); // гасим светодиод состояния сигнализации.
}
void loop() { /// === основной цикл программы === ///
AlarmPinOff(); // выключаем сирену, если прошло время.
Button1(); // проверяем кнопку1.
Button2(); // проверяем кнопку2.
LedDetect();
if (Guard == 1) { // если на охране
Detect(); // проверяем датчики.
Led(); // моргаем светодиодом.
}
if (gsm.available()) { // Если модем, что-то отправил...
sendsmscaller = 1;
String gval = ""; // Переменная для хранения ответа модуля
if (gsm.available()) { // если GSM модем что-то послал.
while (gsm.available()) { // сохраняем входную строку в переменную val.
char ch = gsm.read();
gval += char(ch); // собираем принятые символы в строку
delay(3);
}
}
if (gval.indexOf(F("+PBREADY")) > -1) InitModem();
else if (gval.indexOf(F("+CLIP")) > -1) { // если обнаружен вызов.
Serial.println(F("Process RING"));
delay(2000);
int ind = gval.indexOf(F("+CLIP: \"")); // обрезаем номер
ind += 8; // Парсим строку и
String ring = gval.substring(ind, gval.indexOf("\"", ind));
Serial.println(String(F("RingPhone->")) + ring);
if (CheckPhone(ring) == 1) {sendATCommand("ATH", true); // сбрасываем вызов
Serial.println(F("Master Ring OK!"));
MasterRing();
} else sendATCommand("ATA", true);
} else if (gval.indexOf(F("+CMT")) > -1) { // если обнаруженa СМС
Serial.println(F("Process CMT"));
parsesms(gval);
} else if(gval.indexOf(F("+CUSD:")) > -1) { // если пришел баланс
Serial.println(F("Process USD"));
Serial.println("gval1 " + gval);
String bal = "";
if (ModemID == 3) {
int p1 = gval.indexOf("\""); // начало строки
int p2 = gval.lastIndexOf("\""); // конец строки
gval = gval.substring(p1 + 1, p2);
Decode7bit(gval, bal);
sendATCommand(F("AT+CUSD=0"), true);
} else if (ModemID == 1 || 2) {
bal = String(gval.substring(gval.indexOf("\"") + 1,gval.indexOf("\","))); //
}
sendATCommand(F("AT+CUSD=0"), true);
sms(String(F("Sim ")) + bal, 0);
}
} else if (Serial.available()) { // если в мониторе порта что-то ввели
String sval = "";
while (Serial.available()) { // сохраняем входную строку в переменную val.
char ch = Serial.read();
sval += char(ch); // собираем принятые символы в строку
delay(3);
}
sendsmscaller = 0;
Komand(sval); // запускаем консольную программу
// sendsmscaller = 1;
}
}
String waitgsm() { // Функция ожидания ответа и возврата полученного результата
String gsmval = ""; // Переменная для хранения результата
uint32_t _timeout = millis() + 5000; // Переменная для отслеживания таймаута (10 секунд)
while (!gsm.available() && (millis() < _timeout)) {}; // Ждем ответа5 секунд, если пришел ответ или наступил таймаут, то...
if (gsm.available()) { // если GSM модем что-то послал.
while (gsm.available()) { // сохраняем входную строку в переменную val.
char ch = gsm.read();
gsmval += char(ch); // собираем принятые символы в строку
delay(5);
}
} else { // Если пришел таймаут, то...
Serial.println(F("Timeout...")); // ... оповещаем об этом и...
}
return gsmval; // ... возвращаем результат. Пусто, если проблема
}
void parsesms(String msg) {
String msgheader = "";
String msgsms = "";
String msgphone = "";
msg = msg.substring(msg.indexOf("+CMT: "));
msgheader = msg.substring(0,msg.indexOf("\r")); // Выдергиваем телефон
msgsms = msg.substring(msgheader.length() + 2);
msgsms = msgsms.substring(0, msgsms.lastIndexOf("OK")); // Выдергиваем текст SMS
msgsms.trim();
int Index = msgheader.indexOf("+CMT:");
msgphone = msgheader.substring(Index + 8, Index + 20);
msgphone.trim();
Serial.println("Phone: " + msgphone); // Выводим номер телефона
Serial.println("Message: " + msgsms); // Выводим текст SMS
if (CheckPhone(msgphone) == 1) { // если СМС от хозяина
Serial.println(F("Master SMS OK!"));
Komand(msgsms);
} else Serial.println(F("No Master SMS!"));
}
int CheckPhone(String phone) { /// === проверка телефона === ///
if (Firststart == 0) { // если не первый старт
for (int i = 0; i < 5; i++) {
if (phone == AlarmPhone[i] && phone != 0) { // если есть вызов, и он наш
phone = AlarmPhone[i]; // запоминаем его.
RingPhone = AlarmPhone[i]; // запоминаем его.
RingPhone.toCharArray(Phone, 13);
EEPROM.put(100, Phone); // записываем RingPhone в память.
Serial.println(String(F("RingPhone ")) + RingPhone);
return 1; // возвращаем 1 - номер наш!
}
} return 0; // возвращаем 0 - номер не наш!
} else if (Firststart == 1) { // иначе (если первый старт)
// первый звонивший добавляется как основной мастер номер для управления сигнализацией
phone.toCharArray(Phone, 13);
EEPROM.put(25, Phone); // пишем номер в EEPROM
EEPROM.put(100, Phone); // записываем RingPhone в память.
AlarmPhone[0] = Phone; // запишем
RingPhone = Phone; // запоминаем его.
EEPROM.update(10, 0); // обновляем Firststart
Firststart = 0; // пишем 0
Serial.println(String(F("Firststart:")) + Firststart);
sms(String(F("Master0->")) + phone + " Add", 0); // смс на звонивший
// приходит смс в виде: " Master0:79111234567 Ok "
} return 1;
}
void eepromconfig() { /// === конфигурирование сигнализации === ///
if (EEPROM.read(0) != 1) { // если записана не 1
for (int i = 0 ; i < 512 ; i++) { // переписываем все ячейки
EEPROM.write(i, 0);
} // и записываем:
EEPROM.update(1, 0); // Guard охрана выкл.
EEPROM.update(2, 1); // AlarmRING вызов вкл.
EEPROM.update(3, 1); // SendSMS смс вкл.
EEPROM.update(4, 1); // DOORon датчики дверей вкл.
EEPROM.update(6, 1); // PIRon датчик движения вкл.
EEPROM.update(8, 1); // Sirena сирена вкл.
EEPROM.update(10, 1); // Firststart первый старт!.
EEPROM.update(20, 0); // баланс, записываем массив в EEPROM
EEPROM.update(0, 1); //
Serial.println(F("EEPROM != 1/ RESET!"));
} if (EEPROM.read(0) == 1) {
Guard = EEPROM.read(1); // Охрана
AlarmRING = EEPROM.read(2); // Вызов
SendSMS = EEPROM.read(3); // Отправка смс
DOORon = EEPROM.read(4); // Датчик двери
PIRon = EEPROM.read(6); // Датчик движения
Sirena = EEPROM.read(8); // сирена
Firststart = EEPROM.read(10); //
}
}
String eepromtext() { /// === состояние системы === ///
String SIGN = ""; // текущее состояние системы.
String SIRENA = ""; // аварийная сирена.
String RING = ""; // текущее состояние вызов.
String SMS = ""; // текущее состояние смс.
String Door = ""; // текущее состояние датчика двери.
String Pir = ""; // текущее состояние датчика движения.
if (Guard == 1) SIGN = F("System on\n"); else SIGN = F("System off\n");
if (Sirena == 1) SIRENA = F("Sirena on\n"); else SIRENA = F("Sirena off\n");
if (AlarmRING == 1) RING = F("Ring on\n"); else RING = F("Ring off\n");
if (SendSMS == 1) SMS = F("SMS on\n"); else SMS = F("SMS off\n");
if (DOORon == 1) Door = F("Door on\n"); else Door = F("Door off\n");
if (PIRon == 1) Pir = F("Pir on\n"); else Pir = F("Pir off\n");
String LastEvent = SIGN + RING + SMS + SIRENA + Pir + Door; // полное состояние системы и датчиков.
return LastEvent;
}
String eepromphone() { /// === чтение мастер-номеров из EEPROM === ///
for (int i = 0; i < 5 ; i++) {
EEPROM.get(Adress[i], Phone); // считываем мастер-номера
AlarmPhone[i] = Phone;
}
String numbers = "[0] " + AlarmPhone[0] + "\n[1] " + AlarmPhone[1] + "\n[2] " + AlarmPhone[2] + "\n[3] " + AlarmPhone[3] + "\n[4] " + AlarmPhone[4] + "\n";
EEPROM.get(100, Phone); // считываем номер последнего звонившего
RingPhone = Phone;
String ring = String(F("Ring ")) + RingPhone + "\n";
EEPROM.get(20, Bal); // считываем номер баланса
String bal = String(F("Balance *")) + Bal + "#\n";
String EEPhone = numbers + ring + bal;
return EEPhone;
}
void Detect() { /// === чтение датчиков === ///
DOORState = digitalRead(DOOR);
PIRState = digitalRead(PIR);
int ac_volt = analogRead(Ac_pin);
if (DOORon == 1) {
if (DOORState == LOW && DOORFlag == 0) {
previousMillis_door = millis();
DOORFlag = 1;
// Serial.println(F("Dver' otkrita!"));
Alarm(); //
}
else if (DOORState == HIGH && DOORFlag == 1) {
int currentMillis_door = millis();
if (((currentMillis_door - previousMillis_door) / 1000 > interval_door)) {
DOORFlag = 0;
}
}
}
if (ac_volt <= acv && ac_sended == 0){
ac_sended = 1;
ac_sended_on = 0;
Alarm();
}
if (ac_volt >= acv+10 && ac_sended_on == 0){
ac_sended = 0;
ac_sended_on = 1;
Alarm2();
}
if (PIRon == 1) {
if (PIRState == LOW && PIRFlag == 0) {
previousMillis_pir = millis();
PIRFlag = 1;
// Serial.println(F("Dvizhenie u dveri!"));
Alarm(); //
}
else if (PIRState == HIGH && PIRFlag == 1) {
int currentMillis_pir = millis();
if (((currentMillis_pir - previousMillis_pir) / 1000 > interval_pir)) {
PIRFlag = 0;
}
}
}
}
void Alarm() { /// === запускаем сирену и отправку смс === ///
previousMillis_alarm = millis();
if (Sirena == 1) digitalWrite(BUZ, HIGH);
Serial.println(F("Alarm!!!"));
if (SendSMS == 1) {
if (DOORFlag == 1) {
sms(F("Dver' otkrita!\n"), 1); // смс на все номера
}
else if (PIRFlag == 1) {
sms(F("Dvizhenie y dveri!\n"), 1); // смс на все номера
}
else if (ac_sended == 1) {
sms(F("220 is OFF\n"), 1); // смс на все номера
}
}
if (AlarmRING == 1) {
gsm.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру
}
}
void Alarm2() { /// === запускаем сирену и отправку смс === ///
previousMillis_alarm = millis();
if (ac_sended_on == 1);
Serial.println(F("Alarm2!!!"));
if (SendSMS == 1) {
sms(F("220 is ON\n"), 1); // смс на все номера
}
}
void AlarmPinOff() { /// === если прошло время, отключаем сирену === ///
int currentMillis_alarm = millis();
if (((currentMillis_alarm - previousMillis_alarm) / 1000 > interval_alarm) || Guard == 0) {
digitalWrite(BUZ, LOW);
}
}
void MasterRing() { /// === мастер звонков === //
if (Guard == 1) GuardOff(); // меняем состояние
else if (Guard == 0) GuardOn(); // меняем состояние
}
void GuardOff() { /// === выключение сигнализации === ///
Guard = 0;
EEPROM.update(1, Guard);
sms(String(F("System->off\n")), 1); // смс на все номера
}
void GuardOn() { /// === включение сигнализации === ///
Guard = 1;
EEPROM.update(1, Guard);
sms(String(F("System->on\n")), 1); // смс на все номера
}
void Led() { /// === состояние светодиода === ///
if (Guard == 1) { // если на охране
int currentMillis_led = millis(); // светодиод моргает
//проверяем не прошел ли нужный интервал, если прошел то
if (currentMillis_led - previousMillis_led > interval_led) {
// сохраняем время последнего переключения
previousMillis_led = currentMillis_led;
// если светодиод не горит, то зажигаем, и наоборот
if (LEDState == HIGH) LEDState = LOW;
else LEDState = HIGH;
digitalWrite(LED, LEDState);
}
} else if (Guard==0) digitalWrite(LED, LOW); // иначе гасим его
}
void Komand(String kom) { /// === мастер смс === ///
Serial.println("kom> " + kom);
kom.toLowerCase();
if (RingPhone == AlarmPhone[0] || sendsmscaller == 0) { // команды выполняются только с 0 мастер номера
if (kom.indexOf(F("reset")) > -1) { // полный сброс ЕЕПРОМ
sms(F("System Reset!\n"), 0); // смс на последний номер
EEPROM.write(0, 0);
eepromconfig();
Serial.println(eepromtext());
Serial.println(eepromphone());
} else if ((p = kom.indexOf(F("master"))) > -1) { // добавление мастер-номера
master(kom.substring(p + 6, p + 7).toInt(), kom.substring(p + 8, p + 23));
///// sms типа: " master1:79111234567 " - ячейка + номер
} else if ((p = kom.indexOf(F("balance:"))) > -1) { // добавление номера баланса
balnum(kom.substring(p + 8, p + 11));
///// sms типа: " balance:100 " - номер баланса
} else if ((p = kom.indexOf(F("dell:"))) > -1) { // удаление номера из ячейки
dellphone(kom.substring(p + 5, p + 6).toInt());
///// sms типа: " dell:1 " - удалить номер из ячейки 1
} else if (kom.indexOf(F("phone")) > -1) { // инфо о номерах системы
sms(eepromphone(), 0); // смс на последний номер
}
}
if ((kom.indexOf(F("info")) > -1) || (kom.indexOf(F("?")) > -1)) { // инфо о состоянии системы
eepromconfig();
sms(eepromtext(), 0); // смс на последний номер
} else if (kom.indexOf(F("money")) > -1) { // запрос баланса
balance();
} else if (kom.indexOf(F("datchiki")) > -1) {
if (kom.indexOf(on) > -1) { // вкл
DOORon = 1;
PIRon = 1;
EEPROM.update(4, DOORon);
EEPROM.update(6, PIRon);
} else if (kom.indexOf(off) > -1) { // выкл
DOORon = 0;
PIRon = 0;
EEPROM.update(4, DOORon);
EEPROM.update(6, PIRon);
}
sms(eepromtext(), 1); // смс на последний номер
} else if (kom.indexOf(F("system")) > -1) { // вкл/выкл сигнализацию
if (kom.indexOf(on) > -1) { // вкл
GuardOn();
} else if (kom.indexOf(off) > -1) { // вкл
GuardOff();
}
} else if (kom.indexOf(F("sirena")) > -1) { // вкл/выкл сирены
if (kom.indexOf(on) > -1) { // вкл
Sirena = 1;
EEPROM.update(8, Sirena);
sms(String(F("Sirena->on\n")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл
Sirena = 0;
EEPROM.update(8, Sirena);
sms(String(F("Sirena->off\n")), 1); // смс на все номера
}
} else if (kom.indexOf(F("ring")) > -1) { // вкл/выкл вызов при сработке
if (kom.indexOf(on) > -1) { // вкл
AlarmRING = 1;
EEPROM.update(2, AlarmRING);
sms(String(F("Ring->on\n")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл
AlarmRING = 0;
EEPROM.update(2, AlarmRING);
sms(String(F("Ring->off\n")), 1); // смс на все номера
}
} else if (kom.indexOf(F("sms")) > -1) { // вкл/выкл смс при сработке
if (kom.indexOf(on) > -1) { // вкл
SendSMS = 1;
EEPROM.update(3, SendSMS);
sms(String(F("SMS->on\n")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл
SendSMS = 0;
EEPROM.update(3, SendSMS);
sms(String(F("SMS->off\n")), 1); // смс на все номера
}
} else if (kom.indexOf(F("door")) > -1) { // вкл/выкл контроль датчика двери
if (kom.indexOf(on) > -1) { // выкл
DOORon = 1;
EEPROM.update(4, DOORon);
sms(String(F("DOOR->on\n")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл контроль датчика двери
DOORon = 0;
EEPROM.update(4, DOORon);
sms(String(F("DOOR->off\n")), 1); // смс на все номера
}
} else if (kom.indexOf(F("pir")) > -1) { // вкл/выкл контрол датчика движения
if (kom.indexOf(on) > -1) { // вкл
PIRon = 1;
EEPROM.update(6, PIRon);
sms(String(F("PIR->on\n")), 1); // смс на все номера
} else if (kom.indexOf(off) > -1) { // выкл
PIRon = 0;
EEPROM.update(6, PIRon);
sms(String(F("PIR->off\n")), 1); // смс на все номера
}
}
gsm.println(F("AT+CMGD=1,4")); // стираем смс
}
void Signal() {
String csq = sendATCommand(F("AT+CSQ"), true); //
csq = csq.substring(csq.indexOf(":") + 2, csq.indexOf(","));
csq.trim();
csq.toCharArray(CSQ, 4);
}
void balance() { /// === проверка баланса сим-карты === ///
EEPROM.get(20, Bal); // считываем массив символов
delay(1000); // ждем секунду, т.к. вылетает с ошибкой
if (ModemID == 1 || ModemID == 2) {
sendATCommand(F("AT+CUSD=1"), true); // вывключить эхо
sendATCommand(String(F("ATD#")) + Bal + "#;", true);
// gsm.println(String(F("ATD#")) + Bal + "#;");
} else if (ModemID == 3) sendATCommand(String(F("AT+CUSD=1")) + ",#" + Bal + F("#,15"), true);
gsm.println(String(F("AT+CUSD=1,#")) + Bal + "#,15");
Serial.println(String(F("Balance#")) + Bal + "#");
}
int master (int i, String num) { /// === добавление мастер-номеров === ///
if (i < 5 && i != 0) {
num.toCharArray(Phone, 13); // конвертируем
AlarmPhone[i] = num; // пишем номер
EEPROM.put(Adress[i], Phone); // записываем массив в EEPROM
sms(String(F("Master")) + i + ":" + num + " add\n", 0); // смс на 0 номер.
}// else Serial.println(F("MAX number 4!")); // 4 номера максимум!
// 0 номер можно удалить только через RESET!!!
return 1;
}
int dellphone (int i) { /// === удаление мастар-номеров === ///
if (i < 5 && i != 0) {
sms(String(F("Master")) + i + ":" + AlarmPhone[i] + " dell\n", 0); // смс на 0 номер
EEPROM.put(Adress[i], 0);
AlarmPhone[i] = ""; // обнулим номер
}
return 1;
}
int balnum (String num) { /// === добавляем номер баланса === ///
num.toCharArray(Bal, 4); // конвертируем
EEPROM.put(20, Bal); // записываем массив в EEPROM
sms(String(F("Balance:*")) + num + F("# Ok\n"), 0); // смс на 0 номер
return 1;
}
void Decode7bit(String &instr, String &outstr) { /// === декодирование баланса === ///
byte reminder = 0;
int bitstate = 7;
for (unsigned int i = 0; i < instr.length(); i++) {
byte b = instr[i];
byte bb = b << (7 - bitstate);
char c = (bb + reminder) & 0x7F;
outstr += c;
reminder = b >> bitstate;
bitstate--;
if (bitstate == 0) {
char c = reminder;
outstr += c;
reminder = 0;
bitstate = 7;
}
}
}
void InitModem() { /// === инициализация модема === ///
gsm.begin(9600); //Скорость порта для связи Arduino с GSM модулем
waitConnect();
String val = sendATCommand(F("ATI"), true);
if (val.indexOf(F("M590")) > -1) ModemID = 1;
else if (val.indexOf(F("SIM800")) > -1) ModemID = 2;
else if (val.indexOf("A6C") > -1) ModemID = 3;
Serial.println(String(F("ModemID ")) + ModemID + "\n");
sendATCommand(F("ATE0"), true); // вывключить эхо
sendATCommand(F("AT+CLIP=1"), true); // включить АОН
sendATCommand(F("AT+CMGF=1"), true); // включить текстовый формат смс
sendATCommand(F("AT+CSCS=\"GSM\""), true); // включить кодировка текста gsm
sendATCommand(F("AT+CNMI=2,2,0,0,0"), true); // смс прямо в порт
sendATCommand(F("AT+CREG?"), true); // регистрация в сети
}
String sendATCommand(String cmd, bool waiting) {
String atval = ""; // Переменная для хранения результата
Serial.println(cmd); // Дублируем команду в монитор порта
gsm.println(cmd); // Отправляем команду модулю
if (waiting) { // Если необходимо дождаться ответа...
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд)
while (!gsm.available() && (millis() < _timeout)) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то...
if (gsm.available()) { // если GSM модем что-то послал.
while (gsm.available()) { // сохраняем входную строку в переменную val.
char ch = gsm.read();
atval += char(ch); // собираем принятые символы в строку
delay(3);
}
} else Serial.println(F("Timeout...")); // ... оповещаем об этом и...
Serial.println(atval); // Дублируем ответ в монитор порта
}
return atval;
}
void waitConnect() { // запуск модема
int countok = 0;
uint32_t msAT = 0;
String str;
while(countok < 10) { //ждём 10 ОК
uint32_t ms = millis();
if(( ms - msAT ) > 500 || ms < msAT ) { // Событие срабатывающее каждые 500 мс
msAT = ms;
Serial.println(">>AT");
gsm.println("AT"); // посылаем команду
str = "";
delay(100); // ждём ответа
while (gsm.available()) { // сохраняем входную строку в переменную val.
char ch = gsm.read();
str += char(ch); // собираем принятые символы в строку
delay(3);
}
if (str.indexOf("OK") > -1) {
Serial.println("OK");
countok++;
} else countok = 0;
}
}
}
void sms(String text, byte sendnum) { /// === отправка СМС === ///
String phone = "";
if (sendsmscaller == 1 && sendnum == 0) { // отправка смс на номер звонившего
phone = RingPhone;
sendATCommand("AT+CMGS=\"" "+" + phone + "\"", true); // Переходим в режим ввода текстового сообщения
sendATCommand(text + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z Serial.println(String(F("SMS send=>")) + phone);
} else if (sendsmscaller == 1 && sendnum == 1) { // отправка смс на все номера
for (uint8_t i = 0; i < 4 ; i++) {
phone = AlarmPhone[i];
if (phone != 0) {
sendATCommand("AT+CMGS=\"" "+" + phone + "\"", true); // Переходим в режим ввода текстового сообщения
sendATCommand(text + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z Serial.println(String(F("SMS send=>")) + phone);
}
}
} else if (sendsmscaller == 0) Serial.println(text + "\n");
}
void Button1(){ //кнопка снятия/постановки на охрану
int reading = digitalRead(BUTTON1);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
if (buttonState == HIGH) {
Guard = !Guard;
EEPROM.update(1, Guard);
// Serial.println(F("Button"));
}
}
}
lastButtonState = reading;
}
void Button2(){ //кнопка отключения контроля датчиков на 25 мин
if(digitalRead(BUTTON2)==HIGH&&Guard==1) //если кнопка нажата и на охране
{
DOORon=0; //отключаем датчик двери
PIRon=0; //отключаем датчик движения
digitalWrite(LEDTimer, HIGH); //зажигаем красный светодиод
time=millis();
}
if(digitalRead(BUTTON2)==LOW&&Guard==1&&((millis()-time)>1500000)) //задержка 25 минут
{
DOORon=1; //включаем датчик двери
PIRon=1; //включаем датчик движения
digitalWrite(LEDTimer, LOW); //гасим красный светодиод
}
}
void LedDetect(){ //состояние датчиков (вкл/выкл)
if(Guard==1&&DOORon==1&&PIRon==1) //если на охране и нет сработки
{
digitalWrite(LEDDetect, HIGH); //включаем зеленый светодиод
}
else digitalWrite(LEDDetect, LOW); //иначе гасим
if(Guard==0){ //если не на охране
DOORState = digitalRead(DOOR);
PIRState = digitalRead(PIR);
if (DOORState == LOW || PIRState == LOW) { // проверяем датчики.
digitalWrite(LEDDetect,HIGH);
digitalWrite(LEDTimer,HIGH); // включаем красный и зеленый светодиоды при сработке двери или движения.
}
else {
digitalWrite(LEDDetect,LOW); //иначе гасим
digitalWrite(LEDTimer,LOW);
}
}
}
и еще вопрос. компилятор выдает ошибку в строке while (!gsm.available() && (millis() < _timeout)) {};
String sendATCommand(String cmd, bool waiting) {
String atval = ""; // Переменная для хранения результата
Serial.println(cmd); // Дублируем команду в монитор порта
gsm.println(cmd); // Отправляем команду модулю
if (waiting) { // Если необходимо дождаться ответа...
long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд)
while (!gsm.available() && (millis() < _timeout)) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то...
if (gsm.available()) { // если GSM модем что-то послал.
while (gsm.available()) { // сохраняем входную строку в переменную val.
char ch = gsm.read();
atval += char(ch); // собираем принятые символы в строку
delay(3);
}
} else Serial.println(F("Timeout...")); // ... оповещаем об этом и...
Serial.println(atval); // Дублируем ответ в монитор порта
}
return atval;
}
Здравствуйте. Сейчас точно не скажу, но скорее всего мой последний это рабочий, у меня год сигналка проработала, сейчас перешёл на raspberry + zigbee датсикин
После команды PHONE номер приходит в формате +380*********
После команды PHONE номер приходит в формате +380*********
Уже обсуждали в теме про длинные номера, поищите.
Там по-моему необходимо изменить:
282 строка:. Index += 9;
Номер должен сохраняться без +, ну и по длине нормально обрезает?
по длине нормально токи с +
по длине нормально токи с +
Пробуйте изменить Index
А 203 строка "ring:" как номер приходит?
Спасибо за помощь.
Сигналка стоит дома а я на работе Получилось добавить номер отправив его без+.И все ОК.
Вечером беду посмотреть на програму.
Хорошо
Добрый день. Программирование только начал осваивать, потому может допустил где-то ошибки. На основе вашего скетча, с использованием примеров и других проэктов, немного переделал сигналку.
Добавлено следующее:
- кнопка вкл/выкл охраны;
- кнопка откл датчиков на 25 минут, если на охране;
- двохцветный светодиод: индикация контроля датчиков в режиме охраны - зеленый; контроль отключен на охране - красный; контроль срабатывания датчиков не на охране - оранжевый;
- контроль питающего напряжения сети с смс уведомлением.
Если есть ошибки, ткните носом где и желательно пояснить почему и в какую сторону грести.
#include <EEPROM.h> #include <SoftwareSerial.h> #define Ver F("Alarm v4.3.3_UK_Phone[12]\n") SoftwareSerial gsm(2, 3); // модем подключен к 7 и 8 пинам. #define DOOR 4 // пин 4. концевик двери. #define PIR 5 // пин 5. датчик движения. #define LED 6 // пин 6. состояние системы. #define Ac_pin A0 // пин А0. контроль 220 #define BUZ 7 // пин 7. сирена. #define LEDDetect 11 // пин 11. контроль датчиков вкл. #define LEDTimer 10 // пин 10. контроль датчиков откл. #define BUTTON1 8 // пин 8. кнопка постановки/снятия с охраны #define BUTTON2 9 // пин 9. кнопка откл датчиков на 25 мин #define on "on" // вкл #define off "off" // выкл int8_t ModemID = 0; // тип модема boolean Guard = 0; // 1. охрана: 1 - вкл, 0 - выкл. boolean AlarmRING = 1; // 2. вызов при сработке: 1 - вкл, 0 - выкл. boolean SendSMS = 1; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл. boolean DOORon = 1; // 4. контроль концевика двери: 1 - вкл, 0 - выкл. boolean PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл. boolean Sirena = 1; // 7. сирена: 1 - вкл, 0 - выкл. boolean Firststart = 1; // первый старт. boolean DOORFlag = 0; // флаг состояние датчика двери. boolean PIRFlag = 0; // флаг состояние датчика движения. int8_t DOORState = HIGH; // Состояние концевика двери. int8_t PIRState = HIGH; // Состояние датчика движения. int8_t LEDState = LOW; // Состояние светодиода. boolean sendsmscaller = 1; // разрешение отправки смс. int ac_sended = 0; // Отправлено сообщение о пропадании напряжения int ac_sended_on = 0; //Отправлено сообщение о появлении напряжения int acv = 200; // Пороговое напряжение питания 220В int buttonState; // текущее состояние кнопки int lastButtonState = LOW; // предыдущее состояние кнопки unsigned long lastDebounceTime = 0; // время последнего переключения unsigned long debounceDelay = 50; unsigned long time; uint32_t msAT = 0; char CSQ[4]; // для хранения уровня сигнала char Bal[4]; // для временного хранения номера баланса. char Phone[13]; // для временного хранения номера телефона. String AT[] = {"AT+CLIP=1", "AT+CMGF=1", "AT+CSCS=\"GSM\"", "AT+CNMI=2,2,0,0,0", "AT+CREG?"}; // общие АТ команды #define AT_M590 F("AT+CUSD=1") // баланс для М590 #define AT_SIM800_A6 F("AT+CUSD=1,#") // баланс для А6 и СИМ800 String RingPhone = ""; // номер звонившего. String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс. byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ. int p = 0; #define interval_alarm 20 // Секунд до отключения "тревожного" пина. int previousMillis_alarm = 0; #define interval_led 1000 // для мигания LED, 1 сек. int previousMillis_led = 0; #define interval_door 10 // секунд не смотрим на датчик двери. int previousMillis_door = 0; #define interval_pir 20 // секунд не смотрим на датчик движения. int previousMillis_pir = 0; void setup() { /// === настройка программы === /// Serial.begin(9600); Serial.println(Ver); pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +. pinMode(PIR, INPUT_PULLUP); // вход датчика движения с подтяжкой на +. pinMode(BUZ, OUTPUT); pinMode(LED, OUTPUT); pinMode(LEDTimer, OUTPUT); pinMode(LEDDetect, OUTPUT); pinMode(BUTTON1, INPUT); // кнопка1 pinMode(BUTTON2, INPUT); // кнопка2 digitalWrite(BUZ, LOW); // сирена выкл. digitalWrite(PIR, LOW); // игнорируем при включении. digitalWrite(LEDTimer, LOW); digitalWrite(LEDDetect, LOW); InitModem(); // запускаем инициализация модема. eepromconfig(); Serial.println(eepromphone()); Signal(); Serial.println(eepromtext() + F("\nSignal seti: ") + CSQ ); // закомментировать если смс sms(eepromtext() + F("\nSignal seti: ") + CSQ + "%", 0); // смс на последний номер digitalWrite(LED, LOW); // гасим светодиод состояния сигнализации. } void loop() { /// === основной цикл программы === /// AlarmPinOff(); // выключаем сирену, если прошло время. Button1(); // проверяем кнопку1. Button2(); // проверяем кнопку2. LedDetect(); if (Guard == 1) { // если на охране Detect(); // проверяем датчики. Led(); // моргаем светодиодом. } if (gsm.available()) { // Если модем, что-то отправил... sendsmscaller = 1; String gval = ""; // Переменная для хранения ответа модуля if (gsm.available()) { // если GSM модем что-то послал. while (gsm.available()) { // сохраняем входную строку в переменную val. char ch = gsm.read(); gval += char(ch); // собираем принятые символы в строку delay(3); } } if (gval.indexOf(F("+PBREADY")) > -1) InitModem(); else if (gval.indexOf(F("+CLIP")) > -1) { // если обнаружен вызов. Serial.println(F("Process RING")); delay(2000); int ind = gval.indexOf(F("+CLIP: \"")); // обрезаем номер ind += 8; // Парсим строку и String ring = gval.substring(ind, gval.indexOf("\"", ind)); Serial.println(String(F("RingPhone->")) + ring); if (CheckPhone(ring) == 1) {sendATCommand("ATH", true); // сбрасываем вызов Serial.println(F("Master Ring OK!")); MasterRing(); } else sendATCommand("ATA", true); } else if (gval.indexOf(F("+CMT")) > -1) { // если обнаруженa СМС Serial.println(F("Process CMT")); parsesms(gval); } else if(gval.indexOf(F("+CUSD:")) > -1) { // если пришел баланс Serial.println(F("Process USD")); Serial.println("gval1 " + gval); String bal = ""; if (ModemID == 3) { int p1 = gval.indexOf("\""); // начало строки int p2 = gval.lastIndexOf("\""); // конец строки gval = gval.substring(p1 + 1, p2); Decode7bit(gval, bal); sendATCommand(F("AT+CUSD=0"), true); } else if (ModemID == 1 || 2) { bal = String(gval.substring(gval.indexOf("\"") + 1,gval.indexOf("\","))); // } sendATCommand(F("AT+CUSD=0"), true); sms(String(F("Sim ")) + bal, 0); } } else if (Serial.available()) { // если в мониторе порта что-то ввели String sval = ""; while (Serial.available()) { // сохраняем входную строку в переменную val. char ch = Serial.read(); sval += char(ch); // собираем принятые символы в строку delay(3); } sendsmscaller = 0; Komand(sval); // запускаем консольную программу // sendsmscaller = 1; } } String waitgsm() { // Функция ожидания ответа и возврата полученного результата String gsmval = ""; // Переменная для хранения результата uint32_t _timeout = millis() + 5000; // Переменная для отслеживания таймаута (10 секунд) while (!gsm.available() && (millis() < _timeout)) {}; // Ждем ответа5 секунд, если пришел ответ или наступил таймаут, то... if (gsm.available()) { // если GSM модем что-то послал. while (gsm.available()) { // сохраняем входную строку в переменную val. char ch = gsm.read(); gsmval += char(ch); // собираем принятые символы в строку delay(5); } } else { // Если пришел таймаут, то... Serial.println(F("Timeout...")); // ... оповещаем об этом и... } return gsmval; // ... возвращаем результат. Пусто, если проблема } void parsesms(String msg) { String msgheader = ""; String msgsms = ""; String msgphone = ""; msg = msg.substring(msg.indexOf("+CMT: ")); msgheader = msg.substring(0,msg.indexOf("\r")); // Выдергиваем телефон msgsms = msg.substring(msgheader.length() + 2); msgsms = msgsms.substring(0, msgsms.lastIndexOf("OK")); // Выдергиваем текст SMS msgsms.trim(); int Index = msgheader.indexOf("+CMT:"); msgphone = msgheader.substring(Index + 8, Index + 20); msgphone.trim(); Serial.println("Phone: " + msgphone); // Выводим номер телефона Serial.println("Message: " + msgsms); // Выводим текст SMS if (CheckPhone(msgphone) == 1) { // если СМС от хозяина Serial.println(F("Master SMS OK!")); Komand(msgsms); } else Serial.println(F("No Master SMS!")); } int CheckPhone(String phone) { /// === проверка телефона === /// if (Firststart == 0) { // если не первый старт for (int i = 0; i < 5; i++) { if (phone == AlarmPhone[i] && phone != 0) { // если есть вызов, и он наш phone = AlarmPhone[i]; // запоминаем его. RingPhone = AlarmPhone[i]; // запоминаем его. RingPhone.toCharArray(Phone, 13); EEPROM.put(100, Phone); // записываем RingPhone в память. Serial.println(String(F("RingPhone ")) + RingPhone); return 1; // возвращаем 1 - номер наш! } } return 0; // возвращаем 0 - номер не наш! } else if (Firststart == 1) { // иначе (если первый старт) // первый звонивший добавляется как основной мастер номер для управления сигнализацией phone.toCharArray(Phone, 13); EEPROM.put(25, Phone); // пишем номер в EEPROM EEPROM.put(100, Phone); // записываем RingPhone в память. AlarmPhone[0] = Phone; // запишем RingPhone = Phone; // запоминаем его. EEPROM.update(10, 0); // обновляем Firststart Firststart = 0; // пишем 0 Serial.println(String(F("Firststart:")) + Firststart); sms(String(F("Master0->")) + phone + " Add", 0); // смс на звонивший // приходит смс в виде: " Master0:79111234567 Ok " } return 1; } void eepromconfig() { /// === конфигурирование сигнализации === /// if (EEPROM.read(0) != 1) { // если записана не 1 for (int i = 0 ; i < 512 ; i++) { // переписываем все ячейки EEPROM.write(i, 0); } // и записываем: EEPROM.update(1, 0); // Guard охрана выкл. EEPROM.update(2, 1); // AlarmRING вызов вкл. EEPROM.update(3, 1); // SendSMS смс вкл. EEPROM.update(4, 1); // DOORon датчики дверей вкл. EEPROM.update(6, 1); // PIRon датчик движения вкл. EEPROM.update(8, 1); // Sirena сирена вкл. EEPROM.update(10, 1); // Firststart первый старт!. EEPROM.update(20, 0); // баланс, записываем массив в EEPROM EEPROM.update(0, 1); // Serial.println(F("EEPROM != 1/ RESET!")); } if (EEPROM.read(0) == 1) { Guard = EEPROM.read(1); // Охрана AlarmRING = EEPROM.read(2); // Вызов SendSMS = EEPROM.read(3); // Отправка смс DOORon = EEPROM.read(4); // Датчик двери PIRon = EEPROM.read(6); // Датчик движения Sirena = EEPROM.read(8); // сирена Firststart = EEPROM.read(10); // } } String eepromtext() { /// === состояние системы === /// String SIGN = ""; // текущее состояние системы. String SIRENA = ""; // аварийная сирена. String RING = ""; // текущее состояние вызов. String SMS = ""; // текущее состояние смс. String Door = ""; // текущее состояние датчика двери. String Pir = ""; // текущее состояние датчика движения. if (Guard == 1) SIGN = F("System on\n"); else SIGN = F("System off\n"); if (Sirena == 1) SIRENA = F("Sirena on\n"); else SIRENA = F("Sirena off\n"); if (AlarmRING == 1) RING = F("Ring on\n"); else RING = F("Ring off\n"); if (SendSMS == 1) SMS = F("SMS on\n"); else SMS = F("SMS off\n"); if (DOORon == 1) Door = F("Door on\n"); else Door = F("Door off\n"); if (PIRon == 1) Pir = F("Pir on\n"); else Pir = F("Pir off\n"); String LastEvent = SIGN + RING + SMS + SIRENA + Pir + Door; // полное состояние системы и датчиков. return LastEvent; } String eepromphone() { /// === чтение мастер-номеров из EEPROM === /// for (int i = 0; i < 5 ; i++) { EEPROM.get(Adress[i], Phone); // считываем мастер-номера AlarmPhone[i] = Phone; } String numbers = "[0] " + AlarmPhone[0] + "\n[1] " + AlarmPhone[1] + "\n[2] " + AlarmPhone[2] + "\n[3] " + AlarmPhone[3] + "\n[4] " + AlarmPhone[4] + "\n"; EEPROM.get(100, Phone); // считываем номер последнего звонившего RingPhone = Phone; String ring = String(F("Ring ")) + RingPhone + "\n"; EEPROM.get(20, Bal); // считываем номер баланса String bal = String(F("Balance *")) + Bal + "#\n"; String EEPhone = numbers + ring + bal; return EEPhone; } void Detect() { /// === чтение датчиков === /// DOORState = digitalRead(DOOR); PIRState = digitalRead(PIR); int ac_volt = analogRead(Ac_pin); if (DOORon == 1) { if (DOORState == LOW && DOORFlag == 0) { previousMillis_door = millis(); DOORFlag = 1; // Serial.println(F("Dver' otkrita!")); Alarm(); // } else if (DOORState == HIGH && DOORFlag == 1) { int currentMillis_door = millis(); if (((currentMillis_door - previousMillis_door) / 1000 > interval_door)) { DOORFlag = 0; } } } if (ac_volt <= acv && ac_sended == 0){ ac_sended = 1; ac_sended_on = 0; Alarm(); } if (ac_volt >= acv+10 && ac_sended_on == 0){ ac_sended = 0; ac_sended_on = 1; Alarm2(); } if (PIRon == 1) { if (PIRState == LOW && PIRFlag == 0) { previousMillis_pir = millis(); PIRFlag = 1; // Serial.println(F("Dvizhenie u dveri!")); Alarm(); // } else if (PIRState == HIGH && PIRFlag == 1) { int currentMillis_pir = millis(); if (((currentMillis_pir - previousMillis_pir) / 1000 > interval_pir)) { PIRFlag = 0; } } } } void Alarm() { /// === запускаем сирену и отправку смс === /// previousMillis_alarm = millis(); if (Sirena == 1) digitalWrite(BUZ, HIGH); Serial.println(F("Alarm!!!")); if (SendSMS == 1) { if (DOORFlag == 1) { sms(F("Dver' otkrita!\n"), 1); // смс на все номера } else if (PIRFlag == 1) { sms(F("Dvizhenie y dveri!\n"), 1); // смс на все номера } else if (ac_sended == 1) { sms(F("220 is OFF\n"), 1); // смс на все номера } } if (AlarmRING == 1) { gsm.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру } } void Alarm2() { /// === запускаем сирену и отправку смс === /// previousMillis_alarm = millis(); if (ac_sended_on == 1); Serial.println(F("Alarm2!!!")); if (SendSMS == 1) { sms(F("220 is ON\n"), 1); // смс на все номера } } void AlarmPinOff() { /// === если прошло время, отключаем сирену === /// int currentMillis_alarm = millis(); if (((currentMillis_alarm - previousMillis_alarm) / 1000 > interval_alarm) || Guard == 0) { digitalWrite(BUZ, LOW); } } void MasterRing() { /// === мастер звонков === // if (Guard == 1) GuardOff(); // меняем состояние else if (Guard == 0) GuardOn(); // меняем состояние } void GuardOff() { /// === выключение сигнализации === /// Guard = 0; EEPROM.update(1, Guard); sms(String(F("System->off\n")), 1); // смс на все номера } void GuardOn() { /// === включение сигнализации === /// Guard = 1; EEPROM.update(1, Guard); sms(String(F("System->on\n")), 1); // смс на все номера } void Led() { /// === состояние светодиода === /// if (Guard == 1) { // если на охране int currentMillis_led = millis(); // светодиод моргает //проверяем не прошел ли нужный интервал, если прошел то if (currentMillis_led - previousMillis_led > interval_led) { // сохраняем время последнего переключения previousMillis_led = currentMillis_led; // если светодиод не горит, то зажигаем, и наоборот if (LEDState == HIGH) LEDState = LOW; else LEDState = HIGH; digitalWrite(LED, LEDState); } } else if (Guard==0) digitalWrite(LED, LOW); // иначе гасим его } void Komand(String kom) { /// === мастер смс === /// Serial.println("kom> " + kom); kom.toLowerCase(); if (RingPhone == AlarmPhone[0] || sendsmscaller == 0) { // команды выполняются только с 0 мастер номера if (kom.indexOf(F("reset")) > -1) { // полный сброс ЕЕПРОМ sms(F("System Reset!\n"), 0); // смс на последний номер EEPROM.write(0, 0); eepromconfig(); Serial.println(eepromtext()); Serial.println(eepromphone()); } else if ((p = kom.indexOf(F("master"))) > -1) { // добавление мастер-номера master(kom.substring(p + 6, p + 7).toInt(), kom.substring(p + 8, p + 23)); ///// sms типа: " master1:79111234567 " - ячейка + номер } else if ((p = kom.indexOf(F("balance:"))) > -1) { // добавление номера баланса balnum(kom.substring(p + 8, p + 11)); ///// sms типа: " balance:100 " - номер баланса } else if ((p = kom.indexOf(F("dell:"))) > -1) { // удаление номера из ячейки dellphone(kom.substring(p + 5, p + 6).toInt()); ///// sms типа: " dell:1 " - удалить номер из ячейки 1 } else if (kom.indexOf(F("phone")) > -1) { // инфо о номерах системы sms(eepromphone(), 0); // смс на последний номер } } if ((kom.indexOf(F("info")) > -1) || (kom.indexOf(F("?")) > -1)) { // инфо о состоянии системы eepromconfig(); sms(eepromtext(), 0); // смс на последний номер } else if (kom.indexOf(F("money")) > -1) { // запрос баланса balance(); } else if (kom.indexOf(F("datchiki")) > -1) { if (kom.indexOf(on) > -1) { // вкл DOORon = 1; PIRon = 1; EEPROM.update(4, DOORon); EEPROM.update(6, PIRon); } else if (kom.indexOf(off) > -1) { // выкл DOORon = 0; PIRon = 0; EEPROM.update(4, DOORon); EEPROM.update(6, PIRon); } sms(eepromtext(), 1); // смс на последний номер } else if (kom.indexOf(F("system")) > -1) { // вкл/выкл сигнализацию if (kom.indexOf(on) > -1) { // вкл GuardOn(); } else if (kom.indexOf(off) > -1) { // вкл GuardOff(); } } else if (kom.indexOf(F("sirena")) > -1) { // вкл/выкл сирены if (kom.indexOf(on) > -1) { // вкл Sirena = 1; EEPROM.update(8, Sirena); sms(String(F("Sirena->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл Sirena = 0; EEPROM.update(8, Sirena); sms(String(F("Sirena->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("ring")) > -1) { // вкл/выкл вызов при сработке if (kom.indexOf(on) > -1) { // вкл AlarmRING = 1; EEPROM.update(2, AlarmRING); sms(String(F("Ring->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл AlarmRING = 0; EEPROM.update(2, AlarmRING); sms(String(F("Ring->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("sms")) > -1) { // вкл/выкл смс при сработке if (kom.indexOf(on) > -1) { // вкл SendSMS = 1; EEPROM.update(3, SendSMS); sms(String(F("SMS->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл SendSMS = 0; EEPROM.update(3, SendSMS); sms(String(F("SMS->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("door")) > -1) { // вкл/выкл контроль датчика двери if (kom.indexOf(on) > -1) { // выкл DOORon = 1; EEPROM.update(4, DOORon); sms(String(F("DOOR->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл контроль датчика двери DOORon = 0; EEPROM.update(4, DOORon); sms(String(F("DOOR->off\n")), 1); // смс на все номера } } else if (kom.indexOf(F("pir")) > -1) { // вкл/выкл контрол датчика движения if (kom.indexOf(on) > -1) { // вкл PIRon = 1; EEPROM.update(6, PIRon); sms(String(F("PIR->on\n")), 1); // смс на все номера } else if (kom.indexOf(off) > -1) { // выкл PIRon = 0; EEPROM.update(6, PIRon); sms(String(F("PIR->off\n")), 1); // смс на все номера } } gsm.println(F("AT+CMGD=1,4")); // стираем смс } void Signal() { String csq = sendATCommand(F("AT+CSQ"), true); // csq = csq.substring(csq.indexOf(":") + 2, csq.indexOf(",")); csq.trim(); csq.toCharArray(CSQ, 4); } void balance() { /// === проверка баланса сим-карты === /// EEPROM.get(20, Bal); // считываем массив символов delay(1000); // ждем секунду, т.к. вылетает с ошибкой if (ModemID == 1 || ModemID == 2) { sendATCommand(F("AT+CUSD=1"), true); // вывключить эхо sendATCommand(String(F("ATD#")) + Bal + "#;", true); // gsm.println(String(F("ATD#")) + Bal + "#;"); } else if (ModemID == 3) sendATCommand(String(F("AT+CUSD=1")) + ",#" + Bal + F("#,15"), true); gsm.println(String(F("AT+CUSD=1,#")) + Bal + "#,15"); Serial.println(String(F("Balance#")) + Bal + "#"); } int master (int i, String num) { /// === добавление мастер-номеров === /// if (i < 5 && i != 0) { num.toCharArray(Phone, 13); // конвертируем AlarmPhone[i] = num; // пишем номер EEPROM.put(Adress[i], Phone); // записываем массив в EEPROM sms(String(F("Master")) + i + ":" + num + " add\n", 0); // смс на 0 номер. }// else Serial.println(F("MAX number 4!")); // 4 номера максимум! // 0 номер можно удалить только через RESET!!! return 1; } int dellphone (int i) { /// === удаление мастар-номеров === /// if (i < 5 && i != 0) { sms(String(F("Master")) + i + ":" + AlarmPhone[i] + " dell\n", 0); // смс на 0 номер EEPROM.put(Adress[i], 0); AlarmPhone[i] = ""; // обнулим номер } return 1; } int balnum (String num) { /// === добавляем номер баланса === /// num.toCharArray(Bal, 4); // конвертируем EEPROM.put(20, Bal); // записываем массив в EEPROM sms(String(F("Balance:*")) + num + F("# Ok\n"), 0); // смс на 0 номер return 1; } void Decode7bit(String &instr, String &outstr) { /// === декодирование баланса === /// byte reminder = 0; int bitstate = 7; for (unsigned int i = 0; i < instr.length(); i++) { byte b = instr[i]; byte bb = b << (7 - bitstate); char c = (bb + reminder) & 0x7F; outstr += c; reminder = b >> bitstate; bitstate--; if (bitstate == 0) { char c = reminder; outstr += c; reminder = 0; bitstate = 7; } } } void InitModem() { /// === инициализация модема === /// gsm.begin(9600); //Скорость порта для связи Arduino с GSM модулем waitConnect(); String val = sendATCommand(F("ATI"), true); if (val.indexOf(F("M590")) > -1) ModemID = 1; else if (val.indexOf(F("SIM800")) > -1) ModemID = 2; else if (val.indexOf("A6C") > -1) ModemID = 3; Serial.println(String(F("ModemID ")) + ModemID + "\n"); sendATCommand(F("ATE0"), true); // вывключить эхо sendATCommand(F("AT+CLIP=1"), true); // включить АОН sendATCommand(F("AT+CMGF=1"), true); // включить текстовый формат смс sendATCommand(F("AT+CSCS=\"GSM\""), true); // включить кодировка текста gsm sendATCommand(F("AT+CNMI=2,2,0,0,0"), true); // смс прямо в порт sendATCommand(F("AT+CREG?"), true); // регистрация в сети } String sendATCommand(String cmd, bool waiting) { String atval = ""; // Переменная для хранения результата Serial.println(cmd); // Дублируем команду в монитор порта gsm.println(cmd); // Отправляем команду модулю if (waiting) { // Если необходимо дождаться ответа... long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) while (!gsm.available() && (millis() < _timeout)) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... if (gsm.available()) { // если GSM модем что-то послал. while (gsm.available()) { // сохраняем входную строку в переменную val. char ch = gsm.read(); atval += char(ch); // собираем принятые символы в строку delay(3); } } else Serial.println(F("Timeout...")); // ... оповещаем об этом и... Serial.println(atval); // Дублируем ответ в монитор порта } return atval; } void waitConnect() { // запуск модема int countok = 0; uint32_t msAT = 0; String str; while(countok < 10) { //ждём 10 ОК uint32_t ms = millis(); if(( ms - msAT ) > 500 || ms < msAT ) { // Событие срабатывающее каждые 500 мс msAT = ms; Serial.println(">>AT"); gsm.println("AT"); // посылаем команду str = ""; delay(100); // ждём ответа while (gsm.available()) { // сохраняем входную строку в переменную val. char ch = gsm.read(); str += char(ch); // собираем принятые символы в строку delay(3); } if (str.indexOf("OK") > -1) { Serial.println("OK"); countok++; } else countok = 0; } } } void sms(String text, byte sendnum) { /// === отправка СМС === /// String phone = ""; if (sendsmscaller == 1 && sendnum == 0) { // отправка смс на номер звонившего phone = RingPhone; sendATCommand("AT+CMGS=\"" "+" + phone + "\"", true); // Переходим в режим ввода текстового сообщения sendATCommand(text + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z Serial.println(String(F("SMS send=>")) + phone); } else if (sendsmscaller == 1 && sendnum == 1) { // отправка смс на все номера for (uint8_t i = 0; i < 4 ; i++) { phone = AlarmPhone[i]; if (phone != 0) { sendATCommand("AT+CMGS=\"" "+" + phone + "\"", true); // Переходим в режим ввода текстового сообщения sendATCommand(text + (String)((char)26), true); // После текста отправляем перенос строки и Ctrl+Z Serial.println(String(F("SMS send=>")) + phone); } } } else if (sendsmscaller == 0) Serial.println(text + "\n"); } void Button1(){ //кнопка снятия/постановки на охрану int reading = digitalRead(BUTTON1); if (reading != lastButtonState) { lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { if (reading != buttonState) { buttonState = reading; if (buttonState == HIGH) { Guard = !Guard; EEPROM.update(1, Guard); // Serial.println(F("Button")); } } } lastButtonState = reading; } void Button2(){ //кнопка отключения контроля датчиков на 25 мин if(digitalRead(BUTTON2)==HIGH&&Guard==1) //если кнопка нажата и на охране { DOORon=0; //отключаем датчик двери PIRon=0; //отключаем датчик движения digitalWrite(LEDTimer, HIGH); //зажигаем красный светодиод time=millis(); } if(digitalRead(BUTTON2)==LOW&&Guard==1&&((millis()-time)>1500000)) //задержка 25 минут { DOORon=1; //включаем датчик двери PIRon=1; //включаем датчик движения digitalWrite(LEDTimer, LOW); //гасим красный светодиод } } void LedDetect(){ //состояние датчиков (вкл/выкл) if(Guard==1&&DOORon==1&&PIRon==1) //если на охране и нет сработки { digitalWrite(LEDDetect, HIGH); //включаем зеленый светодиод } else digitalWrite(LEDDetect, LOW); //иначе гасим if(Guard==0){ //если не на охране DOORState = digitalRead(DOOR); PIRState = digitalRead(PIR); if (DOORState == LOW || PIRState == LOW) { // проверяем датчики. digitalWrite(LEDDetect,HIGH); digitalWrite(LEDTimer,HIGH); // включаем красный и зеленый светодиоды при сработке двери или движения. } else { digitalWrite(LEDDetect,LOW); //иначе гасим digitalWrite(LEDTimer,LOW); } } }и еще вопрос. компилятор выдает ошибку в строке while (!gsm.available() && (millis() < _timeout)) {};
String sendATCommand(String cmd, bool waiting) { String atval = ""; // Переменная для хранения результата Serial.println(cmd); // Дублируем команду в монитор порта gsm.println(cmd); // Отправляем команду модулю if (waiting) { // Если необходимо дождаться ответа... long _timeout = millis() + 10000; // Переменная для отслеживания таймаута (10 секунд) while (!gsm.available() && (millis() < _timeout)) {}; // Ждем ответа 10 секунд, если пришел ответ или наступил таймаут, то... if (gsm.available()) { // если GSM модем что-то послал. while (gsm.available()) { // сохраняем входную строку в переменную val. char ch = gsm.read(); atval += char(ch); // собираем принятые символы в строку delay(3); } } else Serial.println(F("Timeout...")); // ... оповещаем об этом и... Serial.println(atval); // Дублируем ответ в монитор порта } return atval; }что упущено в скобках?
что упущено в скобках?
Это написано в ошибке.
и действительно, все описано в ошибке, но дошло после перевода и вкурения темы https://forum.arduino.cc/index.php?topic=443491.0
поменял long _timeout = millis() + 10000; на unsigned long
"а мама говорила, учи английский, будет легче жить"
1. Маму надо слушаться
2. Текст ошибки нужно было запостить в #810
slovyan - Какая-то странная вещь. У меня есть Arduino 1.8.9, и он не показывает никаких ошибок при компиляции( #809). ???.
Он назвал ошибкой предупреждение. Это нормально. Такого рода предупреждения я тоже "внутренним голосом" называю ошибками.
Подскажите,а реально работающий проект в этом топике есть?Хотелось бы повторить..
Здравствуйте. Сейчас точно не скажу, но скорее всего мой последний это рабочий, у меня год сигналка проработала, сейчас перешёл на raspberry + zigbee датсикин
Сэр, пожалуйста, помогите мне
Программа не работает