Sunday, September 26, 2021

SARTopo and APRS

Update: 3/20/2023 - CalTopo now has KISS support, rendering the information below unnecessary.


SARTopo/Caltopo is a great tool for making maps as it has an option to generate printable PDFs with specific scales (1:24000) and either a UTM or USNG grid.   These work well with a compass for land navigation.   There is an offline version of their software that even supports APRS objects.     I started exploring this option as I would like to be able to connect SARTopo offline to a local radio without needing any IGATE or internet access.

The SARTopo/Caltopo offline/desktop version requires input in the TNC2 format, used most often by IGATEs.   The standard output from Direwolf comes close but includes some extra information about audio level/channel that causes problems for SARTopo.


Hardware

Yaesu FT-857d

Signalink USB

Laptop with Windows 10 Pro


Direwolf

Install Com0Com virtual port

Follow Direwolf instructions to setup virtual com port pair (COM3/COM4)

Make sure to test using Putty or Telnet

Install Cygwin and the packages mentioned in the Direwolf User Manual

Clone the git repo per instructions in User Manual

Checkout the DEV branch

Edit the source on direwolf.c and change lines of code in app_process_rec_packet to not print out [%d.%d%s] or [%d%s]

Follow the Direwolf User Manual steps to build new executables.  Version 1.6 is slightly different than the manual.  When you run "make", it will tell you the new process.

Now you have an executable that can send data to the Sartopo application.

Setup a batch script to launch Direwolf and dump the output to COM3. 

C:\cygwin64\home\<username>\direwolf\build\src\direwolf.exe -l C:\Radio\Direwolf\logs -c C:\cygwin64\home\<username>\direwolf\build\src\direwolf.conf -q h>COM3


SARTopo/Caltopo

Old versions of Sartopo Offline

Edit the Sartopo config file:

C:\<path to caltopo>\caltopo-offline\caltopo\cal.properties

New versions of Caltopo-desktop

C:\Users\<username>\

Add these lines, per SARTopo documentation to the topo.properties file

sarsoft.location.aprs.local.enabled=true

sarsoft.location.serial.COM4=1200,8,1,0

log4j.logger.org.sarsoft.location.service.APRSLocalEngine=INFO

log4j.logger.org.sarsoft.location.service.APRSSerialThread=DEBUG


Launch SARTopo Offline/Caltopo-Desktop

Setup a new map and add a locator object.

Since you have debugging enabled, you should see the packet data appear in the commandline.

As APRS packets are received locally,  you should start to see them appear on the map.


Future

Figure out how to avoid building a custom version of Direwolf.   It may be possible to host an IGATE server or redirect the IGATE packets from Direwolf.




Sunday, December 23, 2018

JNOS2 and Ubuntu Virtual Box



I'm running Ubuntu 18.04.1 LTS in an Oracle Virtualbox with a bridged network adapter on a Windows 10 laptop. I've got my Yaesu FT-857D and Signalink usb connections shared with the VM.  I'm thinking I need to use Direwolf.  However my Kenwood TH-D74a has a built in KISS TNC and was super easy to access in Linux.

To get JNOS2 to work, I thought I'd be able to just follow the instructions listed on the webpages.  Unfortunately this did not work for me.

When I downloaded and extracted the tar file and tried to run the installer, a message saying the file or directory doesn't exist.   This seems to indicate that prerequisite libraries aren't installed.  Eventually I discovered these needed to be installed:

sudo apt-get install libncurses5-dev
sudo apt-get install libssl-dev

I then received messages like in this thread: http://lists.tapr.org/pipermail/nos-bbs_lists.tapr.org/2018-July/005312.html

To resolve this, I downloaded this:

wget https://www.langelaar.net/jnos2/archive/news/tun_sp2l.c
cp tun_sp2l.c   <src directory>/tun.c

Running the make command was finally successful.  The JNOS installer ran successful. 




Tuesday, July 17, 2018

Private Cloud

My next project is building a private cloud to see if I can take my OpenGIS project up a notch or two in order to support field deployable networks.


Existing Hardware:

  • Gigabit Switch
  • Linksys WRT1900AC running OpenWRT
  • Various ODroid C2 and Raspberry PI computers


New Hardware:

Future Hardware (whenever I find more $)
  • 10GB SFP 
  • Fiber 
  • NAS for storage
  • Ram and Storage Upgrades

Software:


With any luck, I'll be able to build out Zones/Containers/Virtual Machines to support not only GIS servers, databases, and web app servers but also some servers to run ham radio apps like PAT and maybe be able to process IoT sensors streams.


Wednesday, October 4, 2017

AX25, ODroid, PAT Part 2

At first I tried the deb package both linux and armhf but ran into problems with each.  Solution was to build from source.

Build from Source:

https://github.com/la5nta/pat/wiki/Building-from-source
sudo apt-get install golang-go
export GOPATH=`pwd`
Attempts at using go to do the install failed.

git clone https://github.com/la5nta/pat $GOPATH/src/github.com/la5nta/pat
cd $GOPATH/src/github.com/la5nta/pat
git submodule update --init --recursive
./make.bash libax25
./make.bash
sudo cp pat /usr/local/bin

Success. Now edit the config:
vi /home/odroid/.wl2k/config.json
Enter your callsign, winlink password, locator, etc.

I set the serial-tc path to:  /dev/ttyACM0

Not sure if this will work yet though.

Run the web client with:
pat http

Next blog post...try to send an email P2P.

73

Tuesday, October 3, 2017

AX25,ODroid and PAT/Winlink

Considering what has been happening in Puerto Rico with Hurricane Maria, I decided  I need to get  Winlink operational so I can send email over radio.  Since I prefer Linux, I started exploring options and found PAT, http://getpat.io/, a cross-platform Winlink client.

Goal:   Get the Kenwood TH-D74A built in KISS TNC to send Winlink email using the PAT client on Ubuntu 16.04 on a 64Bit ODroid C2

Make sure the TH-D74A has the most recent firmware.

On Kenwood TH-D74A, go to:

Menu > Configuration > Interface > KISS > USB or Bluetooth.  I chose USB.

Instructions:
https://github.com/la5nta/pat/wiki/AX25-Linux

Power on the TH-D74 and plug usb cable into it and the ODroid C2.

On the ODroid C2, use 'dmesg' to find the device name:  /dev/ttyACM0

sudo apt-get update && upgrade -y
sudo apt-get install ax25-tools

Modify /etc/ax25/axports

sudo apt-get install ax25-apps


Here is where problems begin:

sudo modprobe ax25

sudo modprobe mkiss

I received messages indicating modprobe cannot find the necessary modules.

Solution

Build a custom kernel
https://github.com/umiddelb/armhf/wiki/How-To-compile-a-custom-Linux-kernel-for-your-ARM-device



Verify your kernel version with:

uname -r

My ODroid say 3.14.79-97

Install the prerequisite software and start the process.

Make sure to run this:

make menuconfig


After completing this step, I decided to make an image of the ODroid OS as a backup in case I screwed something up badly.  To do this, I shutdown the ODroid, ejected the SD Card and put it into a card reader on my Windows 10 computer.  I used Win32Disk Imager to make img files of both the main volume and the boot volume.

After making the backup, I loaded the SD card back into the ODroid, booted up, and continued the kernel build process.

Scroll to Networking and make sure AX 25 Ham Radio components are selected.

Complete the rest of the process.


Summary

$ git clone --depth 1 --single-branch -b odroidc2-3.14.y https://github.com/hardkernel/linux
$ cd linux
$ make odroidc2_defconfig
$ make menuconfig
##Enable the AX25/Ham Radio Components
$ make savedefconfig
$ make -j 4 Image dtbs modules
$ sudo cp arch/arm64/boot/Image arch/arm64/boot/dts/meson64_odroidc2.dtb /media/boot
$ sudo make modules_install
$ sudo make firmware_install
$ sudo make headers_install INSTALL_HDR_PATH=/usr
$ kver=`make kernelrelease`
$ sudo cp .config /boot/config-${kver}
$ cd /boot
$ sudo update-initramfs -c -k ${kver}
$ sudo mkimage -A arm64 -O linux -T ramdisk -a 0x0 -e 0x0 -n initrd.img-${kver} -d initrd.img-${kver} uInitrd-${kver}
$ sudo cp uInitrd-${kver} /media/boot/uInitrd


After running this the first time and rebooting, I check the kernel version which appears to have been changed.

However no luck with AX25 module.

Turns out that in the "Menuconfig" step, those flagged with "*"  need further selections.  I need to redo entire process.   Thanks to:  http://www.tldp.org/HOWTO/AX25-HOWTO/x144.html

This time I made sure to go into each AX25 category and select the appropriate modules.  They should be indicated with "M"

This time things went smoother.    These commands worked without any errors:

sudo modprobe ax25
sudo modprobe mkiss


That's it for now.    In another post,  I'll document steps taken to test the connection and will try to send an email.

Saturday, April 22, 2017

Key Elements

Here is a shell script to receive APRS packet audio through the microphone input:
 arecord -f S16_LE -c 1 -r 48000 -D hw:CARD=Device,DEV=0 - |sox -t raw -esigned-integer  -b16 -r 48000 - -esigned-integer -b16 -r 22050 -t raw - | multimon-ng -q -v 10 -t raw -A - | python aprs_parser.py  


Here is a shell script to receive APRS packets from a RTL-2832 TV Tuner:
 rtl_fm -f 144.390M -s 22050 - | multimon-ng -q -v 10 -t raw -A - | python aprs_parser.py  

aprs_parser.py is a script I wrote to decode the APRS packets and insert into the PostgreSQL/PostGIS database.  I'll post it when I clean the code up. It uses SQLAlchemy, Geoalchemy2, and aprslib Python modules.

The PostgresSQL/PostGIS database needs to have a geometry column with spatial reference id of 4326 (aka WGS_1984).

Thursday, February 9, 2017

Interoperability Conference 2017

Open GIS Server with Raspberry Pi and Radio

Presentation Slides

This was a side project I worked on at night to see if I could run a geographic information system (GIS) that could support both traditional desktop application and modern web mapping applications (server/client). The Raspberry Pi is used to listen for and capture digital data containing location information and insert it into the GIS database.

The goal of this was to get audience members thinking about GIS and how it might be useful or could be applied in the radio/communication community.  

I hope to publish a build log as well as the code I wrote to handle the database insertion.

73,
KE8CRV

Wednesday, February 8, 2017

GIS Data Sources

Finding sources of GIS data can be frustrating for several reasons:

  • Many formats and coordinate systems
  • Lack of metadata
  • Data has not been updated
  • Restrictions that prevent sharing

Here are some useful links and the types of layers that can be found.

State of Michigan
http://gis.michigan.opendata.arcgis.com/
  • All Roads
  • Boundaries
  • Rivers and Lakes
  • Imagery
  • Elevation Data
  • Hospitals
  • FEMA Regions
  • Communication Towers
  • Topo Maps
https://earthexplorer.usgs.gov/

  • Imagery
  • Historical Imagery
  • Elevation
http://www.census.gov/data/data-tools.html

  • Population

City or County
Check with the County or City websites for GIS data. 
  • Parcel data
  • Basemap
Global Administrative Areas
http://gadm.org/
  • Basemap:   Lots of data.  May be better off using Natural Earth Data sets instead
Natural Earth Data
  • Basemaps
US National Grid (USNG)
http://usngcenter.org/fema-region-5/

What other types of data should be included in an offline GIS?  Let me know in the comments section.


Wednesday, January 11, 2017

Imagery from US Topo Maps

With a couple command lines, you can convert US Topo Map pdfs into layers that can be used in GIS or to form a basemap that can be used offline.

US Topo 2 Tif  - This PDF is a good resource to have in an offline GIS.

Download the areas of interest from the US GeoPDF Topo Maps.  These are good to have on hand for printing or for loading to mobile apps like Avenza PDF.

The following examples will assume the pdf is called "MN_Grand_Marais_20160511_TM_geo.pdf"

Run the GDAL command:

gdalinfo MN_Grand_Marais_20160511_TM_geo.pdf –mdd LAYERS

This will allow you to see all the layer names.

Then run the GDAL command:


gdal_translate MN_Grand_Marais_20160511_TM_geo.pdf marais_contours.tif \
--config GDAL_PDF_LAYERS "Map_Frame.Terrain.Contours" --config GDAL_PDF_BANDS 3 \
--config GDAL_PDF_DPI 400

You will now have a TIF file that can can be loaded into the open source GIS

There are additional command line options to do compression and other stuff to the outputs.  Check the pdf for more info.

Tuesday, January 3, 2017

Stack Preview



Here is a preview of the ODroid C2 stack.  Currently the brass standoffs are mounted to a piece of acryllic I got from Menards.  Still need to come up with a with a good case design.  You can imagine how easy this would fit into a Pelican case to provide a temporary mobile GIS server,















Ideas for cases?  Let me know in the comments.

Sunday, January 1, 2017

GeoNode and /tmp

I noticed that when you use the web browser to load layers into GeoNode, the data gets stored and uncompressed in /tmp.   This is a problem, since the ODroid C2 has 16GB eMMC.   Fortunately, the C2 can run both eMMC and SD Card storage simultaneous.

I added a 32 GB SD Card to the ODroid C2 that was hosting GeoNode.  Here are the steps to do this:

su root

Use fdisk to list the devices:

fdisk -l

Create new partition with the device id that belongs to the SD Card:

fdisk /dev/mmcblk1

Create new primary partition, use default settings

Format the new partition:

mkfs.ext4 /dev/mmcblk1p1

Automount the new partition by editing  /etc/fstab

Add line:

/dev/mmcblk1p1 /tmp ext4 defaults 0 0

Allow read/write access

chmod 777 /tmp

Reboot and you should see GeoNode start using the new /tmp directory.  You can check by running this command:


df -h

This will also need to be done to accommodate the geonode data directories.  This will be done in a further blog post.

Saturday, December 24, 2016

APRS and Laptop Power Cord Interference

One of the great things about the Kenwood TH-D74A is how easy APRS is to use. However I was puzzled for a few days because I could not make it work with my rtl-sdr receiver within my apartment.  It turns out my Lenovo W520 Laptop power cord was causing just enough interference to make the TH-D74 think it was receiving a message all the time preventing the HT from transmitting.

At the time, I was developing a python script to extract location data from APRS packets.  I had my cheap RTL2832 tv tuner plugged into an Odroid C2 on a different monitor and was watching the waterfall with GQRX.  After turning off all other electronics in the house, the spike near 144.390 MHz went away.   Trial and error revealed the problem to be with the laptop power supply.

Hooray!

Thursday, December 22, 2016

DStar Repeaters and QGIS

I recently purchased a Kenwood TH-D74A and downloaded the Repeater List by region from dstarinfo.com.   The data comes as a tab separated file (TSV) and has columns for Lat DD, Lat MM.mm, and N/S as well as Lon DD, Lon MM.mm, and E/W.

To import into QGIS, the file needs latitude/longitude in Decimal Degrees so we need to convert formats.

According to Directions Magazine:

Degrees Minutes Seconds to Degrees Minutes.m
Degrees = Degrees
Minutes.m = Minutes + (Seconds / 60)

Degrees Minutes.m to Decimal Degrees
.d = M.m / 60
Decimal Degrees = Degrees + .d

It's also worth noting that N and E are both positive numbers while S and W are both negative numbers.

Open Excel

On my repeater list, the columns were as follows:

  • U2 is Lat DD
  • S2 is Lat MM.mm
  • T2 is N/S
  • Y2 is Lon DDD
  • Y2 is Lon MM.mm
  • X2 is E/W


Add a new column for Lat

Use this formula: =IF(U2="N",(S2+(T2/60))*1,(S2+(T2/60))*-1)

Add a new column for Lng

Use this formula:  =IF(Y2="E",(W2+(X2/60))*1,(W2+(X2/60))*-1)

Copy and Paste into remaining cells.

Save as CSV

In QGIS, click the import delimited file button


Use the new columns created by the Excel formulas


Click Ok and you should see your repeater list as points on the map.



On further inspection, it appears the coordinates may have a lack of precision that puts the points not quite where they should be.   More research is needed.

Monday, December 12, 2016

Tips for installing GeoNode on Ubuntu 16.04.1


I followed the GeoNode install instructions for Ubuntu 14.04

I installed Postgresql 9.5/postgis and Geoserver as specified and then later changed them to other servers. I install Tomcat 8.


Tip One:
sudo pip uninstall celery
sudo pip install celery=3.1.18
sudo pip freeze > requirements
sudo pip install -e .


Tip Two
Edit /var/www/geonode/geonode.wsgi

#Comment out these lines and replace with:
#from django.core.handlers.wsgi import WSGIHandler
#application = WSGIHandler()

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

Saturday, December 10, 2016

Separating GeoNode Capabilities

I was able to use separate hosts for GeoNode, Geoserver, and Postgresql/Postgis instead of having them all on a single machine.

On the remote Postgresql server:

  • Create the geonode user and both the geonode and geonode_data databases.  I used the instructions available here
  • Edit /etc/postgres/9.5/main/pg_hba.conf  to allow geonode user and database access
  • Edit /etc/postgres/9.5/main/postgresql.conf to allow listeners outside of localhost


On the GeoNode host:

  • Test access to remote server with:  psql -h <remote host ip> -U geonode
  • Edit /etc/geonode/local_settings.conf  and change the database host and password
  • Add the remote database server to the ALLOWED_HOSTS
  • Edit /etc/geonode/local_settings.conf and change the GEOSERVER_URL
  • Make sure the remote geoserver has an admin user/password that matches local_settings.conf
  • Edit /etc/apache2/sites-available/geonode.conf and change the ProxyPass and ReverseProxyPass directives.


For future builds:

Before running the install.sh script, edit the geonode/package/support/geonode.local_settings and change the remote database settings and remote geoserver settings



Friday, December 9, 2016

Creating C2 Images

After configuring each ODroid C2 computer with /etc/hostname, /etc/hosts, npre plugin for nagios server monitoring and other settings, I decided to clone the image without an additional software so I could easily create new builds for the host later on.  Here are the steps I took:

Put the eMMC into the ODroid SD card adapter and plug into a card reader

Launch Win32 Disk Imager

Choose location to store images and create a filename such as hostname_yyyymmdd.img

Choose Device drive letter and click Read

The final size was 14.5 GB for a single image so make sure you have enough space to store multiple images.


Tuesday, December 6, 2016

Virtual Machines have been built

So far, I've successfully created 3 virtual machines using Oracle VirtualBox and Ubuntu 16.04 Server


  • Geoserver 2.10
  • Postgresql with Postgis 9.5
  • GeoNode 2.5.5


As separate virtual machines, the Geoserver and Postgresql builds have been pretty straight forward. The Geonode has been quite painful but it is finally up and running.   However, the Geonode server involves installing Geoserver, Postgresql, and Geonode on the same machine.    I need to further configure the Geonode server to point Geoserver and databases to separate machines.  

I used virtual machines so I could take snapshots and restore to clean installs when I made mistakes.  The builds will be eventually repeated on the small single board computer, ODroid C2

To do in the near future:

  • Configure the Geonode server to separate duties
  • Install Nagios NPRE client so I can record various performance data onto the Nagios 3 software I have running on my Raspberry Pi 2.
  • Plan installs of Geonode, Postgresql, and Geoserver onto the ODroid C2 stack (More info later!)



Saturday, December 3, 2016

Portable Open Source GIS with Raspberry PI and Radio

I wanted a low cost, open source geographic information system (GIS) that would would support ham radio operations and could be added to a mobile ham shack.   I also wanted the GIS to work without internet access and be able to be updated using digital modes available to ham radio operators.

ESRI ArcGIS for Server, ESRI Portal for ArcGIS, ESRI ArcGIS Desktop,  and Microsoft SQL Server are widely used in the GIS community.  While these are great products, they did not meet my requirements.

Software:
  • Geoserver is the open source equivalent of ArcGIS Server, software that can provide geospatial information to applications
  • PostgreSQL is the database for storing both geospatial and non-geospatial information.
  • PostGIS is an extension for Postgresql that adds geospatial capability
  • GeoNode is an open source equivalent of Portal for ArcGIS, software that allows users to create and share web maps and documents
  • QGIS is desktop application for producing high quality maps and performing geospatial analyses
  • GNU Radio is the toolkit for developing software defined radios
  • RTL-SDR software used to demodulate radio signals
  • Python - script language for processing text and performing database operations
Hardware:
  • Raspberry Pi 2 (900 Mhz, 512 MB Ram, 10/100 Ethernet)
  • Raspberry Pi 3 (1.2 GHz, 1 GB Ram, 10/100 Ethernet)
  • ODroid C2 (1.5 GHz, 2GB Ram, 10/100/1000 Ethernet, 4K display support)
  • RTL-SDR RTL2832U  - a cheap radio receiver
  • HackRF One - a software defined radio receiver/transmitter
GIS Data:

In future posts, I'll be detailing the build and configuration process, expanding on GIS data sources, and discussing potential applications.

Wednesday, October 19, 2016

Morse Code, Linux, and Powershell


Here are some CW tips:

Use this to receive audio through mic jack and decode the cw signal:

arecord -f S16_LE -c1 -r48000 -D hw:CARD=Device,DEV=0 - | sox -t raw -esigned-integer -b16 -r 48000 - -esigned-integer -b16 -r 22050 -t raw - |multimon-ng -a MORSE_CW -t raw -


Use a command like this to receive and decode CW from an RTL2832U SDR:

rtl_fm -f <freq> -s 22050 -M wbfm | multimon-ng -a DTMF -t raw - 


Use Powershell to make system speaker beep CW:

$frequency = 400
#frequency needs to be between 37 and 32767

$time = 200

$dot_duration = 100
$dash_duration = 300

$dot = '[console]::beep($frequency, $dot_duration)'
$dash = '[console]::beep($frequency, $dash_duration)'

$spacing = 0.1
$char_spacing = .3
$word_spacing = 0.7

$morse_rev_lookup = @{
    ".-"="A";
    "-..."="B";
    "-.-."=    "C";
    "-.."=    "D";
    "."=    "E";
    "..-."=    "F";
    "--."=    "G";
    "...."=    "H";
    ".."=    "I";
    ".---"=    "J";
    "-.-"=    "K";
    ".-.."=    "L";
    "--"=    "M";
    "-."=    "N";
    "---"=    "O";
    ".--."=    "P";
    "--.-"=    "Q";
    ".-."=    "R";
    "..."=    "S";
    "-"=    "T";
    "..-"=    "U";
    "...-"=    "V";
    ".--"=    "W";
    "-..-"=    "X";
    "-.--"=    "Y";
    "--.."=    "Z";
    ".----"=    "1";
    "..---"=    "2";
    "...--"=    "3";
    "....-"=    "4";
    "....."=    "5";
    "-...."=    "6";
    "--..."=    "7";
    "---.."=    "8";
    "----."=    "9";
    "-----"=    "0";
    ".-.-.-"=  ".";
    "--..--"= ";";
    "..--.."= "?";
    "-...-"= "==";
    "-..-."= "/";
    "---..."= "=";
    "-....-"= "-";
    "..--.-"= "_"
    }

$morse_lookup = @{}

foreach($k in $morse_rev_lookup.Keys){
    $morse_lookup.add($morse_rev_lookup[$k], $k)
}

$someinput  = [Environment]::UserName

$chararr = $someinput.ToCharArray()
foreach($k in $chararr){
    
    if( $morse_lookup[$k -join ""] ){

        Write-Host $k, ":", $morse_lookup[$k -join ""]
        $letter = $morse_lookup[$k -join ""].ToCharArray()
        foreach($l in $letter){
            if($l -eq "."){
                Invoke-Expression $dot
            }else{
                Invoke-Expression $dash
            }
            sleep($spacing)
        }
        sleep($char_spacing)
    }else{
        sleep($word_spacing)
    }
}