' Layout de définition pour la carte ATM8-STEPPER-TEST ' ------------------------------------------------------------------------------ ' ' Description du programme ' ------------------------ ' Calcul de la position d'une vanne à trois voies dans le cadre d'une ' régulation de chauffage central. La température de chaudière idéale ' est calculée dans l'optimiseur, et envoyée a ce programme. ' Ce programme, démonstrateur de la logique floue, permet de calculer ' le mouvement d'une vanne trois voies, en fonction de la température ' d'eau mesurée et la température d'eau calculée. ' ' Sur ce démonstrateur, les boutons rouges, incrémentent ou décrémentent ' les valeurs des températures d'eau : ' ' T° Eau Mesurée + ' T° Eau Calculée - T° Eau Calculée + ' T° Eau Mesurée - ' ' Et un appuis sur un des boutons noir, lance le calcul du temps ' de commande de la vanne trois voies et le sens (ouverture ou fermeture) ' ' Les résultats sont affichés sur l'écran LCD.sous la forme ' ' +----------------+ ' |M:xx.yy C:xx.yy | M=T°mesurée - C=T°calculée ' |Ouvert x.yy | Ouvert ou Ferme (Temps exprimé en "unité de temps") ' +----------------+ ' ' ------------------------------------------------------------------------------ ' ' Brochage de l'ATMega8 sur la carte de test ' ------------------------------------------ ' I/O ATMega8 = Pn = Fct ' ----------------------------------------------- ' PB0(ICP1) = 14 = OUT8 de ULN2803 ' PB1(OC1A) = 15 = OUT7 de ULN2803 ' PB2(OC1B-/SS) = 16 = OUT6 de ULN2803 ' PB3(MOSI-OC2) = 17 = OUT5 de ULN2803 & MOSI de ISP ' PB4(MISO) = 18 = OUT4 de ULN2803 & MISO de ISP ' PB5(SCK) = 19 = OUT2 de ULN2803 & CLK de ISP ' PB6(XTAL1-TOSC1) = 09 = OUT1 de ULN2803 ' PB7(XTAL2-TOSC2) = 10 = OUT3 de ULN2803 ' ' PC0(ADC0) = 23 = LCD RS ' PC1(ADC1) = 24 = LCD E ' PC2(ADC2) = 25 = LCD D4 ' PC3(ADC3) = 26 = LCD D5 ' PC4(ADC4-SDA) = 27 = LCD D6 ' PC5(ADC5-SCL) = 28 = LCD D7 ' PC6(/RESET) = 01 = RST de ISP ' ' PD0(RXD) = 02 = SW2 (Noir extreme gauche) & RXD UART ' PD1(TXD) = 03 = SW3 (Noir central gauche) & TXD UART ' PD2(INT0) = 04 = SW4 (Noir central droit) ' PD3(INT1) = 05 = SW5 (Noir extreme droit) ' PD4(XCK-T0) = 06 = SW6 (Rouge Bas) ' PD5(T1) = 11 = SW7 (Rouge Gauche) ' PD6(AIN0) = 12 = SW8 (Rouge Droit) ' PD7(AIN1) = 13 = SW9 (Haut) ' ' ------------------------------------------------------------------------------ ' DEBUT DU CODE ' ------------------------------------------------------------------------------ ' Définition & initialisation du processeur ' ----------------------------------------- ' Définition du processeur $regfile = "m8def.dat" ' Définition des fusibles ' LockByte = %11111111 = $FF = 255 - Pas de protection ' HighByte = %11010111 = $D7 = 215 - RSTDISBL=1(PC6=RST)/WDTON=1(Pas de Watchdog)/ ' SPIEN=0(SPI activé)/CKOPT=1(Voir horloge)/ ' EESAVE=0(Eprom préservée)/ ' BOOTSZ1,BOOTSZ0,BOOTRST=111(Pas de Bootrst) ' LowByte = %00100100 = $24 = 36 - BODLEVEL=0/BODEN=0(Brownout activé à 4V)/ ' SUT1..0=10(Startup à 6CK & 65ms)/ ' CKSEL3..0=0100(Clock interne à 8Mhz) ' ------------------------------------------------------------------------------ ' Définition de la vitesse d'horloge ' ---------------------------------- ' (Valeur par défaut = 8 Mhz) (Fusibles CKOPT=1, CKSEL3..0=0100, SUT1..0=10) $crystal = 8000000 ' ------------------------------------------------------------------------------ ' Configuration des I/O ' --------------------- ' Registre DDRxN : Direction (0=Entrée - 1=Sortie) ' Registre PORTxN si entrée : Résistance Pull-up (0=off - 1=on) ' Registre PORTxN si sortie : Ecriture sur le port (0=low - 1=high) ' Registre PINxN : registre de lecture du port (0=low - 1=high) Ddrb = &B11111111 ' OUT8,OUT7,OUT6,OUT5,OUT4,OUT2,OUT1,OUT3 Portb = &B00000000 ' Toutes les sorties à zéro Ddrc = &B11111100 ' RS,E,D4,D5,D6,D7,RST,nc Portc = &B00000011 ' LCD à zéro, et RST en entrée avec pullup Ddrd = &B00000000 ' SW2,SW3,SW4,SW5,SW6,SW7,SW8,SW9 Portd = &B11111111 ' En entrées avec Pullup ' ------------------------------------------------------------------------------ ' Réservation de l'espace mémoire de travail ' ------------------------------------------ $hwstack = 32 ' Réserve la place de la pile hardware $swstack = 10 ' Réserve la place de la pile software $framesize = 40 ' default use 40 for the frame space ' ------------------------------------------------------------------------------ ' Initialisation et configuration de l'UART Hardware ' -------------------------------------------------- $baud = 9600 ' ------------------------------------------------------------------------------ ' Configuration de l'anti-rebond pour les touches ' ----------------------------------------------- Config Debounce = 20 ' ------------------------------------------------------------------------------ ' Configuration de l'écran LCD ' ---------------------------- ' Définition du LCD 2 lignes de 16 caractères et définition des connexions Config Lcd = 16 * 2 Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0 Initlcd Cls Waitms 200 ' ' ------------------------------------------------------------------------------ ' DEBUT DU PROGRAMME ' ------------------------------------------------------------------------------ ' ' Définition des Alias ' -------------------- Sw2 Alias Pind.0 ' SW2 (Noir extreme gauche) Sw3 Alias Pind.1 ' SW3 (Noir central gauche) Sw4 Alias Pind.2 ' SW4 (Noir central droit) Sw5 Alias Pind.3 ' SW5 (Noir extreme droit) Sw6 Alias Pind.4 ' SW6 (Rouge Bas) Sw7 Alias Pind.5 ' SW7 (Rouge Gauche) Sw8 Alias Pind.6 ' SW8 (Rouge Droit) Sw9 Alias Pind.7 ' SW9 (Rouge Haut) Out1 Alias Portb.6 ' OUT1 & LED1 (gauche) Out2 Alias Portb.5 ' OUT2 & LED2 Out3 Alias Portb.7 ' OUT3 & LED3 Out4 Alias Portb.4 ' OUT4 & LED4 Out5 Alias Portb.3 ' OUT5 & LED5 Out6 Alias Portb.2 ' OUT6 & LED6 Out7 Alias Portb.1 ' OUT7 & LED7 Out8 Alias Portb.0 ' OUT8 & LED8 (droite) ' ' Définition des variables ' ------------------------ ' Dim Teauc As Integer ' Température de l'eau calculée en centièmes Dim Teaum As Integer ' Température de l'eau mesurée en centièmes Dim Tconv As Single ' variable "flotante" pour l'affichage des températures Dim Ecart As Single ' Ecart = Teaum-Teauc exprimé en hystérésis Dim Hyseau As Word ' Hystérésis choisi en centièmes de degrés Dim Eca As Single ' Ecart + 3 "retravaillé" dans les limites Dim Ecb As Single ' Partie entière de Eca Dim Fuza As Single ' Première valeur "fuzzifiée" Dim Fuzb As Single ' Deuxième valeur "fuzzifiée" Dim Fuzmin As Single ' Plus petite valeur de Fuza ou fuzb Dim I As Byte ' Variable de travail Dim J As Single ' Variable de travail Dim Tpsvanne As Single ' Temps d'ouverture de la vanne exprimée en unité de temps Dim Sensvan As Bit ' Sens de commande de la vanne (0=Fermeture, 1=Ouverture) Dim Ligne1 As String * 16 ' Première ligne d'affichage Dim Ligne2 As String * 16 ' Deuxième ligne d'affichage Dim Debut As Bit ' Variable activée pour lancer le calcul du temps ' ' Initialisation des variables ' ---------------------------- ' Let Teauc = 5000 ' T° calculée égale 50,00°C Let Teaum = 5000 ' T° mesurée égale 50,00°C Let Hyseau = 500 ' Hystérésis = 5,00°C Let Tpsvanne = 0 ' Temps de commande de vanne = 0 Let Sensvan = 0 ' Sens de commande = Fermeture Let Debut = 0 ' Calcul du temps "bloqué" Let Ligne1 = "Micro-Info asbl" ' Message d'acceuil Let Ligne2 = "-+-+-+-++-+-+-+-" Gosub Affilcd Wait 2 ' Pause de 2 secondes ' ------------------------------------------------------------------------------ ' DEBUT DE LA BOUCLE PRINCIPALE ' ------------------------------------------------------------------------------ Do Gosub Affival ' Affichage des 2 lignes Gosub Lecture ' Lecture des poussoirs If Debut = 1 Then ' Si appuis sur touche noire ' Etape de Fuzzification ' ---------------------- Let Ecart = Teauc - Teaum ' Calcul de l'écart entre mesure et calcul Let Ecart = Ecart / Hyseau ' Print " Ecart : " ; Ecart ' Envoi de la valeur par rs232 Let Eca = Ecart + 3 ' Calcul "brut" de EcA Let Fuza = 0 ' Raz des valeurs Fuza Let Fuzb = 0 ' et Fuzb If Eca <= 1 Then ' Test du cas particulier si Ecart est plus Let Eca = 0 ' petit que -3. Alors EcA est fixé à zéro End If ' Fin du test If Eca >= 5 Then ' Test du cas particulier si Ecart est plus Let Eca = 5.99 ' grand que 3. Alors Eca est fixé à 5,99 End If ' Fin du test Let Ecb = Int(eca) ' Calcul de EcB (partie entière de EcA) Let Fuza = Frac(eca) ' Calcul de Fuza partie fractionnaire de Eca Let Fuza = Fuza * 100 ' et expression de cette valeur en % Let Fuzb = 100 - Fuza ' Fuzb est la valeur complémentaire de Fuza ' Print " Eca : " ; Eca ' Envoi des valeurs par rs232 ' Print " Ecb : " ; Ecb ' Print " Fuza : " ; Fuza ' Print " Fuzb : " ; Fuzb ' Etape de Défuzzification ' ------------------------ If Ecb = 0 Then ' Cas particulier où le temps de commande Let Tpsvanne = -3 ' de la vanne est inférieur à -3. Else ' Sinon If Ecb = 5 Then ' Cas particulier où le temps de commande Let Tpsvanne = 3 ' de la vanne est supérieur à 3 Else ' Si TpsVanne est compris entre -3 et 3 Let Fuzmin = Fuza ' Mise à jour "arbitraire" de Fuzmin sur Fuza If Fuzb < Fuza Then ' Si Fuzb est plus petite que Fuza Let Fuzmin = Fuzb ' alors Fuzmin est mis à jour sur Fuzb End If ' Fin du test sur Fuzb ' Print " Fuzmin : " ; Fuzmin ' Envoi de la valeur de fuzmin par rs232 Let J = Ecb - 2.5 Let Tpsvanne = Fuzmin / 400 ' Calcul du temps de commande Let Tpsvanne = Tpsvanne + J End If ' Fin du test de TpsVanne > 3 End If ' Fin du test de TpsVanne < -3 Let Sensvan = 1 ' Le sens de commande est mis en ouverture If Tpsvanne < 0 Then ' Si le tps de commande de vanne est négatif Let Sensvan = 0 ' Le sens de commande est mis en "Fermeture" End If ' Fin du test de sens de commande Let Tpsvanne = Abs(tpsvanne) ' Calcul du tempsVanne en valeur positive ' Print "Tpsvanne : " ; Tpsvanne ' Envoi des valeurs de sortie par rs232 ' Print "Sensvan : " ; Sensvan ' Print "-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+" ' Envoi d'un séparateur End If ' Fin du test "touche noire" Loop ' Fin de la boucle du programme principal End ' Fin du programme ' ------------------------------------------------------------------------------ ' SOUS ROUTINES ' ------------------------------------------------------------------------------ ' Lecture (Routine de lecture des poussoirs) ' ------- Lecture: ' Début de la routine Let Debut = 0 ' Initialisation de la variable de conversion If Sw9 = 0 Then ' si appuis de la touche rouge haut Let Teaum = Teaum + 10 ' Augmentation de la température mesurée de 1/10°C Waitms 100 ' Petite pause End If ' Fin du test touche rouge haut If Sw6 = 0 Then ' si appuis de la touche rouge haut Let Teaum = Teaum - 10 ' Diminution de la température mesurée de 1/10°C Waitms 100 ' Petite pause End If ' Fin du test touche rouge haut If Sw8 = 0 Then ' si appuis de la touche rouge haut Let Teauc = Teauc + 10 ' Augmentation de la température calculée de 1/10°C Waitms 100 ' Petite pause End If ' Fin du test touche rouge haut If Sw7 = 0 Then ' si appuis de la touche rouge haut Let Teauc = Teauc - 10 ' Diminution de la température calculée de 1/10°C Waitms 100 ' Petite pause End If ' Fin du test touche rouge haut If Sw2 = 0 Or Sw3 = 0 Or Sw4 = 0 Or Sw5 = 0 Then ' Si appuis touche noire Let Debut = 1 ' Mise à jour de la variable de conversion Waitms 200 ' Petite pause End If ' Fin du test des touches noires Return ' Fin de la routine ' ------------------------------------------------------------------------------ ' AffiLCD (Routine d'affichage des deux lignes sur l'écran LCD) ' ------- Affilcd: ' Début de la routine Home ' Curseur en position Home Lcd Ligne1 ' Affichage de la première ligne Lowerline ' Curseur en deuxième ligne Lcd Ligne2 ' Affichage de la deuxième ligne Return ' Fin de la routine ' ------------------------------------------------------------------------------ ' AffiVal (Formation des deux lignes avec les valeurs à afficher) ' ------- Affival: ' Début de la routine Let Tconv = Teaum / 100 ' Calcul de la valeur à afficher (Teaum) Let Ligne1 = "M:" + Fusing(tconv , "##.##") ' Construction de l'affichage de la valeur mesurée Let Tconv = Teauc / 100 ' Calcul de la valeur à afficher (Teauc) Let Ligne1 = Ligne1 + " C:" + Fusing(tconv , "##.##") ' Construction de l'affichage de la valeur calculée If Sensvan = 1 Then ' Test du sens de commande de la vanne Let Ligne2 = "Ouvert " ' Construction de la deuxième ligne Else ' Let Ligne2 = "Ferme " ' End If ' Fin du test du sens de la commande Let Tconv = Tpsvanne ' Calcul de la valeur à afficher (Tpsvanne) Let Ligne2 = Ligne2 + Fusing(tconv , "#.##") ' Construction de l'affichage pour cette valeur Gosub Affilcd ' Fin de la routine Return