Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
bac2f24
ads1115 work
TopherTimeMachine May 12, 2023
2a25bc8
install script
TopherTimeMachine May 12, 2023
7897923
fix for ads115 input. show text output. analog input for aircraft ob…
hpmicrowave Jul 6, 2023
8579bb1
changed input gain and using difference.
TopherTimeMachine Jul 10, 2023
ab32a57
write data to nav object in aircraft.
TopherTimeMachine Jul 10, 2023
9697263
write data to nav object in aircraft.
TopherTimeMachine Jul 11, 2023
56a4d57
fix
hpmicrowave Jul 11, 2023
ceaae58
cycle modes for CDI
TopherTimeMachine Jul 12, 2023
612d8fe
CDI updates
TopherTimeMachine Jul 12, 2023
eee6820
use waterline for CDI
TopherTimeMachine Jul 12, 2023
51601bb
Merge branch 'ads1115' of https://github.com/flyonspeed/TronView into…
hpmicrowave Jul 12, 2023
f23c738
try catch
TopherTimeMachine Jul 13, 2023
03e3498
changed syntax errors
hpmicrowave Jul 13, 2023
0e266b5
fix
TopherTimeMachine Jul 13, 2023
838eca9
fix
TopherTimeMachine Jul 13, 2023
44d96d4
Merge pull request #49 from flyonspeed/topher_adc
TopherTimeMachine Jul 13, 2023
8aabf6d
merger
hpmicrowave Jul 13, 2023
3b9b930
merge
hpmicrowave Jul 13, 2023
005287f
Corrected Errors
hpmicrowave Jul 13, 2023
3f0fc6e
merge g3x serial fix
TopherTimeMachine Jul 13, 2023
31a5483
Merge branch 'ads1115' of https://github.com/flyonspeed/TronView into…
hpmicrowave Jul 13, 2023
b8f912b
fix EOL for g3x error
TopherTimeMachine Jul 13, 2023
cf91556
fix for g3x playback and live serial data
hpmicrowave Jul 13, 2023
9e6e5c3
apply avg
TopherTimeMachine Jul 18, 2023
d78b244
fixs for avg
TopherTimeMachine Jul 18, 2023
00cfa4f
Update ADS1115
midwestpanels Aug 9, 2024
29b6d61
Update README to include ADS information
midwestpanels Aug 9, 2024
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
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,22 @@ Following install guide if you need help. https://www.raspberrypi.org/documenta

Setup your serial input using the GPIO pins on pi zero. This page will help you. https://www.instructables.com/id/Read-and-write-from-serial-port-with-Raspberry-Pi/

## Analog CDI from IFR Navigator

TronView supports reading CDI and VDI data from an IFR Navigator for use on EFIS systems that do not output this data over RS-232. This is done via the ADS 1115 Analog to Digital Converting I2C chip from Texas Instruments. The ADS 1115 is available on a carrier board from Adafruit to make connecting to it more convenient with a Pi.

This interface enables a "crosshair" style presentation of CDI data on the defaul and F18 hud pages, plus any page you may come up with. This essentially creates the ability for one to fly an ILS or GPS/LPV approach using TronView, though since TronView is NOT a certified instrument nor is it intended in any way to be used as primary instrumentation.

In order to wire this up, you'll need an IFR navigator (GPS or NAV radio) that supports the output of +L/+R and +U/+D signals. Examples of radios that do this include the Garmin GNS, GTN and 2-inch GPS Navigator series, Garmin GNC 255/215, SL-30, Avidyne IFD and King KX 165 (NOT 155) units. There are certainly more that will do this, but these are the most popular examples.

This hookup uses the same wiring as most mechanical CDIs.

The ADC has 4 input channels, labeled 0-3. Channel 0 is CDI +L, Channel 1 is CDI +R, Channel 2 is VDI +U, and Channel 3 is VDI +D. Refer to your navgiator's installation manual/pinout to determine the matching pins.

We recommend installing an intermediate D-Sub connector for both diagnostics and future changes.



## Steps to get the software running on raspberry pi

1) WIFI and autologin. You’ll want to get the pi on your wifi network so it can download the latest source. Here are some instructions online that might help. https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md
Expand Down Expand Up @@ -372,6 +388,4 @@ https://github.com/flyonspeed/TronView/blob/master/config_example.cfg

# Stratux Data

Recorded data for stratux is saved in the example data. stratux_1.dat shows traffic near by. Like 0.5 miles away.


Recorded data for stratux is saved in the example data. stratux_1.dat shows traffic near by. Like 0.5 miles away.
6 changes: 6 additions & 0 deletions config_example.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#inputsource = levil_wifi
#inputsource = serial_logger
#inputsource = stratux_wifi
#inputsource = adc_ads1115


# Set serial port. defaults to /dev/ttyS0
Expand All @@ -45,6 +46,11 @@
# 2nd input source will overwrite the data from the 1st source (if data exists)
#inputsource = stratux_wifi

[DataInput3]
# set this to use a 3rd data input source
# 2nd input source will overwrite the data from the 1st source (if data exists)
#inputsource = adc_ads1115

[Stratux]
# To ignore ahrs data from stratux set use_ahrs=false, defaults to true
#use_ahrs = false
Expand Down
13 changes: 12 additions & 1 deletion lib/aircraft.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@ def __init__(self):
self.traffic = TrafficData()
self.fuel = FuelData()
self.internal = InteralData()
self.inputs = [InputDetails(),InputDetails()]
self.inputs = [InputDetails(),InputDetails(),InputDetails()]
self.alerts = []
self.analog = AnalogData()
self.debug1 = ""
self.debug2 = ""
self.debug3 = ""
Expand Down Expand Up @@ -202,6 +203,15 @@ def get_vsi_string(self):
else:
return "+%d %s" % (v,d)

#############################################
## Class: Analog Input Data
class AnalogData(object):
def __init__(self):
self.Name = None
self.Num = 0
self.Data = [0,0,0,0,0,0,0,0]


#############################################
## Class: AlertData
class AlertData(object):
Expand Down Expand Up @@ -287,6 +297,7 @@ def __init__(self):
self.NavStatus = ""
self.HSISource = 0
self.VNAVSource = 0
self.SourceDesc = ""
self.AP = 0
self.HSINeedle = 0
self.HSIRoseHeading = 0
Expand Down
1 change: 1 addition & 0 deletions lib/common/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
## Inputs can be from Serial, Files, wifi, etc...
CurrentInput = None
CurrentInput2 = None
CurrentInput3 = None

####################################
## SmartDisplay Obect
Expand Down
4 changes: 4 additions & 0 deletions lib/inputs/_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ def printTextModeData(self, aircraft):
hud_text.print_header("Traffic Data")
hud_text.print_object(aircraft.traffic,showHowManyListItems=showHowManyListItems)

if self.textMode_whatToShow==0 or self.textMode_whatToShow==3:
hud_text.print_header("Analog")
hud_text.print_object(aircraft.analog,showHowManyListItems=showHowManyListItems)

if self.textMode_whatToShow==0 or self.textMode_whatToShow==4:
hud_text.print_header("GPS Data")
hud_text.print_object(aircraft.gps)
Expand Down
125 changes: 125 additions & 0 deletions lib/inputs/adc_ads1115.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!/usr/bin/env python

# ads1115 input source


from ._input import Input
from lib import hud_utils
from . import _utils
import struct
import time
import Adafruit_ADS1x15
import statistics

class adc_ads1115(Input):
def __init__(self):
self.name = "ads1115"
self.version = 1.0
self.inputtype = "adc"
self.values = []
self.ApplySmoothing = 1
self.SmoothingAVGMaxCount = 10
self.smoothingA = []
self.smoothingB = []

def initInput(self,num,aircraft):
Input.initInput( self,num, aircraft ) # call parent init Input.
if(aircraft.inputs[self.inputNum].PlayFile!=None):
# Get playback file.
#if aircraft.inputs[self.inputNum].PlayFile==True:
# defaultTo = "ads1115_Flight1.bin"
# aircraft.inputs[self.inputNum].PlayFile = hud_utils.readConfig(self.name, "playback_file", defaultTo)
#self.ser,self.input_logFileName = Input.openLogFile(self,aircraft.inputs[self.inputNum].PlayFile,"rb")
self.isPlaybackMode = True
else:
self.isPlaybackMode = False
#self.efis_data_format = hud_utils.readConfig("DataInput", "format", "none")
#self.efis_data_port = hud_utils.readConfig("DataInput", "port", "/dev/ttyS0")
#self.efis_data_baudrate = hud_utils.readConfigInt(
# "DataInput", "baudrate", 115200
#)

# setup comm i2c to chipset.
self.adc = Adafruit_ADS1x15.ADS1115()
# Choose a gain of 1 for reading voltages from 0 to 4.09V.
# Or pick a different gain to change the range of voltages that are read:
# - 2/3 = +/-6.144V
# - 1 = +/-4.096V
# - 2 = +/-2.048V
# - 4 = +/-1.024V
# - 8 = +/-0.512V
# - 16 = +/-0.256V
# See table 3 in the ADS1015/ADS1115 datasheet for more info on gain.
self.GAIN = 2/3
aircraft.analog.Name = "ads1115"
self.Amplify = 6.144/32767
self.values = [0,0,0,0,0,0,0,0]


def closeInput(self,aircraft):
print("ads1115 close")


#############################################
## Function: readMessage
def readMessage(self, aircraft):
if self.shouldExit == True: aircraft.errorFoundNeedToExit = True
if aircraft.errorFoundNeedToExit: return aircraft
if self.skipReadInput == True: return aircraft

try:

# for i in range(4):
# time.sleep(0.025)
# self.values[i] = 0;
# # Read the specified ADC channel using the previously set gain value.
# self.values[i] = self.adc.read_adc_difference(i, gain=self.GAIN) * self.Amplify

time.sleep(0.025)
self.values[1] = self.adc.read_adc_difference(0, gain=self.GAIN) * self.Amplify
time.sleep(0.025)
self.values[0] = self.adc.read_adc_difference(3, gain=self.GAIN) * self.Amplify

# apply smoothing avg of adc values?
if(self.ApplySmoothing):
self.smoothingA.append(self.values[0])
if(len(self.smoothingA)>self.SmoothingAVGMaxCount): self.smoothingA.pop(0)
aircraft.analog.Data[0] = statistics.mean(self.smoothingA)


self.smoothingB.append(self.values[1])
if(len(self.smoothingB)>self.SmoothingAVGMaxCount): self.smoothingB.pop(0)
aircraft.analog.Data[1] = statistics.mean(self.smoothingB)
else:
#else don't apply smoothing.
aircraft.analog.Data = self.values

# TODO: have config file define what this analog input is for.

# if analog input is for nav needles.. .then.
# limit the output voltages to be within +/- 0.25V
# format value to +/- 4095 for needle left/right up/down.
aircraft.nav.GSDev = round (16380 * (max(min(aircraft.analog.Data[0], 0.25), -0.25)))
aircraft.nav.ILSDev = round (16380 * (max(min(aircraft.analog.Data[1], 0.25), -0.25)))


#aircraft.analog = self.values[0]
#aircraft.nav.GSDev = self.values[1]

#aircraft.nav.GLSHoriz = GLSHoriz
#aircraft.nav.GLSVert = GLSVert

#aircraft.nav.msg_count += 1
#if(self.textMode_showRaw==True): aircraft.nav.msg_last = binascii.hexlify(Message) # save last message.
#else: aircraft.nav.msg_last = None

except Exception as e:
aircraft.errorFoundNeedToExit = True
print(e)
print(traceback.format_exc())
return aircraft




# vi: modeline tabstop=8 expandtab shiftwidth=4 softtabstop=4 syntax=python
8 changes: 6 additions & 2 deletions lib/inputs/serial_g3x.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@ def initInput(self,num, aircraft):
Input.initInput(self,num, aircraft) # call parent init Input.
if(aircraft.inputs[self.inputNum].PlayFile!=None):
# play a log file?
self.EOL = 10 # if log file then change the EOL
if aircraft.inputs[self.inputNum].PlayFile==True:
defaultTo = "garmin_g3x_data1.txt"
aircraft.inputs[self.inputNum].PlayFile = hud_utils.readConfig(self.name, "playback_file", defaultTo)
self.ser,self.input_logFileName = Input.openLogFile(self,aircraft.inputs[self.inputNum].PlayFile,"r")
self.isPlaybackMode = True
else:
self.EOL = 13
self.efis_data_format = hud_utils.readConfig("DataInput", "format", "none")
self.efis_data_port = hud_utils.readConfig(
"DataInput", "port", "/dev/ttyS0"
Expand All @@ -58,10 +60,10 @@ def initInput(self,num, aircraft):

# check for system platform??
#if sys.platform.startswith('win'):
# self.EOL = 10
#self.EOL = 10
#else:
# self.EOL = 13
self.EOL = 13
#self.EOL = 13

# close this input source
def closeInput(self, aircraft):
Expand Down Expand Up @@ -202,9 +204,11 @@ def mean(nums):

else:
aircraft.msg_bad += 1
aircraft.debug2 = "bad air data - unkown ver"

else:
aircraft.msg_bad += 1
aircraft.debug2 = "bad air data - wrong len"

elif SentID == 7: # GPS AGL data message
msg = self.ser.read(16)
Expand Down
27 changes: 23 additions & 4 deletions lib/modules/hud/cdi/cdi.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ def initMod(self, pygamescreen, width, height):
self.xLDMaxDotsFromCenter = width/2

self.cdi_color = (255, 255, 255) # start with white.
# pull water line offset from HUD config area.
self.y_offset = hud_utils.readConfigInt("HUD", "Horizon_Offset", 0) # Horizon/Waterline Pixel Offset from HUD Center Neg Numb moves Up, Default=0



# called every redraw for the mod
def draw(self, aircraft, smartdisplay, pos):
Expand All @@ -57,39 +61,54 @@ def draw(self, aircraft, smartdisplay, pos):

# NAV Test Graphics for MGL
# Is Glide Slope Active

self.new_y_center = smartdisplay.y_center + self.y_offset

if aircraft.nav.HSISource == 1:
pygame.draw.line(
self.pygamescreen,
self.cdi_color,
(smartdisplay.x_center - (aircraft.nav.ILSDev / 60), smartdisplay.y_center - 67), (smartdisplay.x_center - (aircraft.nav.ILSDev / 60), smartdisplay.y_center - 8),
(smartdisplay.x_center - (aircraft.nav.ILSDev / 60), self.new_y_center - 67), (smartdisplay.x_center - (aircraft.nav.ILSDev / 60), self.new_y_center - 8),
4,
)
pygame.draw.line(
self.pygamescreen,
self.cdi_color,
(smartdisplay.x_center - (aircraft.nav.ILSDev / 60), smartdisplay.y_center + 8), (smartdisplay.x_center - (aircraft.nav.ILSDev / 60), smartdisplay.y_center + 67),
(smartdisplay.x_center - (aircraft.nav.ILSDev / 60), self.new_y_center + 8), (smartdisplay.x_center - (aircraft.nav.ILSDev / 60), self.new_y_center + 67),
4,
)

if aircraft.nav.VNAVSource == 1:
pygame.draw.line(
self.pygamescreen,
self.cdi_color,
(smartdisplay.x_center-70,(aircraft.nav.GSDev / 60) + smartdisplay.y_center),(smartdisplay.x_center-8, (aircraft.nav.GSDev / 60) + smartdisplay.y_center),
(smartdisplay.x_center-70,(aircraft.nav.GSDev / 60) + self.new_y_center),(smartdisplay.x_center-8, (aircraft.nav.GSDev / 60) + self.new_y_center),
4,

)
pygame.draw.line(
self.pygamescreen,
self.cdi_color,
(smartdisplay.x_center+8,(aircraft.nav.GSDev / 60) + smartdisplay.y_center),(smartdisplay.x_center+70, (aircraft.nav.GSDev / 60) + smartdisplay.y_center),
(smartdisplay.x_center+8,(aircraft.nav.GSDev / 60) + self.new_y_center),(smartdisplay.x_center+70, (aircraft.nav.GSDev / 60) + self.new_y_center),
4,
)
# Localizer
# End Test Graphics


# cycle through NAV sources
def cycleNavSource(self,aircraft):
if aircraft.nav.HSISource == 0 and aircraft.nav.VNAVSource == 0:
aircraft.nav.HSISource = 1
aircraft.nav.SourceDesc = "Localizer"
elif aircraft.nav.HSISource == 1 and aircraft.nav.VNAVSource == 0:
aircraft.nav.VNAVSource = 1
aircraft.nav.SourceDesc = "ILS"
else:
aircraft.nav.HSISource = 0
aircraft.nav.VNAVSource = 0
aircraft.nav.SourceDesc = ""


# called before screen draw. To clear the screen to your favorite color.
def clear(self):
Expand Down
10 changes: 4 additions & 6 deletions lib/screens/F18_HUD.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,14 +219,12 @@ def processEvent(self, event, aircraft, smartdisplay):
self.trafficScope.processEvent(event,aircraft,smartdisplay)

elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_KP9:
if event.key == pygame.K_KP9 or event.key == pygame.K_9:
self.horizon.cyclecaged_mode()
if event.key == pygame.K_9:
self.horizon.cyclecaged_mode()
if event.key == pygame.K_8:
self.gcross.cycleGunSight()
if event.key == pygame.K_KP8:
elif event.key == pygame.K_8 or event.key == pygame.K_KP8:
self.gcross.cycleGunSight()
elif event.key == pygame.K_0 or event.key == pygame.K_KP0:
self.cdi.cycleNavSource(aircraft)



Expand Down
Loading