// GENERATEUR de Signaux Carrés Basse Fréquence, Version V2 // - Affichage 4 digits à virgule mobile, piloté par un 74HC595 // Partie Générateur BF : // - Plage théorique des Fréquences Arduino : 31 Hz à 65.535 Hz ; MAIS Fréquences hautes et Raport Cyclique instables // - Réglage de la Fréquence par Potentiomètre, et Choix de 5 Gammes par poussoir // - Formule de calcul de FREQUENCE = a * MEMO + b ( avec : b min = 31 ) // - Calcul de a et b : Voir fichier "CALCUL Géné BF.xlsx" // ---------- BIBLIOTHEQUE TridentTD_7Segs74HC595.h - Appel et Configuration -------------------------------------------------------------- #include // Appel de la Bibliothèque de l'afficheur 74HC595 #define SCLK 5 // SCLK (Clock) broche D5 (pin 8) #define RCLK 6 // RCLK (Latch) broche D6 (pin 9) #define DIO 7 // DIO (Data) broche D7 (pin 10) TridentTD_7Segs74HC595 my7SEGMENT( SCLK, RCLK, DIO); // Configuration de la Bibliothèque // ---------- VARIABLES GLOBALES ---------------------------------------------------------------------------------------------------------- const int POTAR = A0 ; // ENTREE = entrée Analogique "A0" (pin 19) - de 0 à 1023 const byte SORTIE = 9 ; // Sortie Logique du signal carré Basse Fréquence en D9 (pin 12) unsigned long SOMME = 0 ; // SOMME pour le calcul de la moyenne (permet 4.000.000 de mesures!) int MOYENNE = 0 ; // MOYENNE des Mesures du "POTAR" (0 à 1023) const unsigned int NOMBRE = 20 ; // Nombre de mesures pour calcul de la moyenne (NOMBRE < 4.000.000) int MEMO = 0 ; // Variable qui mémorise la "MOYENNE", et qui est prise comme Consigne float FREQUENCE = 0 ; // Valeur de la Fréquence calculée à partir de MEMO float AFFICH = 0 ; // Valeur à afficher si la FREQUENCE est supérieure à 9999 Hz const int HYST = 1 ; // Variation requise pour prendre en compte une nouvelle valeur (diminue l'instabillité) int i = 0 ; // Variable d'incrémentation int GAMME = 0 ; // N° de la GAMME choisie, on démarre sur la GAMME 0 String TITRE_GAMME = " OFF" ; // Déclaration d'une Variable de Chaine de Caractères pour afficher le Titre de la GAMME // ---------- VARIABLES pour INTERRUPTION (changement de Gammes) -------------------------------------------------------------------------- const byte POUSS = 2 ; // Affectation en D2 (=> IT"0" - broche 5) - Entrée traitée en Interruption et niveaux byte POUSSOIR = 0 ; // Etat du poussoir (= 1 si Poussoir appuyé) volatile unsigned long TOP_IT = 0 ; // Variable de temps mémorisant l'instant de validation de la dernière IT // ("volatile" car gérée par Interruption, et pouvant donc changer à tout moment) // ---------- VARIABLES PARAMETRIQUES pour le filtrage numérique de l'entrée "Poussoir" (temps en ms) ------------------------------------- unsigned int APPUI = 300 ; // 20 Temps minimal (ms) d'appui du Poussoir pour être pris en compte unsigned int TEMPO_VISU = 1200 ; // Persistance de la Visualisation du titre de la Gamme (lors des changements de GAMME) //________________________________________________________________________________________________________________________________________SETUP__________ void setup() { pinMode (POTAR, INPUT) ; // POTAR est une entrée (analogique) pinMode (SORTIE, OUTPUT) ; // SORTIE est la sortie du signal de Fréquence // ---------- VARIABLES pour le traitement de l'INTERRUPTION ---------------------------------------------------------------------------- pinMode (POUSS, INPUT_PULLUP) ; // Entrée POUSS (D2); avec résistance de PULL-UP interne Arduino (20 à 50 kOhms) attachInterrupt(0, APPUI_BOUTON, FALLING); // Déclaration : IT "0" (D2, pin 5), fonction appelée : "INTERRUPTION" , FALLING (front Descendant) // ---------- Pilotage de l'Afficheur ( 4 Digits 7 SDegments ) -------------------------------------------------------------------------- my7SEGMENT.init(); // Initialisation de la bibliothèque de gestion de l'affichage (Indispensable !) my7SEGMENT.setTextScroll("HELLO") ; // "Bonjour" (scrollé) my7SEGMENT.setText(" OFF") ; // Appareil éteint au démarrage // ---------- Console COM6 de Débug ----------------------------------------------------------------------------------------------------- // Serial.begin(9600) ; // Initialisation Liaison série pour visualisation de variables sur moniteur du PC // Serial.println("Bonjour") ; // Début de communication : Impression de "Bonjour" et retour à la ligne (...ln) } // Fin Setup //_________________________________________________________________________________________________________________________________________LOOP__________ void loop() { // BOUCLE PRINCIPALE SANS FIN // ---------- Calcul de la MOYENNE glissante, qui temporise également la mesure) -------------------------------------------------------- SOMME = SOMME + analogRead (POTAR) ; // SOMME de NOMBRE valeurs POTAR (< 4.000.000 mesures ; POTAR = 0 à 1023) i = i + 1 ; // On incrémente le nombre de mesures if (i >= NOMBRE) { // Quand on arrive à "NOMBRE" de mesures : MOYENNE = SOMME / NOMBRE ; // - On fait la moyenne SOMME = 0 ; // - On remet la SOMME à 0 i = 0 ; // - On réinitialise "i" pour le prochain comptage } // Fin du calcul de la moyenne glissante => MESURE // ---------- On vérifie si la nouvelle mesure sort de la fourchette d'hystérésis ------------------------------------------------------- if (MOYENNE > MEMO || MOYENNE < MEMO - HYST) { // On prend en compte la nouvelle MOYENNE si elle est différente de HYST de la précédente (MEMO) // ( Difficulté d'atteindre la valeur max de la gamme si on utilise + HYST ) : MEMO = MOYENNE ; // Mise à jour de MEMO pour prochain affichage } // Fin de if // ---------- Pour chaque GAMME : Titre, et Calcul des Fréquences ----------------------------------------------------------------------- switch (GAMME) { // Selon la valeur de GAMME : case 0 : // Si GAMME = 0 TITRE_GAMME = " OFF" ; // - OFF ( Pas de Fréquence générée ) break ; // Sortie de switch case 1 : // Si GAMME = 1 TITRE_GAMME = " F1" ; // - Gamme F1 FREQUENCE = CALCUL (0.5565, 31) ; // - de 31 à 600 Hz (Pas de 1 Hz) break ; // Sortie de switch case 2 : // Si GAMME = 2 TITRE_GAMME = " F2" ; // - Gamme F2 FREQUENCE = CALCUL (5, 585) ; // - de 585 à 5700 Hz (Pas de = 5 Hz) break ; // Sortie de switch case 3 : // Si GAMME = 3 TITRE_GAMME = " F3" ; // - Gamme F3 FREQUENCE = CALCUL (10, 4770) ; // - de 4770 à 15.000 Hz (pas de 10 Hz) break ; // Sortie de switch case 4 : // Si GAMME = 4 TITRE_GAMME = " F4" ; // - Gamme F4 FREQUENCE = CALCUL (50, 14350) ; // - de 14.350 à 65.500 Hz (pas de 50 Hz) break ; // Sortie de switch case 5 : // Si GAMME = 5 TITRE_GAMME = " tot" ; // - tot : Gamme Totale possible Arduino FREQUENCE = CALCUL (64.0313, 31) ; // - de 31 à 65.5350 Hz (pas de #64 Hz) break ; // Sortie de switch } // Fin de switch // ---------- Gestion de la Visualisation ( afficheur 4 digits à virgule mobile ) ------------------------------------------------------- // ---------- Visualisation pendant un court instant (TEMPO_VISU), de l'intitulé de la GAMME choisie : if (millis() < TOP_IT + TEMPO_VISU) { // Durant le temps TEMPO_VISU, après une Interruption : my7SEGMENT.setText(TITRE_GAMME) ; // - On affiche le Titre de la Gamme } // Fin de if // ---------- Visualisation permanante de la FREQUENCE réglée : else { // Sinon (hors période d'affichage temporisé du Titre de la GAMME) : if ( GAMME == 0) { // Cas particulier où le Générateur est à l'arrêt : my7SEGMENT.setText(TITRE_GAMME) ; // - On affiche le Titre de la GAMME (... donc OFF !) } // Fin de if else { // Dans tous les autres cas : if (FREQUENCE > 9999) { // . Si la FREQUENCE en Hz dépasse 4 chiffres : AFFICH = FREQUENCE / 1000 ; // - On affiche des kilo Hertz (=> /1000) my7SEGMENT.setNumber(AFFICH, 2) ; // - Et on affiche 2 chiffres après la virgule } // Fin de if else { // . Si non (FREQUENCE <= 9999) : my7SEGMENT.setNumber(FREQUENCE, 0) ; // - On affiche la FREQUENCE telle quelle (sans virgule) } // Fin de else } // Fin de else } // Fin de else // -------------------------------- Pilotage de la SORTIE_BF ---------------------------------------------------------------------------- if ( GAMME == 0) { // Si on est sur OFF : noTone(SORTIE) ; // - On coupe le signal de sortie } // Fin de if else { // Sinon : tone(SORTIE, FREQUENCE) ; // - On Pilote la SORTIE avec la valeur de FREQUENCE } // Fin de else // -------------------------------- Tests Console --------------------------------------------------------------------------------------- /* Serial.print ("MEMO : ") ; // Impression sans retour à la ligne Serial.println(MEMO) ; // Impression avec retour à la ligne Serial.print (" FREQUENCE : ") ; Serial.println (FREQUENCE) ; */ } // Fin de void loop() //____________________________________________________________________________________________________________________________________FIN DE LOOP________ // ----------------------------------- Fonction CALCUL de la Fréquence -------------------------------------------------------------------- unsigned int CALCUL (float A, unsigned int B) { // Déclaration de la Fonction CALCUL et de ses Variables Locales A et B unsigned int RESULT = A * MEMO + B ; // Déclaration de la Variable Locale RESULT, et formule de calcul return RESULT ; // RESULT : Résultat qui est retourné par le Fonction } // Fin de la Fonction CALCUL // ----------------------------------- Fonction Interruption "APPUI_BOUTON" appelée par un appui sur le Poussoir --------------------------- void APPUI_BOUTON() { // Fonction appelée par l'Interruption (IT) externe n°0 (entrée POUSS) // Si une Interruption est présente car un front a été détect), ET // Si le POUSSOIR est appuyé (avec inversion car contact à la masse), pendant un temps > APPUI, pour filtrer les rebonds et les parasites : if (! digitalRead (POUSS) == 1 && (millis() > TOP_IT + APPUI)) { TOP_IT = millis () ; // - On mémorise l'heure de prise en compte de cette IT GAMME = GAMME + 1 ; // - On commute à la GAMME suivante if (GAMME > 5) { // Si fin des GAMME : GAMME = 0 ; // - On revient au début (0) } // Fin du if Dépassement GAMME } // Fin du if Validation IT } // Fin de la Fonction "INTERRUPTION" //___________________________________________________________________ " THE END " _______________________________________________________________________