Проект GSM/GPRS сигнализации на Arduino ч.2

Проект GSM/GPRS сигнализации на Arduino ч.2 Сигнализация, Arduino, Sim800l, Gsm, Gprs, Смс-рассылка, Длиннопост

Приветствую моих читателей. В первой части https://pikabu.ru/story/proekt_gsmgprs_signalizatsii_na_ardu... я рассказал вам, как сделать простую GPRS сигнализацию на Ардуино. Проект продолжает развиваться. Сигнализация эксплуатируется около месяца, и уже можно подводить некоторые итоги. За это время не было ни одного случая отказа или зависания, как модуля SIM800L, так и самой Ардуины. Напомню, в моём проекте микроконтроллер питается напрямую от аккумулятора пониженным напряжением 4 В. К каким-то отказам, как опасались многие читатели, это не приводит. Мною был проведён эксперимент, чтобы узнать, как поведёт себя сигнализация при постепенном разряде батареи.

Так как Ардуина разряжала аккумуляторы очень медленно, я подключил её вместе с модемом к лабораторному источнику питания, выставил ограничение по току 2А, и проверил работу на различных значениях напряжения.

Что удалось выяснить. При 3,5 В и выше SIM800L работает штатно. С питанием 3,4 В иногда начинаются перезагрузки при входящих звонках. При снижении напряжения ниже 3,4 В отваливается сеть, могут начаться перезагрузки, но на AT команды модуль продолжает отвечать. Так он работает в плоть до 3В, после чего выключается.

Ардуина работает даже при напряжении 2,7 В, ниже которых отключается. Никаких сбоев отмечено не было.

Но этого нам не достаточно. Нужно было проверить работу при длительной разрядке аккумулятора. Так сказать в условиях, близких к боевым. Я отключил режим сна Ардуины, подключил дополнительную нагрузку к аккумулятору, включил Serial монитор, и отслеживал поведение сигнализации, периодически проверяя её работоспособность. Эксперимент продолжался более суток. Аккумулятор разрядился до 3,6 В. Сбоев замечено не было. Схема полностью работоспособна.  Ставьте ёмкий аккумулятор и не о чём не думайте.

Для справки. Номинальное напряжение питания чипа зависит от частоты его работы. Если программно понизить частоту до 10МГц или ниже, то питание напряжением от 2,7 до 5,5В для Atmega328p будет стандартным. Если кого-то не убедили результаты эксперимента, то они могут  поиграться с настройками частоты.


С этим разобрались, теперь поговорим о доработках проекта.


За прошедшие две недели проект претерпел некоторые изменения. Геркон теперь подтянут через резистор не к +5В, а к +4,2В батареи (см. фото). Что позволит сохранить на пине высокий уровень при отключении внешнего питания без программной подтяжки. Мне кажется это более надёжным решением. Резисторы можно использовать любого номинала, начиная с 2,2 кОм и выше.


Остальные доработки касаются программной части. Файл настроек settings.h получил новые опции. https://github.com/wisenheimer/Arduino/blob/master/libraries...


По рекомендации читателей, в проект был добавлен watchdog (WTD), который перезагрузит Ардуину в случае её зависания. Включен по умолчанию следующим дефайном:

Проект GSM/GPRS сигнализации на Arduino ч.2 Сигнализация, Arduino, Sim800l, Gsm, Gprs, Смс-рассылка, Длиннопост

Т. к. стандартный загрузчик Ардуино Нано не поддерживает watchdog, и в случае его срабатывания уходит в бесконечную перезагрузку, для его работы нужно либо сменить загрузчик на другой, либо поступить проще. Прошить Ардуину через программатор. В этом случае на Ардуине больше не будет загрузчика. И watchdog будет работать. Но вы уже не сможете прошивать Ардуину по USB. Если вас это не устраивает, не используйте watchdog.


В качестве программатора я применил Ардуино УНО с прошивкой ArduinoISP из примеров.


Следующее изменение касается способа доставки отчётов. Теперь сигнализация поддерживает SMS отправку сообщений. Ранее мы отправляли ответы сигнализации на e-mail при помощи GPRS. Теперь можно выбирать способ отправки. Для этого добавлен следующий дефайн:

Проект GSM/GPRS сигнализации на Arduino ч.2 Сигнализация, Arduino, Sim800l, Gsm, Gprs, Смс-рассылка, Длиннопост

По умолчанию включены оба варианта.


SET_FLAG_ONE(GPRS_ENABLE) разрешает отправку e-mail по GPRS.

SET_FLAG_ONE(SMS_ENABLE) разрешает отправку отчётов по SMS.


GPRS имеет более высокий приоритет. Если сигнализации не удалось установить GPRS соединение, и SMS режим разрешён, то сообщения будут отправлены по SMS, флаг GPRS_ENABLE  выключен, и в дальнейшем будет задействована только SMS отправка. Включить или выключить оба режима можно так же в ручную DTMF командой.

Если мы хотим всегда использовать один режим, то дефайн нужно отредактировать, удалив лишнее.


Следующим нововведением стало изменение списка DTMF команд:

Проект GSM/GPRS сигнализации на Arduino ч.2 Сигнализация, Arduino, Sim800l, Gsm, Gprs, Смс-рассылка, Длиннопост

Команды, не вошедшие в список, будут подставлены в USSD запрос и отправлены сотовому оператору. Так что можете в режиме DTMF напирать любые USSD команды. Например запрос баланса. В случае успеха ответ оператора вернётся в виде отчёта.


Админ так же может управлять модемом SIM800L при помощи АТ команд из его даташита http://www.mt-system.ru/sites/default/files/documents/sim800... .


Например, добавлять и удалять номера из телефонной книги. Для этого достаточно с телефона Админа отправить сигнализации SMS с текстом АТ команды.


Дальше хочу подробно рассказать, как добавлять в проект датчики.


Для начала необходимо определиться с количеством пинов, требуемых для ваших датчиков. Датчики у нас подключаются, начиная с 4 пина. Первым желательно выбрать геркон, т.к. он будет будить Ардуину, если она войдёт в режим энергосбережения при отключении внешнего питания.

Проект GSM/GPRS сигнализации на Arduino ч.2 Сигнализация, Arduino, Sim800l, Gsm, Gprs, Смс-рассылка, Длиннопост

В файле https://github.com/wisenheimer/Arduino/blob/master/libraries... описан класс Sensor и следующие типы датчиков:

Проект GSM/GPRS сигнализации на Arduino ч.2 Сигнализация, Arduino, Sim800l, Gsm, Gprs, Смс-рассылка, Длиннопост

DIGITAL_SENSOR - любой датчик с одним цифровым выходом, на котором может быть только два состояния, 0 или 1.

CHECK_DIGITAL_SENSOR - тоже самое, только с проверкой от ложного срабатывания. Если через 10 секунд датчик сбросил своё значение, то срабатывание считается ложным.  Применяется для тех датчиков, которые удерживают логическое значение на выходном пине при сохранении внешнего воздействия. Например датчик пламени.

ANALOG_SENSOR - любой датчик с аналоговым выходом. Например датчик газа MQ-2.

DHT11, DHT21, DHT22 - датчики температуры и влажности.


Конструктор класса имеет следующий вид:

Проект GSM/GPRS сигнализации на Arduino ч.2 Сигнализация, Arduino, Sim800l, Gsm, Gprs, Смс-рассылка, Длиннопост

В нашем файле настроек имеется целый массив таких классов для каждого датчика:

Проект GSM/GPRS сигнализации на Arduino ч.2 Сигнализация, Arduino, Sim800l, Gsm, Gprs, Смс-рассылка, Длиннопост

Очень важно указать точный размер массива, иначе проект не соберётся. В данном случае у меня имеется 6 датчиков, конструктор для каждого описан отдельно.


Например:

Sensor(DOOR_PIN, DIGITAL_SENSOR, "DOOR", HIGH, 0)

означает, что для датчика двери (геркона) задействован пин Ардуино DOOR_PIN (задан в том же в файле), тип датчика DIGITAL_SENSOR, название датчика, которое будет выводиться в отчётах - "DOOR" (можно заменить на любое другое слово), обычное состояние пина  HIGH (DOOR_PIN у нас подтянут к 4,2В), время подготовки датчика при включении питания в секундах, через которое он начнёт показывать правильные значения - 0 секунд.


Для аналогового датчика газа MQ-2:

Sensor(A0, ANALOG_SENSOR, "GAS", LOW, 120)

пин A0, тип датчика ANALOG_SENSOR, имя  "GAS", значение на пине LOW, на прогрев датчика и выход на номинальный режим работы отводится 120 секунд. До истечения этого времени после включения датчик не опрашивается, что бы не получать неверные значения.


Для датчика температуры DHT11

Sensor(DHT_PIN, DHT11, "DHT", LOW, 10, 35)

в конце появилась цифра 35, которая означает уровень в градусах, при превышении которого считается, что датчик сработал. В помещении стало слишком жарко.


Внимательный читатель уже заметил, что для разных датчиков описано разное количество параметров. Дело в том, что в языке С++ можно не писать все параметры функции, если в заголовке функции указаны их значения по умолчанию. Мы пишем только то, что не имеет значения по умолчанию, или мы хотим задать другое значение. Однако никто не запрещает указать все параметры конструктора класса.


Вы можете подключать к сигнализации любые датчики, не требующие отдельной библиотеки, лишь заполнив конструктор класса, и добавив его в массив Sensor sensors[]. И это будет работать. Если для датчика требуется отдельная библиотека, то её можно добавить точно так же, как в проект была добавлена библиотека stDHT.h для датчика DHT11, который имеет свой протокол для обмена данными. Или напишите мне, я добавлю.


На этом всё, спасибо за внимание.


Скачать проект можно как всегда по ссылке: https://github.com/wisenheimer/Arduino

Arduino & Pi

1.4K постов20.6K подписчиков

Добавить пост

Правила сообщества

В нашем сообществе запрещается:

• Добавлять посты не относящиеся к тематике сообщества, либо не несущие какой-либо полезной нагрузки (флуд)

• Задавать очевидные вопросы в виде постов, не воспользовавшись перед этим поиском

• Выкладывать код прямо в посте - используйте для этого сервисы ideone.com, gist.github.com или схожие ресурсы (pastebin запрещен)

• Рассуждать на темы политики

• Нарушать установленные правила Пикабу

Вы смотрите срез комментариев. Показать все
Автор поста оценил этот комментарий

Повторил схему, есть проблема.

+CPBS: "SM",4,100

OK

init end

AT+SAPBR=3,1,"CONTYPE","GPRS";+SAPBR=3,1,"APN","internet";+SAPBR=3,1,"USER","";+SAPBR=3,1,"PWD","";+SAPBR=1,1

....

ERROR

..................................................BOOT


и так по кругу, есть мнение что по факту сим карта теле2, а модем видит это при старте:

..........AT+COPS?

+COPS: 0,0,"MOTIV"

OK


Хелп...Спасибо.

раскрыть ветку (14)
1
Автор поста оценил этот комментарий

Для начала попробуйте с симкой другого оператора, если есть.


MOTIV в коде тоже прописан.

Для теле2 можете попробовать в файле modem.cpp подправить дефайн вот так


#define GPRS_CONNECT(op) if(!answer_flags && !flag_gprs_connect){SERIAL_PRINT(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\";+SAPBR=3,1,\"APN\",\"internet.tele2.ru\";+SAPBR=3,1,\"USER\",\"")); \


А ещё лучше отключить режим отладки. Он может влиять, т.к. что в порт пришло, отправляет обратно. Из-за этого может быть ошибка.

раскрыть ветку (13)
Автор поста оценил этот комментарий

Спасибо за ответ. Сегодня само отпустило, видимо проблема том, что симка свежекупленная была. Сегодня все включается, работает, пытаюсь понять логику, особенно структуру e-mail-ов приходящих. :)

раскрыть ветку (12)
1
Автор поста оценил этот комментарий

Это хорошо. Код рабочий, проверено, в том числе на теле2. В боевом режиме отключите вывод отладочных сообщений. Он мешает отправке смс и email.

раскрыть ветку (11)
Автор поста оценил этот комментарий

Раз вы на связи, позвольте несколько вопросов:

Много ли кода переписывать если геркон NO, таких валом, а NC под рукой нет?

Когда срабатывает прерывание что нет питания, в почту(у меня сейчас только она включена) идет такое, да еще и по кругу:

Svet OFF.GUARD=0 TEL=0 GPRS=1 CONNECT=1 SMS=0 Svet ON.GUARD=0 TEL=0 GPRS=1 CONNECT=1 SMS=0 Svet OFF.GUARD=0 TEL=0 GPRS=1 CONNECT=1 SMS=0 Svet ON.GUARD=0 TEL=0 GPRS=1 CONNECT=1 SMS=0 Svet OFF.GUARD=0 TEL=0 GPRS=1 CONNECT=1 SMS=0 Svet ON.GUARD=0 TEL=

Не могу придумать как победить, чтобы по прерыванию код из case выполнялся единожды, для любого состояния прерывания.

Спасибо.

Ну и может кому пригодится, при звонке с номера из записной, состояние GUARD переключается при каждом "гудке", победил так:

modem.cpp

стр 376 else DTMF[0] = GUARD_ON;

}добавить строку чтоб получилось так:

else DTMF[0] = GUARD_ON; RING_BREAK; // Сбросить звонящего из записной, после смены статуса }

раскрыть ветку (10)
1
Автор поста оценил этот комментарий

Для использования геркона NO надо немного изменить схему. На фото пин 4 через резистор 10 кОм подтянут к 4 вольтам батареи. Вам надо поставить геркон между резистором и 4В.  Когда дверь закрыта, геркон замкнут. На пине 4 высокий уровень. При размыкании геркона уровень станет равным нулю. Код менять не надо.

раскрыть ветку (3)
Автор поста оценил этот комментарий

Я правильно понял: +4---резистор---геркон NO---D4 и все?

Если да, то не совсем работает. После "открытия двери" D4 остается в воздухе, видимо опять грабли дребезга. Через минуту в почте такое STATUS это аналог вашего ALL:

STATUS: DOOR:11(0) ALARM! DOOR:1(0) или

STATUS: DOOR:10(1) ALARM! DOOR:1(0) или

STATUS: DOOR:9(1)

И так по кругу каждую минуту, после "закрытия двери", или "закрытия двери" в первую минуту все штатно становится в режим Guard

раскрыть ветку (2)
1
Автор поста оценил этот комментарий

Поняли правильно. Тут не дребезг, тут скорее всего наводки виноваты. Можно посмотреть тестером, как меняется напряжение на пине 4 при открытии двери. Должно быть около нуля. Если скачет, значит наводки.


Верните схему назад, как было. В коде просто укажите низкий уровень для датчика


Sensor(DOOR_PIN, DIGITAL_SENSOR, "DOOR", LOW, 0)

Должно заработать.

раскрыть ветку (1)
Автор поста оценил этот комментарий

Не взлетело: вернул схему, поправил код. В ответах - RND сплошное.

Исключаю геркон, вместо него проводки - как часы все. Меняю 4 геркона, резистор, провода, не работает. Мне, и последователям на заметку: геркон, круглый неодимовый магнит с дыркой  - НЕ ДРУЗЬЯ!

Автору, за консультации - спасибо!

1
Автор поста оценил этот комментарий
Ну и может кому пригодится, при звонке с номера из записной, состояние GUARD переключается при каждом "гудке", победил так:


Спасибо, подправил в коде.

Автор поста оценил этот комментарий

Про прерывание отбой, разобрался. В сборке схемы неточности были, я рвал цепь d3-резистор-питание для проверки, и это не правильно.

раскрыть ветку (4)
1
Автор поста оценил этот комментарий

Множественное срабатывание прерывания происходит из-за дребезга контактов, когда вы в ручную рвете цепь. При пропадании электричества в сети дребезга не будет.  И сообщение будет только одно. Но никто не запрещает вам подавить дребезг аппаратным способом при помощи резистора с конденсатором. В интернете всё это описано.

раскрыть ветку (3)
Автор поста оценил этот комментарий

Еще вопрос, оставил на ночь от аккумуляторов жить. WTD откл, сон - вкл. Каждые 4 минуты приходит сообщение в почту:

WakeUp:

И так до включения. В остальном штатно. Что это, где это я нашел. А как регулировать период этого сообщения? Спасибо.

раскрыть ветку (2)
1
Автор поста оценил этот комментарий

У меня такого эффекта не наблюдается. Уснул и спит.

Просыпаться контроллер может если на пине 3 появится высокий уровень (появилось питание). Если на модем поступит звонок, или придёт смс, то на пине 2 появится  нулевой импульс, что вызовет прерывание, и оно пробудит контроллер. И последний случай, при срабатывании геркона на пине 4 тоже появится прерывание. Возможно с последним у вас проблемы. Наводки или что-то ещё.


При засыпании ардуина прекращает выполнять код. Никаких интервалов там нет. Спит пока её не разбудят вышеперечисленные случаи. Тогда она проснётся и отправит вам сообщение  WakeUp.

Далее если питания нет, снова уйдет в глубокий сон.


У вас какая-то аппаратная проблема.

Если не найдёте причину, просто отключите режим сна. И без него сутки другие проработает на батарейке.

раскрыть ветку (1)
Автор поста оценил этот комментарий

Благодарю, буду искать причину, пока оно на макетке чудеса возможны. Да еще NANO какая-то древняя и проблемная досталась, может и тут что.

Вы смотрите срез комментариев. Чтобы написать комментарий, перейдите к общему списку