'Resolu ' mesure de courant et tension

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

   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

 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

Je pense que le problème vient de la formule :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.

Leptro:
Je pense que le problème vient de la formule :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

Le problème vient bien ce cette ligne :

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

Remplacez la valeur 1000 par 1000.0

Ça devrait mieux aller.

Cordialement.

Pierre

ChPr:
Le problème vient bien ce cette ligne :

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

domo_08_11_17.ino (55.9 KB)

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+

ChPr:
Le problème vient bien ce cette ligne :

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 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)

J-M-L:
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 :

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

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é

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

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.
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.1Calibre_IIntensite/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 :slight_smile: )

EDIT: NON, il me manque mes lunettes :slight_smile:

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.

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

Il me semble que celui de la 1ere ligne de la fonction doit suffire ?

Serge .D

aligote:
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... :slight_smile:

(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... :cold_sweat: :cold_sweat: )

J-M-L:
(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.

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

il est bon d'utiliser des capteurs numériques plutôt que analogique

Pas pour moi :grin: Le numérique ce n'est pas drôle.

Plus sérieusement oui sans connaissance particulière, et on ne peut pas tout connaître, les capteurs numériques posent moins de difficulté de mise en œuvre.

Mais, il y a toujours un mais, même avec un capteur numérique on peut être ennuyé avec des problèmes analogiques comme on le voit de temps en temps sur ce forum avec des connexion de l'ordre de plusieurs mètres.
Dès que les longueurs de câble ne sont plus négligeables on tombe dans l'analogique pur et là cela se gâte.
Les signaux sont numériques oui, mais le transport des signaux est analogique.

Ce que j'aimerai que l'on retienne de ce que j'ai écrit c'est que les composants électroniques ne sont des trucs théoriques mais des êtres réels avec leur défauts. Les datasheet donnent le plus souvent des valeurs centrées qui sont le résultat d'une moyenne.
Un montage électronique cela se mesure USB = 5V c'est du rêve, chaque PC fourni une valeur différentes et même à l'intérieur d'un même PC selon le module USB il peut y avoir des différences.
On est dans la vrai vie, en électronique on ne peut jamais écrire U = 4,352 V mais U = 4,325 V +/- x mV

68tjs:
Ce que j'aimerai que l'on retienne de ce que j'ai écrit c'est que les composants électroniques ne sont des trucs théoriques mais des êtres réels avec leur défauts. Les datasheet donnent le plus souvent des valeurs centrées qui sont le résultat d'une moyenne.

tout à fait OK

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

Ajouter aussi pour compléter le tableau que la précision de ce genre de capteur de courant n'est pas non plus si grande que cela :

Par exemple une erreur de 2% pour le capteur à pleine échelle représente 20 unités sur le résultat de la conversion A/D sur 10 bits.

Serge .D

Capture.PNG

bonsoir,
je n ai toujours pas des solution a mon probleme il doit y avoir un probleme d 'ecriture dans le code non en rapport avec l ' equation ....
je suis dans le neant C tique....

Pascal17740:
bonsoir,
je n ai toujours pas des solution a mon probleme il doit y avoir un probleme d 'ecriture dans le code non en rapport avec l ' equation ....
je suis dans le neant C tique....

qu'avez vous fait pour débugger?

postez tout le code et dites nous ce que vous voyez comme valeur de analogRead dans votre fonction... avez vous fait le Serial print?