dimanche 23 mai 2010

Programme de gestion

Voici le programme de gestion complet...  Après plusieurs versions, celui à l'air de répondre au cahier des charges... il correspond au diagramme de fonctionnement décrit ici.
Il a été rajouté une commande manuelle / automatique, un affichage un peu plus abouti des diverses températures et modes de fonctionnement (afficheur et LEDs),



NB : attention aux retours  des lignes longues





'-----------------------------------------------------------------------------------------------
' ------------------------ COMMANDE CIRCULATEUR CHAUFFE-EAU SOLAIRE ---------------------------
'-----------------------------------------------------------------------------------------------

'################################ constantes ########################################
'----------------------- PIC --------------
CONST DEVICE = 3B                    'pic utilisé

'----------------------- variables de fonctionnement ----------------
dim deltaON as byte
dim Tchlimit as byte
dim tempoV3 as byte
dim tempoBOUCLE as byte
dim Tchmin as byte
dim Nmax as byte
dim version as byte

'------------------------------------------------------------------------
'----------------------- initialisation des variables -------------------
'------------------------------------------------------------------------
deltaON = 4                        'difference de temperature pour enclencher le fonctionnement (en degrés)
Tchlimit = 90                        'temperature maxi du haut de cuve (en degrés)
tempoV3 = 40                        'durée du démarrage en vitesse 3 (en secondes)
tempoBOUCLE = 50                    'durée de la boucle principale - sans tenir compte des autres temps (en ms)
Tchmin = 48                        'valeur minimale de Tch pour obtenir ECS à 38°C (en degrés) alarme LED
Nmax = 50                        'temporisation de l affichage des choix de mode auto / manu, de mode manu (en 0,1 seconde)
version = 8                        'version du programme

'----------------------- I2C --------------
Const SCL = 11                        'port I2C
Const SDA = 12                        'port I2C

'----------- DS2482 adresses de canaux d'acquisition --------------
Const CH0 = &HF0                    'chanel P0 - pin 14
Const CH1 = &HE1                    'chanel P1 - pin 15
Const CH2 = &HD2                    'chanel P2 - pin 16
Const CH3 = &HC3                    'chanel P3 - pin 1
Const CH4 = &HB4                    'chanel P4 - pin 12
Const CH5 = &HA5                    'chanel P5 - pin 11
Const CH6 = &H96                    'chanel P6 - pin 10
Const CH7 = &H87                    'chanel P7 - pin 9

'----------------------- SORTIES --------------
CONST SV1 = 14                        'port sortie pour commande vitesse 1
CONST SV3 = 15                        'port sortie pour commande vitesse 3

'----------------------- LEDS --------------
Const LEDR1 = 5                        'led rouge clignotante sur Tch < Tchmin (necessaire pour ECS)
Const LEDR2 = 6                        'led rouge témoin circulateur en vitesse 1 (normal)
Const LEDJ = 7                        'led jaune témoin circulateur en vitesse 3 (pour monter colonne eau)
Const LEDV = 8                        'led verte témoin circulateur en arrêt

'----------------------- Inters --------------
Const bpBleu = 16                    'bouton poussoir bleu
Const bpRouge = 17                    'bouton poussoir rouge

'################################ variables ########################################

'---------------------- Variables temperature ----------------------
'--- mesures dans l'eau
dim Trc as byte                        'température de l'eau en sortie de capteur solaire (le capteur échange-t-il bien ?)
dim Tch as byte                        'température de l'eau en haut de la cuve
dim Tcb as byte                        'température de l'eau en bas de la cuve (stratification ?)
dim Tecs as byte                    'température de l'eau chaude sanitaire (le serpentin échange-t-il bien ?)

'--- mesures dans l'air
dim Tcap as byte                    'température de l'air dans le capteur solaire
dim Tint as byte                    'température de l'air de la maison
dim Text as byte                    'température de l'air extérieur

'--- mesures dans l'eau
dim Src as byte                        'signe de la température de l'eau en sortie de capteur solaire (le capteur échange-t-il bien ?)
dim Sch as byte                        'signe de la température de l'eau en haut de la cuve
dim Scb as byte                        'signe de la température de l'eau en bas de la cuve (stratification ?)

'--- mesures dans l'air
dim Secs as byte                    'signe de la température de l'eau chaude sanitaire (le serpentin échange-t-il bien ?)
dim Scap as byte                    'signe de la température de l'air dans le capteur solaire
dim Sint as byte                    'signe de la température de l'air de la maison
dim Sext as byte                    'signe de la température de l'air extérieur

'---------------------- Variables 1-Wire ----------------------
Dim CH as byte                         'Channel lecture : num de l'entrée capteur considérée
Dim KL as byte                         'Octet de poids faible DS18B20
Dim KH as byte                         'Octet de poids fort DS18B20
Dim DA as byte                        'variable de commande du DS18B20
Dim BY as byte                        'test busy
Dim Sig as byte                        'signe
Dim Tf as byte                         'valeur décimale
Dim TL as byte                        '4 bits poids faible
Dim TH as byte                        '3 bits poids fort
Dim TT as byte                        'temperature

'---------------------- Variables de fonctionnement ----------------------
dim tempoVAR as integer                    'pour sub TEMPO1S
dim j as integer                    'pour sub TEMPO1S
dim n as byte                        'pour sub affichMODE
dim etatCIRC as byte                    'etat commande circulateur
dim etatCircTemp as byte                'etat commande circulateur temporaire (mode manu)
dim Tseuil1 as byte                    'temperature seuil sub auto (calcul)
dim Tseuil2 as byte                    'temperature seuil sub auto (calcul)
dim Tchi as byte                    'temperature cuve haute initiale
dim autoManu as byte                    'variable d etat du type de gestion 1=auto 0=manu
dim autoManuTemp as byte                'variable temporaire d autoManu
dim bouton as byte                    'variable acquisition des boutons poussoir
dim Tmax as byte                    'variable pour declencher l'arret



'################################# initialisation ########################################

'curseur off
CSROFF

'variables
autoManu = 1                        'gestion mode auto par defaut

'led
out LEDR1,0                        'led pb temperature Tch < Tchmin eteinte
out LEDR2,0                        'led circulateur en vitesse3 eteinte
out LEDJ,0                        'led circulateur en vitesse1 etainte
out LEDV,1                        'debut commande led circulateur au repos

'circulateur non commandé
GOSUB CIRC_STOP



'################################# PROGRAMME PRINCIPAL #################################

'mesure initiale des températures
GOSUB MESURES
       
'affichage du choix du mode de gestion
GOSUB affichMODE

'affichage du fond de l'afficheur (caracteres qui ne changent pas)
GOSUB affichFOND


DEBUT:
        'mesure des températures
        GOSUB MESURES
       
        'affichage des temperatures
        GOSUB affichTEMP

        'mode de fonctionnement
        if autoManu = 1 then GOSUB AUTO

        'affichage de l'etat de l eau dans la cuve (utilisable ou non)
        GOSUB affichETAT
       
        delay tempoBOUCLE           

        'changement mode ?
        bouton = keyin(bpRouge,50)        'test bp rouge (changement)
        if bouton = 0 then
            CLS
            delay 1000
            GOSUB affichMODE
            GOSUB affichFOND
        end if

GOTO DEBUT




'###################################### SUBROUTINES #################################

AUTO:
    '-- commande du circulateur en mode auto
    if Tch >= Tchlimit then
        if etatCIRC = 1 then
            GOSUB CIRC_STOP                'arret du circulateur si temperature trop elevée
        else
            return
        end if
    else
        Tseuil2 = Tch + deltaON                'calcul température declenchement
        'commande d arret du circulateur
        if etatCIRC = 1 then
            Tseuil1 = Tmax - 1            'hysteresis
            if Tch > Tmax then
                Tmax = Tch            'memorisation valeur max
            elseif ((Tch < Tseuil1) AND (Tcap < Tseuil2)) then
                GOSUB CIRC_STOP            'arret ciculateur si temperature cuve en baisse ET temp capt < seuil2
            end if
        'commande de marche du circulateur
        else
            if Tcap >= Tseuil2 then
                GOSUB CIRC_START        'declenchement circulateur si temp capteur sup bas cuve + deltaON
            end if
        end if
    end if
return


'------------------- affichage du fond d'ecran qui ne change pas (varIN : etatCIRC)----
affichFOND:
        CLS
        'ligne 1
        LOCATE 0,0
        if etatCIRC = 1 then
            PRINT "Capt Air/Eau"
        else
            print "Air Capteur"
        end if

        'ligne 2
        LOCATE 0,1
        PRINT "Haut Cuve"

        'ligne 3
        LOCATE 0,2
        PRINT "Bas Cuve"

        'ligne 4
        LOCATE 0,3
        PRINT "int    ext"
return


'------------------- affichage des températures (varIN : Trc, Tch, Tcb, Tecs, Tcap, Text, Tint)----
affichTEMP:

        '--- capteur Temp air capteur
        LOCATE 13,0
        if Tcap < 127 then
            PRINT DEC(Tcap,3,1)
        else
            PRINT "---"
        end if
        'signe
        if Tcap > 9 then
            LOCATE 13,0
        else
            LOCATE 14,0
        end if
        if Scap = 1 then
            PRINT "-"
        else
            print " "
        end if

        '--- capteur eau retour capteur
        if etatCIRC = 1 then
            LOCATE 16,0
            print "/"
            if Trc < 127 then
                PRINT DEC(Trc,2,1)
            else
                PRINT "--"
            end if
        else
            locate 16,0
            print "    "
        end if


        '--- capteur Temp cuve haute
        LOCATE 11,1
        if Tch < 127 then
            PRINT DEC(Tch,3,1)
        else
            PRINT "---"
        end if
       
        '--- capteur Temp cuve haute initiale
        if etatCIRC = 1 then
            LOCATE 16,1
            PRINT "(  )"
            LOCATE 17,1
            PRINT DEC(Tchi,2,1)
        else
            LOCATE 16,1
            PRINT "    "
        end if

        '--- capteur Temp cuve basse
        LOCATE 11,2
        if Tcb < 127 then
            PRINT DEC(Tcb,3,1)
        else
            PRINT "---"
        end if


        '--- capteur Temp interieure
        LOCATE 4,3
        if Tint < 127 then
            PRINT DEC(Tint,2,1)
        else
            PRINT "--"
        end if

        '--- capteur Temp exterieure
        LOCATE 12,3
        if Text < 127 then
            PRINT DEC(Text,2,1)
        else
            PRINT "--"
        end if
        'signe
        if Text > 9 then
            LOCATE 11,3
        else
            LOCATE 12,3
        end if
        if Sext = 1 then
            PRINT "-"
        else
            print " "
        end if

        '---auto/manu
        locate 16,3
        if autoManu = 1 then
            print "AUTO"
        else
            print "MANU"
        end if
return


'----------------------------- mesure des temperatures ------------------------------------
MESURES:   
        CH = CH0
        GOSUB LECTURE
        Trc = TT
        Src = Sig

        CH = CH1
        GOSUB LECTURE
        Tch = TT
        Sch = Sig

        CH = CH2
        GOSUB LECTURE
        Tcb = TT
        Scb = Sig

'        CH = CH3
'        GOSUB LECTURE
'        Tecs = TT
'        Secs = Sig

        CH = CH4
        GOSUB LECTURE
        Tcap = TT
        Scap = Sig

        CH = CH5
        GOSUB LECTURE
        Tint = TT
        Sint = Sig

        CH = CH6
        GOSUB LECTURE
        Text = TT
        Sext = Sig
return

'-------------------------- LECTURE D'UN CAPTEUR (varIN : SCL, SDA, CH, DA  varOUT : TT, Tf) -------------
LECTURE:               
Channel:
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30        'AD,0 adresse I2C (DS2482) ecrire
            Shiftout SCL,SDA,2,&HC3        'CHSL    Pointer sur Channel Selection Register               
            Shiftout SCL,SDA,2,CH        'CHANNEL choisi   
        Gosub  I2C_STOP   
        Gosub  OneWReset
        Gosub  OWWread
CONVER:                            'ROUTINE DE CONVERSION DU RESULTAT
        DA=&HCC : Gosub  OWWrite        'Commande skip ROM  (DS18B20)               
        DA=&H44 : Gosub  OWWrite        'Commande convertion               
        Gosub BUSY                'Routine de test ligne1-wire                   
        Gosub OWWread                                           
        Sig=KH AND &H80                'signe (0 : positif, 1 : négatif)
        Tf=KL AND &H0F                 'Octet L partie decimale = 4bits poids faible (non utilisé)
        TL=KL AND &HF0 : TL=TL/16        'Octet L Decale de 4 >>               
        TH=KH AND &H07 : TH = TH*16        'Octet H 3 bits poids faible
        TT=TL+TH                'TT resultat temperature sur 7 bits
        if Sig = 1 then    TT=&H80-TT        'temperature negative
return

                                                                   
'-----------------------'ROUTINE ECRITURE DS2482-800 1-WIRE (varIN : SCL, SDA, DA) ---------------------
OWWrite:
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30         'AD,0 adresse I2C (DS2482)ecrire           
            Shiftout SCL,SDA,2,&HA5        'command 1WWB 1Wire write byte
            Shiftout SCL,SDA,2,DA        'Envoie variable
        Gosub  I2C_STOP
return

'----------------------- ROUTINE LECTURE DS2482-800 1-WIRE (varIN : SCL, SDA, DA, varOUT : KL, KH) ------------
OWWread:
        DA=&HCC : Gosub  OWWrite        'Commande skip ROM > DS18B20
        DA=&HBE : Gosub  OWWrite        'Commande Lecture > DS18B20                   
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30        'AD,0 Adresse Ecriture DS2482               
            Shiftout SCL,SDA,2,&H96        '1WRB Lecture byte > 1-wire               
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30        'AD,0 Adresse Ecriture DS2482
            Shiftout SCL,SDA,2,&HE1        'SRP    Set Read Pointer    (E1)               
            Shiftout SCL,SDA,2,&HE1        'E1h    Pointer sur Read Data Regiser           
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H31        'AD,1 adresse lecture (DS2482)               
            KL=Shiftin (SCL,SDA,1)        'Byte > KL                       
        Gosub  I2C_START               
            Shiftout SCL,SDA,2,&H30        'AD,0 Adresse Ecriture DS2482               
            Shiftout SCL,SDA,2,&H96        '1WRB Lecture byte > 1-wire               
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30        'AD,0
            Shiftout SCL,SDA,2,&HE1        'SRP    Set Read Pointer                   
            Shiftout SCL,SDA,2,&HE1        'E1h    Pointer sur Read Data Regiser           
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H31        'AD,1 adresse lecture(DS2482)               
            KH=Shiftin (SCL,SDA,1)        'Byte > KH                       
        Gosub  I2C_STOP
        Gosub BUSY                '*** INDISPENSABLE ***   
return
                   
'-------------------- RESET DS2482-800 1-WIRE ------------------
OneWReset:
        Gosub  I2C_START                                           
            Shiftout SCL,SDA,2,&H30         'AD,0 adresse I2C (DS2482)ecrire               
            Shiftout SCL,SDA,2,&HB4        '1WRS  RESET Device Reset F0h
        Gosub  I2C_STOP
return

'------------------------ TEST LIGNE 1-WIRE (varIN : SCL, SDA) ----
BUSY:           
        Gosub  I2C_START   
            Shiftout SCL,SDA,2,&H30
            Shiftout SCL,SDA,2,&HB4        '0= LSB d'abord                   
            delay 10
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H31        'Adresse (DS2482) Lecture               
RE:           
        BY = Shiftin (SCL,SDA,1)        'Test 2482
        BY = BY AND &b00000001               
        IF BY = 1 THEN                 'Test ligne <> 0
            CLS
            Locate 0,0
            Print "WAIT BY=",HEX(BY,2,1)
            GOTO RE
        END IF                   
        gosub I2C_STOP
return


'------------------------ START I2C (varIN : SCL, SDA) ----
I2C_START:   
        Out SCL,1
        Out SDA,1
        Out SDA,0
return

'------------------------ STOP I2C (varIN : SCL, SDA) ----
I2C_STOP:
        Out SDA,0
        Out SCL,1
        Out SDA,1
return


'------------------- START CIRCULATEUR (varIN : V1, V3, tempoV3, tempoVAR) ----
CIRC_START:
        etatCIRC = 1                'flag etat circulateur
        Tchi = Tch                'memorisation temp initiale
        Tmax = Tch                'memorisation pour la temp max
        out SV1,0                'arret commande vitesse 1
        delay 100                'attente pour eviter double commande
        out SV3,1                'commande vitesse 3
        out LEDV,0                'arret commande témoin circulateur au repos
        out LEDJ,1                'debut commande témoin vitesse 3
        tempoVAR = tempoV3            'temporisation
        GOSUB TEMPO1S
        out SV3,0                'arret vitesse 3
        out LEDJ,0                'arret commande témoin vitesse 3
        delay 100                'attente pour eviter double commande
        out SV1,1                'commande vitesse 1
        out LEDR2,1                'debut commande témoin vitesse 1   
return


'------------------- STOP CIRCULATEUR (varIN : V1, V3) ----
CIRC_STOP:
        etatCIRC = 0                'flag etat circulateur
        LOCATE 0,1
        PRINT "           "            'arret affichage retour eau capteur
        out LEDJ,0                'arret commande témoin vitesse 3
        out LEDR2,0                'arret commande témoin vitesse 1
        out LEDV,1                'debut commande témoin circulateur au repos
        out SV1,0                'arret vitesse 1
        out SV3,0                'arret vitesse 3
return


'------------------- temporisation (varIN : tempoVAR)----
TEMPO1S:
        for j = 1 to tempoVAR
            delay 1000
        next j
return



'------------------- affichage/extinction du temoin de fonctionnement du circulateur (varIN : Tch, Tchmin)----
affichETAT:
       
        '---clignotement LEDR1 si temp haut cuve insuffisante
        if Tch < Tchmin then
            out LEDR1,1
            delay 30
            out LEDR1,0
            delay 120
            out LEDR1,1
            delay 30
            out LEDR1,0
        else
            out LEDR1,0
        end if
       
        '---clignotement LEDs si mode manu
        if autoManu = 0 then
            if etatCIRC = 1 then
                    out LEDJ,1
                    out LEDV,1
                    delay 30
                    out LEDJ,0
                    out LEDV,0
                    delay 120
                    out LEDJ,1
                    out LEDV,1
                    delay 30
                    out LEDJ,0
                    out LEDV,0
            else
                    out LEDJ,1
                    out LEDR2,1
                    delay 30
                    out LEDJ,0
                    out LEDR2,0
                    delay 120
                    out LEDJ,1
                    out LEDR2,1
                    delay 30
                    out LEDJ,0
                    out LEDR2,0
            end if
        else
            if etatCIRC = 1 then
                    out LEDR2,1
                    out LEDJ,0
                    out LEDV,0
            else
                    out LEDR2,0
                    out LEDJ,0
                    out LEDV,1
            end if
        end if
return



'------------------- affichage et choix du mode de gestion
affichMODE:

    '---------------------
    '--- choix du mode ---
    '---------------------
    'affichage fond
    CLS
    locate 0,0
    print "Gestion Solaire v"
    locate 17,0
    print dec(version,2,0)
    locate 0,2
    print "Mode automatique"
    locate 0,3
    print "Mode manuel"

    'affichage de la situation actuelle
    if autoManu = 1 then
        locate 19,2
    else
        locate 19,3
    end if
    print "*"
   
    'test des bp : bleu changement, rouge validation
    autoManuTemp = autoManu                    'prise en compte de l etat precedent
    for n = 1 to Nmax
        bouton = keyin(bpBleu,50)            'test bp bleu (changement)
        if bouton = 0 then
            if autoManuTemp = 1 then        'ancien = auto
                autoManuTemp = 0        'nouveau = manuel
                locate 19,2
                print " "
                locate 19,3
                print "*"
            else
                autoManuTemp = 1        'ancien = manuel, nouveau = auto
                locate 19,2
                print "*"
                locate 19,3
                print " "
            end if
        end if
        bouton = keyin(bpRouge,50)            'test bp rouge (validation)
        if bouton = 0 then
            n = Nmax                'fin de la boucle
        end if
    next n
   
   
    '---------------------------------
    '--- menu des differents modes ---
    '---------------------------------

    '--- affichage menu mode manuel --
    if autoManuTemp = 0 then
        CLS                           
        locate 0,0
        print "Mode Manuel"
        locate 0,1
        print "Circulateur :"
        if etatCIRC = 1 then
            locate 18,1
            print "ON"
            locate 0,2
            print "-> Arreter (rouge)"
            locate 0,3
            print "-> Retour (bleu)"
        else
            locate 17,1
            print "OFF"
            locate 0,2
            print "-> Demarrer (rouge)"
            locate 0,3
            print "-> Retour (bleu)"
        end if
           
           
        'test des boutons
        etatCircTemp = 2                'init de la valeur (differente de 0 ou 1)
        for n = 1 to Nmax
            bouton = keyin(bpBleu,50)        'test bp bleu (cancel)
            if bouton = 0 then
                n = Nmax
            end if

            bouton = keyin(bpRouge,50)        'test bp rouge (changement)
            if bouton = 0 then
                if etatCIRC = 1 then
                    etatCircTemp = 0    'memo etat
                else
                    etatCircTemp = 1    'memo etat
                end if
            n = Nmax
            end if
        next n

        'affichage prise en compte bouton
        locate 17,0
        print "---"
        delay 1000
   
        'confirmation
        CLS   
        locate 0,0
        print "Mode Manuel"
        locate 0,2
        if etatCircTemp = 0 then
            print "Arret en cours.."
        elseif etatCircTemp = 1 then
            print "Demarrage en cours.."
        elseif etatCircTemp = 2 then
            print "Aucun changement"
        end if
        delay 2000

        'commande
        if etatCircTemp = 0 then
            GOSUB CIRC_STOP
        elseif etatCircTemp = 1 then
            GOSUB CIRC_START
        end if

           
    else
        'mode automatique
        'confirmation
        CLS   
        locate 0,0
        print "Mode Automatique"
        locate 0,2
        if autoManu = 1 then                'precedent auto : pas de changement
            print "Enregistre"
        else                        'precedent manu
            print "Changement OK"
        end if
        delay 2000
   
    end if

    'enregistrement valeur
    autoManu = autoManuTemp
return

Programme de test

Faire fonctionner un composant basé sur le protocole 1-Wire sur un picBasic 3B n'était pas vraiment évident... la littérature et les publications à ce sujet ne courent pas le web..
Un grand merci à Jacobée JP pour son aide précieuse concernant l'aide qu'il m'a fourni...
Grâce à ces bases, le picBasic dialogue en mode I2C avec un DS2482-800 qui pilote les composant 1-Wire.
J'ai essayé de refaire un programme de base  le plus simple possible et de le commenter afin que d'autres puissent s'en servir si nécessaire.
NB : attention aux retours à la ligne de lignes longues

Dans un autre article, je décrirait mon programme de gestion qui est bien plus compliqué.... ;-)





'--------------------------------------------------------------------------------------
' ---MESURE DE TEMPERATURE SUR PIC BASIC 3B / BUS 1-WIRE ---------
' ----COPYLEFT CHRISTIAN TRILLAUD trillaud@gmail.com -------------------
'-------------------------------------------------------------------------------------


'################################ constantes ########################################

'----------------------- PIC --------------
CONST DEVICE = 3B                    'pic utilisé

'----------------------- I2C --------------
Const SCL = 11                        'port I2C
Const SDA = 12                        'port I2C

'----------- DS2482 adresses de canaux d'acquisition --------------
Const CH0 = &HF0                    'chanel P0 - pin 14
Const CH1 = &HE1                    'chanel P1 - pin 15
Const CH2 = &HD2                    'chanel P2 - pin 16
Const CH3 = &HC3                    'chanel P3 - pin 1
Const CH4 = &HB4                    'chanel P4 - pin 12
Const CH5 = &HA5                    'chanel P5 - pin 11
Const CH6 = &H96                    'chanel P6 - pin 10
Const CH7 = &H87                    'chanel P7 - pin 9


'################################ variables ########################################

'--- mesures de temperature
dim T1 as byte
dim T2 as byte
dim T3 as byte
dim T4 as byte
dim T5 as byte
dim T6 as byte
dim T7 as byte
dim T8 as byte

'--- signe des mesures de températures
dim S1 as byte
dim S2 as byte
dim S3 as byte
dim S4 as byte
dim S5 as byte
dim S6 as byte
dim S7 as byte
dim S8 as byte

'--- Variables 1-Wire
Dim CH as byte                         'Channel lecture : num de l'entrée capteur considérée
Dim KL as byte                         'Octet de poids faible DS18B20
Dim KH as byte                         'Octet de poids fort DS18B20
Dim DA as byte                        'variable de commande du DS18B20
Dim BY as byte                        'test busy
Dim Sig as byte                        'signe
Dim Tf as byte                         'valeur décimale
Dim TL as byte                        '4 bits poids faible
Dim TH as byte                        '3 bits poids fort
Dim TT as byte                        'temperature






'############ PROGRAMME PRINCIPAL ################
'suppression du curseur de l'affichage
CRSOFF

'boucle principale
DEBUT:

        'mesure des températures
        GOSUB MESURES

        'affichage des temperatures
        GOSUB affichTEMP

GOTO DEBUT




'############# SUBROUTINE ###################

'----------------------------- mesure des temperatures ------------------------------------
MESURES:   
        CH = CH0
        GOSUB LECTURE
        T1 = TT
        S1 = Sig

        CH = CH1
        GOSUB LECTURE
        T2 = TT
        S2 = Sig

        CH = CH2
        GOSUB LECTURE
        T3 = TT
        S3 = Sig

        CH = CH3
        GOSUB LECTURE
        T4 = TT
        S4 = Sig

        CH = CH4
        GOSUB LECTURE
        T5 = TT
        S5 = Sig

        CH = CH5
        GOSUB LECTURE
        T6 = TT
        S6 = Sig

        CH = CH6
        GOSUB LECTURE
        T7 = TT
        S7 = Sig

        CH = CH7
        GOSUB LECTURE
        T8 = TT
        S8 = Sig
RETURN

'-------------------------- LECTURE D'UN CAPTEUR  -------------
LECTURE:               
Channel:
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30        'AD,0 adresse I2C (DS2482) ecrire
            Shiftout SCL,SDA,2,&HC3        'CHSL    Pointer sur Channel Selection Register               
            Shiftout SCL,SDA,2,CH        'CHANNEL choisi   
        Gosub  I2C_STOP   
        Gosub  OneWReset
        Gosub  OWWread
CONVER:                            'ROUTINE DE CONVERSION DU RESULTAT
        DA=&HCC : Gosub  OWWrite        'Commande skip ROM  (DS18B20)               
        DA=&H44 : Gosub  OWWrite        'Commande convertion               
        Gosub BUSY                'Routine de test ligne1-wire                   
        Gosub OWWread                                           
        Sig=KH AND &H80                'signe (0 : positif, 1 : négatif)
        Tf=KL AND &H0F                 'Octet L partie decimale = 4bits poids faible (non utilisé)
        TL=KL AND &HF0 : TL=TL/16        'Octet L Decale de 4 >>               
        TH=KH AND &H07 : TH = TH*16        'Octet H 3 bits poids faible
        TT=TL+TH                'TT resultat temperature sur 7 bits
        if Sig = 1 then    TT=&H80-TT        'temperature negative

RETURN

                                                                   
'-----------------------'ROUTINE ECRITURE DS2482-800 1-WIRE (varIN : SCL, SDA, DA) ---------------------
OWWrite:
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30         'AD,0 adresse I2C (DS2482)ecrire           
            Shiftout SCL,SDA,2,&HA5        'command 1WWB 1Wire write byte
            Shiftout SCL,SDA,2,DA        'Envoie variable
        Gosub  I2C_STOP
RETURN

'----------------------- ROUTINE LECTURE DS2482-800 1-WIRE (varIN : SCL, SDA, DA, varOUT : KL, KH) ------------
OWWread:
        DA=&HCC : Gosub  OWWrite        'Commande skip ROM > DS18B20
        DA=&HBE : Gosub  OWWrite        'Commande Lecture > DS18B20                   
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30        'AD,0 Adresse Ecriture DS2482               
            Shiftout SCL,SDA,2,&H96        '1WRB Lecture byte > 1-wire               
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30        'AD,0 Adresse Ecriture DS2482
            Shiftout SCL,SDA,2,&HE1        'SRP    Set Read Pointer    (E1)               
            Shiftout SCL,SDA,2,&HE1        'E1h    Pointer sur Read Data Regiser           
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H31        'AD,1 adresse lecture (DS2482)               
            KL=Shiftin (SCL,SDA,1)        'Byte > KL                       
        Gosub  I2C_START               
            Shiftout SCL,SDA,2,&H30        'AD,0 Adresse Ecriture DS2482               
            Shiftout SCL,SDA,2,&H96        '1WRB Lecture byte > 1-wire               
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H30        'AD,0
            Shiftout SCL,SDA,2,&HE1        'SRP    Set Read Pointer                   
            Shiftout SCL,SDA,2,&HE1        'E1h    Pointer sur Read Data Regiser           
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H31        'AD,1 adresse lecture(DS2482)               
            KH=Shiftin (SCL,SDA,1)        'Byte > KH                       
        Gosub  I2C_STOP
        Gosub BUSY                '*** INDISPENSABLE ***   
Return
                   
'-------------------- RESET DS2482-800 1-WIRE ------------------
OneWReset:
        Gosub  I2C_START                                           
            Shiftout SCL,SDA,2,&H30         'AD,0 adresse I2C (DS2482)ecrire               
            Shiftout SCL,SDA,2,&HB4        '1WRS  RESET Device Reset F0h
        Gosub  I2C_STOP
RETURN

'------------------------ TEST LIGNE 1-WIRE (varIN : SCL, SDA) ----
BUSY:           
        Gosub  I2C_START   
            Shiftout SCL,SDA,2,&H30
            Shiftout SCL,SDA,2,&HB4        '0= LSB d'abord                   
            delay 10
        Gosub  I2C_START
            Shiftout SCL,SDA,2,&H31        'Adresse (DS2482) Lecture               
RE:            BY = Shiftin (SCL,SDA,1)    'Test 2482
            BY = BY AND &b00000001               
            IF BY = 1 THEN             'Test ligne <> 0
                CLS:Locate 0,0 : Print "WAIT BY=",HEX(BY,2,1): GOTO RE
            END IF                   
        gosub I2C_STOP
RETURN


'------------------------ START I2C (varIN : SCL, SDA) ----
I2C_START:   
        Out SCL,1
        Out SDA,1
        Out SDA,0
RETURN

'------------------------ STOP I2C (varIN : SCL, SDA) ----
I2C_STOP:
        Out SDA,0
        Out SCL,1
        Out SDA,1
RETURN



'------------------- affichage des températures (afficheur 4 x 20) ----
affichTEMP:

    LOCATE 0,0
    print "T1 "
    'signe
    if S1 = 1
        then PRINT "-"
    else
        print " "
    end if
    print dec(T1,3,1)

    LOCATE 10,0
    print "T5 "
    'signe
    if S5 = 1
        then PRINT "-"
    else
        print " "
    end if
    print dec(T5,3,1)

    LOCATE 0,1
    print "T2 "
    'signe
    if S2 = 1
        then PRINT "-"
    else
        print " "
    end if
    print dec(T2,3,1)

    LOCATE 10,1
    print "T6 "
    'signe
    if S6 = 1
        then PRINT "-"
    else
        print " "
    end if
    print dec(T6,3,1)

    LOCATE 0,2
    'signe
    if S3 = 1
        then PRINT "-"
    else
        print " "
    end if
    print dec(T3,3,1)

    LOCATE 10,2
    print "T7 "
    'signe
    if S7 = 1
        then PRINT "-"
    else
        print " "
    end if
    print dec(T7,3,1)

    LOCATE 0,3
    print "T4 "
    'signe
    if S4 = 1
        then PRINT "-"
    else
        print " "
    end if
    print dec(T4,3,1)

    LOCATE 10,3
    print "T8 "
    'signe
    if S8 = 1
        then PRINT "-"
    else
        print " "
    end if
    print dec(T8,3,1)


RETURN

Réalisation de la carte..

Basée sur le schéma de cablage précemment donné, voici la carte de commande du circulateur...



On aperçoit l'afficheur 4 x 20 caractères (à noter que la photo des données a été prise le 24/05/2010 à 23h43 ce qui explique que la température de l'air du capteur soit de 17°...
Je pense que les tuiles de mon toit doivent encore rayonner car la température extérieure (qui est prise à ce niveau) est supérieure à celle à l'intérieur du capteur... mais que cette tendance est inversée au petit matin...
En bas de la carte figure le picBasic 3B, 4 LED permettent d'informer l'utilisateur de l'état du circulateur et 2 boutons-poussoir permettent de commander le mode manuel ou automatique...

Il ne reste plus qu'à intégrer tout ça dans un boîtier plus convivial....

Nouveau diagramme de fonctionnement

Suite à divers essais, il apparait plus probant de définir la commande d'arrêt lorsque la température de l'eau dans la cuve commence à baisser, ceci pour éviter des commandes successives de mise en route et d'arrêt du circulateur...
En effet, un nuage qui ombrage le capteur produit une chute de la température interne de l'air dans le capteur relativement rapide et importante si bien que le système de gestion initial coupait la commande du circulateur...
Le fait de se baser sur la mesure de la température dans la cuve (et la détection d'une décroissance de cette dernière) assure une plus grande stabilité au système..
On introduit une nouvelle variable (Tchmax) qui est la valeur maxi atteinte par la cuve au cours du cycle. On compare la valeur instantanée à cette variable et on commande l'arrêt SI Tch < Tchmax ET SI la température de l'air dans le capteur n'est pas supérieure à Tseuil (sinon le système redéclencherait immédiatement la commande du circulateur).

jeudi 6 mai 2010

Schéma de cablage

Je suis parti sur la base d'un PicBasic 3B, de capteurs de température Dallas 18B20.
Le Pic gère le protocole I2C mais les capteurs dialoguent à travers le protocole 1-Wire.
Heureusement, il existe un circuit adaptateur référencé DS 2482-800 qui jouera le rôle d'interface entre les capteurs de température et le Pic.
Le circulateur nécessite de démarrer en vitesse 3 mais requiert la vitesse 1 pour récupérer un maximum de calories. Il est donc impératif de prévoir deux relais et les éléments pour la commande (REL2 et REL3 sur le schéma ci-dessous).
On rajoute divers voyants permettant de constater de l'état du circulateur (repos, vitesse 3, vitesse 1).
Deux interrupteurs permettront ultérieurement des commandes de réglage.
Pour finir, un afficheur LCD 4 lignes par 20 caractères permettra d'informer des valeurs des températures dans le capteur, en haut et en bas du ballon, ainsi que le retour d'eau du capteur.

Une surprise lors de la réception du circuit DS2482-800, je n'avais pas suffisamment lu la notice, notamment le passage où il est indiqué qu'il se présente en boitier de type CMS !!!
En attendant de recevoir un adaptateur DIL - CMS, il aura fallu souder (micro-souder !!) 16 fils sur le composant lui-même pour le relier à son environnement... pfff....
Mais ça marche.... !!!



Diagramme de fonctionnement

La commande du circulateur (ON ou OFF) est subordonnée à une différence de température entre celle mesurée dans le ballon et celle de l'air dans le capteur.


Les différences sont notées deltaON et deltaOFF. Elles sont positionnées par défaut respectivement à 10 et 2°C.
Lors des essais sans régulateur, je constatais par moment, lors du déclenchement du circulateur le matin, que la température du ballon avait tendance à décroître de quelques dixièmes de degrés.

Pour éviter de chauffer l'atmosphère avec les calories du ballon, il est nécessaire d'ajuster ce delta d'une manière optimale.. Seuls les essais permettront d'ajuster précisément ces valeurs...

mercredi 14 avril 2010

Mise en place des capteurs de température...

Pour la régulation, il est nécessaire de placer des capteurs aux endroits stratégiques de l'installation...
Je pars sur la base de capteurs Dallas 18B20

Il est prévu de mesurer les valeurs suivantes :
  • Tcapt : température de l'air dans le capteur solaire
  • Tint : température de l'air de la maison
  • Text : température de l'air extérieur
  • Tch : température de l'eau en haut de la cuve
  • Tcb : température de l'eau en bas de la cuve (stratification ?)
  • Tecs : température de l'eau chaude sanitaire (le serpentin échange-t-il bien ?)
  • Trc : température de l'eau en sortie de capteur solaire (le capteur échange-t-il bien ?)

 Les températures mesurées dans l'eau se feront à travers un "doigt de gant" qui présente l'énorme avantage 'avoir accès au médium sans se mouiller ;-) autrement dit, on peut mesurer la température de l'eau sans être obligé d'être en contact direct avec elle. L'inconvénient majeur étant un retard sur l'information  : il faut le temps que le cuivre se mette à la température de l'eau, puis qu'il transmette cette température à l'air intérieur et enfin que ce dernier chauffe ou refroidisse le capteur..d'où la nécessité d'avoir un ajustement assez précis entre le capteur et le "doigt" pour améliorer le transfert.

Le principe retenu est de placer dans le flux d'eau un tuyau de cuivre de faible diamètre (6-8 mm) qui ne vienne pas perturber l'écoulement de ce dernier et de rendre étanche cette liaison. Pour cela, j'ai augmenté le diamètre du tube en soudant des éléments successifs.

Fabrication des doigts de gant pour Tecs et Trc :

Empilage de tuyau de cuivre de différents diamètres jusqu'au dernier (6-8 mm) ouvert sur l'extérieur, pincé-soudé à l'intérieur.

Pincé-soudé sur l'intérieur

Sur le Té en laiton qui s'insérera dans le retour du capteur solaire


Le capteur rentrera dans cet orifice, sera en contact "indirect" avec l'eau

La même chose réalisée pour la température de l'eau chaude sanitaire (Tecs) sur un Té en cuivre de 14 mm.