31#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega2560__)
32 #define DCSBIOS_IRQ_SERIAL
34 #define DCSBIOS_DEFAULT_SERIAL
41#include "LedUpdateState.h"
42#include "RotaryEncoder.h"
50 static const int MAX_CHANNELS = 10;
51 static const int MODE_NORMAL = 1;
52 static const int MODE_MANUAL = 2;
53 static const int MODE_RAINBOW = 3;
54 Channel* channels[MAX_CHANNELS];
61 int dcs_brightness_console;
62 int dcs_brightness_instrument;
63 int dcs_brightness_flood;
65 RotaryEncoder* encoder;
67 static Board* instance;
68 DcsState prevDcsState = DcsState::EXITED;
79 currentMode = MODE_NORMAL;
80 mode2_brightness = 64;
81 mode3_brightness = 64;
82 dcs_brightness_console = 0;
83 dcs_brightness_instrument = 0;
84 dcs_brightness_flood = 0;
97 return instance ? instance : (instance =
new Board()); }
107 this->encSwPin = encSwPin;
108 pinMode(encSwPin, INPUT_PULLUP);
109 encoder =
new RotaryEncoder(encAPin, encBPin, RotaryEncoder::LatchMode::TWO03);
118 channels[channelCount++] = channel;
127 updCountdown = (updCountdown == 0) ? 32 : updCountdown;
129 if (updCountdown == 0) {
145 static bool lastButtonState = HIGH;
146 static unsigned long lastButtonPressTime = 0;
147 const unsigned long BUTTON_WAIT = 1000;
149 bool currentButtonState = digitalRead(encSwPin);
150 unsigned long currentTime = millis();
152 if (currentButtonState == LOW && lastButtonState == HIGH) {
153 if (currentTime - lastButtonPressTime < BUTTON_WAIT) {
154 lastButtonState = currentButtonState;
157 lastButtonPressTime = currentTime;
158 int previousMode = currentMode;
159 currentMode = (currentMode % 3) + 1;
161 if (currentMode == MODE_NORMAL) {
163 sendDcsBiosMessage(
"CONSOLES_DIMMER", String(dcs_brightness_console).c_str());
164 sendDcsBiosMessage(
"INST_PNL_DIMMER", String(dcs_brightness_instrument).c_str());
165 sendDcsBiosMessage(
"FLOOD_DIMMER", String(dcs_brightness_flood).c_str());
167 if (currentMode == MODE_MANUAL) {
168 mode2_brightness = 64;
171 if (currentMode == MODE_RAINBOW) {
172 mode3_brightness = 64;
174 rotary_pos = encoder->getPosition();
178 lastButtonState = currentButtonState;
181 lastButtonState = currentButtonState;
192 switch(currentMode) {
196 if (currentDcsState == DcsState::EXITED && prevDcsState != DcsState::EXITED) {
198 }
else if (prevDcsState == DcsState::EXITED &&
199 currentDcsState != DcsState::EXITED &&
200 currentDcsState != DcsState::PAUSED) {
201 for (
int i = 0; i < channelCount; i++) {
209 prevDcsState = currentDcsState;
215 newPos = encoder->getPosition();
216 if (newPos != rotary_pos) {
217 RotaryEncoder::Direction direction = encoder->getDirection();
218 if (direction == RotaryEncoder::Direction::CLOCKWISE) {
219 mode2_brightness = (mode2_brightness < 224) ? mode2_brightness + 32 : 255;
221 mode2_brightness = (mode2_brightness > 32) ? mode2_brightness - 32 : 0;
229 newPos = encoder->getPosition();
230 if (newPos != rotary_pos) {
231 RotaryEncoder::Direction direction = encoder->getDirection();
232 if (direction == RotaryEncoder::Direction::CLOCKWISE) {
233 mode3_brightness = (mode3_brightness < 224) ? mode3_brightness + 32 : 255;
235 mode3_brightness = (mode3_brightness > 32) ? mode3_brightness - 32 : 0;
239 for (
int i = 0; i < channelCount; i++) {
240 fill_rainbow(channels[i]->getLeds(), channels[i]->getLedCount(), thisHue, deltaHue);
242 nscale8_video(channels[i]->getLeds(), channels[i]->getLedCount(), mode3_brightness);
257 void fillSolid(
const CRGB& color,
int brightness = -1) {
258 int targetBrightness = (brightness >= 0) ? brightness : this->mode2_brightness;
259 for (
int i = 0; i < channelCount; i++) {
271 for (
int i = 0; i < channelCount; i++) {
283 dcs_brightness_instrument = newValue;
284 if (currentMode != MODE_NORMAL)
return;
285 for (
int i = 0; i < channelCount; i++) {
298 dcs_brightness_console = newValue;
299 if (currentMode != MODE_NORMAL)
return;
300 for (
int i = 0; i < channelCount; i++) {
313 dcs_brightness_flood = newValue;
314 if (currentMode != MODE_NORMAL)
return;
315 for (
int i = 0; i < channelCount; i++) {
331 DcsBios::IntegerBuffer instrIntLtBuffer{FA_18C_hornet_INSTR_INT_LT,
onInstrIntLtChange};
359Board* Board::instance =
nullptr;
DCS State Monitor for OpenHornet.
DcsState getDcsState()
Determine the current DCS connection state (heartbeat-only variant)
static void onConsolesDimmerChange(unsigned int newValue)
Callback for console dimmer changes from DCS-BIOS.
static void onFloodDimmerChange(unsigned int newValue)
Callback for flood lighting changes from DCS-BIOS.
void setupRotaryEncoder(int encSwPin, int encAPin, int encBPin)
Sets up the rotary encoder with switch and encoder pins.
static Board * getInstance()
Gets or createsthe singleton instance of the Board class.
int handleModeChange()
Handles mode change button press and returns current mode.
static void onInstrIntLtChange(unsigned int newValue)
Callback for instrument lighting changes from DCS-BIOS.
void setAllLightsOff()
Turns off all lights in all channels and resets brightness state.
void updateConsoleLights(uint16_t newValue)
Updates all channels with new console lighting value.
void registerChannel(Channel *channel)
Registers a channel with the board.
void updateLeds()
Update the physical LED state.
void updateInstrumentLights(uint16_t newValue)
Updates all channels with new instrument lighting value.
void updateFloodLights(uint16_t newValue)
Updates all channels with new flood lighting value.
void processMode()
Processes the current mode.
void fillSolid(const CRGB &color, int brightness=-1)
Fills all channels with a solid color.
void updateInstrLights(uint16_t brightness, const CRGB &color=NVIS_GREEN_A)
Updates backlights for all panels in this channel.
void updateConsoleLights(uint16_t brightness, const CRGB &color=NVIS_GREEN_A)
Updates console lights for all panels in this channel.
void updateFloodLights(uint16_t brightness)
Updates flood lights for all panels in this channel.
void setAllLightsOff()
Turns off all lights in all panels of this channel and resets brightness state.
void setUpdateFlag(bool requireUpdate)
Sets the LED update flag in an atomic operation.
static LedUpdateState * getInstance()
Gets the singleton instance of the LedUpdateState class.