Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin for Dynon D10/D100 data stream #167

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions fixgw/config/connections/dynon.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
dynon:
load: DYNON
module: fixgw.plugins.dynon
port: /dev/ttyUSB0
1 change: 1 addition & 0 deletions fixgw/config/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ connections:
- IFLY_CONFIG
- MEGASQUIRT_CONFIG
- MGL_CONFIG
- DYNON_CONFIG
- DEMO_CONFIG

# Logging configuration - See Python logging.config module documenation
Expand Down
2 changes: 2 additions & 0 deletions fixgw/config/preferences.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ includes:
IFLY_CONFIG: connections/ifly.yaml
MEGASQUIRT_CONFIG: connections/megasquirt.yaml
MGL_CONFIG: connections/mgl.yaml
DYNON_CONFIG: connections/dynon.yaml
DEMO_CONFIG: connections/demo.yaml
# This section is used to turn things on or off
enabled:
Expand Down Expand Up @@ -60,5 +61,6 @@ enabled:
IFLY: false
MEGASQUIRT: false
MGL: false
DYNON: false
DEMO: true

116 changes: 116 additions & 0 deletions fixgw/plugins/dynon/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#!/usr/bin/env python

# Copyright (c) 2024 Janne Mäntyharju
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

# Reads data from Dynon D10/D100 serial output stream

import threading
from collections import OrderedDict

import serial
import fixgw.plugin as plugin


class MainThread(threading.Thread):
def __init__(self, parent):
super(MainThread, self).__init__()
self.getout = False # indicator for when to stop
self.parent = parent # parent plugin object
self.log = parent.log # simplifies logging
self._buffer = bytearray()
self._c = None
self._vario_values = []

def run(self):
self._c = serial.Serial(self.parent.config['port'],
baudrate=115200,
timeout=0.5,)
while not self.getout:
try:
s = self._c.read(self._c.in_waiting)
except serial.SerialException:
self.parent.log.error("Serial port error")

for c in s:
if c == 0x0A: # message end
message = self._buffer
self._buffer = bytearray()
self._parse(message)
else:
self._buffer.extend(c.to_bytes())

def stop(self):
self.getout = True

def _parse(self, message):
if len(message) != 52:
self.parent.log.error("Incorrect data length")
return

status = int(message[41:47], 16) & 1

pitch = int(message[8:12]) / 10.0
self.parent.db_write("PITCH", pitch)

roll = int(message[12:17]) / 10.0
self.parent.db_write("ROLL", roll)

yaw = int(message[17:20])
self.parent.db_write("YAW", yaw)

if status == 0:
alt = round(int(message[24:29]) * 3.28084) # meters to feet

self.parent.db_write("ALT", alt)
self.parent.db_write("TALT", alt)

turn_rate = int(message[29:33]) / 10
self.parent.db_write("ROT", turn_rate)
else:
vs = int(message[29:33]) / 10 * 60

self._vario_values.append(vs)
if len(self._vario_values) > 128:
self._vario_values.pop(0)
if len(self._vario_values):
vs = round(sum(self._vario_values) / len(self._vario_values))

self.parent.db_write("VS", vs)

# 1/10 m/s to knots
speed = round(int(message[20:24]) * 0.194384)
self.parent.db_write("IAS", speed)


class Plugin(plugin.PluginBase):
def __init__(self, name, config):
super(Plugin, self).__init__(name, config)
self.thread = MainThread(self)
self.status = OrderedDict()

def run(self):
self.thread.start()

def stop(self):
self.thread.stop()
if self.thread.is_alive():
self.thread.join(1.0)
if self.thread.is_alive():
raise plugin.PluginFail

def get_status(self):
return self.status