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
}