Monday, May 13, 2024

How to transfer AIS signal to aprs.fi with the Raspberry PI 4B

 


    Install RTL-SDR

    install dongle anda V3 atau V4

sudo apt update
sudo apt upgrade
  sudo apt-get install cmake
  sudo apt install build-essential
  sudo apt install libudev-dev
  wget https://github.com/libusb/libusb/releases/download/v1.0.24/libusb-1.0.24.tar.bz2
  tar xjf libusb-1.0.24.tar.bz2
  cd libusb-1.0.24
    ./configure
    make
    sudo make install
    sudo ldconfig

    Jika V3
git clone https://github.com/osmocom/rtl-sdr.git
cd rtl-sdr
mkdir build
cd build
cmake -DINSTALL_UDEV_RULES=ON -DDETACH_KERNEL_DRIVER=ON ../
sudo make install
sudo ldconfig
kemudian....
sudo nano /etc/modprobe.d/rtlsdr-blacklist.conf
tambah list ini,
blacklist dvb_usb_rtl28xxu
blacklist rtl2832
blacklist rtl2830
blacklist dvb_usb_rtl2832u
blacklist dvb_usb_v2
blacklist dvb_core
kemudian periksa samada dongle anda sukses atau tidak install
$ rtl_test

Found 1 device(s):
  0:  Realtek, RTL2838UHIDIR, SN: 00000002

Using device 0: Generic RTL2832U OEM
Found Rafael Micro R820T tuner
Supported gain values (29): 0.0 0.9 1.4 2.7 3.7 7.7 8.7 12.5 14.4 15.7 16.6 19.7 20.7 22.9 25.4 28.0 29.7 32.8 33.8 36.4 37.2 38.6 40.2 42.1 43.4 43.9 44.5 48.0 49.6
[R82XX] PLL not locked!
Sampling at 2048000 S/s.

Info: This tool will continuously read from the device, and report if
samples get lost. If you observe no further output, everything is fine.

Reading samples in async mode...

jika anda guna V4,

  1. Purge the previous driver:
    sudo apt purge ^librtlsdr
    sudo rm -rvf /usr/lib/librtlsdr* /usr/include/rtl-sdr* /usr/local/lib/librtlsdr* /usr/local/include/rtl-sdr* /usr/local/include/rtl_* /usr/local/bin/rtl_*
  2. Install the RTL-SDR Blog drivers:
    sudo apt-get install libusb-1.0-0-dev git cmake pkg-config
    git clone https://github.com/rtlsdrblog/rtl-sdr-blog
    cd rtl-sdr-blog
    mkdir build
    cd build
    cmake ../ -DINSTALL_UDEV_RULES=ON
    make
    sudo make install
    sudo cp ../rtl-sdr.rules /etc/udev/rules.d/
    sudo ldconfig
  3. Blacklist the DVB-T TV drivers.
    echo 'blacklist dvb_usb_rtl28xxu' | sudo tee --append /etc/modprobe.d/blacklist-dvb_usb_rtl28xxu.conf
  4. Reboot

---------------------------------------------------------------------------------------------------------

Jika keluar error seperti di bawah, Jika jalan elok, skip saja step ni.

pi@raspberrypi:~/rtl-sdr $ rtl_test

Found 1 device(s):

  0:  6▒▒▒;▒▒▒▒▒, , SN: ▒I▒▒▒

Using device 0: Generic RTL2832U OEM

usb_open error -3

Please fix the device permissions, e.g. by installing the udev rules file rtl-sdr.rules

Failed to open rtlsdr device #0.

Maka follow step di bawah:

download dan install udev Rules untuk RTL-SDR

sudo wget -O /etc/udev/rules.d/20-rtlsdr.rules https://raw.githubusercontent.com/osmocom/rtl-sdr/master/rtl-sdr.rules

Reload udev Rules

sudo udevadm control --reload-rules
sudo udevadm trigger

Tambah User anda ke plugdev Group

sudo usermod -aG plugdev $USER

cabut dongle anda dan test semula.

--------------------------------------------------------------------------------------------------------------------

Install Ais Dispatcher

wget https://www.aishub.net/downloads/dispatcher/install_dispatcher

chmod 755 install_dispatcher

sudo ./install_dispatcher

REBOOT

Buka browser anda dan masukkan URL berikut:

http://IPADDRESS:8080 (tukar IP anda sendiri)

Default web login adalah:

Username: admin

Password: admin

---------------------------------------------------------------------------------------------------

Untuk mengkonfigurasi AIS Dispatcher anda pilih "Configuration" dari panel kiri.


INPUT :

Mode = UDP Server

Host = 127.0.0.1

Port = 10110


OUTPUT :

Host 1     = 127.0.0.1

UDP PORT 1 = 5999

COMMENT 1  = AISHub bla bla


SETTINGS :

Station Latitude           : xxxxxxxx

Station Longitude         : xxxxxxx

Inactivity Timeout         : 300

Reconnect Timeout        : 60

Downsampling Time      : 10

Log Verbosity                : Errors Only

Duplicates Removal      : Yes

NMEA Tags                 : Yes

Non-VDM                   : Yes

Enable                         : Yes


kemudian Save

---------------------------------------------------------------------------------------------------

Install RTL-AIS

sudo apt install librtlsdr-dev libpthread-stubs0-dev

jika RPI anda 32 bit, maka

wget https://launchpad.net/~sailoog/+archive/ubuntu/openplotter/+files/rtl-ais_0.4.2-stable_armhf.deb

sudo dpkg -i rtl-ais_0.4.2-stable_armhf.deb

Manakala jika RPI anda 64 bit, maka

wget https://launchpad.net/~sailoog/+archive/ubuntu/openplotter/+files/rtl-ais_0.4.2-stable_arm64.deb

sudo dpkg -i rtl-ais_0.4.2-stable_arm64.deb


TESTING

Cucuk dongle ke raspi dan test,

sudo rtl_ais -R on -n

dan jika sukses, akan muncul paparan seperti di bawah.


Edge tuning disabled.

DC filter enabled.

RTL AGC enabled.

Internal AIS decoder enabled.

Buffer size: 163.84 mS

Downsample factor: 64

Low pass: 25000 Hz

Output: 48000 Hz

Found 1 device(s):

  0:  NooElec, NESDR Nano 3, SN: XXXXXX


Using device 0: Generic RTL2832U OEM

Detached kernel driver

Found Rafael Micro R820T tuner

Log NMEA sentences to console ON

AIS data will be sent to 127.0.0.1 port 10110

Tuner gain set to automatic.

RTL AGC mode ON

Tuned to 162000000 Hz.

Sampling at 1600000 S/s.

Allocating 12 zero-copy buffers

!AIVDM,1,1,,B,137KW60018PqU<bP6M2<?9iV08N=,0*7E

!AIVDM,1,1,,A,15V3Qh000I0qPQ8P7al=9bAf08Qf,0*6B

!AIVDM,1,1,,A,137KW60018PqU5DP6MQ<?ah00D1;,0*0B

!AIVDM,1,1,,B,137KW60018PqTtFP6N6t?IhF086b,0*1A

ok sukses.

----------------------------------------------------------------------------------------------

Untuk nak feed ke aprs.fi kita memerlukan password yang diberikan oleh aprs.fi.

masuk aprs.fi dan terus cari perkataan AIS sites dan klik.

kemudian klik my account, dan copy AIS password dan paste lah dimana2 atau tulis.

AIS JSON - json file ini diperlukan feed data dari ais-dispatcher ke aprs.fi.

Install ais_jason ( akan nampak beberapa error, tapi boleh abaikan)

git clone https://github.com/hsiboy/ais_json.git

pip install libais

pip install termcolor

cd ais_json/


ais_json ini diperlukan run sentiasa, maka

 ./ais_json.py &

---------------------------------------------------------------------------------------------------------

pada awal tadi, kita kan set pada OUTPUT Dispatcher seperti di bawah,

OUTPUT :

Host 1     = 127.0.0.1

UDP PORT 1 = 5999

jadi untuk membolehkan ais json ini menerima data dari dispatcher, maka kita perlu

ubahnya juga, untuk ubah, masuk ke dalam ais_json.py dan cari line ini:

IP = '127.0.0.1'

PORT = 5000 

dan ubah ke

IP = '127.0.0.1'

PORT = 5999 

pada awal tadi, kita kan save password ais untuk aprs.fi kan, so masa ni lah

nak guna password tu, untuk ubah, pergi file settings.py

URL='http://aprs.fi/jsonais/post/PASSWORD'

NAME='CALLSIGN'

akan nampak seperti di atas, dan ubah mengikut password dan callsign anda.

URL='http://aprs.fi/jsonais/post/xxxxxxxx'

NAME='9m2zak'

ok siap!!! sila reboot. selepas reboot, buka 2 terminal.

terminal pertama :

cd ais_json/

./ais_json.py &

terminal kedua

sudo rtl_ais -R on -n

kemudian buka browser :

http://IPADDRESS:8080 (tukar IP anda sendiri)

dan buka aprs.fi dan jika berjaya, kapal akan muncul selepas beberapa minit seperti dibawah.


---------------------------------------------------------------------------------

auto start rtl-ais

Buat bash script untuk rtl-ais dahulu. buka mana-mana word editor 

dan namakan rtl_ais.sh

----------------------------------------------------------

#!/bin/bash

# Change to the desired directory

cd ~

# Run your command

sudo rtl_ais -R on -n

----------------------------------------------------------

chmod +x rtl_ais.sh

----------------------------------------------------------

kemudian pada terminal baru, 

sudo apt update

sudo apt install lxterminal

mkdir -p ~/.config/autostart

nano ~/.config/autostart/rtl_ais.desktop

copy dan paste semua line dibawah, kemudian save


[Desktop Entry]

Type=Application

Exec=sh -c 'sleep 15 && /home/pi/rtl_ais.sh'

Hidden=false

NoDisplay=false

X-GNOME-Autostart-enabled=true

Name[en_US]=RTL AIS

Name=RTL AIS

Comment[en_US]=Run RTL AIS script on startup

Comment=Run RTL AIS script on startup

----------------------------------------------------------

auto start ais_json.py

sekarang kita setup untuk ais_json pula.

nano ~/.config/autostart/ais_json.desktop


copy dan paste, semua yang dibawah dan save. 

[Desktop Entry]

Type=Application

Exec=lxterminal --command="bash -c 'cd ~/ais_json/ && ./ais_json.py'"

Hidden=false

NoDisplay=false

X-GNOME-Autostart-enabled=true

Name[en_US]=AIS JSON

Name=AIS JSON

Comment[en_US]=Run AIS JSON script on startup

Comment=Run AIS JSON script on startup

--------------------------------------------------------

chmod +x ~/ais_json/ais_json.py

-----------------------------------------------------------

Pengguna python3

bagi mereka yang guna python3, sila guna script dibawah

untuk ais_json.py anda.

------------------------------------------------------------------------------------------------------

#!/usr/bin/python


import warnings

warnings.simplefilter(action='ignore', category=FutureWarning)

from termcolor import colored

from settings import URL, NAME

import json

import ais.stream

import socket

import datetime

import requests


IP = '127.0.0.1'

PORT = 5999


sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind((IP, PORT))


while True:


  for msg in ais.stream.decode(sock.makefile('r'),keep_nmea=True):

    rxtime =  datetime.datetime.utcnow().strftime("%Y%m%d%H%M%S") #YYYYMMDDHHMMSS

    parsed = json.loads(json.dumps(msg))

    

    ais = {

            'msgtype': parsed['id'],

            'mmsi': parsed['mmsi'],

            'rxtime': rxtime

            }


    if 'x' in parsed:

      ais['lon'] = parsed['x']

    if 'y' in parsed:

      ais['lat'] = parsed['y']

    if 'sog' in parsed:

      ais['speed'] = parsed['sog']

    if 'cog' in parsed:

      ais['course'] = parsed['cog']

    if 'true_heading' in parsed:

      ais['heading'] = parsed['true_heading']

    if 'nav_status' in parsed:

      ais['status'] = parsed['nav_status']

    if 'type_and_cargo' in parsed:

      ais['shiptype'] = parsed['type_and_cargo']

    if 'part_num' in parsed:

      ais['partno'] = parsed['part_num']

    if 'callsign' in parsed:

      ais['callsign'] = parsed['callsign']

    if 'name' in parsed:

      ais['shipname'] = parsed['name']

    if 'vendor_id' in parsed:

      ais['vendorid'] = parsed['vendor_id']

    if 'dim_a' in parsed:

      ais['ref_front'] = parsed['dim_a']

    if 'dim_c' in parsed:

      ais['ref_left'] = parsed['dim_c']

    if 'draught' in parsed:

      ais['draught'] = parsed['draught']

    if 'length' in parsed:

      ais['length'] = parsed['length']

    if 'width' in parsed:

      ais['width'] = parsed['width']

    if 'destination' in parsed:

      ais['destination'] = parsed['destination']

    if 'persons' in parsed:

      ais['persons_on_board'] = parsed['persons']


    path = { 

            "name": NAME, 

            "url": URL }


    groups = { 

            "path": [path], 

            "msgs":[ais] }

    

    output = {

            "encodetime": rxtime,

            "protocol": 'jsonais',

            "groups":  [groups]

            }

    

    post = json.dumps(output)

    try:

      r = requests.post(URL, files={'jsonais': (None, post)})

      #dump non common packets for debugging

      if parsed['id'] not in (1,2,3,4):

        print (colored('-- Uncommon packet recieved\n', 'red'))

        print (colored('id:', 'green'), parsed['id'])

        print (colored('NMEA:', 'green'), parsed['nmea'])

        print (colored('Parsed:', 'green'), parsed)

        print (colored('Post:', 'green'), post)

        print (colored('Result:', 'green'), json.loads(r.text)['description'])

    except requests.exceptions.RequestException as e:

      print (e)

-------------------------------------------------------------------------------------------------------

Pengguna python3

bagi mereka yang guna python3, sila guna script dibawah

untuk ais_json.py, ni option jika yg atas tak dekod.


import warnings

warnings.simplefilter(action='ignore', category=FutureWarning)

from termcolor import colored

from settings import URL, NAME

import json

import ais.stream

import socket

import datetime

import requests


IP = '127.0.0.1'

PORT = 5999


sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

sock.bind((IP, PORT))


while True:

    # Decode the incoming AIS message stream

    for msg in ais.stream.decode(sock.makefile('r'), keep_nmea=True):

        rxtime = datetime.datetime.utcnow().strftime("%Y%m%d%H%M%S")  # Format the timestamp

        parsed = json.loads(json.dumps(msg))


        ais = {

            'msgtype': parsed['id'],

            'mmsi': parsed['mmsi'],

            'rxtime': rxtime

        }


        # Add other parsed data to the ais dictionary as needed

        if 'x' in parsed:

            ais['lon'] = parsed['x']

        if 'y' in parsed:

            ais['lat'] = parsed['y']

        if 'sog' in parsed:

            ais['speed'] = parsed['sog']

        if 'cog' in parsed:

            ais['course'] = parsed['cog']

        if 'true_heading' in parsed:

            ais['heading'] = parsed['true_heading']

        if 'nav_status' in parsed:

            ais['status'] = parsed['nav_status']

        if 'type_and_cargo' in parsed:

            ais['shiptype'] = parsed['type_and_cargo']

        if 'part_num' in parsed:

            ais['partno'] = parsed['part_num']

        if 'callsign' in parsed:

            ais['callsign'] = parsed['callsign']

        if 'name' in parsed:

            ais['shipname'] = parsed['name']

        if 'vendor_id' in parsed:

            ais['vendorid'] = parsed['vendor_id']

        if 'dim_a' in parsed:

            ais['ref_front'] = parsed['dim_a']

        if 'dim_c' in parsed:

            ais['ref_left'] = parsed['dim_c']

        if 'draught' in parsed:

            ais['draught'] = parsed['draught']

        if 'length' in parsed:

            ais['length'] = parsed['length']

        if 'width' in parsed:

            ais['width'] = parsed['width']

        if 'destination' in parsed:

            ais['destination'] = parsed['destination']

        if 'persons' in parsed:

            ais['persons_on_board'] = parsed['persons']


        # Constructing the path and group for the JSON payload

        path = { 

            "name": NAME, 

            "url": URL 

        }


        groups = { 

            "path": [path], 

            "msgs": [ais] 

        }


        # The main JSON payload to be posted

        output = {

            "encodetime": rxtime,

            "protocol": 'jsonais',

            "groups": [groups]

        }


        # Convert the dictionary to a JSON string

        post_json = json.dumps(output)


        # Send the JSON data using requests

        try:

            r = requests.post(URL, data={'jsonais': post_json})


            # Log the status and response

            print(colored(f"Status Code: {r.status_code}", 'yellow'))

            print(colored(f"Response Text: {r.text}", 'yellow'))


            if r.status_code == 200:

                print(colored('Result:', 'green'), r.text)

            else:

                print(colored("Unexpected response received from APRS.fi", 'red'))

        except requests.exceptions.RequestException as e:

            print(colored("Request Error:", 'red'), str(e))

--------------------------------------------------------------------------------------------------------


LOAD dan reboot kemudian boleh tengok hasilnya di aprs.fi

semoga bermanfaat. 73


Connect a GPS module to a Raspberry Pi 4

  To connect a GPS module with four wires (RST, TX, VCC, and GND) to a Raspberry Pi 4, follow these steps:  Materials Needed: 1. GPS module ...