нужна помощ в доведении охраной сигнализации до ума
- Войдите на сайт для отправки комментариев
Втр, 02/07/2019 - 19:08
Друзья доброго времени суток нужна помощь и не бесплатная, если поможете
с прoшивкой и частично с подключением дополнительного датчика
речь идет о системе прото-типе сигнализации на ардуино нано 3.0
с модулем отправки смс m590 neoway, управление системой тоже по смс
с датчиком противопожарной сигнализации на термодатчике dallas ds18b20
с пирометрическим датчиком движения HC-SR501
с датчиком газа на присутствие бутана MQ-2
возможно в систему понадобится добавить емкостной датчик для baypass (защиты ) пирометрического и нужна будет помощь в его подключении в плате
или просто все заменить на микроволновый датчик движения ..(нужно где то 7 метров реагирования плюс минус )
как это реализовано в этом проэкте
проэкт мне этот передали по наследству со всеми болячками от того кто этот концепт разрабатывал но по каким то мотивам
отошел от проэкта и поддержи этого проэкта
надеюсь с вашей помощью можно будет быстро его довести до ума в С++ я ноль а платформой Адрунино встречаюсь впервые хотя в принципе понимаю как там все
но не в деталях
контакт whatsup +34 6О4.2I6.7I5 или пишите в личку или тут на форуме
на данный момент нужно
1 ограничить время гореня светодиодов 3 минутами (где то в прошивке пошукать)
2 установить смс отстук ..потому что система принимает входящие но не отстукивает обратно о статусе системы итд
3 прикрутить дополнительный емкостной датчик или/и микроволновый движения (заказали несколько разных выбирем какой подойдет лутче)
4 заставить таки работать газовый датчик на бутан и термодатчик dallas ds18b20
прошивка на систему
#include <EEPROM.h>
#include <OneWire.h>
#include<SoftwareSerial.h>
SoftwareSerial mySerial(2, 3);
OneWire ds(4); // датчик температуры подключен к 4 пину, подтяжка 4.7кОм на +.
#define DOOR 6 // концевик двери.
#define PIR 9 // датчик движения.
#define INPIR 7 // выход для подачи напряжения на свет
#define Led 5 // состояние системы. моргает - на охране.
#define GAS A0 // датчик дыма.
#define BUZ 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 = 0; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл.
int8_t DOORon = 0; // 4. контроль концевиков дверей: 1 - вкл, 0 - выкл.
int8_t PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл.
int8_t GASon = 0; // 6. контроль датчика дыма: 1 - вкл, 0 - выкл.
int8_t Sirena = 1; // 7. сирена: 1 - вкл, 0 - выкл.
int8_t DOORFlag = 0; // флаг состояние датчика двери.
int8_t PIRFlag = 0; // флаг состояние датчика движения.
int8_t GASFlag = 0; // флаг состояние датчика газа.
int8_t DOORState = LOW; // Состояние концевика двери.
int8_t PIRState = LOW; // Состояние датчика движения. // датчик висит в воздухе программно. аппаратно на минус через 10k.
int8_t LedState = HIGH; // Состояние светодиода.
int8_t Smoky = LOW; // Состояние датчика газа.
int8_t Firststart; // первый старт.
uint32_t msAT = 0;
char Bal[4] = ""; // для временного хранения номера баланса.
char Phone[12]; // для временного хранения номера телефона.
//(если размер номера более 12 цифр нужно поменять на нужное количество по факту определителя как его видно на дисплее +1 )
byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ.
String val; // переменная для хранения пришедших данных.
String temp; // переменная для хранения температуры.
String CSQ; // переменная для хранения пришедших данных уровня сигнала.
String LastEvent; // полное состояние системы.
String RingPhone; // номер звонившего.
String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс.
String Info1 = "Kommanda - deistvie:\nstatus - sostoyanie\nmoney - balance\n"; // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ
String Info2 = "sirenaon/off\nsystemon/off\nringon/off\nsmson/off\n";
String Info3 = "dooron/off\npiron/off\ngason/off";
int p = 0;
int GASThres = 400; // предельная концентрация газа
int interval_alarm = 20; // Секунд до отключения "тревожного" пина, max 300сек
int previousMillis_alarm = 0;
int interval_led = 1000; // для мигания Led
int previousMillis_led = 0;
int interval_door = 10; // секунд не смотрим на датчик двери
int previousMillis_door = 0;
int interval_pir = 10; // секунд не смотрим на датчик движения
int previousMillis_pir = 0;
int interval_gas = 60; // секунд не смотрим на датчик газа
int previousMillis_gas = 0;
/* EEPROM Data:
№ ячейки - значение:
0 - если записана не 1, то необходимо затереть eeprom и восстановить стандартную конфигурацию.
1 - Guard = 0; // охрана: 0 - выкл.
2 - AlarmRING = 1; // звонок: 1 - вкл.
3 - SendSMS = 1; // отправка смс: 1 - вкл.
4 - DOORon = 1; // концевик двери: 1 - вкл.
5 - PIRon = 1; // датчик движения: 1 - вкл.
6 - GASon = 1; // датчик дыма: 1 - вкл.
7 - Sirena = 1; // сирена: 1 - вкл.
10 - Firststars = 1; // первый запуск 1.
20 - ячейка памяти баланса,
25, 40, 55, 70, 85 - ячейки памяти телефонов.
100 - ячейка памяти номера последнего звонившего RingPhone.
*/
void setup() { /// === настройка программы === ///
Serial.begin(9600);
Serial.println(F("GSMTruck4.7"));
pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +.
pinMode(PIR, INPUT); // вход датчика движения .
pinMode(INPIR, OUTPUT); // определяем как выход
pinMode(GAS, INPUT);
pinMode(BUZ, OUTPUT);
pinMode(Led, OUTPUT); // светодиод как выход.
digitalWrite(BUZ, HIGH); // сирена выкл.
digitalWrite(PIR, LOW); // отключаем внутренню подтяжку и вешаем сопротивлени 10k на GND для внешней подтяжки, чтобы не срабатывало на наводки
InitModem(); // запускаем инициализация модема.
eepromconfig();
eepromtext();
eepromphone();
digitalWrite(Led, HIGH); // гасим светодиод состояния сигнализации.
}
void loop() { /// === основной цикл программы === ///
AlarmPinOff(); // выключаем сирену, если прошло время.
if (Guard == 1) { // если на охране
Detect(); // проверяем датчики.
LED(); // моргаем светодиодом.
Timeled(); // включаем свет и камеру при любом движении на заданное время.
}
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), RingPhone); // смс на последний звонивший
} else if (val.indexOf(F("+CSQ:")) > -1) { // пришел уровень сигнала сети
int x = val.indexOf("+CSQ:");
CSQ = "Signal " + val.substring(x+5, x+7) + "%";
} 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 - номер наш!
}
} 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(String("Master0:" + num + " Ok"), num); // смс на звонивший
// приходит смс в виде: " Master0:79111234567 Ok "
}
} return 1;
}
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(7, 1); // Sirena сирена вкл.
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); // Датчик газа/дыма
Sirena = EEPROM.read(7); // сирена
Firststart = EEPROM.read(10); //
}
}
void eepromtext() { /// === состояние системы === ///
mySerial.println("AT+CSQ");
TempC();
delay(250);
String SIGN = ""; // текущее состояние системы.
String SIRENA = ""; // аварийная сирена.
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 (Sirena == 1) SIRENA = String(F("Sirena on\n")); else (SIRENA = String(F("Sirena 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 System = SIGN + SIRENA + RING + SMS; // состояние (вкл/выкл) системы.
String Sensors = Pir + Door + Gas + temp; // состояние (вкл/выкл) датчиков.
LastEvent = System + Sensors + CSQ; // полное состояние системы и датчиков.
Serial.println(LastEvent);
}
void eepromphone() { /// === чтение мастер-номеров из EEPROM === ///
for (int i = 0; i < 5 ; i++) {
EEPROM.get(Adress[i], Phone); // считываем мастер-номера
if (Phone != 0) AlarmPhone[i] = Phone;
Serial.println(String(F("Phone[")) + i + String(F("]:")) + AlarmPhone[i]);
}
EEPROM.get(100, Phone); // считываем номер последнего звонившего
RingPhone = Phone;
Serial.println(String(F("Ring [ ]:")) + RingPhone);
EEPROM.get(20, Bal); // считываем номер баланса
Serial.println(String(F("Balance:")) + Bal);
Firststart = EEPROM.read(10); // cчитаем первый старт
Serial.println(String(F("Firststart:")) + Firststart);
}
void Detect() { /// === чтение датчиков === ///
DOORState = digitalRead(DOOR);
PIRState = digitalRead(PIR);
Smoky = analogRead(GAS);
if (DOORon == 1) {
if (DOORState == HIGH && DOORFlag == 0) {
previousMillis_door = millis();
DOORFlag = 1;
Serial.println(F("Dver' otkrita!"));
Alarm(); //
}
if (DOORState == LOW && DOORFlag == 1) {
int currentMillis_door = millis();
if (((currentMillis_door - previousMillis_door) / 1000 > interval_door)) {
DOORFlag = 0;
}
}
}
if (PIRon == 1) {
if (PIRState == HIGH && PIRFlag == 0) {
previousMillis_pir = millis();
PIRFlag = 1;
Serial.println(F("Dvizhenie u dveri!")); // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ
Alarm(); //
}
if (PIRState == LOW && PIRFlag == 1) {
int currentMillis_pir = millis();
if (((currentMillis_pir - previousMillis_pir) / 1000 > interval_pir)) {
PIRFlag = 0;
}
}
}
if (GASon == 1) {
if ((Smoky > GASThres) && GASFlag == 0) {
previousMillis_gas = millis();
GASFlag = 1;
delay(100);
Serial.println(F("Gas v dome!")); // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ
Alarm(); //
}
if ((Smoky < GASThres) && GASFlag == 1) {
int currentMillis_gas = millis();
if (((currentMillis_gas - previousMillis_gas) / 1000 > interval_gas)) {
GASFlag = 0;
}
}
}
}
void Timeled() { ///=== включаем свет и камеру === ///
unsigned long curMil = millis();
const long interal = 3600000; // задаем время работы света и камеры желательно не менее цикла записи 3 минуты. >=200000 мс сейчас стоит 60 мин
int8_t preMil = 0;
if (Guard == 1 && PIRFlag == 1) { //PIRFlag == 1 заменить на PIRState == HIGH если будут проблемы со срабатыванием
digitalWrite(INPIR, HIGH);
}
if ((curMil - preMil) >= interal) {
preMil = curMil;
digitalWrite(INPIR, LOW);
}
curMil = 0;
}
void Alarm() { /// === запускаем сирену и отправку смс === ///
if (Guard == 1) {
previousMillis_alarm = millis();
if (Sirena == 1) digitalWrite(BUZ, HIGH);
Serial.println(F("Alarm!!!"));
if (SendSMS == 1) {
for (int i = 0; i < 5; i++) { // if (AlarmPhone[i] != 0) {
if (DOORFlag == 1) {
sms(String("Dver' otkrita!"), AlarmPhone[i]); // смс на все номера // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ
}
if (PIRFlag == 1) {
sms(String("Dvizhenie y dveri!"), AlarmPhone[i]); // смс на все номера // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ
}
if (GASFlag == 1) {
sms(String("Gas v dome!"), AlarmPhone[i]); // смс на все номера // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ
}
}
}
if (AlarmRING == 1) {
mySerial.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру
}
}
}
void AlarmPinOff() { /// === если прошло время, отключаем сирену === ///
int currentMillis_alarm = millis();
if (((currentMillis_alarm - previousMillis_alarm) / 1000 > interval_alarm) || Guard == 0) {
digitalWrite(BUZ, LOW);
}
}
void MasterRing() { /// === мастер звонков === //
if (Guard == 1) GuardOff(); // меняем состояние
else if (Guard == 0) GuardOn(); // меняем состояние
}
void GuardOff() { /// === выключение сигнализации === ///
Guard = 0;
EEPROM.update(1, Guard);
Serial.println(String(F("System->off. Ring:")) + RingPhone);
for (int i = 0; i < 5; i++) { // if (AlarmPhone[i] != 0) {
sms(String("System->off " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
}
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[i] != 0) {
sms(String("System->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера
}
}
void LED() { /// === состояние светодиода === ///
if (Guard == 1) { // если на охране
int currentMillis_led = millis(); // светодиод моргает
//проверяем не прошел ли нужный интервал, если прошел то
if (currentMillis_led - previousMillis_led > interval_led) {
// сохраняем время последнего переключения
previousMillis_led = currentMillis_led;
// если светодиод не горит, то зажигаем, и наоборот
if (LedState == HIGH) LedState = LOW;
else LedState = HIGH;
digitalWrite(Led, LedState);
}
} else digitalWrite(Led, HIGH); // иначе гасим его
}
void ConsolePrint() { /// === консольная программа === ///
val.toLowerCase();
if (val.indexOf(F("reset")) > -1) { // сброс ЕЕПРОМ
Serial.println(F("Reset System!"));
EEPROM.write(0, 0);
eepromconfig();
}
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("phone")) > -1) { // инфо о телефонах
eepromphone();
}
if (val.indexOf(F("status")) > -1) { // инфо о состоянии системы
eepromconfig();
eepromtext();
}
if (val.indexOf(F("info")) > -1) { // запрос системы
Serial.println(Info1 + Info2 + Info3); //
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("sirenaon")) > -1) {
EEPROM.update(7, 1); // Sirena сирена вкл.
}
if (val.indexOf(F("sirenaoff")) > -1) {
EEPROM.update(7, 0); // Sirena сирена выкл.
}
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!!!"), RingPhone); // смс на последний номер
Serial.println(F("Reset System!!!"));
EEPROM.write(0, 0);
eepromconfig();
}
if ((p = val.indexOf(F("master"))) > -1) { // добавление мастер-номера
master(val.substring(p + 6, p + 7).toInt(), val.substring(p + 8, p + 19));
///// sms типа: " master1:79111234567 " - ячейка + номер
}
if ((p = val.indexOf(F("balance:"))) > -1) { // добавление номера баланса
balnum(val.substring(p + 8, p + 11));
///// sms типа: " balance:100 " - номер баланса
}
if ((p = val.indexOf(F("dell:"))) > -1) { // удаление номера из ячейки
dellphone(val.substring(p + 5, p + 6).toInt());
///// sms типа: " dell:1 " - удалить номер из ячейки 1
}
if (val.indexOf(F("phone")) > -1) { // инфо о состоянии системы
eepromphone();
for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) {
sms(String(String("Master") + i + String(":") + AlarmPhone[i]), RingPhone); // смс на последний номер
}
}
}
if (val.indexOf(F("info")) > -1) { // запрос баланса
sms(Info1 + Info2 + Info3, RingPhone); // смс на последний номер
}
if (val.indexOf(F("status")) > -1) { // инфо о состоянии системы
eepromconfig();
eepromtext();
sms(String(LastEvent), RingPhone); // смс на последний номер
}
if (val.indexOf(F("money")) > -1) { // запрос баланса
balance();
}
if (val.indexOf(F("sirenaon")) > -1) {
EEPROM.update(7, 1); // сирена вкл.
}
if (val.indexOf(F("sirenaoff")) > -1) {
EEPROM.update(7, 0); // сирена выкл.
}
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), 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), 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), 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), 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), 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), 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), 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), 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), 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), AlarmPhone[i]); // смс на все номера
}
}
}
void balance() { /// === проверка баланса сим-карты === ///
EEPROM.get(20, Bal); // считываем массив символов
delay(1000);
mySerial.println(String(F("ATD#")) + Bal + String(F("#")));
Serial.println(String("Balance#") + Bal + "#");
}
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"), RingPhone); // смс на 0 номер.
sms(String("Master: " + AlarmPhone[i]), AlarmPhone[i]); // смс на добавленный номер.
} else Serial.println(F("MAX number 4!")); // 4 номера максимум!
// 0 номер можно удалить только через RESET!!!
return 1;
}
int dellphone (int i) { /// === удаление мастeр-номеров === ///
if (i < 5 && i != 0) {
Serial.println(String(F("Master")) + i + String(F(" dell")));
sms(String(String("Master") + i + ":" + AlarmPhone[i] + " dell"), RingPhone); // смс на 0 номер
sms(String("Dell: " + AlarmPhone[i]), AlarmPhone[i]); // смс на удаленный номер.
EEPROM.put(Adress[i], 0);
AlarmPhone[i] = ""; // обнулим номер
} return 1;
}
int balnum (String num) { /// === добавляем номер баланса === ///
num.toCharArray(Bal, 4); // конвертируем
Serial.println(String(F("Balance:")) + Bal);
EEPROM.put(20, Bal); // записываем массив в EEPROM
sms(String("Balance:*" + num + "# Ok"), RingPhone); // смс на 0 номер
return 1;
}
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\n"));
}
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() { /// === инициализация модема === ///
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) { /// === отправка СМС === ///
if (phone != 0) {
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);
}
}
Два совета !
1 - вставьте правильно код !
2 - озвучьте размер бюджета "не бесплатной помощи" !
код большой.
ковыряться с ним вряд ли кто будет.
проще с нуля написать.
Ужасть.....купите готовое, это г....проще выкинуть, написать с нуля после полного описания что и когда должно делать устройство - от 8000 рублей + модем m590 и затраты на паяние макета для полноценного тестирования.
код большой.
ковыряться с ним вряд ли кто будет.
проще с нуля написать.
не просто большой, а еще и бестолковый. Сигнализация. в коде которой куча делеев, работа с модемом написана в "лучшем стиле ардуино" - то есть без проверки ответов - не имеет права на жизнь.
И я сильно сомневаюсь. что все это влезет в Нано и после этого будет работать :)
ТС - не зря прошлые авторы забросили проект. Последуй хорошему примеру :)
и еще - мне всегда было интересн смысл этого СМС оповещения?
Вот лежишь ты дома в постели, а тебе в 4 часа ночи приходит СМС "Запах газа!"
Ваши действия? :))))
Надеваешь противогаз (за нормативное время) и ползёшь на выход.
Надеваешь противогаз (за нормативное время) и ползёшь на выход.
противогаз сразу одевать необязательно, СМС-ка с дачи пришла :)
У меня есть готовые системы, отдам по 10 тыр, уже в корпусе и с антенной.
http://ydom.ru/item.html?page=yGuardPro
Джельтмены пишите на ватсап или в личку смету ориентировочную и свои контакты ..обсудим детали.. с Уважением.
Пишите подробное ТЗ, будем обсуждать
Andycat2013@yandex.ru
Могу доработать ваш скетч. Стоимость ориентировочно 6тр. fridgetester@mail.ru
ТС, абьявляй конкурс.
а как проводят конкурсы ? какие правила и где?
вставил прошивку ещо раз ..надеюсь теперь правильно
цену и время исполнения предлагайте свою, свяжусь с каждым и обсудим как мы это будем делать ?
и как вообще это делают ? так чтобы и заказчик и исполнитель остались довольны и не кто не кого не кинул ?
[code] #include <EEPROM.h> #include <OneWire.h> #include<SoftwareSerial.h> SoftwareSerial mySerial(2, 3); OneWire ds(4); // датчик температуры подключен к 4 пину, подтяжка 4.7кОм на +. #define DOOR 6 // концевик двери. #define PIR 9 // датчик движения. #define INPIR 7 // выход для подачи напряжения на свет #define Led 5 // состояние системы. моргает - на охране. #define GAS A0 // датчик дыма. #define BUZ 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 = 0; // 3. отправка смс при сработке: 1 - вкл, 0 - выкл. int8_t DOORon = 0; // 4. контроль концевиков дверей: 1 - вкл, 0 - выкл. int8_t PIRon = 1; // 5. контроль датчика движения: 1 - вкл, 0 - выкл. int8_t GASon = 0; // 6. контроль датчика дыма: 1 - вкл, 0 - выкл. int8_t Sirena = 1; // 7. сирена: 1 - вкл, 0 - выкл. int8_t DOORFlag = 0; // флаг состояние датчика двери. int8_t PIRFlag = 0; // флаг состояние датчика движения. int8_t GASFlag = 0; // флаг состояние датчика газа. int8_t DOORState = LOW; // Состояние концевика двери. int8_t PIRState = LOW; // Состояние датчика движения. // датчик висит в воздухе программно. аппаратно на минус через 10k. int8_t LedState = HIGH; // Состояние светодиода. int8_t Smoky = LOW; // Состояние датчика газа. int8_t Firststart; // первый старт. uint32_t msAT = 0; char Bal[4] = ""; // для временного хранения номера баланса. char Phone[12]; // для временного хранения номера телефона. //(если размер номера более 12 цифр нужно поменять на нужное количество по факту определителя как его видно на дисплее +1 ) byte Adress[5] = {25, 40, 55, 70, 85}; // ячейки для пяти номеров в ЕЕПРОМ. String val; // переменная для хранения пришедших данных. String temp; // переменная для хранения температуры. String CSQ; // переменная для хранения пришедших данных уровня сигнала. String LastEvent; // полное состояние системы. String RingPhone; // номер звонившего. String AlarmPhone[5]; // номера для постановки/снятии с охраны и отправки смс. String Info1 = "Kommanda - deistvie:\nstatus - sostoyanie\nmoney - balance\n"; // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ String Info2 = "sirenaon/off\nsystemon/off\nringon/off\nsmson/off\n"; String Info3 = "dooron/off\npiron/off\ngason/off"; int p = 0; int GASThres = 400; // предельная концентрация газа int interval_alarm = 20; // Секунд до отключения "тревожного" пина, max 300сек int previousMillis_alarm = 0; int interval_led = 1000; // для мигания Led int previousMillis_led = 0; int interval_door = 10; // секунд не смотрим на датчик двери int previousMillis_door = 0; int interval_pir = 10; // секунд не смотрим на датчик движения int previousMillis_pir = 0; int interval_gas = 60; // секунд не смотрим на датчик газа int previousMillis_gas = 0; /* EEPROM Data: № ячейки - значение: 0 - если записана не 1, то необходимо затереть eeprom и восстановить стандартную конфигурацию. 1 - Guard = 0; // охрана: 0 - выкл. 2 - AlarmRING = 1; // звонок: 1 - вкл. 3 - SendSMS = 1; // отправка смс: 1 - вкл. 4 - DOORon = 1; // концевик двери: 1 - вкл. 5 - PIRon = 1; // датчик движения: 1 - вкл. 6 - GASon = 1; // датчик дыма: 1 - вкл. 7 - Sirena = 1; // сирена: 1 - вкл. 10 - Firststars = 1; // первый запуск 1. 20 - ячейка памяти баланса, 25, 40, 55, 70, 85 - ячейки памяти телефонов. 100 - ячейка памяти номера последнего звонившего RingPhone. */ void setup() { /// === настройка программы === /// Serial.begin(9600); Serial.println(F("GSMTruck4.7")); pinMode(DOOR, INPUT_PULLUP); // вход датчика двери с подтяжкой на +. pinMode(PIR, INPUT); // вход датчика движения . pinMode(INPIR, OUTPUT); // определяем как выход pinMode(GAS, INPUT); pinMode(BUZ, OUTPUT); pinMode(Led, OUTPUT); // светодиод как выход. digitalWrite(BUZ, HIGH); // сирена выкл. digitalWrite(PIR, LOW); // отключаем внутренню подтяжку и вешаем сопротивлени 10k на GND для внешней подтяжки, чтобы не срабатывало на наводки InitModem(); // запускаем инициализация модема. eepromconfig(); eepromtext(); eepromphone(); digitalWrite(Led, HIGH); // гасим светодиод состояния сигнализации. } void loop() { /// === основной цикл программы === /// AlarmPinOff(); // выключаем сирену, если прошло время. if (Guard == 1) { // если на охране Detect(); // проверяем датчики. LED(); // моргаем светодиодом. Timeled(); // включаем свет и камеру при любом движении на заданное время. } 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), RingPhone); // смс на последний звонивший } else if (val.indexOf(F("+CSQ:")) > -1) { // пришел уровень сигнала сети int x = val.indexOf("+CSQ:"); CSQ = "Signal " + val.substring(x+5, x+7) + "%"; } 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 - номер наш! } } 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(String("Master0:" + num + " Ok"), num); // смс на звонивший // приходит смс в виде: " Master0:79111234567 Ok " } } return 1; } 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(7, 1); // Sirena сирена вкл. 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); // Датчик газа/дыма Sirena = EEPROM.read(7); // сирена Firststart = EEPROM.read(10); // } } void eepromtext() { /// === состояние системы === /// mySerial.println("AT+CSQ"); TempC(); delay(250); String SIGN = ""; // текущее состояние системы. String SIRENA = ""; // аварийная сирена. 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 (Sirena == 1) SIRENA = String(F("Sirena on\n")); else (SIRENA = String(F("Sirena 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 System = SIGN + SIRENA + RING + SMS; // состояние (вкл/выкл) системы. String Sensors = Pir + Door + Gas + temp; // состояние (вкл/выкл) датчиков. LastEvent = System + Sensors + CSQ; // полное состояние системы и датчиков. Serial.println(LastEvent); } void eepromphone() { /// === чтение мастер-номеров из EEPROM === /// for (int i = 0; i < 5 ; i++) { EEPROM.get(Adress[i], Phone); // считываем мастер-номера if (Phone != 0) AlarmPhone[i] = Phone; Serial.println(String(F("Phone[")) + i + String(F("]:")) + AlarmPhone[i]); } EEPROM.get(100, Phone); // считываем номер последнего звонившего RingPhone = Phone; Serial.println(String(F("Ring [ ]:")) + RingPhone); EEPROM.get(20, Bal); // считываем номер баланса Serial.println(String(F("Balance:")) + Bal); Firststart = EEPROM.read(10); // cчитаем первый старт Serial.println(String(F("Firststart:")) + Firststart); } void Detect() { /// === чтение датчиков === /// DOORState = digitalRead(DOOR); PIRState = digitalRead(PIR); Smoky = analogRead(GAS); if (DOORon == 1) { if (DOORState == HIGH && DOORFlag == 0) { previousMillis_door = millis(); DOORFlag = 1; Serial.println(F("Dver' otkrita!")); Alarm(); // } if (DOORState == LOW && DOORFlag == 1) { int currentMillis_door = millis(); if (((currentMillis_door - previousMillis_door) / 1000 > interval_door)) { DOORFlag = 0; } } } if (PIRon == 1) { if (PIRState == HIGH && PIRFlag == 0) { previousMillis_pir = millis(); PIRFlag = 1; Serial.println(F("Dvizhenie u dveri!")); // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ Alarm(); // } if (PIRState == LOW && PIRFlag == 1) { int currentMillis_pir = millis(); if (((currentMillis_pir - previousMillis_pir) / 1000 > interval_pir)) { PIRFlag = 0; } } } if (GASon == 1) { if ((Smoky > GASThres) && GASFlag == 0) { previousMillis_gas = millis(); GASFlag = 1; delay(100); Serial.println(F("Gas v dome!")); // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ Alarm(); // } if ((Smoky < GASThres) && GASFlag == 1) { int currentMillis_gas = millis(); if (((currentMillis_gas - previousMillis_gas) / 1000 > interval_gas)) { GASFlag = 0; } } } } void Timeled() { ///=== включаем свет и камеру === /// unsigned long curMil = millis(); const long interal = 3600000; // задаем время работы света и камеры желательно не менее цикла записи 3 минуты. >=200000 мс сейчас стоит 60 мин int8_t preMil = 0; if (Guard == 1 && PIRFlag == 1) { //PIRFlag == 1 заменить на PIRState == HIGH если будут проблемы со срабатыванием digitalWrite(INPIR, HIGH); } if ((curMil - preMil) >= interal) { preMil = curMil; digitalWrite(INPIR, LOW); } curMil = 0; } void Alarm() { /// === запускаем сирену и отправку смс === /// if (Guard == 1) { previousMillis_alarm = millis(); if (Sirena == 1) digitalWrite(BUZ, HIGH); Serial.println(F("Alarm!!!")); if (SendSMS == 1) { for (int i = 0; i < 5; i++) { // if (AlarmPhone[i] != 0) { if (DOORFlag == 1) { sms(String("Dver' otkrita!"), AlarmPhone[i]); // смс на все номера // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ } if (PIRFlag == 1) { sms(String("Dvizhenie y dveri!"), AlarmPhone[i]); // смс на все номера // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ } if (GASFlag == 1) { sms(String("Gas v dome!"), AlarmPhone[i]); // смс на все номера // поменять на ИСПАНСКИЙ ЛАТИНИЦЕЙ } } } if (AlarmRING == 1) { mySerial.println("ATD+" + String(AlarmPhone[0]) + ";"); // звоним первому номеру } } } void AlarmPinOff() { /// === если прошло время, отключаем сирену === /// int currentMillis_alarm = millis(); if (((currentMillis_alarm - previousMillis_alarm) / 1000 > interval_alarm) || Guard == 0) { digitalWrite(BUZ, LOW); } } void MasterRing() { /// === мастер звонков === // if (Guard == 1) GuardOff(); // меняем состояние else if (Guard == 0) GuardOn(); // меняем состояние } void GuardOff() { /// === выключение сигнализации === /// Guard = 0; EEPROM.update(1, Guard); Serial.println(String(F("System->off. Ring:")) + RingPhone); for (int i = 0; i < 5; i++) { // if (AlarmPhone[i] != 0) { sms(String("System->off " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера } } 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[i] != 0) { sms(String("System->on " + RingPhone + "\n" + temp), AlarmPhone[i]); // смс на все номера } } void LED() { /// === состояние светодиода === /// if (Guard == 1) { // если на охране int currentMillis_led = millis(); // светодиод моргает //проверяем не прошел ли нужный интервал, если прошел то if (currentMillis_led - previousMillis_led > interval_led) { // сохраняем время последнего переключения previousMillis_led = currentMillis_led; // если светодиод не горит, то зажигаем, и наоборот if (LedState == HIGH) LedState = LOW; else LedState = HIGH; digitalWrite(Led, LedState); } } else digitalWrite(Led, HIGH); // иначе гасим его } void ConsolePrint() { /// === консольная программа === /// val.toLowerCase(); if (val.indexOf(F("reset")) > -1) { // сброс ЕЕПРОМ Serial.println(F("Reset System!")); EEPROM.write(0, 0); eepromconfig(); } 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("phone")) > -1) { // инфо о телефонах eepromphone(); } if (val.indexOf(F("status")) > -1) { // инфо о состоянии системы eepromconfig(); eepromtext(); } if (val.indexOf(F("info")) > -1) { // запрос системы Serial.println(Info1 + Info2 + Info3); // } if (val.indexOf(F("money")) > -1) { // запрос баланса balance(); } if (val.indexOf(F("sirenaon")) > -1) { EEPROM.update(7, 1); // Sirena сирена вкл. } if (val.indexOf(F("sirenaoff")) > -1) { EEPROM.update(7, 0); // Sirena сирена выкл. } 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!!!"), RingPhone); // смс на последний номер Serial.println(F("Reset System!!!")); EEPROM.write(0, 0); eepromconfig(); } if ((p = val.indexOf(F("master"))) > -1) { // добавление мастер-номера master(val.substring(p + 6, p + 7).toInt(), val.substring(p + 8, p + 19)); ///// sms типа: " master1:79111234567 " - ячейка + номер } if ((p = val.indexOf(F("balance:"))) > -1) { // добавление номера баланса balnum(val.substring(p + 8, p + 11)); ///// sms типа: " balance:100 " - номер баланса } if ((p = val.indexOf(F("dell:"))) > -1) { // удаление номера из ячейки dellphone(val.substring(p + 5, p + 6).toInt()); ///// sms типа: " dell:1 " - удалить номер из ячейки 1 } if (val.indexOf(F("phone")) > -1) { // инфо о состоянии системы eepromphone(); for (int i = 0; i < 5 ; i++) if (AlarmPhone[i] != 0) { sms(String(String("Master") + i + String(":") + AlarmPhone[i]), RingPhone); // смс на последний номер } } } if (val.indexOf(F("info")) > -1) { // запрос баланса sms(Info1 + Info2 + Info3, RingPhone); // смс на последний номер } if (val.indexOf(F("status")) > -1) { // инфо о состоянии системы eepromconfig(); eepromtext(); sms(String(LastEvent), RingPhone); // смс на последний номер } if (val.indexOf(F("money")) > -1) { // запрос баланса balance(); } if (val.indexOf(F("sirenaon")) > -1) { EEPROM.update(7, 1); // сирена вкл. } if (val.indexOf(F("sirenaoff")) > -1) { EEPROM.update(7, 0); // сирена выкл. } 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), 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), 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), 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), 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), 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), 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), 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), 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), 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), AlarmPhone[i]); // смс на все номера } } } void balance() { /// === проверка баланса сим-карты === /// EEPROM.get(20, Bal); // считываем массив символов delay(1000); mySerial.println(String(F("ATD#")) + Bal + String(F("#"))); Serial.println(String("Balance#") + Bal + "#"); } 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"), RingPhone); // смс на 0 номер. sms(String("Master: " + AlarmPhone[i]), AlarmPhone[i]); // смс на добавленный номер. } else Serial.println(F("MAX number 4!")); // 4 номера максимум! // 0 номер можно удалить только через RESET!!! return 1; } int dellphone (int i) { /// === удаление мастeр-номеров === /// if (i < 5 && i != 0) { Serial.println(String(F("Master")) + i + String(F(" dell"))); sms(String(String("Master") + i + ":" + AlarmPhone[i] + " dell"), RingPhone); // смс на 0 номер sms(String("Dell: " + AlarmPhone[i]), AlarmPhone[i]); // смс на удаленный номер. EEPROM.put(Adress[i], 0); AlarmPhone[i] = ""; // обнулим номер } return 1; } int balnum (String num) { /// === добавляем номер баланса === /// num.toCharArray(Bal, 4); // конвертируем Serial.println(String(F("Balance:")) + Bal); EEPROM.put(20, Bal); // записываем массив в EEPROM sms(String("Balance:*" + num + "# Ok"), RingPhone); // смс на 0 номер return 1; } 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\n")); } 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() { /// === инициализация модема === /// 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) { /// === отправка СМС === /// if (phone != 0) { 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); } } [/code]а это команды управления ..работает только на прием смс но не отстукивает команды типа
info - меню помощи с командами в виде смс
ТЗ наверно такое
сделать так чтобы при срабатывания датчиков джижения газа и температуры
на телефоный номер или группу номеров приходило сообщение о взломе или пожаре плюс включалась сирена и светодиоды типа фар
так же по смс запросу система отстукивала о своем статусе включена она или не включена и состояние датчиков
постановка на охрану и снятие по звонку и по смс
тоесть все примерно как уже реализовано
НО ещо не мешало бы дописать если это возможно примерно такую функцию при не долгом срабатывании датчика или датчиков движения
скажем менее 10 секунд
сирена орала не долго скажем секунд 5 но без отсылки смс о тревоге
а если датчик движения постоянно регистрирует двжижение скажем более 10 секунд (или многократно и часто )
смысл чтобы не было лишних фальш срабатываний от того что кто то рядом прошел
и ещо если возможно чтобы при постанвки систему на охрану и снятию тоже она сама кидала смс о своем
статусе с текстом типа alarm on / alarm off
можете написать свою прошивку можете доработать имеющуюся ..это без разницы
имеющяся прошивка залазит в ардуино нано 3.0 (где то около 87% занимая память)
+
1 версия прошивки это под работу датчиков движения пирометрического датчика + емкосного + газового и температурного
2 версия это под работу датчика движения микроволнового датчика точно такого как по ссылке в первом посте + газового и температурного)
а так же подсказать куда припаять емкостной датчик которого нет в изначяльном проэкте в уже имеющуюсю плату для работы в паре с пиродатчиком
и подсказать куда и как подпаять версию на микроволновом датчике
заказчик хочет просто доработать имеющийся уже проэкт потому что под него распечатаны платы и куплены детали
электронную схемы системы буду скидывать уже в привате
и ещо говорят м590 глючный и его уже сняли с производства . может быть имеет смысл поменять на другой чип если это целесообразно ?
ну вот вроде бы ничего не забыл в ТЗ надеюсь что составил его понятно, если будут вопросы задавайте уточним
жаль что на форуме нет лички поэтому скину мой емайл rap1db0xer@gmail.com
заказчик предлогает оплату заказа оформить все через платформу типа freelance.ru или подобное когда деньги за заказ переводятся платформе посреднику и до выполения заказа замораживаются на счету этой платформы посредника
вы можете предложить другую платформу но он настаивает на оплате после того как работа была выполнена
вы можете предложить другую платформу но он настаивает на оплате после того как работа была выполнена
это +50% к цене
дак и надо искать исполнителя тогда на freelance.ru
Тут одних переговоров тыщи на три ))
ТС получается посредник, фриланс тож посредник и комсу берет насколько мне известно. Цепочка достойная госзакупок выходит. Удачи.
TC скажем так будет все это на месте собирать спаивать и отлаживать по сути
а платит за все заказчик который и есть конечный бенефециар системы если ее довести до ума
TC скажем так будет все это на месте собирать спаивать и отлаживать по сути
а платит за все заказчик который и есть конечный бенефециар системы если ее довести до ума
вы бы ему дали почитать эту ветку :)
Пишу специально для него - сама идея бредовая, платить за нее смешно. Купите готовое .
я думаю заказчика более интересует быстрое и качественое выполенние заказа и сопровождение проэкта
чем лишние 50%
называйте сумму ,примерные сроки, уточняйте ТЗ или предлогайте внести в ТЗ коррективы
тот кто эту систему разработал вышел из проэкта не оставил полной сопроводительной документации и рабочей
прошивки
на данный момент собраны две платы одна мной другая самим разработчиком обе ведут себя на этой прошивке одинаково
кроме того что добавить емкосной датчик в схему ИЛИ заменить пирометрический микроволновым + рабочая прошивка
более по сути проблем которые мы не сможем решить на месте не наблюдаю
так заказчик и почитывает ветку )
он заказал эту систему разработчику ..купил готовое ..и купил сырого не доделаного кота в мешке
второго сырого кота он не хочет ..а просто хочет по быстрому доделать имеющегося кота из сырого в сваренного
МКВ-датчик будет обнаруживать всех котов в округе - хоть в мешке, хоть без.
видима, разрабоччиком был карамзин.
Тут есть и другие умельцы слиться втихую ;)
я тоже о котах думал в радиусе .. но заказчик говорил что котов и собак с голубями там нет, в чем я лично сомневаюсь
поэтому и есть мысль что собрать два варианта на пиродатчике защищеного емкосным
и просто на микроволновом и проверит в реальных условиях что лутче ...
хотя я все равно не верю что там не залетит какой нибуть воробей или не пробежит ящерица или крыса не на делает ложных срабатываний
просто сигналка на одном пиродатчике очень уязвима ..накинул на него тряпку или встал за лист фанеры а то и кусок коробки .. и он тебя уже не видит и ты делай что хочеш
микроволновый так не надуеш насколько я понимаю .. думаю все же надо сразу делать проэкт на одном микроволновом
в том месте где будет стоять пиродатчик все равно его не прикрыть надежно ... емкосным
... проэкт разрабатывал человек явно не понимающий что такое защита периметра и что такое сигнализация вообще ... так мигающяя свистелка которую надо доводить до ума чтобы она стала сигнализацией а не игрушкой
А, ну да, я забыл. Вместо того, чтобы обратица сразу к людям, знающим что такое защита периметра, мы заплотим в три раза больше разным исполнителям подешевле, но нихрена в этом не понимающим. Экономия по-русски.
Тупой платит трижды.
есть такое дело .. сыр только в мышеловке дешовый .
вношу коррективы в ТЗ
вообщем да таки надо собирать только 1 версию на микроволновом
пиродатчик слишком легко надуть и не возможно в той зоне прикрыть ничем
от ложных срабатываний микроволновый прикрыть алгоритмом
1 если кот проходит рядом пищим и светим 3 секунды без отсыла смс
2 если кот или жулик почему то задержался в охраняемой зоне более 20 секунд то идет смс оповещение
орем сиреной и светим лампочками пока обьект не уйдет и продолжаем светить и орать ещо минуты 2
делать по такому ТЗ сигналку - проще и дешевле купить у китайцев муляж имперского штурмового лазера, перемещающегося на движение. И по утрам собирать навоз по периметру.
alexBCN , одно только уточнение по Вашему "ТЗ" займет несколько дней, посчитайте для примера свою рабочую неделю в рублях - Вы готовы оплачивать все это?
ЗЫ. Скучный / не интересный проект.
P.P.S. Вот вам свеженький пример (сигнализацией язык не поворачивается назвать) СМС информера о произошедшем событии, без задержек delay в основном цикле и без Software Serial, добавьте туда побольше датчиков и будет вам счастье.
#include <avr/wdt.h> #include <avr\pgmspace.h> #include <EEPROM.h> char phoneMain[] = "7920*******"; // admin phone const char at21cmd[] PROGMEM = "AT+CUSD=1,*100#,15\r\n"; // USSD string get balance #define DOOR_CONTROL #define EXT_POW_CONTROL #define USE_DS18B20 #ifdef EXT_POW_CONTROL #define ext_pow_pin (byte)5 // 2 <--> 5 test #define READEXTPOW digitalRead(ext_pow_pin) #define delaySMSpowerOFF 120000UL // задержка 2 минут отправки СМС при отключении питания #define delaySMSpowerON 120000UL // задержка 2 минут отправки СМС при включении питания unsigned long timer_power_on_off; byte startPowerTimer; byte lastPower220; #endif #ifdef DOOR_CONTROL #define key_pin (byte)2 // 5 <--> 2 test #define READKEY !digitalRead(key_pin) #define delay_alarm_door 600000UL unsigned long timer_alarm_door = 0; byte flsend_alarm_door; #endif #ifdef USE_DS18B20 #include <OneWire.h> #include <DallasTemperature.h> #define TEMPERATURE_PRECISION 9 // точность получения значения темературы #define ds18_pin A0 // pin DS18B20 OneWire oneWire(ds18_pin); // объект 1Ware DallasTemperature sensors(&oneWire); // объект датчика температуты byte dsCount; // количество датчиков температуры #define max_ds_count 5 // максимальное количество датчиков DeviceAddress massTherm[max_ds_count]; // массив адресов датчиков ds18b20 #define period_get_temp 780137UL // получение температуры каждые 13 min unsigned long timer_get_temp; // таймер получения температуры word massTemper[max_ds_count]; //массив температур byte requestTemp = 1; // запрос температуры #endif #define bLedOn HIGH #define led1_pin (byte)9 // status led #define LED1ON digitalWrite(led1_pin,bLedOn) #define LED1OFF digitalWrite(led1_pin,!bLedOn) #define led2_pin (byte)4 // error led #define LED2ON digitalWrite(led2_pin,bLedOn) #define LED2OFF digitalWrite(led2_pin,!bLedOn) #define reset_A6_pin (byte)7 #define power_A6_pin (byte)8 #define count_ext_commands 4 // count external commands from incoming sms byte deviceMode = 1; // 1 = сигнализация включена byte flGetBalance; byte FirstStart; #define period_wait_phone 30000UL // ждем 30 секунд после инициализации модема звонка чтоб записать админский номер unsigned long timer_wait_phone; byte flag_wait_phone; #define pos_eeprom_flag_saved_admin_phone 67 // value 139 - exist phone #define pos_eeprom_admin_phone 76 unsigned long timer_reg_modem; // timer registration modem in net #define max_size_pgm_buf 128 char pgm_buf[max_size_pgm_buf]; #define period_read_sms 29971UL // read sms every ~30 sec unsigned long timer_read_sms = 0; // timer read sms #define period_send_sms 8937UL // send sms every ~9 sec unsigned long timer_send_sms = 0; // timer read sms #define max_size_fixed_resp 16 // in work save 3 response from buf commands char resp1[max_size_fixed_resp]; char resp2[max_size_fixed_resp]; char resp3[max_size_fixed_resp]; // 3 parts response byte flresp1, flresp2, flresp3; // found parts of response #define max_size_sms_buf 110 // max size sms with stop byte and text uptime char sms_buf[max_size_sms_buf]; // sms buf char sender[13]; // phone number for send sms. +7 and 10 digits + stop byte = always 13 digits!!! #define max_size_resp_buf 254 // max size response buf from modem, then more than goodest char resp_buf[max_size_resp_buf]; // response buf from modem byte pos_buf; // current pos response buf byte ledStatus, ledError, flLedSt, flLedEr; // ledError // 0 - normal work, modem status 101, 1 flash per 3 sec // 1 - init modem status 100, 1 flash per 1 sec // 2 - problem modem, no response, flash everu 20 milli sec,reset modem and new start // ledStatus // number flash per 3 sec = number modem step < 100 unsigned long timer_led_status, timer_led_error; byte modem_step; // current work mode mode in table of command // static steps: // 100 - delay for registration modem in net // 101 - not wait response, wait incomming call or other commands byte wait_response; // 0-no wait response, wait ring or other command // 1-wait fixed response, if time more - reset modem #define period_fixed_wait 15000UL // max time for type 1 wait response // 2-wait response data or wait action user, if time more - clear command #define period_data_wait 15000UL // max time for type 2 wait response unsigned long current_millis; uint8_t mcusr_mirror __attribute__ ((section (".noinit"))); void get_mcusr(void) \ __attribute__((naked)) \ __attribute__((used)) \ __attribute__((section(".init3"))); void get_mcusr(void) { mcusr_mirror = MCUSR; MCUSR = 0; wdt_disable(); } void setup() { MCUSR = 0; wdt_disable(); Serial.begin(9600); // modem speed // read mainPhone from EEPROM if ((EEPROM.read(pos_eeprom_flag_saved_admin_phone) == 139)) { for (byte i = 0; i < 11; ++i) phoneMain[i] = EEPROM.read(pos_eeprom_admin_phone + i); phoneMain[11] = 0; } #ifdef USE_DS18B20 sensors.begin(); // инициировать датчики температуры dsCount = sensors.getDeviceCount(); // получить количество датчиков if (dsCount > max_ds_count) dsCount = max_ds_count; // если датчиков больше чем максимальное - уменьшаем oneWire.reset_search(); // сброс шины поиска датчиков byte i = 0; while (i < dsCount) { // цикл по всем датчикам if (sensors.getAddress(massTherm[i], i)) sensors.setResolution(massTherm[i], TEMPERATURE_PRECISION); ++i; } #endif // put your setup code here, to run once: initAll(); wdt_enable(WDTO_8S); } void loop() { wdt_reset(); //delay(9000); // test WDT current_millis = millis(); // put your main code here, to run repeatedly: flashLed(); // read sms if (((current_millis - timer_read_sms) >= period_read_sms) && (wait_response == 0) && (modem_step == 101)) { timer_read_sms = current_millis; // reset timer read sms // set mode read sms modem_step = 9; } // send sms if (((current_millis - timer_send_sms) >= period_send_sms) && (wait_response == 0) && (modem_step == 101) && (sender[0] > 0) && (sms_buf[0] > 0)) { timer_send_sms = current_millis; // reset timer send sms // send sms modem_step = 11; } // door control #ifdef DOOR_CONTROL if ((READKEY) && (deviceMode)) { if ((!flsend_alarm_door) && (modem_step != 100)) { flsend_alarm_door = 1; sendSMS(phoneMain, (char*) "Alarm! Door opened! "); timer_alarm_door = current_millis; } } if (flsend_alarm_door) if ((current_millis - timer_alarm_door) >= delay_alarm_door) flsend_alarm_door = 0; #endif // external power control #ifdef EXT_POW_CONTROL // power 220V control if (startPowerTimer) { byte currentPower = READEXTPOW; if (lastPower220) { if (!currentPower) { startPowerTimer = 0; lastPower220 = currentPower; } else { if ((current_millis - timer_power_on_off) >= delaySMSpowerON) { startPowerTimer = 0; sendSMS(phoneMain, (char *) "Power AC220 ON "); } } } else { if (currentPower) { startPowerTimer = 0; lastPower220 = currentPower; } else { if ((current_millis - timer_power_on_off) >= delaySMSpowerOFF) { startPowerTimer = 0; sendSMS(phoneMain, (char *) "Alarm! Power AC220 OFF "); } } } } else { if (READEXTPOW != lastPower220) { startPowerTimer = 1; timer_power_on_off = current_millis; lastPower220 = READEXTPOW; } } #endif // get balance if ((wait_response == 0) && (modem_step == 101) && (flGetBalance)) { flGetBalance = 0; modem_step = 21; } #ifdef USE_DS18B20 if (((current_millis - timer_get_temp) >= period_get_temp) && (wait_response == 0) && (modem_step == 101)) { if (requestTemp) { sensors.requestTemperatures(); requestTemp = 0; } else if ((current_millis - timer_get_temp) >= (period_get_temp + 200UL)) { // for 9 bit PRECISION timer_get_temp = current_millis; requestTemp = 1; byte i = 0; while (i < dsCount) { float tct = sensors.getTempC(massTherm[i]); if (tct < 0) massTemper[i] = ((-tct) * 10) + 2000; else massTemper[i] = (tct * 10); ++i; } } } #endif // modem work loadDataFromModem(); // load data mainLoopModem(); // main actions on modem } void initAll() { #ifdef DOOR_CONTROL pinMode(key_pin, INPUT_PULLUP); flsend_alarm_door = 0; #endif #ifdef EXT_POW_CONTROL pinMode(ext_pow_pin, INPUT_PULLUP); lastPower220 = READEXTPOW; startPowerTimer = 0; #endif pinMode(led1_pin, OUTPUT); LED1OFF; pinMode(led2_pin, OUTPUT); LED2OFF; pinMode(reset_A6_pin, OUTPUT); pinMode(power_A6_pin, OUTPUT); initModem(); ledError = 1; // 1 = modem status 100 deviceMode = 1; } void initModem() { digitalWrite(reset_A6_pin, LOW); digitalWrite(power_A6_pin, HIGH); while ((millis() - current_millis) <= 3200UL) { Serial.print("AT\r\n"); delay(100); } modem_step = 100; // first step = wait modem for registration on net wait_response = 0; // no wait response sms_buf[0] = 0; // clear sms sender[0] = 0; // clear sender timer_reg_modem = millis(); pos_buf = 0; resp_buf[pos_buf] = 0; ledStatus = 0; flGetBalance = 0; flag_wait_phone = 0; FirstStart = 1; } void resetModem() { ledError = 2; digitalWrite(reset_A6_pin, HIGH); delay(500); initModem(); } void flashLed() { // led1 - led status if ((ledStatus > 0) && (ledStatus <= 15)) { if ((current_millis - timer_led_status) >= (3000UL + (250UL * flLedSt))) { if (flLedSt >= (ledStatus * 2)) { LED1OFF; flLedSt = 0; timer_led_status = current_millis; } else { if (bitRead(flLedSt, 0)) LED1OFF; else LED1ON; ++flLedSt; } } } else { LED1OFF; } // led2 - led error switch (ledError) { case 1: { if ((current_millis - timer_led_error) >= 1000UL) { if (flLedEr) { if ((current_millis - timer_led_error) >= 1050UL) { timer_led_error = current_millis; LED2OFF; flLedEr = 0; } } else { LED2ON; flLedEr = 1; } } break; } case 2: { if ((current_millis - timer_led_error) >= 50UL) { if (flLedEr) { if ((current_millis - timer_led_error) >= 100UL) { timer_led_error = current_millis; LED2OFF; flLedEr = 0; } } else { LED2ON; flLedEr = 1; } } break; } default: { if ((current_millis - timer_led_error) >= 3000UL) { if (flLedEr) { if ((current_millis - timer_led_error) >= 3050UL) { timer_led_error = current_millis; LED2OFF; flLedEr = 0; } } else { LED2ON; flLedEr = 1; } } } } } const char at0cmd[] PROGMEM = "AT\r\n"; // 0 const char at1cmd[] PROGMEM = "AT+DDET=1\r\n"; const char at2cmd[] PROGMEM = "ATE0\r\n"; // 1 const char at3cmd[] PROGMEM = "AT+CLIP=1\r\n"; // 3 const char at4cmd[] PROGMEM = "ATS0=5\r\n"; // 4 const char at5cmd[] PROGMEM = "ATV1\r\n"; // 2 const char at6cmd[] PROGMEM = "AT+CMEE=2\r\n"; const char at7cmd[] PROGMEM = "AT+CMGF=1\r\n"; // 6 const char at8cmd[] PROGMEM = "AT+CREG?\r\n"; const char at8resp1[] PROGMEM = "+CREG:"; const char at8resp2[] PROGMEM = ",1"; // 5 const char at9cmd[] PROGMEM = "AT+CMGL=\"ALL\"\r\n"; const char at10cmd[] PROGMEM = "AT+CMGD=1,4\r\n"; // 7 const char at11cmd[] PROGMEM = "AT+CMGS=\""; const char at12cmd[] PROGMEM = "~sender~"; const char at13cmd[] PROGMEM = "\r\n"; const char at13resp1[] PROGMEM = ">"; const char at14cmd[] PROGMEM = "~textsms~"; const char at15cmd[] PROGMEM = "~ctrlz~"; const char at15resp1[] PROGMEM = "+CMGS:"; const char at16cmd[] PROGMEM = "ATA\r\n"; const char at16resp2[] PROGMEM = "NO CARRIER"; const char at17cmd[] PROGMEM = "ATH\r\n"; const char at18cmd[] PROGMEM = "\""; const char at19cmd[] PROGMEM = "AT+CSQ\r\n"; const char at19resp1[] PROGMEM = "+CSQ:"; const char at19resp2[] PROGMEM = ","; const char at20cmd[] PROGMEM = "AT+GSN\r\n"; // get imei const char atOKcmd[] PROGMEM = "OK"; const char atOKRNcmd[] PROGMEM = "OK\r\n"; const char atNULLcmd[] PROGMEM = ""; const char at1status[] PROGMEM = "1"; const char at2status[] PROGMEM = "2"; const char at1step[] PROGMEM = "1"; const char at2step[] PROGMEM = "2"; const char at3step[] PROGMEM = "3"; const char at4step[] PROGMEM = "4"; const char at5step[] PROGMEM = "5"; const char at6step[] PROGMEM = "6"; const char at7step[] PROGMEM = "7"; const char at8step[] PROGMEM = "8"; const char at9step[] PROGMEM = "9"; const char at10step[] PROGMEM = "10"; const char at11step[] PROGMEM = "11"; const char at12step[] PROGMEM = "12"; const char at13step[] PROGMEM = "13"; const char at14step[] PROGMEM = "14"; const char at15step[] PROGMEM = "15"; const char at16step[] PROGMEM = "16"; const char at17step[] PROGMEM = "17"; const char at18step[] PROGMEM = "18"; const char at19step[] PROGMEM = "19"; const char at101step[] PROGMEM = "101"; const char at20step[] PROGMEM = "20"; const char at21resp1[] PROGMEM = "+CUSD: 2,"; const char at21resp2[] PROGMEM = ",72\r\n"; const char * const str_at[] PROGMEM = { // record of AT commands at0cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at2step, at1cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at2step, at2cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at3step, at3cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at4step, at4cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at5step, at5cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at7step, at6cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at7step, at7cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at8step, at8cmd, at8resp1, at8resp2, atOKcmd, at1status, at20step, at9cmd, atOKRNcmd, atNULLcmd, atNULLcmd, at1status, at101step, at10cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at101step, at11cmd, atNULLcmd, atNULLcmd, atNULLcmd, at1status, at12step, at12cmd, atNULLcmd, atNULLcmd, atNULLcmd, at1status, at18step, at13cmd, at13resp1, atNULLcmd, atNULLcmd, at1status, at14step, at14cmd, atNULLcmd, atNULLcmd, atNULLcmd, at1status, at15step, at15cmd, at15resp1, atOKcmd, atNULLcmd, at1status, at101step, at16cmd, atOKRNcmd, at16resp2, atNULLcmd, at2status, at101step, at17cmd, atOKRNcmd, atNULLcmd, atNULLcmd, at1status, at101step, at18cmd, atNULLcmd, atNULLcmd, atNULLcmd, at1status, at13step, at19cmd, at19resp1, at19resp2, atOKcmd, at1status, at101step, at20cmd, atOKcmd, atNULLcmd, atNULLcmd, at1status, at10step, // get imei and go to 10 cmd - last cmd for init - delete sms at21cmd, atOKRNcmd, at21resp1, at21resp2, at1status, at101step }; void getPgmBuf(byte idxPgmBuf) { const char * addrStroki = pgm_read_word_near((int)(str_at + idxPgmBuf)); strcpy_P(pgm_buf, addrStroki); } void loadDataFromModem() { // load data from modem to buf - only one line (string) if (Serial.available()) { byte br; while (Serial.available()) { br = Serial.read(); if (br) { if (pos_buf >= (max_size_resp_buf - 1)) pos_buf = 0; resp_buf[pos_buf] = br; ++pos_buf; if (br == '\n') if ((pos_buf > 1) && (resp_buf[pos_buf - 2] == '\r')) break; // new string*/ } } resp_buf[pos_buf] = 0; // stop byte of string } } void mainLoopModem() { // main action modem switch (modem_step) { case 100: { if ((current_millis - timer_reg_modem) >= 20000UL) { // wait 20sec registration modem wait_response = 0; // do not response modem_step = 0; // go to init modem mode - first command } break; } case 101: { ledError = 0; ledStatus = 0; if (FirstStart) { FirstStart = 0; flag_wait_phone = 1; timer_wait_phone = current_millis; } if (pos_buf == 0) break; // no response // find ring and other commands and execute if (flag_wait_phone) { if ((current_millis - timer_wait_phone) < period_wait_phone) { byte pb1 = posSubStrFromPos(resp_buf, pos_buf, (char *) "+CLIP: \"79", 0); char testPhone[12]; if ((pb1) && (pos_buf > (pb1 + 20))) { // save to EEPROM EEPROM.write(pos_eeprom_flag_saved_admin_phone, 139); for (byte i = 0; i < 11; ++i) { byte bc = resp_buf[i + pb1 + 7]; phoneMain[i] = bc; EEPROM.write(pos_eeprom_admin_phone + i, bc); } phoneMain[11] = 0; EEPROM.write(pos_eeprom_admin_phone + 11, 0); flag_wait_phone = 0; wait_response = 0; modem_step = 17; // answer on ring 16 or break ring 17 break; } } else { flag_wait_phone = 0; } } // other find break; } default: { switch (wait_response) { case 0: { sendAtCommand(modem_step); // send command to modem break; } case 1: { if ((current_millis - timer_reg_modem) >= period_fixed_wait) { // if end timer wait response resetModem(); // we have problem - no correct response from modem } else { if (pos_buf == 0) break; // no response // action before find response, example long ussd if (findRespParts() == 1) { // need fixed response // good response from modem // other action on one item command switch (modem_step) { case 15: { // end send sms sender[0] = 0; sms_buf[0] = 0; // clear sms buf // go to next step wait_response = 0; // do not wait response getPgmBuf(6 * modem_step + 5); modem_step = strToByte(pgm_buf); // to next at command or mode break; } case 9: { // read all sms // find command from sms if (posSubStrFromPos(resp_buf, pos_buf, (char*) "+CMGL: ", 0) > 0) { // we have sms int sbeg = 0; int spos; lsms1: if (sbeg < pos_buf) { spos = posSubStrFromPos(resp_buf, pos_buf, (char*) "+CMGL: ", sbeg); if (spos > 0) { spos += 7; if (spos < pos_buf) { spos = posSubStrFromPos(resp_buf, pos_buf, phoneMain, spos); if (spos > 0) { spos += 7; spos = posSubStrFromPos(resp_buf, pos_buf, (char*) "\r\n", spos); if (spos > 0) { ++spos; // begin text sms byte ends = posSubStrFromPos(resp_buf, pos_buf, (char*) "\r\n", spos); // end text sms if (ends > 0) { for (byte i = 0; i < count_ext_commands; ++i) { getExtBuf(i); if (posSubStrFromPos(resp_buf, ends, pgm_buf, spos) > 0) { execExtCmd(i); break; } } sbeg = ends; goto lsms1; } } } } } } // go to step delete SMS wait_response = 0; // do not wait response modem_step = 10; // step 10 } else { // go to next step wait_response = 0; // do not wait response getPgmBuf(6 * modem_step + 5); modem_step = strToByte(pgm_buf); // to next at command or mode } break; } default: { // go to next step wait_response = 0; // do not wait response getPgmBuf(6 * modem_step + 5); modem_step = strToByte(pgm_buf); // to next at command or mode } } } } break; } case 2: { if ((current_millis - timer_reg_modem) >= period_data_wait) { // if end timer wait response // no data or no user action // exit from command // go to next step wait_response = 0; // do not wait response getPgmBuf(6 * modem_step + 5); modem_step = strToByte(pgm_buf); // to next at command or mode } else { if (pos_buf == 0) break; // no response // read parts of sms or other commands or DTMF // go to next step after actions wait_response = 0; // do not wait response getPgmBuf(6 * modem_step + 5); modem_step = strToByte(pgm_buf); // to next at command or mode } break; } default: { // go to next step after actions wait_response = 0; // do not wait response getPgmBuf(6 * modem_step + 5); modem_step = strToByte(pgm_buf); // to next at command or mode } } } } } int strPos(char *str11, char *str22) { // find position substring in string char*p = LastPos(str11, str22); int n = p - str11; return n; } char* LastPos(char *str1, char *str2) { // find substring in string int L1 = strlen(str1); int L2 = strlen(str2); for (int i = L1 - L2; i >= 0; i--) { int j = 0; for (; j < L2; j++) if ((str1[i + j] != str2[j])) break; if (j == L2) return str1 + i; } return 0; } void sendAtCommand(byte numcmd) { // send at command if modem not busy // find key worlds getPgmBuf(6 * numcmd); if (posSubStrFromPos(pgm_buf, strlen(pgm_buf), (char *) "~sender~", 0) > 0) { Serial.print(sender); } else if (posSubStrFromPos(pgm_buf, strlen(pgm_buf), (char *) "~textsms~", 0) > 0) { Serial.print(sms_buf); } else if (posSubStrFromPos(pgm_buf, strlen(pgm_buf), (char *) "~ctrlz~", 0) > 0) { Serial.print(char(26)); } else { Serial.print(pgm_buf); // send cmd from cmd buf by number cmd } timer_reg_modem = current_millis; // reset wait response timer // load response from command to buf getPgmBuf(6 * numcmd + 1); if (pgm_buf[0] == 0) { // no response resp1[0] = 0; resp2[0] = 0; resp3[0] = 0; // no response wait_response = 0; getPgmBuf(6 * numcmd + 5); modem_step = strToByte(pgm_buf); // go to next step or mode pos_buf = 0; // clear response buf return; // next loop } else { getPgmBuf(6 * numcmd + 1); byte i = 0; while ((resp1[i] = pgm_buf[i]) > 0) ++i; resp1[i] = 0; // save first response from buf at cmd getPgmBuf(6 * numcmd + 2); if (pgm_buf[0] == 0) { // no second response resp2[0] = 0; resp3[0] = 0; // no response 2 and 3 } else { byte i = 0; while ((resp2[i] = pgm_buf[i]) > 0) ++i; resp2[i] = 0; // save secont response from buf at cmd getPgmBuf(6 * numcmd + 3); if (pgm_buf[0] == 0) { // no thr response resp3[0] = 0; // no response 3 } else { byte i = 0; while ((resp3[i] = pgm_buf[i]) > 0) ++i; resp3[i] = 0; // save thr response from buf at cmd } } } getPgmBuf(6 * numcmd + 4); wait_response = strToByte(pgm_buf); // set wait resp from command buf flresp1 = 0; flresp2 = 0; flresp3 = 0; // clear result response pos_buf = 0; resp_buf[pos_buf] = 0; // clear response buf ledStatus = numcmd + 1; ledError = 0; } byte strToByte(char *instr) { byte sl = strlen(instr); if (sl < 1) return 0; byte res = 0, i = 0; while (instr[i] > 0) { res += ((instr[i] - '0') * pow(10, (sl - i - 1))); ++i; } if (sl > 2) ++res; return res; } byte posSubStrFromPos(char *inBuf, byte maxPosBuf, char *subStr, byte resPos) { if (resPos >= maxPosBuf) return 0; while ((resPos < maxPosBuf) && (inBuf[resPos] > 0)) { byte isub = 0; if (inBuf[resPos] == subStr[isub]) { byte sslen = strlen(subStr); while (((resPos + isub) < maxPosBuf) && (inBuf[resPos + isub] > 0) && (isub < sslen)) { if (subStr[isub] != inBuf[resPos + isub]) break; ++isub; } if (isub >= sslen) { ++resPos; return resPos; } } ++resPos; } return 0; } byte findRespParts() { // find response parts in response buf byte countresp = 0, countgood = 0; if (resp1[0] > 0) { // exist response 1 ++countresp; if (strPos(resp_buf, resp1) >= 0) { flresp1 = 1; // found response 1 } if (resp2[0] > 0) { // exist response 2 ++countresp; if (strPos(resp_buf, resp2 ) >= 0) { flresp2 = 1; // found response 2 } if (resp3[0] > 0) { // exist response 3 ++countresp; if (strPos(resp_buf, resp3) >= 0) { flresp3 = 1; // found response 3 } } } } if (flresp1 == 1) { ++countgood; } if (flresp2 == 1) { ++countgood; } if (flresp3 == 1) { ++countgood; // calculate good response } if ((countresp > 0) && (countresp == countgood)) return 1; else return 0; } const char ex0cmd[] PROGMEM = "getstatus"; const char ex1cmd[] PROGMEM = "poweroff"; const char ex2cmd[] PROGMEM = "poweron"; const char ex3cmd[] PROGMEM = "getbalance"; const char * const ext_pgm_cmd[] PROGMEM = { ex0cmd, ex1cmd, ex2cmd, ex3cmd }; void getExtBuf(byte idxPgmBuf) { const char * addrStroki = pgm_read_word_near((int)(ext_pgm_cmd + idxPgmBuf)); strcpy_P(pgm_buf, addrStroki); } void execExtCmd(byte numCmd) { switch (numCmd) { case 0: { if (deviceMode) sendSMS(phoneMain, (char*) "Power ON "); sendSMS(phoneMain, (char*) "Power OFF "); break; } case 1: { deviceMode = 0; break; } case 2: { deviceMode = 1; break; } case 3: { flGetBalance = 1; break; } default: {} } } void sendSMS(char *phnum, char *txtsms) { // prepare sender phone number and text for sms sender[0] = 0; sms_buf[0] = 0; strcpy(sender, "+"); strcat(sender, phnum); strcpy(sms_buf, txtsms); byte i = strlen(sms_buf); i = addTextUptime(sms_buf, i , max_size_sms_buf); // add uptime text to sms buf sms_buf[i] = 0; #ifdef USE_DS18B20 if (dsCount) { i = addTextTemp0(sms_buf, i , max_size_sms_buf); // add DS18B20 temp idx 0 to sms buf sms_buf[i] = 0; } #endif timer_send_sms = current_millis; // reset timer send sms timer_read_sms = current_millis; // reset timer read sms } byte addTextUptime(char *text, byte firstpos, byte maxsize) { // add uptime text to input text byte days = current_millis / 86400000UL; byte hours = (current_millis % 86400000UL) / 3600000UL; byte mins = ((current_millis % 86400000UL) % 3600000UL) / 60000UL; if (firstpos >= (maxsize - 1)) return firstpos; text[firstpos] = 'u'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; if (days > 9) { text[firstpos] = (days / 10) + '0'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; } text[firstpos] = (days % 10) + '0'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; text[firstpos] = 'd'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; if (hours > 9) { text[firstpos] = (hours / 10) + '0'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; } text[firstpos] = (hours % 10) + '0'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; text[firstpos] = 'h'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; if (mins > 9) { text[firstpos] = (mins / 10) + '0'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; } text[firstpos] = (mins % 10) + '0'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; text[firstpos] = 'm'; ++firstpos; return firstpos; } byte addTextTemp0(char *text, byte firstpos, byte maxsize) { // add uptime text to input text if (firstpos >= (maxsize - 1)) return firstpos; text[firstpos] = ' '; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; word ttt = massTemper[0]; if (ttt >= 2000) { text[firstpos] = '-'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; ttt -= 2000; } word bbb = ttt / 10; if (bbb > 9) { text[firstpos] = (bbb / 10) + '0'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; } text[firstpos] = (bbb % 10) + '0'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; text[firstpos] = '.'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; text[firstpos] = (ttt % 10) + '0'; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; text[firstpos] = ' '; ++firstpos; if (firstpos >= (maxsize - 1)) return firstpos; text[firstpos] = 'C'; ++firstpos; return firstpos; }индусы в шоке
Все мои знакомые коты лижут яйца там, где им приперло и более 20сек. Или спят. Или втыкают на стену.
абажаю людей с юмором и ценю ... но всеже ..
http://psenyukov.ru/%D0%BE%D1%82%D0%BF%D1%80%D0%B0%D0%B2%D0%BA%D0%B0-%D1%81%D0%BC%D1%81-%D1%81-neoway-m590-%D0%BF%D1%80%D0%B8-%D0%BE%D0%B1%D0%BD%D0%B0%D1%80%D1%83%D0%B6%D0%B5%D0%BD%D0%B8%D0%B8-%D0%B4%D0%B2%D0%B8%D0%B6/
вот готовый проэкт на микроволновом датчике который уже заказан и в пути ..с готовой прошивкой в принципе я осилю его собрать
и я абсолютно уверен что заказчику понаворачивали свестелок такие как термодатчик и дачик на бутан просто чтобы накрутить ...
ибо там где это будет стоать это абсолютно бесполезно если событие случится спасать там от пожара будет нечего и некого слишком малое помещение наполненное грючими матерьялами выгорит все до углей за 1..1,5 минуты
если рядом не стоиш с огнетушителем ничего не спасеш ... но пока я не смог убедить заказчика что эти функции на температуру и на газы горючие совершенно бесполезны в этом месте и для этих целей ...
ок можно ли этот проэкт что по ссылке собрать на ардуино нано 3.0 ?
и может быть просто ТЗ оформить как то что чутка подправить под наши задачи эту готовую прошивку ?
в этом случае проэкт этого 1 разработчика просто идет на свалку
а делаем вот этот простейший проэкт ЕСЛИ ОН РАБОЧИЙ и без косяков ? и ТЗ просто превращяется в некой модификаций уже имеющейся прошивки ?
Нежелание занимать своими делами требует от меня немного поболтать. Тем более тема приятная.
Вот такая, описанная система, это хуже, чем купить китайский GSM модуль сигналки, прошитый "на отъе..сь".
ОС - Охранные Сигнализации - это комплекс технических и психологических мероприятий и средств. Начинают с определения круга угроз и их классификации. Затем воздействия и оповещения.
Пример: просто прожектор с датчиком движения уже предотвращает угрозу спонтанного нежелательного проникновения. Для пьяного хулигана перелезть через освещенный забор - уже труднее решиться, чем в темноте.
Компонетны ОС:
1. скрытые датчики - пояснять не надо;
2. наглядные элементы - от муляжа камеры и мигающего диодика до реальных камер, лазеров и емкостных кабелей - цель повысить контрмотивацию у злодея: "Тут всё серьёзно! Да-ну-нах, пойду другой ларёк бомбану!";
3. средства ЗиВО Звукового и Визуального Оповещения - сирена, прожектор, проблесковый маяк и т.п. Нужны лишь в том случае, если предполагается, что кто-то среагирует, или хоть злодей испугается ;).
4. Коммуникационный блок - для приема команд, отправки извещений и телеметрии;
5. Центральное управляющее устройство.
---------------------------------------
Общие правила построения ОС, если не на "отъе..ись" и не детская поделка.
1. скрытые датчики должны быть соединены с ЦУУ так, чтобы определялось разрушении линии.
2. Желательно и наглядные средства тоже соединять таким образом.
3. средства ЗиВО должны быть нормально включены, иметь автономное питание (на время оповещения) и соединяться с ЦУУ гальванически развязанно. Нормально включены - чтобы сработать при разрушении ЦУУ, гальванически развязаны - защита от "шокера", разрушаюшего ЦУУ и линии.
4. Коммуникационный блок - как и ЗиВО, развязка и автономное питание на время, достаточное для отправки аларма.
5. ЦУУ - вот тут нужно помнить, что "в одну телегу впрячь неможно коня и трепетную лань". Не нужно грузить ЦУУ несвойственными функциями: предсказания погоды, заказ пиццы и деффок в баню и пр. Простой защищенный от сбоев алгоритм, просто конечный автомат. Если есть желание приделать "свистоперделки" - они оформляются в отдельный блок, который активизируется событиями определенного уровня ("цвета") опасности.
Вот про уровни опасности, на что реагировать немедленным самоуничтожением ;)))), а на что нежным посвистыванием - это тема отдельной лекции... и мне уже явно лень будет ее читать.
=====================================
В связи с изложенным - описанное решение (пока трезвый - без мата) ..ну детский сад, штоле?!
По поводу того что коты лижут яйца как минимум 20 секунд абсолютно согласен.. сам котовод в прошлом.ок тогда выставим 40..50? секунд. Я ещё не видел чтобы коты занимались онанизмом. а на гигиену им хватит и 30 секунд? Логично? А глючный м590 заменим на более дорогой и не глючный?
..хотя то что все это с китая лично у меня не вызывет уверенности что это будет работать долго и надежно
..там среди деталей что мне доставили лежит пачка м590 которая обозначена как бракованные
Да нормально всё делать на Китае. Китай выпускает что угодно любого качества. Даже Ардуино модули можно использовать готовые. Если есть сомнения в пайке - прогреть феном, закрыть лаком...
М590 - говно, sim800 нужно использовать. Просто sim800 в три раза дороже.
А про твой заказ - бред это. С такими требованиями нужно просто купить хреновину на Али готовую.
Или делать по-человечески. Ты, как я понял, и сам знаешь как.
вообщем пообрщявшись в вашим коллективным разумом И с заказчиком и его запросами, я понял что вы ребята правы ... и генеральная линия сдесь только 1
или ты нанимаеш специалиста или команаду специалистов по сигналкам например таких как wdrakula и платиш им хорошие деньги за каждый день их работы + матерьялы и прочие расходы включая аренду помещения
либо вариант 2 ты просто покупаеш уже готовое и прособачиваеш под себя я уверен что заказчик 1 линию просто не тянет
а 3 варианта тут нет ..3 эконом вариант это то что он уже получил свистелку недоделанную от некого кулибина
и платит за 3 вариант будет даже не дважды а как правильно сказали выше ТРИЖДЫ а подделка в конечном итоге будет достойна только чтобы ее с размаха выкинуть в помойное ведро.
потеря время и денег
нельзя сделать сигнализацию из глины и палок ..люди на фрикерских форумах где разрабатывают системы взлома профессиональных сигнализаций вваливают тысячи и тысячи евро а иногда и десятки тысячь... не смешите их свистелками на ардуино которые можно тряпкой или куском коробки на которой рядом бомжи спали, взломать
вообщем я прошу у вашего коллективного разума раз уж тут упоминалось что готовую систему с СМС оповещеним которую можно купить на алибабе
подсказать название готовых систем охраны на смс китайских или русских или каких угодно других не дорогих
куда можно подключить 2 датчика движения и 1 датчик температуры и может быть ещо 1 или 2 каких то датчика скорее всего емкосных
кстати по поводу китая ... я так померял радномно несколько смд конденсаторов и резисторов и везде отклонение от номинала около 10..15%
чето многовато
кстати по поводу китая ... я так померял радномно несколько смд конденсаторов и резисторов и везде отклонение от номинала около 10..15%
чето многовато
С чего это вы взяли ? Что касается резисторов то есть серии где допустимое отклонение +-10%, а некоторые серии конденсаторов +-50% !
https://www.proline-rus.ru/catalog/komplekty-besprovodnoj-gsm-signalizacii-bastion-2070/bastion-x1-55874/?utm_source=gm&utm_medium=gm&utm_campaign=gm&utm_content=komplekty_besprovodnoj_gsm_signalizacii_bastion&utm_term=55874&gclid=CjwKCAjwx_boBRA9EiwA4kIELo7Ag2DkonxJR_H2cYdY_U31otJg8qCJWDUxpjmyyDun80TZaFuX_RoCEaUQAvD_BwE
...я так померял радномно несколько смд конденсаторов и резисторов и везде отклонение от номинала около 10..15%...
Во первых, чем меряли? Во вторых, условия измерения? В третьих, погрешность укладывается в разброс для X7R.
multi meter Welleman + capacitance meter TES 1500
когда раньше я покупал детали в радимагазине такого разброса не было ..эти же все заказаны алибабы
я понимаю что адруино цифровая логическая схемотехника и там такой разброс наверное не важен ..
но все же ... китаец он вседаки китаец
я помню, взял в китае на gearbest исключительно потому что дизайн понравился ботинки, писали что кожа, оказалось бумага пропитанная чем то
а подошва на 3 день насквозь ибо толщина ее 1,5мм и сырой резины
я в магазин выслал им фото ботинка с пальцем из подошвы деньги вернули ... а сколько тысячь или милионов пар этого поделия они людям впаривают ? до сих пор реклама линейки этой CHINA SHOES моды в браузер залазит
вот где милионы денег надо делать
я 1/4 добавил к цене тех CHINA говнодавов и купил в реальном магазине классные кожанные шузы на подошве из полиуретана
3 года проходят и не развалятся
ой спасибо ... да добротная система
БАСТИОН X1
а не кривое поделие на 3д принтере с лампочками и свистком
а система стоит вообще копейки, блок и датчики да ещо и беспроводные
пс
вы ребята были абсолютно правы что надо брать в китае готовое ... а не маяца фигней и фольклорной самодеятельностью
да и ещо вопрос .. а то от многостраничных даташитов уже коты волосатые летают перед глазами
можно ли на плате которая разработана под M590 воткнуть SIM800 или SIM 900 ?
или потребуются серьзеные доработки по обвеске и плате ?
а это новую плату делать ... просто из спортивного любопытства вопрос
Скорее всего можно. хотя какой то минимум обвеса возможно придется прилепить.
Жесть. Тут объем работ на небольшое КБ. Особенно понравилось требование к обнаружению неизвестного газа.
может попробуете еще раз посоветовать заказчику сразу поменять свой