/////////////////////////////////////////////////////////////////////////////////////////// // DECLARATIONS DES VARIABLES & BIBLIOTHEQUES - INITIALISATION // /////////////////////////////////////////////////////////////////////////////////////////// #include // Déclaration de la librairie permettant la gestion de l'afficheur LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // Mode de connexion de l'afficheur (objet appelé lcd) #include // Déclaration de la librairie permettant la gestion du bus I2C // Déclaration variables et entrées/sorties du clavier analogique #define ClavierAnalog 1 // la valeur constante de ClavierAnalog est 1 int tensionClav = 0; // tensionClav est la variable qui sera lue sur l'entrée du clavier analogique boolean avant [8] = {false}; // Tableau des états précédents des 7 boutons poussoirs (false = bouton relâché) // Déclaration des variables des boutons : bouton relâché = false. Bouton enfoncé = true boolean bouton_0 = false; // Provisoirement Sauvegarde des paramètres boolean bouton_1 = false; // BLI, BLS boolean bouton_2 = false; // 40m ou 10m boolean bouton_3 = false; // RIT ou - dans les sous-menus boolean bouton_4 = false; // Pas en fréquence ou + dans les sous-menus boolean bouton_5 = false; // Sélection d'un paramètre dans le MENU boolean bouton_6 = false; // Activation/désactivation du MENU // Déclaration des variables pour sélectionner fréquence, pas de fréquence, fréquence émission, fréquence réception, FI, OL int pas_en_freq [] = {10, 100, 1000, 10000}; // Tableau contenant les 4 pas en fréquence possibles : 10, 100, 1000 ou 10000 Hz int pef; // Variable pas en fréquence (pef) byte index_pef; // Déclaration de l'index "pas en fréquence" (pef). Anciennement compteur_pef unsigned long freq40; // Fréquence courante bande 40m unsigned long freq10; // Fréquence courante bande 10m unsigned long freq; // Variable fréquence émission servant aux calculs unsigned long freqFI = 11059000; // Rentrer ici votre fréquence FI en hertz (dans mon cas 11,059 MHz) unsigned long freqOL; // Fréquence de l'OL calculée en fonction de la bande sélectionnée et de la FI # define offset 1500 // Décalage de + ou - 1,5 kHz de l'OL selon le mode BLI ou BLS byte Freq40[4]; // Tableau indexé de 0 à 3 contenant 4 octets de poids forts et faibles de la fréquence sur 40 m unsigned long Freq40PF ; // Poids forts sur 32 bits unsigned long Freq40Pf ; // Poids faibles sur 32 bits byte Freq10[5]; // idem sur 10 m unsigned long Freq10PF ; unsigned long Freq10Pf ; // Déclaration des variables pour sélectionner le mode BLI/BLS char* mode_BLU[] = {"BLI", "BLS"}; // Tableau contenant 2 chaînes de caractères BLI et BLS byte index_BLU; // index_BLU (0 = BLI, 1 = BLS) byte index_BLU40 = 0; // index_BLU sur 40 m, initialisé à 0 (BLI) byte index_BLU10 = 1; // index_BLU sur 10 m, initialisé à 1 (BLS) // Déclaration des variables pour sélectionner la bande 40 m ou 10 m byte bande; // Variable bande (0 pour le 40 m, 1 pour le 10 m) byte pos_freq; // la fréquence sur 40 m s'affichera sur le 6ème digit. Pour le 10 m, sur le 5ème digit. Valeur calculée // Déclaration variable et entrée analogique du S-mètre et du ROS-mètre #define Smetre 0 // La tension du S-mètre est lue en A0 en mode réception #define Rosmetre 0 // La tension ROS-mètre est également lue en A0 en mode émission int tensionA0 = 0; // tensionA0 est la variable lue sur l'entrée A0 // Déclaration variable Emission-Réception byte RxTx = 0; // En émission RxTx = 1, 0 en réception // Déclaration variables RIT byte etat_RIT;// etat_RIT = 0 (RIT désactivé), etat_RIT = 1 (RIT activé) int Rit; //Décalage en fréquence positif ou négatif // Déclaration supplémentaire pour la gestion des mémoires en EEPROM byte memoire [20]; // tableau contenant les octets à sauvegarder (10 = 10 positions utilisées + 1) // Déclaration des variables pour détection de la mise hors tension, déclenchement de la sauvegarde et affichage de la tension d'alimentation int tension_sonde_alim; float tension_alim; byte seuil_alim; // Petite astuce : 110 correspond à 11,0 V (type byte ==> 1 seul octet à sauvegarder) boolean alerte_alim; byte j; // Variable de boucle pour faire clignoter l'alerte ALM // Déclaration des variables pour la gestion de la température int tension_sonde_temp; float temp; byte seuil_temp; // Petite astuce : 50 correspond à 50°C boolean alerte_temp; byte k; // Variable de boucle pour faire clignoter l'alerte TMP // Déclaration AD9851 #define DDS_CLOCK 179996860 // Constante à ajuster pour calibrer le DDS (initialement 180000000) byte LOAD = 12; // Port digital 12 affecté à LOAD byte CLOCK = 13; // Port digital 13 affecté à CLOCK byte DATA = 11; // Port digital 11 affecté à DATA // Déclaration des ports et des variables de l'encodeur optique #define encodeur_A 2 // Voie A de l'encodeur sur le port digital D2 #define encodeur_B 3 // Voie B de l'encodeur sur le port digital D3 boolean etat_A; // Etat de A boolean etat_B; // Etat de B // Déclaration des variables pour les fonctions accessibles par le menu byte index_FI; // Mémorisé byte etat_Notch; // Mémorisé byte index_Mesure; // Mémorisé byte index_Alim; byte index_Temp; byte index_Scanneur; boolean etat_scanneur; unsigned long freq_centrale; byte excursion; // Mémorisée byte index_Horloge; byte raz; // Déclaration des variables pour la gestion des menus # define max_menu 8 // Nombre maximal de menus (modifiable) # define choix_max 8 // Choix maximal par menu (modifiable) char* Menu [] = {"Filtre FI","Notch","Mesure TX","ALIM","TEMP","Scanneur","Horloge","RAZ"}; // Titres des menus de niveau 1 char* Choix [][choix_max] = {{"2,7 kHz", "2,2 kHz"}, // Affichage des menus de niveau 2 (titres ou paramètres fixes) {"Arret","Marche"}, {"ROS", "Puissance"}, {"= ","Alerte"}, {"= ","Alerte"}, {"Arret","Marche","Excursion"}, {"UTC", "Local","Heures","Minutes", "Jour", "Date", "Mois", "Annee"}, {"Non", "Oui"}}; // La ligne ci-dessous contient un tableau regroupant les valeurs courantes des variables associées au menu de niveau 1 byte valeur_var [max_menu]; // index_FI, etat_Notch, index_Mesure, index_Alim, index_Temp, index_Scanneur, index_Horloge, raz // La ligne ci-dessous contient un tableau regroupant les valeurs possibles des variables ci-dessus byte valeur_choix [][choix_max] = {{0,1}, // Tableau à 2 dimensions : 8 menus de 0 à 7 avec chacun un choix de 8 valeurs max (pour l'horloge) {0,1}, {0,1}, {0,1}, {0,1}, {0,1,2}, {0,1,2,3,4,5,6,7}, {0,1}}; byte nb_choix [] = {2,2,2,2,2,3,8,2}; // Nombre de choix possibles dans chaque menu (modifiable). Voir ligne ci-dessus int index_menu = 0; // Indique de 0 à 7 le numéro du menu sélectionné (par ex. Menu 5 = Scanneur) int index_choix = 0; // Indique de 0 à 7 la position du choix possible dans chaque menu (par ex. pour le Menu 1 le 0 correspond à Arrêt, le 1 à Marche) int select; // select = 0 (Sélection du choix dans le menu désactivé), select = 1 (Sélection du choix dans le menu activé) int niveau_menu; // menu = 0 (Menus désactivés), menu >= 1 (Menus activés) volatile int pulse = 10; // Permet le comptage des impulsions de l'encodeur pour changer de menu. Initialisé à 10 byte niveau_max [][8] = {{2,2}, // Indique, pour chaque menu, le niveau max qu'il peut atteindre {2,2}, {2,2}, {2,3}, {2,3}, {2,3,3}, {3,3,3,3,3,3,3,3}, {2,3}}; // Déclaration des variables pour la gestion de l'horloge byte secs; byte mins; byte hrs; byte jour; // Jour de la semaine byte date; byte mois; byte annee; ///////////////////////////////////////////////////////////////////////// //////////////////////////// SETUP ///////////////////////////////// ///////////////////////////////////////////////////////////////////////// void setup() { Wire.begin(); // Initialisation de la bibliothèque Wire.h pour gestion I2C lcd.begin(16, 2); // Initialisation de la bibliothèque LiquidCrystal.h pour gestion de l'afficheur LCD pinMode (10, OUTPUT); // Port digital D10 configuré en sortie pour commande BLI/BLS pinMode (0, OUTPUT); // Port digital D0 configuré en sortie pour commande 40 m/10 m pinMode (1, INPUT); // Port digital D1 configuré en entrée (mode réception ou émission) // Initialisation du DDS, de l'encodeur et des interruptions pinMode (DATA, OUTPUT); // Port digital D11 configuré en sortie (ves DDS-D7) pinMode (CLOCK, OUTPUT); // Port digital D13 configuré en sortie (DDS-WCLK) pinMode (LOAD, OUTPUT); // Port digital D12 configuré en sortie (DDS-FQUP) pinMode(encodeur_A, INPUT); // Port digital D2 configuré en entrée (encodeur optique voie A) pinMode(encodeur_B, INPUT); // Port digital D3 configuré en entrée (encodeur optique voie B) attachInterrupt(0, Traitement_A, CHANGE); // Interruption provoquée par le changement d'état du port digital D2 attachInterrupt(1, Traitement_B, CHANGE); // Interruption provoquée par le changement d'état du port digital D3 ///////////////////////// RECUPERATION DES PARAMETRES //////////////////////////////////////////////////// ////////////////////// PLAN MEMOIRE DE L'EEPROM //////////////////////////////////////////////////// /* byte memoire [] = {index_pef, bande, index_BLU40, index_BLU10, // index 0, 3 : pas en fréquence, bande, mode sur 40 m, mode sur 10 m Freq40[3], Freq40[2], Freq40[1], Freq40[0], // index 4 à 7 : fréquence courante 40m Freq10[3], Freq10[2], Freq10[1], Freq10[0], // index 8 à 11 : fréquence courante 10m index_FI, etat_Notch, index_Mesure, alerte_Alim, // index 12 à 15 : Filtre FI, Notch, seuil d'alerte tension d'alimentation, alerte_Temp, excursion }; // index 16 à 17 : Seuil d'alerte température PA, excursion. */ for(byte i = 0; i < 18; i=i+1) { memoire[i] = eeprom_read (0x50, i); // Lecture octet par octet des positions mémoire à l'adresse 0x50 de l'EEPROM } index_pef = memoire [0]; // Index du pas en fréquence : 0, 1, 2 ou 3 pef = pas_en_freq [(index_pef)]; // pef est calculé bande = memoire[1]; index_BLU40 = memoire[2]; index_BLU10 = memoire[3]; Freq40[3] = memoire[4]; Freq40[2] = memoire[5]; Freq40[1] = memoire[6]; Freq40[0] = memoire[7]; Freq10[3] = memoire[8]; Freq10[2] = memoire[9]; Freq10[1] = memoire[10]; Freq10[0] = memoire[11]; index_FI = memoire[12]; etat_Notch = memoire[13]; index_Mesure = memoire[14]; seuil_alim = memoire[15]; seuil_temp = memoire[16]; excursion = memoire[17]; Freq40PF = ((Freq40[3]<<8)&0xFF00)+(Freq40[2]&0x00FF); Freq40Pf = ((Freq40[1]<<8)&0xFF00)+(Freq40[0]&0x00FF); Freq10PF = ((Freq10[3]<<8)&0xFF00)+(Freq10[2]&0x00FF); Freq10Pf = ((Freq10[1]<<8)&0xFF00)+(Freq10[0]&0x00FF); lcd.clear(); // Effacement de l'afficheur lcd.setCursor (0,0); // Positionnement du curseur position 0, ligne 0 pour afficher BLU ou BLI lcd.print (" Chargement"); lcd.setCursor (0,1); lcd.print (" en cours"); delay (2000); ///////////////////////////// FIN DE LA RECUPERATION DES PARAMETRES ///////////////////////////////////////////////////////////////// // A la première utilisation ou en cas de changement d'EEPROM, effectuer une RAZ pour charger les paramètres initiaux freq40 = (((Freq40PF<<16)&0xFFFF0000)+(Freq40Pf&0x0000FFFF)); // Recombinaison de la fréquence courante sur 40 m freq10 = (((Freq10PF<<16)&0xFFFF0000)+(Freq10Pf&0x0000FFFF)); // Recombinaison de la fréquence courante sur 10 m if (bande == 0) { freq = freq40; pos_freq = 5; } else { freq = freq10; pos_freq = 4; } } ///////////////////// FIN DE SETUP //////////////// /////////////// PROGRAMME PRINCIPAL void loop() //////////// void loop() { lcd.clear(); // Effacement de l'afficheur Rafraich_tab_var(); // Le tableau des valeurs mémorisées des variables des menus est rafraîchi lcd.setCursor (0,0); if (niveau_menu == 0) { RXTX (); PAS_FREQUENCE (); } CLAVIER (); ALIM (); TEMP (); MENU(); delay(10); // A ajuster pour optimiser le rafraichissement de l'affichage ///// Mise hors tension et sauvegarde des données //////////////////////////////////////////////////// // Mode manuel, via le bouton 0 (provisoire) // La ligne ci-dessous devra être masquée par // en fonctionnement automatique if (bouton_0 == true) // Provisoirement, c'est l'appui sur la bouton 0 qui déclenche la sauvegarde des paramètres // En automatique, une fois l'interface intégrée au transceiver, la sauvegarde sera déclenchée par le port analogique 2 // Il faudra donc démasquer les 2 lignes suivantes : // tension_sonde_alim = analogRead (2); // if (tension_sonde_alim < 716)// 716 est la valeur convertie de 0 à 1023 de la tension de 3,5 V correspondant à 11 V { lcd.clear (); lcd.setCursor (0,0); // Positionnement du curseur position 0, ligne 0 pour afficher BLU ou BLI lcd.print (" Sauvegarde "); lcd.setCursor (0,1); lcd.print (" en cours"); sauve_param (); lcd.setCursor (0,0); // Positionnement du curseur position 0, ligne 0 pour afficher BLU ou BLI lcd.print (" Sauvegarde ok !"); lcd.setCursor (0,1); lcd.print (" Au revoir..."); delay (3000); // Temporisation laissant le temps au transceiver de s'éteindre niveau_menu = 0; // A effacer en mode automatique index_menu = 0; // A effacer en mode automatique index_choix; // A effacer en mode automatique } ////////////// Fin de Mise hors tension et sauvegarde des données //////// /////////// Commutation 40m /10m /////////////////////////////////////////// if ((bouton_2 == true) && (avant[2] == false)) { bande = bande + 1; if(bande > 1)// La variable bande ne peut prendre (pour le moment) que 2 valeurs (0 ou 1) { bande = 0; // Remise à 0 } etat_RIT = 0; Rit = 0; // Le changement de bande annule le mode RIT avant[2] = bouton_2; } if (bande == 0) // 40 m { MODE_BLU40(); freq = freq40;// Fréquences sur la bande des 40m pos_freq = 5; digitalWrite (0,LOW); } if (bande == 1) // 10 m { MODE_BLU10(); freq = freq10 ; // Fréquences sur la bande des 10m pos_freq = 4; digitalWrite (0,HIGH); } if (bouton_2 == false) { avant[2] = false; } /////////////////// Fin de commutation 40 m / 10 m ////////////////////////// // Calcul de la fréquence à synthétiser SYNTHESE(); } /// FIN DE void loop() /////////////////////////////////////////////////////////////////////////////////////////// // SOUS-PROGRAMMES ET FONCTIONS // /////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// void SYNTHESE () { // Ces lignes sont données à titre d'exemple pour une FI = 11,059 MHz, mélange supradyne //if (index_BLU == 0) freqOL = freq + freqFI - offset; //if (index_BLU == 1) freqOL = freq + freqFI + offset; // envoyerFrequence(freqOL); // Appel de la fonction envoyerFrequence (DDS) pour synthétiser l'OL envoyerFrequence(freq); // Appel de la fonction envoyerFrequence (DDS) // Ici en mode démo : freq = fréquence affichée } //////////////////////////////////////////////////////////////////// void MODE_BLU40 () { if ((bouton_1 == true) && (avant[1] == false)) // Test de l'appui sur le bouton et prise en compte de son état précédent { index_BLU40 = index_BLU40 + 1; // Si la condition est vraie, l'index_BLU est augmenté de 1 if(index_BLU40 > 1)// Si l'index_BLU est supérieur à 1... { index_BLU40 = 0; // ...il est remis à 0 } avant[1] = bouton_1; // La variable de l'état précédent prend la valeur du bouton (maintenant enfoncé) } if(index_BLU40 == 0) // BLI { digitalWrite (10,LOW); // Le port digital D10 est mis à l'état bas (BLI) index_BLU = 0; } if (index_BLU40 == 1) // BLS { digitalWrite (10,HIGH); // Sinon, le port digital D10 est mis à l'état haut (BLS)pour commuter relais faible consommation ou un transistor index_BLU = 1; } if (bouton_1 == false) // Si le bouton est relâché... { avant[1] = false; // ... son état devient relâché } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void MODE_BLU10 () { if ((bouton_1 == true) && (avant[1] == false)) // Test de l'appui sur le bouton et prise en compte de son état précédent { index_BLU10 = index_BLU10 + 1; // Si la condition est vraie, l'index_BLU est augmenté de 1 if(index_BLU10 > 1)// Si l'index_BLU est supérieur à 1... { index_BLU10 = 0; // ...il est remis à 0 } avant[1] = bouton_1; // La variable de l'état précédent prend la valeur du bouton (maintenant enfoncé) } if(index_BLU10 == 0) // BLI { digitalWrite (10,LOW); // Le port digital D10 est mis à l'état bas (BLI) index_BLU = 0; } if (index_BLU10 == 1) // BLS { digitalWrite (10,HIGH); // Sinon, le port digital D10 est mis à l'état haut (BLS)pour commuter relais faible consommation ou un transistor index_BLU = 1; } if (bouton_1 == false) // Si le bouton est relâché... { avant[1] = false; // ... son état devient relâché } } ////////////////////////////////////////////////////////////////// // RXTX void RXTX() { lcd.print (mode_BLU[index_BLU]); lcd.setCursor (pos_freq,0); // Positionnement du curseur sur le 5ème ou 6ème digit RxTx = digitalRead (1); // Lecture de l'état émission ou réception sur le port digital A1 if (RxTx==HIGH)// Le transceiver est en mode émission { lcd.print(float(freq)/1000); // Affiche la fréquence d'émission AFF_RIT (); // Affichage du RIT (si activé) lcd.setCursor(0,1); // Positionnement du curseur position 0, ligne 1 pour afficher le ROS-mètre if (niveau_menu == 0) { ROSMETRE (); // Ne pas confondre Rosmetre en tant que variable et ROSMETRE en tant que fonction } } else { RIT (); // Appel de la fonction RIT AFF_RIT (); // Affichage du RIT (si activé) if ((Rit != 0) && (etat_RIT == 1)) { lcd.setCursor (pos_freq,0); lcd.print(float(freq + Rit)/1000); // Affiche la fréquence de réception en kHz avec 2 chiffres après la virgule } else { lcd.setCursor (pos_freq,0); lcd.print(float(freq)/1000); // Affiche la fréquence de réception sans RIT en kHz avec 2 chiffres après la virgule } lcd.setCursor(0,1); // Positionnement du curseur position 0, ligne 1 pour afficher le S-mètre if (niveau_menu == 0) { SMETRE (); // Ne pas confondre Smetre en tant que variable et SMETRE en tant que fonction } } } ////////////////////////////////////////////////////////////////////////// // Gestion du MENU void MENU () { // APPUI SUR LE BOUTON MENU ///////////////// if ((bouton_6 == true) & (avant[6] == false)) // Si on appuie sur le bouton 6, alors qu'il était relâché... { index_choix = 0; if(niveau_menu == 0) // Un nouvel appui sur le bouton 6, alors qu'il était relâché... { niveau_menu = niveau_menu + 1; // } else // Un nouvel appui sur le bouton 6, alors qu'il était relâché... { niveau_menu = niveau_menu-1; // } } avant[6] = bouton_6; if (bouton_6 == false) { avant[6] = false; } // APPUI SUR LE BOUTON SELECT ///////////////// if (niveau_menu == 1) // Si le mode Menu est activé au niveau des titres { // L'encodeur tourne vers la droite if (pulse > 20) // La variable pulse était initialisée à 10. Si elle est égale à 20 (donc + 10 impulsions)... { index_menu = index_menu + 1; // 10 impulsions incrémente index_menu de 1, c. à d. menu suivant if (index_menu > max_menu-1) // Si l'on dépasse le nombre maximal de menu défini... { index_menu = 0; // on remet l'index des menus à 0 } pulse = 10; // ... on remet pulse à 10. } // L'encodeur tourne vers la gauche if (pulse < 0) { index_menu = index_menu - 1; if (index_menu < 0) { index_menu = max_menu-1; } pulse = 10; } lcd.setCursor (0,0); lcd.print (index_menu); // ... on affiche le numéro du menu... lcd.print (":"); // ... suivi de : ... lcd.print (Menu [index_menu]); // ... suivi du nom du menu ... lcd.setCursor (13,0); lcd.print (""); // ... suivi de symbolisant le recours à l'encodeur optique } // Fin des menus de niveau 1 if ((bouton_5 == true) & (avant[5] == false) & (niveau_menu >0)) // Si appui sur le bouton Select, alors qu'il était relâché... { avant[5] = bouton_5; if (niveau_menu < niveau_max [index_menu][index_choix]) { niveau_menu = niveau_menu + 1; // MENUS NIVEAU 2, 3, ... } } if (bouton_5 == false) { avant[5] = false; } if (niveau_menu == 2) // { index_choix = valeur_choix[index_menu][valeur_var[index_menu]]; // if (pulse > 20) { index_choix = index_choix + 1; // après 10 impulsions, on incrémente l'index des choix possibles pour le menu en cours if (index_choix > nb_choix[index_menu]-1) // Si l'on dépasse le nombre maximal de choix défini par menu... { index_choix = 0; // on remet l'index des choix à 0 } pulse = 10; valeur_var [index_menu] = valeur_choix[index_menu][index_choix]; } if (pulse < 0) { index_choix = index_choix - 1; if (index_choix < 0) { index_choix = nb_choix[index_menu]-1; } pulse = 10; valeur_var [index_menu] = valeur_choix[index_menu][index_choix]; } lcd.setCursor (0,0); lcd.print (Menu [index_menu]); // On affiche sur la première ligne le menu sélectionné lcd.setCursor (0,1); lcd.print(Choix [index_menu][index_choix]); // Puis, sur la seconde ligne le choix possible en cours // Cas des sous-menus ALIM, TEMP, SCANNEUR, HORLOGE et RAZ // Affichage tension d'alimentation ///////////////////// if ((index_menu == 3)&(index_Alim == 0)) { lcd.setCursor (2,1); lcd.print (tension_alim, 1); lcd.print (" V"); lcd.setCursor (13,1); lcd.print (""); } // Alerte Alimentation : affichage fin de la seconde ligne else if ((index_menu == 3)&(index_Alim == 1)) { lcd.setCursor (11,1); lcd.print ("S "); } // Affichage température ////////////////////////////////// else if ((index_menu == 4)&(index_Temp == 0)) { lcd.setCursor (2,1); lcd.print (temp, 1); lcd.print (char(223)); lcd.print ("C"); lcd.setCursor (13,1); lcd.print (""); } // Alerte Température : affichage fin de la seconde ligne else if ((index_menu == 4)&(index_Temp == 1)) { lcd.setCursor (11,1); lcd.print ("S "); } // Excursion : affichage fin de la seconde ligne else if ((index_menu == 5)&(index_Scanneur == 2)) { lcd.setCursor (11,1); lcd.print ("S "); } // RAZ : affichage fin de la seconde ligne else if ((index_menu == 7)&(raz == 1)) { lcd.setCursor (11,1); lcd.print ("S "); } // Autres menus else { lcd.setCursor (13,1); lcd.print (""); } } // Fin de if (niveau_menu == 2) ////////////////////////////////// // Cas particuliers des menus de niveau 3 ALIM et TEMP (tension d'alimentation et température), Scanneur, Horloge et RAZ // ALIMENTATION : réglage du seuil d'alerte if ((index_menu == 3)&(niveau_menu == 3)) { lcd.setCursor(0,0); lcd.print("Alerte ALIM"); lcd.setCursor(0,1); lcd.print("Seuil = "); lcd.setCursor (8,1); lcd.print (float (seuil_alim)/10,1); // Affichage du seuil d'alerte à régler au-dessus du seuil de déclenchement de la sauvegarde (11 V) lcd.print ("V"); // seuil_alim est le seuil en-dessous duquel l'alerte apparaît sur l'afficheur, par ex. 11,5 V lcd.setCursor (13,1); lcd.print (""); } // TEMPERATURE : réglage du seuil d'alerte if ((niveau_menu == 3)&(index_menu == 4)) { lcd.setCursor(0,0); lcd.print("Alerte TEMP"); lcd.setCursor(0,1); lcd.print("Seuil = "); lcd.setCursor (8,1); lcd.print (seuil_temp,1); // Affichage du seuil d'alerte lcd.print (char(223)); lcd.print ("C"); lcd.setCursor (13,1); lcd.print (""); } // SCANNEUR : démarrage et réglage de l'excursion // Démarrage if ((niveau_menu == 3)&(index_menu == 5)&(index_Scanneur == 1)) { SCANNEUR(); } // Excursion if ((niveau_menu == 3)&(index_menu == 5)&(index_Scanneur == 2)) { lcd.setCursor(0,0); lcd.print("Excursion"); lcd.setCursor(0,1); //lcd.print("+- "); lcd.print(excursion); lcd.print(" kHz c/c"); lcd.setCursor (13,1); lcd.print (""); } // HORLOGE : affichage en mode local if ((niveau_menu == 3)&(index_menu == 6)&(index_choix < 2)) { HORLOGE (); DATE(1); } if ((index_menu == 6)&(niveau_menu == 3)&(index_choix > 1) & (index_choix < 4)) { HORLOGE (); REG_HORLOGE (); } if ((index_menu == 6)&(niveau_menu == 3)&(index_choix > 3)) { DATE(0); REG_DATE (); } // RAZ if ((niveau_menu == 3)&(index_menu == 7)&(raz==1)) { RAZ(); } // Fin des cas particuliers du niveau 3 ////////////////////////////////// Rafraich_var(); // Si la sélection a changée, la nom de la variable qui a changée prend la nouvelle valeur stockée dans le tableau des valeurs des variables valeur_var[] } //////// Raffraichissement des variables des menus /////////////////////////// void Rafraich_var() { index_FI = valeur_var [0]; etat_Notch = valeur_var [1]; index_Mesure = valeur_var [2]; index_Alim = valeur_var [3]; index_Temp = valeur_var [4]; index_Scanneur = valeur_var [5]; index_Horloge = valeur_var [6]; raz = valeur_var [7]; } //////// Raffraichissement du tableau des variables des menus ///////////////// void Rafraich_tab_var() { valeur_var [0] = index_FI; valeur_var [1] = etat_Notch; valeur_var [2] = index_Mesure; valeur_var [3] = index_Alim; valeur_var [4] = index_Temp; valeur_var [5] = index_Scanneur; valeur_var [6] = index_Horloge; valeur_var [7] = raz; } //////////////////////////////////////////////////////////////////////////// // Traitement des interruptions : changement d'état de A void Traitement_A() { // Transition montante? if ((digitalRead(encodeur_A) == HIGH)&(!etat_B)) { etat_A = true; /////////////////////////////////////////////////////////////////////////// // Instructions à exécuter : // En mode MENU : // Instructions à exécuter (seul le traitement A est commenté) : if (niveau_menu == 1) // Si le mode MENU est activé... { pulse = pulse +1; // ... on compte les impulsions de l'encodeur } if (niveau_menu == 2) // Si maintenant on appuie sur le bouton Sélect (on pourrait le renommer OK) { pulse = pulse +1; } // Réglage alerte alimentation ////////////////////////// if ((niveau_menu == 3)&(index_menu == 3)&(Choix [3][index_choix]=="Alerte")) { pulse = pulse +1; if (pulse > 20) { seuil_alim = seuil_alim + 1; pulse = 0; } } // Fin réglage alerte alimentation ////////////////////////////// // Réglage alerte température ////////////////////////// if ((niveau_menu == 3)&(index_menu == 4)&(Choix [4][index_choix]=="Alerte")) { pulse = pulse +1; if (pulse > 20) { seuil_temp = seuil_temp + 1; pulse = 0; } } // Fin réglage alerte temperature ////////////////////////////// // Arrêt du scanneur if ((niveau_menu == 3)&(index_menu == 5)&(index_Scanneur == 1)) { pulse = pulse + 1; } // Fin Arrêt du scanneur // Réglage de l'excursion du scanneur if ((niveau_menu == 3)&(index_menu == 5)&(index_Scanneur == 2)) { pulse = pulse +1; if (pulse > 15) { excursion = excursion + 10; if (excursion > 200 ) excursion = 10; pulse = 10; } } // Fin du réglage de l'excursion du scanneur // Fin du traitement A en mode MENU if (niveau_menu == 0) { if (etat_RIT == 0) // Teste si le RIT est hors service { if (bande == 1) { freq = freq10; freq = freq + pef; // La fréquence est augmentée du pas défini par l'utilisateur freq10 = freq; } else { freq = freq40; freq = freq + pef; // La fréquence est augmentée du pas défini par l'utilisateur freq40 = freq; } } else // Le RIT est activé { if (RxTx==LOW) // Le réglage du décalage du RIT n'est possible qu'en mode réception { Rit = Rit + 10; // La fréquence est augmentée de 10 Hz (modifiable) } } } // Fin des instructions à exécuter. /////////////////////////////////////////////////////////////////////////// } // Transition descendante? if (digitalRead(encodeur_A) == LOW) { etat_A = false; } } // Traitement de l'interruption générée par le changement d'état de B void Traitement_B() { // Transition montante? if ((digitalRead(encodeur_B) == HIGH)&(!etat_A)) { etat_B = true; ///////////////////////////////////////////////////////////////////////////// // Instructions à exécuter en mode MENU (voir les commentaires sur le traitement A) : if (niveau_menu == 1) { pulse = pulse -1; } if (niveau_menu == 2) { pulse = pulse -1; } // Réglage alerte alimentation ////////////////////////// if ((niveau_menu == 3)&(index_menu == 3)&(Choix [3][index_choix]=="Alerte")) { pulse = pulse -1; if (pulse < 0) { seuil_alim = seuil_alim - 1; pulse = 10; } } // Fin réglage alerte alimentation //////////////////////////// // Réglage alerte température ////////////////////////// if ((niveau_menu == 3)&(index_menu == 4)&(Choix [4][index_choix]=="Alerte")) { pulse = pulse -1; if (pulse < 0) { seuil_temp = seuil_temp - 1; pulse = 10; } } // Fin réglage alerte température ////////////////////////////// // Arrêt du scanneur if ((niveau_menu == 3)&(index_menu == 5)&(index_Scanneur == 1)) { pulse = pulse - 1; } // Fin Arrêt du scanneur // Réglage de l'excursion du scanneur if ((niveau_menu == 3)&(index_menu == 5)&(index_Scanneur == 2)) { pulse = pulse -1; if (pulse < 5) { excursion = excursion - 10; if (excursion < 10 ) excursion = 200; pulse = 10; } } // Fin du réglage de l'excursion du scanneur // Fin du traitement B en mode MENU if (niveau_menu == 0) { if (etat_RIT == 0) // Teste si le RIT est hors service { if (bande == 1) { freq = freq10; freq = freq - pef; // La fréquence est augmentée du pas défini par l'utilisateur freq10 = freq; } else { freq = freq40; freq = freq - pef; // La fréquence est augmentée du pas défini par l'utilisateur freq40 = freq; } } else // Le RIT est activé { if (RxTx==LOW) // Le réglage du décalage du RIT n'est possible qu'en mode réception { Rit = Rit - 10; // La fréquence est diminuée de 10 Hz (modifiable) } } } // Fin des instructions à exécuter. /////////////////////////////////////////////////////////////////////////// } // Transition descendante? if (digitalRead(encodeur_B) == LOW) { etat_B = false; } } ///////////// Fin du traitement des interruptions ////////////////// //////////////////////////////////////////////////////////////////// //Détermination du pas en fréquence (10, 100, 1000 ou 10000 Hz) void PAS_FREQUENCE () { if ((bouton_4 == true) && (avant[4] == false)) { avant[4] = bouton_4; index_pef = index_pef + 1; if(index_pef > 3) // le compteur_pef peut prendre les valeurs 0, 1, 2 ou 3 { index_pef = 0; } if (index_pef == 0 || index_pef == 1) { lcd.setCursor (11 - index_pef, 0); // Positionne le curseur sur le chiffre 100 Hz ou 10 Hz } else { lcd.setCursor (11 - index_pef-1, 0); // Positionne le curseur sur le chiffre des 10 kHz ou kHz } lcd.print (char (255)); delay (200);// Noircit pendant 2/10ème de seconde le chiffre sélectionné pour indiquer le pas en fréquence pef = pas_en_freq [index_pef]; // Le pas en fréquence devient 10, 100, 1000 ou 10000 Hz } if ((bouton_4 == false) && (avant[4] == true)) { avant[4] = false; } } ////////////////////////////////////////// // Gestion du RIT void RIT () { if ((bouton_3 == true) && (avant[3] == false)) { avant[3] = bouton_3; etat_RIT = etat_RIT + 1; if(etat_RIT > 1) { etat_RIT = 0; } } if ((bouton_3 == false) && (avant[3] == true)) { avant[3] = false; } } // Affichage RIT void AFF_RIT () { if (etat_RIT == 1) { lcd.setCursor (12, 0); if (Rit==0) { lcd.print ("="); } if (Rit > 0) { lcd.print ("+"); } if (Rit < 0) { lcd.print ("-"); } } } /////////////////////////////////////////// // Gestion du clavier analogique void CLAVIER() { tensionClav = analogRead(ClavierAnalog); // La variable tensionClav prend la valeur lue sur l'entrée ClavierAnalog if (tensionClav > 117 && tensionClav < 137) { bouton_6 = true; } else { bouton_6 = false; } if (tensionClav > 246 && tensionClav < 266) { bouton_5 = true; } else { bouton_5 = false; } if (tensionClav > 374 && tensionClav < 394) { bouton_4 = true; } else { bouton_4 = false; } if (tensionClav > 502 && tensionClav < 522) { bouton_3 = true; } else { bouton_3 = false; } if (tensionClav > 630 && tensionClav < 650) { bouton_2 = true; } else { bouton_2 = false; } if (tensionClav > 758 && tensionClav < 778) { bouton_1 = true; } else { bouton_1 = false; } if (tensionClav > 890 && tensionClav < 900) { bouton_0 = true; } else { bouton_0 = false; } } /////////////////////////////////////////// // Gestion du S-mètre void SMETRE () { tensionA0 = map(analogRead(Smetre), 0, 1023, 0, 500); // Port A0, plage 0 à 1023 ramenée à 500 if (tensionA0 < 7) { lcd.print("<"); lcd.setCursor(10,1); lcd.print(" 6 && tensionA0 < 47) { lcd.print(char (255)); lcd.setCursor(11,1); lcd.print("S1"); } if (tensionA0 > 46 && tensionA0 < 76) { lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(11,1); lcd.print("S2"); } if (tensionA0 > 75 && tensionA0 < 110) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(11,1); lcd.print("S3"); } if (tensionA0 > 109 && tensionA0 < 146) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(11,1); lcd.print("S4"); } if (tensionA0 > 145 && tensionA0 < 181) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(11,1); lcd.print("S5"); } if (tensionA0 > 180 && tensionA0 < 216) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(11,1); lcd.print("S6"); } if (tensionA0 > 215 && tensionA0 < 249) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(11,1); lcd.print("S7"); } if (tensionA0 > 248 && tensionA0 < 290) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(11,1); lcd.print("S8"); } if (tensionA0 > 289 && tensionA0 < 350) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(11,1); lcd.print("S9"); } if (tensionA0 > 349 && tensionA0 < 400) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(">"); lcd.setCursor(11,1); lcd.print("S9+10"); } if (tensionA0 > 399) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(">>"); lcd.setCursor(11,1); lcd.print("S9+20"); } } /////////////////////////////////////////// // Gestion du ROS-mètre void ROSMETRE () { tensionA0 = map(analogRead(Rosmetre), 0, 1023, 0, 500); // Port analogique A0, plage 0 à 1023 ramenée à 500 if (tensionA0 < 7) { lcd.setCursor(8,1); lcd.print("ROS=1"); } if (tensionA0 > 6 && tensionA0 < 47) { lcd.print(char (255)); lcd.setCursor(8,1); lcd.print("ROS=1.1"); } if (tensionA0 > 46 && tensionA0 < 76) { lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(8,1); lcd.print("ROS=1.3"); } if (tensionA0 > 75 && tensionA0 < 110) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(8,1); lcd.print("ROS=1.7"); } if (tensionA0 > 109 && tensionA0 < 146) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(8,1); lcd.print("ROS=2"); } if (tensionA0 > 145 && tensionA0 < 181) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(8,1); lcd.print("ROS=2.5"); } if (tensionA0 > 180 && tensionA0 < 216) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(8,1); lcd.print("ROS=3"); } if (tensionA0 > 215) { lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.print(char (255)); lcd.setCursor(7,1); lcd.print(">3 DANGER"); } } ///////////////////////////////////////////////////////////////// // Gestion DDS // // ////////////////////////////////////////////////////////////// // Original code from Peter Marks // http://blog.marxy.org/2008/05/controlling-ad9851-dds-with-arduino.html // Modified par George Smart, M1GEO - 12 Feb 2012 /////////////////////////////////////////// void envoyerFrequence(unsigned long freq) { unsigned long tuning_word = (freq * pow(2, 32)) / DDS_CLOCK; digitalWrite (LOAD, LOW); for(int i = 0; i < 32; i++) { if ((tuning_word & 1) == 1) outOne(); else outZero(); tuning_word = tuning_word >> 1; } byte_out(0x09); digitalWrite (LOAD, HIGH); } void byte_out(unsigned char byte) { int i; for (i = 0; i < 8; i++) { if ((byte & 1) == 1) outOne(); else outZero(); byte = byte >> 1; } delay (10); // initialement à 200. Ajuster cette valeur pour augmenter ou diminuer la vitesse de synthèse en fréquence } void outOne() { digitalWrite(CLOCK, LOW); digitalWrite(DATA, HIGH); digitalWrite(CLOCK, HIGH); digitalWrite(DATA, LOW); } void outZero() { digitalWrite(CLOCK, LOW); digitalWrite(DATA, LOW); digitalWrite(CLOCK, HIGH); } ///////////////////////////////////////////////////// // GESTION DE L'EEPROM // ///////////////////////////////////////////////////// // Sauvegarde des paramètres //////////////////////// void sauve_param () { // Conversion des fréquences (nombre entier non signé long - unsigned long) en 4 octets Freq40[3] = (freq40>>24)&(0xFF); Freq40[2] = (freq40>>16)&(0xFF); Freq40[1] = (freq40>>8)&(0xFF); Freq40[0] = (freq40)&(0xFF); Freq10[3] = (freq10>>24)&(0xFF); Freq10[2] = (freq10>>16)&(0xFF); Freq10[1] = (freq10>>8)&(0xFF); Freq10[0] = (freq10)&(0xFF); // Tableau contenant les variables prêtes à être écrites dans l'EEPROM byte memoire [] = { index_pef, bande, index_BLU40, index_BLU10, // index 0, 3 : pas en fréquence, bande, mode sur 40 m, mode sur 10 m Freq40[3], Freq40[2], Freq40[1], Freq40[0], // index 4 à 7 : fréquence courante 40m Freq10[3], Freq10[2], Freq10[1], Freq10[0], // index 8 à 11 : fréquence courante 10m index_FI, etat_Notch, index_Mesure, seuil_alim, // index 12 à 15 : Filtre FI, Notch, seuil d'alerte tension d'alimentation, seuil_temp, excursion }; // index 16 à 17 : Seuil d'alerte température PA, excursion et vitesse du scanneur, UTC ou Local for(byte i = 0; i < 18; i=i+1) { eeprom_write (0x50, i, memoire [i]); // Ecriture en mémoire delay (100); } } ///////////////////////////////////////////////////////////// // Ecriture dans l'EEPROM void eeprom_write( byte device_address, byte mem_address, byte data) { Wire.beginTransmission(device_address); Wire.write(mem_address); Wire.write(data); Wire.endTransmission(); } ///////////////////////////////////////////////////////////// // Lecture à partir de l'EEPROM byte eeprom_read(int device_address, int mem_address) { Wire.beginTransmission(device_address); Wire.write(mem_address); Wire.endTransmission(); Wire.requestFrom(device_address, 1); if(Wire.available()) return Wire.read(); else return 0xFF; } ////////////////////////////////////////////////////////////// void HORLOGE () { lcd.setCursor (2,0); Wire.beginTransmission (0x68); Wire.write(0); Wire.endTransmission(); secs = BCD_DEC(Wire.read()); // Lecture des secondes et conversion en décimal mins = BCD_DEC(Wire.read()); hrs = BCD_DEC(Wire.read()); jour = BCD_DEC(Wire.read()); date = BCD_DEC(Wire.read()); mois = BCD_DEC(Wire.read()); annee = BCD_DEC(Wire.read()); Wire.requestFrom (0x068,7); if ((niveau_menu == 3)&(Choix [6][index_choix]=="Local")|(index_choix == 2) | (index_choix == 3)) { if (hrs < 10) { lcd.print("0"); } lcd.print(hrs, DEC); lcd.print(":"); if (mins<10) lcd.print("0"); // Attention notation abrégée de if, donc pas de { } lcd.print(mins, DEC); lcd.print(":"); if (secs < 10) lcd.print("0"); lcd.print(secs, DEC); lcd.print(" LOC"); } if ((niveau_menu == 3)&(Choix [6][index_choix]=="UTC")) { if (hrs < 10) { lcd.print("0"); } lcd.print(hrs-1, DEC); // C'est ici que le décalage UTC/Local doit être effectué. Ici UTC = Local - 1 lcd.print(":"); if (mins<10) lcd.print("0"); // Attention notation abrégée de if, donc pas de { } lcd.print(mins, DEC); lcd.print(":"); if (secs < 10) lcd.print("0"); // Attention notation abrégée de if, donc pas de { } lcd.print(secs, DEC); lcd.print(" UTC"); } } /////////////////////////////////////////////////////// void DATE(byte reg) { lcd.setCursor (1,reg); Wire.beginTransmission (0x68); Wire.write(0); Wire.endTransmission(); secs = BCD_DEC(Wire.read()); // Lecture des secondes et conversion en décimal mins = BCD_DEC(Wire.read()); hrs = BCD_DEC(Wire.read()); jour = BCD_DEC(Wire.read()); date = BCD_DEC(Wire.read()); mois = BCD_DEC(Wire.read()); annee = BCD_DEC(Wire.read()); Wire.requestFrom (0x068,7); switch (jour) { case 1 : lcd.print ("Lun "); break; case 2 : lcd.print ("Mar "); break; case 3 : lcd.print ("Mer "); break; case 4 : lcd.print ("Jeu "); break; case 5 : lcd.print ("Ven "); break; case 6 : lcd.print ("Sam "); break; case 7 : lcd.print ("Dim "); break; } if (date<10) lcd.print("0"); lcd.print(date, DEC); lcd.print("-"); if (mois < 10) lcd.print("0"); lcd.print(mois, DEC); lcd.print("-"); lcd.print("20"); if (annee < 10) lcd.print("0"); lcd.print(annee, DEC); if (annee < 10) lcd.print("0"); } ///////////////////////////////////////////////////// void REG_HORLOGE() { HORLOGE(); switch (index_choix) { case 2 : //Réglage des heures lcd.setCursor (5,1); lcd.print ("H- H+"); // Affichage de H- et H+ au-dessus des boutons 3 et 4 if (bouton_3 == true) { hrs = hrs - 1; delay(100); if (hrs == 0) hrs = 23; ENVOI(2, hrs); // 2 correspond à la position mémoire des heures dans le DS1307 } if (bouton_4 == true) { hrs = hrs + 1; delay(100); if (hrs == 24) hrs = 0; ENVOI(2, hrs); } break; case 3 : //Réglage des minutes lcd.setCursor (4,1); lcd.print ("Mn- Mn+"); if (bouton_3 == true) { mins = mins - 1; delay(100); if (mins == 0) mins = 59; ENVOI(1, mins); ENVOI(0, 11); } if (bouton_4 == true) { mins = mins + 1; delay(100); if (mins == 60) mins = 0; ENVOI(1, mins); ENVOI(0, 11); } break; } } ///////////////////////////////////////////////////// void REG_DATE () { switch (index_choix) { case 4 : //Réglage du jour de la semaine (1 à 7) lcd.setCursor (5,1); lcd.print ("J- J+"); if (bouton_3 == true) { jour = jour - 1; delay(100); if (jour == 0) jour = 7; ENVOI(3, jour); } if (bouton_4 == true) { jour = jour + 1; delay(100); if (jour == 8) jour = 1; ENVOI(3, jour); } break; case 5 : //Réglage de la date (1 à 31) lcd.setCursor (5,1); lcd.print ("D- D+"); if (bouton_3 == true) { date = date - 1; delay(100); if (date == 0) date = 31; ENVOI(4, date); } if (bouton_4 == true) { date = date + 1; delay(100); if (date == 32) date = 1; ENVOI(4, date); } break; case 6 : //Réglage des mois (1 à 12) lcd.setCursor (4,1); lcd.print ("Mo- Mo+"); if (bouton_3 == true) { mois = mois - 1; delay(100); if (mois == 0) mois = 12; ENVOI(5, mois); } if (bouton_4 == true) { mois = mois + 1; delay(100); if (mois == 13) mois = 1; ENVOI(5, mois); } break; case 7 : //Réglage des années (2010 à 2098) lcd.setCursor (5,1); lcd.print ("A- A+"); if (bouton_3 == true) { annee = annee - 1; delay(100); if (annee == 10) annee = 98; ENVOI(6, annee); } if (bouton_4 == true) { annee = annee + 1; delay(100); if (annee == 99) annee = 10; ENVOI(6, annee); } break; } } // Envoi des données à l'horloge void ENVOI (byte pos_mem, byte parametre) { delay (300); Wire.beginTransmission(0x68); Wire.write (pos_mem); delay (50); Wire.write (DEC_BCD (parametre)); // Paramètre de l'horloge à régler Wire.endTransmission(); } /////////////////////////////////////////////////////////////////// // Fonction de conversion décimal en BCD (Binaire Codé Décimal) byte DEC_BCD(byte dec) { return ((dec / 10 * 16) + (dec % 10)); } // Fonction de conversion BCD en décimal byte BCD_DEC(byte bcd) { return ((bcd / 16 * 10) + (bcd % 16)); } //////////////////////////////////////////////////////////////////// // SCANNEUR : mise en route, arrêt automatique, fonctionnement void SCANNEUR () { freq_centrale = freq; // La fréquence en cours devient la fréquence centrale fo pulse = 10; for (long n = 0; n <= excursion*10; n = n + 1 ) // Nombre de pas = excursion (en kHz) x 1000 / (pas de 100 Hz) { freq = freq_centrale - (long (excursion))*500 + 100*n; // La fréquence croît de fo - excursion à fo + excursion avec un pas de 100 Hz delay (200-excursion*0.75); // La vitesse diminue avec l'excursion lcd.clear(); lcd.setCursor (0,0); lcd.print (" Scanneur "); lcd.setCursor (0,1); lcd.print ("F = "); lcd.print (float(freq)/1000); lcd.setCursor (13,1); lcd.print ("MHz"); SYNTHESE (); if ( pulse < 9 | pulse > 11) // Si l'on tourne l'encodeur de + ou - 2 par rapport à sa valeur initiale (10) { pef = 10; // Mise à 10 Hz du pas en fréquence valeur_var [5] = 0; // On arrête le scanneur en mettant index_Scnanneur à 0 niveau_menu = 0; index_choix = 0; break; // Permet de quitter prématurément la boucle for } if (n >= excursion*10) n = 0; // Tant que l'on ne touche pas à l'encodeur oprique, la boucle est répétée } switch (bande) // En fonction de la bande... { case 0 : freq40 = freq; // la fréquence courante sur 40 m prend la valeur de la fréquence d'arrêt du scanneur break; case 1 : freq10 = freq; // la fréquence courante sur 10 m prend la valeur de la fréquence d'arrêt du scanneur break; } } ////////////////////////////////////////////////////////////////// // Mesure alimentation void ALIM () { tension_sonde_alim = map(analogRead (2), 0,900,0,1380); // Pour 5 volts, la tension convertie sur le port vaut 1023. Pour 4,4 V (correspondant à 13,8 V) elle vaut 900 // On convertie donc la plage 0-900 en 0-1380 par la fonction map() tension_alim = tension_sonde_alim*0.01; // Remplacer *0.01 par /100 donne une valeur fausse. if (tension_alim < float (seuil_alim*0.1))// Petite conversion locale de type de variable : byte en float. Exemple : 110 devient 11,00 { alerte_alim = true; ALERTE (); } else { alerte_alim = false; } } ////////////////////////////////////////////////////////////////// // Mesure de la température void TEMP () { tension_sonde_temp = map(analogRead (3), 0, 1023, 0, 1000); // Pour 5 volts, la tension convertie sur le port vaut 1023 et est ramenée à 1000 par la fonction map(). Pour 500 mV (correspondant à 50 °C) elle vaut 100 // Pour afficher 50° il faut un coefficient multiplicateur de 0,5 temp = tension_sonde_temp*0.5; if (temp > float (seuil_temp)) // Petite conversion locale de type de variable : byte en float. Exemple : 50 devient 50,000000 { alerte_temp = true; ALERTE(); } else { alerte_temp = false; } } /////////////////////////////////////////////////////////////////// // Affichage des alertes Alimentation ou Température void ALERTE () { if (alerte_alim == true & alerte_temp == false) // Alerte alimentation activée, alerte température désactivée { j = j +1; if (j < 30) { lcd.setCursor (13, 0); lcd.print ("ALM"); } if (j > 30 & j < 60) { lcd.setCursor (13, 0); lcd.print (" ! "); } if (j > 60) { j = 0; } } if (alerte_alim == false & alerte_temp == true) // Alerte alimentation désactivée, alerte température activée { k = k +1; if (k < 30) { lcd.setCursor (13, 0); lcd.print ("TMP"); } if (k > 30 & k < 60) { lcd.setCursor (13, 0); lcd.print (" ! "); } if (k > 60) { k = 0; } } if (alerte_alim == true & alerte_temp == true) // Alerte alimentation activée, alerte température activée { j = j +1; if (j < 30) { lcd.setCursor (13, 0); lcd.print ("ALM"); } if (j > 30 & j < 60) { lcd.setCursor (13, 0); lcd.print (" ! "); } if (j > 60 & j < 90) { lcd.setCursor (13, 0); lcd.print ("TMP"); } if (j > 90 & j < 120) { lcd.setCursor (13, 0); lcd.print (" ! "); } if (j > 120) { j = 0; } } } //////////////////////////////////////////////////////////////// // RAZ ou remise à l'état initial de tous les paramètres void RAZ() { // Réglages par défaut : lcd.setCursor (0,0); lcd.print ("RAZ & sauvegarde"); lcd.setCursor (0,1); lcd.print (" en cours..."); index_pef = 0; // Pas en fréquence = 10 Hz bande = 0; // Bande 40 m index_BLU40 = 0; // index_BLU sur 40 m, initialisé à 0 (BLI) index_BLU10 = 1; // index_BLU sur 10 m, initialisé à 1 (BLS) freq40 = 7100000; // Fréquence par défaut sur 40 m freq10 = 28480000; // Fréquence par défaut sur 10 m index_FI = 0; // Filte FI 2,7 kHz etat_Notch = 0; // Désactivé index_Mesure = 0; // ROS en émission seuil_alim = 110; // Seuil d'alerte de l'alimentation réglé à 11,0 V seuil_temp = 50; // Seuil d'alerte en température réglé à 50°C excursion = 100; // Excursion du scanneur réglée à 100 kHz sauve_param (); // Sauvegarde des réglages par défaut en mémoire delay (2000); raz = 0; // Remet RAZ à l'arrêt Rafraich_tab_var(); // Le tableau de variables des menus est rafraichi niveau_menu = 0; index_menu = 0; index_choix = 0; }