[go: up one dir, main page]

0% found this document useful (0 votes)
95 views33 pages

Fsbus DLL Manual

FSBus Documentation
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
95 views33 pages

Fsbus DLL Manual

FSBus Documentation
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 33

FSBUS

FSBUS DLL
Programmers
Manual

2008

Version 1.0

Dirk Anderseck
FSBUS DLL

History
08/2008 Change in CheckIn procedure; fsobjects.cpp with all fsuipc
variables added

09/2008 Migration to Microsoft DLL format

09/2008 Variable length dataformat for stepper controller implemented


as a separate type (BTP_V_OUT)

This SDK is posted with the intention that flightsim enthusiasts around the world will
be able to build their own cockpit that are both inexpensive and highly functional.
While the instructions may be printed and followed at no charge, they are not
intended to be used as instructions for starting your own business.

Terms of use
The software and documentation included in the FSBUS DLL is copyrighted by Dirk
Anderseck (dirk@anderseck-net).

Permission is granted to anyone to use this software for any purpose, FSBUS DLL is
free software for non-commercial purpose.

All rights in the Software (including any images or text incorporated into the
Software) are owned by the author of this software, except otherwise stated.

The author of this software does not guarantee that this software is free from bugs
or free from viruses.

The author may, from time to time, revise or update the Software. In so doing, the
author incurs no obligation to furnish such revision or updates to you.

The software is provided “as is” and the author disclaims all other warrenties and
conditions, fitness for a particular purpose, conformance with description, title and
non-infringement of third party rights.

Dirk Anderseck, Erkrath dirk@anderseck.net 2 von 33


FSBUS DLL

Introduction
The FSBUS DLL is a powerfull tool for your home-cockpit. It integrates the flightsim
interface, the FSBUS hardware, the DirectX Sound Mixer, timers and more into an
easy programming API.

You need to define your FSBUS hardware objects and modify the list of the fsuipc
variables, which are predefined for your convinience.

There is room for adding so called offsets of 3rd party software.

I have designed the interface as easy as possible. That’s the reason why the syntax
is classic C-style for console applications.

I have developed the DLL with Microsoft Visual C++ 2008 Express, which is free
available in the internet. The tests were made with Windows Vista and FSX SP2. It
may also work with Windows XP and FS2004.

The FSBUS DLL makes use of fsuipc. According to the license policy of the fsuipc
interface, your selfmade application may require a personal license, which you can
refer over the Internet. It’s up to you to fullfill these license terms.

The FSBUS DLL itself is free for personal usage. If you like it, a small donation is
welcome (please refer to www.fsbus.de ).

Thank you!

Dirk Anderseck, Erkrath dirk@anderseck.net 3 von 33


FSBUS DLL

Files
There is also a “Zero Cockpit” zip file which contains a small cockpit solution ready to
run with Microsoft Visual C++ 2008 tools. This could be a base for any of your
cockpits. You can extract the file into a directory of your choice, start Visual C++ and
open the cockpit.vcproj file.

fsbus.dll The DLL which is loaded, when your exe program starts.

fsbus.lib This file is the interface to the DLL. You will have to add
this file as a resource into your project.

fsbus.h contains all function and dataformat definitions of the


DLL. You will have to include it in any of your C-
programs, which use the fsbus dll.

laser.wav This is a demo sound for the intro1 sample. FSBUS DLL
makes use of Direct Sound.

fsobjects.h Contains all fsuipc variables by name. A unique ID is


assigned. I suggest you copy the lines needed into your
project files and modify the id’s or names.

fsobjects.cpp Contains code to instanciate the objects declared in


fsbus.h. As with the .h file I suggest you copy the lines
needed into your project files.

Dirk Anderseck, Erkrath dirk@anderseck.net 4 von 33


FSBUS DLL

Requirements
• Windows XP, Windows Vista
• Microsoft Flightsimulator 2004, FSX
• fsuipc DLL in Modules folder of Flight Simulator
• Microsoft Visual C++ 2008 Express Edition
• Microsoft Windows SDK

Dirk Anderseck, Erkrath dirk@anderseck.net 5 von 33


FSBUS DLL

Code example Intro1


This example code makes use of a timer object and a sound object. After the timer
expires, the sound object is played.
#include "stdafx.h" The include statements adds definitions to your
#include "fsbus.h"
program.
#define M_MYSOUND 1001
#define T_HEY 1002 Each object needs a name and an ID.

int _tmain(int argc, _TCHAR* argv[]) The main function is the start of a C-program.
{

CheckIn(EventCallback); First, you initialize the DLL by CheckIn function.


FsConnect(); Connect to flightsim
MkSound (M_MYSOUND, "laser.wav");
MkTimer (T_HEY, 1000, FLG_ONESHOT); Create a sound and a timer object.

printf ("press any key to exit ...\r\n");


while (!_kbhit()) Now loop while no key is pressed. In the loop call
FsbusMux(500); FsbusMux for a period of 500ms.
CheckOut();
return 0; The program finishes with CheckOut.
}

void EventCallback(int oid,int val,double dval) This function is called from the DLL at any event.
{
DWORD dw;
The timer T_HEY is fired one time after 1s. The
switch (oid)
{ action to this event is playing the laser sound
case T_HEY: followed by a direct read of the fsuipc version
Play(M_MYSOUND); number.
FsReadDirect(0x3306, 2, &dw);

printf ("FSUIPC Version %d.%d\r\n",


((dw & 0xf000)>>12),
(dw & 0xfff));
break;
case FS_FRAMERATE: Each time the framerate value changes, an event
printf ("FrameRate: %d\r\n",32768/val); with object ID FS_FRAMERATE is generated. It is
break;
} converted and shown on console.
}

Dirk Anderseck, Erkrath dirk@anderseck.net 6 von 33


FSBUS DLL

How to exchange data with Flightsim


Each variable is declared as a software object in the function BuildFsuipcObjects in
file fsobjects.cpp. The names and associated id’s are declared in fsobjects.h.

With these predefined objects you have access to any of the thousands of
parameters inside Flightsim. To access an object, you pass the object ID (oid) to
one the FSBUS DLL functions.

There are two strategies to read a value from flightsim, POLLING and DIRECTREAD.
All frequently used values should be polled automatically by the internal FSBUS DLL
functions.

POLLING of a specific variable is enabled by setting the poll parameter in


fsobjects.cpp to one of the constants FS_NORMAL, FS_LAZY or FS_QUICK.
If you set this parameter to FS_NONE, polling is disabled.

Anyway you can obtain a value from flightsim by calling FsReadDirect(). This should
be used for parameters read once or very few times. Another good choice of
FsReadDirect is, if you read variables with special length or format.

How to obtain a value by polling

Each change of the value is sent as an event to your event callback function. There
are 3 parameters in the callback, the first identifies the source, the second one
contains a converted integer value and the third is the floating point value, which is
valid for fsuipc parameters in 8 byte floating point format.

Example: display a message when the pause status of flightsim changes

// file fsobjects.cpp:
MakeFsObject(FS_PAUSEINDICATOR, 0x0264, 2,TP_UI16, FS_NORMAL);

// code for event handling


void EventCallback (int oid, int value, double dval)
{
switch (oid)
{
case FS_PAUSEINDICATOR:
if (value == 0)
printf (“continue flying\r\n”);
else
printf (“time for coffee\r\n”);
break;
}
}

Dirk Anderseck, Erkrath dirk@anderseck.net 7 von 33


FSBUS DLL

Example: read the objects read buffer, instead of using the converted int “val”.

void EventCallback (int oid, int val, double dval)


{
UVAR *newvar;
UVAR *lastvar;

switch (oid)
{
case FS_PAUSEINDICATOR:
FsGetCompareBuffers (oid, &newvar, &lastvar);

if (newvar->urd.i16 == 0)
printf (“continue flying\r\n”);
else
printf (“time for coffee \r\n”);
break;
}
}

Please look at FsGetCompareBuffers(). You may wonder about a second variable


pointer lastvar. This allows not only to obtain current values, but also the value at
last polltime. Now you can compare two polled values and detect any difference.

This is very usefull for values with a high resolution as the altitude value which
changes very frequently, because the resolution is in some millimeters.

It makes no sense to perform actions on a millimeter base. It only costs cpu time.
With FsGetCompareBuffers() you now have a chance to make your own compare and
probably return without action.

How to obtain a value without polling

Example:
short zoom;
FsReadDirect (0x02b2, 2, &zoom);

The arguments for this function are the fsuipc based offset, the length information
and an address of a variable, where to put the read value.

Dirk Anderseck, Erkrath dirk@anderseck.net 8 von 33


FSBUS DLL

How to exchange data with Fsbus hardware


You need to declare and instanciate each FSBUS object with the function

void MkFsbusObject(FSBUSTYPE ftp, int oid, int c, int r, int flg = 0)

The parameters are:


ftp The type of hardware. The predefined id’s are:

BTP_D_IN Digital Input (keys, buttons, sensors)


BTP_ROTARY Rotary switches
BTP_A_IN Analogue input
BTP_D_OUT Digital output
BTP_DISPLAY 7 segment display
BTP_A_OUT Analogue output

oid The id of this object (1-3999). You may choose your own numbering
scheme.

c Controller ID

r Register in the controller

flg Flags
FLG_DISABLED
FLG_ONESHOT

For each object a unique id is needed.

Example:

#define C_ADF1ROTARY 1001


#define C_NAV1DISPLAY 1002

Each hardware event (button, switch, rotary, pot) is sent as an event to your event
callback function. There is one parameter in the callback, that contains the converted
integer value.

There are some functions to access the FBBUS hardware:

BOOL FsbusWrite(int oid, int val) Send a value to an object with


an object id . The object must
be created before use.

BOOL FsbusWrite(unsigned char* buf, int You can build your own buffer
according to the fsbus
count) software documentation and
send this raw buffer.

Dirk Anderseck, Erkrath dirk@anderseck.net 9 von 33


FSBUS DLL

BOOL FsbusWriteFmt2(int cid, int rid, int val) FSBUS software format has 3
different length of command
blocks.
You can send a 2 byte long
format with this function.

BOOL FsbusWriteFmt3(int cid, int rid, int val) FSBUS software format has 3
different length of command
blocks.
You can send a 3 byte long
format with this function.

BOOL FsbusWriteFmtVar(int cid, int rid, int val) FSBUS software format has 3
different length of command
blocks.
You can send a variable length
format with this function.

Dirk Anderseck, Erkrath dirk@anderseck.net 10 von 33


FSBUS DLL

FSBUS DLL
The FSBUS DLL contains functions and variables. The names and structures are
declared in fsbus.h.

DLL functions

GetFsbusDLLVersion
Syntax int GetFsbusDLLVersion ()

Return Return value is a 3 digit version number of this DLL.

Example int v = GetFsbusDLLVersion ();


printf (“Fsbus DLL version = %d.%d.%d“, v/100, (v/10)%10, v%10);

CheckIn
Syntax BOOL CheckIn (void (*cbEvent)(DObject* po, int v, double d))
This initializes the DLL functions and objects. cbEvent Is a pointer to
a function which receives any event of flightsim, fsbus hardware and
timers.

Return This function will return, if it was success full. If an error occurs
the error function is executed.
Unless you change the default error mode, the application will show a
message and stop execution.

Example void EventCallback (int oid, int v);


int main(int argc, char* argv[])
{
CheckIn(EventCallback);
}
void EventCallback (int oid, int v)
{

}

Dirk Anderseck, Erkrath dirk@anderseck.net 11 von 33


FSBUS DLL

CheckOut
Syntax BOOL CheckOut ();

This should be called before your application exits.

Example int main(int argc, char* argv[])


{

CheckOut();
return 0;
}

FsbusMux
Syntax BOOL FsbusMux (int maxtime);

Return
This is the single multiplexer function, which handles all your defined
objects. Usually you call this function in a permanent loop. In order
to get you a chance to add own code, you define a time in milliseconds.
The function will return after that period.
In the example below, the kbhit function checks for a keyboard action
after the 500ms FSBUS actions are done.

Don’t worry about 500ms actions with full cpu load, the strategy is to
sleep most time. It’s your responsibility to keep your event code as
efficient as possible.

while (!kbhit())
FsbusMux(500);

MakeFsObject
Syntax BOOL MakeFsObject (int id, DWORD offset,int datasz, UTYPE datatp,
FSINTERVAL intvl, int flags);

This function creates an object for the flightsim interface. You do


this by specifing and id, offset and length (fsuipc programmers
manual), a datatype, one of 4 speed classes and optional flags.

Dirk Anderseck, Erkrath dirk@anderseck.net 12 von 33


FSBUS DLL
Parameter Id: a unique id for this object. This will be a systemwide access key
to the new created object.
Offset: this defines the offset in the fsuipc interface.
Datasz: the length of the parameter in byte according to fsuipc
interface. The length is restricted to a maximum of 8 byte. There are
longer variables in fsuipc. These need to be read by FsReadDirect.

Datatp: the type of the data. It is used for a default conversion into
an int32 datatype. Valid types are:
TP_I8, TP_UI8, // signed, unsigned 8Bit vars
TP_I16, TP_UI16, // signed, unsigned 16Bit vars
TP_I32, TP_UI32, // signed, unsigned 32Bit vars
TP_I64, // signed 64Bit vars
TP_DBL // 8Byte floating point vars

Intvl: there are 4 classes to define the poll frequency


FS_NONE, // no polling (reading)
FS_LAZY, // one read in 3s
FS_NORMAL, // one read in 300ms
FS_QUICK // one read in 100ms
( you can change the timing by callung FsSetPollTiming)

The only flag for FS objects is the FLG_DISABLED flag, which turns the
object off until you reenable it.

Return TRUE, if the object was created successfull.

Example
#define F_BUSVOLT 1002
MakeFsObject (F_BUSVOLT, 0x2384,8, TP_DBL, FS_LAZY, 0);

MkFsbusObject
Syntax BOOL MkFsbusObject (FSBUSTYPE ftp, int id, int c, int r, int flg=0);

BTP_D_IN Digital Input on the IO controller


BTP_ROTARY Rotary Input on the IO controller
BTP_A_IN Analogue input on the IO controller
BTP_D_OUT Digital Output on the IO or DO64 controller
BTP_DISPLAY 7 segment display controller
BTP_A_OUT Analogue Output on IO or servo controller
the first channel begins with r = 80, the 8th channel is r = 87
BTP_V_OUT Stepper controller
the first channel begins with r = 80, the 8th channel is r = 87

Dirk Anderseck, Erkrath dirk@anderseck.net 13 von 33


FSBUS DLL
Example #define C_GEARUP 3001
int main(int argc, char* argv[])
{
MkFsbusObject (BTP_D_IN, C_GEARUP, 2, 33);
MkFsbusObject
}

void EventCallback (int oid, int v)


{
switch (oid)
{
case C_GEARUP:
if (v == 0)
{
cout << “GearUp:” << v << endl;
}
break;
}
}

Example 2: Using the FLG_DISABLED flag

MkFsbusObject
MkFsbusObject (BTP_D_IN, C_GEARUP, 2, 33, FLG_DISABLED);

Enable(C_GEARUP
C_GEARUP);
C_GEARUP

MkTimer
Syntax BOOL MkTimer (int id, DWORD tm, int flg);

This function creates a timer. Each timer generates one single or


continuous events. The time is defined in milliseconds and uses the
ordinary windows timing as a base.
For more precise timing in ms range you should use the multimedia
timers of windows.

Return

Example

MkSound
Syntax BOOL MkSound (int id, char* soundfile);
The FSBUS DLL supports the DirectX polyphonic mixer capabilities. A
sound object is created with MkSound.

Return

Example

BCD2Int
Syntax int BCD2Int (unsigned short bcd);
This helper function converts the bcd based dataformat of some fsuipc
varaibles mainly in the navigation area.

Dirk Anderseck, Erkrath dirk@anderseck.net 14 von 33


FSBUS DLL
Return

Example

Keyboard
Syntax void Keyboard (const char* simple);
The FSBUS simple keyformat can generate keycodes for the following keys:

Numeric 0-9
Lowercase alpha a-z
Upercase alpha A-Z
German Umlauts äöüß
Special characters #,.-´<+

Return

Example Keyboard(“A”);

ExtKeyboard
Syntax void ExtKeyboard (const char* complex);
If you need to generate other keys, modifier keys, mouse events or other controls, you’ll
have to use the complex format.

A command in complex format consists of a letter, followed by optional + or – and


parameters. Strings containig more than one command have a semicolon acting as
command separator.

The control characters:

K+ A key down event is pushed on the windows keyboard queue


K- A key up event is pushed on the windows keyboard queue
L+ A left mouse down event is pushed on the windows mouse queue
L- A left mouse up event is pushed on the windows mouse queue
R+ A right mouse down event is pushed on the windows mouse queue
R- A right mouse up event is pushed on the windows mouse queue
D Delay between 2 events

Return

Dirk Anderseck, Erkrath dirk@anderseck.net 15 von 33


FSBUS DLL
Example

K+c Key Down Key = ‘c’


K-c Key Up key = ‘c’
L+30,40 left mouse down X=30 Y=40
L-30,40 Left mouse up X=30 Y=40
R+100,400 Right mouse down X=100 Y=400
R-10,30 Right mouse up X=10 Y=30
D50 Delay 50ms
K+VK_SHIFT;K+c Press Shift key, press ‘c’
K-c; K-VK_SHIFT Release ‘c’, release Shift

List of windows keynames


VK_CANCEL VK_BACK VK_TAB VK_CLEAR
VK_RETURN VK_SHIFT VK_CONTROL VK_MENU
VK_PAUSE VK_ESCAPE VK_SPACE VK_PRIOR
VK_NEXT VK_END VK_HOME VK_LEFT
VK_UP VK_RIGHT VK_DOWN VK_LCONTROL
VK_RCONTROL VK_LMENU VK_RMENU VK_SELECT
VK_PRINT VK_EXECUTE VK_INSERT VK_DELETE
VK_HELP VK_LWIN VK_RWIN VK_APPS
VK_SNAPSHOT VK_SLEEP
VK_NUMPAD0 - VK_NUMPAD9
VK_MULTIPLY VK_ADD VK_SEPARATOR VK_SUBTRACT
VK_DECIMAL VK_DIVIDE VK_NUMLOCK VK_SCROLL
VK_F1 - VK_F24
VK_OEM_NEC_EQUAL VK_LSHIFT VK_RSHIFT VK_BROWSER_BACK
VK_BROWSER_FORWARD VK_BROWSER_REFRESH VK_BROWSER_STOP VK_BROWSER_SEARCH
VK_BROWSER_FAVORITES VK_BROWSER_HOME VK_VOLUME_MUTE VK_VOLUME_DOWN
VK_VOLUME_UP VK_MEDIA_NEXT_TRACK VK_MEDIA_PREV_TRACK VK_MEDIA_STOP
VK_MEDIA_PLAY_PAUSE VK_LAUNCH_MAIL VK_LAUNCH_MEDIA_SELECT VK_LAUNCH_APP1
VK_LAUNCH_APP2 VK_OEM_1 VK_OEM_PLUS VK_OEM_COMMA
VK_OEM_MINUS VK_OEM_PERIOD VK_OEM_2 VK_OEM_3
VK_OEM_4 VK_OEM_5 VK_OEM_6 VK_OEM_7
VK_OEM_8 VK_OEM_AX VK_OEM_102 VK_ICO_HELP
VK_ICO_00 VK_PROCESSKEY VK_ICO_CLEAR VK_PACKET
VK_OEM_RESET VK_OEM_JUMP VK_OEM_PA1 VK_OEM_PA2
VK_OEM_PA3 VK_OEM_WSCTRL VK_OEM_CUSEL VK_OEM_ATTN
VK_OEM_FINISH VK_OEM_COPY VK_OEM_AUTO VK_OEM_ENLW
VK_OEM_BACKTAB VK_ATTN VK_CRSEL VK_EXSEL
VK_EREOF VK_PLAY VK_ZOOM VK_NONAME
VK_PA1 VK_OEM_CLEAR VK_CAPITAL VK_KANA
VK_HANGUL VK_JUNJA VK_FINAL VK_HANJA
VK_KANJI VK_CONVERT VK_NONCONVERT VK_ACCEPT
VK_MODECHANGE

Dirk Anderseck, Erkrath dirk@anderseck.net 16 von 33


FSBUS DLL

FsConnect
Syntax BOOL FsConnect ();
Connects the object to fsuipc. Flightsim must be started before executing FsConnect.

Return

Example

FsDisconnect
Syntax BOOL FsDisconnect ();
Disconnects the object from fsuipc.

Return

Example

FsReadDirect
Syntax BOOL FsReadDirect (int offset, int sz, void* dest)

You can read any offset in fsuipc without declaring an object with the FsReadDirect function.

If you are reading hundreds of variables, FsReadDirect is less efficient.


Use the polling method whenever possible. ReadDirect is useful if you read a value only once
(Versionnumber, …) or if you need to read an exceptional dataformat.

Return

Example short zoom;


FsReadDirect (0x02b2, 2, &zoom);

FsWriteDirect
Syntax BOOL FsWriteDirect (int offset, int sz, void* dest)

Updating a variable in flightsim is usually done in the poll procedure.


If you like to write something to flightsim, which you haven’t declared as an object,
FsWriteDirect is your choice.

Return

Example short zoom = 100;


FsWriteDirect (0x02b2, 2, &zoom);

Dirk Anderseck, Erkrath dirk@anderseck.net 17 von 33


FSBUS DLL

FsWrite
Syntax BOOL FsWrite (int oid, int )
BOOL FsWrite (int oid, double)
BOOL FsWrite (int oid, __int64)
BOOL FsWrite (int oid, UVAR )

This is a write function to send an integer value to a flightsim object.


The update occurs during the next poll sequence.

Return

Example

FsSetPollTiming
Syntax BOOL FsSetPollTiming (int quick, int normal, int lazy)

Any created DFsObject is assigned a poll class . The class determines the pollfrequency.
There are 4 classes defined:
None (no polling)
Lazy (3s)
Normal (300ms)
Fast (100ms)

You can modifiy these times with SetPollTiming.

Example FsSetPollTiming (50, 500, 5000);

FsbusOpen
Syntax BOOL FsbusOpen (LPSTR dev);
Open the serial interface. Dev is one of the predefined device names
like “COM1” “COM2” a.s.o.

If FsbusOpen fails, an exception is thrown with a text message, which


probably shows a reason.

Example try
{
CheckIn(EventCallback, EventCompare);
FsbusOpen("COM1");
}
catch (LPSTR text)
{
cout << text << endl;
}

FsbusClose
Syntax BOOL FsbusClose();
Close the serial interface.

Example FsbusClose();

Dirk Anderseck, Erkrath dirk@anderseck.net 18 von 33


FSBUS DLL

FsbusWrite
Syntax BOOL FsbusWrite (int oid, int val);

FsbusWrite is used to send a value to an fbus object.

Example FsbusWrite (C_VOR1, 110500);

FsbusWrite
Syntax BOOL FsbusWrite(unsigned char* buf, int count);
Usually, you send a command to one of your cockpit controls by
FsbusWrite(int oid, int val).
FsbusWrite is a generic function to build and send a command buffer by
yourself. Please refer to the software interface description at the end
of this book.

Example Send a reset command as broadcast to each controller.


char buf[2]; // declare a 2 byte buffer
buf[0] = 0x81; // Bit 2^7 is always 1. 2^0 is the first value bit
buf[1] = 128; // 128 is the R-Command Reset
FsbusWrite (buf, 2);

You can also send this command with FsbusWriteFmt2()

FsbusWriteFmt2
Syntax BOOL FsbusWriteFmt2(int cid, int rid, int val);
This is another way to send a command to an fsbus controller. All 2
byte long commands can be sent with this function.

Example Send a reset command as broadcast to each controller.


FsbusWriteFmt2 (0, 128, 1);

FsbusWriteFmt3
Syntax BOOL FsbusWriteFmt3(int cid, int rid, int val);
This is another way to send a command to an fsbus controller. All 3
byte long commands can be sent with this function.

Example Send the voltage information (80%) to all controllers with command 131.
FsWriteFmt3 (0, 131, 80);

FsbusWriteFmtVar
Syntax BOOL FsbusWriteFmtVar(int cid, int rid, int val);
This Write function sends a variable length data format to controllers
which require longer data formats like stepper controller.

Dirk Anderseck, Erkrath dirk@anderseck.net 19 von 33


FSBUS DLL

Example

DisplayOptions
Syntax BOOL DisplayOptions (int oid, int SegCount, int SegOffs, bool
LeadZero, int DecPoint);
Display Options sets some paramters to a 7 segment display controller.
The number of segment can vary between 3 and 6, the offset parameter is
a shift of the display start. If you want leading zeros, set LeadZero
to TRUE, The DecPoint controls the position of decimal point, where the
value zero means no decimal point.

Example

Dirk Anderseck, Erkrath dirk@anderseck.net 20 von 33


FSBUS DLL

Error Handling
There are 3 different modes to deal with errors. The error mode is defined by the
internal variable “ErrorMode” which is of type ERRORMODE. It is declared in fsbus.h.

The possible values are EM_STOPEXECUTION (default), EM_RESUMERETURN,


EM_THROWEXCEPTION.

The default (EM_STOPEXECUTION) will show an error message on the console and
after a keypress, the application exits. This suites the needs of most applications.

If you like to handle all errors by yourself, you can set ErrorMode =
EM_RESUMERETURN. In this case, the error text is not shown on console, but copied
into the variable ErrorText. The function which caused the failure will return with
FALSE (if it is one of the BOOL ... functions) and you can code your own error
handling.

Own error handling may be usefull, if you want to control the initialization phase.
One example might be waiting for the flightsim until it has started.

Example code:

ErrorMode = EM_RESUMERETURN;

int retry;

for (retry=0; retry < 5; retry ++)


{
If (FsConnect() == TRUE)
break;
Sleep (5000);
}

if (retry >= 5)
{
printf (“cannot open flightsim\r\n”);
exit (1);
}
ErrorMode = EM_STOPEXECUTION; // continue with default error mode

People writing C++ application frequently use a throw/catch mode to handle errors.
If you want the DLL to throw an exception, set ErrorMode = EM_THROWEXCEPTION.
On error it will throw an exception with one argument of type LPSTR.

Dirk Anderseck, Erkrath dirk@anderseck.net 21 von 33


FSBUS DLL

Make your own cockpit software


It is easy to begin developing your own cockpit software. The cockpit.zip contains all
files for a Visual C++ 2008 Express Edition project. You can extract the files into an
empty directory, start Visual C++ 2008 Express Edition and open tan existing project
(cockpit.vcproj) in this directory.

This project still contains some code for real cockpit implementations. Just look at
gauges.cpp, gauges.h and get an idea how you can extend that. It is also a
recommendation how to deal with more than one sourcecode file.

Now i will describe the steps to make a new throttle group by copying the gauges
example files.

Copy gauges.h an rename the copy to throttle.h


In Project Explorer, right-click headerfiles and add this file as an existing element to
the project.

Copy gauges.cpp an rename the copy to throttle.cpp


In Project Explorer, right-click sourcefiles and add this file as an existing element to
the project.

Edit the throttle.h file and modify it. It should look loke this:

#ifndef __THROTTLE_H
#define __THROTTLE_H

#define OID_THROTTTLE_GROUP (5 << OID_CONTROL_BITS)

#define FS_ENGINE1_THROTTLE_CONTROL OID_THROTTLE_GROUP+0


#define C_THROTTLE_LEVER_LEFT OID_THROTTLE_GROUP+1

void BuildThrottleObjects();
void cbThrottle (int oid, int val, double dval);

#endif

The important things are the new unique group id 5 and the associated name
OID_THROTTTLE_GROUP. There is one object to control the flightsim and an analogue
input (potentiometer) to receive the input. And as usual the definition of the
functions in throttle.cpp.

Now you modify the throttle.cpp file:

#include "stdafx.h"

void BuildThrottleObjects ()
{
MakeFsObject(FS_ENGINE1_THROTTLE_CONTROL, 0x089A, 2,TP_I16,
FS_NONE);
MkFsbusObject (BTP_A_IN, C_THROTTLE_LEVER_LEFT, 2, 70);
Dirk Anderseck, Erkrath dirk@anderseck.net 22 von 33
FSBUS DLL
}

void cbThrottle (int oid, int val, double dval)


{
switch (oid)
{
case C_THROTTLE_LEVER_LEFT:
FsWrite (FS_ENGINE1_THROTTLE_CONTROL, val * 64);
break;
}
}

We see the code to create both objects and the function which receives the throttle
movement events. Of coarse you have to modify the CID and RID to your cockpit
hardware address. The cbThrottle callback function will receive a value from 0 to
255 depending on the lever position. Each new value is sent immediatly to flightsim
by FsWrite. Since the fsuipc expects a value from 0 to 16384, we have to multiply val
by 64.

The first line includes the stdafx.h file. It contains the include statements of all our
selfmade groups. We have to manually add the last lines.
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>

#include "fsbus.h"

#include "gauges.h"
#include "planectrl.h"
#include "llswitchboard.h"
#include "throttle.h"

Last not least, the main callback function in cockpit.cpp is modified. It now contains
code to dispatch all events of the throttle group to our cbThrottle function:

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])


{
CheckIn(EventCallback);
FsbusOpen("COM7");

BuildGaugesObjects();
BuildPlaneControlObjects();
BuildLLSwitchboardObjects ();
BuildThrottleObjects ();
FsConnect();
while (!_kbhit())
FsbusMux(500);
}

void EventCallback (int oid, int val, double dval)


{
switch (oid & OID_GROUP_MASK)
{
Dirk Anderseck, Erkrath dirk@anderseck.net 23 von 33
FSBUS DLL
case OID_GAUGES_GROUP:
cbGauges (oid, val, dval);
break;
case OID_PLANECTRL_GROUP:
cbPlaneCtrl (oid, val, dval);
break;
case OID_PLANECTRL_GROUP2:
cbPlaneCtrl2 (oid, val, dval);
break;
case OID_LLSWITCHBOARD_GROUP:
cbLLSwitchboard (oid, val, dval);
break;
case OID_THROTTLE_GROUP:
cbThrottle (oid, val, dval);
break;
}
}

Once you are familiar with this scheme, you can adopt these procedures for any
group of your cockpit.

Dirk Anderseck, Erkrath dirk@anderseck.net 24 von 33


FSBUS DLL

Names and OID’s


Let’s discuss the object names and object id’s. There is an example file fsobjects.h,
which has defined all fsuipc objects predefined. The names are ordinary C macro
names with prefix “FS_” .

I made a design decision and reduced the number of objects, fsbus objects +
flightsim objects, to a maximum amout of 4096. This is due to performance issues.
Each object is accessed by an object id (OID). Accessing the objects is very
frequently done during runtime and a table in memory with 4096 slots is by far the
most quickest way to get a pointer to the objects.

The names for each object are C-macro names. All names and id’s are defined in .h
files.

If we are dealing with 10 or 100 objects, it’s easy to put all into a single file, but i
think our cockpit solutions are somewhat larger than 100.

I recommend grouping the objects into functional units and giving each unit or group
it’s own unique id. Please compare this to the ip addresses, where the network part
and computer part of the address are also mixed into a 4 byte ip address.

Our addressing scheme of the OID’s is as follows:

11 10 9 8 7 6 5 4 3 2 1 0

With 12 bit we can address 4096 different objects. Bits 0-4 allows us to define 32
objects per group.
Bits 5-11 allows to build 128 groups.

Guidelines

• Make individual files (.cpp sourcefile and .h include file) per group

• Add a unique group id in each of your .h files


#define OID_THROTTTLE_GROUP (5 << OID_CONTROL_BITS)

• Add a function to create all objects concerning a group


void BuildThrottleObjects();

• Add a function to receive all events of a group


void cbThrottle (int oid, int val, double dval);

• Insert the include statement into stdafx.h


#include "throttle.h"

• All definitions of flightsim variables can be copied out of fsobjects.h


Dirk Anderseck, Erkrath dirk@anderseck.net 25 von 33
FSBUS DLL

• All creation code of flightsim variables can be copied out of fsobjects.cpp


• All definition and code for your cockpit variables have to be written manually

Dirk Anderseck, Erkrath dirk@anderseck.net 26 von 33


FSBUS DLL

Application Notes

Emulated Power Control

Nearly every component of a real cockpit is driven by electric power. During flight the
power is supplied by one or more generators and a small battery is used to start the
engines and provide basic power during startup phase.
The FSBUS controllers have a builtin feature to emulate power up and down. It is
sent with a RID of 131.

The example below reads the battery value from flightsim via offset 0x2834. This
value ranges from 0 to 24 and is read from fsuipc as a double value. FSBUS supports
a percentage value, which is calculated by multiplying 100 and dividing 24. The
system route is used to send this value to any attached controller.

void EventCallback (int oid, int val)


{
switch (oid)
{
case F_BUSVOLT:
// send the voltage information as a percent value
// to all controllers with command 131.
FsWriteFmt3 (0, 131, val * 100 / 24 );
}
}

Dirk Anderseck, Erkrath dirk@anderseck.net 27 von 33


FSBUS DLL

FSBUS dataformat
This chapter describes the dataformat for FSBUS hardware controllers. The hardware
parameters for serial communication is 19200bps, 8bit, no parity, 2 stop bit. Usually
you haven’t to deal with this format, because the Fsbus Object in the DLL does the
conversion.
The normal way of sending data to a piece of hardware is:
FsWrite (C_NAVDISPLAY, 11375);

If you like to do something special, like sending data as a broadcast to all controllers,
the following dataformat description and a couple of function will help you doing so.

Data from FSBUS Router to Controller


The 5 C bit determine the CID. Up to 31 controllers can be addressed with 5 bit.
There are 2 exceptions to the rule.
If C=0 then the sent data is interpreted by any controller (broadcast).
If C=31 then the dataframe is sent with an extended address format. This is a future
solution for cockpits with more than 30 controller.

The 8 bit value R determines the command.

A value may have different length and format. A general format is shown in the table
below. Value bits (V) are marked grey.

Byte 7 6 5 4 3 2 1 0
1 1 C4 C3 C2 C1 C0 R7 V0
2 0 R6 R5 R4 R3 R2 R1 R0
3 0 V7 V6 V5 V4 V3 V2 V1
4 0 V14 V13 V12 V11 V10 V9 V8
5 0 V21 V20 V19 V18 V17 V16 V15
6 0 V28 V27 V26 V25 V24 V23 V22

Data sent by IO Controller to FSBUS Router


The key controller of the IO board is organized by 1 to 8 rows, each with 8 bit
corresponding to a switch.
The keycontroller requires a setup before use. That setup function defines the
keytype of specific input lines.
If a change on any key is detected by a controller, an absolute key value is sent, or
in case of rotaries a relative value is sent to FSBUS Router.

Dirk Anderseck, Erkrath dirk@anderseck.net 28 von 33


FSBUS DLL

Byte 7 6 5 4 3 2 1 0
1 1 C4 C3 C2 C1 C0 R7 V0
2 0 R6 R5 R4 R3 R2 R1 R0
3 0 V7 V6 V5 V4 V3 V2 V1

C0-4 CID of the controller, which sent this dataframe


R0-7 the number is calculated by row * 8 + bit, at which a change was detected
V0-7 a signed value of the key state

Common R-Commands

all commonly used R-commands are numbered between 128 and 255.

R Name L
128 Reset 2 0: Reset controller without
displaying the CID
1: Reset controller and display
the CID after reboot

129 SetCID 3 Parameter is the CID (Bit0-4),


which is stored in eeprom.
For safeteness, this command needs
to be sent 3 times in sequence.
Bit5-7 counts the sequence (0,1,2).

130 SetBright 3 Setup brightness 0 (dark) –


255(bright)

131 SetPower 3 This command simulates the battery


state. A value from 0(battery
empty) to 100(full) is supported.
Usually the controllers will
shutdown below a value of 80.

132 SetDecimalPoint 3 Position of decimal point. A value


of 0 turns off the decimal point. 1
is the right most position.

133 SetBaseBright 3 Setup the controller individual


brightness value, stored in
internally eeprom.

Dirk Anderseck, Erkrath dirk@anderseck.net 29 von 33


FSBUS DLL

R-Commands for IO Controller

Except the display format, any IO controller uses this multi purpose data format.
R Name L to fsbus router to controller
0-7 Key R0 3 Keyvalue setup keytype
bit 0-7
8-15 Key R1 3 Keyvalue setup keytype

16-23 Key R2 3 Keyvalue setup keytype

24-31 Key R3 3 Keyvalue setup keytype

32-39 Key R4 3 Keyvalue setup keytype

40-47 Key R5 3 Keyvalue setup keytype

48-55 Key R6 3 Keyvalue setup keytype

56-63 Key R7 3 Keyvalue setup keytype

72-79 A-In 3 analogue value tolerance of analogue input


0-7
80-87 A Out 0-7 3 value of analogue out

88-95 D-Out 0: 0- 2 value of a digital output bit


7 on port 0

96-103 D-Out 1: 0- 2 value of a digital output bit


7 on port 1

104-111 D-Out 2: 0- 2 value of a digital output bit


7 on port 2

112-119 D-Out 3: 0- 2 value of a digital output bit


7 on port 3

120 D-Outbyte 0 3 value of a digital output port


0

121 D-Outbyte 1 3 value of a digital output port


1

122 D-Outbyte 2 3 value of a digital output port


2

123 D-Outbyte 3 3 value of a digital output port


3

124 A-In Mask 3 mask of mask of analogue input pins in


analogue input use.
pins in use.

125 A-Out Mask 3 mask of mask of analogue output pins in


analogue output use
pins in use

128-135 A-Tolerance 3 tolerance of


analogue input

136-155 DDP area 3 Device Device dependent setup


dependent parameters
parameters

200-207 D-Out 4: 0- 2 value of a digital output bit


Dirk Anderseck, Erkrath dirk@anderseck.net 30 von 33
FSBUS DLL
7 on port 4

208-215 D-Out 5: 0- 2 value of a digital output bit


7 on port 5

216-223 D-Out 6: 0- 2 value of a digital output bit


7 on port 6

224-231 D-Out 7: 0- 2 value of a digital output bit


7 on port 7

232 D-Outbyte 4 3 value of a digital output port


4

233 D-Outbyte 5 3 value of a digital output port


5

234 D-Outbyte 6 3 value of a digital output port


6

235 D-Outbyte 7 3 value of a digital output port


7

255 Init 3 The controller


was new
startet.
Parameter is
the version
number

Dirk Anderseck, Erkrath dirk@anderseck.net 31 von 33


FSBUS DLL

Display Controller
the display controllers display values are in a special format. It is detected by a 0 in
bit 1 of byte 0.
Each segment value is transmitted as a 4bit nibble. The dataformat has variable
length. The final byte is detected by a 1 in bit 6 of the last byte.

Byte 7 6 5 4 3 2 1 0
0 1 C4 C3 C2 C1 C0 0 x
1 0 0 A3 A2 B3 B2 B1 B0
2 0 0 A1 A0 C3 C2 C1 C0
3 0 0 D3 D2 E3 E2 E1 E0
4 0 1 D1 D0 F3 F2 F1 F0

C0-4 Controller ID
A,B,C,D,E,F nibbles for max. 6 segments

The order of the segments is from left to right: F E D C B A

The decimal point is defined by a R-Command 132. The value defines the position of
decimal point:

F E D C B A
6 5 4 3 2 1

One nibble (4Bit) can show 16 different characters:

Wert Anzeige Wert Anzeige


0 0 8 8
1 1 9 9
2 2 A -
3 3 B S
4 4 C t
5 5 D d
6 6 E E
7 7 F

Dirk Anderseck, Erkrath dirk@anderseck.net 32 von 33


FSBUS DLL

More than 30 controllers


Some years ago, when fsbus was designed, i never thought about needs for more
than 30 controllers. But there are requests for it.

The CID 31 is now reserved for longer CID values

Byte 7 6 5 4 3 2 1 0
1 1 1 1 1 1 1 R7 V0
2 0 C6 C5 C4 C3 C2 C1 C0
3 0 R6 R5 R4 R3 R2 R1 R0
4 0 V7 V6 V5 V4 V3 V2 V1
5 0 V14 V13 V12 V11 V10 V9 V8
6 0 V21 V20 V19 V18 V17 V16 V15
7 0 V28 V27 V26 V25 V24 V23 V22

This format is now able to support 30 + 128 CID’s. There must be an updated
firmware for the controllers.

Dirk Anderseck, Erkrath dirk@anderseck.net 33 von 33

You might also like