24ppqn external clock added
This commit is contained in:
11
README.MD
11
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" ;)
|
> It is like a "Pamela's 'very light' Workout" ;)
|
||||||
|
>
|
||||||
> —u/BBougre
|
> —u/BBougre
|
||||||
|
|
||||||
Features:
|
### Features:
|
||||||
- 24ppqn internal clock with master BPM
|
- 24ppqn internal clock with master BPM
|
||||||
- 6 output channels
|
- 6 output channels
|
||||||
- Separate divider or multiplier per chennel (from /32 to x24)
|
- 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
|
- All channel settings and bpm are saved on play/pause and recalled on power up
|
||||||
- 2 external clock modes (24ppqn and beat)
|
- 2 external clock modes (24ppqn and beat)
|
||||||
|
|
||||||
TODO:
|
### TODO:
|
||||||
- swing
|
- swing
|
||||||
- settings (input mode, pulse length)
|
- settings (pulse length, display timeout)
|
||||||
- expanders with midi/tap tempo etc
|
- expanders with midi/tap tempo etc
|
||||||
|
|
||||||
|
### Acknowlidgements
|
||||||
Timer library available here
|
Timer library available here
|
||||||
https://github.com/PaulStoffregen/FlexiTimer2
|
https://github.com/PaulStoffregen/FlexiTimer2
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
const int outsPins[6] = {6, 11, 7, 10, 8, 9};
|
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;
|
unsigned int bpm = 130;
|
||||||
|
|
||||||
@ -51,8 +51,6 @@ int playingModes[6]; //actual channel modes array updated from channels each bea
|
|||||||
unsigned int pulsePeriod;
|
unsigned int pulsePeriod;
|
||||||
bool isPlaying = false;
|
bool isPlaying = false;
|
||||||
|
|
||||||
bool pulseCounted = false;
|
|
||||||
|
|
||||||
unsigned int tickCount = 0;
|
unsigned int tickCount = 0;
|
||||||
unsigned int pulseCount = 0;
|
unsigned int pulseCount = 0;
|
||||||
|
|
||||||
@ -74,7 +72,7 @@ unsigned long encPressedTime;
|
|||||||
unsigned long encReleasedTime;
|
unsigned long encReleasedTime;
|
||||||
bool encPressRegistered;
|
bool encPressRegistered;
|
||||||
|
|
||||||
unsigned long lastInteractionTime;
|
unsigned long lastInteractionTime; // used for display timeout
|
||||||
|
|
||||||
Adafruit_SSD1306 display(128, 64, &Wire, -1);
|
Adafruit_SSD1306 display(128, 64, &Wire, -1);
|
||||||
RotaryEncoder encoder(ENC_D1_PIN, ENC_D2_PIN, RotaryEncoder::LatchMode::TWO03);
|
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, INPUT_PULLUP);
|
||||||
pinMode(START_STOP_BTN_PIN, ANALOGUE_INPUT_1_PIN);
|
pinMode(START_STOP_BTN_PIN, ANALOGUE_INPUT_1_PIN);
|
||||||
pinMode(INPUT_PIN, INPUT_PULLUP);
|
pinMode(INPUT_PIN, INPUT_PULLUP);
|
||||||
attachInterrupt(digitalPinToInterrupt(INPUT_PIN), externalClock, RISING);
|
attachInterrupt(digitalPinToInterrupt(INPUT_PIN), externalClock, FALLING);
|
||||||
|
|
||||||
for (int i=0; i<6; i++) {
|
for (int i=0; i<6; i++) {
|
||||||
pinMode(outsPins[i], OUTPUT);
|
pinMode(outsPins[i], OUTPUT);
|
||||||
@ -149,16 +147,15 @@ void clock() {
|
|||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
|
|
||||||
// Action on each pulse
|
// Action on each pulse
|
||||||
if (tickCount == 0 && !pulseCounted) {
|
if (tickCount == 0 && masterClockMode == 0) {
|
||||||
sendTriggers();
|
sendTriggers();
|
||||||
pulseCounted = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//this part gets the Pulse and Ticks ticking
|
//this part gets the Pulse and Ticks ticking
|
||||||
//it's placed after the triggers to avoid problems on the start (when pulseCount==0)
|
//it's placed after the triggers to avoid problems on the start (when pulseCount==0)
|
||||||
if (tickCount < pulsePeriod) {
|
|
||||||
tickCount++;
|
tickCount++;
|
||||||
} else {
|
if (masterClockMode == 0) {
|
||||||
|
if (tickCount == pulsePeriod) {
|
||||||
tickCount = 0;
|
tickCount = 0;
|
||||||
if (pulseCount < (PPQN-1)) { //-1 is here to avoid extra IF to reset to 0
|
if (pulseCount < (PPQN-1)) { //-1 is here to avoid extra IF to reset to 0
|
||||||
pulseCount++;
|
pulseCount++;
|
||||||
@ -166,10 +163,6 @@ void clock() {
|
|||||||
pulseCount = 0;
|
pulseCount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//pulse and beat count reset
|
|
||||||
if (tickCount == 0) {
|
|
||||||
pulseCounted = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// pull low all outputs after set pulse length
|
// pull low all outputs after set pulse length
|
||||||
@ -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() {
|
void sendTriggers() {
|
||||||
//switching modes on the beat and resetting channel clock
|
//switching modes on the beat and resetting channel clock
|
||||||
if (pulseCount == 0) {
|
if (pulseCount == 0) {
|
||||||
for (int i = 0; i<6; i++) {
|
for (int i = 0; i<6; i++) {
|
||||||
if (playingModes[i] != clockModes[channels[i].mode]) {
|
if (playingModes[i] != clockModes[channels[i].mode]) {
|
||||||
//playingModes[i] = clockModes[channels[i].mode];
|
|
||||||
calculateCycles();
|
calculateCycles();
|
||||||
channelPulseCount[i] = 0;
|
channelPulseCount[i] = 0;
|
||||||
}
|
}
|
||||||
@ -220,10 +228,6 @@ void calculateCycles() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void externalClock() {
|
|
||||||
externalPulseCounted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateTiming() {
|
void updateTiming() {
|
||||||
if (masterClockMode == 0) {
|
if (masterClockMode == 0) {
|
||||||
pulsePeriod = 60000 / (bpm * PPQN);
|
pulsePeriod = 60000 / (bpm * PPQN);
|
||||||
@ -335,8 +339,8 @@ void checkInputs() {
|
|||||||
|
|
||||||
//play button
|
//play button
|
||||||
if (!digitalRead(START_STOP_BTN_PIN) && !playBtnPushed) {
|
if (!digitalRead(START_STOP_BTN_PIN) && !playBtnPushed) {
|
||||||
isPlaying = !isPlaying;
|
|
||||||
resetClocks();
|
resetClocks();
|
||||||
|
isPlaying = !isPlaying;
|
||||||
playBtnPushed = true;
|
playBtnPushed = true;
|
||||||
saveState();
|
saveState();
|
||||||
updateScreen(); //to wake up the screen if turned off
|
updateScreen(); //to wake up the screen if turned off
|
||||||
|
|||||||
Reference in New Issue
Block a user