// ППС-2М
// https://forum.arduino.cc/t/warning-lights-panel/1457319/
#include <Adafruit_NeoPixel.h>
#define PIXPIN 5
#define PIXNUM 15
Adafruit_NeoPixel pix(PIXNUM, PIXPIN, NEO_GRB + NEO_KHZ800);
#define LGEARpix 12 // first LGEAR pixel
#define LGRUPpix 9 // first Landing Gear UP pixel
#define FLAPSpix 6 // first FLAPS pixel
#define BRAKEpix 3 // first BRAKE pixel
#define LGRDNpix 0 // first Landing Gear DOWN pixel
#define ENCCLK 2 // Encoder clock
#define ENC_DT 3 // Encoder data
#define ENC_SW 4 // Encoder switch
#define LGEAR 14 // ВЫПУСТИ ШАССИ - "release landing gear" (gear down, pump works)
#define FLAPS 15 // КРЫЛК ВЫПУЩЕНЫ - "wings release" (flaps extend)
#define BRAKE 16 // ВЫПУЩЕНЫ ЩИТКИ- "release flaps" (airbrake extend)
int brightness = 127; // middle brightness
int dimmer = 16; // factor of 128 for dimming
volatile bool interruptFlag = 0; // used in interrupt
bool lgearOneTime = 1, flapsOneTime = 1, brakeOneTime = 1, oneTimeOnly = 1; // set one time flags
void setup() {
Serial.begin(115200);
pinMode(LED_BUILTIN, OUTPUT); // onboard LED
pinMode(ENC_SW, INPUT_PULLUP); // encoder pushbutton
pinMode(ENCCLK, INPUT); // encoder clock pin
pinMode(ENC_DT, INPUT); // encoder data pin
pinMode(LGEAR, INPUT_PULLUP); // 14
pinMode(FLAPS, INPUT_PULLUP); // 15
pinMode(BRAKE, INPUT_PULLUP); // 16
attachInterrupt( // configure Interrupt Callback
digitalPinToInterrupt(ENCCLK), // interrupt pin
readEncoder, // Interrupt Service Routine
FALLING); // transition HIGH to LOW
pix.begin(); // start NeoPixel object
// start with lgear down, flaps up, brake up
pixGroup(LGEARpix, 0, brightness, 0); // LGEAR is green
pixGroup(LGRDNpix, 0, brightness, 0); // LGEAR DOWN is green
pixGroup(FLAPSpix, 0, brightness, 0); // FLAPS UP is green
pixGroup(BRAKEpix, 0, brightness, 0); // BRAKE UP is green
}
void loop() {
readEncoderSwitch(); // read encoder switch/pushbutton
readLGearSwitch(); // read landing gear switch
readFlapsSwitch(); // read flaps switch
readBrakeSwitch(); // read air brake switch
checkInterruptFlag(); // read rotary encoder direction
}
void checkInterruptFlag() {
if (interruptFlag) { // test interrupt for knob turned
int dtValue = digitalRead(ENC_DT); // read direction of turn
if (dtValue == HIGH) { // counter clockwise
brightness -= dimmer; // dimmer/night/НОЧЬ
if (brightness < 64) brightness = 64;
// Serial.print("CW "); // Serial output for debugging
}
if (dtValue == LOW) { // clockwise
brightness += dimmer; // brighter/day/ДЕНЬ
if (brightness > 255) brightness = 255;
// Serial.print("CC "); // Serial output for debugging
}
interruptFlag = 0; // reset/clear flag
}
}
void readLGearSwitch() {
if (digitalRead(LGEAR) == 0) {
pixGroup(LGRDNpix, 12, brightness, 0); // LGRDN lamp
pixGroup(LGEARpix, 0, brightness, 0); // LGEAR lamps
pixGroup(LGRUPpix, 0, 0, 0); // LGRUP lamp
lgearOneTime = 1; // set oneTime flag
} else {
if (lgearOneTime) {
lgearOneTime = 0; // reset oneTime flag
pixGroup(LGRDNpix, 0, 0, 0);
pixGroup(LGRUPpix, 255, 0, 0);
pixGroup(LGEARpix, 0, 0, 0);
}
}
}
void readFlapsSwitch() {
if (digitalRead(FLAPS) == 0) {
pixGroup(FLAPSpix, 0, brightness, 0);
flapsOneTime = 1; // set oneTime flag
} else {
if (flapsOneTime) {
flapsOneTime = 0; // reset oneTime flag
pixGroup(FLAPSpix, 0, 0, 0);
}
}
}
void readBrakeSwitch() {
if (digitalRead(BRAKE) == 0) {
pixGroup(BRAKEpix, 0, brightness, 0);
brakeOneTime = 1; // set oneTime flag
} else {
if (brakeOneTime) {
brakeOneTime = 0; // reset oneTime flag
pixGroup(BRAKEpix, 0, 0, 0);
}
}
}
void readEncoderSwitch() {
if (digitalRead(ENC_SW) == LOW) { // switch pressed
delay(100); // debounce encoder switch press
lamptest(1); // turn all lamps on
digitalWrite(LED_BUILTIN, HIGH); // ON
oneTimeOnly = 1; // set flag to turn test LEDs off one time
} else {
if (oneTimeOnly) { // if oneTimeOnly is true...
oneTimeOnly = 0; // ... reset flag so only one time...
lamptest(0); // ... turn test LEDs off
digitalWrite(LED_BUILTIN, LOW); // OFF
}
}
}
void pixGroup(byte first, int red, int grn, int blu) { // turn NeoPixels ON in GROUPS
for (int i = first; i < first + 3; i++)
pix.setPixelColor(i, pix.Color(red, grn, blu)); // CYN
pix.show();
}
void readEncoder() { // This is the complete Interrupt Service Routine
interruptFlag = 1;
}
void lamptest(bool state) { // state is used for 0 = OFF, 1 = ON
// Serial.print("SW "); // showing PRESSED
pixGroup(LGRDNpix, 0, state * brightness, 0); // green
pixGroup(BRAKEpix, 0, state * brightness, 0); // green
pixGroup(FLAPSpix, 0, state * brightness, 0); // green
pixGroup(LGRUPpix, state * 255, 0, 0); // red
pixGroup(LGEARpix, 0, state * brightness, 0); // green
delay(1000);
for (int i = 0; i < PIXNUM; i++) // all pixels...
pixGroup(i, 0, 0, 0); // ... black
}ВЫПУЩЕНЫ
ВЫПУСТИ
ШАССИ
^
DAY ДЕНЬ
NIT НОЧЬ
v
ТОЛКАТЬ
КРЫЛК
ЩИТКИ
ШАССИ
КРЫЛК
ЩИТКИ
UP
DN
UP
DN
UP
DN