Interface

Writing a interface plugin for Force Profiler 2.x

Writing a interface plugin is the most complicated plugin you can write for X-sim2. It is a plug’n’play oriented plugin.
You will find two sample source codes. One is based on the velleman serial output to a K8063 interface and one
is a input to a ADC USB interface which also use serial communication. (USB to RS232 adapter onchip)

The code is written in C++ and MFC. You need Visual Studio 2005 or higher in standard edition as minimum.
The free express edition will not work. (no MFC user dialogs included)

You will need good knowledge about your used hardware interface. It is better to write a simple application where you can test your output or input code and then copy that working code to the profiler interface plugin functions.
The goals of a clean interface plugin code:
1. detect a interface automatically on a profiler startup
2. list ALL inputs and outputs in the profiler
3. Read access to all inputs
4. Write to all outputs
5. Write virtually to all outputs and make a synchrony execution code of all outputs at one time
6. Poll the interface if it is disconnected and reduce the number of found interfaces (Plug’n’Play)

Here is a list of the needed exported functions of this type of plugin:
//This are all function that are used by x-sim2 profiler2 interface plugin
//All other function used here are internal functions for the interface
//Used to get information’s about the plugin
//This will return the plugin name
DllInfo GetType(void);
//Returns all found interfaces, if the plugin supports auto detection of more than one interface
//Here you can give the output and input names for one interface
//If there is only one interface used, than this will return only one of 255 possible output definitions
IOsharing GetInterfaceIO(void);
//Returns inputs of a interface, with the parameter is defined which should be readed to reduce processor work
INPUTSTRUCT GetInput(bool inputs[255]);
//Set output of a interface
int SetOutput(int number, unsigned int wert);
//Only gives back the number of controlled interfaces by this plugin
int IsConnected(void);
//Same as output, but set as buffered
int SetVirtualOutput(int number, unsigned int wert);
//Execute all buffered values
int ExecuteVirtual(void);
//Enables needed threads
void EnableThread(bool enable);
//Called after DLL is loaded
void InitDLL(void);
//Opens the setting dialog, if defined
void OpenSettingsDialog(void);

On the profiler2 startup the GetType() function will be called to identify it is a interface plugin through the INPUTSTRUCT structure. There you have to place a short 10 character plugin name which is be displayed in the interface setup test section of the profiler. After the plugin is noticed the DLL will be started with the InitDLL() function where you should place some variable init code. After the init function the EnableThread() function is called which will start and stop your used asynchrony threads. This function is called with true on profiler2 startup and with false on a profiler2 shutdown. Normally all readout or write code should be placed in a thread which updates on a value change. If you like to add a user interface you can use the velleman sourcecode to get a predefined working MFC dialog. The OpenSettingsDialog() function will invoke that dialog if needed (if called in the interface setup section).

Each plugin will offer X-Sim inputs and outputs of a interface. These are called “ports” on a hardware interface. The plugin has to collect information’s about them and manage the input questions or output command calls from the profiler2. The profiler will see only a number of outputs and a number of inputs. The plugin can detect up to 255 of inputs and 255 of outputs of a number of equal hardware interfaces. You can use a interface detection routine which will detect more than one interface, but you have to refer which output of interface x will be a output y to the profiler. For the beginning you should start with one interface and map them to the IOSharing mapping structure.

Single interface plugin
This type of plugin is normally used. Only one interface will be set up with a dialog and this interface will than be displayed in the output or input dialogs of the force-profiler. But if someone likes to use more than one same interface, you must implement a multiple interface detection and add the outputs to the plugin GetInterfaceIO() section. The first step is normally a single interface plugin.

Multi interface plugin
One profiler interface plugin is designed to detect more than one interface and use them if available. They should be automatically displayed in the output or input selection in all the profiler2 selection boxes.
A sample for multiple plugins is the velleman K8055d interface plugin.
pluginmapping

How the input question call works?
A input will be called if needed from the profiler2 application. Therefore it will call the GetInput() function. As parameter there will be a array off 255 bool values which shows you which input is needed. The INPUTSTRUCT must be filled with the interface input port values.
Importand Note: The profiler2 needs every time the whole range of a unsigned integer as result value. If your interface only sopports 8 Bit, you have to multiply your result to a 32 bit unsigned integer size of 0 to 4294967295. In 8 bit case this would be a multiplier of 16777216. If you use a digital port, you have to return more then zero or 4294967295.

How the output commands calls are working?
Outputs are more importand. Therefore the profiler2 is using the SetVirtualOutput() and ExecuteVirtual() funktions. You need also the SetOutput() function for the interface test setup as testing command (implement this first and tryout the calls in the profiler2). With SetOutput() you will immediately switch output ”number” to a value “wert”. The SetVirtualOutput() will store that switch and the ExecuteVirtual() will set all virtual values. This is needed to syncronise all interfaces and outputs in realtime.
Importand Note: The profiler2 provides only whole range of a unsigned integer as output value. If your interface only supports 8 Bit analogue output PWM, you have to devide the incoming profiler value to your maximal output width. In 8 bit case this would be a devider of 16777216. If you use a digital port, you have set the output to HIGH if the profiler value is higher than zero and to LOW if the profiler value reaches zero..

Plug’n’Play with USB and the detection routine
The profiler will ask every 300 ms the IsConnected() function for the number of connected interfaces. If the interface is not detected this is zero. On a multiple interface this could be more than one. If a interface was unplugged and your code noticed that the interface was unplugged, you have to decrease this value. After this the profiler2 will stop its work and unload all plugins followed by a reload and redetection. It will ask the user if a output of a interface was missing. The IsConnected() function must be only a quick variable feedback with fastest response as possible. Insure the calls to a false or not anymore existing port (unplugged port) will not call a “out of array” request in your memory management.


Notes:
-Use your own registry area to store important information’s for redetections.
-User GUI dialogs are multithreaded called, so unsure your code can handle this (volatile variables, critical sections)
-Give your ports name which are unique, for example “Interface XY digital port 1” (the name will be redetected in a profile).
-If you add a plugin for a intelligent interface with only the position data’s, you can use it as “Direct output” which will directly output a math value to the interface.