Bonjour à tous,
Ce post est pour faire suite à une discussion que j'ai démarré en 2017. Après de nombreuses suggestions, j'ai retenu celle de Mag1, soit 3 sondes capacitives utilisant les MP Picaxe. Je résume rapidement le projet :
Il y a 3 réservoirs d'eau de forme cubique et de volume identique. Je voulais un affichage LCD me donnant le volume d'eau dans chaque réservoir et la sommes totales. Le LCD affiche en %, Litres et Gallons Impériaux.
Les sondes qui m'ont donné le meilleur résultat sont fait en plastique PVC avec un fil émaillé et un fil d'inox pour le gnd. (voir les photos plus bas).
Les programmes sont de Mag1.
Le programme principale :
Code:;Ex: sonde de niveau capacitive MM 13/06/2018 ;**** calibration de la sonde par action 3 sec sur le poussoir de validation *********** ;**** La réponse de la comande TOUCH est considérée comme linéaire (elle l'est...) ;**** Le sous programme "calib:" mesure deux points arbitraires 0 et 100% ********* ;**** mesure de la référence interne de température dans l'émetteur 08M2 ;**** Ces trois mesures sont mémorisées en EEPROM ;**** Calcul de la proportionnalité entre la mesure et les valeurs mémorisées **** ;**** Calcul d'une correction de température (par rapport à la t° lors de la calibration) ;**** Affichage du Niveau en % et en litres ;**** Affiche les étapes successives ********* #picaxe 14M2 ;directive picaxe utilisé (pour erreur de commandes) setfreq M16 ;fréquence 16MHz ;****** Nominations constantes ******** symbol baud= N2400_16 ;vitesse liaison RS232 symbol capacit= 323 ;capacité réservoir en L symbol gallon=7105 ;capacité en /100 de Gallon Imp ;****** noms variables word ********* symbol mesur = w13 ;(b27,b26) symbol compens = w12 ;(b25,b24) symbol bas = w11 ;ref niveau bas symbol memcomp = w10 ;mémo réf compensation t° symbol delta = w9 ;delta haut-bas symbol total = w8 ;total réservoirs en % symbol varw = w7 ;variable tempotaire symbol deb = w6 ;debut texte symbol cpt = w5 ;compteur ;***** noms variables bytes **************** ; b1,b2,b3,b4 utilisés dans bintoascii symbol car =b5 ;caractère à afficher symbol dat =b6 ;data I2C symbol sonde =b7 ;n° sonde symbol posi =b8 ;position curseur symbol ajust =b9 ;ajustement °C lue sur potar ;******* noms variables bit sur b0 *********** symbol rsbit=bit0 ;bit commande/data afficheur symbol calibr=bit1 ;memo phase calibration ;******* Nominations ports *********** symbol sonde0 = C.0 ;entrée sonde0 n°broche=8 symbol sonde1 = C.1 ;entrés sonde1 n°broche=9 symbol sonde2 = C.2 ;entrée sonde2 n°broche=10 symbol valid = pinC.3 ;valeur poussoir de validation symbol potaj2 = B.1 ;valeur ajustage sonde C.1 symbol potaj3 = B.2 ;valeur ajustage sonde C.2 ; Initialisation I2C . pour 14M2:sda sur B.4 ; scl sur B.3 hi2csetup i2cmaster,%01001110, i2cfast_16, i2cbyte ;** Entrée des données texte dans "table" *********** table 0,(51,50,40,12,6,1) ;initialisation LCD 4 bits table 20,(" calibration 0% ") table 40,(" mesure 0%= ") table 60,(" calibraton 100% ") table 80,(" mesure 100%= ") table 100,(" calibration ") table 120,(" effectu",1,"e ") ;1 pour é table 140,(" DEFAUT SONDE ") table 160,(" DEFAUT TIMEOUT ") table 180,(2,4,14,17,31,16,14,0) ;descripton lettre é table 200,(" SONDE nß ") ;ß= alt+0223 =° sur clavier table 220,("RESERVES D'EAU: %") table 240,("#1 % L , GI") table 260,("#2 % L , GI") table 280,("#3 % L , GI") pullup %0100000000000 ;pullup sur C.3 ;***** macro texte *************** #macro text(posi,deb,varw) car=posi:gosub EnvoiByteComm ;pos curseur en 128 for cpt=deb to varw readtable cpt,car ;texte gosub EnvoiByteData next #endmacro ; Initialisation LCD ********* for cpt=0 to 5 readtable cpt,car gosub EnvoiByteCommInit next pause 500 ;temps init du LCD ; définition des caractères ajoutés en CGRAM ; def du é en CGRAM 1 ************************** car=1*8|$40 :gosub EnvoiByteComm for cpt=180 to 187 readtable cpt,car ;description du é vers CGRAM n°1 gosub EnvoiByteData next ;******* Début Programme principal ***************** car=1:gosub EnvoiByteComm ; raz afficheur read 0,word bas, word delta,word memcomp ; lecture param droire + t° pendant calib if bas =0 then calib ; Vers calib si aucun paramètre enregistré ;***** boucle pricipale ************************************** debut: calibr=0 ;on est pas en calibration text(128,220,239) ;texte "RESERVES D'EAU: %" text(192,240,259) ;texte fixe text(148,260,279) text(212,280,299) Do time=0 do while valid=0 ;si valid=1, on entre pas if time> 3 then calib ;demande de calibration loop total=0 for sonde=8 to 10 ;n° des broches : broches C.0=8,C.1=9,C.2=10 gosub mesure gosub calcul gosub affich total=total+mesur next gosub afftotal loop ;******* Fin programme principal ************* ;******* Les sous programmes: ******************** ;************** Mesure des sondes, liaison RS232 *********** ; Pour les essais avec une seule sonde, le port serin est bloqué à 8 (C.1) au lieu de scanner les 3 sondes ; Pour le scanne réel, il faut remplacer le "8" par "sonde" dans la commande serin ci dessous mesure: serin [10000,alarmsonde],sonde ,baud,b27,b26,b25,b24 ;(b27;b26)mesur ; (b25,b24)compens ;mesur=w13 = (b27;b26) ;reconstitution de la mesure brute ;compens = (b25,b24) ft tempé interne if mesur =0 then alarmsonde ;erreur de mesure, dépassement 65535 ;***** compensation dispersion °C ************ if sonde=8 then mesur=mesur/100 elseif sonde=9 then readadc potaj2,ajust ;ajust=0 à 255 ajust=ajust/5 ;255/5=50 curseur milieu=25 ajust=75+ajust ;ajust = de 75 à 125 mesur=mesur/ajust elseif sonde=10 then readadc potaj3,ajust ajust=ajust/5 ajust=75+ajust mesur=mesur/ajust endif ;******* compensation température ************ if memcomp>compens then compens=memcomp- compens ;plus froid compens=compens /4 ;ici un rapport 4 entre les variations mesure et ref t° interne mesur=mesur + compens else compens=compens - memcomp ;plus chaud compens=compens /4 mesur=mesur - compens ;on garde les chiffres significatifs endif return '******** Affichage des valeurs lues *********** affich: if sonde=8 then posi=192 elseif sonde=9 then posi=148 elseif sonde=10 then posi=212 endif ;********** affichage en % ************** car=posi+3:gosub EnvoiByteComm ;pos curseur aff % bintoascii mesur,b1,b1,b1,b2,b3 ;décomposition ascii for cpt=0 to 2 lookup cpt,(b1,b2,b3),car ;affichage valeur en % gosub EnvoiByteData next ;********* affichage en litres *********** car=posi+8:gosub EnvoiByteComm ;pos curseur aff L varw=capacit *mesur/100 bintoascii varw,b1,b1,b1,b2,b3 for cpt=0 to 2 lookup cpt,(b1,b2,b3),car ;affichage valeur en L gosub EnvoiByteData next ;*********** affichage en gallon imp ************ car=posi+13:gosub EnvoiByteComm ;pos curseur varw=70*mesur ;décomposition 7105*mesur/100 =70*mesur >> 7000 varw=1*mesur+varw ;+1*mesur >> 100 + 7000 >> 7100 varw=mesur/20+varw ;+ mesur/20 >> 100/20 + 7100 >> 7105 bintoascii varw,b1,b1,b2,b3,b4 ;pas écraser les octets utiles for cpt=0 to 1 lookup cpt,(b1,b2),car ;affichage partie entière gosub EnvoiByteData next car=posi+16:gosub EnvoiByteComm ;pos curseur for cpt=0 to 1 lookup cpt,(b3,b4),car ;affichage décimales, après virgule gosub EnvoiByteData next pause 1000 ;pour stabiliser l'affichage return ;afichage du total des 3 réservoirs en % (max=100%) afftotal: total=total/3 ;moyenne de la somme des trois réservoirs bintoascii total,b1,b1,b1,b2,b3 car=144 :gosub EnvoiByteComm ;position % global for cpt=0 to 2 lookup cpt,(b1,b2,b3),car ;affichage valeur en % gosub EnvoiByteData next return ;******* Calibration, Calcul paramètres, Affichage, Mise en mémoires *** calib: car=1:gosub EnvoiByteComm ;raz afficheur calibr=1 text(128,20,39) ;texte "calibration 0%" do:loop while valid=0 ;attente relachement poussoir text(192,40,59) ;texte "mesure 0=%" do serin [20000,alarmsonde],8,baud,b27,b26,b25,b24 ;(b27,b26) mesur (b25,b24) comprend if mesur =0 then gosub alarmsonde ;erreur de mesure, dépassement 65535 mesur=mesur/100 ;on garde les chiffres significatifs bas=mesur ;mesure du point 0% bintoascii mesur,b1,b1,b1,b2,b3 ;affichage car=207: gosub EnvoiByteComm ;pos curseur en 205 for cpt=0 to 2 lookup cpt,(b1,b2,b3),car ;affichage valeur 0% gosub EnvoiByteData next pause 500 loop while valid=1 ;attente validation car=1:gosub EnvoiByteComm ;raz affichage text(128,60,79) ;texte calibration 100% do:loop while valid=0 ;attente relachement poussoir text(192,80,99) ;texte valeur mesure 100%= do serin [20000,alarmsonde],8 ,baud,b27,b26,b25,b24 if mesur =0 then gosub alarmsonde ;erreur de mesure sonde, dépassement 65535 mesur=mesur/100 ;on garde les chiffres significatifs bintoascii mesur,b1,b1,b1,b2,b3 car=207: gosub EnvoiByteComm ;pos curseur en 205 for cpt=0 to 2 lookup cpt,(b1,b2,b3),car ;affichage mesure 100% gosub EnvoiByteData next pause 500 loop while valid=1 if bas>mesur then calib ;erreur de procédure. retour début do:loop while valid=0 ;attente relachement poussoir delta=mesur-bas write 0,word bas,word delta,word compens ;Mise en mémoire EEPROM text(128,100,119) ;texte calibration text(192,120,139) ;texte effectuée pause 4000 ;Temps d'affichage reset ;*********** Calcul pourcentage *********************** calcul: if mesur <=bas then ; on est en dessous de 0 mesur=0 ;butée à 0 else mesur=mesur-bas ;calage à l'origine mesur=100*mesur/delta ;proportionnalité ,unités en pourcents endif return ;***** Alarmes dépassement Time Out liaison sonde (temporaire) et défaut sonde ********** Alarmsonde: car=1:gosub EnvoiByteComm ;raz afficheur if mesur=0 then ;erreur de mesure sonde (défaut isolant ?) text(128,140,159) else ;temps TIMEOUT dépassé (liaison coupée ?) text(128,160,179) endif text(192,200,219) ;texte sonde n° sonde =sonde-7 ;pour numéroter les sondes de 1 à 3 bintoascii sonde,b1,b2,b3 car=203:gosub EnvoiByteComm ;pos curseur en 128 car=b3: gosub EnvoiByteData ;sonde en défaut pause 6000 ;temps de lecture if calibr=1 then calib ;on tait en calibration. On y retourne goto debut ;retour au dbut de la boucle principale ; 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 2 dat=dat | %1100 hi2cout (dat) ;pulse sur E cad P2 pause 2 ;pause 2 pour 32 MHz dat=dat | %1000 ;fin pulse hi2cout (dat) pause 2 ;2ème moitié dat=car & $0F * 16 | %1000 | rsbit hi2cout (dat) pause 2 dat=dat | %1100 hi2cout (dat) pause 2 dat=dat | %1000 & %1011 hi2cout (dat) rsbit=1 return
Le programme pour les sondes est le suivant. Noté qu'il a fallu jouer avec la sensibilité du PICAXE afin de s'adapter le mieux possible avec la sonde.
Code:;EMETTEUR SERIE pour sonde capacitive MM 020619 ;Avec correction de température ;sondes Yex2 #picaxe 08M2 ;directive pour cohérence commandes #no_data ;pour gagner 3 s au chargement code ;******* Nominations ports et variables*********** setfreq m4 ;rappel fréq de base symbol baud= N2400_4 ;constante fréq rs232 ;**** Nomination des ports symbol sonde = C.4 ;canal commande touch idem C.4 sur M2 symbol portS = C.1 ;port liaison série ;****** Boucle de mesure et liaison série *********** Do ;touch16 [%11010001],sonde,w13 ;w13 (type word est composé des deux bytes (b27;b26) ;touch16 [%10010001],sonde,w13 ;Pour x2: touch16 [%01010001],sonde,w13 ;Pour x3: (semble parfaite pour les nouvelles sondes du bateau 11/2020) ;touch16 [%00010001],sonde,w13 ;Pour x4: valeur par défaut ;touch16 [%01011001],sonde,w13 ; (sonde nu2) ;touch16 [%01011000],sonde,w13 ;Meilleur résultat à date ;touch16 [%11111011],sonde,w13 ; moins grande sensibilité (de l'ordre de 100 pF à 10 nF (utilisé pour la sonde du chalet) (sonde nu3) readinternaltemp IT_RAW_H,0,w12 ;transmission réfrence t° interne pour Vcc 5v serout portS,baud,(b27,b26,b25,b24) ;deux octets de w13 et 2 octets w12 par serout pause 500 ;Faut pas aller trop vite loop
Voici le circuit :
niveaux3sondes-LCD2004.JPG
Voici les sondes :
IMG_20201113_142706016.jpg IMG_20201111_135844793.jpgIMG_20201113_142727118.jpg
Bon ma question s'adresse à Mag1. Si je peux me permettre, il y a selon moi il y a un bug de logique dans le programme principale. À la ligne 125 on trouve le code suivant :
Si une sonde venait qu'à faire défaut, ce qui est plus que possible dans l'environnement salin, alors le programme va dans la sous routine "alarmsone", affiche l'erreur approprié de la ligne 56 ou 57, soitCode:if mesur =0 then alarmsonde ;erreur de mesure, dépassement 65535
table 140,(" DEFAUT SONDE ")
table 160,(" DEFAUT TIMEOUT ")
et n'en ressort plus. C'est là le problème selon moi. Il faudrait plutôt afficher l'erreur en question sur la ligne de la mesure de la sonde et permettre au programme de continuer à donner de l'information sur les deux autres réservoirs. Ex. disons que la sonde 3 fait défaut :
Si tout va bien, l'afficheur LCD renvoi ceci lorsque les réservoirs sont pleins :
RESERVES D'EAU: 100%
#1 100% 323L 71,05GI
#2 100% 323L 71,05GI
#3 100% 323L 71,05GI
Si la sonde #3 cesse e fonctionner, au lieu de sortir, il faudrait plutôt afficher quelques chose comme ceci :
RESERVES D'EAU: 66%
#1 100% 323L 71,05GI
#2 100% 323L 71,05GI
#3 DEFAUT SONDE
ou
RESERVES D'EAU: 66%
#1 100% 323L 71,05GI
#2 100% 323L 71,05GI
#3 DEFAUT TIMEOUT
Au moins dans ce cas, nous avons toujours les deux première sondes fonctionnelles. J'ai tenté d'ajuster ton programme mais pas trop compris comment tout se jouait... Peux-tu m'aider stp ?
Merci,
Yex2
-----