diff --git a/README.MD b/README.MD index 5937f46..919b332 100644 --- a/README.MD +++ b/README.MD @@ -3,17 +3,16 @@ Features: - Master BPM - Separate divider or multiplier per chennel (from /32 to x24) - Per-channel random pulse skip (currently only 50/50 chance) -- 2 inputs for external modulation (currently only 1, hardcoded to channel 6) +- 2 inputs for external modulation TODO: - per-channel modulation settings - different chance options for random -- External clock - Save state to EEPROM when stopped +- design PCB +- external clock - swing -- Switch to U8G2 for screen - settings (input mode, pulse length) -- Design PCB Timer library available here https://github.com/PaulStoffregen/FlexiTimer2 diff --git a/software/GToE/GToE.ino b/software/GToE/GToE.ino index b0d8537..953ce53 100644 --- a/software/GToE/GToE.ino +++ b/software/GToE/GToE.ino @@ -24,9 +24,10 @@ const int outsPins[6] = {5, 6, 7, 8, 9, 10}; const int outsModes[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 -int outsModeIndex[6] = {8, 9, 10, 7, 6, 6}; //10 - /1, 9 - off +int outsModeIndex[6] = {8, 9, 10, 7, 2, 6}; //8 - 1 bool outsRandom[6] = {0,0,0,0,0,1}; -bool outsMod[6] = {0,0,0,0,0,1}; //0 - A1, 1 - A2 +bool outsMod[6] = {0,0,0,0,1,1}; //0 - A1, 1 - A2 +int outsModRange[6] = {0,0,0,0,4,-4}; int outsPeriods[6]; int outsClocksCounts[6]; int outsModesPlay[6]; //actual channel modes array updated from outsModeIndex each beat @@ -45,11 +46,10 @@ int needToResetChannel; bool beatCounted = false; bool pulseCounted = false; - int displayTab = 0; int displayTabOld; -bool needToChangeTab = 0; -bool buttonPushed = false; +int insideTab = 0; +bool playBtnPushed = false; int a1Input = 0; int a2Input = 0; @@ -80,7 +80,7 @@ void setup() { display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS); updateScreen(); - updatePeriod(); + updateTiming(); FlexiTimer2::set(1, 1.0/1000, internalClock); // 1.0/1000 = 1ms period FlexiTimer2::start(); @@ -98,11 +98,14 @@ void internalClock() { //modulation for (int i = 0; i<6; i++) { + int mod; if (!outsMod[i]) { - outsModesPlay[i] = outsModes[outsModeIndex[i] - a1Input]; + mod = a1Input; } else { - outsModesPlay[i] = outsModes[outsModeIndex[i] - a2Input]; + mod = a2Input; } + mod = map (mod, 0, 1023, 0, outsModRange[i]); + outsModesPlay[i] = outsModes[outsModeIndex[i] - mod]; //subtrackting because the innitiall array is backwards } //divider @@ -171,7 +174,7 @@ void internalClock() { } } -void updatePeriod() { +void updateTiming() { pulsePeriod = 60000 / (bpm * PPQN); } @@ -200,15 +203,26 @@ void checkInputs() { Serial.println(encReleasedTime - encPressedTime); if (encReleasedTime - encPressedTime < 500) { // press shorter than .5s switches tabs - displayTabOld = displayTab; - displayTab++; - if (displayTab>6) { - displayTab = 0; + if (insideTab == 0) { + displayTabOld = displayTab; + displayTab++; + if (displayTab>6) { + displayTab = 0; + } + } else if (insideTab < 2) { + insideTab ++; + } else { + insideTab = 1; } - needToChangeTab = 0; updateScreen(); } else if (encReleasedTime - encPressedTime < 2000 && displayTab != 0) { // longer press (<2s) and switches random mode, longer than 2s presses are ignored - outsRandom[displayTab-1] = !outsRandom[displayTab-1]; + if (insideTab == 0) { + insideTab = 1; + } else { + insideTab = 0; + } + + //outsRandom[displayTab-1] = !outsRandom[displayTab-1]; updateScreen(); } } @@ -225,37 +239,36 @@ void checkInputs() { } else if (bpm < MINBPM) { bpm = MINBPM; } - updatePeriod(); - } else { + updateTiming(); + } else if (displayTab != 0 && insideTab == 0) { outsModeIndex[displayTab-1] = outsModeIndex[displayTab-1] - change; if (outsModeIndex[displayTab-1] < 0) { outsModeIndex[displayTab-1] = 0; } else if (outsModeIndex[displayTab-1] > (sizeof(outsModes)/sizeof(int)) - 1) { outsModeIndex[displayTab-1] = (sizeof(outsModes)/sizeof(int)) - 1; - } + } needToResetChannel = displayTab-1; + } else if (displayTab != 0 && insideTab == 1) { //random + outsRandom[displayTab-1] = !outsRandom[displayTab-1]; + } else if (displayTab != 0 && insideTab == 2) { //modulation + outsModRange[displayTab-1] = outsModRange[displayTab-1] + change; } updateScreen(); encPositionOld = encPosition; } //play button - if (!digitalRead(START_STOP_BTN_PIN) && !buttonPushed) { + if (!digitalRead(START_STOP_BTN_PIN) && !playBtnPushed) { isPlaying = !isPlaying; resetClocks(); - buttonPushed = true; - } else if (digitalRead(START_STOP_BTN_PIN) && buttonPushed) { - buttonPushed = false; + playBtnPushed = true; + } else if (digitalRead(START_STOP_BTN_PIN) && playBtnPushed) { + playBtnPushed = false; } //modulations a1Input = analogRead(ANALOGUE_INPUT_1_PIN); - - a1Input = map (a1Input, 0, 1023, 0, 4); a2Input = analogRead(ANALOGUE_INPUT_2_PIN); - Serial.println(a2Input); - a2Input = map (a2Input, 0, 1023, 0, 4); - } @@ -320,19 +333,41 @@ void updateScreen() { //Extra params display.setTextSize(1); - display.print(F("RND:")); if (displayTab != 0) { - if (outsRandom[displayTab-1]) { - display.print(F("On")); + if (insideTab == 1) { + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); } else { - display.print(F("Off")); + display.setTextColor(SSD1306_WHITE); } - display.setCursor(64,50); - display.print(F("MOD:")); - if (outsMod[displayTab-1]) { - display.print(F("A2 ")); + display.print(F(" RND:")); + if (outsRandom[displayTab-1]) { + display.print(F("On ")); } else { + display.print(F("Off ")); + } + display.setCursor(60,50); + if (insideTab == 2) { + display.setTextColor(SSD1306_BLACK, SSD1306_WHITE); + } else { + display.setTextColor(SSD1306_WHITE); + } + display.print(F(" MOD:")); + if (outsMod[displayTab-1] && outsModRange[displayTab-1] != 0) { + display.print(F("A2 ")); + if (outsModRange[displayTab-1] > 0) { + display.print(F("+")); + } + display.print(outsModRange[displayTab-1]); + display.print(F(" ")); + } else if (!outsMod[displayTab-1] && outsModRange[displayTab-1] != 0) { display.print(F("A1 ")); + if (outsModRange[displayTab-1] > 0) { + display.print(F("+")); + } + display.print(outsModRange[displayTab-1]); + display.print(F(" ")); + } else { + display.print(F("Off ")); } }