Програмований GSM телефон на Raspberry Pi

Колись одного разу...

Якось підшукуючи аксесуари до Raspberry Pi я випадково натрапив на GSM-модуль для Raspberry Pi на основі GSM модуля SIM900 і вирішив побавитись з ним. Як виявилось, цей модуль перетворює Raspberry Pi на повноцінний мобільний телефон, програмований через модемні AT команди.

Найпростішим для мене як для Java-програміста способом працювати з цим всім виявилась Groovy Shell + Java бібліотеки для роботи з послідовним портом (jSSC) та GPIO пінами Raspberry Pi (Pi4J). Все це робилось на Raspberry Pi Model B під OS Raspbian (Debian Wheezy Linux). Отже ділюсь своїм досвідом.

В Україні Raspberry Pi та GMS-модуль можна придбати наприклад на arduino-ua.com.

Що це і з чим його їдять?

Сам модуль являє собою платку котра «насаджується» на GPIO піни Raspberry Pi. Керування модулем відбувається через послідовний порт та GPIO піни для включення/виключення модуля і для «скиду» (reset). Для роботи з GSM мережею потрібна звичайна повнорозмірна SIM-карта. Для вводу/виводу звуку модуль має мікрофонний вхід та лінійний вихід для звичайних 3.5" jack роз'ємів. Також на модулі є пара світлодіодних індикаторів — стану модуля та стану з'єднання із GSM мережею.

До модуля додається C-шна бібліотека і пара сішних демо програм, але все це добро написано досить криво і з коробки не зовсім працює. Логіка підказує що перед використанням SIM карти потрібно ввести PIN код, але можливості це зробити бібліотека не надає. Також немає out-of-the-box можливості вводити будь-які AT команди — хоча невелика модифікація бібліотеки дозволяє витягти в публічний інтерфейс ці методи, в цілому все це досить незручно.

Для експериментування хотілось вводити AT команди інтерактивно, тому, як я вже писав вище, я вирішив використати давно любимий мною інструмент — Groovy Shell. Groovy Shell це інтерактивна консоль для Java/Groovy яка йде в дистрибутиві Groovy (bin/groovysh).

PDF з AT командами для SIM900 вільно доступна на FTP виробника Pi адаптера. Там само можна знайти ще документацію.

Початок — включення

Для програмного включення/виключення та reset-у модуля потрібна бібліотека для роботи з GPIO пінами Raspberry Pi. Для Java існує така бібліотека — Pi4j. Хоча насправді можна обійтись і без неї і включати модуль разом з Raspberry Pi фізично руками. Але якщо вже автоматизувати то автоматизувати. Звичайно, можна спрочатку включити модуль через який-небудь python скріпт для GPIO (використання python з відповідними бібліотеками — типове рішення для роботи з GPIO на Raspberry Pi), але якщо Java то вже Java.

Для доступу до послідовного порта використовувалась бібліотека Java Simple Serial Connector — jSSC

Все це добро разом з депендами було викачане з офіційних сайтів і складене в lib фолдер в дистрибутиві groovy.

Тепер можна запустити GroovyShell (/bin/groovysh), але для доступу до GPIO потрібно робити це через sudo.

Алгоритм та код для включення досить простий — взяти пін, «включити», почекати декілька секунд, «виключити»:

gpio = com.pi4j.io.gpio.GpioFactory.getInstance();
pin = gpio.provisionDigitalOutputPin(com.pi4j.io.gpio.RaspiPin.GPIO_00, "Pin00", com.pi4j.io.gpio.PinState.LOW);
pin.setState(com.pi4j.io.gpio.PinState.HIGH);
Thread.sleep(3000);
pin.setState(com.pi4j.io.gpio.PinState.LOW);

Після цих маніпуляцій індикатор стану на SIM900 має загорітись.

Налаштовуєм SIM — PIN-код та адреса SMS-центру

Почнем з того, що відкриємо доступ до порта та ініціалізуєм модем:

sp = new jssc.SerialPort("/dev/ttyAMA0");
sp.openPort();
sp.setParams(9600, 8, 1, 0);

def readPort(p) { s = p.readString(); while(s!=null) { println s; s= p.readString(); } }

sp.writeString("AT\r");
readPort(sp);

Остання команда має повернути результат:

AT
OK

Тепер, як підказує мануал, для вводу PIN коду потрібно виконати команду AT+CPIN, а для налаштування номеру SMS центру — AT+CSCA. Мій PIN — 1111:

sp.writeString("AT+CPIN=1111\r");
readPort(sp);

Повертає:

AT+CPIN=1111
OK

Виконуєм:

sp.writeString("AT+CSCA=\"+380672021111\"\r");
readPort(sp);

Повертає:

AT+CSCA="+380672021111"
OK

Якщо замість OK повертається ERROR, просто виконайте команду ще раз. Я не впевнений чому, але перший раз буває повертає ERROR.

Після вводу PIN коду зелений світлодіодний індикатор на модулі має змінити частоту свого мерехтіння після того як приєднається до GSM мережі.

Відправляєм та приймаєм SMS

Робота з SMS в модулі може бути відносно складна, адже це по суті повноцінний телефон, який зберігає SMS — чорновики, вхідні, вихідні і т.п. Для простоти використаєм текстовий режим роботи з SMS (див. документацію):

sp.writeString("AT+CMGF=1\r");
readPort(sp);

Відправляєм сам SMS:

sp.writeString("AT+CMGS=\"+38<номер телефону>\"\r");
sp.writeString("Test message"+((char)0x1a));
readPort(sp);

Повертає:

AT+CMGS="+38<номер телефону>"
> Test message

Через деякий час на телефон приходить SMS з текстом «Test message». Вичитаємо ще раз з порту після затримки:

Thread.sleep(3000);
readPort(sp);

Повертає:

+CMGS: 4

OK

З мобільного я відповідаю на SMS текстом «hi».

Тепер вичитаєм вхідний SMS:

sp.writeString("AT+CMGL=\"ALL\"\r");
readPort(sp);

Повертає:

AT+CMGL="ALL"
+CMGL: 1,"REC UNREAD","+38<номер телефону>","","14/07/24,03:15:45+12"
hi

OK

Прибирання — видалимо всі SMS:

sp.writeString("AT+CMGL=\"ALL\"\r");
readPort(sp);
Щє дещо

Перевіряєм стан рахунку:

sp.writeString("ATD*111#\r");
readPort(sp);

Повертає:

ATD*111#
OK

Повторюєм readPort поки не отримаєм результат на кшталт такого:

+CUSD: 0,"Na rahunku: 108.75 grn. Info pro bonusy na *112# i *118#.
Popovniujte bud'-yakyj nomer telefonu za dopomogoju *448#

",64
Епілог

Ось наразі і все. Для більшого «фану» можна ще здійснити дзвінок з/на пристрій, але це все працює приблизно так само як і SMS — команда для вихідного дзвінку, команда для опиту стану дзвінків (чи є вхідні), команда для зняття трубки і т.п. Звичайно, для більш змістовного викоритсання бажано принаймні включити в пристрій колонки чи навушники. Але такі речі вже кращє демонструвати на відео а не описувати в статтях. Тому на цьому завершуєм.

Коментарі 4

vlisivka - 26 вересня 2014, 15:29

Дистанційного шпійона на ньому забацати можна? Напр. почув звук важкої гусеничної техніки — послав СМС_-ку в штаб чи зробив дзвінок.

mvmn - 26 вересня 2014, 15:33

Теоретично можна, але потрібно щоб мобільний зв'язок не пропадав — а в зоні АТО з цим проблеми.

Крім того, рішення само по собі не є водостійким, потребує живлення і т.п.

Ну і щодо звуку важкої техніки — нажаль програмно відрізнити від будь-якого голосного звуку буде складно. Я не знаю яким чином таке можна зробити.

vlisivka - 26 вересня 2014, 15:48

Крім зони АТО, є ще й інші зони, де зв’язок є, і де потрібно вести спостереження. Водо-морозо-стійкість — це окрема проблема, як і живлення. Літом можна використовувати сонячну батарею та акумулятор. Взимку можна просто закопати біля дороги на глибину промерзання (тільки антену вивести) і використовувати велику хімічну батарею (всеодно дешевше ніж тримати солдата на позиції).

Звуки важкої техніки чи звуки голосу можна розпізнати по частотному спектру. Особлива точність не потрібна — це буде ліс чи поле, де не буде великої кількості шумів. Основне правило: щось почув — записуй і труби тривогу.

mvmn - 30 червня 2016, 15:08

Лайфхак - перед посиланням команд на SIM900 варто послати ctrl+z щоб очистити буфер від сміття чи попередніх response-ів.

Коментувати
© 2009 - 2020, Розробка - соціальна ІТ спільнота.
Контакти: info@rozrobka.com
Правила користування