diff --git a/Extra/CVTest/CVTest.ino b/Extra/CVTest/CVTest.ino new file mode 100644 index 0000000..4e95e6a --- /dev/null +++ b/Extra/CVTest/CVTest.ino @@ -0,0 +1,150 @@ +#include +#include +#include +#include + +#define SCREEN_ADDRESS 0x3C + +// Rev 2 and 3 Config +#define ENC_BTN_PIN 14 +#define ENC_D1_PIN 17 +#define ENC_D2_PIN 4 +#define START_STOP_BTN_PIN 5 +#define SHIFT_BTN_PIN 12 +#define EXT_INPUT_PIN 2 //needs to be an interrupt pin +#define ANALOGUE_INPUT_1_PIN A7 +#define ANALOGUE_INPUT_2_PIN A6 +const byte outsPins[6] = { 7, 8, 10, 6, 9, 11 }; +const byte clockOutPin = 3; + +int CV1Calibration = 0; +int CV2Calibration = 0; +bool rotateScreen = false; + + +int a1Input = 0; +int a2Input = 0; + + +U8G2_SSD1306_128X64_NONAME_2_HW_I2C u8g2(U8G2_R2, SCL, SDA, U8X8_PIN_NONE); + +//Font +const uint8_t velvetscreen[437] U8G2_FONT_SECTION("velvetscreen") = + "\64\0\2\2\3\3\2\3\4\5\5\0\0\5\0\5\0\0\221\0\0\1\230 \4\200\134%\11\255tT" + "R\271RI(\6\252\334T\31)\7\252\134bJ\12+\7\233\345\322J\0,\5\221T\4-\5\213" + "f\6.\5\211T\2/\6\244\354c\33\60\10\254\354T\64\223\2\61\7\353\354\222\254\6\62\11\254l" + "\66J*\217\0\63\11\254l\66J\32\215\4\64\10\254l\242\34\272\0\65\11\254l\206\336h$\0\66" + "\11\254\354T^\61)\0\67\10\254lF\216u\4\70\11\254\354TL*&\5\71\11\254\354TL;" + ")\0:\6\231UR\0A\10\254\354T\34S\6B\11\254lV\34)\216\4C\11\254\354T\324\61" + ")\0D\10\254lV\64G\2E\10\254l\206\36z\4F\10\254l\206^\71\3G\11\254\354TN" + "\63)\0H\10\254l\242\34S\6I\6\251T\206\0J\10\254\354k\231\24\0K\11\254l\242J\62" + "\225\1L\7\254lr{\4M\11\255t\362ZI\353\0N\11\255t\362TI\356\0O\10\254\354T" + "\64\223\2P\11\254lV\34)g\0Q\10\254\354T\264b\12R\10\254lV\34\251\31S\11\254\354" + "FF\32\215\4T\7\253dVl\1U\10\254l\242\63)\0V\11\255t\262Ne\312\21W\12\255" + "t\262J*\251.\0X\11\254l\242L*\312\0Y\12\255tr\252\63\312(\2Z\7\253df*" + "\7p\10\255\364V\266\323\2q\7\255\364\216\257\5r\10\253d\242\32*\2t\6\255t\376#w\11" + "\255\364V\245FN\13x\6\233dR\7\0\0\0\4\377\377\0"; + +const uint8_t fabryka[450] U8G2_FONT_SECTION("fabryka") = + "\17\0\4\4\4\5\2\1\6\17\30\1\0\30\0\0\0\1K\0\0\1\245%'\17\37\313\330R#&" + "\32!F\14\211I\310\24!\65\204(MF\21)Cd\304\10\62b\14\215\60Vb\334\20\0/\15" + "\376\36\357\244$\351\77\35;\26\0\60$\216\37\17*\65,\210\35\264\335\61T\42\14\11\61#\306\210" + " \23\242\220\235\63h\303c$\330\250B\3\0\61\27\216\37\27\311\202\346\216\221\30Ed\324\230Q\202" + "\306\316\377\263\26\35\62\33\216\37\17*\65,\210\35\64\70v\246\344\316h\203\252$\321\261s\373\340\1" + "\3\63\35\216\37\17*\65,\210\35\64\70v(IZZKv\266\6\15\36#\301F\25\32\0\64\37" + "\216\37\227\240\331\20\32Bj\310\260\21\304F\214\33\61n\304\70\203\366\360\301\203\20m\347\3\65\32\216" + "\37\7\213.\306\316'\205\326\60!E\226\354\334\32 (CV1Calibration)) { + a1Input = map(analogRead(ANALOGUE_INPUT_1_PIN), CV1Calibration, 1023, 512, 1023); + } else if (analogRead(ANALOGUE_INPUT_1_PIN) < (CV1Calibration)) { + a1Input = map(analogRead(ANALOGUE_INPUT_1_PIN), 0, CV1Calibration, 0, 512); + } else { + a1Input = 512; + } + //a2Input = map(analogRead(ANALOGUE_INPUT_2_PIN), 0 - CV2Calibration, 1023 - CV2Calibration, 0, 1023); +} + +void updateScreen() { + + u8g2.firstPage(); + do { + u8g2.setFont(velvetscreen); + String valueStr = String(analogRead(ANALOGUE_INPUT_1_PIN)); + char valueChar[16]; + + u8g2.drawStr(10, 8, "CV1:"); + valueStr.toCharArray(valueChar, 16); + u8g2.drawStr(32, 8, valueChar); + + u8g2.drawStr(64, 8, "CAL:"); + valueStr = String(a1Input); + valueStr.toCharArray(valueChar, 16); + u8g2.drawStr(86, 8, valueChar); + + u8g2.drawStr(10, 16, "MAP:"); + valueStr = String(map(a1Input, -1, 1024, -6, 6)); + valueStr.toCharArray(valueChar, 16); + u8g2.drawStr(32, 16, valueChar); + + /* + u8g2.drawStr(10, 32, "CV2:"); + valueStr = String(analogRead(ANALOGUE_INPUT_2_PIN)); + valueStr.toCharArray(valueChar, 16); + u8g2.drawStr(32, 32, valueChar); + u8g2.drawStr(64, 32, "CAL:"); + valueStr = String(analogRead(a2Input)); + valueStr.toCharArray(valueChar, 16); + u8g2.drawStr(86, 32, valueChar);*/ + + if (!digitalRead(SHIFT_BTN_PIN)) { + calibrateCVs(); + u8g2.drawStr(40, 64, "CALIBRATING"); + } + + } while ( u8g2.nextPage() ); +} + +void calibrateCVs() { + CV1Calibration = analogRead(ANALOGUE_INPUT_1_PIN); + CV2Calibration = analogRead(ANALOGUE_INPUT_2_PIN); + //CV1Calibration = 255 - (analogRead(ANALOGUE_INPUT_1_PIN) / 2); + //CV2Calibration = 255 - (analogRead(ANALOGUE_INPUT_2_PIN) / 2); +} + +void checkScreenRotation() { + if (rotateScreen) { + u8g2.setDisplayRotation(U8G2_R0); + } else { + u8g2.setDisplayRotation(U8G2_R2); + } +} \ No newline at end of file diff --git a/Software/Gravity/Gravity.ino b/Software/Gravity/Gravity.ino index 62ec58c..72f7f48 100644 --- a/Software/Gravity/Gravity.ino +++ b/Software/Gravity/Gravity.ino @@ -40,21 +40,21 @@ struct channel { byte mode; //0 - CLK, 1 - RND, 2 - SEQ byte subDiv; byte CV1Target; //0 - Off, 1 - Subdiv, 2 - RND, 3 - SeqPattern - byte CV1Value; + byte CV1Range; byte CV2Target; - byte CV2Value; + byte CV2Range; byte offset; byte random; byte seqPattern; }; channel channels[6] = { //array of channel settings - { 0, 7, 0, 3, 0, 3, 0, 0, 0 }, - { 0, 7, 0, 3, 0, 3, 0, 0, 0 }, - { 0, 7, 0, 3, 0, 3, 0, 0, 0 }, - { 0, 7, 0, 3, 0, 3, 0, 0, 0 }, - { 0, 7, 0, 3, 0, 3, 0, 0, 0 }, - { 0, 7, 0, 3, 0, 3, 0, 0, 0 } + { 0, 7, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 7, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 7, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 7, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 7, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 7, 0, 0, 0, 0, 0, 0, 0 } }; bool seqA1[16] = {1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1}; @@ -82,7 +82,7 @@ byte memCode = 'A'; //Change to different letter if you changed the data structu unsigned int channelPulseCount[6]; unsigned int channelPulsesPerCycle[6]; byte sixteenthPulseCount = 0; -int playingModes[6]; //actual channel modes array updated from channels object on each beat +int playingModes[6]; // should be renamed to currentSubdivs or something. Updated from channels object on beat and with applied CV modulation unsigned int pulsePeriod; bool isPlaying = false; @@ -158,23 +158,7 @@ const uint8_t fabryka[450] U8G2_FONT_SECTION("fabryka") = "\65L\206\221\30\67b\334\210q#\306\215\30\67b\30\11&\234\14#\61\356\240\275{ \242\5\23\0" "x\32\336\36\303\300c$\10\221!B\12\235I\222\346P\21!C\210\4\261\203\3\0\0\0\4\377\377" "\0"; - -static const uint16_t fabryka_first_encoding_table[4] = { - 47, 49, 55, 65535}; -static const uint16_t fabryka_index_to_second_table[4] = { - 0, 5, 6, 11}; -static const uint16_t fabryka_second_encoding_table[11] = { - 47, 49, 50, 51, 55, 52, 37, 52, 65, 66, 120}; -static const uint8_t fabryka_kerning_values[11] = { - 10, 6, 2, 4, 9, 5, 2, 3, 2, 2, 2}; -u8g2_kerning_t fabryka_k = { - 4, 11, - fabryka_first_encoding_table, - fabryka_index_to_second_table, - fabryka_second_encoding_table, - fabryka_kerning_values}; - - + void setup() { //Serial.begin(9600); @@ -287,9 +271,9 @@ void sendTriggers() { int seqMod = 0; byte seqPattern; if (channels[i].CV2Target == 3) { - seqMod = map(a2Input, 0, 1023, -8, 8); + seqMod = map(a2Input, -1, 1024, -8, 8); //-1 and 1024 are to try to make the last step not at max value (should make the range from -7 to +7) } else if (channels[i].CV1Target == 3) { - seqMod = map(a1Input, 0, 1023, -8, 8); + seqMod = map(a1Input, -1, 1024, -8, 8); } if (channels[i].seqPattern < 8 && channels[i].seqPattern + seqMod >= 8) { seqPattern = 7; @@ -388,7 +372,6 @@ void sendTriggers() { randAmount = 10; } - if ((channels[i].mode == 0 && channelPulseCount[i] == channels[i].offset) //CLK with offset || (channels[i].mode == 1 && channelPulseCount[i] == 0 && (random(10) + 1) > randAmount) //RND ) { @@ -406,19 +389,13 @@ void sendTriggers() { void calculateCycles() { for (byte i = 0; i < 6; i++) { - if (channels[i].CV1Target != 1 && channels[i].CV2Target != 1) { - playingModes[i] = subDivs[channels[i].subDiv]; - } else if (channels[i].CV1Target == 1) { //subdiv modulation happens here - int mod; - mod = a1Input; - mod = map(mod, 0, 1023, (channels[i].CV1Value * -1), channels[i].CV1Value); - playingModes[i] = subDivs[channels[i].subDiv - mod]; //subtracting because the innitial array is backwards + int mod = 0; //subdiv modulation happens here + if (channels[i].CV1Target == 1) { + mod = map(a1Input, -1, 1024, -5, 5); //(channels[i].CV1Value * -1), channels[i].CV1Value) } else if (channels[i].CV2Target == 1) { - int mod; - mod = a2Input; - mod = map(mod, 0, 1023, (channels[i].CV2Value * -1), channels[i].CV2Value); - playingModes[i] = subDivs[channels[i].subDiv - mod]; + mod = map(a2Input, -1, 1024, -5, 5); } + playingModes[i] = subDivs[channels[i].subDiv - mod]; //subtracting because the innitial array is backwards if (playingModes[i] > 0 && channels[i].mode != 2) { channelPulsesPerCycle[i] = (playingModes[i] * PPQN) - 1; diff --git a/Software/Gravity/UI.ino b/Software/Gravity/UI.ino index 75594fe..6b7bafd 100644 --- a/Software/Gravity/UI.ino +++ b/Software/Gravity/UI.ino @@ -316,7 +316,6 @@ void updateScreen() { //Settings Screen else if (displayScreen == 2) { - //u8g2.drawButtonUTF8(64, 5, U8G2_BTN_BW1|U8G2_BTN_HCENTER, 128, 0, 2, "SETTINGS" ); u8g2.drawStr(8, 5,"SETTINGS" ); u8g2.drawStr(102, 5, version ); u8g2.drawHLine(0, 8, 128);