Programmation structurée du programme Optimiseur ************************************************ BEGIN ' Début du programme GOSUB InitMicro ' Initialisation du Hardware GOSUB InitVar ' Création & initialisation des variables GOSUB InitLcd ' Initialisation de l'écran LCD GOSUB InitI2c ' Initialisation de l'horloge et de la mémoire GOSUB Init1Wire ' Initialisation des sondes de température DO WHILE I=I ' Début de la boucle principale infinie GOSUB LitEncodeur ' Lecture de la molette GOSUB LitHeure ' Lecture de l'heure dans le DS3231 en I2C GOSUB LitPlageH ' Lecture de la plage en cours (1=jour/0=nuit) GOSUB LitSondeT ' Lecture des DS18B20-PAR en 1Wire GOSUB Consommation ' Mise à jour des donnéesde consomation GOSUB CourbeDeChau ' Adaptation de la "courbe de chauffe" GOSUB ModeActif ' Actions à réaliser en fonction du mode actif GOSUB Communication ' Teste si le PC "demande" des infos et les envoie GOSUB Affichage ' Mise en forme de l'affichage GOSUB AffiLCD ' Mise à jour de l'affichage sur le LCD ENDDO ' Fin de la boucle principale infinie END ' Fin du programme ******************************************************************************* SOUS-ROUTINES ******************************************************************************* ------------------------------------------------------------------------------- Routine InitVar ------------------------------------------------------------------------------- Cette routine crée et initialise toutes les variables du programme Variables d'entrées : Aucune Variables de sortie : Toutes Variables de travail : Toutes Routines appellées : Aucune ------------------------------------------------------------------------------- SUB InitVar DECLARE MoletteCompteur AS INTEGER ' Compteur de la rotation de la molette DECLARE MoletteComptOld AS INTEGER ' Ancienne valeur de MoletteCompteur DECLARE MoletteDelta AS INTEGER ' Valeur du changement de la valeur ' du compteur de la molette DECLARE Bouton AS BIT ' Etat du bouton de la molette DECLARE BoutonOld AS BIT ' Ancienne valeur du bouton de molette DECLARE CompteurBtn AS WORD ' Compteur de temps pour l'appuis DECLARE TpsBouton AS WORD ' Valeur de la durée de l'appuis DECLARE CompteurTps AS WORD ' Compteur général de temps (Timeout) DECLARE TpsDemiSeconde AS WORD ' Nombre de référence pour 0,5s DECLARE AffiFormat AS BYTE ' Format d'affichage sur l'écran LCD ' Dizaines = Nombre de chiffres avant la virgule ' Unités = Nombre de chiffres après la virgule ' Si = 99 alors, affichage HH:MM DECLARE AffiNombre AS BYTE ' Nombre à afficher à l'écran LCD DECLARE NbAsc$ AS ALPHA ' Représentation alphanumérique ' de Affinombre avec le format AffiFormat ENDSUB ------------------------------------------------------------------------------- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Routine IntBouton ------------------------------------------------------------------------------- Cette routine fonctionne par intérruptions. Lors d'une rotation de la molette, ou lors de l'appuis sur le bouton, Une intéruption du microcontrôleur est générée et le processeur est arrêté, puis dirigé vers cette routine. Elle met alors le compteur MoletteCompteur à jour, ainsi que la variable Bouton. Pendant l'exécution de cette routine, les intéruptions sont inhibées. Variables d'entrées : Aucune Variables de sortie : MoletteCompteur, MoletteComptOld, MoletteDelta Bouton, BoutonOld Variables de travail : Aucune Routines appellées : Aucune ------------------------------------------------------------------------------- SUB IntBouton ' Début de la routine ' Evite une double entrée dans la ' routine. ' Petite pause antirebond LET MoletteComptOld = MoletteCompteur ' Mise en mémoire ancienne valeur IF THEN ' Si le bouton est tourné --> LET MoletteCompteur = MoletteCompteur + 1 ' Incrémente le compteur ELSE ' Si le bouton est tourné <-- LET MoletteCompteur = MoletteCompteur - 1 ' Décrémente le compteur ENDIF ' Fin du test de rotation LET MoletteDelta = MoletteCompteur - MoletteCompteurOld LET BoutonOld = Bouton ' Mise en mémoire de l'ancienne ' valeur de "Bouton" (appuis) LET Bouton = 0 ' Mise à zéro (bouton relaché) IF THEN ' Si la molette est appuyée LET Bouton = 1 ' Mise à jour de Bouton ENDIF ' Fin du test d'appuis ' Redémarre les intéruptions ENDSUB ' Fin de la routine ------------------------------------------------------------------------------- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Routine IntTempo ------------------------------------------------------------------------------- Cette routine fonctionne par intérruptions. Un compteur tourne en permanence dans le processeur. A chaque fois qu'il atteint une valeur prédéfinie, des compteurs sont incrémentés. Ces compteurs servent au "timeout" du menu par exemple, et à mesurer le temps d'appuis sur les boutons. Pendant l'exécution de cette routine, les intéruptions sont inhibées. Variables d'entrées : Aucune Variables de sortie : CompteurBtn, CompteurTps Variables de travail : Routines appellées : Aucune ------------------------------------------------------------------------------- SUB IntTempo ' Début de la routine ' Evite une double entrée dans la routine. LET CompteurBtn = CompteurBtn + 1 ' Incrémentation des LET CompteurTps = CompteurTps + 1 ' compteurs de temps ' Redémarre les intéruptions ENDSUB ' Fin de la routine ------------------------------------------------------------------------------- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Routine LitEncodeur ------------------------------------------------------------------------------- Cette routine permet de lire l'encodeur rotatif, et permet les changements de température de consigne, les changements de modes, la gestion des dérogations et éventuellement l'entrée dans le menu Variables d'entrées : MoletteDelta, Bouton, Mode, Plage, TpsDemiSeconde Variables de sortie : Mode, Indice(16), Indice(15), Derogabit Variables de travail : AffiFormat, AffiNombre, AffiDiviseur, Ligne1$, Ligne 2$, TConsNuitOld, TConsJourOld, CompteurTps, CompteurBtn, NbAsc$, Oldmode Routines appellées : ConvNumAsc, AffiLcd, Menu, ChgtMode ------------------------------------------------------------------------------- SUB LitEncodeur IF Bouton = 1 THEN ' Si appuis sur le bouton ' Activation de l'afficheur IF MoletteDelta <> 0 THEN ' Si roulette tournée IF Mode=2 OR (Mode=4 AND Plage=0) OR (Mode=5 AND OldMode=3) THEN ' Si Mode Nuit LET TConsNuitOld = Indice(16) ' Maj de l'ancienne T° LET AffiFormat = 21 ' Préparation des variables LET AffiNombre = TConsNuitOld ' pour l'appel de la routine LET AffiDiviseur = 2 ' "ConvNumAsc" GOSUB ConvNumAsc ' Appel de la routine LET Ligne1$ = "ANCIENNE: "+NbAsc$+"°C" ' Maj de la ligne 1 DO WHILE compteurTps < TpsDemiSeconde*6 OR Bouton = 1 ' Boucle d'attente ' sur 3s ou sur appuis bouton LET Indice(16) = Indice(16) + MoletteDelta ' Maj de la TConsNuit IF Indice(16) > 60 THEN ' Test de dépassement haut Indice(16) = 60 ' Ajustement de la valeur ENDIF ' Fin du test haut IF Indice(16) < 20 THEN ' Test de dépassement bas Indice(16) = 20 ' Ajustement de la valeur ENDIF ' Fin du test bas LET AffiFormat = 21 ' Préparation des variables LET AffiNombre = Indice(16) ' pour l'appel de la routine LET AffiDiviseur = 2 ' "ConvNumAsc" GOSUB ConvNumAsc ' Appel de la routine LET Ligne2$ = "NOUVELLE: "+NbAsc$+"°C"' Maj de la ligne 2 GOSUB AffiLcd ' Affiche les 2 lignes sur LCD ENDDO ' Fin de la boucle d'attente ENDIF ' Fin du test du mode nuit (2) IF Mode=3 OR (Mode=4 AND Plage=1) OR (Mode=5 AND OldMode=2) THEN ' Si Mode Jour LET TConsJourOld = Indice(15) ' Maj de l'ancienne T° LET AffiFormat = 21 ' Préparation des variables LET AffiNombre = TConsJourOld ' pour l'appel de la routine LET AffiDiviseur = 2 ' "ConvNumAsc" GOSUB ConvNumAsc ' Appel de la routine LET Ligne1 = "ANCIENNE: "+NbAsc$+"°C" ' Maj de la ligne 1 DO WHILE CompteurTps < TpsDemiSeconde*6 OR Bouton = 1 ' Boucle d'attente ' sur 3s ou sur appuis bouton LET Indice(15) = Indice(15) + MoletteDelta ' Maj de la TConsJour IF Indice(15) > 60 THEN ' Test de dépassement haut Indice(15) = 60 ' Ajustement de la valeur ENDIF ' Fin du test haut IF Indice(15) < 20 THEN ' Test de dépassement bas Indice(15) = 20 ' Ajustement de la valeur ENDIF ' Fin du test bas LET AffiFormat = 21 ' Préparation des variables LET AffiNombre = Indice(15) ' pour l'appel de la routine LET AffiDiviseur = 2 ' "ConvNumAsc" GOSUB ConvNumAsc ' Appel de la routine LET Ligne2 = "NOUVELLE: "+NbAsc$+"°C" ' Maj de la ligne 2 GOSUB AffiLCD ' Affiche les 2 lignes sur LCD ENDDO ' Fin de la boucle d'attente ENDIF ' Fin du test du mode jour (3) ENDIF ' Fin du test de rotation de roulette ELSE ' Si Bouton relaché (ou inactif) IF BoutonOld = 1 THEN ' Et si il vient de l'être IF CompteurBtn >= TpsDemiSeconde THEN ' Si appuis >= à une 1/2s IF CompteurBtn > TpsDemiSeconde*2 THEN' Si appuis > à une seconde GOSUB Menu ' Aller à la routine "MENU" ELSE ' Si appuis entre 1/2s et 1s IF Derogabit = 0 THEN ' Si pas mode dérogation LET Derogabit = 1 ' Passage en mode dérogation LET OldMode = Mode ' Mise en mémoire du mode LET Mode = 5 ' Maj du mode dérogation ELSE ' Si mode dérogation LET Derogabit = 0 ' Sortie de dérogation LET Mode = OldMode ' Retour au mode précédent ENDIF ' Fin du changement dérogation ENDIF ' Fin test appuis 1s ELSE ' Si appuis < à 1/2s IF MoletteDelta <> 0 THEN ' Si molette tournée ENDIF ' Fin de test de rotation GOSUB ChgtMode ' Changement de mode ENDIF ' Fin de test 1/2s LET CompteurBtn = 0 ' Reset tps bouton appuyé ENDIF ' Fin de test relachement bouton ' Désactivation de l'afficheur LET CompteurTps = 0 ' Reset du compteur de temps ENDIF ' Fin de test d'activité bouton ENDSUB ' Fin de la routine ------------------------------------------------------------------------------- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Routine ConvNumAsc ------------------------------------------------------------------------------- Cette routine exécute la conversion d'un nombre AffiNombre, divisé par AffiDiviseur, en une chaine de charactère NbAsc$. Le Format est donné par la variable AffiFormat Variables d'entrées : AffiFormat, AffiNombre, AffiDiviseur Variables de sortie : NbAsc$, Quart Variables de travail : Nombre, Digit$(5), NbChar, I Routines appellées : Aucune ------------------------------------------------------------------------------- SUB ConvNumAsc IF AffiFormat = 99 THEN ' S'il s'agit d'un format "horaire" LET Digit$(1) = CHR$(INT(AffiNombre/40) + 48) ' Extraction des dizaines d'heures LET Digit$(2) = CHR$(INT(AffiNombre/4) - ((ASC(Digit$(1)) - 48) * 10) + 48) ' Extraction des unités d'heures LET Digit$(3) = ":" ' Séparateur des hures et des minutes LET Quart = (AffiNombre - INT(AffiNombre/4) * 4) * 15 ' Calcul des minutes par quart d'heure LET Digit$(4) = CHR$(INT(Quart/10) + 48) ' Extraction des dizaines de minutes LET Digit$(5) = CHR$(Quart - (INT(Quart/10) * 10) + 48) ' Extraction des unités de minutes LET NbChar = 5 ' Nombre de charactères à afficher = 5 ELSE ' Si le format n'est pas "horaire" LET Nombre = AffiNombre / AffiDiviseur ' Calcul du nombre à convertir IF AffiFormat = 10 THEN ' Si le format est "un chiffre" LET Digit$(1) = CHR$(Nombre + 48) ' Extraction du chiffre LET NbChar = 1 ' Nombre de charactères à afficher = 1 ENDIF ' Fin du format "un chiffre" IF AffiFormat = 11 THEN ' Si "un chiffre avant et après la virgule" LET Digit$(1) = CHR$(Nombre + 48) ' Extraction du chiffre avant la virgule LET Digit$(2) = "," ' Ajout de la virgule LET Digit$(3) = CHR$((Nombre - INT(Nombre)) * 10 + 48) ' Extraction du chiffre après la virgule LET NbChar = 3 ' Nombre de charactères à afficher = 3 ENDIF ' Fin du format "un chiffre avant & après la ," IF AffiFormat = 20 THEN ' Si le format est "deux chiffres" LET Digit$(1) = CHR$(INT(Nombre/10) + 48) ' Extraction des dizaines LET Digit$(2) = CHR$((Nombre - INT(Nombre/10)) * 10 + 48) ' Extraction des unités LET NbChar = 2 ' Nombre de charactères à afficher = 2 ENDIF ' Fin du format "deux chiffres" IF AffiFormat = 21 THEN ' Si le format est "2 avant & 1 après la ," LET Digit$(1) = CHR$(INT(Nombre/10 + 48) ' Extraction des dizaines LET Digit$(2) = CHR$(INT(Nombre - (INT(Nombre/10) * 10) + 48)) ' Extraction des unités LET Digit$(3) = "," ' Ajout de la virgule LET Digit$(4) = CHR$(Affi-((ASC(Digit$(1))-48)*10) -((ASC(Digit$(2))-48]*10)+48) ' Extraction des dizièmes LET NbChar = 4 ' Nombre de charactères à afficher = 4 ENDIF ' Fin du format "2 avant & 1 après la ," ENDIF ' Fin des tests de formats LET NbAsc$ = "" ' Reset de la variable d'affichage I = 1 ' Reset du compteur de boucle DO WHILE I <= NbChar ' Boucle sur le nombre de charactères à afficher LET NbAsc$ = NbAsc$ + Digit$(I) ' Ajout des digits dans la variable LET I = I + 1 ' Incrémentation du compteur de boucle ENDDO ' Bouclage ENDSUB ' Fin de la routine ------------------------------------------------------------------------------- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Routine Menu ------------------------------------------------------------------------------- Le fonctionnement du menu est articulé autour de trois éléments : 1 - Un tableau stocké en EEprom contenant les éléments suivants : - Le contenu d'affichage de la ligne 1 (16 octets) - Le contenu d'affichage de la ligne 2 (16 octets) - La position du curseur sur l'écran de 1 à 32 (1 octet) - Action si molette --> (1 octet) - Action si molette <-- (1 octet) - Action si bouton appuyé (1 octet) (élément 2) - Indice de variable (1 octet) (élément 3) Ce tableau reprend 59 "lignes" reprenant les 59 "écrans" du menu. 2 - Des codes actions qui déterminent l'action à réaliser dans le menu. Les actions sur molette sont de deux types. Soit la valeur est inférieure à 128, et dans ce cas, le nombre indique la "ligne" à laquelle le menu vas se connecter suite à l'action de la molette. La valeur 128 correspond à l'incrémentation de la variable en cours, et le code 129 à la diminution. Pour l'appuis sur la molette, les codes sont compris entre 130 et 144 et déterminent des actions "spéciales" : sortie du menu, choix du cycle, choix du jour, suppression de plage ou choix du type de vanne de régulation. 3 - Des variables indicées Indice(18), LimitBas(18), LimitHaut(18), Divise(18) et Format(18). Ces variables indicées reprennent en fait les différentes variables que le menu est capable de modifier. Pour chacune des 18 variables, nous avons Indice(n) qui reprend la variable en elle-même. Pour des raisons de facilité et d'économie de mémoire, ces variables sont exprimées en "Unité", donc toujours des nombres entiers. Pour contourner cet obstacle, la variable Divise(n) contient le diviseur de la variable Indice(n). Par exemple, si l'on veux stocker une température exprimée avec une précision d'un dixième de degré, le contenu de la variable Indice(n) contiendra T°*10, et Divise(n) sera égal à 10. Les variables LimitBas(n) et LimitHaut(n) contiennent les limites haute et basse entre lesquelles la variable Indice(n) doit se trouver. Enfin, l'élément Format(n) contient le "format d'affichage" de la variable Indice(n). Les dizaines de cette variable indiquent le nombre de chiffre avant la virgule, tandis que les unités indiquent le nombre de chiffre après la virgule. Dans notre programme, seuls les formats 10, 11, 20 & 21 seront utilisés. Une exeption pour le format "99" qui lui renvoie vers un format horaire "hh:mm". Un autre avantage de l'utilisation de variables "unité" est que chaque "clic" de la molette correspondra toujours à une différence égale à la précision de la variable en cours de modification. Si par exemple, la modification concerne une T° au dixième de degré, chaque clic de la molette provoquera une modification de 1/10 de °C. Dans son fonctionnement, la routine "Menu" vas reprendre le contenu de l'EEprom pour la ligne en cours (pour cela, il démarre sur la première zone mémoire de l'EEprom), puis, en fonctions de l'action sur la molette, exécutera soit une action, soit un passage à une autre ligne du menu. Et l'action à réaliser est définie par les différentes variables mises à jour par le contenu correspondant de l'EEprom Variables d'entrées : Aucune Variables de sortie : Aucune Variables de travail : BoucleMenu, MnuNum, MnuAdres, BaseAdres, Ligne1$, Ligne2$, MnuPosCur, MnuActHorlo, MnuActAntiH, MnuActRet, MnuIndiVar, RetroLcd, MoletteDelta, CompteurTps Indice(),Divise(),Format(),LimitBas(),LimitHaut() AffiFormat, AffiNombre, AffiDiviseur, Tmp$, NbAsc$ NbChar, NumCycle, Jour, TypeVanne, TpsDemiSeconde PlDe(), PlDu() Routines appellées : AffiLcd, ConvNumAsc, SupprimePlage, CreaVarPlag ------------------------------------------------------------------------------- SUB MENU LET MnuNum = 1 DO WHILE BoucleMenu = 1 ' Début de la boucle principale LET MnuAdres = BaseAdres + 37 * (MnuNum - 1) ' Lecture de la mémoire (MENU) à partir de MnuAdres LET Ligne1$ = MnuAdres ' 16 premières mem dans Ligne1$ LET Ligne2$ = MnuAdres + 16 ' 16 suivantes dnas Lignes2$ LET MnuPosCur = MnuAdres + 32 ' Les 5 variables suivantes LET MnuActHorlo = MnuAdres + 33 ' sont mises à jour avec LET MnuActAntiH = MnuAdres + 34 ' les 5 octets qui suivent LET MnuActRet = MnuAdres + 35 ' la fin de la seconde ligne. LET MnuIndiVar = MnuAdres + 36 ' LET RetroLcd = 1 ' Allumage du Rétro-éclairage IF MnuNum >= 26 AND MnuNum <=31 THEN ' Si le menu concerne un cycle LET AffiFormat = 10 ' Préparation des variables LET AffiNombre = Cycle ' pour l'appel de la routine LET AffiDiviseur = 1 ' "ConvNumAsc" GOSUB ConvNumAsc ' Appel de la routine de conv. LET Ligne1$ = "" ' Mise à jour de la première ligne ENDIF ' Fin du test d'affichage de cycle GOSUB Affilcd ' Affichage des 2 lignes IF Bouton = 0 THEN ' Si pas d'appuis sur le bouton IF MoletteDelta > 0 THEN ' Molette dans le Sens horlogique LET CompteurTps = 0 ' Reset du compteur de temps (Timeout) IF MnuActHorlo < 128 THEN ' Si MnuActHorlo plus petit que 128 LET MnuNum = MnuActHorlo ' Aller à la ligne du Menu indiquée ' par la valeur de MnuActHorlo ELSE ' Si action > 127 (Inc. variable) LET Indice(MnuIndiVar) = Indice(MnuIndiVar) + 1 ' Incrémente la variable IF Indice(MnuIndiVar) > LimitHaut(MnuIndiVar)) ' Si Limite haute dépassée LET Indice(MnuIndiVar) = LimitBas(MnuIndiVar) ' Mettre à la limite basse ENDIF ' Fin de test de limite haute LET AffiFormat = Format(MnuIndiVar) ' Préparation des variables LET AffiNombre = Indice(MnuIndiVar) ' pour l'appel de la routine LET AffiDiviseur = Divise(MnuIndiVar) ' "ConvNumAsc" GOSUB ConvNumAsc ' Appel de la routine de conv. Tmp$ = Ligne2$ ' Création de la deuxième Ligne2$ = LEFT$(Tmp$,MnuPosCur) ' ligne d'affichage avec la Ligne2$ = Ligne2$ + NbAsc$ ' variable retournée par la Ligne2$ = Ligne2$ + RIGHT(Tmp$,MnuPosCur+NbChar) ' routine "ConvNumAsc" GOSUB AffiLCD ' Affichage sur l'écran LCD ENDIF ' Fin du test de modif de variable ELSE ' Molette dans le sens AntiHorlogique LET CompteurTps = 0 ' Reset du compteur de temps (Timeout) IF MnuActHorlo < 128 THEN ' Si MnuActHorlo plus petit que 128 LET MnuNum = MnuActHorlo ' Aller à la ligne du Menu indiquée ' par la valeur de MnuActHorlo ELSE ' Si action > 127 (Déc. variable) LET Indice(MnuIndiVar) = Indice(MnuIndiVar) - 1 ' Incrémente la variable IF Indice(MnuIndiVar) > LimitBas(MnuIndiVar) ' Si Limite basse dépassée LET Indice(MnuIndiVar) = LimitHaut(MnuIndiVar) ' Mettre à la limite haute ENDIF ' Fin de test de limite basse LET AffiFormat = Format(MnuIndiVar) ' Préparation des variables LET AffiNombre = Indice(MnuIndiVar) ' pour l'appel de la routine LET AffiDiviseur = Divise(MnuIndiVar) ' "ConvNumAsc" GOSUB ConvNumAsc ' Appel de la routine de conv. Tmp$ = Ligne2$ ' Création de la deuxième Ligne2$ = LEFT$(Tmp$,MnuPosCur) ' ligne d'affichage avec la Ligne2$ = Ligne2$ + NbAsc$ ' variable retournée par la Ligne2$ = Ligne2$ + RIGHT(Tmp$,MnuPosCur+NbChar) ' routine "ConvNumAsc" GOSUB AffiLCD ' Affichage sur l'écran LCD ENDIF ' Fin du test de modif de variable ENDIF ' Fin du test de rotation de molette ELSE ' Si appuis sur le bouton LET CompteurTps = 0 ' Reset du compteur de temps (Timeout) IF MnuActRet = 130 THEN ' Si MnuActRet = 130, LET BoucleMenu=0 ' Quitter le Menu, affichage normal ENDIF ' Fin de "sortie" IF MnuActRet < 128 THEN ' Si MnuActRet plus petit que 128 LET MnuNum = MnuActRet ' Changer de ligne dans le Menu ENDIF ' Fin de "changement menu" IF MnuActRet >= 131 AND MnuActRet <= 134 THEN ' Si Changement de cycle LET NumCycle = MnuActRet - 130 ' Sélection du "Cycle" ENDIF ' Fin de changement de cycle IF MnuActRet >= 135 AND MnuActRet <= 141 THEN ' Si séléction du jour LET Jour = MnuActRet - 134 ' Sélection du "Jour" LET MnuNum = 54 ' Aller à la ligne 54 du Menu ENDIF ' Fin du changement de jour IF MnuActRet = 142 THEN ' Si Suppression plage LET BitAction = 0 ' Prépare l'éffacement de la plage GOSUB ModifPlage ' Suppression de la Plage en cours LET MnuNum = 31 ' Aller à la ligne 31 du Menu ENDIF ' Fin de suppression plage IF MnuActRet >= 143 AND MnuActRet <= 144 THEN ' Si Chgt de type de vanne LET TypeVanne = MnuActRet - 143 ' 0 = Vanne à positionement ' ou 1 = Vanne Analogique ENDIF ' Fin Chgt de type de vanne ENDIF ' Fin du test du bouton IF CompteurTps >= TpsDemiSeconde*6 ' Si Timeout atteint LET BoucleMenu = 0 ' Quitter le menu ENDIF ' Fin du test de TimeOut ENDDO ' Fin de la boucle de menu LET RetroLcd = 0 ' Extinction du Rétro-éclairage RETURN 'Fin de la Routine MENU ------------------------------------------------------------------------------- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Routine AffiLCD ------------------------------------------------------------------------------- Affichage des chaînes Ligne1$ et Ligne2$ sur l'écran LCD Variables d'entrées : Ligne1$, Ligne2$ Variables de sorties : Aucune Variables de travail : Aucune Sousroutines appellées : Aucune SUB Affilcd ' Début de la routine ' Affichage de la première ligne ' Affichage de la seconde ligne ENDSUB ' Fin de la routine ------------------------------------------------------------------------------- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Routine ModifPlage ------------------------------------------------------------------------------- Active ou Supprime la Plage en cours Variables d'entrées : BaseAdresPlage, NumCycle, Jour, PlDe(NumCycle) PlDu(NumCycle), BitAction Variables de sorties : Aucune Variables de travail : PlI, PlOctCal, PlBitCal, PlPosCyc, PlPosJou, PlPosMem PlValMem, PlPosBit, PlValBit Sousroutines appellées : Aucune ------------------------------------------------------------------------------- SUB SupprimePlage ' Début de la routine LET PlPosCyc = (NumCycle*84) ' Calcul adresse de base du cycle LET PlPosJou = INT(Jour*12) ' Calcul adresse de base du jour dans le cycle LET PlI = PlDe(Cycle) ' Init. de la boucle DO While PlI < PlDe(NumCycle) + PlDu(NumCycle) ' Comptage sur la durée LET PlOctCal = INT(plDe(NumCycle)/8) ' LET PlBitCal = 7 - (PlDe(NumCycle)-(PlOctCal*8)) ' LET PlPosMem = PlAdresse + PlPosCyc + PlPosJou + PlOctCal ' ' Calcul de l'octet à adresser en fonction du cycle, de la date et l'heure. LET PlValMem = ' IF BitAction = 0 THEN ' Si action éffacement LET PlValMem = PlValMem .OR. (.AND. (255-2^PlBitCal)' Effacement (Reset) ELSE ' Si action écriture LET PlValMem = PlValMem .OR. (2^PlBitCal) ' Ecriture (Set) ENDIF ' Fin de test Set/Reset LET PlI = PlI + 1 LET Octect à l'adresse PlPosmem = PlValMem ENDDO ENDSUB ------------------------------------------------------------------------------- Routine CreaVarPlag ------------------------------------------------------------------------------- Création des variables nécessaires aux manipulation sur les plages horaires Variables d'entrées : BaseAdresPlage, NumCycle, Jour Variables de sorties : PlDe(4), PlDu(4) Variables de travail : PlI, PlPosCyc, PlPosJou, PlPlage, PlAdrOct, PlValOct, PlAdrBit, PlBitAnt, PlDuree, PlOctet Sousroutines appellées : Aucune ------------------------------------------------------------------------------- SUB CreaVarPlag ' Début de la routine PlPosCyc = (NumCycle*84) ' Calcul de l'adresse du cycle PlPosJou = INT(Jour*12) ' Calcul de l'adresse du jour LET PlI = 1 ' Initialisation remise à zéro DO WHILE PlI < 5 ' Début boucle de remise à zéro LET PlDe(PlI) = 0 ' Mise à zéro "début" LET PlDu(PlI) = 0 ' Mise à zéro "durée" LET PlI = PlI+1 ' Incrémentation compteur ENDDO ' Bouclage de raz LET PlPlage = 1 ' Initialisation compteur "Debut" LET PlBitAnt = 0 ' Initialisation du bit "antérieur" LET PlI = 0 ' Initialisation variable de boucle DO WHILE PlI <= 95 ' Boucle sur les 96 bits à tester LET PlOctet = INT(PlI/12) ' Calcul de l'octet à adresser LEt PlAdrBit = 7-(PlI-(PlOctet*8)) ' Calcul du numéro du bit à adresser LET PlAdrOct = BaseAdresPlage+PlPosCyc+PlPosJou ' Cacul de l'adresse de l'octet à tester LET PlValOct = ' Traitement de l'erreur trop de plages ENDIF ' Fin du test de dépassement du nombre de plages ENDIF ' Fin du test de changement de bit ENDIF ' Fin du test du bit LET PlI = PlI + 1 ' Incrémentation de la variable de boucle ENDDO ' Bouclage sur les 96 bits ENDSUB ' Fin de la routine