#include #include "TimedPin.h" #include "ui.h" /***************************************************************************//** * @brief Timer class for generate cyclic signals *******************************************************************************/ struct Tmr { int32_t Period; // cycle length (it must be initialized!) uint32_t TrefMillis; //--------------------------------------------------------------------------- bool Check(uint32_t t) { // check with external timebase int32_t tdif = t - TrefMillis; if (tdif >= Period) { // period expired TrefMillis += Period; return true; } return false; }; bool Check() { // check with millisec timebase uint32_t t = millis(); int32_t tdif = t - TrefMillis; if (tdif >= Period) { // period expired TrefMillis += Period; return true; } return false; }; }; Tmr Tmr10ms = { .Period = 10 }; Tmr Tmr100ms = { .Period = 100 }; Tmr Tmr1s = { .Period = 1000 }; /***************************************************************************//** * @brief Volume buttons and LEDs *******************************************************************************/ const uint8_t pinLedInc1 = 2; const uint8_t pinBtnInc1 = 3; const uint8_t pinGndDec1 = 4; const uint8_t pinLedDec1 = 5; const uint8_t pinBtnDec1 = 6; const uint8_t pinGndInc2 = 7; const uint8_t pinLedInc2 = 8; const uint8_t pinBtnInc2 = 9; const uint8_t pinGndDec2 = A4; const uint8_t pinLedDec2 = A5; const uint8_t pinBtnDec2 = A6; /***************************************************************************//** * @brief Mute buttons and LEDs *******************************************************************************/ const uint8_t pinGndChOn1 = A3; const uint8_t pinLedChOn1 = A2; const uint8_t pinBtnChOn1 = A1; const uint8_t pinGndChOn2 = 12; const uint8_t pinLedChOn2 = 11; const uint8_t pinBtnChOn2 = 10; /***************************************************************************//** * @brief Relay *******************************************************************************/ const uint8_t pinRelay = A0; TimedPin RelayMute(pinRelay); /***************************************************************************//** * @brief LED *******************************************************************************/ TimedPin LedBoard(LED_BUILTIN); TimedPin LedChOn1(pinLedChOn1); TimedPin LedChOn2(pinLedChOn2); TimedPin LedInc1(pinLedInc1); TimedPin LedDec1(pinLedDec1); TimedPin LedInc2(pinLedInc2); TimedPin LedDec2(pinLedDec2); bool MidiCfgTxOnly; /// duplex or only tx configuration (without MIDI rx line) MixerMuteState AirMutes[2] = { // No LED Relay init button MixerMuteState(22, &LedChOn1, &RelayMute, 0, BTN_CH_ON1, EV_UI_RX_MUTE_CH1_ON, EV_UI_RX_MUTE_CH1_OFF), MixerMuteState( 4, &LedChOn2, 1, BTN_CH_ON2, EV_UI_RX_MUTE_CH2_ON, EV_UI_RX_MUTE_CH2_OFF) }; MixerFaderState AirFaders[2] = { MixerFaderState(0, 80, 96, 112, &LedInc1, &LedDec1, BTN_INC1, BTN_DEC1), MixerFaderState(1, 80, 96, 112, &LedInc2, &LedDec2, BTN_INC2, BTN_DEC2) }; /***************************************************************************//** * @brief MIDI instance (serial port) *******************************************************************************/ MIDI_CREATE_DEFAULT_INSTANCE(); // ----------------------------------------------------------------------------- void MidiCCHandler(byte channel, byte ctrl_no, byte val) { if (channel == 1) { // Faders: ch=1 for (uint_fast8_t i=0; i= 64); mute.MuteLocal = mute.MuteMixer; mute.Led->Set(!mute.MuteMixer); UI_EventProc(mute.MuteMixer ? mute.UiEventOff : mute.UiEventOn); LedBoard.OnTimed(200); } } } } // ----------------------------------------------------------------------------- void setup() { pinMode(pinBtnInc1, INPUT_PULLUP); pinMode(pinBtnDec1, INPUT_PULLUP); pinMode(pinBtnInc2, INPUT_PULLUP); pinMode(pinBtnDec2, INPUT_PULLUP); pinMode(pinBtnChOn1, INPUT_PULLUP); pinMode(pinBtnChOn2, INPUT_PULLUP); pinMode(pinRelay, OUTPUT); pinMode(pinGndDec1, OUTPUT); pinMode(pinGndInc2, OUTPUT); pinMode(pinGndDec2, OUTPUT); pinMode(pinGndChOn1, OUTPUT); pinMode(pinGndChOn2, OUTPUT); digitalWrite(pinRelay, LOW); digitalWrite(pinGndDec1, LOW); digitalWrite(pinGndInc2, LOW); digitalWrite(pinGndDec2, LOW); digitalWrite(pinGndChOn1, LOW); digitalWrite(pinGndChOn2, LOW); LedBoard.begin(); LedChOn1.begin(); LedChOn2.begin(); LedInc1.begin(); LedDec1.begin(); LedInc2.begin(); LedDec2.begin(); RelayMute.begin(); MIDI.setHandleControlChange(MidiCCHandler); MIDI.begin(MIDI_CHANNEL_OMNI); // Initiate MIDI communications, listen to all channels MIDI.turnThruOff(); UI_Init(); // Start user interface (main state machine) } static uint8_t BtnPrev = 0x00; uint8_t ButtonGetVal() { return BtnPrev; } bool ButtonCheck(uint8_t btn) { return (BtnPrev & (1 << btn)) ? true : false; } /***************************************************************************//** * @brief Main loop *******************************************************************************/ void loop() { MIDI.read(); // Call MIDI.read the fastest you can for real-time performance. uint32_t t = millis(); // execute every 10ms ******************************************************* if (Tmr10ms.Check(t)) { static uint8_t BtnNew = 0; static uint8_t BtnRel = 0; uint8_t btn = (digitalRead(pinBtnInc1) ? 0: (1 << BTN_INC1 )) | (digitalRead(pinBtnDec1) ? 0: (1 << BTN_DEC1 )) | (digitalRead(pinBtnInc2) ? 0: (1 << BTN_INC2 )) | (digitalRead(pinBtnDec2) ? 0: (1 << BTN_DEC2 )) | (digitalRead(pinBtnChOn1) ? 0: (1 << BTN_CH_ON1)) | (digitalRead(pinBtnChOn2) ? 0: (1 << BTN_CH_ON2)); BtnNew |= btn & (~BtnPrev); BtnRel |= (~btn) & BtnPrev; BtnPrev = btn; uint8_t mask = 1; if (BtnNew) { for (uint_fast8_t i = 0; i < 8; i++) { if (BtnNew & mask) { BtnNew &= ~mask; // Bit clr UI_EventProc(EV_UI_KEY_PRESS + i); LedBoard.OnTimed(50); break; } mask <<= 1; } }else if (BtnRel) { // released button for (uint_fast8_t i = 0; i < 8; i++) { if (BtnRel & mask) { BtnRel &= ~mask; // Bit clr UI_EventProc(EV_UI_KEY_REL + i); break; } mask <<= 1; } } UI_EventProc(EV_TIMER_TICK); UI_EventProc(EV_UI_TICK_10MS); UI_CheckEvent(); LedBoard.update(); LedChOn1.update(); LedChOn2.update(); LedInc1.update(); LedDec1.update(); LedInc2.update(); LedDec2.update(); RelayMute.update(); } // execute every 100ms ****************************************************** if (Tmr100ms.Check(t)) { UI_EventProc(EV_UI_TICK_100MS); } // execute every 1s ********************************************************* if (Tmr1s.Check(t)) { UI_EventProc(EV_UI_TICK_1S); } }