Wiring Keypad pin as an interrupt

Hi there,
I have this project of a "phone". It consists of:

  • Arduino DUE,
  • 4x4 Keypad,
  • SD Data shield,
  • an Amp and a Speaker.

In the beginning, I need it to play a .wav file of an intro on how to choose a language. And this .wav should be interrupted when the user presses the 4th row of a keypad (Buttons A/B/C/D).
I only need one pin as far as I know, in this setup - pin 38 (Column 4 pin). As I understand, there is no proper way to have a keypad input pin as an interrupt on DUE.

So my question - how to wire a keypad input pin as an interrupt?
I have read about wiring with a diode. But most of the threads lack any specifics.

Can someone push me in the right direction?
Cheers!

The schematics (if you can call it that) below:

If anyone interested, my code so far:

#include <DAC.h>
#include <SD.h>
#include <SPI.h>
#include <Audio.h>
#include <Key.h>
#include <Keypad.h>

const byte ROW_NUM = 4;
const byte COLUMN_NUM = 4;

int code1 = 12345;  //The code I used, you can change it
int code2 = 45678;  //The code I used, you can change it
int code3 = 78900;  //The code I used, you can change it

int tot, i1, i2, i3, i4, i5;
char c1, c2, c3, c4;

char hexaKeys[ROW_NUM][COLUMN_NUM] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte interruptPin = 22;  // your interrupt pin
byte pin_rows[ROW_NUM] = {52, 50, 48, 46}; //connect to the row pinouts of the keypad
byte pin_column[COLUMN_NUM] = {44, 42, 40, 38}; //connect to the column pinouts of the keypad

int keyCounter = 0;

Keypad myKeypad = Keypad(makeKeymap(hexaKeys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM);

char keypresses[5];
char language;
char key;

volatile uint8_t interruptState = 0;


void setup() {
  // debug output at 9600 baud
  Serial.begin(9600);
  SD.begin(10);
  analogWriteResolution(12);

  pinMode(38, INPUT_PULLUP);
  
//  attachInterrupt(digitalPinToInterrupt(interruptPin), interruptToggle, RISING); //test interrupt with a regular button
  attachInterrupt(digitalPinToInterrupt(38), interruptToggle, RISING);
  
  DACC->DACC_CHDR = DACC_CHDR_CH1; //disable DAC1
}


int state = 0;
const int STATE_IDLE = 0;
const int STATE_LISTEN_KEY = 1;
const int STATE_PLAYER = 2;

bool isLanguageKey(char customKey) {
  return ('A' == customKey || 'B' == customKey || 'C' == customKey || 'D' == customKey);
}

void loop() {
  switch (state) {
    case STATE_IDLE:
    //listen for a language key. Cannot dial a number before
    
//      interruptState = digitalRead(38);   // read the input pin
//      Serial.println(interruptState);
               if (interruptState == 0) {
              playSound("intro.wav");
      Serial.print("interruptStateA ");
      Serial.println(interruptState);
               }
            else {
                buttonBeep();
                interruptState = 0;
        processLanguage();
        state = STATE_LISTEN_KEY;
        }
      break;
    case STATE_LISTEN_KEY:
    //listen for any key
      Serial.print("interruptStateD ");
      Serial.println(interruptState);
      if (isKeyPressed()) {
      Serial.print("interruptStateE ");
      Serial.println(interruptState);
                   buttonBeep();
        if (isLanguageKey(key)) {
          processLanguage();
        }
        else {
      Serial.print("interruptStateF ");
      Serial.println(interruptState);
          keypresses[keyCounter] = key;
          keyDial();
          keyCounter++;
          if (keyCounter > 4) {
            state = STATE_PLAYER;
            //when 5 numbers are pressed - try to open the .wav file
          }
        }
      }
      break;
    case STATE_PLAYER:
        //Play the audio and go back to state LISTEN
      calculateAndPlay();
      keyCounter = 0;
      interruptState = 0;
      state = STATE_LISTEN_KEY;
      //go back to the number dial (person will likely use the same language)
      break;
    default:
      break;
  }
}

void interruptToggle() {
    interruptState = 1;
}

void kalba() {
  Serial.println("Kalba? Language? Valoda? Yazik?");
}

bool isKeyPressed() {
  key = myKeypad.getKey();
  return key != NO_KEY;
}

bool langKeyPressed() {
  key = myKeypad.getKey();
  return key != NO_KEY && isLanguageKey(key);
}

void processLanguage() { //press A/B/C/D keys - select 1 out of 4 languages
  //goIntoKeys = 1;
  keyCounter = 0;
  if (key == 'A') {
    Serial.println("   LT    ");
  }
  if (key == 'B') {
    Serial.println("   EN    ");
  }
  if (key == 'C') {
    Serial.println("   LV    ");
  }
  if (key == 'D') {
    Serial.println("   RU    ");
  }
  language = key;
}


void keyDial() {    // LCD displays the number dialed in 3 slots.
  keypresses[keyCounter] = 0x00;//null-byte
  keypresses[keyCounter] = key;

  if (key != NO_KEY)   {
    Serial.println(keypresses[keyCounter]);
  }
}

void buttonBeep(){
      for (int j = 0; j < 200; j++) {
        for (int i = 0; i < 200; i++)
          analogWrite(DAC0, i);
        for (int i = 200; i >= 0; i--)
          analogWrite(DAC0, i);
      }
}

void backgroundHumm() {
      for (int j = 0; j < 256; j++) {
        for (int i = 0; i < 256; i++)
          analogWrite(DAC0, j);
          for (int j = 256; j >= 0; j--) {
            for (int i = 256; i >= 0; i--)
          analogWrite(DAC0, j);
      }
  }
}
 
void calculateAndPlay() {
  //if we have 4+1 numbers - proceed
  //the keys pressed are stored into chars I convert them to int then i did some multiplication to get the code as an int of xxxx
  i1 = (keypresses[0] - 48) * 10000;
  i2 = (keypresses[1] - 48) * 1000;
  i3 = (keypresses[2] - 48) * 100;
  i4 = (keypresses[3] - 48) * 10;
  i5 = (keypresses[4] - 48) * 1;  

  tot = i1 + i2 + i3 + i4 + i5;
  if (language == 'A') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiLT.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisLT.wav");
    }
    else if (tot == code3)
    {
      playSound("draugLT.wav");
    }
    else //if the code is wrong you get a beep and audio message
  {
      playSound("blogasLT.wav");
    }
  }
  if (language == 'B') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiEN.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisEN.wav");
    }
    else if (tot == code3)
    {
      playSound("draugEN.wav");
    }
    else //if the code is wrong you get a beep and audio message
    {
      playSound("blogasEN.wav");
    }
  }
  if (language == 'C') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiLV.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisLV.wav");
    }
    else if (tot == code3)
    {
      playSound("draugLV.wav");
    }
    else //if the code is wrong you get a beep and audio message
    {
      playSound("blogasLV.wav");
    }
  }
  if (language == 'D') {
    if (tot == code1) //if the code is correct you trigger to play .wav
    {
      playSound("ledaiRU.wav");
    }
    else if (tot == code2)
    {
      playSound("zuvisRU.wav");
    }
    else if (tot == code3)
    {
      playSound("draugRU.wav");
    }
    else //if the code is wrong you get a beep and audio message
    {
      playSound("blogasRU.wav");
    }
  }
}

// Playing assigned filename
void playSound(const char* cName) {  
  File myFile = SD.open(cName);
  const int S = 1024; // Number of samples to read in block
  short buffer[S];
  // until the file is not finished
  Serial.println("playing ");
  Serial.println(cName);


  Audio.begin(44100, 200);
  delay(200);
  while (myFile.available()) {
    myFile.read(buffer, sizeof(buffer));
    // Prepare samples
    int volume = 512;
    //max volume 1024
    Audio.prepare(buffer, S, volume);
    Audio.write(buffer, S);
   if ( interruptState ) break;
  }
  Audio.end();
  myFile.close();
  delay(50);
  DACC->DACC_CHDR = DACC_CHDR_CH1; //disable DAC1
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.