Note overlap/simultaneous key press for matrix CV keyoboard

I'm trying to program note overlap for my matrix cv keyboard project. I have got to the point where I can play each note but it has to be released before a new note can be pressed.

I have implemented the Multikey code from the keypad library into the main loop which shows press/release/hold/idle key presses in the serial monitor.

I believe i am writing to the DAC + turning gate on when key-pressed and turning gate off when key-released however my DAC value (DACnum) is only printing zero's + gate is not working either.

Can anyone point me in the right direction?

#include <Keypad.h>
#include <stdlib.h>
#include <Wire.h>//Include the Wire library to talk I2C
#include <Adafruit_MCP4725.h>

//This is the I2C Address of the MCP4725, by default (A0 pulled to GND).
#define MCP4725_ADDR 0x60

Adafruit_MCP4725 dac;

#define LED 13    // Arduino Board LED is on Pin 13
#define GATE A0 // Use Pin 0 to output GATE signal

int DACnum = 0;
int LEDval = LOW;
int GATEval = LOW;

const byte numRows = 6;
const byte numCols = 9;


//Code that shows the the keypad connections to the arduino terminals
byte colPins[numCols] = {13, 12, 11, 10, 9, 8, 4, 3, 2}; //Rows 0 to 3
byte rowPins[numRows] = {A1, A2, A3, A4, A5, A6}; //Columns 0 to 3


//keymap defines the key pressed according to the row and columns just as appears on the keypad
byte keymap[numRows][numCols] =
{
  {1, 7, 13, 19, 25},
  {2, 8, 14, 20, 26},
  {3, 9, 15, 21, 27},
  {4, 10, 16, 22, 28},
  {5, 11, 17, 23, 29},
  {6, 12, 18, 24},

};



// DAC = 4096/5 V/12 (for 1V per Octave) = 67.9 per step
unsigned int DACpitches[29] =
{

  0, 68,  137,  205,  273,  341,  410,  478,
  546,  614,  683,  751,  819,  887,  956, 1024,
  1092, 1161, 1229, 1297, 1365, 1434, 1502, 1570,
  1638, 1707, 1775, 1843, 1911,
};


//initializes an instance of the Keypad class
Keypad kpd = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

unsigned long loopCount;
unsigned long startTime;
String msg;

void setup()
{
  // initialize the serial communication:
  Serial.begin(19200);

  pinMode(GATE, OUTPUT); // Set GATE pin to output

  Wire.begin();
  dac.begin(0x60);

  loopCount = 0;
  startTime = millis();
  msg = "";


}

//If key is pressed, this key is stored in keyPadNum variable


void loop() {

  unsigned int KeyPadNum = kpd.getKey();

  unsigned int DACnum = DACpitches[KeyPadNum];

  loopCount++;
  if ( (millis() - startTime) > 5000 ) {
    //    Serial.print("Average loops per second = ");
    //   Serial.println(loopCount/5);
    startTime = millis();
    loopCount = 0;
  }

  // Fills kpd.key[ ] array with up-to 10 active keys.
  // Returns true if there are ANY active keys.
  if (kpd.getKeys())
  {
    for (int i = 0; i < LIST_MAX; i++) // Scan the whole key list.
    {
      if ( kpd.key[i].stateChanged )   // Only find keys that have changed state.
      {
        switch (kpd.key[i].kstate) {  // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
          case PRESSED:
            msg = "pressed";
            dac.setVoltage(DACnum, false);
            digitalWrite(GATE, HIGH); //Turn GATE on
            Serial.println(DACnum);

            break;
          case HOLD:
            msg = " HOLD.";
                digitalWrite(GATE, HIGH); //Turn GATE on
            break;
          case RELEASED:
            msg = "Released";
                digitalWrite(GATE,LOW);  //Turn GATE off
            break;
          case IDLE:
            msg = " IDLE.";
                digitalWrite(GATE,LOW);  //Turn GATE off
        }
        Serial.print("Key ");
        Serial.print(kpd.key[i].kchar);

         Serial.print(myKeypad.key[i].kchar);
        Serial.println(msg);
      }
    }
  }
}  // End loop

You seem to have an array of up to 10 keys which may be in Pressed state. As far as I can see you try to write to the DAC for any or all of them. That seems wrong because I assume your CV synth/device is monophonic. But what strategy are you planning to have when multiple notes are pressed? First note pressed is on? Last note pressed on? Highest or lowest note on? Something else?

I've never tried it but I'm guessing the reason you're currently getting nothing from the DAC is because you're using both the single key getKey() and the multikey getKeys(). I don't think you should be using both in the same program but I could be wrong.

Steve

Thanks for the reply! Basically i want to be able to play a note on the keyboard that outputs a gateON and the corresponding value to the DAC. If I then hold down any other key, this one takes priority but the gate will stay on until all keys are released. This is what i'm struggling with!

My Idea is to have something that counts how many keys are currently held down, giving priority to the highest number?

I think it would involve returning a value (1-10) from kpd.key and using it in an if statement inside KEY PRESSED case like: if new key < previous key then output new value to DAC. Then the oppsoite in KEY RELEASED case so it would step back down and output the last value to the DAC?

Not sure how to code this so any help would be appreciated!

So I've tried to simplify my code down to one problem at a time.

Using the multikey code from keypad library - I can have up to 10 keys held down at once.

How can I return a value 1-10 for each key pressed (eg 5 keys held down = print number 5)?

I'm trying to do this using kcode and saying "if one key is held down print 1" "if 2 keys are held down print 2"

Can anyone help with this please?

#include <Keypad.h>

const byte numRows = 6;
const byte numCols = 9;

//Code that shows the the keypad connections to the arduino terminals
byte colPins[numCols] = {13, 12, 11, 10, 9, 8, 4, 3, 2}; //Rows 0 to 3
byte rowPins[numRows] = {A1, A2, A3, A4, A5, A6}; //Columns 0 to 3

//keymap defines the key pressed according to the row and columns just as appears on the keypad
byte keymap[numRows][numCols] =
{
  {1, 7, 13, 19, 25},
  {2, 8, 14, 20, 26},
  {3, 9, 15, 21, 27},
  {4, 10, 16, 22, 28},
  {5, 11, 17, 23, 29},
  {6, 12, 18, 24},

};

//initializes an instance of the Keypad class
Keypad kpd = Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

void setup()
{
  // initialize the serial communication:
  Serial.begin(19200);

}

void loop() {


  char keyChar;
  int keyCode;
  KeyState keyState;
  boolean keyIsActive;

  // Fills kpd.key[ ] array with up-to 10 active keys.
  // Returns true if there are ANY active keys.
  if (kpd.getKeys())
  {
    for (int i = 0; i < LIST_MAX; i++) // Scan the whole key list.
    {
      if (kpd.key[i].stateChanged)   // Only find keys that have changed state.
      {
   

        if (kpd.key[i].kcode == 1 { //if 1 key held down

        serial.println("1");
        }
        if (kpd.key[i].kcode == 2 { //if 2 keys held down

        serial.println("2");

        }
        if (kpd.key[i].kcode == 3 { //if 3 keys held down

        serial.println("3");

        }
      }
    }
  }