ctytler Posted April 28, 2021 Share Posted April 28, 2021 (edited) I was searching the forums and couldn't find any discussion on how to set up an Arduino board to enable/disable functionality based on Module. So I came up with a method to do so for LEDs and thought I'd share if it's useful to anyone else. Here is an example sketch to set up a Master Caution indicator light for multiple modules for a single LED. It's done with a wrapper around the DcsBios::LED class that can set it active or deactive. Note the code copy/pasted from the Control Reference is modified to be a ModuleLED instead of DcsBios::LED and includes the aircraft module name as the first argument -- this name must match the names used for the modules by the game. You'll also see that "A-10C" and "A-10C_2" are considered different modules so each are there with the same values. #define DCSBIOS_DEFAULT_SERIAL #include <DcsBios.h> constexpr int kPinMasterCautionLed = 15; /// Pin number LED is connected to. // ModuleLED: This is a wrapper around the standard DcsBios::LED that allows // the functionality to only be enabled when the specified module is in use. class ModuleLED : public DcsBios::LED { private: char *moduleName; bool is_active = false; unsigned char pin; public: ModuleLED(char *moduleName, unsigned int address, unsigned int mask, char pin) : moduleName(moduleName), pin(pin), DcsBios::LED(address, mask, pin) {} virtual void loop() { if (is_active) { DcsBios::LED::loop(); } } void set_active_according_to_module(char *newValue) { digitalWrite(pin, LOW); // Turn off by default until turned on again by module. is_active = !strcmp(moduleName, newValue); } }; // Define all LEDs in an array to easily loop through them later. ModuleLED leds[] = { ModuleLED("A-10C", 0x1012, 0x0800, kPinMasterCautionLed), ModuleLED("A-10C_2", 0x1012, 0x0800, kPinMasterCautionLed), ModuleLED("AV8BNA", 0x7860, 0x1000, kPinMasterCautionLed), ModuleLED("FA-18C_hornet", 0x7408, 0x0200, kPinMasterCautionLed), ModuleLED("F-16C_50", 0x4472, 0x0800, kPinMasterCautionLed), ModuleLED("UH-1H", 0x1416, 0x0100, kPinMasterCautionLed), }; // This callback function is called every aircraft change with the module name as newValue. void onAcftNameChange(char *newValue) { const size_t number_of_leds = sizeof(leds) / sizeof((leds)[0]); for (size_t i = 0; i < number_of_leds; i++) { leds[i].set_active_according_to_module(newValue); } } DcsBios::StringBuffer<24> AcftNameBuffer(0x0000, onAcftNameChange); // For reference, these are the copy/paste code snippets as found in // the DCS-BIOS Control Reference that were modified. // DcsBios::LED masterCaution(0x1012, 0x0800, PIN); // From A-10C // DcsBios::LED mcLight(0x7860, 0x1000, PIN); // From AV8BNA // DcsBios::LED masterCautionLt(0x7408, 0x0200, PIN); // From FA-18C // DcsBios::LED lightMasterCaution(0x4472, 0x0800, PIN); // From F-16C // DcsBios::LED masterCautionInd(0x1416, 0x0100, PIN); // From UH-1H void setup() { DcsBios::setup(); } void loop() { DcsBios::loop(); } Edited April 28, 2021 by ctytler Removed unnecessary line from code Link to comment Share on other sites More sharing options...
No1sonuk Posted August 30, 2021 Share Posted August 30, 2021 Why do you have to know which module is running? Why not just call the same light-handling function with the "onChange" function for the modules? e.g. #define DCSBIOS_IRQ_SERIAL #include "DcsBios.h" #define mcLEDpin 13 // Common light function void onMasterCautionChange(unsigned int newValue) { if (newValue > 0) { digitalWrite (mcLEDpin, HIGH); // Turn on LED } else { digitalWrite (mcLEDpin, LOW); // Turn off LED } } // A-10 call DcsBios::IntegerBuffer masterCautionBuffer(0x1012, 0x0800, 11, onMasterCautionChange); // F-16 call DcsBios::IntegerBuffer lightMasterCautionBuffer(0x4476, 0x0080, 7, onMasterCautionChange); // P-51 landing gear red light DcsBios::IntegerBuffer landingGearRedBuffer(0x500e, 0x4000, 14, onMasterCautionChange); void setup() { DcsBios::setup(); } void loop() { DcsBios::loop(); } I just tested that code in a Nano. On the P-51, pressing the Unsafe Landing Gear Light Test turned on the LED. In the same DCS session, with no reset of the arduino, the LED responded to the A-10 Master Caution light. I don't have the F-16, so can't test that, but having the code in there didn't affect anything. You'd obviously need to check for address conflicts, and I may be missing some other issues, but for LEDs at least, it seems to be far less complicated than you make it appear. 2 Link to comment Share on other sites More sharing options...
No1sonuk Posted August 30, 2021 Share Posted August 30, 2021 (edited) Having thought a bit more, I wondered if it works for input too. And it DOES! Added this in: #define mcSWpin 2 // Added at top of code DcsBios::Switch2Pos ufcMasterCaution("UFC_MASTER_CAUTION", mcSWpin); // A-10 Master Caution Switch DcsBios::Switch2Pos unsafeLndGearLtTest("UNSAFE_LND_GEAR_LT_TEST", mcSWpin); // P-51 landing gear red light test switch And now, a single switch on the Nano either activates the P-51 unsafe gear light test or the A-10 Master Caution reset depending on which aircraft you're using. Again, same caveats that there's no conflicts in these functions, but there might be in others. Edited January 16, 2022 by No1sonuk 1 Link to comment Share on other sites More sharing options...
agrasyuk Posted August 30, 2021 Share Posted August 30, 2021 That's a very interesting find. Thanks! Anton. My pit build thread . Simple and cheap UFC project Link to comment Share on other sites More sharing options...
Recommended Posts