Lecture de niveau par sonde capacitive Picaxe
Détection de bas niveau avec alarme
La commande "TOUCH16" des picaxes est ici détournée pour fabriquer un lecteur de niveau avec affichage sur LCD1602 série "maison" et déclenchement d'une alarme en cas de sous niveau.
Ce projet utilise un picaxe 08M2 et ne nécessite qu'un minimum de composants.
Le schéma:
Il ne peut pas faire plus simple et pourtant, les résultats sont intéressants.
La sonde, cet élément capital est composé d'un simple morceau de fil électrique rigide de 2,5 mm², avec son isolant, dont une extrémité est fermée par une goutte de colle (ici, colle au pistolet).
Un second fil dénudé trempe à côté, relié au 0v (masse).
Un 08M2, un potensiomètre de réglage de l'alarme, un poussoir de validation, un LCD série, une LED, c'est tout.
La précision et la linéarité est estimée grossièrement de 2 ou 3 %.
(La pile de livres et la boite en carton n'améliorent pas la précision de la mesure).
Mise en oeuvre:
Le poussoir, pressé pendant la mise sous tension, donne accès à la calibration.
- Enregistrement du niveau correspondant à 0%
- Enregistrement du niveau correspondant à 100%
L'enregistrement des données en EEPROM est automatique
Aprés les validations successives, le LCD affiche le niveau du liquide en % et le niveau d'alarme. Le niveau bas est bloqué à 0%, mais le niveau haut peut dépasser les 100%. En fait, touch16 est un capacimètre. Voici la droite donnant la valeur brute retournée par la commande en fonction de la capacité mesurée sur ma platine d'essais. |  |
Premier écran: calibration 0% On trempe un petit bout du fil dans l'eau et on presse le poussoir |  |
Second écran: calibration 100% En soulevant la bouteille par 6 ou 7 livres, on trempe un bon bout de fil dans l'eau, et on presse le poussoir. |  |
L'écran suivant affiche ensuite le niveau du liquide et le réglage de l'alarme en %. Petite vérification, retour au niveau 0% |  |
La pile de lit tes ratures a été divisée. Il reste un peu plus de la moitié |  |
La même pile vue du dessus. Le niveau est en dessous du minimum, l'alarme est allumée |  |
Test de linéarité: Effectué avec du câble pour multimètre, souple et bien isolé.
La valeur max retournée par la commande "touche16" du picaxe est 65535, elle est divisée par 100 dans ce graphique
On peut donc espérer mesurer une hauteur de 1 m d'eau avec ce type de câble.
Pour mesurer une hauteur d'eau plus importante, il faut changer de sonde ou modifier les paramètres par défaut de la commande "Touch16".
La commande touch16 est configurable, l'octet de configuration élargit les possibilités en augmentant ou en diminuant la sensibilité. Les mesures ci dessus sont faites sans tenir compte de cette possibilité, en modifiant l'octet de configuration, la valeur de la capacité mesurable atteint quelques nanofarads.
Le byte de configuration: Sur les picaxes de la série M2, la commande "touch16" a cette forme:
touch16 [config], broche, wordvariable broche désigne la broche utilisée, compatible Touch
wordvariable est la variable 16 bits retournée par la commande
config est optionnel et peut être omis (d'où les crochets). C'est un octet de la forme: %aaabbccc.
Sa valeur par défaut est :%00001001
Sans entrer dans les détails: aaa est un compteur d'oscillations (décroissant de 256 à 32) par défaut: 256
bb est un courant de charge ( croissant: OFF, 0,1µA, 1,2µA, 18µA) par défaut :0,1µA
ccc est un prédiviseur du compteur (de 2 à 256). par défaut 4
La valeur de wordvariable croit linéairement avec la capacité mesurée. Elle n'est jamais nulle, sauf si la capacité provoque le dépassement de la valeur max (65535) . C'est une indication d'erreur de mesure.
Voici un tableau comparatif des effets de ces paramètres, avec une capacité de 100pF
paramètre | valeur retournée |
000 01 001 | 24950 |
| |
010 01 001 | 18820 |
100 01 001 | 12650 |
110 01 001 | 6450 |
111 01 001 | 3360 |
| |
000 10 001 | 5700 |
000 11 001 | 1475 |
| |
000 01 000 | 12510 |
000 01 010 | 50069 |
Remarques :
- Les deux derniers chiffres de la variable retournée sont instables. Il faut diviser cette variable par 100 pour garder les chiffres significatifs.
- La première composante (aaa) est particulièrement intéressante pour adapter la mesure aux sondes utilisées.
L'afficheur LCD utilisé est un LCD standard, muni d'une interface série "maison" (
voir ici), mais il existe aussi des LCD série tout fait.
Le code de cet essai:
'Ex: Sonde de niveau capacitive MM 29/05/2013
;**** calibration de la sonde à la mise sous tension. ***************
;**** La réponse de la comande TOUCH est considérée comme linéaire
;**** La droite est de la forme pct(%) = pente x var1 - Y0 *****
;**** Le sous programme "calib:" mesure deux points arbitraires 0 et 100% *********
;**** Calcule les paramètres pente et Y0 et les met en mémoire ****
;**** Affiche les étapes successives **************
#picaxe 08M2
'****** Nominations variables ********
symbol baud= N4800
;****** variables word *********
symbol pente = w13
symbol mesur = w12
symbol var2 = w11
symbol var1 = w10
symbol valsonde = w9
symbol Y0 = w8
symbol seuil = w7
;******* variables byte ********
symbol cpt = b6 ; compteur
;******* variables bit *********
symbol flag = bit0 ;flag alarme
'******* Nominations ports ***********
symbol valid = pinC.3 ;poussoir de validation
symbol LED = C.0
symbol POTAR = C.4
symbol LCD = C.1
symbol SONDE = C.2
'******* Programme 0 en Temps partagé *******
start0:
pause 200 ' initiation LCD
read 0,word pente, word Y0 ; lecture des paramètres de la droite enregistrée
if pente =0 or valid=1 then gosub calib ; Vers calib: si paramètre nul ou nouvelle calibration
Do 'BOUCLE PRINCIPALE
gosub mesure
gosub calcul
gosub compare
gosub affich
loop
;************** Mesure de la sonde, moyenne sur 10 lectures ***************
mesure:
mesur=0 ;initialisation seuil
for cpt=1 to 10 ;boucle sur 10 valeurs
touch16 SONDE,valsonde ;lecture sonde
valsonde=valsonde/10 ;sup dernier digit
mesur=mesur+valsonde ;moyenne des 10 lectures
next
return
'******** Affichage des valeurs lues ***********
affich:
bintoascii var1,b1,b2,b3,b4,b5 ;décomposition ascii
serout LCD,baud,(254,128,"niveau =",b3,b4,b5, "%") ;envoi LCD série
bintoascii seuil,b1,b2,b3,b4,b5
serout LCD,baud,(254,192,"Minimum =",b3,b4,b5, "%") ;envoi LCD série
return
'********* Comparaison Sonde / Seuil **********
compare:
readadc10 POTAR,seuil ;lecture potentiomètre
seuil=seuil/4 ;max vers 250%
if seuil>var1 then ;comparaison
flag=1 ;flag=1 = allumage led dans start1:
else flag=0 ;led éteinte
endif
return
;******* Calibration, Calcul paramètres, Affichage, Mise en mémoires ***
calib:
do:loop while valid=1 ;attente relachement poussoir
serout LCD,baud,(254,1) ;effacement écran
serout LCD,baud,(254,128, "calibration 0%") ;titre
do
gosub mesure
var1=mesur ;mesure du point 0%
var1=var1/100 ;division par 100, on garde les digits significatifs
bintoascii var1,b1,b2,b3,b4,b5 ;affichage
serout LCD,baud,(254,192,"mesure 0%=",b3,b4,b5) ;pour voir
loop while valid=0 ;attente validation
serout LCD,baud,(254,128,"calibration 100%") ;titre
do:loop while valid=1 ;attente relachement poussoir
do
gosub mesure
var2=mesur ;mesure du point 100%
var2=var2/100 ;division par 100
bintoascii var2,b1,b2,b3,b4,b5
serout LCD,baud,(254,192,"mesure 100%=",b3,b4,b5)
loop while valid=0
if var1>var2 then calib ;erreur de procédure. retour début
var2=var2-var1 ;différence des mesures (déja /100)
pente= 10000/var2 ;delta % (=100 par def) x 100; / par var mesure /100 d'ou pente x 10000
Y0 = var1 * pente ;ordonnée origine d'ou,( % *100 = mesure/100 * pente - Y0 )
do:loop while valid=0
write 0,word pente,word Y0 ;Mise en mémoire EEPROM
serout LCD,baud,(254,1) ;Effacement écran
serout LCD,baud,(254,128, "calibration ") ;affichage
serout LCD,baud,(254,192, "effectu",1,"e ")
pause 3000 ;Temps de lecture
serout LCD,baud,(254,1)
return
;*********** Calcul pourcentage ***********************
calcul:
var1=mesur ;valeur mesurée dans mesure:
var1=var1/100 ;div par 100 (comme d'ab)
var1=var1 * pente ;un bout de l'équation
if Y0>var1 then ;pour éviter de passer du côté obscur
var1=0
else var1=var1-Y0 ;calcul poucentage (en centièmes de pourcents)
endif
var1=var1/100 ;unités de pourcentage
return
;******** Programme 1 en Temps partagé: Signalisation **************
start1:
do ;allumage led
if flag=1 then ;en fonction
high LED ;du
else low LED ;flag
endif
loop