Make a synthesizer out of multiplexers!
Wed Apr 12 2023 05:58:32 GMT+0000 (Coordinated Universal Time)
Saved by @snh345 #arduino #c++ #synthesizer
// for LEDS #include <Adafruit_NeoPixel.h> #ifdef __AVR__ #include <avr/power.h> // Required for 16 MHz Adafruit Trinket #endif #include <Keypad.h> // int old_color_piano; int old_color_guitar; // for row/col scan bool initialized = false; const byte ROWS = 3; const byte COLS = 8; char fastPressed; int lastPressed; char hexaKeys[ROWS][COLS] = { {'0','1','2','3','4','5','6','7'}, {'8','9','A','B','C','D','E','F'}, {'G','H','I','J','K','L','M','N'} }; byte colPins[COLS] = {37,41,43,45,47,49,51,53}; byte rowPins[ROWS] = {31,33,35}; // this one im adding int current_button; Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS); // for the debouncer unsigned long lastDebounceTime = 0; // the last time the output pin was toggled unsigned long debounceDelay = 50; int lastButtonState = LOW; //#define LED_PIN 8 //#define LED_COUNT 60 int LED_PIN_piano = 13; int LED_PIN_guitar = 29; int LED_COUNT = 60; Adafruit_NeoPixel piano_strip(LED_COUNT, LED_PIN_piano, NEO_GRB + NEO_KHZ800); Adafruit_NeoPixel guitar_strip(LED_COUNT, LED_PIN_guitar, NEO_GRB + NEO_KHZ800); int current_step = 0; int old_color; // end LEDS // NEW AS OF 12/10 // C = 2,5 B = 6,3 A = 7,4 int g1[] = {0,0,0}; int g2[] = {0,0,0}; //int g2Pins[] = {5,6,7}; //int g1Pins[] = {2,3,4}; int g1Pins[] = {7,6,5}; int g2Pins[] = {4,3,2}; //int g1Pins[] = {5,6,7}; //int g2Pins[] = {2,3,4}; // C = 16,19 B = 15,18 A = 14,17 int p1[] = {0,0,0}; int p2[] = {0,0,0}; int p1Pins[] = {16,15,14}; int p2Pins[] = {19,18,17}; int potVal; int potVal_speed; int potPin_piano = A0; int potPin_guitar = A1; int potPin_speed = A2; int buttonPins[] = {41,43,45,47,49,51,53,52}; int buttonCounts[] = {0,0,0,0,0,0,0,0}; //int piano_steps[] = {1,8,11,0,20,0,23,17}; int piano_steps[] = {1,0,3,0,5,0,0,7}; //int guitar_steps[] = {0,1,2,3,4,5,6}; int guitar_steps[] = {17,17,17,17,17,17,17,0}; int modeButton = 10; // END NEW /// FROM 12_9_PUTTINGTOGETHER int prevStateMode = 0; int lastDebounceTimeMode = 0; int buttonStateMode = 0; int lastButtonStateMode = 0; // mode_bool must be false on init // false -> write mode, true -> play mode int mode_bool = true; int just_pressed[] = {false,false,false,false,false,false,false,false}; int still_pressed[] = {false,false,false,false,false,false,false,false}; int debounced_times[] = {0,0,0,0,0,0,0,0}; int just_pressed_mode = false; int still_pressed_mode = false; int debounced_times_mode = 0; int wait_time = 1000; // // for piano int myArray[40][6]{ {0,0,0,0,0,0}, {0,0,0,0,0,1}, {0,0,0,0,1,0}, {0,0,0,0,1,1}, {0,0,0,1,0,0}, {0,0,0,1,0,1}, {0,0,0,1,1,0}, {0,0,0,1,1,1}, {0,0,1,0,0,0}, {0,0,1,0,0,1}, {0,0,1,0,1,0}, {0,0,1,0,1,1}, {0,0,1,1,0,0}, {0,0,1,1,0,1}, {0,0,1,1,1,1}, {0,1,0,0,0,0}, {0,1,0,0,0,1}, {0,1,0,0,1,0}, {0,1,0,0,1,1}, {0,1,0,1,0,0}, {0,1,0,1,0,1}, {0,1,0,1,1,1}, {0,1,1,0,0,0}, {0,1,1,0,0,1}, {0,1,1,0,1,0}, {0,1,1,0,1,1}, {0,1,1,1,0,0}, {0,1,1,1,0,1}, {0,1,1,1,1,0}, {0,1,1,1,1,1}, {1,0,0,0,0,0}, {1,0,0,0,0,1}, {1,0,0,0,1,0}, {1,0,0,0,1,1}, {1,0,0,1,0,0}, {1,0,0,1,0,1}, {1,0,0,1,1,0}, {1,0,0,1,1,1}, {1,0,1,0,0,0}, {1,0,1,0,0,1}, // {1,0,1,0,1,0}, //{1,0,1,0,1,1} }; // for guitar int myArray_guitar[8][6]{ {0,0,0,0,0,0}, {0,0,0,0,0,1}, {0,0,0,0,1,0}, {0,0,0,0,1,1}, {0,0,1,0,0,0}, {0,0,1,0,0,1}, {0,0,1,0,1,0}, {0,0,1,0,1,1} }; void setup() { // for leds #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000) clock_prescale_set(clock_div_1); #endif // END of Trinket-specific code. piano_strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) piano_strip.show(); // Turn OFF all pixels ASAP piano_strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255) guitar_strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED) guitar_strip.show(); // Turn OFF all pixels ASAP guitar_strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255) // end LEDS Serial.begin(9600); pinMode(potPin_piano, INPUT); pinMode(potPin_guitar, INPUT); pinMode(potPin_speed, INPUT); // init mx/dmx for (int i = 0; i < 3; i++){ pinMode(g1Pins[i],OUTPUT); pinMode(g2Pins[i],OUTPUT); pinMode(p1Pins[i],OUTPUT); pinMode(p2Pins[i],OUTPUT); } // init buttons for (int i = 0; i < 8; i++){ pinMode(buttonPins[i], INPUT); } for(int i=0; i<8; i++) { piano_strip.setPixelColor(i+3,255,0,0); guitar_strip.setPixelColor(i+3,255,0,0); } piano_strip.show(); guitar_strip.show(); } void loop() { Serial.print(digitalRead(12)); //Serial.print(analogRead(A0)); //Serial.print(analogRead(A1)); //Serial.println(analogRead(A2)); // put your main code here, to run repeatedly: //Serial.println(digitalRead(modeButton)); if (!mode_bool) { new_write_mode(); } // Serial.print("piano "); // Serial.print(piano_steps[0]); // Serial.print(piano_steps[1]); // Serial.print(piano_steps[2]); // Serial.print(piano_steps[3]); // Serial.print(piano_steps[4]); // Serial.print(piano_steps[5]); // Serial.print(piano_steps[6]); // Serial.println(piano_steps[7]); //Serial.print("guitar "); // Serial.print(guitar_steps[0]); // Serial.print(guitar_steps[1]); // Serial.print(guitar_steps[2]); // Serial.print(guitar_steps[3]); // Serial.print(guitar_steps[4]); // Serial.print(guitar_steps[5]); // Serial.print(guitar_steps[6]); // Serial.println(guitar_steps[7]); // } if (mode_bool) { play_mode(); } checkModeButton(); } void checkButtons(){ Serial.println("write mode"); // iterate thru buttons for (int i = 0; i < 8; i++){ // for LEDS //if (steps[i] == 0) { //strip.setPixelColor(i,255,0,0); // } //else if (steps[i] != 0) { //strip.setPixelColor(i,0,0,255); // } // end LEDS // read button pin int buttonState = digitalRead(buttonPins[i]); if (buttonState == 1 && just_pressed[i] == false){ buttonCounts[i]++; // NEW if (buttonCounts[i] % 2 != 0){ debounced_times[i] = millis(); potVal = map(analogRead(potPin_piano), 0,920,0,35); //steps[i] = potVal; //Serial.println(steps[i]); if (millis() - debounced_times[i] > wait_time) { if (digitalRead(buttonPins[i] == 1)) { buttonCounts[i]++; } } if (buttonCounts[i] % 2 != 0) { // is this the right place to show lights? //strip.show(); break; } } } } } void play_mode() { Serial.println("read mode"); //for play mode test 12/11 3pm //int piano_steps[] = {10,11,12,0,13,14,0,25}; //int guitar_steps[] = {0,1,2,3,4,5,6,7}; //int piano_steps[] = {0,1,2,3,4,5,6,7}; for (int i = 0; i < 8; i++){ // iterate thru all 8 steps //Serial.println("read mode"); int t_piano = piano_steps[i]; int t_guitar = guitar_steps[i]; checkModeButton(); // TODO IMPLEMENT FOR MULTIPLE LED STRIPS play_mode_leds(i); for (int j = 0; j < 3; j++){ p1[j] = myArray[t_piano][j+3]; p2[j] = myArray[t_piano][j]; checkModeButton(); g2[j] = myArray[t_guitar][j+3]; g1[j] = myArray[t_guitar][j]; } // for (int i = 0; i < 3; i++){ // Serial.print(g1[i]); // } // for (int i = 0; i < 2; i++){ // Serial.print(g2[i]); // } // Serial.println(g2[2]); //atoi() // Serial.print(p1[0]); // Serial.print(p1[1]); // Serial.print(p1[2]); // Serial.print(p2[0]); // Serial.print(p2[1]); // Serial.println(p2[2]); checkModeButton(); for (int j = 0; j < 3; j++){ digitalWrite(p1Pins[j],p1[j]); digitalWrite(p2Pins[j],p2[j]); digitalWrite(g1Pins[j],g1[j]); digitalWrite(g2Pins[j],g2[j]); } wait_time = map(analogRead(potPin_speed),0,1000,100,800); checkModeButton(); delay(wait_time); } } void checkModeButton(){ //Serial.println("fug"); int reading = digitalRead(modeButton); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited long enough // since the last press to ignore any noise: // If the switch changed, due to noise or pressing: if (reading != prevStateMode) { // reset the debouncing timer lastDebounceTimeMode = millis(); } if ((millis() - lastDebounceTimeMode) > 50) { // whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state: //Serial.println("I am capable of extreme violence"); // if the button state has changed: if (reading != buttonStateMode) { buttonStateMode = reading; // only toggle the LED if the new button state is HIGH if (buttonStateMode == HIGH) { mode_bool = !mode_bool; } } } // save the reading. Next time through the loop, it'll be the lastButtonState: lastButtonState = reading; } void play_mode_leds(int current_step) { current_step = current_step+3; if (current_step > 0) { //old_color = strip.getPixelColor(current_step-1); piano_strip.setPixelColor(current_step-1,old_color_piano); guitar_strip.setPixelColor(current_step-1,old_color_guitar); if (piano_steps[current_step-1] == 0) { piano_strip.setPixelColor(current_step-1,255,0,0); } else if (piano_steps[current_step-1] != 0) { piano_strip.setPixelColor(current_step-1,0,0,255); } if (guitar_steps[current_step-1] == 0) { guitar_strip.setPixelColor(current_step-1,255,0,0); } else if (guitar_steps[current_step-1] != 0) { guitar_strip.setPixelColor(current_step-1,0,0,255); } } else if (current_step == 0) { //old_color = strip.getPixelColor(7); //strip.setPixelColor(7,old_color); if (piano_steps[7] == 0) { piano_strip.setPixelColor(7+3,255,0,0); } // else if (piano_steps[7] != 0) { else{ piano_strip.setPixelColor(7+3,0,0,255); } if (guitar_steps[7] == 0) { guitar_strip.setPixelColor(7+3,255,0,0); } else if (guitar_steps[7] != 0) { guitar_strip.setPixelColor(7+3,0,0,255); } } old_color_piano = piano_strip.getPixelColor(current_step); old_color_guitar = guitar_strip.getPixelColor(current_step); piano_strip.setPixelColor(current_step,0,255,0); guitar_strip.setPixelColor(current_step,0,255,0); //old_color = strip.getPixelColor(current_step-1) //strip.setPixelColor(current_step-1,old_color); piano_strip.show(); guitar_strip.show(); } void new_write_mode() { Serial.println("write mode"); //Serial.print("potVAL_no press "); //Serial.println(potVal); checkModeButton(); char customKey = customKeypad.getKey(); Serial.println(lastPressed); if (customKey != NO_KEY){ initialized = true; decoder(customKey); } if (lastPressed < 8 && initialized == true) { potVal = map(analogRead(potPin_piano),20,1000,0,35); Serial.print("potVAL "); Serial.println(potVal); piano_steps[lastPressed] = potVal; } else if (lastPressed > 7 && lastPressed < 16) { potVal = map(analogRead(potPin_guitar),0,1013,0,8); Serial.print("potVAL "); Serial.println(potVal); guitar_steps[lastPressed-8] = potVal; Serial.println(lastPressed); } for(int i=0; i<8; i++) { if (piano_steps[i] == 0) { piano_strip.setPixelColor(i+3,255,0,0); } else if (piano_steps[i] != 0) { piano_strip.setPixelColor(i+3,0,0,255); } if (guitar_steps[i] == 0) { guitar_strip.setPixelColor(i+3,255,0,0); } else if (guitar_steps[i] != 0) { guitar_strip.setPixelColor(i+3,0,0,255); } } piano_strip.show(); guitar_strip.show(); } void decoder(char myKey){ if (myKey == '0'){lastPressed = 7;} if (myKey == '1'){lastPressed = 6;} if (myKey == '2'){lastPressed = 5;} if (myKey == '3'){lastPressed = 4;} if (myKey == '4'){lastPressed = 3;} if (myKey == '5'){lastPressed = 2;} if (myKey == '6'){lastPressed = 1;} if (myKey == '7'){lastPressed = 0;} if (myKey == 'G'){lastPressed = 15;} if (myKey == 'H'){lastPressed = 14;} if (myKey == 'I'){lastPressed = 13;} if (myKey == 'J'){lastPressed = 12;} if (myKey == 'K'){lastPressed = 11;} if (myKey == 'L'){lastPressed = 10;} if (myKey == 'M'){lastPressed = 9;} if (myKey == 'N'){lastPressed = 8;} }
Man, I barely even remember how this stuff works. Big honkin' synthesizer code.
Comments