Jump to content

DCS-BIOS Dynamic Mapping based on Aircraft Type Code


Blue73

Recommended Posts

Hello fellow builders, hopefully others may find this useful. This is the code that will enable you to change the control mapping based on the aircraft loaded. I've tested it with my A-10C Fuel Panel which only has a bunch of Switch2's and a couple of POTs, but I've shown how to also use with the other switch types. I've had to add a small member function to all the DCS-BIOS input libraries to gain access to the msg_ private variable.

 

If you want to try Unzip/Copy the attached file to your Arduino DCSBIOS library location, backup up the old one first.

Location: C:\Users\<username>\Documents\Arduino\libraries\dcs-bios-arduino-library-0.2.11\src\internal

 

dcs-bios library dynamic map.zip

 

Sample Code below

 

////////////////////////////////////////////////////
//
//  DCS-BIOS Dynamic Control Mapping based on Aircraft Type
//
//

#define DCSBIOS_IRQ_SERIAL
#include "DcsBios.h"

bool g_bRun = true;    //main loop control

/////////////////////////////////////////////////////////
// Define Control Layout - supports input types Switch2Pos, Switch3Pos, SwitchMultiPos, ActionButton, RotaryEncoder, Potentiometer
//

 /////////////////////////////////
 //  Examples
 // 
 //  DcsBios::Switch2Pos switch2_01("BATTERY_SW", 3);
 //  DcsBios::Switch3Pos switch3_01("BATTERY_SW", 3,4);
 //
 //  const byte pinArray[3] = {3, 4, 5};
 //  DcsBios::SwitchMultiPos switchM_01("BATTERY_SW", pinArray, 3);
 // 
 //  DcsBios::RotaryEncoder enc_01("BATTERY_SW", 3,4);
 //

#define NUMBER_OF_CONTROLS 16

DcsBios::Switch2Pos switch2_01("UNDEF", 14);
DcsBios::Switch2Pos switch2_02("UNDEF", 15);
DcsBios::Switch2Pos switch2_03("UNDEF", 2);
DcsBios::Switch2Pos switch2_04("UNDEF", 3);
DcsBios::Switch2Pos switch2_05("UNDEF", 4);
DcsBios::Switch2Pos switch2_06("UNDEF", 5);
DcsBios::Switch2Pos switch2_07("UNDEF", 12);
DcsBios::Switch2Pos switch2_08("UNDEF", 7);
DcsBios::Switch2Pos switch2_09("UNDEF", 8);
DcsBios::Switch2Pos switch2_10("UNDEF", 18);
DcsBios::Switch2Pos switch2_11("UNDEF", 19);
DcsBios::Switch2Pos switch2_12("UNDEF", 16);
DcsBios::Switch2Pos switch2_13("UNDEF", 17);
DcsBios::Switch2Pos switch2_14("UNDEF", 9);
DcsBios::Potentiometer pot_01("UNDEF", 6);
DcsBios::Potentiometer pot_02("UNDEF", 7);

/////////////////////////////////////////////////////////


struct _controllayout_type
{
   const char *  cntrl_name[NUMBER_OF_CONTROLS];
   
   _controllayout_type(const char *_name[] )
   {
        for (int i = 0; i<NUMBER_OF_CONTROLS; i++ )
         cntrl_name[i] = _name[i];
         
   }
    
   void MakeCurrent()
   {

       /////////////////////////////////
       //  Needs to match the control map objects (DcsBios::#####) defined above
       // 
       
         switch2_01.SetControl(cntrl_name[0]);
         switch2_02.SetControl(cntrl_name[1]);
         switch2_03.SetControl(cntrl_name[2]);
         switch2_04.SetControl(cntrl_name[3]);
         switch2_05.SetControl(cntrl_name[4]);
         switch2_06.SetControl(cntrl_name[5]);
         switch2_07.SetControl(cntrl_name[6]);
         switch2_08.SetControl(cntrl_name[7]);
         switch2_09.SetControl(cntrl_name[8]);
         switch2_10.SetControl(cntrl_name[9]);
         switch2_11.SetControl(cntrl_name[10]);
         switch2_12.SetControl(cntrl_name[11]);
         switch2_13.SetControl(cntrl_name[12]);
         switch2_14.SetControl(cntrl_name[13]);
         pot_01.SetControl(cntrl_name[14]);
         pot_02.SetControl(cntrl_name[15]);
             
   }
};

// Example: Assign A-10 controls
const char *controlnames_A10C[] = { 
   //define all aircraft DCS-BIOS messages including unused controls (e.g. "UNDEF"), needs to have NUMBER_OF_CONTROLS elements
   "FSCP_BOOST_MAIN_L",    //switch2_01
   "FSCP_BOOST_MAIN_R",    //switch2_02
   "FSCP_BOOST_WING_L",    //switch2_03
   "FSCP_BOOST_WING_R",    //switch2_04
   "FSCP_TK_GATE",         //switch2_05
   "FSCP_CROSSFEED",       //switch2_06
   "FSCP_EXT_TANKS_WING",  //switch2_07
   "FSCP_EXT_TANKS_FUS",   //switch2_08
   "FSCP_AMPL",            //switch2_09
   "FSCP_FD_MAIN_L",       //switch2_10
   "FSCP_FD_MAIN_R",       //switch2_11
   "FSCP_FD_WING_L",       //switch2_12
   "FSCP_FD_WING_R",       //switch2_13
   "FSCP_LINE_CHECK",      //switch2_14
   "ALCP_RCVR_LTS",        //pot_01
   "UNDEF_PT_2",           //pot_02
   };
_controllayout_type cl_A10C(controlnames_A10C);

// Example: Assign UH-1H controls
const char *controlnames_UH1H[] = { 
   
   "UNDEF_SW2_01",       //switch2_01
   "UNDEF_SW2_02",       //switch2_02
   "UNDEF_SW2_03",       //switch2_03
   "UNDEF_SW2_04",       //switch2_04
   "UNDEF_SW2_05",       //switch2_05
   "LDG_LIGHT_SW",       //switch2_06
   "UNDEF_SW2_07",       //switch2_07
   "UNDEF_SW2_08",       //switch2_08
   "UNDEF_SW2_09",       //switch2_09
   "ANTICOLL_LTS_SW",    //switch2_10
   "STARTER_GEN_SW",     //switch2_11
   "UNDEF_SW2_12",       //switch2_12
   "UNDEF_SW2_13",       //switch2_13
   "BAT_SW",             //switch2_14
   "BRT_CONSOLE",        //pot_01
   "THROTTLE"            //pot_02
   };
_controllayout_type cl_UH1H(controlnames_UH1H);

//_controllayout_type cl_F18C;

void setup() 
{
  DcsBios::setup();
}

void onAcftNameChange(char* newValue) 
{
   
   g_bRun = false; //signal main loop to skip DcsBios::Loop
   
   delay(500); 
    
   if (!strcmp(newValue, "A-10C"))
   {
      cl_A10C.MakeCurrent();
    }
   else if (!strcmp(newValue, "UH-1H")) 
   {
      cl_UH1H.MakeCurrent();
   }
   else if (!strcmp(newValue, "FA-18C_hornet")) 
   {
      //cl_F18C.MakeCurrent();
   }

    g_bRun = true;
}

DcsBios::StringBuffer<16> AcftNameBuffer(0x0000, onAcftNameChange);

void loop() {

 if ( g_bRun )
 {
   DcsBios::loop();
 }
   
}

cheers

 

John


Edited by Blue73
  • Thanks 1
Link to comment
Share on other sites

Awesome, I was planning on messaging you regarding this after someone have mentioned you had a solution.

 

Thank you for sharing. I am a rookie when it comes to coding so you may be able to shed more light on this but would it be possible to code so that when no plane is loaded it acts as a default joystick?

 

Sent from my SM-G930W8 using Tapatalk

Link to comment
Share on other sites

Thank you for sharing. I am a rookie when it comes to coding so you may be able to shed more light on this but would it be possible to code so that when no plane is loaded it acts as a default joystick?

 

I don't think that would be possible, as each DCS-BIOS script is specific to a singe module. Things like MMJoy and Arduino Joystick library would give you a default / generic joystick, but this is very different to DCS-BIOS.

Link to comment
Share on other sites

Yes very true, for your controls to be seen as joysticks you need it to present as a HID. One method is to use a Leonardo but there are other plug-and-play systems many people use. This is purely using DCS-BIOS which has direct I/O messaging with DCS.

 

cheers

 

John

Link to comment
Share on other sites

Not a problem Marques :)

Absolutely you can use it for TACAN, though currently this only works for input types like switches, rotaries, pots, etc... Any output controls like LEDs or servos aren't supported.

 

cheers

 

John

 

Blue73, this is something that I was hoping for! Thank you very much!

I understand that with this piece of code I can have a TACAN, for example that´d serve for every module that uses it, isn´t it?

Link to comment
Share on other sites

Sounds ok for me. My plan is for having certain panels to be used with VR so no lights, etc involved.

My idea was to have physical panels, such as tacan, vhf, uhf, etc.. that I can relocate to the aproxímate position where I see them in the module I’m flying. That I have already sorted out but my problem was that I’d load the dcs bios code in those arduinos depending on the plane I intended to fly. Sounds like with your code I can avoid that cumbersome step.

Link to comment
Share on other sites

It will apply to your case, if you do have any issues I'm happy to help.

 

cheers

 

John

 

 

Sounds ok for me. My plan is for having certain panels to be used with VR so no lights, etc involved.

My idea was to have physical panels, such as tacan, vhf, uhf, etc.. that I can relocate to the aproxímate position where I see them in the module I’m flying. That I have already sorted out but my problem was that I’d load the dcs bios code in those arduinos depending on the plane I intended to fly. Sounds like with your code I can avoid that cumbersome step.

Link to comment
Share on other sites

  • 8 months later...
Any output controls like LEDs or servos aren't supported.

 

Does anyone know if at any point it would be possible to output controls using this dynamic mapping method? I’m building a desk pit based on an F-18, have a gear lever wired up using DCS-BIOS, and using the gear solenoid with detection of Weight on Wheels. I’ve got this dynamic mapping working for the gear handle operation for the F-18, F-14, F-16, F-5, and M2000 but I’d also like to use the WOW (IntegerBuffer) code so it works with different modules without having to re-upload aircraft specific sketches.

 

Thanks in advance for your help!

 

**EDIT** Ok, so shortly after writing this I think I came up with a solution... I'm still new to DCS-BIOS so didn't realize I could just rename the WOW functions in the aircraft LUA file under DCS.openbeta\Scripts\DCS-BIOS\lib. I appended "VIPER" and "HORNET" to the code to differentiate the WOW functions for both the F-16 and F-18 and tested it out and works fine. I guess it's not ideal but instead of using the code by Blue in my sketch I'm just adding all the functions for each aircraft. So far it's working fine for the gear lever, gear unsafe LED, and the WOW/solenoid output signal for multiple aircraft, so hoping my luck continues for other switches/panels that I plan to build!


Edited by Sickdog
Found solution I think

TM Warthog, Oculus Rift, Win10...

Link to comment
Share on other sites

I've created some code to do basic export of the DED panels and that will hopefully be availablein the DCS-Flightpanel fork of the code soon.

 

It currently only exports the data without formatting like inverse and oversize characters because I haven't found a way to render that on the Arduino fast enough to avoid problems with the data being updated while it's still being written to the screen.

Link to comment
Share on other sites

I've created some code to do basic export of the DED panels and that will hopefully be availablein the DCS-Flightpanel fork of the code soon.

 

It currently only exports the data without formatting like inverse and oversize characters because I haven't found a way to render that on the Arduino fast enough to avoid problems with the data being updated while it's still being written to the screen.

 

Hello, how you read the DED? is it possiple to see the code?

Link to comment
Share on other sites

  • 1 year later...
On 1/31/2019 at 1:19 PM, Blue73 said:

Hello fellow builders, hopefully others may find this useful. This is the code that will enable you to change the control mapping based on the aircraft loaded. I've tested it with my A-10C Fuel Panel which only has a bunch of Switch2's and a couple of POTs, but I've shown how to also use with the other switch types. I've had to add a small member function to all the DCS-BIOS input libraries to gain access to the msg_ private variable.

 

If you want to try Unzip/Copy the attached file to your Arduino DCSBIOS library location, backup up the old one first.

Location: C:\Users\<username>\Documents\Arduino\libraries\dcs-bios-arduino-library-0.2.11\src\internal

 

dcs-bios library dynamic map.zip 3.01 kB · 86 downloads

 

Sample Code below

 

 



////////////////////////////////////////////////////
//
//  DCS-BIOS Dynamic Control Mapping based on Aircraft Type
//
//

#define DCSBIOS_IRQ_SERIAL
#include "DcsBios.h"

bool g_bRun = true;    //main loop control

/////////////////////////////////////////////////////////
// Define Control Layout - supports input types Switch2Pos, Switch3Pos, SwitchMultiPos, ActionButton, RotaryEncoder, Potentiometer
//

 /////////////////////////////////
 //  Examples
 // 
 //  DcsBios::Switch2Pos switch2_01("BATTERY_SW", 3);
 //  DcsBios::Switch3Pos switch3_01("BATTERY_SW", 3,4);
 //
 //  const byte pinArray[3] = {3, 4, 5};
 //  DcsBios::SwitchMultiPos switchM_01("BATTERY_SW", pinArray, 3);
 // 
 //  DcsBios::RotaryEncoder enc_01("BATTERY_SW", 3,4);
 //

#define NUMBER_OF_CONTROLS 16

DcsBios::Switch2Pos switch2_01("UNDEF", 14);
DcsBios::Switch2Pos switch2_02("UNDEF", 15);
DcsBios::Switch2Pos switch2_03("UNDEF", 2);
DcsBios::Switch2Pos switch2_04("UNDEF", 3);
DcsBios::Switch2Pos switch2_05("UNDEF", 4);
DcsBios::Switch2Pos switch2_06("UNDEF", 5);
DcsBios::Switch2Pos switch2_07("UNDEF", 12);
DcsBios::Switch2Pos switch2_08("UNDEF", 7);
DcsBios::Switch2Pos switch2_09("UNDEF", 8);
DcsBios::Switch2Pos switch2_10("UNDEF", 18);
DcsBios::Switch2Pos switch2_11("UNDEF", 19);
DcsBios::Switch2Pos switch2_12("UNDEF", 16);
DcsBios::Switch2Pos switch2_13("UNDEF", 17);
DcsBios::Switch2Pos switch2_14("UNDEF", 9);
DcsBios::Potentiometer pot_01("UNDEF", 6);
DcsBios::Potentiometer pot_02("UNDEF", 7);

/////////////////////////////////////////////////////////


struct _controllayout_type
{
   const char *  cntrl_name[NUMBER_OF_CONTROLS];
   
   _controllayout_type(const char *_name[] )
   {
        for (int i = 0; i<NUMBER_OF_CONTROLS; i++ )
         cntrl_name[i] = _name[i];
         
   }
    
   void MakeCurrent()
   {

       /////////////////////////////////
       //  Needs to match the control map objects (DcsBios::#####) defined above
       // 
       
         switch2_01.SetControl(cntrl_name[0]);
         switch2_02.SetControl(cntrl_name[1]);
         switch2_03.SetControl(cntrl_name[2]);
         switch2_04.SetControl(cntrl_name[3]);
         switch2_05.SetControl(cntrl_name[4]);
         switch2_06.SetControl(cntrl_name[5]);
         switch2_07.SetControl(cntrl_name[6]);
         switch2_08.SetControl(cntrl_name[7]);
         switch2_09.SetControl(cntrl_name[8]);
         switch2_10.SetControl(cntrl_name[9]);
         switch2_11.SetControl(cntrl_name[10]);
         switch2_12.SetControl(cntrl_name[11]);
         switch2_13.SetControl(cntrl_name[12]);
         switch2_14.SetControl(cntrl_name[13]);
         pot_01.SetControl(cntrl_name[14]);
         pot_02.SetControl(cntrl_name[15]);
             
   }
};

// Example: Assign A-10 controls
const char *controlnames_A10C[] = { 
   //define all aircraft DCS-BIOS messages including unused controls (e.g. "UNDEF"), needs to have NUMBER_OF_CONTROLS elements
   "FSCP_BOOST_MAIN_L",    //switch2_01
   "FSCP_BOOST_MAIN_R",    //switch2_02
   "FSCP_BOOST_WING_L",    //switch2_03
   "FSCP_BOOST_WING_R",    //switch2_04
   "FSCP_TK_GATE",         //switch2_05
   "FSCP_CROSSFEED",       //switch2_06
   "FSCP_EXT_TANKS_WING",  //switch2_07
   "FSCP_EXT_TANKS_FUS",   //switch2_08
   "FSCP_AMPL",            //switch2_09
   "FSCP_FD_MAIN_L",       //switch2_10
   "FSCP_FD_MAIN_R",       //switch2_11
   "FSCP_FD_WING_L",       //switch2_12
   "FSCP_FD_WING_R",       //switch2_13
   "FSCP_LINE_CHECK",      //switch2_14
   "ALCP_RCVR_LTS",        //pot_01
   "UNDEF_PT_2",           //pot_02
   };
_controllayout_type cl_A10C(controlnames_A10C);

// Example: Assign UH-1H controls
const char *controlnames_UH1H[] = { 
   
   "UNDEF_SW2_01",       //switch2_01
   "UNDEF_SW2_02",       //switch2_02
   "UNDEF_SW2_03",       //switch2_03
   "UNDEF_SW2_04",       //switch2_04
   "UNDEF_SW2_05",       //switch2_05
   "LDG_LIGHT_SW",       //switch2_06
   "UNDEF_SW2_07",       //switch2_07
   "UNDEF_SW2_08",       //switch2_08
   "UNDEF_SW2_09",       //switch2_09
   "ANTICOLL_LTS_SW",    //switch2_10
   "STARTER_GEN_SW",     //switch2_11
   "UNDEF_SW2_12",       //switch2_12
   "UNDEF_SW2_13",       //switch2_13
   "BAT_SW",             //switch2_14
   "BRT_CONSOLE",        //pot_01
   "THROTTLE"            //pot_02
   };
_controllayout_type cl_UH1H(controlnames_UH1H);

//_controllayout_type cl_F18C;

void setup() 
{
  DcsBios::setup();
}

void onAcftNameChange(char* newValue) 
{
   
   g_bRun = false; //signal main loop to skip DcsBios::Loop
   
   delay(500); 
    
   if (!strcmp(newValue, "A-10C"))
   {
      cl_A10C.MakeCurrent();
    }
   else if (!strcmp(newValue, "UH-1H")) 
   {
      cl_UH1H.MakeCurrent();
   }
   else if (!strcmp(newValue, "FA-18C_hornet")) 
   {
      //cl_F18C.MakeCurrent();
   }

    g_bRun = true;
}

DcsBios::StringBuffer<16> AcftNameBuffer(0x0000, onAcftNameChange);

void loop() {

 if ( g_bRun )
 {
   DcsBios::loop();
 }
   
}
 

cheers

 

John

 

 

@Blue73Appreciate this is an old thread but thanks for the inspiration to create an auto-switching F16 mimic CRUISE page and AJS37 waypoint/CK output/fuel state/alt 16x2 LCD output 😄


Edited by Sideburns

Ryzen 5800x@5Ghz | 96gb DDR4 3200Mhz | Asus Rx6800xt TUF OC | 500Gb OS SSD + 1TB Gaming SSD | Asus VG27AQ | Trackhat clip | VPC WarBRD base | Thrustmaster stick and throttle (Deltasim minijoystick mod).

 

F14 | F16 | AJS37 | F5 | Av8b | FC3 | Mig21 | FW190D9 | Huey

 

Been playing DCS from Flanker 2.0 to present 😄

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...