| #include <Audio.h> | |||||
| #include <Wire.h> | |||||
| #include <SD.h> | |||||
| // Create the Audio components. These should be created in the | |||||
| // order data flows, inputs/sources -> processing -> outputs | |||||
| // | |||||
| AudioInputI2S audioIn; | |||||
| AudioAnalyzeToneDetect row1; // 7 tone detectors are needed | |||||
| AudioAnalyzeToneDetect row2; // to receive DTMF dial tones | |||||
| AudioAnalyzeToneDetect row3; | |||||
| AudioAnalyzeToneDetect row4; | |||||
| AudioAnalyzeToneDetect column1; | |||||
| AudioAnalyzeToneDetect column2; | |||||
| AudioAnalyzeToneDetect column3; | |||||
| AudioSynthWaveform sine1(AudioWaveformSine); // 2 sine wave | |||||
| AudioSynthWaveform sine2(AudioWaveformSine); // to create DTMF | |||||
| AudioMixer4 mixer; | |||||
| AudioOutputI2S audioOut; | |||||
| // Create Audio connections between the components | |||||
| // | |||||
| AudioConnection c01(audioIn, 0, row1, 0); | |||||
| AudioConnection c02(audioIn, 0, row2, 0); | |||||
| AudioConnection c03(audioIn, 0, row3, 0); | |||||
| AudioConnection c04(audioIn, 0, row4, 0); | |||||
| AudioConnection c05(audioIn, 0, column1, 0); | |||||
| AudioConnection c06(audioIn, 0, column2, 0); | |||||
| AudioConnection c07(audioIn, 0, column3, 0); | |||||
| AudioConnection c10(sine1, 0, mixer, 0); | |||||
| AudioConnection c11(sine2, 0, mixer, 1); | |||||
| AudioConnection c12(mixer, 0, audioOut, 0); | |||||
| AudioConnection c13(mixer, 0, audioOut, 1); | |||||
| // Create an object to control the audio shield. | |||||
| // | |||||
| AudioControlSGTL5000 audioShield; | |||||
| void setup() { | |||||
| // Audio connections require memory to work. For more | |||||
| // detailed information, see the MemoryAndCpuUsage example | |||||
| AudioMemory(12); | |||||
| // Enable the audio shield and set the output volume. | |||||
| audioShield.enable(); | |||||
| audioShield.volume(82); | |||||
| while (!Serial) ; | |||||
| delay(100); | |||||
| // Configure the tone detectors with the frequency and number | |||||
| // of cycles to match. These numbers were picked for match | |||||
| // times of approx 30 ms. Longer times are more precise. | |||||
| row1.frequency(697, 21); | |||||
| row2.frequency(770, 23); | |||||
| row3.frequency(852, 25); | |||||
| row4.frequency(941, 28); | |||||
| column1.frequency(1209, 36); | |||||
| column2.frequency(1336, 40); | |||||
| column3.frequency(1477, 44); | |||||
| } | |||||
| const float row_threshold = 0.2; | |||||
| const float column_threshold = 0.2; | |||||
| void loop() { | |||||
| float r1, r2, r3, r4, c1, c2, c3; | |||||
| char digit=0; | |||||
| // read all seven tone detectors | |||||
| r1 = row1.read(); | |||||
| r2 = row2.read(); | |||||
| r3 = row3.read(); | |||||
| r4 = row4.read(); | |||||
| c1 = column1.read(); | |||||
| c2 = column2.read(); | |||||
| c3 = column3.read(); | |||||
| // print the raw data, for troubleshooting | |||||
| Serial.print("tones: "); | |||||
| Serial.print(r1); | |||||
| Serial.print(", "); | |||||
| Serial.print(r2); | |||||
| Serial.print(", "); | |||||
| Serial.print(r3); | |||||
| Serial.print(", "); | |||||
| Serial.print(r4); | |||||
| Serial.print(", "); | |||||
| Serial.print(c1); | |||||
| Serial.print(", "); | |||||
| Serial.print(c2); | |||||
| Serial.print(", "); | |||||
| Serial.print(c3); | |||||
| // check all 12 combinations for key press | |||||
| if (r1 >= row_threshold) { | |||||
| if (c1 > column_threshold) { | |||||
| digit = '1'; | |||||
| } else if (c2 > column_threshold) { | |||||
| digit = '2'; | |||||
| } else if (c3 > column_threshold) { | |||||
| digit = '3'; | |||||
| } | |||||
| } else if (r2 >= row_threshold) { | |||||
| if (c1 > column_threshold) { | |||||
| digit = '4'; | |||||
| } else if (c2 > column_threshold) { | |||||
| digit = '5'; | |||||
| } else if (c3 > column_threshold) { | |||||
| digit = '6'; | |||||
| } | |||||
| } else if (r3 >= row_threshold) { | |||||
| if (c1 > column_threshold) { | |||||
| digit = '7'; | |||||
| } else if (c2 > column_threshold) { | |||||
| digit = '8'; | |||||
| } else if (c3 > column_threshold) { | |||||
| digit = '9'; | |||||
| } | |||||
| } else if (r4 >= row_threshold) { | |||||
| if (c1 > column_threshold) { | |||||
| digit = '*'; | |||||
| } else if (c2 > column_threshold) { | |||||
| digit = '0'; | |||||
| } else if (c3 > column_threshold) { | |||||
| digit = '#'; | |||||
| } | |||||
| } | |||||
| // print the key, if any found | |||||
| if (digit > 0) { | |||||
| Serial.print(" --> Key: "); | |||||
| Serial.print(digit); | |||||
| } | |||||
| Serial.println(); | |||||
| // uncomment these lines to see how much CPU time | |||||
| // the tone detectors and audio library are using | |||||
| //Serial.print("CPU="); | |||||
| //Serial.print(AudioProcessorUsage()); | |||||
| //Serial.print("%, max="); | |||||
| //Serial.print(AudioProcessorUsageMax()); | |||||
| //Serial.print("% "); | |||||
| // check if any data has arrived from the serial monitor | |||||
| if (Serial.available()) { | |||||
| char key = Serial.read(); | |||||
| int low=0; | |||||
| int high=0; | |||||
| if (key == '1') { | |||||
| low = 697; | |||||
| high = 1209; | |||||
| } else if (key == '2') { | |||||
| low = 697; | |||||
| high = 1336; | |||||
| } else if (key == '3') { | |||||
| low = 697; | |||||
| high = 1477; | |||||
| } else if (key == '4') { | |||||
| low = 770; | |||||
| high = 1209; | |||||
| } else if (key == '5') { | |||||
| low = 770; | |||||
| high = 1336; | |||||
| } else if (key == '6') { | |||||
| low = 770; | |||||
| high = 1477; | |||||
| } else if (key == '7') { | |||||
| low = 852; | |||||
| high = 1209; | |||||
| } else if (key == '8') { | |||||
| low = 852; | |||||
| high = 1336; | |||||
| } else if (key == '9') { | |||||
| low = 852; | |||||
| high = 1477; | |||||
| } else if (key == '*') { | |||||
| low = 941; | |||||
| high = 1209; | |||||
| } else if (key == '0') { | |||||
| low = 941; | |||||
| high = 1336; | |||||
| } else if (key == '#') { | |||||
| low = 941; | |||||
| high = 1477; | |||||
| } | |||||
| // play the DTMF tones, if characters send from the Arduino Serial Monitor | |||||
| if (low > 0 && high > 0) { | |||||
| Serial.print("Output sound for key "); | |||||
| Serial.print(key); | |||||
| Serial.print(", low freq="); | |||||
| Serial.print(low); | |||||
| Serial.print(", high freq="); | |||||
| Serial.print(high); | |||||
| Serial.println(); | |||||
| AudioNoInterrupts(); // disable audio library momentarily | |||||
| sine1.frequency(low); | |||||
| sine1.amplitude(0.4); | |||||
| sine2.frequency(high); | |||||
| sine2.amplitude(0.45); | |||||
| AudioInterrupts(); // enable, both tones will start together | |||||
| delay(100); // let the sound play for 0.1 second | |||||
| AudioNoInterrupts(); | |||||
| sine1.amplitude(0); | |||||
| sine2.amplitude(0); | |||||
| AudioInterrupts(); | |||||
| delay(50); // make sure we have 0.05 second silence after | |||||
| } | |||||
| } | |||||
| delay(25); | |||||
| } | |||||