DCS-Skunkworks / dcs-bios-arduino-library

A library designed to run on Arduinos and similar microcontrollers and communicate with DCS-BIOS.
MIT License
61 stars 25 forks source link

F/A-18 AoA Indexer Brightness Control not functioning correctly #74

Closed kbastronomics closed 3 months ago

kbastronomics commented 3 months ago

Version

Aircraft

F/A-18C

Control

HUD_AOA_INDEXER

Description

the HUD_AOA_INDEXER which controls the brightness of the AoA Index does not correctly represent the the brightness. when properly coded it will show as off from 0 to approximately 62% then the brightness works from 62%-100%.

the brightness on my indexer also reflect about 62% then jumps to OFF.

a look at BORT for the control appears correct.

Steps to reproduce

  1. start any instant action, i use free flight
  2. bring aircraft to landing speed, lower hook, gear and set flaps.
  3. trim for AoA
  4. adjust AoA Indexer Control up/down

Expected behavior

as the AoA indexer control is adjusted from full on to off the indexer should follow in brightness.

Screenshots

https://github.com/user-attachments/assets/b8c248e6-051b-4b02-bbf6-f1c671e3e22c

Additional context

see discord from discussion and details here https://discordapp.com/channels/533342958712258572/535008796536340480/1273959366969659557 https://discordapp.com/channels/533342958712258572/535008796536340480/1274110819516420116 https://discordapp.com/channels/533342958712258572/535008796536340480/1274738017386364940

in my testing i validate that my code does function outside of DCS, video in discord link above i then changed the control from the AoA indexer to using the Internal Lights controll. doing do the Index works correctly

i'll including my full (though needs cleanup from all the testing) control, I use the AdaFruit Trinket M0 and Adafruit 5mm RGB LEDS in my AoA Indexer.

kbastronomics commented 3 months ago

Looks like I can not attach a 'c' file.

here's the main part of the code that's not working

void onHudAoaIndexerChange(unsigned int newValue) {
  brightness = map(newValue,0,65535,0,255);
  FastLED.setBrightness(brightness);
  FastLED.show();
}
DcsBios::IntegerBuffer hudAoaIndexerBuffer(0x745e, 0xffff, 0, onHudAoaIndexerChange);

and using the INST Lights that does work

void onInstPnlDimmerChange(unsigned int newValue) {
  brightness = map(newValue,0,65535,0,255);
  FastLED.setBrightness(brightness);
  FastLED.show();
}
DcsBios::IntegerBuffer instPnlDimmerBuffer(0x7546, 0xffff, 0, onInstPnlDimmerChange);
charliefoxtwo commented 3 months ago

I can take a look, but if bort is showing the correct data then it sounds like bios is working correctly and any error is either at the arduino or arduino library level.

kbastronomics commented 3 months ago

it could be the arduino library yes, i've rules out my code as the issue though

kbastronomics commented 3 months ago

on the Arduino Library side DcsBios::IntegerBuffer hudAoaIndexerBuffer(0x745e, 0xffff, 0, onHudAoaIndexerChange); fails DcsBios::IntegerBuffer instPnlDimmerBuffer(0x7546, 0xffff, 0, onInstPnlDimmerChange); works

that tends to point that given the same call the library is not suspect but the data being passed to it is

charliefoxtwo commented 3 months ago

HUD_AOA_INDEXER appears correct on the dcs-bios side. I logged the value being output within dcs-bios from 100%-0%-100% and noticed no abnormalities in the data from dcs or the data we export

2024-08-24 11:27:31  INFO   raw: 0.6546630859375
2024-08-24 11:27:31  INFO   exported: 41919
2024-08-24 11:27:31  INFO   raw: 0.6396484375
2024-08-24 11:27:31  INFO   exported: 40935
2024-08-24 11:27:31  INFO   raw: 0.6246337890625
2024-08-24 11:27:31  INFO   exported: 39951
2024-08-24 11:27:31  INFO   raw: 0.609619140625
2024-08-24 11:27:31  INFO   exported: 38967
2024-08-24 11:27:31  INFO   raw: 0.5946044921875
2024-08-24 11:27:31  INFO   exported: 38967
2024-08-24 11:27:31  INFO   raw: 0.5946044921875
2024-08-24 11:27:31  INFO   exported: 37983
2024-08-24 11:27:31  INFO   raw: 0.57958984375
2024-08-24 11:27:31  INFO   exported: 37983

It looks like the data we export for the AOA indexer lights themselves is full-range brightness - have you tried just using that data to control the brightness of the LEDs rather than the brightness knob itself? I'm referring to these three controls:

AOA_INDEXER_HIGH_F
AOA_INDEXER_NORMAL_F
AOA_INDEXER_LOW_F

I tested them in bort and they seem to accurately represent the brightness of the individual lights.

kbastronomics commented 3 months ago

Yes, using AOA_INDEXER_HIGH_F AOA_INDEXER_NORMAL_F AOA_INDEXER_LOW_F works,

But why does the pot output.
my routine works if I say use the pot output from the console brightness. or any other on the internal lights panel. it just does not work using the aoa indexer output

I see same thing in bort/dcs-bios buddy

charliefoxtwo commented 3 months ago

I don't know why the pot has that issue, but as far as I can tell the data being exported from dcs-bios is correct.

We can transfer this to the arduino library repo if you want. Maybe it's not just this control, maybe it's others too - I don't know. At least they might be able to attempt to repro the problem - I don't have any arduino hardware personally.

kbastronomics commented 3 months ago

Yes that works for me,

No1sonuk commented 3 months ago

@kbastronomics I'm going to need the whole code file to test. From what I can see, there's some missing parameters on the FastLED calls. Also, are you using 5mm Neopixels?

kbastronomics commented 3 months ago

ah, the code, the one I just cleaned up and removed the pot stuff from. i'll recreate it, it was not very difficult and upload SAP

yes, using 5mm Neopixels

the missing parameters is interesting since same code works for the interalal lighting lol

No1sonuk commented 3 months ago

Your code seems to be changing the brightness of the whole string of LEDs, rather than just a few. Is it only the AOA on that string?

kbastronomics commented 3 months ago

Yes, entire string is 3 5mm Neopixels

No1sonuk commented 3 months ago

OK. I wrote some test code - going to try it now.

No1sonuk commented 3 months ago

I confirmed the LED cuts out part-way through the range. HOWEVER, I connected an LCD to display the values and newValue tracks correctly between 0 and 65535. Brightness is mapped correctly between 0 and 255. So it appears something is causing FastLED to not work properly in this one case...

BUT, it DOES work if all the LEDs are on. More digging needed.

No1sonuk commented 3 months ago

I think I have a fix, but I need some time to test it.

kbastronomics commented 3 months ago

"BUT, it DOES work if all the LEDs are on."

that is something i did not test.

but also, if you use the console lighting pot instead, same code works

void onConsolesDimmerChange(unsigned int newValue) 
{
// Aoa code here.
}
DcsBios::IntegerBuffer consolesDimmerBuffer(0x7544, 0xffff, 0, onConsolesDimmerChange);
No1sonuk commented 3 months ago

Yes. That Does work... BUT only if the AOA control is turned up... Turn the AOA control down, and the LED goes out. SO, it's actually the AOA control itself that is turning off the LED when it gets turned down.

No1sonuk commented 3 months ago

There is a fix. The AOA lights have a float value available. This is the brightness of each light. This tracks the in-game light brightness, and is not affected by the brightness control shutoff. SO, the fix is to set the LED to on if the float is >0 and use the float itself for the brightness.

Try this:


/*
  Tell DCS-BIOS to use a serial connection and use interrupt-driven
  communication. The main program will be interrupted to prioritize
  processing incoming data.

  This should work on any Arduino that has an ATMega328 controller
  (Uno, Pro Mini, many others).
 */
#define DCSBIOS_IRQ_SERIAL

#include "DcsBios.h"

//****************  Neopixel setup  ***************
#include <FastLED.h>

// How many leds in your strip?
#define NUM_LEDS 3

#define DATA_PIN 2

int brightness = 255;

// Define the array of leds
CRGB leds[NUM_LEDS];
//*************************************************

/* paste code snippets from the reference documentation here */

void onAoaIndexerHighFChange(unsigned int newValue) {
    leds[0] = CRGB::Black;                // Set the LED to off
    if (newValue >0){
      leds[0] = CRGB::Green;
      brightness = map(newValue,0,65535,0,255);
      }   // Set it to on if required
    FastLED.setBrightness(brightness);
    FastLED.show();                       // Send to LED array
}
DcsBios::IntegerBuffer aoaIndexerHighFBuffer(FA_18C_hornet_AOA_INDEXER_HIGH_F, onAoaIndexerHighFChange);

void onAoaIndexerLowFChange(unsigned int newValue) {
    leds[2] = CRGB::Black;                // Set the LED to off
    if (newValue >0){
      leds[2] = CRGB::Red;
      brightness = map(newValue,0,65535,0,255);
      }   // Set it to on if required
    FastLED.setBrightness(brightness);
    FastLED.show();                       // Send to LED array
}
DcsBios::IntegerBuffer aoaIndexerLowFBuffer(FA_18C_hornet_AOA_INDEXER_LOW_F, onAoaIndexerLowFChange);

void onAoaIndexerNormalFChange(unsigned int newValue) {
    leds[1] = CRGB::Black;                // Set the LED to off
    if (newValue >0){
      leds[1] = CRGB::Yellow;
      brightness = map(newValue,0,65535,0,255);
      }   // Set it to on if required
    FastLED.setBrightness(brightness);
    FastLED.show();                       // Send to LED array
}
DcsBios::IntegerBuffer aoaIndexerNormalFBuffer(FA_18C_hornet_AOA_INDEXER_NORMAL_F, onAoaIndexerNormalFChange);

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

  FastLED.addLeds<NEOPIXEL, DATA_PIN>(leds, NUM_LEDS);  // GRB ordering is assumed
  FastLED.setBrightness(brightness);

  onAoaIndexerHighFChange(65535);  // Turn all the lights on
  onAoaIndexerLowFChange(65535);
  onAoaIndexerNormalFChange(65535);

  delay (1000);

  onAoaIndexerHighFChange(0);  // Turn all the lights off
  onAoaIndexerLowFChange(0);
  onAoaIndexerNormalFChange(0);

}

void loop() {
  DcsBios::loop();
}```
kbastronomics commented 3 months ago

Hi, Yes I am aware that the Float ones do work and have made use of them. I open the issue because the AoA Indexer Control itself does not appear to function correctly. I cannot find a reason for is as I also see DCS sends correct values, DCS-BIOS passes those on but for some reason when used to control the brightness it fails to work correctly

I mainly point out the inst console as it and the aoa indexer control both use the same function DcsBios::IntegerBuffer

so I find it difficult the believe there's a issue in that function especially since I've used it for other controls as well and they all work.

charliefoxtwo commented 3 months ago

So I spoke with @No1sonuk on discord about this.

It sounds like you were using the non-float controls (e.g. AOA_INDEXER_NORMAL) initially, and that's what was turning off. I initially misunderstood and thought you were saying the potentiometer itself was outputting zero, not the light value.

AOA_INDEXER_NORMAL is a binary value exported by dcs-bios. These sort of controls are really intended for lights which are either on or off, not which have any sort of brightness control, so I'm not sure why these controls were created in the first place, but I digress. By design, we export a 1 for these controls when the value we get from DCS is greater than or equal to 0.3. Note that the brightness of the light in-game as set by DCS won't necessarily correspond linearly to the brightness knob. If you look at the value of AOA_INDEXER_NORMAL_F during your testing, I'm guessing you'll see the issue right when that value drops below 19660 - 30% of the full range of the control, and a value from DCS of less than 0.3. As such, AOA_INDEXER_NORMAL will export 0 when that happens, which is expected behavior.

Ultimately, these controls as binary outputs shouldn't exist in dcs-bios, because they don't do what you might think they do, and I definitely don't think these are the controls you want for your use case here. The "non-float" controls do not indicate which light is the active light, they just indicate whether the light is above a certain brightness threshold (and again, for this reason, they shouldn't be used for this use case).

Hopefully this makes sense. Let me know if you still think there's an issue.

No1sonuk commented 3 months ago

To clarify: The AOA brightness control output value obtained from "DcsBios::IntegerBuffer hudAoaIndexerBuffer(0x745e, 0xffff, 0, onHudAoaIndexerChange);" does exactly what it's supposed to do - it tracks correctly between 0 and 65535. DCS maps that value non-linearly to the light brightness - AOA_INDEXER_NORMAL_F. The AOA_INDEXER_NORMAL binary signal switches on when AOA_INDEXER_NORMAL_F is above 19960. The non-linear mapping of the control position to the light brightness results in the AOA_INDEXER_NORMAL_F falling below 19960 at around 2/3 brightness on the control, which turns off the binary AOA_INDEXER_NORMAL signal.

As for the console lights "working correctly": They only have float values as far as I can see. When you try the console lights control knob, its value is NOT what's controlling the AOA lights being on or off - that's still controlled by the AOA brightness control. As I wrote above, when you're using the console control for the brightness, turn down the AOA control and the lights' binary controls will go off.

The bottom line: All the functions are behaving as intended. You are using the wrong function for what you want to achieve.

kbastronomics commented 3 months ago

ah that was not clear that the DcsBios::IntegerBuffer hudAoaIndexerBuffer(0x745e, 0xffff, 0, onHudAoaIndexerChange); is a non-linear change

no-where do i see that mentioned here.

image

it simply says "postion of the potentiometer"

I was well aware that the onAoaIndexerLowChange (and others) are on/off values

void onAoaIndexerLowChange(unsigned int newValue) {
  swtich(newValue) {
    case AOA_ON:
      AoA[AOA_LOW_FAST_START].setRGB(FA18IntLights.HUD_AOA_INDEXER,0,0);
      FastLED.show();
      break;
    case AOA_OFF:
      AoA[AOA_LOW_FAST_START].setRGB(0,0,0);
      FastLED.show();
      break;
  }
}
DcsBios::IntegerBuffer aoaIndexerLowBuffer(0x7408, 0x0020, 5, onAoaIndexerLowChange);

i then set the brightness value in

void onHudAoaIndexerChange(unsigned int newValue) {
  FA18IntLights.HUD_AOA_INDEXER = map(newValue,0,65535,0,255);
  FastLED.setBrightness(FA18IntLights.HUD_AOA_INDEXER);
  FastLED.show();
}
DcsBios::IntegerBuffer hudAoaIndexerBuffer(0x745e, 0xffff, 0, onHudAoaIndexerChange);

however, you've answered the issue with the value is NON-LINEAR.
I'd say it would be good if the doc produced by BIOS Buddy and others was clear that its a NON-LINEAR value

No1sonuk commented 3 months ago

The "position of the potentiometer" value IS linear. DCS interprets that value internally in a non-linear manner to determine the brightness of the light. That's nothing to do with DCS-BIOS. The brightness of the light determines the state of the binary controls, not the pot position.

As far as I can see, the AOA is the only instance of this dual-control thing on the F-18.

What we're saying is ignore the binary light signals. Just use the float values.

Did you try my code?

kbastronomics commented 3 months ago

The net effect though is a non-linear behavior so that you cannot use the AoA brightness control as intended. i get that you're saying that its DCS behavior and not DCS-BIOS that is causing this. now why in earth they decided this sould act like a audio pot is beyond me. only volume control pots should do that not a brightness pot that's ED's issues not DCS-BIOS.

as for the Floats, I understand and as I have stated, I've been using the float values in my own code.

void onAoaIndexerNormalFChange(unsigned int newValue) 
{
  FA18IntLights.HUD_AOA_INDEXER = map(newValue,0,65535,0,255);
  AoA[AOA_NORMAL_ONSPEED_START].setRGB(FA18IntLights.HUD_AOA_INDEXER,FA18IntLights.HUD_AOA_INDEXER,0);
  FastLED.show();
}
DcsBios::IntegerBuffer aoaIndexerNormalFBuffer(FA_18C_hornet_AOA_INDEXER_NORMAL_F, onAoaIndexerNormalFChange);

I update my global structure with the current value for other purposes. then use the value directly in the callback to set the color and brightness but directly using the newValue as appropriate for the RED, GREEN and YELLOW indicators.

Thank you, we can close this issue as it's not a DCS-BIOS/Arduino Library Issue