Добрый день. Программирование только начал осваивать, потому может допустил где-то ошибки. На основе вашего скетча, с использованием примеров и других проэктов, немного переделал сигналку.
Добавлено следующее:
- кнопка вкл/выкл охраны;
- кнопка откл датчиков на 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 минут, если на охране;
- двохцветный светодиод: индикация контроля датчиков в режиме охраны - зеленый; контроль отключен на охране - красный; контроль срабатывания датчиков не на охране - оранжевый;
- контроль питающего напряжения сети с смс уведомлением.
Если есть ошибки, ткните носом где и желательно пояснить почему и в какую сторону грести.
и еще вопрос. компилятор выдает ошибку в строке while (!gsm.available() && (millis() < _timeout)) {};
что упущено в скобках?
что упущено в скобках?
Это написано в ошибке.
и действительно, все описано в ошибке, но дошло после перевода и вкурения темы 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 датсикин
Сэр, пожалуйста, помогите мне
Программа не работает