diff --git a/README.MD b/README.MD index b512a9a..e1c34d1 100644 --- a/README.MD +++ b/README.MD @@ -1,9 +1,10 @@ -6hp multichannel clock utility designed to be low cost and DIY friendly. +6hp multichannel eurorack clock and trigger utility designed to be low cost and DIY friendly. > It is like a "Pamela's 'very light' Workout" ;) +> > —u/BBougre -Features: +### Features: - 24ppqn internal clock with master BPM - 6 output channels - Separate divider or multiplier per chennel (from /32 to x24) @@ -13,10 +14,12 @@ Features: - All channel settings and bpm are saved on play/pause and recalled on power up - 2 external clock modes (24ppqn and beat) -TODO: +### TODO: - swing -- settings (input mode, pulse length) +- settings (pulse length, display timeout) - expanders with midi/tap tempo etc +### Acknowlidgements Timer library available here -https://github.com/PaulStoffregen/FlexiTimer2 \ No newline at end of file +https://github.com/PaulStoffregen/FlexiTimer2 + diff --git a/software/GToE/GToE.ino b/software/GToE/GToE.ino index 5c1372d..e80bf54 100644 --- a/software/GToE/GToE.ino +++ b/software/GToE/GToE.ino @@ -23,7 +23,7 @@ const int outsPins[6] = {6, 11, 7, 10, 8, 9}; -const int clockModes[18] = {-24, -16, -12, -8, -6, -4, -3, -2, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32}; //positive - divide, negative - multiply, 0 - off +const int clockModes[17] = {-24, -12, -8, -6, -4, -3, -2, 1, 2, 3, 4, 5, 6, 7, 8, 16, 32}; //positive - divide, negative - multiply, 0 - off unsigned int bpm = 130; @@ -51,8 +51,6 @@ int playingModes[6]; //actual channel modes array updated from channels each bea unsigned int pulsePeriod; bool isPlaying = false; -bool pulseCounted = false; - unsigned int tickCount = 0; unsigned int pulseCount = 0; @@ -74,7 +72,7 @@ unsigned long encPressedTime; unsigned long encReleasedTime; bool encPressRegistered; -unsigned long lastInteractionTime; +unsigned long lastInteractionTime; // used for display timeout Adafruit_SSD1306 display(128, 64, &Wire, -1); RotaryEncoder encoder(ENC_D1_PIN, ENC_D2_PIN, RotaryEncoder::LatchMode::TWO03); @@ -112,7 +110,7 @@ void setup() { pinMode(START_STOP_BTN_PIN, INPUT_PULLUP); pinMode(START_STOP_BTN_PIN, ANALOGUE_INPUT_1_PIN); pinMode(INPUT_PIN, INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(INPUT_PIN), externalClock, RISING); + attachInterrupt(digitalPinToInterrupt(INPUT_PIN), externalClock, FALLING); for (int i=0; i<6; i++) { pinMode(outsPins[i], OUTPUT); @@ -149,29 +147,24 @@ void clock() { if (isPlaying) { // Action on each pulse - if (tickCount == 0 && !pulseCounted) { + if (tickCount == 0 && masterClockMode == 0) { sendTriggers(); - pulseCounted = true; } //this part gets the Pulse and Ticks ticking //it's placed after the triggers to avoid problems on the start (when pulseCount==0) - if (tickCount < pulsePeriod) { - tickCount++; - } else { - tickCount = 0; - if (pulseCount < (PPQN-1)) { //-1 is here to avoid extra IF to reset to 0 - pulseCount++; - } else { - pulseCount = 0; - } + tickCount++; + if (masterClockMode == 0) { + if (tickCount == pulsePeriod) { + tickCount = 0; + if (pulseCount < (PPQN-1)) { //-1 is here to avoid extra IF to reset to 0 + pulseCount++; + } else { + pulseCount = 0; + } + } } - //pulse and beat count reset - if (tickCount == 0) { - pulseCounted = false; - } - // pull low all outputs after set pulse length if (tickCount >= PULSE_LENGTH) { for (int i = 0; i<6; i++) { @@ -182,12 +175,27 @@ void clock() { } } +void externalClock() { + externalPulseCounted = false; + lastExtPulseTime = newExtPulseTime; + newExtPulseTime = millis(); + if (masterClockMode == 1) { + isPlaying = true; + sendTriggers(); + tickCount = 0; + if (pulseCount < (PPQN-1)) { + pulseCount++; + } else { + pulseCount = 0; + } + } +} + void sendTriggers() { //switching modes on the beat and resetting channel clock if (pulseCount == 0) { for (int i = 0; i<6; i++) { if (playingModes[i] != clockModes[channels[i].mode]) { - //playingModes[i] = clockModes[channels[i].mode]; calculateCycles(); channelPulseCount[i] = 0; } @@ -220,10 +228,6 @@ void calculateCycles() { } } -void externalClock() { - externalPulseCounted = false; -} - void updateTiming() { if (masterClockMode == 0) { pulsePeriod = 60000 / (bpm * PPQN); @@ -335,8 +339,8 @@ void checkInputs() { //play button if (!digitalRead(START_STOP_BTN_PIN) && !playBtnPushed) { - isPlaying = !isPlaying; resetClocks(); + isPlaying = !isPlaying; playBtnPushed = true; saveState(); updateScreen(); //to wake up the screen if turned off