Главная » Статьи » Proton PICBasic

GSM-сигнализация

Всего в память микроконтроллера заносится 4 ключа. Запись ключей производится следующим образом: не включая разъем телефона, замкнуть перемычку(на схеме обозначена кнопкой на PORTA.5/MCLR), после чего вставить разъем в телефон. Дождаться вспышки светодиода (1 сек), после чего прислонить ключ к приемнику. После вспышки светодиода убрать ключ. После этого можно записать еще 3 ключа. После этого можно снять перемычку. Все - прибор готов к работе.

Статья написана при поддержке портала о вкусном кофе https://blueplanet-cafe.com/

Данная версия прошивки подразумевает слежение за одним каналом, но существует возможность слежения за 4 каналами одновременно. Для каждого канала используется свой текст SMS, который также хранится в EEPROM. Там же хранятся номера телефонов абонентов, которые и будут оповещаться о проникновении в помещение.

Запись в EEPROM удобна тем, что не нужно искать в программе параметры, чтобы подставлять свои значения, достаточно изменить значения EEPROM. Вся работа индицируется с помощью светодиода. Редкие вспышки - нормальный режим охраны, частые вспышки - режим тревоги - указывает на то, что помещение вскрыто и идет время на отключение хозяином сигнализации с помощью ключа. После чего, если не была отключена сигнализация, идет последовательно оповещение - сначала рассылка SMS на три номера, затем поочередно дозвон на эти телефоны, с ожиданием, время которого также задается в EEPROM. Это время дается хозяину на возможное прослушивание помещения. 

Для подключения возможности слежения за остальными тремя каналами, необходимо скопировать текст программы между метками SSSS и EEEE и поменять значения начала и окончания текста SMS для соответствующего канала, после чего вставить этот код дальше проверки первого канала. Если будут вопросы - задавайте в форум.

Еще один момент!

Процедура перекодировки текста в PDU формат взята из просторов интернета, не моя, поэтому особо не скажу про нее. Но хочу заметить, есть нюансы. При записи текста SMS используйте только латинский алфавит, это во-первых, во-вторых, слово должно быть не более 8 букв, в-третьих, по возможности, старайтесь не использовать цифры и много пробелов. Если слово короткое, поставьте по краям пробелы. Я использовал, например слово " GARAZH " (пробелы по краям). В общем, экспериментируйте.

Схема прибора:

Вот текст программы:

EData 0,100,40,2,$FF,%00111100," DVERI1 "," DVERI1 "," DVERI1 "," DVERI1 ","79139990000","F","79139991111", "F","79139992222","F"
Declare Reminders= OFF' 
Declare Warnings = OFF '  
Declare FSR_CONTEXT_SAVE = OFF
Declare Optimiser_Level 3 ' 
'-------------------------- ------------------------------------  
Device = 16F628
Xtal = 4 ' 
Config BODEN_OFF, PWRTE_ON, WDT_OFF, LVP_OFF, MCLRE_OFF, INTRC_OSC_NOCLKOUT,  DATA_CP_ON
'intrc_osc_noclockout - чтобы кварц не ставить
'mclre_off - потому что используется porta.5, можно и другой порт использовать
'pwrte_on - обязательно для лучшего запуска
'cp_on, data_cp_on - чтобы никто не считал программу
'-------------------------- Описание проекта ---------------------------------
'Проект : GSMSTOR
'Автор :  Admin
'Версия : 1.0.0 от 21.10.2009  
'-------------------------- Опции компилятора --------------------------------  
'-------------------------- Настройки USART ----------------------------------

   
Declare Hserial_Baud 19200 ' Скорость передачи данных, бод для сименсов C35 и C45
Declare Hserial_TXSTA = %00100100 ' Включить передатчик USART
Declare Hserial_RCSTA = %10010000 ' Включить приемник USART
Declare Hserial_Clear = On ' Автоматическая очистка бита ошибки переполнения  
'-------------------------- ------------------------------------ 
Declare All_Digital = On 'Все порты - цифровые  
'-------------------------- START------------------------------------  
Dim char[8] As Byte'переменные для хранения букв латинского алфавита при перекодировке
Dim pdu[8] As Byte 'Данные PDU формата 
Dim tmp[8] As Byte 'Массив временных переменных
Dim ch[8] As Byte 'Массив временных переменных
Dim id[8] As Byte 'Массив для считывания значений записанных ключей из EEPROM
Dim ID_real[8] As Byte 'Массив для считанных с ключа значений кода ключа
Dim x As Byte 'Счетчик
Dim j As Byte 'Счетчик
Dim I As Byte 'Счетчик
Dim z As Byte 'Счетчик
Dim PN[13] As Byte 'Массив для считывания телефонных номеров
Dim ALARMFLAGS As Byte 'Переменная флагов тревоги
Dim count_ As Byte 'Переменная - счетчик циклов дозвонов и отправки SMS
Symbol onSMS = ALARMFLAGS .5 'Флаг разрешения отправки SMS
Symbol onCall = ALARMFLAGS .4 'Флаг разрешения дозвона
Symbol CH_4_ALLOW = ALARMFLAGS.3 'Флаг разрешения слежения за четвертым каналом
Symbol CH_3_ALLOW = ALARMFLAGS.2 'Флаг разрешения слежения за третьим каналом
Symbol CH_2_ALLOW = ALARMFLAGS.1 'Флаг разрешения слежения за вторым каналом
Symbol CH_1_ALLOW = ALARMFLAGS.0 'Флаг разрешения слежения за первым каналом
Dim Start_OXR As Bit 'Флаг режима охраны
Dim delrun As Byte 'Переменная - задержка после открытия двери 
Dim DELAY As Byte 'Задержка для прослушивания при дозвоне на номер хозяина
Dim numCall As Byte 'Планировалось использовать для счета числа дозвонов
Dim SN As Byte 'Начало тел. номера
Dim EN As Byte 'Конец тел. номера
Dim SS As Byte 'Начало SMS
Dim ES As Byte 'Конец SMS
Dim ADDR_TEMP As Byte 'Временная переменная для адреса записи
Dim addr As Byte 'Адрес записи
Dim edat As Byte 'Временная переменная для записываемых данных  
Dim date As Byte 'Данные для записи
Dim Num As Byte 'Переменная для хранения количества ключей в EEPROM
Symbol INPUT_1 = PORTB.7 'Канал 1
Symbol INPUT_2 = PORTB.6 'Канал 2
Symbol INPUT_3 = PORTB.5 'Канал 3
Symbol INPUT_4 = PORTB.4 'Канал 4
Symbol INPORT = PORTA.5 'Вход для включения режима записи ключей
Symbol LED = PORTA.0 'Светодиод
Symbol dq = PORTA.1 'Вход для ключей
         Clear 'Очистим RAM
         PORTB=%11110010 'Настроим portb
         CMCON = 7 'Отключим компараторы
         TRISB = %11110010 'Каналы - на вход, ключ - на вход, остальные - на выход
         TRISA = %00100010
         OPTION_REG = %10000000 'Отключим подтяжку на portb
         LED = 1 'Моргнем светодиодом
         DelayMS 1000 'чтобы узреть начало работы
         LED = 0
     CONTr = 0
          GoSub SETPARAM 'Считаем параметры из EEPROM  
WRITE_KEY: 'Начало программы
        If INPORT = 0 Then 'Проверяем, если режим записи ключей включен, то 
             GoSub DS1990 'считываем значение ключа
             If id[0] = $1 Then 'Если это - DS1990, то 
                   If Num = 255 Then 'если в памяти не записан ни один ключ, то 
                          addr=74 : edat = 0 'присваиваем адрес начала записи первого ключа
                   EndIf 'и число, показывающее, куда записывать следующий ключ
                   If Num = 0 Then 'Если в памяти уже записан один ключ, то
                          addr=80 : edat = 1 'присваиваем адрес начала записи второго ключа
                   EndIf 'и число, показывающее, куда записывать следующий ключ
                   If Num = 1 Then 'Если в памяти уже записано два ключа, то 
                          addr=86 : edat = 2 'присваиваем адрес начала записи третьего ключа
                   EndIf 'и число, показывающее, куда записывать следующий ключ
                   If Num = 2 Then 'Если в памяти уже записано три ключа, то 
                          addr=92: edat = 3 'присваиваем адрес начала записи четвертого ключа
                   EndIf 'и число, показывающее, куда записывать следующий ключ
                   If Num = 3 Then 'Если в памяти уже записано четыре ключа, то 
                          addr = 74: edat = 0 'присваиваем адрес начала записи первого ключа
                   EndIf 'и число, показывающее, куда записывать следующий ключ
   
                    For I = 0 To 5  
                          ADDR_TEMP = addr + I
                          date = id[I + 1]  
                          GoSub WRITE_ 'Теперрь записываем считанный ключ по указанному адресу
                    Next
                    ADDR_TEMP = 4: date = edat 'Записываем число, показывающее, куда записывать следующий ключ
                    GoSub WRITE_ 'по адресу 4
                    High LED 'Моргнем светодиодом, указывая пользователю, что запись
                    DelayMS 1000 'ключа завершена
                    Low LED
              EndIf
              GoTo WRITE_KEY 'переходим на начало
        EndIf 'Если не включен режим записи ключей
        DelayMS 2000 'то ожидаем 2 секунды перед началом работы сторожа

CheckPhone: 'Инициализация
        GoSub TURN_LED 'Могрнем, показывая, что идет обмен с телефоном
        HSerOut ["AT" ,13]
        HSerIn 500, CheckPhone,[Wait("OK")]'Ждем ответа, если нет , то снова на CheckPhone

CheckPhone2:
        GoSub TURN_LED 'то же самое, только
        HSerOut ["AT+CMGF=0" ,13] 'команда другая - включаем PDU формат
        HSerIn 500, CheckPhone2,[Wait("OK")]'Ждем ответа от телефона 

loop:
        DelayMS 900 'Задержка для видимости моргания светодиода
        GoSub DS1990 'Проверяем, вставлен ли ключ 
        If id[0] = $1 Then 'Если поднесен ключ
              GoSub Read_ 'Сравниваем с записанными значениями
        EndIf
SSSS:
        If Start_OXR = 1 Then 'Если включен режим охраны
              OPTION_REG.7 = 0 'Включаем подтягивающие резисторы
              LED = 1 'Зажигаем светодиод, отображая режим охраны
              If INPUT_1 = 1 Then 'И сразу проверяем канал охраны на разрыв
                    If CH_1_ALLOW = 1 Then 'Если разрешено слежение за ним
                         Gosub Zaderzh
                         If Start_OXR = 0 Then EEEE 'Если хозяин отключил охрану, то вернемся
                         SS = 6: ES = 13 'устанавливаем адрес начала и конца слова для SMS в EEPROM
                         GoSub GO_EACH_CH 'и переходим на оповещение
                   EndIf
             EndIf
             
             If INPUT_2 = 1 Then 'И сразу проверяем канал охраны на разрыв
                    If CH_2_ALLOW = 1 Then 'Если разрешено слежение за ним
                         Gosub Zaderzh
                         If Start_OXR = 0 Then EEEE 'Если хозяин отключил охрану, то вернемся
                         SS = 14: ES = 20 'устанавливаем адрес начала и конца слова для SMS в EEPROM
                         GoSub GO_EACH_CH 'и переходим на оповещение
                   EndIf
             EndIf

EEEE:  
            OPTION_REG.7 = 1 'отключим подтяжку на portb
            LED = 0 '
            DelayMS 500 'погасим светодиод
       EndIf
GoTo loop 'Начнем сначала


GO_EACH_CH:
      LED = 1    
      If onSMS = 1 Then 'Если разрешена отправка SMS
           SN = 38: EN = 49 'Считаем
           GoSub SETNUM 'первый телефонный номер
           GoSub SendSMS 'и отправим на него SMS
           SN = 50: EN = 61 'Считаем
           GoSub SETNUM 'второй телефонный номер
           GoSub SendSMS 'и отправим на него SMS 
           SN = 62: EN = 73 'Считаем
           GoSub SETNUM 'третий телефонный номер
           GoSub SendSMS 'и отправим на него SMS
      EndIf
      DelayMS 5000 'Задержка нужна, так как телефон не успевает отработать
'команду отправки последнего SMS

      If onCall = 1 Then 'Если разрешен дозвон 
            SN = 38: EN = 49 'считаем 
            GoSub SETNUM 'первый телефонный номер
            GoSub Call_ 'и позвоним на него
            SN = 50: EN = 61 'считаем 
            GoSub SETNUM 'второй телефонный номер
            GoSub Call_ 'и позвоним на него
            SN = 62: EN = 73 'считаем 
            GoSub SETNUM 'третий телефонный номер
            GoSub Call_ 'и позвоним на него
      EndIf
      LED = 0 'выключим светодиод
Return
   
'-------------------------------------------------------------------------------------

SendSMS: 'Начало подпрограммы кодирования текста в PDU формат
      j = 0
      For I = SS To ES
            char [j] = ERead I 'Считаем текст СМС в формате ASCII
            Inc j
      Next
'-----Преобразуем в PDU
       tmp[1]=char[1] << 7 
       tmp[2]=char[2] << 6 
       tmp[3]=char[3] << 5 
       tmp[4]=char[4] << 4 
       tmp[5]=char[5] << 3 
       tmp[6]=char[6] << 2 
       tmp[7]=char[7] << 1

       For z = 0 To
             pdu[z]=tmp[z + 1] + (char[z] >> z)
       Next z
   
Check_: 'Начало отправки сообщения на указанный номер (PN[i]), в формате PDU (pdu[i])
       If CONTr = 2 Then  ret1  'Если произойдет сбой, то после первого раза остановимся
        HSerOut ["AT+CMGS=22",13]'команда на отправку сообщения
        Inc CONTr
        HSerIn 5000, Check_,[Wait(">")]'ожидание подтверждения команды
'Непосредственно отправка сообщения
        HSerOut ["0011FF0B91", PN[1],PN[0],PN[3],PN[2],PN[5],PN[4],PN[7],PN[6],PN[9],PN[8],PN[11],PN[10],_
  "0000AA","08",Hex2 pdu[0], Hex2 pdu[1], Hex2 pdu[2], Hex2 pdu[3], Hex2 pdu[4], Hex2 pdu[5], Hex2 pdu[6],Hex2 pdu[7],26]
        HSerOut [13]
         DelayMs 3000

ret1:   CONTr = 0

Return 'Возврат из ПП отправки SMS
   
Call_: 'ПП дозвона по указанному телефонному номеру (PN[i])
         If CONTr = 2 Then  ret2   'Если произойдет сбой, то после первого раза остановимся
        HSerOut ["ATD+",PN[0],PN[1],PN[2],PN[3],PN[4],PN[5],PN[6],PN[7],PN[8],PN[9],PN[10],";",13] 'Звоним...
        DelayMS 5000 'Задержка
        HSerOut ["AT+CPAS" ,13]'Проверка состояния телефона
         Inc CONTr  
        HSerIn 5000, Call_,[Wait("4")] 'Если состояние не то, которое нам нужно (вызов), то на метку Call_
'чтобы попытаться еще раз
        For x = 1 To DELAY 'Даем время хозяину прослушать помещение
              DelayMS 1000
        Next
        HSerOut ["ATH",13] 'Отменяем вызов по окончанию
ret2:   CONTr = 0
Return

WRITE_:
        EWrite ADDR_TEMP,[ date] 'Процедура записи переменных по указанным адресам
Return

Read_: 'ПП считывания кода ключа и сравнения с записанными в память ключами
        For z = 74 To 98 Step 6 'Ключи записаны последовательно с 74 ячейки по 98
              addr = z 'По 6 байт на каждый ключ
              For j = 0 To 5
                    ID_real[j] = ERead addr + j 'Непосредственно считывание из памяти записанных ключей 
              Next
'Сравниваем только что считанные значения ключа с записанными:
        If ID_real[0]=id[1] And ID_real[1]=id[2] And ID_real[2]=id[3] And ID_real[3]=id[4] And ID_real[4]=id[5] And ID_real[5]=id[6] then 
'Если ключ совпадает с одним из записанных
             If Start_OXR = 1 Then 'то, если охрана включена
                   Start_OXR = 0 'отключим ее
                   LED = 0 'погасим светодиод
             Else 'Если же охрана выключена
                   LED = 1 'Зажжем светодиод, указывая на начало постановки на охрану
                   'DelayMS 25000 'Это время дается хозяину на выход из помещения
                   Start_OXR = 1 'Включаем охрану
             EndIf
             GoTo EXIT_ 'выходим
       EndIf
       Next 'Если ключ не совпал с текущим записанным, то сравниваем со следующим
EXIT_:
Return
   
DS1990:
       OWrite dq, 1, [$33] 'Процедура чтения кода ключа  
       ORead dq, 0, [Str id\8] 'в переменную ID[i]
Return

TURN_LED: 'ПП моргания светодиодом
       LED = 1
       DelayMS 250
       LED = 0
Return

SETPARAM: 'ПП считывания параметров работы прибора
        flags = ERead 0 'Считаем флаги
       delrun = ERead 1 'Считаем задержки
       DELAY = ERead 2 'Считаем задержки
' numCall = ERead 3
       Num = ERead 4 'Считаем число, указывающее на кол-во уже записанных ключей
       ALARMFLAGS = ERead 5 'Считаем переменную установок тревоги
Return

SETNUM: 'ПП считывания телефонных номеров
        I = 0
        For x = SN To EN
              PN[I] = ERead x
              Inc
        Next
Return
Zaderzh:
        For I = 1 To delrun 'то задерживаемся на указанное время
               High LED 'В это время, если зашел хозяин
               DelayMS 75 'ему дается возможность отключить охрану
               Low LED 'отображаем этот режим светодиодом
               DelayMS 100 '
               GoSub DS1990 'здесь хозяин может отключить охрану
               If id[0] = $1 Then
                      GoSub Read_
                EndIf 'в нормальный режим
        Next
Return
End
 
Здесь можно скачать проект Proteus + Proton. Устройство собрано и отработано и не в единственном экземпляре. Комментарии приветствуются!

Спонсор статьи: https://yazvnet.ru/



Категория: Proton PICBasic | Добавил: ADMIN (23.11.2009)
Просмотров: 18839 | Комментарии: 20 | Теги: PROTON, Протон, сигнализация, GSM, Проекты, PIC | Рейтинг: 5.0/9
Всего комментариев: 201 2 »
1 DAlexV   (24.11.2009 20:09) [Материал]
Ну вот хотел сам выложить, а меня опередили cry . Спасибо Макс за статью, есть интересные программые решения. Усовершенствую свою, выкину то же. Вопрос по напруге. Сколько VDD в схеме(5 вольтов Сименсы не любят если не ошибаюсь)

4 terrarus   (26.11.2009 09:13) [Материал]
Очень бы хотелось увидеть Вашу статью на такую же тему. Очень полезно для изучения будет нами начинающими.

2 ADMIN   (25.11.2009 05:22) [Материал]
Схема питается от батареи телефона! Это 4 вывод разъема. Там около 2,6 В. Для схемы достаточно. Собрал таким образом около 40 устройств. Проблем не было.

3 terrarus   (26.11.2009 09:11) [Материал]
Очень хорошая статья. Большой ее плюс, что написана программа на Basic, и тем более на PROTON+IDE.
СПАСИБО!!!

5 terrarus   (26.11.2009 09:24) [Материал]
Максим, нельзя ли выложить DSN-файл этого устройства.

6 brown   (26.11.2009 20:19) [Материал]
ADMIN 5 баллов!

7 Семеркин   (31.05.2010 22:44) [Материал]
А есть у кого-нибудь что то похожее только на PICBASICе?

10 ADMIN   (25.02.2011 18:38) [Материал]
Нетрудно перевести на picbasic. Поднимай тему в форуме, поможем.

8 антошка   (21.12.2010 19:43) [Материал]
отличная статья, автору + и Спасибо
P.S. а в место телефона можно SIM300(SIM900) gsm модуль запаять тогда все устройство на одной плате уместится

9 Костя   (18.02.2011 17:07) [Материал]
А как этот код адаптировать под ПИК17С756А? И нужно просто отправление по усарт2 в терминал

11 tolyn   (24.05.2011 23:46) [Материал]
Очень здорово. Нет ли у кого подобного проекта на pic basic pro

12 ADMIN   (05.06.2011 03:50) [Материал]
Я раньше написал, поднимай тему в форуме. Разница между этими basic-ами небольшая

13 retas   (12.12.2011 20:40) [Материал]
Если применять у себя в доме, то DS1990 слишком жирно. У всех есть дист. пульты от какой либо радио апаратуры, вот и надо GSM-сигнализацию научить понимать ихние посылки. И такая програмка (под любой пульт) пригодилась бы везде и всюду- подобную я видел под AVR.

14 ADMIN   (13.12.2011 16:49) [Материал]
А есть универсальный алгоритм для всех пультов, которые есть у всех людей, прочитавших эту статью? К тому же, DS1990 стоит не дороже 40 рублей. Кроме того, пульт если есть у одного, то есть и у кого-то другого. И таким образом, теряется смысл такой сигнализации. Каждый пульт обучать в программе? Не правда ли, так сложней получается?

15 retas   (16.12.2011 02:15) [Материал]
Однако:
1. Упросчается установка системы.
2. Знакомому да и себе с такой програмой сделать можно кучу полезного.
3. То что сигн. управляется пультом, злодею сперва надо знать, потом его найти, знать куда его направить, потом какую нажать кнопку, а на это всё грубо 30сек.
Про подобную мысль тут:
http://easyelectronics.ru/ik-dist....ore-347

16 ADMIN   (17.12.2011 19:44) [Материал]
1) Усложняется изготовление (пульт) и не совсем понятно, чем проще поставить ИК приемник вместо порта для I-Button
2)Полезное сделать можно и без этой статьи.
3)Если злодей настроен серьезно, он пойдет на все (причем не один)
и 4 - в чем проблема? -
"Если применять у себя в доме, то DS1990 слишком жирно. У всех есть дист. пульты от какой либо радио апаратуры, вот и надо GSM-сигнализацию научить понимать ихние посылки. И такая програмка (под любой пульт) пригодилась бы везде и всюду- подобную я видел под AVR."
Вы можете? Напишите статью об этом

17 retas   (18.12.2011 13:30) [Материал]
1. Никакого пульта не потребуется - централь (коробка) где то под потолком, в шкафу... а в ней глазок. К порту для I-Button вам придётся таскать кабель (ограниченным в длине) да прилично оформить.
2. Любой проект, в целом, может мало кому пригодится а какие то моменты из него очень даже - у каждого ведь свои желания.
3. Здесь злодей=вор а он почуяв что квартира с сигнализацией, старается мигом изчезнуть ибо он обречен поднять на ноги соседей, известить хозяев а то и полицию. Если же вы для кого то уж очень большая ценность то нужен пистолет либо охранник - сигнализации не для таких а для рядовых.

Проект под любой пульт, пожалуй, мне не по зубам либо потребовалось бы куча времени в виде вечности. Я склонен думать, что подобное можно найти на англицком если суметь такое устройство по ихнему обозвать.

18 Broka   (29.03.2012 17:45) [Материал]
А что это за переменная CONTr?... её в программе нет......

19 ADMIN   (01.04.2012 18:56) [Материал]
Да было несколько версий, запутался, а может при публикации удалил случайно. Нужно объявить DIM Contr as byte. Это байт - для контроля отправки, если будут ошибки, чтоб не долбил постоянно. Двух раз достаточно, я думаю

1-15 16-16
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]