ACS712 5a

Bonjour,

Je cherche à utiliser ma carte arduino Uno comme amperemetre, j'ai donc acheté un ACS712 5a.

Je me suis dis ça va être facile, la mesure de l'arduino ça va être 0 pour -5A et 1023 pour 5A mais pas du tout. (0 et 1023 étant les valeurs du port série).

|500x375

Ce qui me perturbe mentalement c'est qu'en inversant (voir les deux schémas), je pensais avoir 664 + X et que dans l'autre sens (fils inversés), 664 - X. Mais non j'ai 494 pour un et 537 pour l'autre.

Du coup pour écrire un programme je sais pas du tout comment m'y prendre.

Mode opératoire de comment j'ai le tableau ci dessus: Je fais mon câblage. Je mes un ampèremètre metrix PX120. Je relève le courant. Je remplace le metrix par l'arduino et je relève la valeur du port série.

J'aimerais avoir des conseils sur la programmation de ce type de matériel.

Cordialement.

bonjour, regarde la fonction map map(0,1023,-5,5)

Bonjour,

certainement une erreur dans ton programme :

-5A donne 1V5 sur datasheet 5A donne 3V5

donc 10A doivent te donner une difference de 2V soit, en digital, 2/5 de 1023 = +/- 400 et non pas 43 comme dans ton message

Pour faire ton programme :

SI -5A = 300 (par exemple) et SI 5A = 700 (toujours un exemple) alors 10A = 400

tu fais une mesure par exemple 560 tu retires 300 (la valeur pour -5A)

donc tu as un courant egal a 260/400 de 10A soit 6.5 A

tu ajoutes ton offset de -5A et tu trouves 1,5A

Voila pour le principe

Jacques

Le probleme c’est que mon programme c’est ça :

// /////////////////////////////// 1. Entête déclarative ///////////////////////

// --- Déclaration des constantes ---

// --- Inclusion des librairies ---
#include <SPI.h> // Serial Peripheral Interface
#include <SD.h> // crée automatiquement un objet racine SD représentant la carte mémoire SD

const int brocheSDCardSelect=4; // broche utilisée pour sélectionner la SD card

// --- Déclaration des constantes des broches analogiques ---

const int analog0= A0; // Constante pour la broche analogique 0

// --- Déclaration des variables globales ---

float calcul_courant; // Variable de calcul du courant 
float mesure_courant; // Variable d'acquisition de données 

int test; // Variable utilisée pour tester valeur renvoyée par fonctions SD Card

File file; // objet file
File root; // objet root pour le répertoire racine


// ////////////////////////// 2. FONCTION SETUP = Code d'initialisation //////////////////////////
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { 

// ------- Initialisation fonctionnalités utilisées -------  

Serial.begin(115200); // initialise connexion série à 115200 bauds (vitesse de transmission des données)
// IMPORTANT : régler le terminal côté PC avec la même valeur de transmission

//---- initialise l'utilisation de la carte mémoire SD en mode SPI  
pinMode(10, OUTPUT); // met la broche 10 (SS) en sortie (nécessaire avec module ethernet)
digitalWrite(10, HIGH); // mais désactive le  circuit intégré W5100 du module ethernet (on ne peut donc pas utiliser la connexion RJ45 et la carte SD en même temps)

  //--- initialisation de la carte SD ---
  Serial.println("Initialisation de la SD card...");

  pinMode(10, OUTPUT); // laisser la broche SS en sortie - obligatoire avec librairie SD

  test=SD.begin(brocheSDCardSelect); // initialisation de la carte SD avec broche 4 en tant que CS - renvoie true/false

  if (test!=true) { // si initialisation n'est pas réussie
    Serial.println("Echec initialisation!"); // message port Série
  }
  else { // si initialisation réussie
    Serial.println("Initialisation reussie !"); // message port Série

  //--- Affiche le contenu du répertoire ---

  root = SD.open("/"); // ouvre la SD Card à la racine

  Serial.println("Repertoire racine ouvert !");

  } // fin si initialisation réussie

delay(10); // pause rapide pour laisser temps initialisation


} 
// ****************************************************************************************************************

/////////////////////////// 3. FONCTION LOOP = Boucle sans fin = coeur du programme //////////////////

void loop(){
   
  //--- Efface fichier au préalable ---
  test=SD.remove("data.txt"); // efface fichier et mémorise résultat opération  
  if (test) Serial.println("Fichier efface"); // affiche message si fichier bien effacé

  //--- Créer fichier en écriture ---
  file = SD.open("data.txt", FILE_WRITE); // ouvre le fichier en écriture
  // NB : le fichier est créé si il n'existe pas !

  //--- Test si fichier dispo en écriture ---
  if (!file) { // si fichier pas disponible

    Serial.println ("Erreur ouverture fichier !");

  } 

  else { // si le fichier existe et est ouvert

    Serial.println ("Fichier pret pour ecriture !");

    //--- Ecriture dans le fichier au format CSV ---

    // premiere ligne du fichier CSV - entete avec liste des champs
    file.println("NumeroMesure;Courant;Temps");

    Serial.println ("Enregistrement en cours :");
   
    for (int i=0; i<10; i++) { // n mesures CAN  (ici on regle le nombre de valeur que l'on veut acquérir) (c'est dans cette boucle qu'on met les différents programmes pour les capteurs)
  
      // acquisition conversion analogique numérique sur broche analogique indiquée
     // mesure_courant = map(mesure_courant, 0, 1023, -5, 5);  
      mesure_courant = analogRead(A0); 
           
    
      // calcul du courant en Ampere
      
      
      // ici on marque les valeurs qui seront affichées sur le tableau openoffice
      // valeur premier champ
      file.print(i), file.print(';');    
    
      // valeur deuxieme champ
      file.print(mesure_courant), file.print(';');
      
      // valeur troisieme champ
      file.print(millis());
       
      // le dernier champ doit se terminer par un saut de ligne 
      file.println();
      
      delay(1000); 
      if ((i+1)%60) Serial.print("."); else  Serial.println(".");// affiche ligne de 50 points
      
    } // fin boucle for

    file.close(); // ferme le fichier
    Serial.println("Fin enregistrement !");  
    Serial.println("Fermeture fichier !");  

    Serial.println("Retirez SD-Card et la lire sur le PC !");  

  } // fin else

  while(1); // stop loop

} // fin de la fonction loop() - le programme recommence au début de la fonction loop 
// ********************************************************************************
[\code]


Je lis seulement la valeur de la pin A0.
Et quand j'aurais compris comment convertir par exemple 500 correspond à 2A.
Je ferais un calcul.

Sauf que quand il y juste deux fils de branché sur l'arduino (reliés à rien) j'ai 664.
Dans un sens j'ai 494 pour 1.56A et dans l'autre sens 537 toujours pour 1.56A.

Ce qui veut dire que la courbe n'est pas linéaire.
ou alors il y a autre chose dans le programme a mettre que le mesure_courant = analogRead(A0); pour avoir la bonne valeur

y a une balise < code > dans l’éditeur :wink:

Il faut resoudre les problemes dans l'ordre :

  • connecter un multimetre a la sortie du ACS712 et mesurer la tension dans les 3 cas (-1,56A, 0A, 1,56A)

  • connecter un potentiometre lineaire entre GND et 5V, relier le curseur a A0 et enlever de ton programme tout ce qui ne concerne pas la mesure. Afficher sur la console les valeurs mesurees. Connecte ton multimetre sur l'entree A0 pour verifier la correspondance.

  • remplace ton potentiometre par le ACS712 et dis nous comment cela fonctionne.

Ne pas oublier que l'Atmega328 est capricieux pour les mesures analogiques. Il faut bien decoupler l'entree ARef. De meme, cela ne coute rien de laisser tomber la 1ere mesure puis d'en effectuer 5 et d'en faire la moyenne. Une facon comme une autre de lisser les resultats.

Jacques

N.B.:

Sauf que quand il y juste deux fils de branché sur l'arduino (reliés à rien) j'ai 664. Dans un sens j'ai 494 pour 1.56A et dans l'autre sens 537 toujours pour 1.56A.

Ce qui veut dire que la courbe n'est pas linéaire.

J'imagine difficilement la tete de la courbe avec ces mesures ;)

1/ Je mesure entre le GND et le OUT du ACS712 avec un voltmètre j'obtiens : 2.42V => 0A 2.55V => 1.56A => moniteur série : 537 (dans un sens de cablage) 2.28V => 1.56A => moniteur série : 480 (dans l'autre sens de cablage)

2/ je branche un potentiometre de 1kohm (cablage des pin : 5V/A0/GND) Pour 2.55V sur le moniteur série j'ai 537 +/- pas grand chose Pour 2.28V sur le moniteur série j'ai 480 +/- pas grand chose

Mais je ne comprend pas bien ce que va être la suite de ces essais, tu peux m'expliquer stp ?

Voila, maintenant tu connectes ton capteur sur Arduino et tu dois avoir le meme resultat.

Pour convertir, soit tu utilises la fonction MAP ou tu fais le calcul comme explique dans mon premier mail.

Le probleme c'est le manque de dynamique. Le capteur a une plage de capture de 10A pour seulement 2v en sortie entre les courants extremes.

Comme tu n'es interresse que par 1,56 A, dans un sens je presume, tu ne vas pas avoir beaucoup de precision.

Bon courage.

Jacques

non je veux mesurer sur une plage de 0A à 5A et je ne veux pas etre embeté avec le sens de cablage de l'ACS712.

Bonjour, tu as maintenant tout ce qu'il te faut pour finir le projet, le capteur sort la tension esperee et l'Arduino mesure correctement une tension DC. Quelle est l'application sur laquelle tu vas installer le capteur ? La demarche disant je ne veux pas etre embete par le sens du capteur me laisse dubitatif. Jacques

C’est pour faire des mesures de courant en sortie de pont de diode (qui lui même est branché à une génératrice synchrone).

Je termine mes essais de voltmetre avec shield ethernet et afficheur alphanumérique et je fais les essais de l’acs712 comme tu me l’as indiqué et je te tiens au courant (u_U).

Merci pour ton aide.

JMe87:
Bonjour,

certainement une erreur dans ton programme :

-5A donne 1V5 sur datasheet
5A donne 3V5

donc 10A doivent te donner une difference de 2V soit, en digital, 2/5 de 1023 = +/- 400 et non pas 43 comme dans ton message

Pour faire ton programme :

SI -5A = 300 (par exemple) et SI 5A = 700 (toujours un exemple) alors 10A = 400

tu fais une mesure par exemple 560
tu retires 300 (la valeur pour -5A)

donc tu as un courant egal a 260/400 de 10A soit 6.5 A

tu ajoutes ton offset de -5A et tu trouves 1,5A

Voila pour le principe

Jacques

Je comprend comment effectuer ta technique mais le probleme c’est que je ne sais pas comment obtenir les valeurs du port série de -5A et de 5 A. J’ai aucun matériel permettant d’avoir les 5A et les -5A.

Je me suis penché sur la fonction map :

mesure_courant = analogRead(A1);  
calcul_courant = map(mesure_courant,0,1023,-5,5);

Faut-il le mettre comme ça ?
Calcul_courant étant la variable que j’enregistre et que j’affiche, et mesure_courant étant la variable ou je lis les informations (ou il y a les valeurs 0-1023 pour être plus clair).

Quand je fais ça :

// /////////////////////////////// 1. Entête déclarative ///////////////////////

// --- Déclaration des constantes ---

// --- Inclusion des librairies ---
#include <SPI.h> // Serial Peripheral Interface
#include <SD.h> // crée automatiquement un objet racine SD représentant la carte mémoire SD
#include <LiquidCrystal.h> // Inclusion de la librairie pour afficheur LCD


const int brocheSDCardSelect=4; // broche utilisée pour sélectionner la SD card

// --- Broche afficheur alphanumérique ---
LiquidCrystal lcd(9, 6, 5, 4, 3, 2);

// --- Déclaration des constantes des broches analogiques ---

const int analog0= A1; // Constante pour la broche analogique 0

// --- Déclaration des variables globales ---

float calcul_courant; // Variable de calcul du courant 
float mesure_courant; // Variable d'acquisition de données 
char message_courant[16] = ""; //Chaine de caractere pour le courant afficher sur LCD
char message[16] = ""; //chaine de caractere pour afficher i sur l'afficheur LCD
int y,i;

int test; // Variable utilisée pour tester valeur renvoyée par fonctions SD Card

File file; // objet file
File root; // objet root pour le répertoire racine


// ////////////////////////// 2. FONCTION SETUP = Code d'initialisation //////////////////////////
// La fonction setup() est exécutée en premier et 1 seule fois, au démarrage du programme

void setup()   { 

// ------- Initialisation fonctionnalités utilisées -------  

  Serial.begin(115200); // initialise connexion série à 115200 bauds (vitesse de transmission des données)
  // IMPORTANT : régler le terminal côté PC avec la même valeur de transmission

 lcd.begin(16,2); // Initialise le LCD avec 16 colonnes x 2 lignes
  delay(10); // pause rapide pour laisser temps initialisation
  
  //---- initialise l'utilisation de la carte mémoire SD en mode SPI  
  pinMode(10, OUTPUT); // met la broche 10 (SS) en sortie (nécessaire avec module ethernet)
  digitalWrite(10, HIGH); // mais désactive le  circuit intégré W5100 du module ethernet (on ne peut donc pas utiliser la connexion RJ45 et la carte SD en même temps)

  pinMode(10, OUTPUT); // laisser la broche SS en sortie - obligatoire avec librairie SD

  test=SD.begin(brocheSDCardSelect); // initialisation de la carte SD avec broche 4 en tant que CS - renvoie true/false

  if (test!=true) { // si initialisation n'est pas réussie
    lcd.print("Echec");
    lcd.clear();
    delay(10000);
  }
  else { // si initialisation réussie
    lcd.print("Init reussie"); // message port Série
    delay(3000);
    lcd.clear();
    
    //--- Affiche le contenu du répertoire ---
    root = SD.open("/"); // ouvre la SD Card à la racine
    lcd.print("Fichier ouvert");
    delay(3000);
    lcd.clear();
    
  } // fin si initialisation réussie


} 
// ****************************************************************************************************************

/////////////////////////// 3. FONCTION LOOP = Boucle sans fin = coeur du programme //////////////////

void loop(){
   
    test=SD.remove("data.txt");
    //--- Ecriture dans le fichier au format CSV ---
    // premiere ligne du fichier CSV - entete avec liste des champs
    file.println("NumeroMesure;Courant;Temps");
             
    for (int i=0; i<30; i++) { // n mesures CAN  (ici on regle le nombre de valeur que l'on veut acquérir) (c'est dans cette boucle qu'on met les différents programmes pour les capteurs)
  
      // acquisition conversion analogique numérique sur broche analogique indiquée       
      mesure_courant = analogRead(A1);  
      calcul_courant = map(mesure_courant,0,1023,-5,5); 
 
      
      // ici on marque les valeurs qui seront affichées sur le tableau openoffice
      // valeur premier champ
      file.print(i), file.print(';');    
    
      // valeur deuxieme champ
      file.print(calcul_courant), file.print(';');
      
      // valeur troisieme champ
      file.print(millis());
       
      // le dernier champ doit se terminer par un saut de ligne 
      file.println();
          
      //--- Affiche sur l'écran LCD ---
      lcd.setCursor(0, 0); // 1ere col - 1ere ligne - positionne le curseur à l'endroit voulu (colonne, ligne) 
      lcd.print(calcul_courant, DEC);
        
      lcd.setCursor(0, 1); // 1ere col - 2eme ligne
      lcd.print(y, DEC);
      delay(1000); // pause d'1 secondes
         
      file.close(); // ferme le fichier
      
    } // fin boucle for
          
    lcd.clear();
    lcd.print("Fin");
    lcd.setCursor(0, 1); // 1ere col - 2eme ligne
    lcd.print("Retirer SD-Card");
   
  while(1); // stop loop

} // fin de la fonction loop() - le programme recommence au début de la fonction loop 
// ********************************************************************************

Mon afficheur me marque n’importe quoi.

Je suppose qu’en faisant :

calcul_courant = (mesure_courant*1.56)/480;
(un produit en croix)

ça ne marchera pas ?

Autre question pour la broche AREF je la branche au +5V de l'arduino et je marque

analogReference(DEFAULT);

Dans le void setup ();

???

Bonjour,

je t'ai conseille de faire 3 choses, tu fais les 2 premieres puis, tu te lances sur un mega programme.

Une chose a la fois.

Comme conseille, tu enleves ton potentiometre et tu places ton capteur et tu lis les valeurs mesurees sur la console incorporee dans IDE Arduino.

Ensuite, quand cela fonctionne, tu fais le calcul pour avoir un affichage en Amperes.

Puis alors, quand cela fonctionne, tu branches ton LCD ..... puis ta carte SD puis ... ...

Pour faire la conversion valeur mesuree vers A, soit tu cherches un peu et tu utilises ce que je t'ai indique, soit tu utilises la fonction MAP, mais pas les 2

Si tu utilises map, je crois que tu dois remplacer 0 et 1023 par les valeurs correspondant a -5A et 5A.

Si tu as besoin d'un courant de 5A pour faire tes reglages, une batterie de voiture, une ou 2 ampoules et ton Metrix, tu devrais t'en sortir. Attention, si tu utilises une batterie, protection par fusible obligatoire.

Par defaut AREF est relie en interne au VCC soit 5V dans la plupart des cas. Mais rien n'empeche, et je te le conseille, de placer une capa de 100nF entre AREF et GND avec des fils tres courts.

Courage

Jacques

Avec la fonction map j’ai fait

calcul_courant = map(mesure_courant,327,696,-5000,5000);
courant_afficheur=calcul_courant/1000;

Ca marche nickel, mesure avec ampèremètre 2A, mesure avec ACS712 1.8 à 1.9.

Vu que je suis un mec chiant, j’ai un autre petit problème.
Les valeurs fluctues énormément normalement le courant doit être constant 2A +/- 0.1A.
Mais la j’ai la plupart du temps 1.8/1.9A mais j’ai aussi de temps en temps 1.5/1.6/1.7.

Je me demande si c’est pas une histoire d’AREF. Ou peut être autre chose.

JMe87:
Bonjour,

Par defaut AREF est relie en interne au VCC soit 5V dans la plupart des cas.
Mais rien n’empeche, et je te le conseille, de placer une capa de 100nF entre AREF et GND avec des fils tres courts.

Courage

Jacques

Je n’ai pas de capacité de 100nF, est-il possible d’affiner ma mesure ?

de placer une capa de 100nF entre AREF et GND avec des fils tres courts.

Oui mais pas sur Aref du connecteur de la carte !

  1. Il y en a déjà une
  2. elle ne sert à rien puisque la piste est poluée à l’intérieur de la carte.

Il faut souder un condensateur directement sur le support du micro (au dos de la carte).
Le point Aref du micro est juste à coté d’un point GND du micro (voir le brochage du micro dans la datasheet de l’Atmega328p).

Concernant la valeur 100nF c’est une valeur excessivement courante c’est pourquoi elle t-a été proposé.
Une valeur supérieure ira très bien, inférieure il faut faire l’essai.

L’important n’est pas tant la valeur que le matériau du condensateur. Il faut un condensateur céramique.
Quant au format l’idéal est un CMS 0805 mais un condensateur à pattes conviendra avec des fils courts comme il t’a été dit .

Aref_Uno.png

Bonjour,

+1 pour la reponse de 68tjs

si tu me fais parvenir ton adresse privee, tu vas trouver ces capas dans quelques jours dans ta boite aux lettre.

Comme je te l’ai dit plus haut, il est preferable de faire une moyenne de quelques mesures avant de l’afficher.

Jacques

En faisant le câblage indiqué j'ai obtenu des mesures parfaitement stables avec un LM35 situé au bout de 50m de câble ethernet cat5 (adapté sur 100 ohms emission/réception bien sûr). Il n'y a eu besoin d'aucun moyennage.

JMe87: Bonjour,

+1 pour la reponse de 68tjs

si tu me fais parvenir ton adresse privee, tu vas trouver ces capas dans quelques jours dans ta boite aux lettre.

Comme je te l'ai dit plus haut, il est preferable de faire une moyenne de quelques mesures avant de l'afficher.

Jacques

Je suis partie pour moyenner le courant sur 30 valeurs. Ca marche nickel avec une batterie de 12V et un rhéostats. Maintenant j’attends la multiplication pour la génératrice et je fais les essais réels.

68tjs: En faisant le câblage indiqué j'ai obtenu des mesures parfaitement stables avec un LM35 situé au bout de 50m de câble ethernet cat5 (adapté sur 100 ohms emission/réception bien sûr). Il n'y a eu besoin d'aucun moyennage.

Je vais quand même essayer de trouver un capacité dans les cartes électroniques que j'ai.

Ordre d'idée : Premier essai : Amperemetre metrix PX120 indique 0.98A L'ACS 712 indique entre 0.9 et 1A.

Je vais essayer de faire des essais avec 2 batteries 12V en série pour avoir 24V +/- pas grand chose (sachant que ma génératrice+multiplication donnera entre 20 et 25V).

Comme ça je pourrais voir si je suis bon ou pas.

En tous cas merci pour l'aide que vous m'avez donné. Je continuerais a donner des nouvelles du projet. Et j'en suis sur d'autres problèmes arriveront ...