W poniższym artykule opowiemy, jak można wykorzystać komputer jednopłytkowy z serii Raspberry Pi z dołączonym modemem GSM do wysyłania krótkich wiadomości tekstowych - popularnych SMS-ów. Do tego popularnego minikomputera można dołączyć, na wiele sposobów, modem GSM, pozwalający na komunikowanie się z siecią telefonii komórkowej. W artykule opisany jest sposób podłączania popularnych modemów na USB do minikomputera Raspberry Pi oraz przedstawiona jest biblioteka, dedykowana do wysyłania i odbierania SMS-ów za pomocą tego minikomputera z modemem GSM.
Tego rodzaju system może mieć wiele zastosowań - samodzielnie, bądź w połączeniu z innymi urządzeniami, czy systemami, takimi jak na przykład centralka alarmowa czy system automatyki domowej. W podsumowaniu artykułu przedstawimy kilka potencjalnych zastosowań takiego systemu.
Modemy GSM
Aby dodać funkcjonalność GSM do komputera jednopłytkowego, takiego jak Raspberry Pi, musimy go wyposażyć w modem GSM. Na rynku dostępnych jest wiele urządzeń tego rodzaju - przyjrzyjmy się im, aby wiedzieć jaki mamy wybór, projektując naszą bramkę SMS. Modemy GSM podłączane są do minikomputerów na kilka sposobów.
Typowo, poprzez interfejs szeregowy (UART), który jest wyprowadzony na 40 pinowym złączu GPIO, ale także modem może być podłączony poprzez mostek UART-USB lub jako ‘dongle’ - zintegrowany modem w postaci urządzenia podpinanego bezpośrednio do portu USB komputera.
Jeśli chodzi o modemy GSM podłączane do sprzętowego interfejsu UART na rynku dostępnych jest wiele zintegrowanych modułów - w postaci modułów HAT oraz samodzielnych elementów, do zabudowania w swoich projektach. Moduły typu HAT, czyli dołączane do złącza GPIO minikomputera Raspberry Pi, są najprostsze do użycia w projektach hobbystycznych - wystarczy zamontować moduł na płytkę komputera. Przykład takiego rozwiązania pokazano na fotografii 1. Wszystkie elementy niezbędne dla działania modemu GSM znajdują się w takim module. Także antena lub gniazdo do podłączenia zewnętrznej anteny. Jeśli nie chcemy korzystać z modułu tego rodzaju, możemy zbudować własny w oparciu o zintegrowany modem GSM o odpowiadających nam parametrach (2G, 3G, 4G) i z potrzebnymi nam dodatkowymi funkcjami. Modem wymaga zainstalowania karty SIM lub tzw. embedded SIM (eSIM), czyli karty w postaci układu scalonego, lutowanego na płytce.
Osobną klasę sprzętów stanowią popularne modemy GSM na USB. Ich podłączanie do komputera z systemem operacyjnym Windows jest bardzo proste, niestety w przypadku Linuksa, który standardowo instalowany jest na komputerach jednopłytkowych, nie jest to już takie trywialne. Istnieje wiele przewodników dostępnych w sieci, wykorzystujących np. skrypt sakis3g, ale uruchomienie niektórych modemów wymaga większego nakładu pracy. Poniżej przedstawimy uniwersalny sposób na podłączenie tego rodzaju modemu do Raspberry Pi pracującego z systemem operacyjnym Raspbian.
Główny problem z podłączaniem tego rodzaju dongla do Raspberry Pi polega na tym, że większość modemów USB zgłasza się jako dwa urządzenia - urządzenie pamięci masowej USB oraz modem USB. Po podłączeniu do Raspberry PI urządzenie zwykle znajduje się w trybie pamięci USB. Istnieje specjalny program o nazwie usb_modeswitch, który może zostać wykorzystany do przełączania trybów zgłaszania się dongla USB. Druga brakująca część to sposób na połączenie się z siecią komórkową za pomocą modemu USB z poziomu minikomputera Raspberry Pi. W tym celu wykorzystane zostanie klasyczne oprogramowanie ppp i wvdial.
W pierwszej kolejności musimy zainstalować program do przełączania trybów urządzenia USB. W tym celu korzystamy z apt-get; w terminalu systemu wpisujemy:
DefaultVendor=0x19d2
DefaultProduct=0x2000
TargetVendor=0x19d2
TargetProduct=0x2002
MessageContent=”5553424312345678000000000000061e000000000000000000000000000000”
MessageContent2=”5553424312345679000000000000061b000000020000000000000000000000”
MessageContent3=”55534243123456702000000080000c85010101180101010101000000000000”
W ten sposób określamy, jakie ma być docelowe VID i PID podłączonego urządzenia - ma to być modem GSM.
Po skonfigurowaniu urządzenia tak, aby uruchamiało się każdorazowo jako modem GSM, musimy skonfigurować łączenie się z siecią GSM. W tym celu instalujemy wymienione wcześniej w tekście programy ppp oraz wvdial. Do instalacji używamy klasycznie apt-get. W terminalu wpisujemy:
sudo apt-get install ppp wvdial
Po zainstalowaniu potrzebnego oprogramowania możemy przystąpić do konfiguracji wvdial. W tym celu otwieramy do edycji plik konfiguracyjny /etc/wvdial.conf. W pliku tym wpisujemy następujący blok konfiguracji:
[Dialer 3gconnect]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Init3 = AT+CGDCONT=1,”IP”,”APN”
Stupid Mode = 1
Modem Type = Analog Modem
ISDN = 0
Phone = *99#
Modem = /dev/gsmmodem
Username = { }
Password = { }
Baud = 460800
W ten sposób skonfigurowaliśmy tzw. dialer, czyli moduł łączący nas z Internetem. W powyższej konfiguracji zamiast zaznaczonego na żółto APN podać musimy nazwę sieci pakietowej, z jakiej korzystamy do łączenia się z Internetem. Numer telefonu, zaznaczony na żółto - *99# - jest typowym numerem dostępowym w internecie mobilnym, ale istnieje możliwość jego edycji, gdyby nasz dostawca usług wykorzystywał inny. Jeśli nasze połączenie wymaga podania nazwy użytkownika oraz hasła (odpowiednio Username i Password), to wpisujemy je w nawiasy klamrowe w pliku konfiguracyjnym.
Po uzupełnieniu wszystkich danych możemy przystąpić do łączenia się z siecią. Aby to zrobić musimy w pierwszej kolejności skonfigurować dongle do pracy jako modem USB, a następnie wykorzystać skonfigurowany przed chwilą dialer do połączenia się z siecią. W tym celu w terminalu wpisujemy:
Biblioteka do połączenia z modemem GSM
Biblioteka, która zaprezentowana jest na listingu 1 jest dedykowana do stosowania w skryptach języka Python. Korzysta z komend AT, aby kontrolować pracę modemu - wysyłać i odbierać wiadomości tekstowe. W bibliotece zdefiniowano szereg funkcji, które używane są do komunikacji z modemem GSM w celu wysłania czy odebrania wiadomości tekstowej. Komentarze w listingu 1 powinny dostatecznie tłumaczyć zastosowanie poszczególnych funkcji. Jako parametr modem podajemy adres sprzętowy portu szeregowego do którego dołączony jest nasz modem. W przypadku dongla na USB będzie to, na przykład, /dev/ttyUSB1.
Listing 1. Biblioteka do połączenia z modemem GSM
import serial, time, logging
from curses import ascii
# logowanie działania aplikacji
logger = logging.getLogger(__name__)
def openModem(modem, time):
"""Otwarcie połączenia z modemem"""
logger.info("Openning " + modem)
serialPort = serial.Serial(modem, 460800, timeout=5)
if serialPort.isOpen():
logger.info("Modem opened.")
return serialPort
else:
logger.error("Could not open modem")
return -1
def closeModem(modem):
"""Zamknięcie połączenia z modemem"""
if modem.isOpen():
modem.close()
logger.info("Modem closed.")
else:
logger.error("Modem is not opened.")
def checkModem(modem):
"""Sprawdzenie połączenia z modemem"""
modem.write("AT\r")
modem.readline()
status = modem.readline()
if status.startswith("OK"):
logger.info("AT OK")
return True
else:
logger.error("AT ERROR")
return False
def setModemTextMode(modem):
"""Ustawienie modemu w trybie tekstowym
(do wysyłania wiadomości SMS"""
modem.write("AT+CMGF=1\r")
modem.readline()
status = modem.readline()
if status.startswith("OK"):
logger.info("Modem set in text mode")
return True
else:
return False
def sendSMS(modem, phoneNumber, text):
"""Wysłanie wiadomości SMS"""
modem.write(‘AT+CMGS="%s"\r’ %phoneNumber)
modem.write(text)
modem.write(ascii.ctrl(‘z’))
time.sleep(2)
modem.readline()
modem.readline()
modem.readline()
cmgi = modem.readline()
modem.readline()
modem.readline()
status = modem.readline()
if status.startswith("OK"):
logger.info("SMS sent.")
return True
else:
logger.error("Error sending SMS")
return False
def deleteSMS(modem, messageIndex):
"""Skasowanie wiadomości SMS z pamięci"""
modem.write("AT+CMGD=%s\r" %messageIndex)
modem.readline()
status = modem.readline()
if status.startswith("OK"):
logger.info("SMS deleted")
return True
else:
return False
def readSMS(modem, messageIndex):
"""Odczytanie wiadomości SMS"""
modem.write("AT+CMGR=%s\r" %messageIndex)
time.sleep(2)
modem.readline()
header = modem.readline()
logger.info(header)
body = modem.readline()
modem.readline()
status = modem.readline()
logger.info("Status is: " + status.strip())
if status.startswith("OK"):
logger.info("SMS read.")
headerParts = header.split(",")
if len(headerParts) > 1:
return "-".join([headerParts[1].strip(‘"’), body])
else:
return body
else:
logger.error("Error reading SMS")
def readLineFromModem(modem):
"""Odczytanie jednej linii z interfejsu UART"""
return modem.readline()
def flushBuffer(modem):
"""Wyczyszczenie buforu interfejsu UART"""
modem.readlines()
def getMessageIndex(newMessageString):
"""Pobierz ilość SMSów (aktualny indeks w liście)"""
newSMSIndicationParts = newMessageString.strip().split(":")
logger.debug(newSMSIndicationParts[1])
messageIndex = newSMSIndicationParts[1].split(",")[1]
logger.debug(messageIndex)
return messageIndex
Stosując opisywaną bibliotekę do wysyłania wiadomości SMS w pierwszej kolejności należy połączyć się z modemem, wykorzystując funkcję openModem. Następnie trzeba przełączyć modem do trybu tekstowego korzystając z funkcji setModemTextMode i już można wysyłać SMS-y z pomocą funkcji sendSMS. Po zakończonej pracy z modemem nie zapominajmy zamknąć połączenia funkcją closeModem.
Przykłady wykorzystania bramki GSM
Podstawowym zastosowaniem opisanego wyżej systemu jest oczywiście wysyłanie i odbieranie SMS-ów. Taka funkcjonalność przydatna jest w szerokiej klasie programów. Bibliotekę można zastosować do stworzenia bramki SMS - urządzenia, które pozwoli nam wysyłać z poziomu komputera wiadomości tekstowe. Jeżeli uzupełnimy program napisany w Pythonie o interfejs webowy, na przykład napisany z wykorzystaniem frameworku Flask, możemy stworzyć prostą bramkę SMS, dostępną jako strona w naszej wewnętrznej domowej sieci.
Biblioteka może posłużyć też do rozbudowy innych aplikacji o możliwość komunikacji za pomocą wiadomości SMS. W szczególności w systemach automatyki domowej może to być wartościowe - pozwala z jednej strony np. sterować poszczególnymi urządzeniami w domu z pomocą wiadomości SMS lub wysyłać SMS-owe alerty.
Z systemu SMS skorzystać można też w samochodzie. Raspberry Pi w naszym pojeździe może np. komunikować się z interfejsem diagnostycznym OBD-II, aby zbierać istotne parametry pracy silnika w naszym pojeździe, a następnie wysyłać nam SMS-y, jeżeli któreś z nich wychodzą poza normę, lub też auto zgłasza jakieś usterki z pomocą kodów błędów. Jeśli do takiego urządzenia dodamy np. moduł nawigacji satelitarnej (GPS), który często jest instalowany na wspólnych modułach HAT z modemami GSM, z łatwością stworzyć możemy system śledzenia pozycji naszego auta, przydatny w razie kradzieży pojazdu... lub gdy zapomnimy, gdzie go zaparkowaliśmy.
Nikodem Czechowski