GPS-приёмник в OpenWrt

Появление на рынке большого разнообразия готового дешевого железа, такого как роутеры и отладочные платы, а также развитие проекта OpenWrt сделало доступным для любого желающего стать разработчиком. Мир для разработчика превратился в конструктор, где нужно только желание и наличие свободного времени, чтобы из разных деталей собрать что-то интересное.

Нашими деталями конструктора будут, как обычно, роутер, gps-приёмник, OpenWrt. В своё свободное время,(когда оно было в последний раз)) ), делаю робота, которого ко всему прочему планировал наградить и gps-разумом. И какое-то время назад для меня словосочетание gps-модуль выглядело как-то пугающе. Настало время развеять этот миф!

На этапе конфигурации OpenWrt нужно отметить следующие модули:
Kernel modules:
USB Support:
<M> kmod-usb-serial
<M> kmod-usb-serial-pl2303
Network:
<M> gpsd
Utilities:
<M> lcd4linux
<*> LCD2USB
<*> gps
Utilities:
<M> lcdproc

После того, как сборка закончилась, необходимо сделать следующее. Зайти в директорию OpenWrt, где находятся собранные пакеты, и скопировать на раздел флэшки (MyData), который монтируется к /home, пакет - gpsd-2.94. У меня путь до пакета вот такой: /OpenWrt/build_dir/target-mipsel_uClibc-0.9.31.

Загружаемся и устанавливаем пакеты.

root@OpenWrt:/# opkg update
Downloading ftp://ftp:ftp@192.168.0.9/Packages.gz.
Inflating ftp://ftp:ftp@192.168.0.9/Packages.gz.
Updated list of available packages in /var/opkg-lists/localpackages.
root@OpenWrt:/# opkg list |grep lc
lcd4linux - r1116-2 - LCD4Linux is a small program that grabs information from the kernel and
lcdproc - 0.5.2-1 - LCDProc is a daemon and client for displaying system information on various displays.
root@OpenWrt:/# opkg list |grep gp
gpsd - 2.94-1 - An interface daemon for GPS receivers
root@OpenWrt:/# opkg list |grep seria
l
kmod-usb-serial - 2.6.36.2-1 - Kernel support for USB-to-Serial converters
kmod-usb-serial-pl2303 - 2.6.36.2-1 - Kernel support for Prolific PL2303 USB-to-Serial converters
root@OpenWrt:/# opkg install gpsd kmod-usb-serial-pl2303 lcdproc
lcd4linux
Installing gpsd (2.94-1) to root...
Downloading ftp://ftp:ftp@192.168.0.9/gpsd_2.94-1_brcm47xx.ipk.
Installing libpthread (0.9.31-64) to root...
Downloading ftp://ftp:ftp@192.168.0.9/libpthread_0.9.31-64_brcm47xx.ipk.
Installing librt (0.9.31-64) to root...
Downloading ftp://ftp:ftp@192.168.0.9/librt_0.9.31-64_brcm47xx.ipk.
Installing kmod-usb-serial-pl2303 (2.6.36.2-1) to root...
Downloading ftp://ftp:ftp@192.168.0.9/kmod-usb-serial-pl2303_2.6.36.2-1_brcm47xx.ipk.
Installing kmod-usb-serial (2.6.36.2-1) to root...
Downloading ftp://ftp:ftp@192.168.0.9/kmod-usb-serial_2.6.36.2-1_brcm47xx.ipk.
Installing lcdproc (0.5.2-1) to root...
Downloading ftp://ftp:ftp@192.168.0.9/lcdproc_0.5.2-1_brcm47xx.ipk.
Installing libncurses (5.7-3) to root...
Downloading ftp://ftp:ftp@192.168.0.9/libncurses_5.7-3_brcm47xx.ipk.
Installing lcd4linux (r1116-2) to root...
Downloading ftp://ftp:ftp@192.168.0.9/lcd4linux_r1116-2_brcm47xx.ipk.
Configuring librt.
Configuring libpthread.
Configuring kmod-usb-serial.
Configuring kmod-usb-serial-pl2303.
Configuring libncurses.
Configuring lcdproc.
Configuring gpsd.
Configuring lcd4linux.

Подключим gps-приёмник и посмотрим вывод dmesg:

root@OpenWrt:/# dmesg
pl2303 1-1.2:1.0: pl2303 converter detected
usb 1-1.2: pl2303 converter now attached to ttyUSB0

Теперь запустим демона, который будет получать данные от gps-приёмника.

root@OpenWrt:/# gpsd -N -D5 /dev/ttyUSB0
gpsd: launching (Version 2.94)
gpsd: opening IPv4 socket
gpsd: opening IPv6 socket
gpsd: can't create IPv6 socket
gpsd: listening on port 2947
gpsd: NTPD shmat(32769,0,0) succeeded, segment 0
gpsd: NTPD shmat(65538,0,0) succeeded, segment 1
gpsd: NTPD shmat(98307,0,0) succeeded, segment 2
gpsd: NTPD shmat(131076,0,0) succeeded, segment 3
gpsd: running with effective group ID 0
gpsd: running with effective user ID 0
gpsd: stashing device /dev/ttyUSB0 at slot 0

Если gpsd демон стартанул без ошибок, то можно его перезапустить в фоновом режиме:

root@OpenWrt:/# gpsd /dev/ttyUSB0

Для того, чтобы получать данные от gpsd демона, можно использовать различные клиенты. Некоторые примеры входят в состав пакета gpsd-2.94, который мы скопировали на в директорию /home.

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

Запускаем cgps.

root@OpenWrt:/# /home/gpsd-2.94/.libs/cgps

На экране должна появится вот такая форма с текущими данными:

Интересно проверить, настоящие ли это данные... Открываем карты Google и вставляем туда текущие координаты. ))

Хотелось бы вывести эти данные и на жк-дисплей. Сделать это опять же очень просто, используя gps-клиента от Lcd4linux. Для этого нужно немного исправить файл lcd4linux.conf, добавив туда, допустим, вот такой gps виджет:
Widget gps-test1 {
class 'Text'
expression gps::parse('0x0000111','0')
width 20
update tack
align 'C'
}

Можно посмотреть, как это сделано у меня lcd4linux.conf. Также это хорошо описано на сайте Lcd4linux вот здесь https://www.bulix.org/projects/lcd4linux/wiki/plugin_gps.

Перед запуском Lcd4linux нужно объявить переменную GPS_PORT, как это описано на сайте. И для gps-клиента от Lcd4linux не требуется работа демона gpsd. Поэтому следует выполнить

killall gpsd

Запускаем Lcd4linux:

root@OpenWrt:/# export GPS_PORT=/dev/ttyUSB0
root@OpenWrt:/# lcd4linux -vv -F
LCD4Linux 0.11.0-SVN-1092 starting
Dump of /etc/lcd4linux.conf:
Display 'LCD2USB'
Display:LCD2USB.Backlight 1
Display:LCD2USB.Driver 'LCD2USB'
Display:LCD2USB.Icons 1
Display:LCD2USB.Size '16x2'
Layout 'Default'
Layout:Default.Row1.Col1 'gps-test1'
Layout:Default.Row2.Col1 'gps-test2'
Variables.tack 100
Variables.tick 500
Widget:gps-test1.align 'L'
Widget:gps-test1.class 'Text'
Widget:gps-test1.expression gps::parse('0x10000110','0')
Widget:gps-test1.update tack
Widget:gps-test1.width 16
Widget:gps-test2.align 'L'
Widget:gps-test2.class 'Text'
Widget:gps-test2.expression gps::parse('0x10001001','0')
Widget:gps-test2.update tack
Widget:gps-test2.width 16
plugin_cfg.c: Variable tack = '100' (100)
plugin_cfg.c: Variable tick = '500' (500)
plugin_gps.c: v0.2
lcd4linux.c: initializing driver LCD2USB
LCD2USB: $Rev: 975 $
LCD2USB: scanning USB for LCD2USB interface ...
LCD2USB: found LCD2USB interface on bus 001 device 010
LCD2USB: echo test successful
LCD2USB: firmware version 1.09
LCD2USB: installed controllers: CTRL0
LCD2USB: reserving 1 of 8 user-defined characters for icons
initializing layout 'Default'
layout.c: Layout:Default: migrating 'row1.col1' to 'Layer:1.row1.col1'
layout.c: Layout:Default: migrating 'row2.col1' to 'Layer:1.row2.col1'
Creating new timer group (100 ms)
widget 'gps-test1': Class 'text', Parent '', Layer 1, Row 0, Col 0 (to 0,16)
widget 'gps-test2': Class 'text', Parent '', Layer 1, Row 1, Col 0 (to 1,16)
lcd4linux.c: starting main loop

Если вы при запуске получили вот такое сообщение:

LCD4Linux 0.11.0-SVN-1092 starting
security error: owner and/or group of '/etc/lcd4linux.conf' don't match
security error: group or other have access to '/etc/lcd4linux.conf'

Необходимо изменить свойства файла lcd4linux.conf
следующим образом:

root@OpenWrt:/# chmod 600 /etc/lcd4linux.conf
root@OpenWrt:/# chown root:root /etc/lcd4linux.conf

У меня на дисплее все значения были по нулям. Хотя только что при запуске cgps мы видели, что всё работает. Ну хоть немного придется задействовать мыслительную часть мозга. ))) Открываем исходный файл gps-клиента — plugin_gps.c и находим в нём следующую строку:
GPS_9600<------>serial port speed, default is 4800 baud, if you define this var speed will be 9600 (export GPS_9600=dummy)

Мой gps-приёмник работает на скорости 9600, в то время как скорость 4800 является по умолчанию. Изменим скорость и снова запустим lcd4linux:

root@OpenWrt:/# export GPS_9600=dummy

Вот теперь посмотрим на дисплей. Должно выглядеть примерно так:

Перед тем, как рассмотреть еще один графический клиент, сделаем маленькое отступление и рассмотрим утилиту lcdproc, которая также как и модули lcd4linux выводит системную информацию. До запуска lcdproc нужно запустить демон LCDd, который является серверной частью lcdproc.

В конфигурационном файле демона LCDd нужно добавить информацию о нашем дисплее:
[hd44780]
ConnectionType=lcd2usb
Contrast=850
Brightness=800
OffBrightness=0
Keypad=yes
Backlight=yes
Size=20x2

Прописать путь:
DriverPath=/usr/lib/lcdproc/

Изменить тип драйвера:
Driver=hd44780

Можно посмотреть, как это сделано у меня LCDd.conf. Также это хорошо описано на сайте lcdproc вот здесь http://lcdproc.sourceforge.net/docs/current-user.html#hd44780-lcd2usb

Запускаем демона LCDd:

root@OpenWrt:/# LCDd

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

Далее запускаем клиента — lcdproc.

root@OpenWrt:/# lcdproc

На дисплее должно быть примерно следующее:

А теперь вернемся к нашему gps-приёмнику. В примерах к gpsd есть и клиент для lcd дисплея — lcdgps. Для его работы как раз и необходим демон LCDd. Посмотрим, как работает lcdgps. Запускаем:

root@OpenWrt:/# gpsd /dev/ttyUSB0
root@OpenWrt:/# LCDd
root@OpenWrt:/# /home/gpsd-2.94/.libs/lcdgps

На дисплее должно быть примерно следующее:

Gps-приёмник