Skip to content

curiosity-workshop/XPLDirectArduinoLibrary

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Curiosity Workshop XPLDirect Arduino Library XPLDirect.h - Library for serial interface to Xplane SDK.
  
  Created by Michael Gerlicher, Curiosity Workshop,  September 2020.

  To report problems, download updates and examples, suggest enhancements or get technical support, please visit one of the following:

     discord:  https://discord.gg/gzXetjEST4
     www.patreon.com/curiosityworkshop
     https://www.youtube.com/channel/UCISdHdJIundC-OSVAEPzQIQ
   
   or email me:  flightpro42@gmail.com

  Branded versions of the plugin are available for commercial redistribution, contact me for details.

  Please support this project in one of the following ways:

        Free:  like and subscribe to our youtube channel!
        Support us at patreon.com/curiosityworkshop
        
Known issues:
    
    Arduino Uno with I2c display seems to interfere with serial dialog between the arduino and Xplane.
    Incompatibility with some bluetooth serial port installations

    Remember to close your serial monitor if it is open, it will tie up the serial port and your device won't be found.

** 03/16/2023

   -- Removed variable attachment to commands, it never made sense.  If you were utilizing this you can manually trigger commands with:
            int commandTrigger(int commandHandle);                                  // triggers specified command 1 time;
            int commandTrigger(int commandHandle, int triggerCount);                // triggers specified command triggerCount times.  
            int commandStart(int commandHandle);                                    // Avoid this unless you know what you are doing.  Command "begins" must be balanced with command "ends"
            int commandEnd(int commandHandle);

    -- Bug fixed with commands.  If they were behaving oddly for you it should be fixed.

    -- additional messages have been added to the status screen to indicate the last dataref sent/received and also command interactions

    -- a message has been added to the protocol to indicate that xplane has shut down normally or if the active plane is unloaded.  If xplane restarts or 
        another aircraft is loaded, the plugin will query the XPLDirect devices again.

        This enhances the connectionStatus() function to be more accurate.

            eg:  if (!connectionStatus()) { doShutDownStuff(); }

        A callback feature could be easily added to do stuff in the event xplane sends the message as well.


    -- multiple iterations of a command enabled.  This is mostly for rotary encoder implementation.  
                        
                        int XPLDirect::commandTrigger(int commandHandle, int triggerCount)

        The triggerCount parameter has been there but didn't work due to xplane only allowing one command trigger per cycle. 
        Now if you send a value greater than 1 there is an accumulator that will trigger the command every cycle until the accumulator is back to zero.



** 03/06/2023 
    -- added file "abbreviations.txt" in the plugin directory.  This allows you to use abbreviations for dataref and command names for the purpose of conserving RAM space
        on your arduino device.  For instance if you want to reference the beacon light status with the dataref "sim/cockpit/electrical/beacon_lights_on", 
        use the shorthand term "LTbcn" and the plugin will search the abbreviations file for the shorthand and convert it to the full length name within the plugin.
        Refer to the "abbreviations.txt" file for more information but it comes with the following abbreviation and a few more.  Feel free to add others and send to me
        suggestions for abbreviations that should be included with the distribution version.

           Example from the abbreviations.txt file:     LTbcn = sim/cockpit/electrical/beacon_lights_on

** 02/09/2023 Build 2302091
    -- Added command to xplane "XPLDirect/ResetDevices" so that keys, LUA scripts, etc can request a resynch of the plugin with attached XPLDirect Devices
    -- Some floating point issues have been resolved, and floating point precision increased.
    -- Other bug fixes that have come up
    -- Function added to trigger speech on xplane!           int XPLDirect::sendSpeakMessage(const char* msg)

  This version of the arduino library should be run with plugin build 2106171 or above.

** 12/17/2021 build 2112161
              - Plugin updated to register devices after a plane completely loads.  Some aircraft have custom datarefs 
		associated with them that won't be available until then.

	      - updated menu options to include the ability to log serial data.  Defaults to off and the settings are saved for 
		next launch.  
		
	      - just a note, xplane does not support multiple command activations during one cycle, so
                    int XPLDirect::commandTrigger(int commandHandle, int triggerCount)
		triggerCount causes only one iteration of a command to occur regardless of the number.  I am exploring options
		to deal with this issue.  Let me know if it is important to you.




 ** 6/10/2021 - new function added:  sendResetRequest();
                    eg: Xinterface.sendResetRequest();
                    This causes the plugin to reset and re-query the Xplane/Direct arduino devices.  
 
 ** 5/28/2021  - the plugin now responds to messages from xplane when aircraft are unloaded and reloaded.  This will ask all the XPL/Direct 
                  devices to reset and will re-register all datarefs and commands from them.  This allows for one sketch to work with multiple
                  aircraft, particularly when the aircraft come with custom datarefs.

  ** 5/27/2021  - fixed timeout problem when attempting to register a dataref that doesnt exist.  The registration count will still increase but 
                  processing for the invalid dataref will not occur.  This is useful if you have a sketch that should work with multiple aircraft,
                  some that register custom datarefs and some that don't.

 ** 5/14/2021   - added support for int array datarefs.



 
 Previous Releases:


** 02/01/2021   - Implemented divider for float data being sent to plugin.  
                - Changed format of floats sent to plugin to reduce dataflow
                - Increased buffer size to accomodate string datarefs up to 190 bytes long.
                - plugin menu items changed for disengage/re-engage to only one item that changes depending on status
                - implementation of data types (strings usually).  This only works with data coming from xplane.  It is up to
                    you to confirm your data buffer is large enough to accomodate the length of the strings that you are receiving.
                    Also, the data can't exceed the maximum buffer size -5 (195 bytes)
                - addition of methods hasUpdated(handle) and datarefsUpdated().  
                    int hasUpdated(int handle);     //  returns true if the specified dataref has changed since the last call to hasUpdated().  
                    int datarefsUpdated();          //  returns true if any datarefs have been updated since the last call to datarefsUpdated().
                - update both the plugin and the library for full functionality
** 12/19/2020   - Added support for commandBegin and commandEnd.  Avoid using these unless you are sure of how they work. 
                  commandBegin commands must be balanced with commandEnd or the world will start to wobble.  
                  This can be useful on the poor implentation of commands and datarefs by a notoriously popular 737 simulator plugin.

                  Usage:    commandStart(myCommand);            // triggers a command to begin
                            commandEnd(myCommand);              // ... then end
                
                - And a reminder, if you are defining a command using a variable, use an "int" type, not "long int" or it won't work 
                  quite right.   

                  int myCommand;                    // will be the handle to the command for triggers/begin/end
                  int myCommandVariable;            // will be the variable the library watches for changes to trigger commands.

                  myCommand = registerCommand("sim/radios/nav2_standy_flip", &myCommandVariable);


                - Support added for version control.  The plugin can query the arduino device for the version of the library it was 
                  compiled with to flag incompatibilities.  

                - corrected type on "int" sends to the plugin to be "long int"
                
** 12/16/2020   - Minor bug fixes

** 11/23/2020   - Added support for manual triggering of registered commands.  

                    an function overload was added for command registration if you only plan to trigger it manually:
                    
                            int registerCommand(char *commandName);     // returns handle to command or negative number on error

                    Two new functions were added:

                            int commandTrigger();                   // triggers the command one time
                            int commandTrigger(int triggerCount);   // triggers the command triggerCount times

                    Example:

                        setup
                            int myCommand = Xinterface.registerCommand("sim/radios/nav2_standy_flip", 6);

                        loop

                            Xinterface.commandTrigger(myCommand);

                This could be useful if you need to trigger commands with a rotary encoder or similar device.

                - small change made to reduce data flow when sending integers to the plugin.

** 11/21/2020   - So I put a serial sniffer on the line to monitor communications between the plugin and the library and found a couple places
                  where packets were being sent twice from the plugin, causing potential buffer overflows and other quirks.  
                  I took the opportunity to revamp the rx engine on the library to increase its robustness.  Please update the library and the 
                  plugin to this version, it has tested quite stable by multiple users.  I have a couple other things on my to-do list but I don't 
                  foresee any short-term major changes at this point.  Thank you for your patience!

** 11/20/2020   - Fixed a minor bug with command registration

                - Added support for PROGMEM.  On some boards, this will prevent the names of the datarefs from being transfered into usable RAM.
                  When *many* datarefs are being registered this makes a substantial difference with memory usage.  Some boards (SAM stuff) don't work
                  this way so the #define XPL_USE_PROGMEM will need to be disabled if you have compiler errors, particularly with things like strlen_PF
                  commands in the library.  Disable the #define and all will be better.  As I prefer more elegant solutions, I will work on making
                  this automatic in the future.
                  
                  To use the change, you will need to wrap your dataref registration command names with an F() macro, for example:

                  Xinterface.registerDataRef(F("sim/cockpit/electrical/beacon_lights_on"), XPL_WRITE, 100, 0, &beacon);

                  For now you can use either, but if you are registering many datarefs you will need to use this on older boards.

                - Minor changes made to the plugin, please update it as well.  


** 11/17/2020    - Added registerCommand overload: registerCommand(char *commandname, int datapin);  
                    This links an arduino datapin to a command, just specify which pin and we do the rest of the work!
                 - fixed a minor bug with command registrations

** 11/16/2020    - changed when dataref and command registration takes place.  Xplane loads plugins, then loads aircraft.  Some 
                    aircraft create new datarefs which would not be found by this plugin.  Registration of datarefs now occurs on the 
                    first flight loop.  If I can find a better way to implement this it will be revised.

                 - variable length loop times implemented for busy loops or slower processors.

                        setMinimumLoopTimes(long int loopTimeBeforeRegistration, long int loopTimeAfterRegistration)
                
                    Add this after the "begin()" command to change the time that xloop watches for serial input before returning.

                    "loopTimeBeforeRegistration" is in milliseconds and xloop will stay looping for this time until all datarefs are
                    registered.  This may need to be higher if the plugin is having difficulty with dataref registrations because of 
                    high packet lengths during the registration time, especially if your code is busier.  The default is 1000ms.

                    "loopTimeAfterRegistration" is also in milliseconds and xloop will stay looping for this time after the dataref 
                    registration process is complete.  This can be a smaller value unless your application is receiving large volumes
                    of data from the plugin.  The default is 20ms.

                - removal of all use of String types
                - streamlining of send and receive buffers
               
** 11/08/2020:  - Memory space allocation for datarefs and xplane commands is now dynamic.  This can be good and bad, as it does not
                  watch for low memory situations.  If things begin to act erratically, memory may be the issue.  
                - Support for Xplane commands has now been implemented.
			            Register a command:  registerCommand(command name, *value);   See example XPLDirectCommandDemo for an example.
                - You will need to update the plugin also with this revision.

** 11/02/2020:  - Changes made to frame formatting to save memory, processing time and data stream traffic.
				- Enabled float type for divider parameter when registering datarefs.  
				  For example, now we can assign a divider of .1 if we only want one decimal precision.
                - Problem fixed with data collisions if arduino board begins sending data before all datarefs are registered
                  with the plugin.
                - Fixed a problem sending negative floats from the arduino board since some don't support floats to string buffers.  
                  What a pain!
				- You will need to update the plugin also with this revision.

** 10/31/2020:  Update to correct an issue with registration of array type datarefs.
** 10/27/2020:  Initial Release 10/27/2020


Installation
-------------
Extract the XPLDirect folder and place it into the libraries folder of your arduino sketches


Usage
------


Include the XPLDirect library:

     #include <XPLDirect.h> 

Create an instance, supply the pointer to your serial port:
     
	 XPLDirect Xinterface(&Serial);

Assign variables for the datarefs you plan to register.  X-plane considers int type to include long int.

     long int beacon;

In your 'begin' code section, initialize your serial port and also the interface:

 Serial.begin(XPLDIRECT_BAUDRATE); 
 Xinterface.begin("Xplane Demo");       
 //Xinterface.setMinimumLoopTimes(beforeRegistration, afterRegistration);  // only needed for specific applications.  Defaults are 1000 and 20.

Also in your 'begin' code, register the datarefs you want to use.
   parameters:  

      char * dataref name, the x-plane dataref you wish to register
      int    write type:				XPL_READ to obtain the value of the dataref from xplane
										XPL_WRITE to send the value to xplane
                                      XPL_READWRITE to do both (not really recommended)
      int    update frequency (ms)	how often we should update this dataref, to reduce traffic
      float  update divider			this reduces the precision of data transferred back and forth.  For example,
                                      if you have a tachometer and only need 10rpm resolution, put 10 here.  This
										will reduce the traffic sent between the arduino and the xplane plugin.  
      long int * variable				the variable containing data that will be written to / read from xplane.


 Xinterface.registerDataRef("sim/cockpit/electrical/beacon_lights_on", XPL_READ, 100, 0, &beacon); 

In your 'loop' code, run the xloop routine:
 
 Xinterface.xloop(); 

That's it!  in this example, the variable 'beacon' will automatically update to reflect the status of the beacon lights in x-plane.

registerDataRef is overloaded also with a float version:

     int registerDataRef(const char*, int, unsigned int, int, float*);     

registerDataRef also includes overloads to handle array type datarefs.  The last parameter is the array element to use:

    int registerDataRef(const char*, int, unsigned int, int, long int*, int);       
    int registerDataRef(const char*, int, unsigned int, int, float*, int);           


-- Avoid using delays in your loop as it can create buffer overflows that will cause frame loss.

--Boards with limited memory such as the original uno and nano fill up quickly and can only handle a few datarefs, depending on 
  the additional code in your sketch.  If you are experiencing erratic operation, try reducing the number of datarefs and commands
  you are using.  If you need more datarefs and your board can handle it, modify the header as needed: 
  
  #define XPLDIRECT_MAXDATAREFS_ARDUINO 10
  #define XPLDIRECT_MAXCOMMANDS_ARDUINO 10

  and specify the number of datarefs/commands you are using.  

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages