Fonction "COUNT"

Yex2

Well-known member
Bonjour à tous,

J'essaye de comprendre comment utiliser la fonction "COUNT". Je ne comprends pas très bien comment adapter et/ou utiliser la "période".

COUNT pin, period, wordvariable

Je tente de fabriquer un compteur d'eau. J'ai acheté ce débitmètre au début de l'été et il s'avère loin d'être linéaire. Alors il doit être calibrer pour un débit quelconque. Comme ma pompe à un débit fixe, une fois calibré j'espère que le compteur sera précis.

J'ai écrit un premier programme qui semblait fonctionner. Mais hélas...

Dans un premier temps, j'utilisais un litre d'eau et je comptais les impulsions avec cette commande.

Code:
Count valid, 2000, w13    ; comptage des impulsions pendant 2 s
today =w13 + today      ; Additionne les impulsions dans today
J'obtenais environ 255 impulsions pour un litre d'eau. Je répétais 4 fois et je faisais la moyenne. Les essais variaient de 252 à 259. Ensuite je stockais cette valeur dans une variable appelé "etalon". Avec la valeur "etalon", je pouvais alors compter l'eau qui passait dans le débitmètre. La précision était très bonne, du moins entièrement satisfaisante pour mon projet.

Dans un deuxième temps, j'ai voulu faire une sous routine de calibrage mais curieusement, les résultats diffères et pourtant j'utilise le même code. Lorsque j'active le circuit, je vérifie pour voir si la variable "etalon" = 0. Si oui je saute dans la sous-routine calib qui demande d'ajouter 1 litre d'eau.

Code:
 Count valid, 2000, w13 ; Compte les impulsions et stock ds w13
 etalon =w13 + etalon   ; Additionne les impulsions et stock dans etalon
Mais voilà le problème. L'ajout d'un litre d'eau ne donne pas ± 255 impulsion mais plutôt autour de 115 qui est stoké dans la mémoire EEPROM. Lorsque le programme redémarre, le litre d'eau est compté comme plus de 2 litres.

Je ne comprends pas pourquoi une aussi grande différence mais je suspect que ça à voir avec la définition de la période de COUNT.

Indice : w13 semble toujours être entre 12 et 13. "today" et "etalon" devrait justement avoir la même sommes mais c'est pas le cas... ?:unsure:

Bon ceci dit, si quelqu'un pouvais m'expliquer comment utiliser COUNT et sa période, je serai très reconnaissant...

Merci,

Yex
 

MGU

Senior Member
Bonjour,

En fait, il faut se référer à une doc digne de ce nom.
Qui donné la formule: débit en l/mn= fréquence / 7,5

MM
 

PieM

Senior Member
Bonjour,
La fonction count, compte bien le nombre de transitions 0 -> 1 pendant le temps appelé period.
Mais il est illusoire de vouloir étalonner de cette façon, ce type de compteur n'est pas rigoureusement volumétrique. Il faut le mettre dans les conditions de la mesure, donc relié à la pompe, et remplir un volume donné en chronométrant la temps.
Il faut qu'il soit dans les conditions de débit et de pression de fonctionnement futur.
"Comme ma pompe à un débit fixe " . C'est une pompe volumétrique ?
"w13 semble toujours être entre 12 et 13. " Vous avez un pb dans le programme de toute façon. Donnez le en entier.
 
Last edited:

MGU

Senior Member
Bonjour,

En fait, il faut se référer à une doc digne de ce nom.
Qui donné la formule: débit en l/mn= fréquence / 7,5

MM
Bonjour,

Et tous comptes faits, il y a 450 impulsions par litre

MM
 

PieM

Senior Member
Bonjour,
Et tous comptes faits, il y a 450 impulsions par litre
Bonjour,
Oui, si c'est bien le même capteur! car il semble différent...
Mais il y a beaucoup d'incohérences dans tout ça...
la valeur de w13 est de 255 puis 115 puis entre 12 et 13 !?
Déjà, passer 1litre en moins de 2s c'est le maxi de ce compteur.
Puisque c'est un compteur et non un débitmètre, l'étalonnage consiste à connaitre le nombre d'impulsions générées par litre. il est inutile d'utiliser la fonction count qui donne un résultat homogène à un débit. Donc -> #3
En principe avec un capteur Hall , il faut une R de tirage à Vcc sur l'entrée signal. Est-ce le cas ?
 

MGU

Senior Member
Bonjour,

Ce capteur YF-S201 est aussi vendu par Gotronic qui donne la même formule.

Il y a quelques années, j'avais répondu a une question à ce sujet. Si ça peut servir:


MM
 
Last edited:

Yex2

Well-known member
Bonjour,

En fait, il faut se référer à une doc digne de ce nom.
Qui donné la formule: débit en l/mn= fréquence / 7,5

MM
Salut Michel,

J'ai la doc du débitmètre que je me suis procuré sur eBAY.

On voit que le nombre d'impulsion n'est pas linéaire. Il augmente avec le débit. De plus la marge d'erreur annoncé est de 10%. Pour ma part, j'ai noté presque 15%.

Mais je peux vivre avec ça. Le but de mon circuit n'est pas de connaître la consommation exacte mais plus de conscientiser mes invités à réduire leur consommation d'eau.

Yex.


.
 

Yex2

Well-known member
Bonjour,
La fonction count, compte bien le nombre de transitions 0 -> 1 pendant le temps appelé period.
Mais il est illusoire de vouloir étalonner de cette façon, ce type de compteur n'est pas rigoureusement volumétrique. Il faut le mettre dans les conditions de la mesure, donc relié à la pompe, et remplir un volume donné en chronométrant la temps.
Au contraire c'est à mon avis la seule façon de faire. Il faut comprendre que j'ai 5 circuits à faire. Le premier est pour le chalet. Il s'agit là de comparer nos consommations d'eau pour nos douches personnelles. Je pensais ajouter des petites alarmes lorsqu'un nouveau record minimum ou maximum était enregistré.

Les 4 autres sont pour mon bateau. Il y a 4 toilettes. Le circuit comptabilisera la consommation quotidienne de chaque couple (cabine) et la sommes total pour le séjour. Le couple qui sera le plus économique se verra offrir une bouteille de Champagne à la fin du voyage ;). Ça coûte moins cher qu'un remplissage d'eau dans les Antilles...

Étant donnée qu'il n'y a qu'une seule pompe sur le bateau et 4 cabines. Les cabines avant sont proches de la pompe alors que les cabines arrières sont loin, il sera donc nécessaire de calibrer individuellement chaque circuit en fonction de la pression et débit qu'elles ont respectivement. De là l'obligation de faire un étalonnage individuel pour chaque cabine.


Il faut qu'il soit dans les conditions de débit et de pression de fonctionnement futur.
"Comme ma pompe à un débit fixe " . C'est une pompe volumétrique ?
"w13 semble toujours être entre 12 et 13. " Vous avez un pb dans le programme de toute façon. Donnez le en entier.
La pompe a un débit fixe mais si deux personnes prennent une douche en même temps, la pression et/ou le débit va diminuer. La fréquence des impulsions du débitmètre n'est pas linéaire mais suffisamment pour que la précision ne soit pas trop affecté.

Encore une fois, l'objectif 'est pas de connaître la consommation exacte mais plutôt de conscientiser les invités de leur consommation personnelle dans un contaxte de groupe. Il faut comprendre que les Québécois sont d'énorme gaspilleurs d'eau et d'électricité parce que ces deux ressources sont en abondance ici et coûte presque rien. Les taxes d'eau au QC varient entre 50 et 70 Euro/année et l'électricité se vend à ± 5 centime le kWhr.

J'ai déjà eu un couple qui m'a vider mes 1000 litres d'eau en deux jours. Et la femme (la responsable du gaspillage) prétendait que mes réservoirs étaient vides ou percés. o_O Elle était dans le dénie total !

Ceci dit, en fin de semaine j'ai trouvé une solution à mon problème initial. Au lieu d'aller d'utiliser une deuxième fonction COUNT pour étalonner le circuit, je vais utiliser la même. Donc peu importe l'erreur que j'aurais pu faire dans la sous-routine, elle sera ainsi éliminer. Puisque la fonction COUNT utilisé pour étalonnage sera la même que pour compter la consommation, j'imagine que les deux donnera le même résultat au finale.

Je vais modifier le code aujourd’hui et faire des essais. Je vous tiens au courant. Merci de vos input.

Yex
 

Yex2

Well-known member
Bonjour,
Oui, si c'est bien le même capteur! car il semble différent...
Mais il y a beaucoup d'incohérences dans tout ça...
la valeur de w13 est de 255 puis 115 puis entre 12 et 13 !?
La solution m'est venu ce week-end. Je vais utiliser la même fonction COUNT pour la lecture normale et/ou l’étalonnage. Ainsi je vais éliminer l'erreur que j'ai sans doute commis.


Déjà, passer 1litre en moins de 2s c'est le maxi de ce compteur.
Puisque c'est un compteur et non un débitmètre, l'étalonnage consiste à connaitre le nombre d'impulsions générées par litre. il est inutile d'utiliser la fonction count qui donne un résultat homogène à un débit. Donc -> #3
1 litre en 2 sec ???? Non c'est pas aussi vite. C'est entre 15 et 30 secondes. Les pompes que j'ai varient de 4 à 8 litres/min. Je ne me souviens pas du volume exact mais c'est pas 1L/2sec, ce qui serait 30 l / min.


En principe avec un capteur Hall , il faut une R de tirage à Vcc sur l'entrée signal. Est-ce le cas ?
La doc ne précise pas l'utilisation d'un R sur le VCC. À quoi servirait-elle cette résistance ?
 

PieM

Senior Member
Heu ... le comptage se faisant sur 2s, je ne vois pas comment vous pouviez avoir 255 impulsions pour 1 litre. Mais c'est pas grave.
Count valid, 2000, w13 ; comptage des impulsions pendant 2 s
today =w13 + today ; Additionne les impulsions dans today
"J'obtenais environ 255 impulsions pour un litre d'eau."
La doc ne précise pas l'utilisation d'un R sur le VCC. À quoi servirait-elle cette résistance ?
En principe, la sortie d'un capteur Hall est un collecteur ouvert.
 
Last edited:

Yex2

Well-known member
Heu ... le comptage se faisant sur 2s, je ne vois pas comment vous pouviez avoir 255 impulsions pour 1 litre. Mais c'est pas grave.


"J'obtenais environ 255 impulsions pour un litre d'eau."

En principe, la sortie d'un capteur Hall est un collecteur ouvert.
Bon voilà on reviens justement à ma question d'origine, comment la fonctionne COUNT ?

L'horloge est règlé à 16 Mhz. J'imagine que ça affecte la "période".

Comment ajuster cette "période" ?

PS: en changeant le code, j'arrive maintenant à ± 338 impulsion/ litre. L'étalonnage fonctionne maintenant correctement. Reste à comprendre ce qui affecte le nombre d'impulsion. J'imagine que c'Est une relation entre la vitesse de l'horloge et celle de la période. Mais je ne comprends toujous pas comment ça fonctionne.
 

MGU

Senior Member
Bonjour,

Tu peux continuer à essayer d'utiliser "count" (je connais ton obstination).
Mais, à mon avis, ce n'est pas la bonne solution. La formule donnée avec le capteur donne un nombre d'impulsions de 450/l avec une marge de 10%.

Donc, commence par compter simplement les impulsions (il faut une résistance de tirage, disons 4,7 k, à la limite, activer la pullup interne), cela donnera un volume d'eau. Jette un oeil sur le programme donné #6, l'interruption en particulier.
Regarde aussi la vidéo, c'est un décompteur, mais c'est pareil.

Mais pour ton problème, je vois plutôt de simples compteurs divisionnaires aux indications incontestables:
https://www.manomano.fr/compteur-deau-et-accessoire-1606?model_id=2124545&g=1&referer_id=685759&ach=baa0e&achsqrt=2d3a4&gclid=EAIaIQobChMIpZbsk97a4wIVCflRCh2gwgFfEAQYASABEgJWGfD_BwE

Un truc encore: "Les 4 autres sont pour mon bateau. Il y a 4 toilettes. "....
Les toilettes sont sur l'eau potable???

MM
 
Last edited:

PieM

Senior Member
Pour compléter ce que dit Michel, l'utilisation de count conduit à faire un fréquencemètre donc un débitmètre et non un compteur !
Quant aux 16MHz, en fait le comptage se fait pendant 0.5s, avec un résultat qui est totalement erroné.
en changeant le code, j'arrive maintenant à ± 338 impulsion/ litre. L'étalonnage fonctionne maintenant correctement.
Avec un appareil qui délivre entre 450 et 480 pulses/litre ? Si ça vous convient pourquoi pas ...
 

Yex2

Well-known member
Pour compléter ce que dit Michel, l'utilisation de count conduit à faire un fréquencemètre donc un débitmètre et non un compteur !
Quant aux 16MHz, en fait le comptage se fait pendant 0.5s, avec un résultat qui est totalement erroné.

Avec un appareil qui délivre entre 450 et 480 pulses/litre ? Si ça vous convient pourquoi pas ...
Alors que proposez-vous comme méthode pour mesurer le volume d'eau ? Je croyais que COUNT était la fonction à utiliser... :unsure:
 

Yex2

Well-known member
Bonjour,

Tu peux continuer à essayer d'utiliser "count" (je connais ton obstination).
La persévérance, et non l'obstination, est une qualité... ;-)

Mais, à mon avis, ce n'est pas la bonne solution. La formule donnée avec le capteur donne un nombre d'impulsions de 450/l avec une marge de 10%.

Donc, commence par compter simplement les impulsions (il faut une résistance de tirage, disons 4,7 k, à la limite, activer la pullup interne), cela donnera un volume d'eau. Jette un oeil sur le programme donné #6, l'interruption en particulier.
Regarde aussi la vidéo, c'est un décompteur, mais c'est pareil.
Mais comment comptes-tu les impulsions si ce n'est pas avec COUNT ? Il existe une autre fonction ? J'ai besoin de tes lumières !

https://www.manomano.fr/compteur-deau-et-accessoire-1606?model_id=2124545&g=1&referer_id=685759&ach=baa0e&achsqrt=2d3a4&gclid=EAIaIQobChMIpZbsk97a4wIVCflRCh2gwgFfEAQYASABEgJWGfD_BwE

Inutile pour le mon projet. Tu comprendras lorsqu'il sera finis et publié.

https://www.manomano.fr/compteur-deau-et-accessoire-1606?model_id=2124545&g=1&referer_id=685759&ach=baa0e&achsqrt=2d3a4&gclid=EAIaIQobChMIpZbsk97a4wIVCflRCh2gwgFfEAQYASABEgJWGfD_BwE

Non les toilettes sont à l'eau de mer. Les douches sont eau douce, donc du réservoir donc potable... C'est l'eau des douches que je veux mesurer. Perso je me lave dans la mer, ça coûte rien et ça fonctionne. Mais les petites madames préfèrent généralement l'intimité de leur cabine...

Je vais ajouter une résistance et des condensateurs tel suggéré à la page 11 du data sheet que tu m'as donnée plus haut. Je verrai si ça augmente la précision.

A+

Yves
 

Yex2

Well-known member
Non, mais elle précise que c'est un capteur à effet hall, et en général, ils ont une sortie avec un transistor en collecteur ouvert:
Ex: http://pdf1.alldatasheet.com/datasheet-pdf/view/45868/SIEMENS/TLE4905L.html

Et sans résistance,....ça fonctionne pas très bien....


MM
Bon j'ai essayer avec une résistance entre Q et Vs ainsi que deux cap de 4.7 nF comme suggéré à la page 11 du data sheet proposé et le résultat est le même.

En passant, j'avais déjà une résistance de 4.7 k entre la masse et Q.
 

Yex2

Well-known member
Bonjour,

Ce capteur YF-S201 est aussi vendu par Gotronic qui donne la même formule.

Il y a quelques années, j'avais répondu a une question à ce sujet. Si ça peut servir:


MM
Michel,

Chaque fois que j'essaye de voir la deuxième page du projet du compteur d'eau ça dit que ma session est expiré et que je dois me loguer... ???
 

MGU

Senior Member
Il doit y avoir une erreur de lien. le visiteur n'a pas à s'identifier.
Voici un lien visiteur pour la version LCD parallèle:

Le principal est le sous programme interruption. Il ne fait que compter les pulses du capteur. Un paquet de 45 pulses = 0,1L

Essaye de copier ce programme (date de 2013...bref) et test le fonctionnement. Si nécessaire, il faudrait enlever ce qui ne sert pas ici, et faire un compteur au lieu d'un décompteur.

MM
 

Yex2

Well-known member
Il doit y avoir une erreur de lien. le visiteur n'a pas à s'identifier.
Voici un lien visiteur pour la version LCD parallèle:

Le principal est le sous programme interruption. Il ne fait que compter les pulses du capteur. Un paquet de 45 pulses = 0,1L

Essaye de copier ce programme (date de 2013...bref) et test le fonctionnement. Si nécessaire, il faudrait enlever ce qui ne sert pas ici, et faire un compteur au lieu d'un décompteur.

MM
Allo Michel,

Bon si j'ai bien compris la fonction "setint", une fois une interruption détectée selon ce qui avait été programmé, le programme saute automatiquement à une sous-routine "interrupt: " qu'il faudra écrire. C'est bien ça ?

Dans ton programme :

Code:
interrupt:                    ;comptage des impulsions débitmètre
    inc partiel
    if partiel>=45 then        ;n litres/min = fréq/7,5
        dec rest            ;-> 1 litre/min = 7,5 impulsions/s
        partiel=0            ;-> 1 L = 7,5 x60 = 450 impulsions -> 0,1L =45 impulsions
    endif
    if rest>=10000 then            ;on essaye de passer en dessous de 0? (0-1=65535)
            rest=0                    ;blocage à 0
    endif
    do     loop while pinC.1=0        ;pour ne compter qu'une impulsion par cycle
    setint %00000000,%00000010    ;niveau 0 sur C.1   
    return
Tu redéfinis la fonction setint juste avant le return. Est-ce comme remettre le ressort sur une trappe à souris, i.e. une fois l'intéruption initiale il n'y en aura pas d'autre à moins de la redéfinir ?

Merci,

Yves
 

MGU

Senior Member
Allo Michel,

Bon si j'ai bien compris la fonction "setint", une fois une interruption détectée selon ce qui avait été programmé, le programme saute automatiquement à une sous-routine "interrupt: " qu'il faudra écrire. C'est bien ça ?
Dans ton programme :
Code:
interrupt:                    ;comptage des impulsions débitmètre
    inc partiel
    if partiel>=45 then        ;n litres/min = fréq/7,5
        dec rest            ;-> 1 litre/min = 7,5 impulsions/s
        partiel=0            ;-> 1 L = 7,5 x60 = 450 impulsions -> 0,1L =45 impulsions
    endif
    if rest>=10000 then            ;on essaye de passer en dessous de 0? (0-1=65535)
            rest=0                    ;blocage à 0
    endif
    do     loop while pinC.1=0        ;pour ne compter qu'une impulsion par cycle
    setint %00000000,%00000010    ;niveau 0 sur C.1 
    return
Tu redéfinis la fonction setint juste avant le return. Est-ce comme remettre le ressort sur une trappe à souris, i.e. une fois l'intéruption initiale il n'y en aura pas d'autre à moins de la redéfinir ?
Merci,
Yves
Une interruption ne sert qu'une fois, il faut un nouveau setint pour réarmer. Mais si on sort et que les conditions qui ont déclenché l'interruption précédente sont encore là, on y retourne. D'où le do loop while pinC.1=0, on reste dans l'interruption tant que le niveau C.0 est bas.

MM
 

Yex2

Well-known member
Une interruption ne sert qu'une fois, il faut un nouveau setint pour réarmer. Mais si on sort et que les conditions qui ont déclenché l'interruption précédente sont encore là, on y retourne. D'où le do loop while pinC.1=0, on reste dans l'interruption tant que le niveau C.0 est bas.

MM

Je comprends.

Pourquoi vérifier l'état 0 plutôt que 1 ? Il me semble que le débimètre génère une impulsion "1". J'Imagine que ça ne fera pas de différence si on mesure le 0 plutôt que le 1 mais est-ce qu'il y a une raison de choisir l'un plus que l'autre ?
 

MGU

Senior Member
Je comprends.
Pourquoi vérifier l'état 0 plutôt que 1 ? Il me semble que le débimètre génère une impulsion "1". J'Imagine que ça ne fera pas de différence si on mesure le 0 plutôt que le 1 mais est-ce qu'il y a une raison de choisir l'un plus que l'autre ?
C'est kif kif, le capteur génère autant de 1 que de 0 (si on met la résistance...). Il n'a pas dû t'échapper qu'entre deux 1, il y a un 0. c'est le montage qui fait que l'on s’intéresse plus à l'un qu'à l'autre, mais s'intéresser à l'un, c'est aussi s'intéresser à l'autre, alors.....

MM
 

Yex2

Well-known member
Je ne comprends pas pourquoi le fonctionnement du poussoir est aléatoire. Parfois il fonctionne mais la plupart du temps il ne réagit pas... J'ai vérifier le voltage au borne de C.4 et le voltage est bien à 0V. Donc il ne s'agit pas d'un problème matériel.

Voici le code :

La boucle se trouve entre les lignes 56 à 65.

Code:
do
    high C.0                ; LED "on" indique qu'on est en mode de comptage
    setint %00001000,%00001000        ; interruption niveau 1 sur C.3
    if calibration=0 then        ; le poussoir simule la fin du cycle de comptage. Il est sur C.4
            low    C.0            ; LED off pour indiquer une fin de cycle de comptage et enregistrement des données MIN et MAX
        pause 8000
        gosub record        ; cette routine enregistre les minimums et maximums
    endif
        gosub AfficheCourant        ; sous-routine de la consommation d'eau.
loop

Voici le code complet :

Code:
;    SCL sur C.1
;    SDA sur C.2
#picaxe 08M2    ;directive picaxe utilisé (pour erreur de commandes)
dirsC =%000111

setfreq M16        ;fréquence 16MHz    
;****** Nominations constantes ********
symbol baud= N2400_16              ;vitesse liaison RS232

 ;******* noms variables bit sur b0 ***********
symbol rsbit=bit0                ;bit commande/data afficheur
symbol calibr=bit1            ;memo phase calibration

;***** noms variables bytes ****************
 ; b1,b2,b3,b4,b5 utilisés dans bintoascii
 symbol posi        =b6            ;position curseur
 symbol car            =b7            ;caractère à afficher
 symbol dat            =b8

;****** noms variables word *********  
symbol etalon        =w13        ;diviseur d'impulsion pour avoir 0.1 litre
symbol cpt            =w12        ;compteur
symbol total        =w11        ;consomation total depuis dernier reset
symbol today        =w10        ;consomation journalière
symbol mini            =w9        ;consomaion miminum depuis dernier reset
symbol maxi            =w8        ;consomaion miminum depuis dernier reset
symbol impulsions        =w7        ;impulsion du bébitmètre

;******* Nominations ports ***********
symbol calibration      = pinC.4    ; poussoir de calibration

; Initialisation I2C 4 bits , etc ********
    hi2csetup i2cmaster,%01001110, i2cslow_32, i2cbyte 
    
; Initialisation LCD *********
    for cpt=0 to 5
        lookup cpt,($33,$32,$28,$c,$6,$01),car
        gosub EnvoiByteCommInit
    next
    pause 100    ;temps init du LCD
    

; lecteur des données en mémoire    
     read 0, word mini, word maxi, word total, word etalon      ; lecture de données enregistrées            
    if etalon =0 then 
        etalon =43            ; ± 0.1 litre
;        gosub calib           ; Afficher texte de calibration         
    endif
    if mini =0 then 
        mini =10000             ; Nécessaire au démarrage sinon la valeur sera toujours 0
    endif
    gosub AfficheInitial

; boucle

do
    high C.0                ; LED "on" indique qu'on est en mode de comptage 
    setint %00001000,%00001000        ; interruption niveau 1 sur C.3
    if calibration=0 then        ; le poussoir simule la fin du cycle de comptage.  Il est sur C.4
            low    C.0            ; LED off pour indiquer une fin de cycle de comptage et enregistrement des données MIN et MAX
        pause 8000
        gosub record        ; cette routine enregistre les minimums et maximums 
    endif
        gosub AfficheCourant        ; sous-routine de la consomation d'eau. 
loop

; les sousroutines **********************

interrupt:                            ;comptage des impulsions du débitmètre
    inc impulsions 
        if impulsions    >=etalon then     ;n litres/min = fréq/7,5
           inc today                    ;-> 1 litre/min = ±7,5 impulsions/s
        inc total                ; volume total consommé
      impulsions =0                  ;-> 1 L = 7,5 x60 = 450 impulsions -> 0,1L =45 impulsions
        endif
do     loop while pinC.3=1        ;pour ne compter qu'une impulsion par cycle
        setint %00001000,%00001000        ;niveau 1 sur C.3 
        return

;calcule les minimums et maxiums

record:
    if mini > today then 
        mini= today
    endif
    if maxi < today then
        maxi=today
    endif
    gosub AfficheRecord
    pause 6000
    return

;  Affichage texte initial ***********************         

AfficheInitial:    

    car= 128    'curseur début ligne 1
    gosub EnvoiByteComm    
    for cpt=0 to 19
    lookup cpt,("Conso Total en LITRE"),car
    GOSUB EnvoiByteData    
    next   

    car= 192    'curseur  début ligne 2
    gosub EnvoiByteComm    
    for cpt=0 to 19
    lookup cpt,("Conso Quotidienne  L"),car
    GOSUB EnvoiByteData    
    next 

    car= 148    'curseur  début ligne 3
    gosub EnvoiByteComm    
    for cpt=0 to 19
    lookup cpt,("Maximum Enregistre L"),car
    GOSUB EnvoiByteData    
    next 

    car=212        'curseur début ligne 4
    gosub EnvoiByteComm
    for cpt=0 to 19
    lookup cpt,("Minimum Enregistre L"),car
    GOSUB EnvoiByteData
    next
    pause 6000  
    gosub AfficheCourant
    gosub AfficheRecord
    pause 6000
return

; Affichage les valeurs Total et courantes

AfficheCourant:    
     car= 139    'curseur  ligne 1, position 12
      gosub EnvoiByteComm    
    if total> 999 then
        bintoascii total,b5,b4,b3,b2,b1    
        for cpt=0 to 8
            lookup cpt,("  ",b4,b3,b2,",",b1," L"),car    ;on a besoin que de 4 chiffres
            GOSUB EnvoiByteData
      next
      else if total> 99 then
         bintoascii total,b5,b4,b3,b2,b1    
        for cpt=0 to 8
            lookup cpt,("   ",b3,b2,",",b1," L"),car    ;on a besoin que de 3 chiffres
            GOSUB EnvoiByteData
      next
    else 
        bintoascii total,b5,b4,b3,b2,b1    
        for cpt=0 to 8
            lookup cpt,("    ",b2,",",b1," L"),car    ;on a besoin que de 2 chiffres
            GOSUB EnvoiByteData
      next
    endif
    
        car= 203    'curseur  ligne 2, position 12
        gosub EnvoiByteComm        
      if today> 99 then
         bintoascii today,b5,b4,b3,b2,b1    
        for cpt=0 to 8
            lookup cpt,(".  ",b3,b2,",",b1," L"),car    ;on a besoin que de 3 chiffres
            GOSUB EnvoiByteData
      next
    else 
        bintoascii today,b5,b4,b3,b2,b1    
        for cpt=0 to 8
            lookup cpt,(".   ",b2,",",b1," L"),car    ;on a besoin que de 2 chiffres
            GOSUB EnvoiByteData
      next
    endif
     write 4, word total      ; écriture des volumes consommés
return

; Affiche minimum et maximum***********************

AfficheRecord:
    car= 159    'curseur  ligne 3, position 12
      gosub EnvoiByteComm 
    if maxi =0 then
         bintoascii maxi,b5,b4,b3,b2,b1         
       for cpt=0 to 8
            lookup cpt,(".   ",b2,",",b1," L"),car     ;on enlève les symboles ">>"
            GOSUB EnvoiByteData
      next
    else if maxi > 999 then
         bintoascii maxi,b5,b4,b3,b2,b1         
       for cpt=0 to 8
            lookup cpt,(">>",b4,b3,b2,",",b1," L"),car    ;on enlève les symboles ">>"
            GOSUB EnvoiByteData
      next
    else if maxi> 99 then
         bintoascii maxi,b5,b4,b3,b2,b1    
        for cpt=0 to 8
            lookup cpt,(">> ",b3,b2,",",b1," L"),car    ;on a besoin que de 3 chiffres
        GOSUB EnvoiByteData
      next
    else 
        bintoascii maxi,b5,b4,b3,b2,b1    
        for cpt=0 to 8
            lookup cpt,(">>  ",b2,",",b1," L"),car    ;on a besoin que de 2 chiffres
        GOSUB EnvoiByteData
      next    
      endif

    car= 223    'curseur  ligne 4, position 12
      gosub EnvoiByteComm 
    if mini > 9999 then
         bintoascii mini,b5,b4,b3,b2,b1         
       for cpt=0 to 8
            lookup cpt,(".   ",b2,",",b1," L"),car     ;Condition de départ
            GOSUB EnvoiByteData
      next
    else if mini > 999 then
         bintoascii mini,b5,b4,b3,b2,b1         
       for cpt=0 to 8
            lookup cpt,(">>",b4,b3,b2,",",b1," L"),car     ;on enlève les symboles ">>"
            GOSUB EnvoiByteData
      next
    else if mini> 99 then
         bintoascii mini,b5,b4,b3,b2,b1    
        for cpt=0 to 8
        lookup cpt,(">> ",b3,b2,",",b1," L"),car    ;on a besoin que de 3 chiffres
            GOSUB EnvoiByteData
      next
    else 
        bintoascii mini,b5,b4,b3,b2,b1    
        for cpt=0 to 8
            lookup cpt,(">>  ",b2,",",b1," L"),car    ;on a besoin que de 2 chiffres
        GOSUB EnvoiByteData
      next
endif
     Today = 0                    ; remise à zéro de la consommation quotidienne
         write 0, word mini, word maxi     ; écriture des nouveaux records
return  


; Sub envoi vers LCD via I2C *************
EnvoiByteCommInit:
    pause 15
EnvoiByteComm:
    rsbit=0
EnvoiByteData:
;1ére moitié
    dat=car & $F0 | %1000 | rsbit ;%1000 pour l'éclairage
    hi2cout (dat)
    pause 1       
    dat=dat | %1100
    hi2cout (dat)    ;pulse sur E cad P2
    pause 1
    dat=dat | %1000 & %1011   ;fin pulse
    hi2cout (dat)
    pause 1   
;2éme moitié
    dat=car & $0F * 16 | %1000 | rsbit
    hi2cout (dat)
    pause 1   
    dat=dat | %1100
    hi2cout (dat)
    pause 1
    dat=dat | %1000 & %1011
    hi2cout (dat)    
    rsbit=1
    return
 

Yex2

Well-known member
J'ai trouvé le problème concernant mon message précédant.

Une fois sur deux, le programme ne sort pas de la sous-routine interrupt: parce que le débimètre utilisé semble retourner alétoirement une valeur ou une autre même au repos... :mad::

Code:
    interrupt:
high    C.0                    ;comptage des impulsions du débitmètre
    inc impulsions
        if impulsions    >=etalon then     ;n litres/min = fréq/7,5
           inc today                    ;-> 1 litre/min = ±7,5 impulsions/s
        inc total                ; volume total consommé
      impulsions =impulsions-etalon     ;-> 1 L = 7,5 x60 = 450 impulsions -> 0,1L =45 impulsions
        endif
do     loop while pinC.3=0            ;pour ne compter qu'une impulsion par cycle
        setint %00000000,%00001000        ;niveau 0 sur C.3
    time=0
    low C.0
        return
En absence de mon oscilloscope (il est dans une unité de storage), j'ai fait les tests suivants :

J'ai placé une DEL sur la pin C.0 Elle s'allume si le programme est entré dans la sous-routine.

J'ai également placé deux DEL sur l'entrée C.3 (là où se fait le comptage des impulsions. La DEL verte s'allume si état =1 et la rouge s'allume si état = 0.

Un coup sur deux l'état est = à 0 et à cause de la ligne suivante: do loop while pinC.3=0 , le programme ne sort jamais de cette loop. La seule solution consiste à renvoyer un peu d'eau en espérant que le hasard m'enverra sur l'état "1".

Bref c'est pas facile ces débitmètres. Présentement la seul solution que j'ai trouvé c'est de le placer verticalement en m'assurant qu'il se vide complètement. Mais c'est vraiment pas utile un débitmètre qui fonctionne correctement seulement s'il y a plus d'eau dedans...

Suggestion de montage quelqu'un ? Qu'est-ce qui n'est pas bon ici ?

Merci,

Yves

PS: j'ai essayé une résistance "pullup" de 10k et une de 1.2k avec les même résultat aléatoire...
 

MGU

Senior Member
Je ne comprends pas pourquoi le fonctionnement du poussoir est aléatoire. Parfois il fonctionne mais la plupart du temps il ne réagit pas... J'ai vérifier le voltage au borne de C.4 et le voltage est bien à 0V. Donc il ne s'agit pas d'un problème matériel.
Bonjour,
Mouai...
Pour le poussoir, j'ai bien une idée, mais sans schéma, je ne peux rien dire.

Pour le reste, j'ai du mal...
A quoi sert la calibration? Le capteur est donné pour 450 pulses par litres (à vérifier).
J'avais compté des paquets de 45 pulses pour une résolution de 0,1L. Si le comptage est toujours faux en + ou en -, enlever ou ajouter des impulsions pour ajuster et mémoriser en EEPROM cette valeur. Mais bon, tu fais comme tu veux.....
Sur quoi est le poussoir?
Sur quoi est le capteur?
Les deux doivent être différents : C.3 et C.4 par ex
Comment est définie la journée ? Là, je vois pas.

Bref... Je conseille de faire un schéma et un cahier des charges qui explique tout.

MM
 

Yex2

Well-known member
Bonjour,
Mouai...
Pour le poussoir, j'ai bien une idée, mais sans schéma, je ne peux rien dire.

Pour le reste, j'ai du mal...
A quoi sert la calibration? Le capteur est donné pour 450 pulses par litres (à vérifier).
Parce que ces capteurs ne sont pas linéaire. Par exemple, le mien donne entre 410 et 445 impulsion lorsque je verse 1 L / 18 sec. Selon la doc, je devrais avoir ±585 impulsions (32.5 Hz pendant 18 secondes). À 430 je suis loin du compte.

Selon la doc la fréquence devrait varier comme suit :

2L/min = 16 Hz
4L/min = 32.5 Hz
6L/min = 49.3 Hz
8L/min = 65.5 Hz
etc.

Donc pour faire quelques chose de précis, il faut calibrer. Pour mon projet de chalet, c'est pas important puisque je n'aurai qu'un seul flow-mètre. La même erreur de lecture se répètera pour chacun. Mais pour le projet du bateau (4 douches), sachant que la pression et le débit varie un peu dans chacune, alors il faut calibrer individuellement pour que la compétition entre invité soit juste et équitable. De plus la doc indique aussi que le niveau de précision peu varier de ±10%. Raison de plus de bien calibrer chaque débitmètre pour que les valeurs consommées de tous soit exactes.


Document ici

J'avais compté des paquets de 45 pulses pour une résolution de 0,1L. Si le comptage est toujours faux en + ou en -, enlever ou ajouter des impulsions pour ajuster et mémoriser en EEPROM cette valeur. Mais bon, tu fais comme tu veux.....
J'utilise la valeur de départ de 43, ce qui me donne presque 100% de précision 2 fois sur 3.

Sur quoi est le poussoir?
Sur quoi est le capteur?
Les deux doivent être différents : C.3 et C.4 par ex
Comment est définie la journée ? Là, je vois pas.
Le poussoir est sur C.4 et le capteur sur C.3

Le problème n'est pas le poussoir mais le capteur et la fonction setint. J'ai compris ce qui se passait. Au repos le débitmètre reste sur un état ou sur un autre de façon aléatoire. i.e.. Au repos il renvois la condition "0" ou "1". C'est ça le bug.

Si le débitmètre s'arrête sur l'état "0", il ne sort jamais de la sous routine interrupt.

Donc on ne peut pas utiliser la fonction setint avec ce débitmètre puisqu'on a 50% de chance qu'il s'arrête sur l'état qui déclenche l’interruption.

Ça prends une fonction qui mesure seulement le front montant ou descendant de l'impulsion. La fonction COUNT fait ça mais je n'ai jamais réussi à lire plus de 300 impulsions pour le débit de 4L/min. De tout évidence, je ne sais pas encore comment l'adapter afin qu'elle retourne une lecture fiable. De plus COUNT arrête tout jusqu'à ce qu'il termine.

Il y a aussi la fonction SETTIMER COUNT xxxxx qui semble capable de lire le front montant de C.0. Mais c'est pur les PICAXE de la série X. Cette fonction à l'avantage de s'exécuter en arrière plan. DOnc le programme continu de rouler normalement pendant qu'il compte les impulsions.

Bon voilà le problème ! Connais-tu une autre fonction qui peut lire le front montant ? Sinon je vais retourner avec COUNT et finir par le faire fonctionner adéquatement.


Bref... Je conseille de faire un schéma et un cahier des charges qui explique tout.

MM
Oui je le ferai mais pour le moment je cherche une nouvelle solution.
 

MGU

Senior Member
J'utilise la valeur de départ de 43, ce qui me donne presque 100% de précision 2 fois sur 3.
Si le débitmètre s'arrête sur l'état "0", il ne sort jamais de la sous routine interrupt.
Oui je le ferai mais pour le moment je cherche une nouvelle solution.
Mais si, la fonction N_litres/N_pulses est linéaire. On se fiche de la fréquence, on compte des impulsions.

Pour l'interrupt, c'est vrai, ça peut bloquer
La solution que je vois: On force la sortie du do loop si time>0 . Ce qui correspond à 1Hz

time=0
do loop while pinC.3= 0 and time=0

A essayer..

MM
 
Last edited:

Yex2

Well-known member
Mais si, la fonction N_litres/N_pulses est linéaire. On se fiche de la fréquence, on compte des impulsions.

Pour l'interrupt, c'est vrai, ça peut bloquer
La solution que je vois: On force la sortie du do loop si time>0 . Ce qui correspond à 1Hz

time=0
do loop while pinC.3= 0 and time=0

A essayer..

MM
Ça ne fonctionnera pas parce qu'au moment qu'on sort de la loop, on y retourne aussitôt parce que la condition est toujours à "0" et ça génère une interruption ! C'est un catch 22 comme dirait la police.

Il faut impérativement lire le front montant ou descendant de l'impulsion. À date je ne vois que COUNT qui peut faire ça.

Il y a peut-être PULSIN qui fonctionnerait également en combinaison avec SETINT.

PULSIN donne un état constant à 1 lorsqu'il détect le front montant d'une impulsion. SETINT pourrait alors la compter sans rester bloqué. À voir...
 
Last edited:

MGU

Senior Member
Bon sang mais c'est bien sûr...

Y a qu'à supprimer l'interruption. Qui finalement ne sert à rien
do
do loop while pinC.3=1
inc pulses ;compte les pulses
do loop while pinC.3=0
loop

A essayer...

MM
 

Yex2

Well-known member
Bon sang mais c'est bien sûr...

Y a qu'à supprimer l'interruption. Qui finalement ne sert à rien
do
do loop while pinC.3=1
inc pulses ;compte les pulses
do loop while pinC.3=0
loop

A essayer...

MM
Originale !

Donc si je comprends bien, on compte seulement entre les 0 et les 1.

À essayer en effet et pas mal plus simple au final !
 

ddaweb

New Member
Bonsoir,
Je lit ce topic sans oser intervenir vu mes connaissances limitées.
@MGU vient d'arriver à la conclusion que je pensais depuis pas mal de temps : simplement compter les impulsions pour connaître la consommation.

Je me pose plusieurs questions :
- Il me semble qu'il manque une horloge en temps réel pour déterminer la conso journalière : elle pourrait faire le reset des variables journalières
- Comme MGU, un enregistrement hard (Eeprom) ne serait pas inutiles vu que si le picaxe viendrait à redémarrer, tout serait perdu ... permettrait également un historique.
- A quoi sert la lecture des impulsions durant un temps déterminé de quelques secondes ?

Tout cela pourrait se faire avec l'I2C présent ?

Donc si je comprends bien, on compte seulement entre les 0 et les 1.
Il me semble que cela ne compte que les 1
 

MGU

Senior Member
Originale !
Donc si je comprends bien, on compte seulement entre les 0 et les 1.
À essayer en effet et pas mal plus simple au final !
En fait, on compte les fronts, montants ou descendants, au choix.
Et mettre le poussoir sur interruption, pour un reset (la calibration ne sera qu'un rattrapage d'erreur systématique d'un capteur donné. Les erreurs hasardeuses se moyennent toutes seules.

Pour une résolution de 0,1L, faire des paquets de 45 (ou 44, ou 46, ou...), avec sauvegarde en EEPROM tous les litres.

MM
 

PieM

Senior Member
Bonjour,
Y a qu'à supprimer l'interruption. Qui finalement ne sert à rien
do
do loop while pinC.3=1
inc pulses ;compte les pulses
do loop while pinC.3=0
loop
Oui Michel mais ça suppose que picaxe ne fait rien d'autre, car il sera toujours dans une boucle do loop !
A mon avis garder l'interrupt, mais utiliser un circuit dérivateur en sortie du capteur.

Autre solution:
on fait une interruption sur l'état 1 (par ex)
dans l'interruption, on monte un flag à 1 , puis on réarme l'interruption pour un niveau 0.
dans l'interruption, si flag à 1 on compte, on remet le flag à 0 et on réarme l'interruption pour un niveau 1.
on génère une interruption lors de changement d'état et on ne compte que dans l'une.
Sais pas si ça marche...
 
Last edited:

MGU

Senior Member
Bonjour,

Oui Piem, exact, avec cette méthode, on est sûr de ne pas sortir de la boucle.
Un différenciateur qui générerait un pulse court aux changements d'états serait une solution.
Mais en général, on adopte les solutions après avoir établit le cahier des charges, là, on fait le contraire...

MM
 

PieM

Senior Member
Mais en général, on adopte les solutions après avoir établit le cahier des charges, là, on fait le contraire...
Bien d'accord !...
De toute façon quand on en est à calibrer un appareil avec autant d'approximation, pour un résultat contestable...
Car il faudrait corriger le nombre d'impulsions en fonction des débits instantanés, si on veut tenir compte de la non linéarité!
Ce qui revient à mesurer le débit instantané et à intégrer en fonction du temps, ce qui n'est pas le même problème.
 

Yex2

Well-known member
Bonjour,

Oui Michel mais ça suppose que picaxe ne fait rien d'autre, car il sera toujours dans une boucle do loop !
A mon avis garder l'interrupt, mais utiliser un circuit dérivateur en sortie du capteur.

Autre solution:
on fait une interruption sur l'état 1 (par ex)
dans l'interruption, on monte un flag à 1 , puis on réarme l'interruption pour un niveau 0.
dans l'interruption, si flag à 1 on compte, on remet le flag à 0 et on réarme l'interruption pour un niveau 1.
on génère une interruption lors de changement d'état et on ne compte que dans l'une.
Sais pas si ça marche...
C'est exactement à ce que j'ai pensé cette nuit. Il faut armer l'interuption dans la boucle et seulement lorsque la condition de C.3 est à 0.

Code:
boucle:

if C.3 = 0 then
            setint %00001000,%00001000        ;niveau 1 sur C.3
endif

ligne de code
ligne de code
etc.

goto boucle
L’interruption ne sert qu'à incrémenter le compteur

Code:
interrupt:                            ;comptage des impulsions du débitmètre
    inc impulsions
        if impulsions    >=etalon then     ;n litres/min = fréq/7,5
           inc today                    ;-> 1 litre/min = ±7,5 impulsions/s
        inc total                ; volume total consommé
      impulsions =0                  ;-> 1 L = 7,5 x60 = 450 impulsions -> 0,1L =45 impulsions
        endif
        return
 

Yex2

Well-known member
Bien d'accord !...
De toute façon quand on en est à calibrer un appareil avec autant d'approximation, pour un résultat contestable...
Car il faudrait corriger le nombre d'impulsions en fonction des débits instantanés, si on veut tenir compte de la non linéarité!
Ce qui revient à mesurer le débit instantané et à intégrer en fonction du temps, ce qui n'est pas le même problème.

C'est la raison pour laquelle j'insiste pour avoir une fonction de calibrage dans mon code.

J'ai 2 projets distincts.

Le premier pour le chalet avec une seule pompe et une seul douche.
Le deuxième pour le voilier avec une seule pompe et 6 sorties. Seulement 4 auront une compteur. Comme les pressions vont varier légèrement d'une douche à l'autre dû au différence de configuration de la plomberie du bateau, il faut calibrer individuellement chaque compteur afin de retourner une valeur exact de consommation d'eau.
 
Top