Gradist Posted August 12, 2021 Posted August 12, 2021 Normally I can search and find the answer pretty well but I'm having trouble finding a clear answer to this. It might just be because I'm new to most of this. I am trying to understand how to use the data from DCS-BIOS in my own code. I have been able to figure out how to get buttons, LED, servo's, etc. to work along with coding in general but I'm stuck. If it helps the current thing I'm trying to figure out is for the Viggen. I've figured out how to toggle the AFK handle, Turn on an LED when it's down, and even have a servo move along with the throttle. (code below) But there are two things I want to add. I want the servo to only move if the AFK lever is down, which is the only time it would move the throttle and it would be nice to add a little bit of delay so that the AFK light comes on when the cockpit light comes on. It seems like there isn't a way to use the actual light, you have to use the AFK handle status which is a little off. My main goal though is to understand the general concept. From the things I've found it seems like there is something with newVal and the map function but I'm missing something. #define DCSBIOS_IRQ_SERIAL #include <Servo.h> #include "DcsBios.h" DcsBios::Switch2Pos afkLever("AFK_LEVER", 4); DcsBios::LED afkLight(0x460e, 0x0400, 5); // Had to rename this one to afkLight to avoid duplicate declaration error DcsBios::ServoOutput throttle(0x4628,3, 544, 2400); void setup() { DcsBios::setup(); } void loop() { DcsBios::loop(); if(pinst) }
No1sonuk Posted August 12, 2021 Posted August 12, 2021 Have a look in the control reference. There's usually the simple option set by default, but a detailed version available by drop-down. I'm not at my PC right now, so I can't be more specific than that. Those advanced options should allow you to get the LED, etc statuses as variables you can use elsewhere, rather than directly using the LED function.
No1sonuk Posted August 12, 2021 Posted August 12, 2021 I'm at home now, so I just searched the control reference of the AJS37 for "AFK". There are about 50 instances in the whole thing, but the one you might be after for the light is this one: Front Panel Lights AFK Enabled Lamp (red)AJS37/AFK_ENABLED_L Output Type: integer Address: 0x4696 Mask: 0x1000 Shift By: 12 Max. Value: 1 Description: 0 if light is off, 1 if light is on void onAfkEnabledLChange(unsigned int newValue) { /* your code here */ } DcsBios::IntegerBuffer afkEnabledLBuffer(0x4696, 0x1000, 12, onAfkEnabledLChange); Or the simple version: DcsBios::LED afkEnabledL(0x4696, 0x1000, PIN); I don't have the Viggen, or any clue about what lights do what, so I suggest you look in the control reference. Switch it to "View: Advanced", with "Category filter: Show all" and text search for AFK with nothing else. Sometimes lights aren't labelled as such, so search as generically as possible.
Gradist Posted August 13, 2021 Author Posted August 13, 2021 Thank you for responding. I was able to find the examples with the "Your code here" but I don't really understand what I can put in there. Is it the code equivalent of the LED coming on? Meaning that whatever code you put in there will run when the state changes? I noticed the name makes it sound like it would run when it changes meaning turn on or off. Is there a way to distinguish which direction or more generally what kind of change? Let me explain a little more about what I am trying to do with the Viggen and that may help. AFK mode is basically an auto throttle for landing, it will physically move the throttle to stay at a proper airspeed for the landing mode selected elsewhere. The typical flow is: Turning AFK Mode ON Mouse Click or use mapped button to lower AFK lever The lever moves down in the cockpit, makes a clicking sound When it is all he way down (about a second) a cockpit light illuminates indicating it is enabled The autopilot takes control of moving the throttle to maintain landing speed. Turning AFK Mode OFF Mouse Click or use mapped button to raise AFK lever The lever moves UP in the cockpit, makes a clicking sound Cockpit light goes out as soon as the lever starts going up The autopilot stops moving the throttle From the code in the OP: DcsBios::Switch2Pos afkLever("AFK_LEVER", 4); The code above is for pin 4 which would be connected to a contact switch that would close when the physical AFK lever is lowered to turn that mode on when desired. When that mode is on a the cockpit light turns on which is picked up by this code which then turns on an LED connected to pin 5 per this code: DcsBios::LED afkLight(0x460e, 0x0400, 5); Independent of all that, this code operates a servo that moves in relation to actual throttle position with the servo being operated by pin 3 DcsBios::ServoOutput throttle(0x4628,3, 544, 2400); I am hoping to use the servo to move the physical throttle but the default behavior is for the servo to always move along with the throttle. I am trying to find some way to disable the servo in normal flight operations so I need to make the servo movement conditional on the AFK mode being on which would be when the pin 4 switch is closed or the LED from pin 5 is is on. (Both of those should always be true at the same time) So if I could use those statements about something like this: if(DcsBios::LED afkLight(0x460e, 0x0400, 5) == on) { DcsBios::ServoOutput throttle(0x4628,3, 544, 2400);} or in simpler terms: if (AFK Light is on) then operate servo That clearly doesn't work but I am assuming there is something correct to fill that in and get the desired result. Thanks again
No1sonuk Posted August 13, 2021 Posted August 13, 2021 52 minutes ago, Gradist said: Thank you for responding. I was able to find the examples with the "Your code here" but I don't really understand what I can put in there. Is it the code equivalent of the LED coming on? Meaning that whatever code you put in there will run when the state changes? I noticed the name makes it sound like it would run when it changes meaning turn on or off. Is there a way to distinguish which direction or more generally what kind of change? Yes. The "Your code here" area is where you put whatever you want to happen when the function is called by the state change. What you then do is put code in there to determine what that change was. So using the example I posted above: void onAfkEnabledLChange(unsigned int newValue) { if (newValue = 1) { // Do this if the change was the light turning on } else { // Do this if the change was the light turning off } } DcsBios::IntegerBuffer afkEnabledLBuffer(0x4696, 0x1000, 12, onAfkEnabledLChange); However, if you want to simply disable a servo when the switch is off, there is a far simpler method: Use a double pole switch for the AFK mode switch... Connect one pole to the arduino to provide the signal. Use the other pole to switch on/off the power line to the servo.
Vinc_Vega Posted August 13, 2021 Posted August 13, 2021 I don't have the Viggen and therefore no DCSBios plugin for that a/c. But why don't you use a variable that is TRUE (logical 1) if the AFK light is on and FALSE (logical 0) if it's off? That variable than can be used in combination with the servo output for the throttle. What I mean is, that the servo can only move if your variable is TRUE. Otherwise the throttle can be moved free. Regards, Vinc Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC]
Gradist Posted August 16, 2021 Author Posted August 16, 2021 On 8/13/2021 at 11:56 AM, No1sonuk said: Yes. The "Your code here" area is where you put whatever you want to happen when the function is called by the state change. What you then do is put code in there to determine what that change was. So using the example I posted above: void onAfkEnabledLChange(unsigned int newValue) { if (newValue = 1) { // Do this if the change was the light turning on } else { // Do this if the change was the light turning off } } DcsBios::IntegerBuffer afkEnabledLBuffer(0x4696, 0x1000, 12, onAfkEnabledLChange); However, if you want to simply disable a servo when the switch is off, there is a far simpler method: Use a double pole switch for the AFK mode switch... Connect one pole to the arduino to provide the signal. Use the other pole to switch on/off the power line to the servo. Thank you, this helped things finally click... so "newValue" is whatever the value that DCS-BIOS is reporting, the number that you can see on the webpage.. I had it in my head that it was the output value of the function which made no sense. I tried the switch idea and it works great, but I'm glad I got the more complete answer so I understand the code part. Thanks again!
Gradist Posted August 16, 2021 Author Posted August 16, 2021 On 8/13/2021 at 11:56 AM, Vinc_Vega said: I don't have the Viggen and therefore no DCSBios plugin for that a/c. But why don't you use a variable that is TRUE (logical 1) if the AFK light is on and FALSE (logical 0) if it's off? That variable than can be used in combination with the servo output for the throttle. What I mean is, that the servo can only move if your variable is TRUE. Otherwise the throttle can be moved free. Regards, Vinc Well that is what I was trying to figure out. No1Sonuk gave a good hardware based solution but I'd love to learn the concept behind this too. I can see how you can set that global variable, just put it in the "Your Code Here" section. But how would you use it? The code that bulls the data isn't in the loop function, it's up at the beginning. Can you use if/then statements there? Seems like I tried it and it didn't work
Vinc_Vega Posted August 16, 2021 Posted August 16, 2021 (edited) You can use these "normal" functions/statements in the DCS BIOS "your code here" like if they were in the Loop. The difference is, that statements in the loop section run from top to down (until the chip is powered off) again and again. In the "your code here" section they only run if an event is triggered, like the change of a state or a switch. If you define a variable before the "your code here" section, it is a global variable, that can be used in the DCS BIOS functions and in the loop as well as in the setup section. If you define a variable within DCS BIOS code, like "new value", it's a private variable and only valid within the same function. Does that make sense to you? Regards, Vinc Edited August 16, 2021 by Vinc_Vega typo correction Regards, Vinc real life: Royal Bavarian Airforce online: VJS-GermanKnights.de [sIGPIC][/sIGPIC]
No1sonuk Posted August 16, 2021 Posted August 16, 2021 (edited) SO... For the exercise, I wrote what I THINK is a software solution: First off, comment out or remove your version of these: DcsBios::ServoOutput throttle(0x4628, PIN, 544, 2400); and DcsBios::LED afkEnabledL(0x4696, 0x1000, PIN); Then put this in, noting what goes where: // Between the stars goes at the top of your code // ************************************ int AutoThrottleEnable = 0 // Global variable to use in enabling the autothrottle servo Servo AutoThrottleServo; // Create the autothrottle servo as an object // DO NOT "attach" it in the setup routine // ********************************* // The rest goes with the othe DCS-Bios functions void onAfkEnabledLChange(unsigned int newValue) { if (newValue = 1) { AutoThrottleEnable = 1; // Turn on autothrottle flag AutoThrottleServo attach(PIN_NO); // Turn on the servo pin } else { AutoThrottleEnable = 0; // Turn off autothrottle flag AutoThrottleServo detach(); // Turn off the servo pin } } DcsBios::IntegerBuffer afkEnabledLBuffer(0x4696, 0x1000, 12, onAfkEnabledLChange); void onThrottleChange(unsigned int newValue) { if (AutoThrottleEnable = 1) //If autothrottle is switched on, run the servo { int throttleServoTime = map(newValue, 0, 65535, 544, 2400); // Map the output value to the servo endstop times servo.writeMicroseconds(throttleServoTime); } else { // Do nothing } } DcsBios::IntegerBuffer throttleBuffer(0x4628, 0xffff, 0, onThrottleChange); Don't forget to change the servo range appropriately. Hopefully, that should work... However, I can't test it. YMMV. EDIT: There may be some missing semicolons... Edited August 16, 2021 by No1sonuk
Recommended Posts