From e2b8a4b085404c293024b3721038bf6ff366f7d4 Mon Sep 17 00:00:00 2001 From: marcel Date: Mon, 31 Jan 2022 15:33:34 +0100 Subject: [PATCH] Last version with RPi-LoRa-KISS-TNC included --- CHANGELOG.md | 21 +++++++++++++ README.md | 16 +++++----- RPi-LoRa-KISS-TNC/CHANGELOG.md | 24 +++++++++++++++ RPi-LoRa-KISS-TNC/LoraAprsKissTnc.py | 41 +++++++++++++++++++++++-- RPi-LoRa-KISS-TNC/README.md | 12 +++++--- RPi-LoRa-KISS-TNC/RPi-LoRa-KISS-TNC.ini | 33 ++++++++++++++++++++ RPi-LoRa-KISS-TNC/Start_lora-tnc.py | 24 +++++++++++++-- aprs_utils/APZMDM::PE1RXF-2 | 0 start_aprs_server.sh | 2 +- 9 files changed, 156 insertions(+), 17 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 RPi-LoRa-KISS-TNC/CHANGELOG.md create mode 100644 RPi-LoRa-KISS-TNC/RPi-LoRa-KISS-TNC.ini delete mode 100644 aprs_utils/APZMDM::PE1RXF-2 diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..dfb5fd7 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,21 @@ +# Changelog + +All notable changes to this project will be documented in this file. + + Added : for new features. + Changed : for changes in existing functionality. + Deprecated: for soon-to-be removed features. + Removed : for now removed features. + Fixed : for any bug fixes. + Security : in case of vulnerabilities. + +## [0.0.1] - 2022-01-31 + +### Added +- Lora support fo an SX1278 connected to the RPi GPIO + +### Deprecated +- RPi-LoRa-KISS-TNC shall be moved to a seperate repository + +### Fixed +- LoRa APRS header (<\xff\x01) was not added to the payload, due to an indentation fault. Long live Python! diff --git a/README.md b/README.md index 6146380..d1dea71 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ It runs on a Raspberry Pi Zero with Raspberry Pi OS Bullseye. It can: - * Function as a normal digipeater (mono, dual or cross band) + * Function as a normal digipeater (mono, dual, threefold or cross band) * Work as an IGate (RX only or RX/TX) * Send and receive APRS messages * Display some basic statistics like heard stations. @@ -18,9 +18,10 @@ It can: In has (hardware): * Two build in 1200bps AFSK modems - * Build in transceiver + * Build in LoRa transceiver (SX1278) + * Build in FM transceiver * Connector for external (second) transceiver - * Two USB ports for a network adapter and a third modem + * Two USB ports for a network adapter and something else * Real Time Clock * Raspberry Pi Zero @@ -28,11 +29,12 @@ It has (software): * APRX digipeater software for the basic functions * Apache2 web server for the user interface + * LoRa KISS TNC support (repository found at https://git.meezenest.nl/marcel/RPi-LoRa-KISS-TNC) * Custom software (from this repository) for extra functionality ## Changelog -- Added LoRa support for SX1278 module on RPi SPI (available on port ax2) +Can be found [here](CHANGELOG.md) ## Further reading @@ -40,6 +42,6 @@ Want to know more? The complete guide (and more) is available on https://www.mee ## Screen shots web interface -![Main page](./screenshots/screenshot_main_page.png "Main page") -![Send message](./screenshots/screenshot_send_message.png "Send message") -![Telemetry](./screenshots/screenshot_telemetry.png "Telemetry") +[Main page](screenshots/screenshot_main_page.png) +[Send message](screenshots/screenshot_send_message.png) +[Telemetry](screenshots/screenshot_telemetry.png) diff --git a/RPi-LoRa-KISS-TNC/CHANGELOG.md b/RPi-LoRa-KISS-TNC/CHANGELOG.md new file mode 100644 index 0000000..a99a375 --- /dev/null +++ b/RPi-LoRa-KISS-TNC/CHANGELOG.md @@ -0,0 +1,24 @@ +# Changelog + +All notable changes to this project will be documented in this file. + + Added : for new features. + Changed : for changes in existing functionality. + Deprecated: for soon-to-be removed features. + Removed : for now removed features. + Fixed : for any bug fixes. + Security : in case of vulnerabilities. + +## [0.0.1] - 2022-01-31 + +### Added +- Lora and TCP settings are now configurable via configuration file RPi-LoRa-KISS-TNC.ini + +### Changed +- Better encoding of AX.25 frames: less/no crashes due to corrupted incomming frames + +### Deprecated +- Configuration via config.py + +### Fixed +- LoRa APRS header (<\xff\x01) was not added to the payload, due to an indentation fault. Long live Python! diff --git a/RPi-LoRa-KISS-TNC/LoraAprsKissTnc.py b/RPi-LoRa-KISS-TNC/LoraAprsKissTnc.py index 4cde9de..b3770dd 100644 --- a/RPi-LoRa-KISS-TNC/LoraAprsKissTnc.py +++ b/RPi-LoRa-KISS-TNC/LoraAprsKissTnc.py @@ -51,9 +51,45 @@ class LoraAprsKissTnc(LoRa): self.set_freq(frequency) self.set_preamble(preamble) self.set_spreading_factor(spreadingFactor) + + if bandwidth == 'BW7_8': + bandwidth = BW.BW7_8 + elif bandwidth == 'BW10_4': + bandwidth = BW.BW10_4 + elif bandwidth == 'BW15_6': + bandwidth = BW.BW15_6 + elif bandwidth == 'BW20_8': + bandwidth = BW.BW20_8 + elif bandwidth == 'BW31_25': + bandwidth = BW.BW31_25 + elif bandwidth == 'BW41_7': + bandwidth = BW.BW41_7 + elif bandwidth == 'BW62_5': + bandwidth = BW.BW62_5 + elif bandwidth == 'BW125': + bandwidth = BW.BW125 + elif bandwidth == 'BW250': + bandwidth = BW.BW250 + elif bandwidth == 'BW500': + bandwidth = BW.BW500 + else: + bandwidth = BW.BW125 + self.set_bw(bandwidth) self.set_low_data_rate_optim(True) - self.set_coding_rate(codingrate) + + if codingrate == 'CR4_5': + codingrate = CODING_RATE.CR4_5 + elif codingrate == 'CR4_6': + codingrate = CODING_RATE.CR4_6 + elif codingrate == 'CR4_7': + codingrate = CODING_RATE.CR4_7 + elif codingrate == 'CR4_8': + codingrate = CODING_RATE.CR4_8 + else: + codingrate = CODING_RATE.CR4_5 + + self.set_coding_rate(codingrate) self.set_ocp_trim(100) self.set_pa_config(paSelect, MaxoutputPower, outputPower) @@ -77,7 +113,8 @@ class LoraAprsKissTnc(LoRa): if self.aprs_data_type(data) == self.DATA_TYPE_THIRD_PARTY: # remove third party thing data = data[data.find(self.DATA_TYPE_THIRD_PARTY) + 1:] - data = self.LORA_APRS_HEADER + data + # Add LoRa-APRS header (original, this was indented one position further, only executed when above if-statement was true. Think it should be executed at all times. + data = self.LORA_APRS_HEADER + data print("LoRa TX: " + repr(data)) self.transmit(data) except QueueEmpty: diff --git a/RPi-LoRa-KISS-TNC/README.md b/RPi-LoRa-KISS-TNC/README.md index 938f9f9..87276af 100644 --- a/RPi-LoRa-KISS-TNC/README.md +++ b/RPi-LoRa-KISS-TNC/README.md @@ -2,13 +2,15 @@ This project was originally started by Tom Kottek (https://github.com/tomelec/RPi-LoRa-KISS-TNC). Because the program had some problems dealing with digipeated frames (it crashed when receiving a ssid with the 'has_been_digipeated' flag -*- set), I took on the task of fixing the code for my personal use. -## Hardware - -I also designed my own (open source) hardware for it: a board holding a Raspberry Pi Zero 2 W, an SX1278 LoRa transceiver and a power supply with on/off button to safely switch on and off the system. The design files can be found on my website: [RPi LoRa_shield](https://meezenest.nl/mees/RPi_LoRa_shield.html) - ## Software The software controls the LoRa transceiver connected to the Raspberry´s SPI bus and emulates a KISS TNC over TCP. That makes it possible to use existing software like APRX. It is also possible to attach the KISS interface to the AX.25 stack via socat/kissattach. +## Hardware + +I also designed my own (open source) hardware for it: a board holding a Raspberry Pi Zero 2 W, an SX1278 LoRa transceiver and a power supply with on/off button to safely switch on and off the system. The design files can be found on my website: [RPi LoRa_shield](https://meezenest.nl/mees/RPi_LoRa_shield.html) + ### To Do -* A lot +* The program (or the LoRa module) still crashes occasionally. After restarting the program (kissattach/socat/RPi-LoRa-KISS-TNC.py) it all works again. Need to investigate. +* Completely remove config.py in favour of RPi-LoRa-KISS-TNC.ini +* Add raw TCP KISS socket for true AX.25 over KISS diff --git a/RPi-LoRa-KISS-TNC/RPi-LoRa-KISS-TNC.ini b/RPi-LoRa-KISS-TNC/RPi-LoRa-KISS-TNC.ini new file mode 100644 index 0000000..d4e6c6e --- /dev/null +++ b/RPi-LoRa-KISS-TNC/RPi-LoRa-KISS-TNC.ini @@ -0,0 +1,33 @@ +[LoRaSettings] +# Settings for LoRa module +frequency=433.775 +preamble=8 +spreadingFactor=12 +# Bandwidth: +# BW7_8 +# BW10_4 +# BW15_6 +# BW20_8 +# BW31_25 +# BW41_7 +# BW62_5 +# BW125 +# BW250 +# BW500 +bandwidth=BW125 +# Coding Rate: +# CR4_5 +# CR4_6 +# CR4_7 +# CR4_8 +codingrate=CR4_5 +appendSignalReport=True +paSelect = 1 +MaxoutputPower = 15 +outputPower = 15 + +[KISS] +# Settings for KISS +TCP_HOST=0.0.0.0 +TCP_PORT_AX25=10001 +TCP_PORT_RAW =10002 diff --git a/RPi-LoRa-KISS-TNC/Start_lora-tnc.py b/RPi-LoRa-KISS-TNC/Start_lora-tnc.py index 1979e31..beebbd2 100755 --- a/RPi-LoRa-KISS-TNC/Start_lora-tnc.py +++ b/RPi-LoRa-KISS-TNC/Start_lora-tnc.py @@ -21,6 +21,25 @@ from TCPServer import KissServer from AXUDPServer import AXUDPServer import config from LoraAprsKissTnc import LoraAprsKissTnc +import configparser + +# Read configuration file # +parser = configparser.ConfigParser() +parser.read('RPi-LoRa-KISS-TNC.ini') + +config_frequency = float(parser.get('LoRaSettings', 'frequency')) +config_preamble = int(parser.get('LoRaSettings', 'preamble')) +config_spreadingFactor = int(parser.get('LoRaSettings', 'spreadingFactor')) +config_bandwidth = parser.get('LoRaSettings', 'bandwidth') +config_codingrate = parser.get('LoRaSettings', 'codingrate') +config_appendSignalReport = parser.get('LoRaSettings', 'appendSignalReport') +config_paSelect = int(parser.get('LoRaSettings', 'paSelect')) +config_MaxoutputPower = int(parser.get('LoRaSettings', 'MaxoutputPower')) +config_outputPower = int(parser.get('LoRaSettings', 'outputPower')) + +config_TCP_HOST = parser.get('KISS', 'TCP_HOST') +config_TCP_PORT_AX25 = int(parser.get('KISS', 'TCP_PORT_AX25')) +config_TCP_PORT_RAW = int(parser.get('KISS', 'TCP_PORT_RAW')) # TX KISS frames go here (Digipeater -> TNC) kissQueue = Queue() @@ -29,13 +48,14 @@ kissQueue = Queue() if config.USE_AXUDP: server = AXUDPServer(kissQueue, config.AXUDP_LOCAL_IP, config.AXUDP_LOCAL_PORT, config.AXUDP_REMOTE_IP, config.AXUDP_REMOTE_PORT) else: - server = KissServer(kissQueue, config.TCP_HOST, config.TCP_PORT) + server = KissServer(kissQueue, config_TCP_HOST, config_TCP_PORT_AX25) server.setDaemon(True) server.start() # LoRa transceiver instance -lora = LoraAprsKissTnc(kissQueue, server, verbose=False, appendSignalReport = config.APPEND_SIGNAL_REPORT) +lora = LoraAprsKissTnc(kissQueue, server, frequency=config_frequency, preamble=config_preamble, spreadingFactor=config_spreadingFactor, bandwidth=config_bandwidth, + codingrate=config_codingrate, appendSignalReport=config_appendSignalReport, paSelect = config_paSelect, MaxoutputPower = config_MaxoutputPower, outputPower = config_outputPower,verbose=True) # this call loops forever inside lora.startListening() diff --git a/aprs_utils/APZMDM::PE1RXF-2 b/aprs_utils/APZMDM::PE1RXF-2 deleted file mode 100644 index e69de29..0000000 diff --git a/start_aprs_server.sh b/start_aprs_server.sh index fe00b93..fe79fc3 100755 --- a/start_aprs_server.sh +++ b/start_aprs_server.sh @@ -64,7 +64,7 @@ ########################### # initializing LoRa modem # ########################### - /home/marcel/ham/RPi-LoRa-KISS-TNC/start_all.sh +# /home/marcel/ham/RPi-LoRa-KISS-TNC/start_all.sh # Start filter for received messages to PE1RXF (all sufixes) # Messages addressed to PE1RXF are stored in file /home/marcel/ham/aprs_utils/aprs_received_messages.log