//DTMF Tone Decoder //Uses an Adafruit 4x4 Keypad #include // Inclusion de la librairie pour afficheur LCD #include // inclusion de la librairie pour clavier matriciel // --- Déclaration des constantes --- //--- Constantes utilisées avec le clavier 4x4 const byte LIGNES = 4; // 4 lignes const byte COLONNES = 4; //4 colonnes // --- constantes des broches --- const int C4=2; //declaration constante de broche const int C3=3; //declaration constante de broche const int C2=4; //declaration constante de broche const int C1=5; //declaration constante de broche const int RS=8; //declaration constante de broche const int E=9; //declaration constante de broche const int D4=10; //declaration constante de broche const int D5=11; //declaration constante de broche const int D6=12; //declaration constante de broche const int D7=13; //declaration constante de broche const int L4=16; //declaration constante de broche const int L3=17; //declaration constante de broche const int L2=18; //declaration constante de broche const int L1=19; //declaration constante de broche // --- Déclaration des variables globales --- //--- Définition des touches char touches[LIGNES][COLONNES] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','D'} }; // tableaux de lignes et colonnes byte BrochesLignes[LIGNES] = {L1, L2, L3, L4}; //connexions utilisées pour les broches de lignes du clavier byte BrochesColonnes[COLONNES] = {C1, C2, C3, C4}; //connexions utilisées pour les broches de colonnes du clavier char touche; // variable de stockage valeur touche appuyée // --- Déclaration des objets utiles pour les fonctionnalités utilisées --- LiquidCrystal lcd(RS, E, D4, D5, D6, D7);// Création d'un objet LiquidCrystal = initialisation LCD en mode 4 bits // création d'un objet keypad = initialisation clavier Keypad clavier = Keypad( makeKeymap(touches), BrochesLignes, BrochesColonnes, LIGNES, COLONNES ); // les broches de lignes sont automatiquement configurées en ENTREE avec pullup interne activé // les broches de colonnes sont automatiquement configurées en SORTIE // Pin allocation for keypad COLUMNS #define Col1 5 // pin for Col 1 #define Col2 4 // pin for Col 2 #define Col3 3 // pin for Col 3 #define Col4 2 // pin for Col 4 // Pin allocation for keypad ROWS #define Row1 19 // pin for Row 1 #define Row2 18 // pin for Row 2 #define Row3 17 // pin for Row 3 #define Row4 16 // pin for Row 4 // pin allocations for tone outputs #define tone1Pin 6 // pin for tone 1 #define tone2Pin 7 // pin for tone 2 #define NoKey 0xff // no key pressed const byte columns[] = {Col1, Col2, Col3, Col4}; // list of all columns const byte rows[] = {Row1, Row2, Row3, Row4}; // list of all rows const byte NumCols = sizeof(columns) / sizeof(byte); // calculate number of columns const byte NumRows = sizeof(rows) / sizeof(byte); // calculate number of rows byte LastKey = NoKey; // last key pressed int DTMF[][2] = { {697, 1209}, // frequencies for key 1 {770, 1209}, // frequencies for key 4 {852, 1209}, // frequencies for key 7 {941, 1209}, // frequencies for key * {697, 1336}, // frequencies for key 2 {770, 1336}, // frequencies for key 5 {852, 1336}, // frequencies for key 8 {941, 1336}, // frequencies for key 0 {697, 1477}, // frequencies for key 3 {770, 1477}, // frequencies for key 6 {852, 1477}, // frequencies for key 9 {941, 1477}, // frequencies for key # {697, 1633}, // frequencies for key A {770, 1633}, // frequencies for key B {852, 1633}, // frequencies for key C {941, 1633}, // frequencies for key D }; int ReadKeyPad() { byte result = NoKey; // no key pressed for (int c = 0; c < NumCols; c++) digitalWrite(columns[c], HIGH); // set all columns HIGH for (int c = 0; c < NumCols; c++) { // scan each column digitalWrite(columns[c], LOW); // set column LOW for (int r = 0; r < NumRows; r++) { // scan each row for LOW on any row if (digitalRead(rows[r]) == LOW) { delay(50); // in case of bounce if (digitalRead(rows[r]) == LOW) return c * 4 + r; } } digitalWrite(columns[c], HIGH); } return result; } void setup() { // initialise row readers for (int i = 0; i < NumRows; i++) pinMode(rows[i], INPUT_PULLUP); // Set row drivers to INPUT // initialise column drivers for (int i = 0; i < NumCols; i++) { pinMode(columns[i], OUTPUT); // Set column drivers to OUTPUT digitalWrite(columns[i], HIGH); } pinMode(tone1Pin, OUTPUT); // Output for Tone 1 pinMode(tone2Pin, OUTPUT); // Output for Tone 2 Serial.begin(9600); // Set serial port speed lcd.begin(16,2); // Initialise le LCD avec 20 colonnes x 4 lignes delay(10); // pause rapide pour laisser temps initialisation // Test du LCD lcd.print("LCD OK") ; // affiche la chaîne texte - message de test delay(2000); // pause de 2 secondes lcd.clear(); // // efface écran et met le curseur en haut à gauche delay(10); // pour laisser temps effacer écran lcd.print("GENERATEUR DTMF");// Print a message to the LCD. // les broches de lignes et d'entrée sont configurées automatiquement lors de l'initialisation du clavier // ------- Broches en sortie ------- // ------- Broches en entrée ------- // ------- Activation du rappel au + interne des broches en entrée si nécessaire ------- } void loop(){ // debut de la fonction loop() // --- ici instructions à exécuter par le programme principal --- byte key = ReadKeyPad(); // read any key being pressed if (key != LastKey) // key has changed switch (key) { case NoKey: break; // nothing to do default: // play tones Serial.print("Pressed "); Serial.println(key); // Debug only playDTMF(key, 200); // changes tone length break; } LastKey = key; // remember last key pressed } void playDTMF(byte digit, unsigned long duration) { // Play the DTMF digit for duration millisecs unsigned long tone1delay = (500000 / DTMF[digit][0]) - 10; // calculate delay (in microseconds) for tone 1 (half of the period of one cycle). 10 is a fudge factor to raise the frequency due to sluggish timing. unsigned long tone2delay = (500000 / DTMF[digit][1]) - 10; // calculate delay (in microseconds) for tone 2 (half of the period of one cycle). 10 is a fudge factor to raise the frequency due to sluggish timing. unsigned long tone1timer = micros(); unsigned long tone2timer = micros(); unsigned long timer = millis(); // for timing duration of a single tone while (millis() - timer < duration) { if (micros() - tone1timer > tone1delay) { tone1timer = micros(); // reset the timer if (digitalRead(tone1Pin) == HIGH) digitalWrite(tone1Pin, LOW); else digitalWrite(tone1Pin, HIGH); // toggle tone output } if (micros() - tone2timer > tone2delay) { tone2timer = micros(); // reset the timer if (digitalRead(tone2Pin) == HIGH) digitalWrite(tone2Pin, LOW); else digitalWrite(tone2Pin, HIGH); // toggle tone output } } digitalWrite(tone1Pin, LOW); digitalWrite(tone2Pin, LOW); // debut de la fonction loop() // --- ici instructions à exécuter par le programme principal --- touche = clavier.getKey(); // lecture de la touche appuyée if (touche != NO_KEY){ // si une touche a été frappée -- gestion de la touche appuyée lcd.print(touche); // efface écran si appui # sinon affiche touche delay(300); // pause entre 2 appuis } { // set the cursor to column 0, line 1 // (note: line 1 is the second row, since counting begins with 0): lcd.setCursor(7, 2); } }