Make a synthesizer out of multiplexers!

PHOTO EMBED

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;}

  }
content_copyCOPY

Man, I barely even remember how this stuff works. Big honkin' synthesizer code.