#include #include #include "src/MortseUi.h" const byte MorseTable[] = {0b00000000,0,0b00010010,0,0,0,0,0b00011110,0b10110110,0b00101101,0,0b10101010,0b00110011,0b00100001,0b00010101,0b10110010,0b10111111,0b10101111,0b10100111,0b10100011,0b10100001,0b10100000,0b10110000,0b10111000,0b10111100,0b10111111,0b00111000,0b00101010,0,0b10110001,0,0b00001100,0b00011010,0b01000001,0b10001000,0b10001010,0b01100100,0b00100000,0b10000010,0b01100110,0b10000000,0b01000000,0b10000111,0b01100101,0b10000100,0b01000011,0b01000010,0b01100111,0b10000110,0b10001101,0b01100010,0b01100000,0b00100001,0b01100001,0b10000001,0b01100011,0b10001001,0b10001011,0b10001100,0b10110110,0,0b00101101,0,0b00001101,0b00011110,0b01000001,0b10001000,0b10001010,0b01100100,0b00100000,0b10000010,0b01100110,0b10000000,0b01000000,0b10000111,0b01100101,0b10000100,0b01000011,0b01000010,0b01100111,0b10000110,0b10001101,0b01100010,0b01100000,0b00100001,0b01100001,0b10000001,0b01100011,0b10001001,0b10001011,0b10001100,0b10110110,0,0b00101101,0}; const int Channel1 = 9; //Output Channel 1 const int Channel2 = 10; //Output Channel 2 const int Channel3 = 11; //Output Channel 3 const int Enc1P1 = 2; //Encoder 1 Pin 1 to Interrupt const int Enc2P1 = 3; //Encoder 2 Pin 1 to Interrupt const int Enc1P2 = 14; //Encoder 1 Pin 2 to non-Interrupting pin because we only have 2 const int Enc2P2 = 15; //Encoder 2 Pin 2 to non-Interrupting pin because we only have 2 const int Enc1Btn = 16; //Encoder 1 Button const int Enc2Btn = 17; //Encoder 2 Button const int ClockIn = 4; //Clock In const int ClockDetect = 7; //Detect clock jack const int DebounceTime = 10; //Debounce time in ms const int DisplaySpi = 0; //todo: find spi port ## from library Encoder LeftEnc( Enc1P1, Enc1P2); Encoder RightEnc( Enc2P1, Enc2P2); //MortseUi Ui(DisplaySpi); String TestText = "Momento Mortse"; int E1 = 0; int E2 = 0; int Channel1Index = 0; int MorseIndex = 0; bool E1Btn = false; bool E2Btn = false; bool ClockState = false; bool Beat = false; unsigned int Channel1Trig = 0, Channel2Trig = 0, Channel3Trig = 0; bool E1Prev, E2Prev, CDPrev, E1Click, E2Click, CDIn = false, Channel1State = false, Channel2State = false, Channel3State = false; unsigned int E1Bounce, E2Bounce, CDBounce = 0, BeatBounce = 0; unsigned long ClockPrev = 0, ClockInPrev = 0, LastBeat = 0; byte Input = 0; int PpQN = 24; float Clock = 120; float ClockTick = (1/((Clock * PpQN)/60)) * 1000; unsigned long ClockTime = 0; unsigned long LastStepTime = 0; long EncLeft, EncRight = 0; void setup() { //Open Serial for output prior to installing a screen Serial.begin( 115200 ); Serial.println("Momento Mortse"); randomSeed(analogRead(A7)); pinMode(Enc1Btn, INPUT_PULLUP); pinMode(Enc2Btn, INPUT_PULLUP); pinMode(ClockIn, INPUT); pinMode(ClockDetect, INPUT_PULLUP); pinMode(Channel1, OUTPUT); pinMode(Channel2, OUTPUT); pinMode(Channel3, OUTPUT); E1Btn = digitalRead(Enc1Btn); E1Prev = E1Btn; E2Btn = digitalRead(Enc2Btn); E2Prev = E2Btn; ClockState = digitalRead(ClockIn); CDPrev = digitalRead(ClockDetect); digitalWrite(Channel1, 0); digitalWrite(Channel2, 0); digitalWrite(Channel2, 0); // Timer0 is already used for millis() - we'll just interrupt somewhere // in the middle and call the "Compare A" function below OCR0A = 0xAF; TIMSK0 |= _BV(OCIE0A); } void loop() { long newLEnc = LeftEnc.read(); long newREnc = RightEnc.read(); if (digitalRead(Enc1Btn) != E1Btn){ if (E1Bounce == 0 & E1Click == false){ Serial.println("E1Btn State Change"); E1Btn = !E1Btn; E1Bounce = DebounceTime; E1Click = true; } } if (digitalRead(Enc2Btn) != E2Btn){ if (E2Bounce == 0 & E2Click == false){ Serial.println("E2Btn State Change"); E2Btn = !E2Btn; E2Bounce = DebounceTime; E2Click = true; } } //false click handler E1Click = false; E2Click = false; bool newCD = digitalRead(ClockDetect); if (newCD != CDPrev){ if (CDBounce == 0){ Serial.println("Clock Jack Status Change"); CDPrev = CDIn = newCD; CDBounce = DebounceTime << 4; } } if ( digitalRead(ClockIn) != ClockState){ ClockState = !ClockState; if (ClockState){ unsigned long tmpClock = micros(); float clkInTick = tmpClock - ClockPrev; ClockPrev = tmpClock; if (abs(ClockInPrev - clkInTick) > 500){ Clock =((1.0/(clkInTick/1000000.0)) * 60.0)/(float)PpQN; String outputBPM = "New BPM: "; outputBPM.concat(Clock); Serial.println(outputBPM); outputBPM = "Clock Tick: "; outputBPM.concat(clkInTick); Serial.println(outputBPM); ClockTick = (1/((Clock * PpQN)/60)) * 1000; } else{ Beat = true; LastBeat = tmpClock; } } } if ((LastBeat + ClockTick) < micros()){ Beat = true; LastBeat = micros(); } if (newLEnc != EncLeft || newREnc != EncRight){ String output = "Left Enc Pos: "; output.concat(newLEnc); output.concat( ", Right Enc Pos: "); output.concat(newREnc); Serial.print(output); if (newLEnc != EncLeft){ Clock = Clock + (((float)EncLeft - (float)newLEnc)/40.0); } else{ Clock = Clock + ((EncRight - newREnc) * 2.5); } ClockTick = (1/((Clock * PpQN)/60)) * 1000; EncLeft = newLEnc; EncRight = newREnc; output = " Clock: "; output.concat(Clock); output.concat( " Clocktick: "); output.concat( ClockTick); Serial.println(output); } if (Beat){ Beat = false; if (!BeatBounce){ //Insert Beat Output here! char outputChar = TestText[Channel1Index]; if (outputChar == '\0'){ Channel1Index = 0; outputChar = TestText[Channel1Index]; } byte morseLength = MorseTable[((int)outputChar - 32)]; byte morsePattern = morseLength; bool trigger = (morsePattern >> MorseIndex) & 1; if (MorseIndex == 0){ Channel1Index++; outputChar = TestText[Channel1Index]; MorseIndex = ((MorseTable[((int)outputChar - 32)]) >> 5) - 1; } MorseIndex--; if (trigger){ digitalWrite(Channel1, true); Channel1Trig = 5; } } } if (Channel1State && !Channel1Trig){ digitalWrite(Channel1, 0); Channel1State = false; } if (Channel2State && !Channel2Trig){ digitalWrite(Channel2, 0); Channel2State = false; } if (Channel3State && !Channel3Trig){ digitalWrite(Channel3, 0); Channel3State = false; } //Ui.tick(); } // Interrupt is called once a millisecond, SIGNAL(TIMER0_COMPA_vect) { E1Bounce = (E1Bounce - 1) & 0b10000000; E2Bounce = (E2Bounce - 1) & 0b10000000; CDBounce = (CDBounce - 1) & 0b10000000; BeatBounce = (BeatBounce - 1) & 0b10000000; Channel1Trig = (Channel1Trig - 1) & 0b10000000; Channel2Trig = (Channel2Trig - 1) & 0b10000000; Channel3Trig = (Channel3Trig - 1) & 0b10000000; }