Go Down

Topic: 'Resolu ' mesure de courant et tension (Read 7170 times) previous topic - next topic

Pascal17740

Nov 07, 2017, 12:40 am Last Edit: Nov 13, 2017, 06:11 pm by Pascal17740
 Bonjour, je réalise un test de tension de batterie et de son courant de charge
le test de tension fonction mais pas celui de courant même quand je port a +vcc l entrée analogique le résultat reste a zéro
les declarations de variables sont les suivantes
Code: [Select]

   float vout = 0.0;
      float vin = 0.0;
        float R1 = 30000.0; 
         float R2 = 7500.0;
            int tensBat = 0.0;
              int ANA0 =0;
                int ANA1 = 1;
                  int ANA2 = 2;
    float ICconso = 0.0; float ICcharge =0.0; float average=0.0;

et les fonctions
Code: [Select]

 void test_bat() {
  tensBat = analogRead(ANA2);
       vout = (tensBat * 5.0) / 1024.0; // see text
        vin = vout / (R2/(R1+R2));Serial.print(vin,1);
   if ((vin <= 12.0))
  {
  batcharge=true;
  }
 if (vin>14)
  {
 batcharge=false;
  }
   if (batcharge || cmdBat)
   {
   digitalWrite(BATCHARGE,LOW); batcharge2=true;
   }
    else
   {
   digitalWrite(BATCHARGE,HIGH);batcharge2=false;
   }
  }
  void test_courant(){
   for(int i = 0; i <3000; i++)
    // average = average + (.0264 * analogRead(ANA0) -13.51) / 1000; //ACS712 5 Ampères
    average = average + (.049 * analogRead(ANA0)-25)/1000;//ACS712 20 Ampères
    Serial.print(average);delay(1);
}

affichage tension ok courant 0.0

Leptro

Je pense que le problème vient de la formule :
Code: [Select]
average = average + (.049 * analogRead(ANA0)-25)/1000;//ACS712 20 Ampères

ce capteur de courant fourni effectivement 185mv/A , il suffit de mesurer la tension en sortie du capteur soustraire les 2.5V si nécessaire et faire la transposition.






Pascal17740

Je pense que le problème vient de la formule :
Code: [Select]
average = average + (.049 * analogRead(ANA0)-25)/1000;//ACS712 20 Ampères

ce capteur de courant fourni effectivement 185mv/A , il suffit de mesurer la tension en sortie du capteur soustraire les 2.5V si nécessaire et faire la transposition.


Non le probleme ne viens pas de la formule si je force l entee analogique a +vcc c 'est a dire 5 volts  je n'ai toujour pas de resultat autre qu e 0.0

ChPr

Le problème vient bien ce cette ligne :

Code: [Select]
average = average + (.049 * analogRead(ANA0)-25)/1000;//ACS712 20 Ampères

Remplacez la valeur 1000 par 1000.0

Ça devrait mieux aller.

Cordialement.

Pierre
Pourquoi faire simple alors qu'il est si facile de faire compliqué !

Pascal17740

Le problème vient bien ce cette ligne :

Code: [Select]
average = average + (.049 * analogRead(ANA0)-25)/1000;//ACS712 20 Ampères

Remplacez la valeur 1000 par 1000.0

Ça devrait mieux aller.

Cordialement.

Pierre
Non le probleme ne viens pas de la formule si je force l entee analogique a +vcc c 'est a dire 5 volts  je n'ai toujour pas de resultat autre qu e 0.0
je viens de corriger la formule

Leptro

si tu force la pin analogue à 5V   analogread retournera 1023.
EN mettant 1023 dans ta formule tu obtiens 0.025  Iccharge sera égale à 0.0 (float icharge=0.0);

pour le test n'applique pas la formule et affiche la valeur issue de analogread.

A+

J-M-L

#6
Nov 08, 2017, 05:55 am Last Edit: Nov 08, 2017, 06:04 am by J-M-L
Le problème vient bien ce cette ligne :
Code: [Select]
average = average + (.049 * analogRead(ANA0)-25)/1000;//ACS712 20 Ampères
Remplacez la valeur 1000 par 1000.0
Ça devrait mieux aller.
Non car il y a déjà un .049 et la variable average qui fait basculer tout le calcul en flottant


Essayez un
Code: [Select]
Serial.print(average, 6); pour avoir un affichage avec 6 chiffres après la virgule (et tant que vous y êtes déclarez les pins en const byte Plutôt qu'en int utiliser A0 plutôt que 0 (même si ça marche ça rend le code plus explicite et évite de se tromper de pin si vous faites un digitalRead dessus) et appuyez sur ctrl-T dans l'éditeur pour indenter correctement ce code)
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

ChPr

#7
Nov 08, 2017, 08:33 am Last Edit: Nov 08, 2017, 08:34 am by ChPr
Non car il y a déjà un .049 et la variable average qui fait basculer tout le calcul en flottant  ...
C'est vrai. Je croyais que la valeur la plus extérieure (1000) donnait le ton. Mais bon, je serai toujours surpris par les subtilités du C.

Pour autant, j'ai essayé votre formule avec un simple Serial.println(average) et en remplaçant la lecture analogique par 1023 : on affiche bien une valeur ... qui plus est, croit avec le temps et tend vers l'infini..

Votre problème vient de la lecture analogique.

Par ailleurs, votre formule décrit le comportement d'un intégrateur.

Pour qu'elle se comporte comme un filtre passe-bas, il faut l'écrire ce cette façon :

Code: [Select]
average = A * average + B * nouvelle_lecture

avec A + B = 1. Par exemple, A = 0.9 et B = 0.1.

Plus le rapport A / B sera grand, plus le filtrage sera efficace mais plus le résultat sera long à obtenir.

Cordialement.

Pierre
Pourquoi faire simple alors qu'il est si facile de faire compliqué !

aligote

#8
Nov 08, 2017, 09:10 am Last Edit: Nov 08, 2017, 06:14 pm by aligote
Bonjour,

J'utilise un capteur d'intensité (+-5A)et tout se passe bien.

J'ai toujours un peu de difficulté à lire le code écrit par une autre personne.

Quelques remarques :

- La valeur 2,5V (donc 512 comme valeur après conversion A/D) est indicative pour la valeur de tension obtenue dans le cas d'intensité nulle. Perso je stocke dans une variable offset la valeur mesurée au démarrage du programme, valeur qui est ensuite retranchée au résultat de la conversion A/D.
- Pour mes mesures, me suis méfié des priorités des opérations pour le compilateur entre les int et les float. De ce fait je fais un affichage préalable du résultat (valeur analogique- offset) avant de multiplier par une valeur de calibre qui sera un float.

Code corrigé

Code: [Select]


int Calibre_I=97;


void AFFICHE_INTENSITE(byte x, byte y)
{Intensite=analogRead(IntensitePin);
  if (Intensite>Offset_I)
     Intensite=Intensite-Offset_I;
    else Intensite=0;
 if (Intensite==1) Intensite=0;
 lcd.setCursor(x,y);
 lcd.print(0.1*Calibre_I*Intensite/200,1);lcd.print(" A ");
}



Serge .D

J-M-L

#9
Nov 08, 2017, 10:31 am Last Edit: Nov 08, 2017, 03:53 pm by J-M-L
Bonjour,

J'utilise un capteur d'intensité (+-5A)et tout se passe bien.

J'ai toujours un peu de difficulté à lire le code écrit par une autre personne.

Quelques remarques :

- La valeur 2,5V (donc 512 comme valeur après conversion A/D) est indicative pour la valeur de tension obtenue dans le cas d'intensité nulle. Perso je stocke dans une variable offset la valeur mesurée au démarrage du programme, valeur qui est ensuite retranchée au résultat de la conversion A/D.
- Pour mes mesures, me suis méfié des priorités des opérations pour le compilateur entre les int et les float. De ce fait je fais un affichage préalable du résultat (valeur analogique- offset) avant de multiplier par une valeur de calibre qui sera un float.

Code: [Select]


int Calibre_I=97;


void AFFICHE_INTENSITE(byte x, byte y)
{Intensite=analogRead(IntensitePin);lcd.setCursor(x,y);
 if (Intensite>Offset_I)
     Intensite=Intensite-Offset_I;
    else Intensite=0;
 if (Intensite==1) Intensite=0;
 lcd.print(0.1*Calibre_I*Intensite/200,1);lcd.print(" A ");
}



Serge .D

il ne vous manque pas un lcd.setCursor(x,y); dans votre fonction? (juste une remarque en passant :) )


EDIT: NON, il me manque mes lunettes :)
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

68tjs

#10
Nov 08, 2017, 01:36 pm Last Edit: Nov 08, 2017, 01:43 pm by 68tjs
Bonjour,

Plusieurs points m'interpellent dans ce sujet :
1) Pourquoi un moyennage ?
Souvent un moyennage sert à cacher la poussière sous le tapis. L'origine des perturbations étant le plus souvent un câblage brouillon non adapté.
Il faut relier la sortie du capteur à l'entrée de mesure analogique avec une paire torsadée. Un fil de la paire torsadée sera le signal, l'autre sera la masse. C'est très important de transporter les signaux ainsi, le fil relié à la masse est très important c'est lui qui apportera une immunité aux bruits ambiants.
S'il subsiste du bruit (provenant du capteur) il faut placer un filtre passe bas pour couper le bruit qui est HF.
Le filtre le plus simple est un filtre RC. La résistance en série avec le fil, au plus près de l'entrée analogique, le condensateur entre l'entrée analogique et la masse.
Valeurs de départ R = 10k , C= 100nF à 1µF
Remarque :
mathématiquement le moyennage est un filtre passe bas.
physiquement : un filtre "vire" les bruits et les empêche de pénétrer dans le  le micro.

2) Si on veut un moyennage c'est qu'on veut de la précision et là il y a des trous dans la raquette.
A) Cela m'étonnerait que la tension Vcc fasse 5,0000 V. Si le Vcc vient de l'USB c'est 5V +/- 5% soit  entre 4,75V et 5,25V, sinon la dispersion sera celle du régulateur interne..
B) Tous les circuits intégrés ont de la dispersion, cela m'étonnerai que le 2,5V théorique soit exactement égal à Vcc/2 parce cette tension vient d'un circuit de polarisation interne au circuit et donc va aussi dépendre de sa tension d'alim Vcc.

Pour moi toutes  ces valeurs doivent être mesurées et ne doivent pas être gravées "en dur" dans le source du programme.

Si l'utilisation est unique on peut utiliser des "defines"
#define Vcc 4.89
#define Vo 2.515
L'adaptation aux valeurs réelles sera simple à faire.

Si le programme doit être distribué à l'identique sur plusieurs postes c'est le moment d'utiliser l'EEPROM du micro pour y charger les valeurs exactes que le programme viendra lire au démarrage.

Remarque sur les cartes :
Si c'est une UNO l'implantation de la piste Aref est tellement mauvaise qu'il est impossible de faire des mesures correctes en l'état. Sur les forum on en est même à un point où les fervents arduinistes trouvent normal d'être obligés de faire un moyennage !
Il faut souder un condensateur de 100 nF au dos de la carte ,sur le support entre les pins  gnd et Aref du micro.
Attention pattes très courtes pour le condo ou mieux un cms format 0805. Et la mesure gagnera immédiatement en stabilité.

Si c'est une nano le problème est sur la tension Vcc.
Si la carte est alimentée par Vin, avec 9V par exemple, Vcc sera peu dispersé --> dispersion du régulateur de tension.
Si c'est par l'USB ce pourra être vite la catastrophe !
1) 5V USB à +/-5% ( 4,75V<Vcc< 5,25V
2) Il y a une diode Schottky entre le Vcc USB et le Vcc micro.  --> chute de tension imprécise d'environ 0,3 à 0.5V qui en plus dépend de la consommation. Et cerise sur le gâteau dispersion de cette chute de tension en fonction de la température.

Au final par l'USB on peut s'attendre à avoir un Vcc compris entre 4,25 V et 4,95 V plus dispersion en température.

Moralité : bien réfléchir avant d'annoncer des résultats avec des chiffres après la virgule.

aligote

il ne vous manque pas un lcd.setCursor(x,y); dans votre fonction? (juste une remarque en passant :) )
Il me semble que celui de la 1ere ligne de la fonction doit suffire ?

Serge .D

J-M-L

#12
Nov 08, 2017, 03:30 pm Last Edit: Nov 08, 2017, 03:43 pm by J-M-L
Il me semble que celui de la 1ere ligne de la fonction doit suffire ?

Serge .D
quoi, vous voulez dire que j'ai encore oublié mes lunettes?

ah oui... :)

(pour ma défense: généralement on mets 1 unité cohérente d'expressions par ligne. Donc pour ma part une lecture analogique et un positionnement sur le LCD devraient être sur 2 lignes séparées, c'est pour cela que je ne l'ai pas vu...  :smiley-roll-sweat:  :smiley-roll-sweat: )
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

kamill

(pour ma défense: généralement on mets 1 unité logique de commande par ligne. Donc pour ma part une lecture analogique et un positionnement sur le LCD devraient être sur 2 lignes séparées, c'est pour cela que je ne l'ai pas vu...
Bonjour,

Moi j'ajouterais que cette instruction n'a rien à faire avec la lecture analogique et qu'elle devrait se trouver juste avant le print. Il faut quand même un minimum de rigueur quand on écrit un programme sinon c'est une grosse source d'erreur.

J-M-L

gros +1 avec @68tjs - c'est aussi pour cela qu'il est bon d'utiliser des capteurs numériques plutôt que analogique. au moins on n'est pas dépendant de la conception de l'arduino pour la lecture
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Go Up