FG Hardware Interace (FGInt)

daweed
Posts: 56
Joined: Sat Apr 23, 2016 11:23 am

Re: FG Hardware Interace (FGInt)

Postby daweed » Sat Apr 30, 2016 7:52 pm

Thanks,

i will begin feeding asap

daweed
Posts: 56
Joined: Sat Apr 23, 2016 11:23 am

Re: FG Hardware Interace (FGInt)

Postby daweed » Sun May 01, 2016 2:35 am

Well,

Before entering deep in the subject, i have to told u a little more on the Story :)

i year and half about, after having lot's of fun with flying & atcing, i was watching some video looking how some have made their cockpit, most on FSX, Xplane.
And most of them are running on .. arggg hard to say this word ... windows ... argg :); that's a long time that there is no more windows software at home.
After having a look on some online shops selling sim cockpit part, i found that very expensive.

Some month later, i discover that Flightgear has a embedded telnet server that allow to act on the properties tree, and i begun to play with it, writing some small script in python (a python Flightgear Telnet Class is avail in the sources).

And quickly, envy me taken de build a cockpit totally from scratch.

Some we are talking about the hardware (pedestal, overhead ... ) but the software part needed to be written, and something was needed to make interface between.
I discover, talking with a friend a bout my project, the Raspberry pi, a full computer with a full linux os, and GPIO port to communicate with the world ....

Here what is a raspberry pi : https://fr.wikipedia.org/wiki/Raspberry_Pi
Final version will be equipped with the last version of the Raspberry PI 2

Next day i was buying 2 rasbpi.

Python language seems to have been very well developed for raspi, lot's a library to use the GPIO (https://fr.wikipedia.org/wiki/General_P ... put/Output)

After having made a lot's of test, i understand that only with the raspberry , a all cockpit could not be done, as in the first version, there is only 12 GPIO (so only 12 Korry for example, and i am not talking about the all in / out needed for light switch.)

But the raspberry is provide with serial buses on is GPIO, I2C and SPI, there is plenty of device that can be connected to this bus, and for example some IO expander
Some more research give me exact model i was needed.

I ll make a break to tell u 2 things about me that could also explain how / why i am actually able to process with my knowledge all of this.
IRL i am a DBA, and work in a good IT unit, computers and their language are in my blood and, for the hardware question, i am an electronic school formation guy.

So bring back to what i have called FGInt (Flightgear Interface)

Quickly, telnet has its limitations, was not responding as needed when lot's of thingfs was declared. And one more time, Flightgear had the answer, the Generic Protocol. Was a little hard, as it's not very well documented, but with test/fail method, i have finished by tame the beast

An another thing i have forgot to tell u is, that in contrary of the most existing interface, interface is not plugin directy on the pc via usb.
The core interface is the raspberry, so the interface has it own OS, CPU, memory and will note affect simulation.

The interface is directly plugin in the LAN, network communication. => that allow to have more that one interface (more that 1 raspberry) to share the charge if needed, and a rasberry is lesss, less expensive that an another pc, i saw that most the the cockpit need to use more that 3 PC ...outch

Next was the brainstorming to imagine and split elements that are used in a cockpit could be fit into python class.

So Globaly here how it work :

an 'interface' is defined & configured via a configuration file where each of the light, switch or other actor can be delcared.
Next i wrote some class to create a large type of that could be use to manage et make the link between hardware and the sim.
For example, to create a switch, u can call a method named CreateSwitch and give some args as the input number on the physic device, physical device address on the i2c bus ... etc
Ex switch = CreateSwitch(device, switchname ...)

Then, u can use the object as for example to read a switch

switch.getSwichState()

I have classes for switch light, light, rotary switch, display (u call for example disp.WriteDisplay(250)) ... etc

and all can be configured in cfg files, to call generic methods as like a CreateSwitches which will create all switches declared taking information directly in the config file.
Hardware need to be more accurate, i have some bounce trouble, but i will probably remove thoose problem with hardware solution, that will be better than a software one.

So here where i am actually , i have create some quick panel with switch, rotary encoder, double switch, pusbt, light switch and all 7 segments displays of the A330 FCU, so globally it's working, but can be tunned more before having a final prototype. What i am presenting here is the final POC version.

Real version will have full pcb (i am able to produce)

I think it's been not bad to digest, i ll talk u more next time about the hardware part, deeper in détail, will take some pics

User avatar
IAHM-COL
Posts: 5635
Joined: Sat Sep 12, 2015 3:43 pm
Location: Homey, NV (KXTA) - U.S.A
Contact:

Re: FG Hardware Interace (FGInt)

Postby IAHM-COL » Sun May 01, 2016 5:10 am

Wow. You really know what you are talking in there. Me? I will need to revisit the last post a few many times to start digesting. :oops: :P
R.M.S.
If we gave everybody in the World free software today, but we failed to teach them about the four freedoms, five years from now, would they still have it? Probably not, because if they don’t recognise their freedoms, they’ll let their freedoms fall

daweed
Posts: 56
Joined: Sat Apr 23, 2016 11:23 am

Re: FG Hardware Interace (FGInt)

Postby daweed » Sun May 01, 2016 11:03 am

Chapter I - Hardware

1°) RASPBERRY PI, so here the heart of the system,

Image

First version, as i said was a raspberry pi B 512 version
ARM1176JZF (mono core 700Mhz)
512 Mo Ram
4 Port USB
OpenGL ES 2.0 avail (so il should be able to process some FGPanel execution too)
HDMI out
Audio out
RJ45 network
GPIO 26 pins

Finla Version will be made around a raspberry pi 2 B
Quad Core 900 Mhz ARM Cortex A7 processor
1G Ram
4 Port USB
OpenGL ES 2.0 avail (so il should be able to process some FGPanel execution too)
HDMI out
Audio out
RJ45 network
GPIO 40 pins

There is compatibility between the 26 GPIO port and the 40 one
V3 version announced in Fev 2016 is just more powerfull:
1.2 Ghz quadri core processor, 1Gb RAM, bluethooth / wifi included, windows 10 IoT (for thoose who like this OS) supported

2°) I/O Hardware (Input / Output) : Chip MCP23017 http://www.microchip.com/wwwproducts/en/MCP23017

Image

(it's the old version, that has been made for raspberry PI but is compatible with RPI 2)

16-bit input/output port expander with interrupt output
Cascadable for up to 8 devices on one bus (so 16 x 8 input on a single buses => 128 GPIO more avail) and there is 2 I2C buses on a rpi
Fact is you can get up to 256 I/O with one raspberry

Here what i am using https://www.abelectronics.co.uk/p/54/IO-Pi-Plus , already breakouted with two chip (so 32 I/O on one board, and up to 4 board can be plugin on the buses. I am using this type of breakout because it can be plus directly on the GPIO connector on the raspberry (HAT system [Hardware Attached on Top])

In my project, thoose type of chip will be used only as INPUT so up to 128 In on one buses.
You have to understand that an input is a single channel, and some "actor" can need more than one to work :

A simple switch (2 stable state) will need only 1 input to be manage.
A double switch with 2 or 3 stable state will need 2 input.
A rotary switch as like the Engine Mode Starter on the A330 will need 3 inputs ...
Korry switch will need ... 1 input (Push btn, only one single stable state) ...

Etc ... etc

So these devices are managed through the I2C bus (serial bus type), i will come back later on the I2C comunications.

3°) Lights & Displays manager : chip HT16K33, breakouted by ADAFRUIT compagny https://www.adafruit.com/products/1427
(humm, would like to meet LadyAda ...)

Image

It's a 16 x 8 Led Matrix Driver and can even manage in input mode a 256 Key keyboard.
So this one can manage up to 128 led or 16 x 7 segments display or a mix of that.
[SPD = 3 Digits, HDG 3 = Digits, ALT = 5 Digits, VS = 5 Digits => Total 16 digits, the all fcu displays can be manage with one ... cost : $5.95

Controlled throught the I2C bus each out can be manage individually.

I use the breakout version because il's more simple to deal with or dev than having a very small circuit to weld


The rest (panel, led and physical displays ) are just what they are .., there ni no electronics part in panels

Next Chapter : I2C Buses

daweed
Posts: 56
Joined: Sat Apr 23, 2016 11:23 am

Re: FG Hardware Interace (FGInt)

Postby daweed » Sun May 01, 2016 3:03 pm

Chapter II I2C Buses

So I2C buses are serial type buses created by Philips to manage domotic devices. And there is plenty of devices as said, going from I/O expander to temp sensor or even audio device (yes, even the audio alert could be played by the raspberry, so by the interface).

The raspberry pi is really seen as a development platform hardware for domotic , robotic or media / small web server . Remember that the Raspi works with a complete Linux OS and the tools chain are available to compile all what we want on the proc, as I said , have HDMI and composite video , nothing prevents compile FGPanel or control an LCD screen ( eg MCDU )

And in this sense the community has provided to numerous low-level libraries , including all it takes to fly an I2C bus

So the functions needed to communicate with I2C devices were already there, it just remained to encapsulate them in a python class to make them interraction more "user friendly".

These devices all work in much the same way , it is always to position the values ​​in different buffers (often 8 bits ) to configure the device and read or write input / output (which correspond also has buffers ) ..

Buffer for those who have already thrown in the towel is not nothing but a memory which stores information , usually 8 bits on this type of device

So the game that was to provide, initially , python methods that would allow me to read and write all what I wanted in the I2C bus.

So i wrote a class qui give me an I2C python object with methods like device.ReadRegister (register addr) or device.WriteRegister (register addr , value) and Some Other allowing to manage 1 bit directly.

this class can manage by herself the all I2C comunication between the raspberry and any device.

Informations about devices address , devices name .. etc are declared in configuration file. One of the goal is be used by evryone, without open a code file. All should be declared throught the config file. So that allow to use it with any plane.

Next FGInt python class

User avatar
it0uchpods
Posts: 2099
Joined: Sun Oct 18, 2015 2:47 am
Location: A far corner of my room.
Contact:

Re: FG Hardware Interace (FGInt)

Postby it0uchpods » Sun May 01, 2016 3:33 pm

@daweed very interesting, I may try this some day.

Regards,
it0uchpods/WTF411

FlightGear Aircraft Developer
Lead Programmer at the it0uchpods Design Group
Download High Quality Aircraft from it0uchpods Hangar

daweed
Posts: 56
Joined: Sat Apr 23, 2016 11:23 am

Re: FG Hardware Interace (FGInt)

Postby daweed » Sun May 01, 2016 3:55 pm

Chapter III FGInt python Class

I then need class allows me to manage each type of physical devices, I have written two classes, one for the MCP23017, one for the driver led HT16K33.

These class bring me the flexibility (again the methods "friendly user") to configure and use the physical devices

With this class I could invoke methods like ReadInput, WriteOutput etc ...

And to consolidate all this, a parent class that would become the core of the class interface via its own method of creating a virtual object interface that all endure.

In this class we find the interace of the management method, such as reading the configuration, creation of virtual elements corresponding to physical elements [the switch, the Korry etc ..]

EVERY types of elements being managed by itself its own class that the purpose of having access to methods such as ReadSwitch, SetLightState or WriteDisplay ...

Class split is a good way to have many files, but it's more easy to manage

finally all that was missing was a daemon who would use the core class to create and use interface

Here is an example on how one panel is manage
Switch part :

Code: Select all

#!/usr/bin/env python
# -*-coding:Utf-8 -*

###################################
# FarmerSoft FlightGear Interface
###################################
# Main Program
# FarmerSoft © 2015
# By Daweed
###################################

# System Module Import <= Module system needed to be imported
import os
import sys
import operator
import time
import struct
import socket
import datetime

# GPIO et PIGPIO Module Import <= that will  be needed in the futur to manage interruption
import RPi.GPIO as GPIO

###################################
#
# Debug Mode :
# Level 0 : Debug mode off
# Level 1 : Debug mode on FarmerFGInt
# Level 2 : Debug mode on Device I2C
# Level 3 : Debug mode on Bus I2C
# Level 4 : Debug mode on Object I2C
#
###################################

##############################
# FarmerSoft Modules Import
##############################
from FarmerFGInt import FarmerFGInt as FGINT <= Here FGInt core class import

########################################
# Variables Initialisation
########################################
loop = True
########################################
loop = True
data = ""
props_tree_input_return = {}
props_tree_old = {}
state = '-'
now = datetime.datetime.now()

########################################
# Main
########################################

# Interface INT2 Creation
# The FGINT call return an FGInt python object
# In this case, it will use the int2.cfg file in the Config directory
INT2 = FGINT('int2.cfg', 1)

# Interface Devices Creation
# This methode list all devices declared in the config file
INT2.ListDevices()
# This methode will create all virtual device in the Interface scope
# Each create device can be access by a call like INT2.devices['devicename']
INT2.CreateDevices()

# I/O pack creation
# Here we get the first device named IOPACK1 which is defined in the config file.
# A pack is a mirror of a MCP23017, an object that will allow me to manage 16 I/O
IOPACK1 = INT2.GetDevice("IOPACK1")
# Same here for the second pack. 16 I/O more avail
IOPACK2 = INT2.GetDevice("IOPACK2")

# Liste des Switches dans la Configuration
# This method will list all switches declared in the config file (more usefull for debug)
INT2.ListSwitches()
# This method will create all switches defined, and each switches will be avail fomr
# INT2.switches["switchname']
INT2.CreateSwitches()

# Liste des Double Switches dans la Configuration
# Same here for double type switches
INT2.ListDblSwitches()
INT2.CreateDblSwitches()

# Liste des Rotary Switches dans la configuration
# and here for rotatry switches
INT2.ListRotSwitches()
INT2.CreateRotSwitches()

# Some debug trace
print("Initialisation de l'interface d'entrée")
print("\n")

# FG Connexion (connexion to simulation)
# This interface have a connexion From the interface and To FG and only in that way
print("Connexion au Serveur FG")
Sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host = '192.168.0.127'
port = 7700
Sock.connect((host, port))

# Starting the principal loop
print("Debut de la boucle principale")

while loop == True:
    data = ""

    if INT2.switches['mainswitch'].getSwitchState() == 1:
        print("Etat du Main Switch : {}".format(INT2.switches['mainswitch'].getSwitchState()))
        print("Fin de la boucle d'entrée de l'interface")
        IOPACK1.configMCP(0, 0)
        IOPACK2.configMCP(0, 0)
        loop = False
    i = 1

    #what i do here is looping on the switches tab and get for each the actual state
    #store in data var, then at the end of the loop send to FG information
    for key, value in INT2.switcheslist:
        if value != 'mainswitch':
            data = data + str(INT2.switches[value].getSwitchState())
            if i < len(INT2.switcheslist):
                data = str(data + ":")
        i += 1

    i = 1

    data = str(data) + ":"

    for key, value in sorted(INT2.dblswitcheslist):
        data = data + str(INT2.dblswitches[value].getSwitchState())
        if i < len(INT2.dblswitcheslist):
            data = str(data) + ":"
        i += 1
    i = 1

    data= str(data) + ":"

    for key, value in sorted(INT2.rotswitcheslist):
        data = data + str(INT2.rotswitches[value].getSwitchState())
        if i < len(INT2.rotswitcheslist):
            data = str(data) + ":"
            i += 1
    i = 1

    #print("DATA : {}".format(data))
    # Here is sent the informations.
    Sock.send(data)
    Sock.send("\n")
    time.sleep(0.001)



As you can see, the main loop is very small , little line of code , the code is ventilated even in my view by the name of methods used enough talking

The following block of code manage by himself all switches declared

Code: Select all

for key, value in INT2.switcheslist:
        if value != 'mainswitch':
            data = data + str(INT2.switches[value].getSwitchState())
            if i < len(INT2.switcheslist):
                data = str(data + ":")
        i += 1


Of course it is obvious that the various class related to a given physical material, but has kept the operation of the interface, you just have to write a management class to the other I2C device , or another class for data elements of the project is really designed to be modular

I need to make a break :)
Last edited by daweed on Sun May 01, 2016 3:57 pm, edited 1 time in total.

User avatar
IAHM-COL
Posts: 5635
Joined: Sat Sep 12, 2015 3:43 pm
Location: Homey, NV (KXTA) - U.S.A
Contact:

Re: FG Hardware Interace (FGInt)

Postby IAHM-COL » Sun May 01, 2016 3:56 pm

Those Python scripts. Are those GPL?

If so I request you modify this:

Code: Select all

# Main Program
# FarmerSoft © 2015
# By Daweed


to this

Code: Select all

# Main Program
# FarmerSoft © 2015
# By Daweed

#License GPL3+
R.M.S.
If we gave everybody in the World free software today, but we failed to teach them about the four freedoms, five years from now, would they still have it? Probably not, because if they don’t recognise their freedoms, they’ll let their freedoms fall

daweed
Posts: 56
Joined: Sat Apr 23, 2016 11:23 am

Re: FG Hardware Interace (FGInt)

Postby daweed » Sun May 01, 2016 4:00 pm

yep it plan to be :)

All code is written by myself, each method

All my code can be found on a old repo, but is no longer up2date.
I ll upload soon all my code in github repo

It's not totally finished, need time to finish some element (working on rotary encoder ( hdg, spd alt ... etc selector)

And the daemon script need to be more accurate before that can really be used by simer. And i want to create a graphic tool to create configuration file, as by now, needed to written with text editor, i will probably need help for that Python GTK should be fine to suit with python daemon

daweed
Posts: 56
Joined: Sat Apr 23, 2016 11:23 am

Re: FG Hardware Interace (FGInt)

Postby daweed » Sun May 01, 2016 4:44 pm

Chapter III FGInt python Class - part2


It work in the same way for all light, switch light or displays. They are defined on a interface which use devices to manage the real digit.
Basicaly, a 7 segment is 8 led arranged in a way to make a 8 + a dot, they are called in this case segment, but fact is each segment is a led, all arrange with a common pin

HT16K33 device is, as i said, a multiplexing led driver. That mean he refresh his buffer one, each buffer reflecting the state of digit, and display one by one ... but at a so hight rate that retinal persistence gives you the impression that all the outputs are on at once.

I am talking about the beginig about config files, so here how as they are architectured

Here what's looks like an interface config file :

Code: Select all

[INT]
intname=INT1

[DEVICES]
device001name=ledpack1
device002name=ledpack2

[SWLIGHTS]
swlight001name=ap1swlts
swlight002name=ap2swlts
swlight003name=athswlts
swlight004name=locswlts
swlight005name=expswlts
swlight006name=appswlts
swlight007name=apumstswlts
swlight008name=apumstswfltlts
swlight009name=apustrswlts
swlight010name=apustrswavaillts
swlight011name=eng1genswlts
swlight012name=eng1genswfltlts
swlight013name=eng2genswlts
swlight014name=eng2genswfltlts
swlight015name=ltkpump1swlts
swlight016name=ctkpump1swlts
swlight017name=rtkpump1swlts
swlight018name=batswlts
swlight019name=apugenswlts
swlight020name=extpwraswlts
swlight021name=extpwraavaillts
swlight022name=extpwrbswlts
swlight023name=extpwrbavaillts
swlight024name=pack1swlts
swlight025name=pack2swlts
swlight026name=eng1bldswlts
swlight027name=apubldswlts
swlight028name=eng2bldswlts

[DISPLAYS]
display001name=spddisplay
display002name=hdgdisplay
display003name=altdisplay
display004name=vsdisplay
display005name=qnhdisplay


Devices used by the inferface, lightswitch and displays, each identified by a name. this named need to be unique in one interface.
and we find a config file by object type to find their definition

Ex 7 segment FCU Displays Config Files

Code: Select all

[SPDDISPLAY]
dispname=SPDDISPLAY
device=LEDPACK1
dispdigit=3
dispcom1=1
dispport=A

[HDGDISPLAY]
dispname=HDGDISPLAY
device=LEDPACK1
dispdigit=3
dispcom1=1
dispport=B

[ALTDISPLAY]
dispname=VSDISPLAY
device=LEDPACK1
dispdigit=5
dispcom1=4
dispport=A

[VSDISPLAY]
dispname=ALTDISPLAY
device=LEDPACK1
dispdigit=5
dispcom1=4
dispport=B

[QNHDISPLAY]
dispname=QNHDISPLAY
device=LEDPACK2
dispdigit=4
dispcom1=5
dispport=B


or dblswitches

Code: Select all

[LOGOLTSW]
switchname=logoltsw
device=IOPACK2
port=A
pin1=6
pin2=7
values=0,1,2
valuestype=int

[DOMELTSW]
switchname=domeltsw
device=IOPACK2
port=A
pin1=3
pin2=4
values=0,0.5,1
valuestype=double


Each elements here is defined by a number of parameter allowing the core class to create automaticly all objects defined.

Ex DomeSwitch Light

Code: Select all

[DOMELTSW]
switchname=domeltsw
device=IOPACK2
port=A
pin1=3
pin2=4
values=0,0.5,1
valuestype=double


So the switch have a name and the section is identified by that name between [ and ] and have to be exact with the one declared in the core config file (intx.cfg)
We found the device that will be use to create the virtual switch, witch port (there is 2 port of 8 bytes on each MCP23017 chip) and physical input pin number to read to determine in wich state the real switch is and then send the data to FG.
Values sent to FG can be tuning using the values and valuestype propreties

In that case, it's a switch for the Dome Light in the A330, that have 3 stable positions, in the fisrt one 0 will be sent, in the middle pos 0.5 and in the upper postion 1 will be sent.

Same way for the light, that not the interface that are reading FG, FG sent his data, which are decoded and apply to each light declared.
Same things for display... values are sent by FG and push to physical display

Code: Select all

[SPDDISPLAY]
dispname=SPDDISPLAY
device=LEDPACK1
dispdigit=3
dispcom1=1
dispport=A


Speed display configuration, the name, the device on which it will be created, the number of digit the, first common pin to use (other digit common pin will be calculate from the number of digit and the first com) and the port to use (HT16K33 can be manage with 16 bits or with 2 ports of 8 bits, i am using this second solution)


Return to “Hardware Development”

Who is online

Users browsing this forum: No registered users and 1 guest