24ppqn external clock added

This commit is contained in:
--global
2023-05-08 23:52:12 +03:00
parent 2177e8dead
commit 2df29ec1cb
2 changed files with 39 additions and 32 deletions

View File

@ -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
https://github.com/PaulStoffregen/FlexiTimer2

View File

@ -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