diff --git a/README.MD b/README.MD index 58453ad..1b83135 100644 --- a/README.MD +++ b/README.MD @@ -1,10 +1,9 @@ Features: - 6 output channels - Master BPM -- Separate divider per chennel +- Separate divider or multiplier per chennel (from /32 to x24) TODO: -- Add multipliers - Add min and max values - External clock - Switch to U8G2 for screen diff --git a/software/GToE/GToE.ino b/software/GToE/GToE.ino index cbbc787..862cc30 100644 --- a/software/GToE/GToE.ino +++ b/software/GToE/GToE.ino @@ -17,26 +17,29 @@ #define ENC_D2_PIN 3 #define START_STOP_BTN_PIN 14 -int outsPins[6] = {5, 6, 7, 8, 9, 10}; +const int outsPins[6] = {5, 6, 7, 8, 9, 10}; - -int outsValues[6] = {1, 2, 4, -4, 0, 0}; //positive - divide, negative - multiply, 0 - off /2 /3 /4 /5 /6 /7 /8 /16 /32 /random x2 x3 x4 x6 x8 x12 x16 x24 +const int outsModes[22] = {-24, -16, -12, -8, -6, -4, -3, -2, -1, 0, 1, 1.5, 2, 3, 4, 5, 6, 7, 8, 16, 32, 100}; //positive - divide, negative - multiply, 0 - off, 100 - random +int outsModeIndex[6] = {10, 8, 9, 9, 9, 9}; //10 - /1, 9 - off int outsPeriods[6]; int outsClocksCounts[6]; +int outsModesPlay[6]; //actual channel modes array bool clockMode; bool clockModeOld; int inputMode; //clock, reset, start/stop int clockCount = 0; -int bpm = 127; +int bpm = 30; int pulseClockCount = 0; int pulseCount = 0; int pulsePeriod; bool isPlaying = 0; int needToResetChannel; +bool beatCounted = false; bool pulseCounted = false; + int displayTab = 0; int displayTabOld; bool needToChangeTab = 0; @@ -50,7 +53,7 @@ Adafruit_SSD1306 display(128, 64, &Wire, -1); RotaryEncoder encoder(ENC_D1_PIN, ENC_D2_PIN, RotaryEncoder::LatchMode::TWO03); void setup() { - Serial.begin(9600); + //Serial.begin(9600); pinMode(INPUT_CONNECTED_PIN, INPUT_PULLUP); pinMode(ENC_BTN_PIN, INPUT_PULLUP); @@ -64,7 +67,7 @@ void setup() { display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); updateScreen(); - updatePeriods(); + updatePeriod(); FlexiTimer2::set(1, 1.0/1000, internalClock); // 1.0/1000 = 1ms period FlexiTimer2::start(); @@ -77,29 +80,74 @@ void loop() { void internalClock() { if (isPlaying) { - // pulse rules for dividers (multipliers should be in separate for loop, as this one occurs only on pulse 0 (bpm)) - if (pulseCount == 0 && !pulseCounted) { + /*/ Dividers and actual modes array update + if (pulseCount == 0 && !beatCounted) { for (int i = 0; i<6; i++) { - if (outsValues[i] > 0) { //Dividers (>0) - if (outsClocksCounts[i] == 0) { //Pulse on 0 + outsModesPlay[i] = outsModes[outsModeIndex[i]]; //updated here to prevent sync out for multipliers + if (outsModesPlay[i] > 0) { //Dividers (>0) + if (outsClocksCounts[i] == 0) { //Pulse on 0 digitalWrite(outsPins[i], HIGH); + Serial.print(" div "); } - if (outsClocksCounts[i] < (outsValues[i]-1)) { + if (outsClocksCounts[i] < (outsModesPlay[i] - 1)) { //-1?? outsClocksCounts[i]++; - if (i == 0) {Serial.println(outsClocksCounts[i]);} + //if (i == 0) {Serial.println(outsClocksCounts[i]);} } else { outsClocksCounts[i] = 0; } } } + beatCounted = true; + } */ + + // Action on each pulse + if (pulseClockCount == 0 && !pulseCounted) { + + //divider + if (pulseCount == 0 && !beatCounted) { + for (int i = 0; i<6; i++) { + outsModesPlay[i] = outsModes[outsModeIndex[i]]; //updated here to prevent sync out for multipliers + if (outsModesPlay[i] > 0) { + if (outsClocksCounts[i] == 0) { //Pulse on 0 + digitalWrite(outsPins[i], HIGH); + //Serial.print(" div "); + } + if (outsClocksCounts[i] < (outsModesPlay[i] - 1)) { //-1?? + outsClocksCounts[i]++; + //if (i == 0) {Serial.println(outsClocksCounts[i]);} + } else { + outsClocksCounts[i] = 0; + } + } + } + beatCounted = true; + } + + //multiplier + for (int i = 0; i<6; i++) { + if (outsModesPlay[i] < 0) { + if (outsClocksCounts[i] == 0) { //Pulse on 0 + digitalWrite(outsPins[i], HIGH); + //Serial.print(" mult "); + } + if (outsClocksCounts[i] < (PPQN / abs(outsModesPlay[i])) - 1) { + outsClocksCounts[i]++; + //if (i == 1) {Serial.println(PPQN / abs(outsModesPlay[1]));} + } else { + outsClocksCounts[i] = 0; + } + } + } pulseCounted = true; } - //lets get internal pulse going + //internal pulse if (pulseClockCount == 0) { + //Serial.println(pulseCount); pulseCount++; + beatCounted = false; pulseCounted = false; - } + } if (pulseClockCount < pulsePeriod) { pulseClockCount++; } else { @@ -119,7 +167,7 @@ void internalClock() { } } -void updatePeriods() { +void updatePeriod() { pulsePeriod = 60000 / (bpm * PPQN); } @@ -158,8 +206,9 @@ void checkInputs() { int change = encPositionOld - encPosition; if (displayTab == 0) { bpm = bpm + change; + updatePeriod(); } else { - outsValues[displayTab-1] = outsValues[displayTab-1] + change; + outsModeIndex[displayTab-1] = outsModeIndex[displayTab-1] + change; needToResetChannel = displayTab-1; } updateScreen(); @@ -217,14 +266,16 @@ void updateScreen() { display.print(bpm); display.println(F("bpm")); } else { - if (outsValues[displayTab-1]==0) { + if (outsModes[outsModeIndex[displayTab-1]] == 0) { display.print(F("OFF")); - } else if (outsValues[displayTab-1]>0) { + } else if (outsModes[outsModeIndex[displayTab-1]] == 100) { + display.print(F("/RANDOM")); + } else if (outsModes[outsModeIndex[displayTab-1]]>0) { display.print(F("/")); - display.print(abs(outsValues[displayTab-1])); + display.print(abs(outsModes[outsModeIndex[displayTab-1]])); } else { display.print(F("x")); - display.print(abs(outsValues[displayTab-1])); + display.print(abs(outsModes[outsModeIndex[displayTab-1]])); } }