Нужна помощь с постановкой на сигнализацию.
- Войдите на сайт для отправки комментариев
Ср, 26/12/2012 - 12:26
Уважаемые!
Пытаюсь организовать постановку на охрану. никак не получается.
Алгоритм такой -
1. уходя из помещения включаем сигнализацию (выключателем).
2. По прошествии 1 минуты система встает на охрану и высылает статусный смс.
3. для снятии с охраны шлем смс о выключении охраны. После этого у нас есть 1 минуты для -
4. захода в помещение и выключение охраны выключателем. Если не успели - система повторно встает на охрану и шлет статусный смс.
вот кусок моего кода -
int eventDetect() { // запуск процедуры обработки событий if (DEBUG) { Serial.println("Waiting for event");} // Сообщение "отладчика" if (!digitalRead(ALARM_ACTIVATE_PIN)){ // Проверяем выключатель if(millis() > currentTimer) { // запускаем таймер ALARM_STATE = !ALARM_STATE; // меняем флаг состояния охраны. if (DEBUG) { Serial.println("Alarm ON");} //начинаем слушать датчики if(digitalRead(INTRUDER_SENSOR_PIN) && !INTRUDER_STATE) { INTRUDER_STATE = 1; blinkLED(); event = 1; raiseEvent(); // запускаем процедуру посылки смс } if(!digitalRead(INTRUDER_SENSOR_PIN)) { INTRUDER_STATE = 0; digitalWrite(ALARM_ON_LED, HIGH); digitalWrite(ALARM_OFF_LED, LOW); } if(digitalRead(DOOR_SENSOR_PIN) && !DOOR_STATE) { DOOR_STATE = 1; blinkLED(); event = 2; raiseEvent(); // запускаем процедуру посылки смс } if(!digitalRead(DOOR_SENSOR_PIN)) { DOOR_STATE = 0; digitalWrite(ALARM_ON_LED, HIGH); digitalWrite(ALARM_OFF_LED, LOW); } if(digitalRead(WINDOW_SENSOR_PIN) && !WINDOW_STATE) { WINDOW_STATE = 1; blinkLED(); event = 3; raiseEvent(); // запускаем процедуру посылки смс } if(!digitalRead(WINDOW_SENSOR_PIN)) { WINDOW_STATE = 0; digitalWrite(ALARM_ON_LED, HIGH); digitalWrite(ALARM_OFF_LED, LOW); } currentTimer = millis() + Alarm_on_interval; // увеличиваем таймер на интервал (1мин) } } else { //если выключатель не на охране - просто считываем состояние датчиков для статуса. if (DEBUG) { Serial.println("Alarm OFF");} digitalWrite(ALARM_ON_LED, LOW); digitalWrite(ALARM_OFF_LED, HIGH); if (!digitalRead(ALARM_ACTIVATE_PIN)) ALARM_STATE = 1; else ALARM_STATE = 0; if(digitalRead(DOOR_SENSOR_PIN) && !DOOR_STATE) DOOR_STATE = 1; if(!digitalRead(DOOR_SENSOR_PIN)) DOOR_STATE = 0; if(digitalRead(WINDOW_SENSOR_PIN) && !WINDOW_STATE) WINDOW_STATE = 1; if(!digitalRead(WINDOW_SENSOR_PIN)) WINDOW_STATE = 0; ALARM_STATE = 0; } }
Что нужно - именно работа с временными интервалами
Из кода можно понять что это только код
Я прежде чем кодировать, прочитал инструкцию по наиболее популярной как мне показалось сигнализации Кситал с функцией поддержания температуры, Из чего вынес, что касается Вашей части -сигнализации - следующие вещи
Пауза, при постановке и снятии как и часть других параметров должна быть записана в виде параметров системы, на симке или в эпроме Ардуины
Цифровыми входами для охранных шлейфов лучше не пользоваться, Аналоговые дают большую гибкость при выборе концевых датчиков
Что касается алгоритма, непонятно зачем слать смс о снятии с охраны, и что будет если смс не будет а человек зайдет и выключит выключатель, я бы предложил снимать с охраны просто смс с авторизованного(ых) телефона(нов)
Ну да ладно, это дело реализации, работа с временными интервалами
что касается временных интервалов - 2 выбора
1) замечательная функция milis()
Timeout=60000;
if (открыли дверь)
tiks=millis();
//продолжаем дальше чтото делать
....
latstiks=millis();
if((lasttiks-Timeout > tiks ) {
/// Прошел таймаут после вскрытия двери, сирену включим или поставим на сигнализацию снова и тд и тп
}
минус использования этой функции в том что раз примерно в 50 дней хорошо бы перезагрузить контроллер иначе счетчик millis переполнится, отсчет начнется сначала, и существует риск того что программа глюканет не каком то важном моменте.
2) в GSM модуле есть часы,
вызывается командой AT+CCLK?
считывается с сериала как +CCLK: "12/08/31,13:53:48+16" и легко раздраконивается на год минуты секунды и проч
Перед тем как ей пользоваться надо сказать модему тоже AT командой чтобы он брал время у сотового оператора, они все сейчас поддерживаютэту фичу.
Иначе модем будет показывать нелепое время
я нашел эту команду, вбил ее в модем, и теперь мой склероз не дает мне ее вспомнить, хотя самому хотелось бы знать и записать ее
Да третий выбор real time чип, но мне кажется он лишний для GSM модуля
Спасибо, попробую.
Решил выложить скетч упрощенный, но полный, а не кусок.
Это исходный код (без интервалов), на который буду накручивать "постановку на охрану"
Прочел, 3 датчика как я понял, Интрудер(Что это кстати?), дверь и окно , если какой либо срабатывает, включаем состояние 1 и шлем смс
На мой вкус, поскольку в loop будет еще логика, и чтобы не мозолить глаза многочисленными проверками вынести проверку всех датчиков в одну функцию типа CheckSensors возвращаюжую 0 если все ок, и номер датчика+1 если плохо) , плюс состояние датчиков можно держать в глобальном массиве (легче проверяется, кроме того сам массив можно хранить и отсылать). Хранение необходимо если предположить такой подход к реализации постановки на охрану - Система запоминает состояние датчиков в момент постановки на охрану. любое изменение состояния в режиме охраны - вызывает алярм и смс.
тогда при постановке на охрану достаточно записать строку состояний датчиков, и сравнивать с ней текущую строку состояния датчиков
запись самой переменной состояния режима Охраны , скажем Armed =1 ( на охране) =0 (снята с охраны) позволит при перезагрузке контроллера, уже в функции setup прочитать состояния Режима Охраны , и строку "нормального" положения датчиков охраны, что позволит контроллеру продолжать прерванную функцию охраны
итого не считая логики обработки сенсоров в основном цикле имеем пока 2 if, легко читается и модифицируется для дальнейшего накручивания логики
byte Sensors[3];
byte Armed;
loop() {
if (Armed)
if (CheckSensors())
sendEventSMS();
}
void
sendEventSMS() {
int i;
for (i=0;i<3;i++)
Serial.print(Sensor[i]);
73
}
Ну это на мой вкус.
Писать лучше конечно в eprom, быстрее и надежнее, писать сразу структурой
Нашел.
Команда , заставляющая GSM модуль устанавливать локальное время сотового оператора
AT+CLTS=1 (разрешить)
AT+CLTS=0(Запретить, модуль не будет учитывать рассылку от оператора)
моя функция получающая время от модуля ICOMSAT с бибилиотекой GSMSHIELD
typedef struct {
byte year;
byte mounth;
byte day;
byte hour;
byte minutes;
byte seconds;
} Timestr;
Borland,
ОГРОМЕННОЕ Вам Спасибо!
Будет чем заняться на выходных!
Не за што
Я попробовал перенести в эпром все системные параметры , но понял что это несколько неблагодарная работа, поскольку память симки организована гораздо удобнее - Номер ячейки, телефон, имя. Номер ячейки обьявляется #define в инклуде в телефоне хранятся цифровые данные, в Имени - коментарии. Все однозначно. В эпроме же приходится работать со структурами параметров системы , и для записи , чтения одного параметра придется либо извращаться отдельными фунциями для записи полей, либо писать читать всю структуру, либо написать одну функцию которая будет вычислять адрес каждого поля в структуре ( поскольку поля все разных типов). В общем и то и другое и третье показалось некрасивым, и помятуя что ячейки эпрома портятся, портя саму дуину, а порча ячеек симки, легко восполняется ее заменой я решил что увеличение скорости чтения записи на 1-3 секунды того не стоят, тем более эта запись чтение производится только при смене каких либо параметров системы, то есть редко
Третьего буду на работе , если интересно скину свои системные параметры которые храню и обновляю на симке
millis отличная функция для организации "таймеров" внутри loop.
Чтото нужно проверять раз в секунду, чтото раз в 10 секунд, чтото раз в час, чтото наконец раз в сутки и тд.
Единственный недостаток кмк, что ее использование сильно засоряет код самого цикла, поскольку требует обязательно двух вызовов millis, первый с первичной отсечкой времени, второй с проверкой - " а прошло ли это время?"
Попробовал избавится от этого, обьединив обе проверки в одну функцию и организовав подобие "каналов" отсчета времени
тогда есть возможность организовать 10 канальный "таймер" который вернет 1 , если время какогото канала вышло и пора чтото сделать:
например так:
TimeGone(11... со спецканалом 11, которого нет в массиве таймеров, дописал только что, так как не нашел подтверждения что при софтверном резете статические и глобальные переменные обнуляются , буду тестировать.
Если они не обнуляются, то есть риск что вызывая функцию скажем на 12 секунд, мы получим ожидание ох неизвестно какого времени, вплоть до суток.
Таким образом основной цикл становится гораздо читабельней, да и кода полагаю меньше, чем при использовании просто millis.
Желающие могут переделать код в десятые, сотые секунды, для GSM - секунды имхо самое то
Можете еще глянуть в http://arduino.ru/forum/programmirovanie/tsifrovoi-datchik-kholla#comment-19985
В сообщении #11 я показывал аналогичное решение через #define.
Плюс его в том, что нет нужды заморачиватся с "сколько у нас каналов". Но, например внутри классов, его уже труднее использовать (хотя, с небольшими поправками - тоже можно).
2 Borland, по поводу АТ запроса времени.
Добрался до нормального интернета. Жалко, что на моем Wismo Q2400 нету такой АТ команды. Походу придется на работе махнуть на SIM 900, если получится конечно. 8-) А пока мне далласовские часы идут...
Конечно мне интересно как и что ты в симке хранишь. Поделись, если можно.
А есть вообще список AT команд для WISMO Q2400 ? я чегото не нашел . Что это вообще - ТАм по сериал общение ? может есть аналог команды.
На самом деле определение времени по способу который я описал имеет для меня один существенный при отладке
у меня часть loop организована как то так:
часть текста выкинул не потому что это ноухау а просто чтобы видна была логика
А логика такова - Все что приходит от GSM модуля читаем, анализируем, исполняем, будь то команда смс или баланс или еще чего он хочет сказать,
все что приходит с клавиатуры тоже анализируем и если это AT команда - отправляем в модуль, если нет то тоже чтото делаем
Позволяет в онлайне какието AT команды набирать, очень удобно для проверки чего либо.
при использовании функции GetDateString эта фича рушится, поскольку она посылает свой
"AT+CCLK?"
в то время когда я набираю ATну естественно ничего хорошего от модуля ждать не приходится. Поэтому раскомментариваю ее если работаю со временем
пока такие параметры , в основном слизаны с кситала, с некоторыми модификациями
Соответсвенно этот кусок кода - инициализация начальных параметров, Пока памяти навалом, делаю в том же скетче
в setup соответствено чтение этих параметров в глобальные переменные, учитывая что модуль в цифровых полях телефона всегда пишет "+" в начале.
смсками любой параметр можно поменять вплоть до пароля и включения нужного реле
Ну и отдельную структуру термометров, ради чего всё задумывалось храню в эпроме,так как в симку ее тяжелее затолкать :
Можете еще глянуть в http://arduino.ru/forum/programmirovanie/tsifrovoi-datchik-kholla#comment-19985
В сообщении #11 я показывал аналогичное решение через #define.
Плюс его в том, что нет нужды заморачиватся с "сколько у нас каналов". Но, например внутри классов, его уже труднее использовать (хотя, с небольшими поправками - тоже можно).
Ну да leshak , мне тоже больно смотреть на if millis раскиданные по телу цикла
Едиственное Имхо с define серьезная логика в скобках тоже не очень читабельна
В сообщении #11 я показывал аналогичное решение через #define.
Ну да leshak , мне тоже больно смотреть на if millis раскиданные по телу цикла
Если честно, то if-фы мне как раз не сильно смущают. Они читаются нормально. Гораздо больше парит "заводитьп еременные", придумывать им имена (и не перепутать).
В вашем варианте с "каналами", на самом деле они тоже нужны. По хорошему магических цифр быть не должно. То есть канал 0,1,2,3 - это моветон. Не дай бог в циферке очепятаешься. Прийдется их или константами как-то обзывать или опять дефайнами объявлять. Да еще и следить их количеством.
Не, я не хочу сказать что ваше решение "ужас". Как раз вполне себе имеет право на жизнь. Я просто предложил "еще вариант". Выбор между ними - вообщем-то дело вкуса.
Едиственное Имхо с define серьезная логика в скобках тоже не очень читабельна
Есть такое. Согласен. Ну можно еще фигурными оборачивать, что-бы "более явно было видно что это код". Делать что-то вида
Тогда это уже будет почти как "настоящие анонимные функции" :) Можно еще и пустой дефайн для слова DO сделать тогда
EVERY(500,DO { ЛОГИКА });
Будет вообще как DSL выглядить ;)
А, по хорошему, серьезная логика не должна быть в loop() в больших объемах. Если там набралось что-то больше 5-ти строк, то почему-бы его не вынести в отдельную функцию с говорящим именем. Что-то типа
- имхо смотрится вполне симпатично и понятно.
соглашусь вполне наверное красиво
но дефайны заменять кодом не люблю, тоже вкус
ну да порты обьявить, смысл тех же "каналов" минута секунда сутки
смысл дефайна именно в этом имхо, а именно - быстро переопределить какой либо параметр
заталкивать в дефайн макрос , ну да есть вариант и вполне смотрибельно , но кто будет анализировать обьем кода и не пора ли дефайн в функцию сунуть
внутри дефайна дефайн не всегда правильно работают
вопщим это дело вкуса и первого нарыва на "ну ево нахер этот дефайн"
хотя решение красивое
мы оба маладцы))