View  Edit  Attributes  History  Attach  Print  Search

ACCUEIL | ARDUINO > S'INSTALLER > DEBUTER > APPROFONDIR | PROCESSING | MECATRONIQUE | MATERIEL | OUTILS | TESTS | Plus...|
Python > Shell > ATELIERS Python + Qt > PyQt apps > PyQt+Arduino | Mes Robots | RepRap | Mes lib'Arduino | Mes shields Arduino | Mes distros | Les Mini-PC |
ATELIERS ARDUINO| VIDEOS | COMPRENDRE | REFERENCES | CODER | TECHNIQUE | GNU/LINUX | LIENS | Rien à voir |

Mesure d'une intensité à l'aide du capteur de courant +/-5A ACS714 (affichage graphique Processing)

Par X. HINAULT - Page créée le : 22/6/2011.

(cliquer sur l'image pour agrandir)

1.  Présentation

Utilisation d'un capteur analogique de courant +/-5A pour mesurer une intensité. Le résultat est envoyé sous forme brute sur le port série pour affichage dans une interface Processing.

Ce programme utilise les fonctionnalités suivantes :

  • Utilise la connexion série vers le PC
  • Utilise la conversion analogique numérique 10 bits

Ressources utiles associées à ce programme :

  • La librairie Serial - pour les communications séries entre la carte Arduino et l'ordinateur ou d'autres composants

2.  Matériel Nécessaire

2.1  L'espace de développement Arduino

  • ... pour éditer, compiler le programme et programmer la carte Arduino.

2.2  Le matériel suivant pour réaliser le montage associé

Acheté ici ( 9 Euros TTC seulement !) : http://www.watterott.com/en/ACS714-Current-Sensor-Carrier-5-to-5A
Une carte de chez Pololu : http://www.pololu.com/catalog/product/1187
Fiche technique (datasheet)du CI ACS714 : Datasheet du capteur ACS 714 - fabricant Allegro Existe en version +/- 30A

3.  Instructions de montage

  • La connexion série vers le PC utilise les broches 0 et 1 (via le câble USB)
  • Broche 14 : Sortie analogique du capteur de courant

4.  Le schéma théorique du montage

Le schéma théorique du montage (cliquer pour agrandir)

5.  Le circuit du montage

Le schéma du montage à réaliser (cliquer pour agrandir)

6.  Explication du programme

  • Le programme Arduino envoie la valeur brute de la conversion analogique numérique sur le port série, sous forme d'une chaine de caractères reconnue par l'interface Processing.
  • Toutes les n mesures, la valeur moyenne est également envoyée sur le port série sous forme d'une autre chaîne de caractères, pouvant être utilisée pour réaliser du datalogging sans surcharger la quantité de données (pas la peine de mémoriser une valeur de l'intensité : la valeur moyenne sur 1 minute pourra suffire par exemple)
  • Le délai entre chaque mesure est fixé par le programme Arduino.
  • Cette valeur est reçue par l'interface Processing pour affichage graphique.

7.  Mise en oeuvre du programme

7.1  Préparation du montage et programmation de la carte Arduino :

  • Commencer par réaliser le montage indiqué sur plaque d'expérimentation
  • Ensuite, programmer la carte Arduino avec ce programme (en bas de page) selon la procédure habituelle

7.2  Fonctionnement

  • Lancer l'interface Processing : la valeur de l'intensité s'affiche ainsi que la courbe de la mesure.

(cliquer sur l'image pour agrandir)

  • L'exemple ci-dessus montre le résultat lors de la mise sous tension puis de l'extinction d'une carte mère mini-ITX (PC) : l'intensité passe par un pic à 2200mA puis ondule autour de la position médiane de 1600mA et rechute à 0 lors de l'extinction. Ce type de graphe est très utile pour bien visualiser ce qui se passe, et ce avec une simple carte Arduino et ce capteur de courant.

8.  Le programme complet en langage Arduino

A copier/coller directement dans l'éditeur Arduino


// --- Programme Arduino ---
// par X. HINAULT - 06/2011

// --- Que fait ce programme ? ---
/* Affiche le résultat brut d'une conversion analogique numérique sur la fenêtre terminal du PC
Réalise la moyenne de n mesure et envoie le résultat vers le PC sous la forme moyenne=valeur=fin
*/


// --- Fonctionnalités utilisées ---
// Utilise la connexion série vers le PC
// Utilise la conversion analogique numérique 10bits sur les voies analogiques  analog 0,

// --- Circuit à réaliser ---
// Connexion série entre la carte Arduino et le PC (utilise les broches 0 et 1)  

// Broche Analog 0 (=broche 14) en entrée Analogique  : connecter la sortie d'une résistance Variable 10K elle-même connectée entre 0 et 5V

//**************** Entête déclarative *******
// A ce niveau sont déclarées les librairies, les constantes, les variables...

// --- Inclusion des librairies utilisées ---

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

// --- constantes des broches ---

const int Voie_0=0; //declaration constante de broche analogique

// --- Déclaration des variables globales ---
int mesureBrute=0;// Variable pour acquisition résultat brut de conversion analogique numérique

float moyenneMesure=0; // moyenne mesure
float nbMesure=60; // nombre de mesures

long millis0; // variable mémorise
long delai=250; // delai entre 2 mesures en millisecondes

int comptMesure=0; // variable comptage nombre mesures

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

//**************** 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()   { // debut de la fonction setup()

// --- ici instructions à exécuter au démarrage ---

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


millis0=millis(); // mémorise millis() courant


} // fin de la fonction setup()
// ********************************************************************************

//*************** FONCTION LOOP = Boucle sans fin = coeur du programme *************
// la fonction loop() s'exécute sans fin en boucle aussi longtemps que l'Arduino est sous tension

void loop(){ // debut de la fonction loop()

// --- ici instructions à exécuter par le programme principal ---

if (abs(millis()-millis0)>delai) { // si plus de delai millisecondes écoulées - utilise abs() pour éviter bug lors overflow millis()

  millis0=millis()-1; // mémorise millisec() courante avec correction -1 mmillis

  // acquisition conversion analogique-numerique (CAN) sur la voie analogique
  mesureBrute=analogRead(Voie_0);
  comptMesure=comptMesure+1;

  // affiche valeur numerique entière ou à virgule au format décimal
//  Serial.print(millis0), Serial.print(":");
//  Serial.print(comptMesure), Serial.print("=");

  Serial.print("CAN=:"),Serial.print(mesureBrute), Serial.println(":=finCAN");

  moyenneMesure=moyenneMesure+mesureBrute;

  if (comptMesure>=nbMesure) { // si le nombre de mesure voulu est effectué

    moyenneMesure=moyenneMesure/comptMesure;
  Serial.print("MOY=:"),Serial.print(mesureBrute), Serial.println(":=finMOY");

    // RAZ variables utiles moyenne
    comptMesure=0;
    moyenneMesure=0;

  }

  //delay(5); // fixe une pause entre 2 mesures
  // plus le délai est court, plus la trace est rapide

  }

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

// --- Fin programme ---

9.  Le programme Processing

9.1  Description

  • Le programme reçoit la valeur en provenance du port série et affiche le résultat sous forme graphique.
  • La valeur de l'intensité est calculée et affichée.

9.2  Le programme complet en langage Processing

A copier/coller directement dans l'éditeur Processing


// Programme processing
// généré avec le générateur de code Processing
// X. HINAULT - Juin 2011 - tous droits réservés

/////////////// Description du programme ////////////
// Utilise le port Serie
// Utilise une police texte

/////////////// ENTETE DECLARATIVE ////////////

// inclusion des librairies utilisées

import processing.serial.*; // importe la librairie série processing

// déclaration objets

// --- port Série ---
Serial  myPort; // Création objet désignant le port série

// --- police texte ---
PFont fontA; // crée un objet de police texte

// déclaration variables globales
 int xPos = 1;         // variable abscisse  - x
 int xPos0=1;       // variable mémorisation xPos n-1

float yPos=1;  // variable yPos - ordonnée
float yPos0=1; // variable yPos n-1

 int xTextPos=50; // variable position texte dans la fenêtre
 int yTextPos=50;


/////////////// Fonction SETUP ////////////

void setup(){ // fonction d'initialisation exécutée 1 fois au démarrage

        // ---- initialisation paramètres graphiques utilisés
        colorMode(RGB, 255,255,255); // fixe format couleur R G B pour fill, stroke, etc...
        fill(0,0,255); // couleur remplissage RGB
        stroke (0,255,0); // couleur pourtour RGB
        strokeWeight(1); // largeur du trait en pixels
        rectMode(CORNER); // origine rectangle coin sup gauche

        // --- initialisation fenêtre de base ---
        //size(200, 200); // ouvre une fenêtre xpixels  x ypixels
         size(int(screen.width*0.6), int(screen.height*0.6));        
        // 90% de l'écran par défaut - régler au besoin -
        // viser taille maxi en hauteur - taille fenêtre (x,y)

        background(0,0,0); // fond fenetre en noir

// --- initialisation des fonctionnalités utilisées ---

        //------------- initialisation de la police texte - à mettre avant série ----
        fontA = loadFont("ArialMT-20.vlw"); // charge le fichier police dans l'objet police texte
        // ce fichier doit être présent dans un rép <data> dans le répertoire du programme
        // pour générer un fichier de police à partir des polices système aller dans Tools > create Fonts
        // voir également http://processing.org/learning/text/

        textFont(fontA, 20); // Initialise la police et sa taille (en pixels)




        //------------- initialisation port série ----
        println(Serial.list()); // affiche dans la console la liste des ports séries
        myPort = new Serial(this, Serial.list()[0], 115200); // Initialise une nouvelle instance du port Série
        //myPort = new Serial(this, "/dev/ttyACM0", 115200); // Initialise une nouvelle instance du port Série
        myPort.bufferUntil('\n'); // attendre arrivée d'un saut de ligne pour générer évènement série

         //------- tracé initial ---------

        traceInitial();

    } // fin fonction Setup

/////////////// Fonction Draw ////////////

void  draw() { // fonction exécutée en boucle


        // while(true); // stoppe boucle draw

} // fin de la fonction draw()

/////////////// Autres Fonctions ////////////

        //------------- Fonction de gestion des évènements série ----
         void serialEvent (Serial myPort) { // fonction appelée lors de la survenue d'un évènement série

        // ******** Gestion de la valeur reçue sur le port série : **********

        String inString = myPort.readStringUntil('\n'); // chaine stockant la chaîne reçue sur le port Série
        // saut de ligne en marque de fin

        if (inString != null) { // si la chaine recue n'est pas vide


                // chaine atendues au format CAN=:valeur:=fin ou MOY=:valeur:=fin

                String[] inSubstring = split(inString, ':'); // extrait les éléments séparés par :

                 println(inSubstring[0]); // debug

                int nombreVoies=1;

                //--- déclaration tableaux utiles
                int[] inByteInt= new int[nombreVoies]; // tableau pour valeur reçue en valeur numérique entiere
                float[] inByteFloat= new float[nombreVoies]; // tableau pour valeur reçue en valeur numérique décimale

                //---- extraction des valeurs de CAN à partir de la chaine
                for (int i=0; i<nombreVoies; i++) {

                     print("Valeur = "+ inSubstring[i+1]); // debug

                     inByteInt[i]=int(inSubstring[i+1]); // conversion valeur reçue en valeur numérique entiere
                     print( " soit en valeur entière : " + inByteInt[i]); // debug

                     inByteFloat[i]=float(inSubstring[i+1]); // conversion valeur reçue en valeur numérique décimale
                     print( " soit en valeur décimale : " + inByteFloat[i]); // debug

                     println("");
                }

                  println(inSubstring[nombreVoies+1]); // debug - chaine de fin de chaine

           //----- gestion du la chaine CAN=:valeur:=fin ----
           //---- affichage en continu de la valeur reçue ---
           if ((match(inSubstring[0],"CAN=")!=null) && (match(inSubstring[nombreVoies+1],"=finCAN")!=null)) { // si la chaine reçue est valide  

                  println("La chaine CAN reçue est valide ! "); // debug


                //inString = trim(inString); // enlève espace blancs de la chaine recue
                int inByte_brut=int(inSubstring[1]); // conversion valeur reçue en valeur numérique entiere
                float inByte = float(inSubstring[1]); // conversion valeur reçue en valeur numérique décimale

                // ré-échelonne la valeur pour affichage
                 inByte = map(inByte, 0, 1023, 0, height);

                 yPos=inByte; // l'ordonnée est la valeur reçue par le port série

                //********** affichage numérique de la valeur reçue et autres calculs *****

                 //---- calcul de la tension à afficher --------
                 float tension=float(inByte_brut);
                 tension=tension*5000;
                 tension=tension/1023;

                 float intensite=tension-2500;
                 intensite=1000*intensite/185; // le capteur a une sensibilité de 185mV/A

                // dessin d'un rectangle sous le texte avant affichage pour effacer texte précédent
                 fill(0,0,0); // couleur de remplissage idem fond
                 stroke(255,0,0); // fixe la couleur utilisée pour le tracé en RVB
                 rect(40, 20, 200, 50);

                  // Use fill() to change the value or color of the text
                  fill(255,0,0);
                  text("         ", xTextPos, yTextPos); //efface la valeur précédente
                  //text(inByte_brut, xTextPos, yTextPos);
                 text(intensite+" mA", xTextPos, yTextPos);

                //*********** gestion du graphique *********

                 // trace la ligne
                 stroke(0,255,255); // fixe la couleur utilisée pour le tracé en RVB
                 strokeWeight(3); // largeur du trait en pixels


                 line (xPos0,height-yPos0,xPos,height-yPos); // trace une ligne en tenant compte valeur reçue

                 xPos0=xPos; // mémorisation xPos n-1
                 yPos0=yPos; // mémorisation xPos n-1

                 // à la fin de l'écran revient au début
                 if (xPos >= width) {
                   xPos = 0;
                   xPos0=0; // pour retour de la trace sans ligne

                   background(0,0,0); // couleur du fond


        //------- tracé initial ---------

        traceInitial();

              }  // fin RAZ graphique

                 else {
                 // incrémente la position horizontale (abscisse)
                 xPos++;
                  }


           } // ------------- fin gestion de la chaine CAN=:val:=fin


           //----- gestion du la chaine MOY=:valeur:=fin ----
           if ((match(inSubstring[0],"MOY=")!=null) && (match(inSubstring[2],"=finMOY")!=null)) { // si la chaine reçue est valide  

                  println("La chaine MOY reçue est valide ! "); // debug

           }

        } // fin condition chaine recue pas vide


} // fin de la fonction de gestion des évènements Série


void traceInitial() {

        fill(0,255,0); // couleur remplissage RGB
        stroke (0,255,0); // couleur pourtour RGB
        strokeWeight(1); // largeur du trait en pixels

        for (int i=0; i<5; i++) {

          line (0,height-((height/5)*i), width-1,height-((height/5)*i));
          text(i+"V", 5, height-((height/5)*i)+25);
        }

        stroke (255,255,0); // couleur pourtour RGB
        strokeWeight(3); // largeur du trait en pixels
        fill(255,255,0); // couleur remplissage RGB

        // --- ligne niveau logique bas = 0.3 x Vcc pour carte Arduino (ATmega328) ----
        text("Niveau BAS", 5, (height-(0.3*height)-5));
        line (0,(height-(0.3*height)), width-1,(height-(0.3*height)));

        // --- ligne niveau logique haut = 0.6 x Vcc pour carte Arduino (ATmega328) ---
        text("Niveau HAUT", 5, (height-(0.6*height)-5));
        line (0,(height-(0.6*height)), width-1,(height-(0.6*height)));  
}