Go Down

Topic: [Conseil] Projet sur Arduino Due, multimètre spécial (Read 2264 times) previous topic - next topic

alex34000

Disposer d'une meilleure résolution ne signifie absolument pas que les mesures soient plus précises, c'est-à-dire entachées de moins d'erreurs.

Une meilleure résolution s'avère très utile pour certaines applications. Mais ce que réclame la tienne, c'est surtout une bonne précision absolue.

Bien évidemment, cela nécessite à la base une résolution suffisante, mais il est également nécessaire que les circuits internes et externes présentent une qualité en rapport avec le résultat souhaité. Or, l'intégration d'un convertisseur à un microcontrôleur impose énormément de contraintes, et en limite par conséquent les performances sur les modèles de basse et moyenne gammes.
message reçu. Néanmoins il doit être possible avec ce dont je dispose, de faire un programme et un circuit qui me permettrai d'avoir un résultat plutôt efficace non ? ils ne m'auraient tout de même pas lancer sur un projet comme celui ci pour que j'arrive et que je leurs dise "non c'est pas possible à faire avec ce que j'ai sous la main" ?

Je sais qu'en entrée j'ai des ponts diviseurs (que je ferais moi même) pour abaisser la tension à un seuil respectable pour la carte (ne pas dépasser le 3.3V) donc si je sais que en entrée, un +6V équivaux à un +3V ou +2.5V après un pont diviseur, les valeurs de références que j'utilise dans mon programme ne serons pas erroné si je ne me trompe pas et la précision de ma mesure sera... Intéressante, non ?

Tu peux placer analogReadResolution(12); dans le setup(). Inutile de le refaire  à chaque boucle.
Fais, merci !

alex34000

Merci _pepe_ pour tout ce que tu m'a dit, j'en prend note et je vais faire mes recherche, je reposterai ici au besoins ;)

Merci à toi aussi dfgh pour le code, je vais le tester et voir ce qui me plait de garder ou non, en tout cas merci pour ce que tu a fais.

Merci à tous les autres pour les informations, les discutions et échanges très intéressant qu'il y a eu.

Je continuerai a poster si j'ai des choses que je ne comprend pas mais je vais pour le moment m'atteler à voir tout ce que vous avez pu me dire, et dans un second temps à m'occuper du contrôle de port numériques par la console, ce qui sera au moins une chose compatible si jamais je doit me servir d'un convertisseur externe à la carte.

68tjs

Juste un point complémentaire.

Je ne connais pas la carte DUE ni son micro-contrôleur mais j'ai une expérience de la UNO.
Les cartes conçues par Arduino sont mal implantées pour une usage analogique. Clairement l'analogique ce n'est pas leur truc.

J'avais à l'époque grandement amélioré les performances de la carte UNO en ajoutant un condensateur de découplage au niveau de la patte Aref du micro  et non pas le AREF du connecteur de la carte.

Les schémas d'implantation de la Due sont disponibles. Si le micro de la DUE comporte un accès pour une référence de tension externe  et si la mesure est bruitée (instable) tu aura tout intérêt à voir si simplement en posant un condensateur de 100 nF entre l'entrée réf externe et la masse n'améliore pas la mesure.
J'insiste : je ne connais pas la DUE, je signale juste le fait.

alex34000

#18
Jun 14, 2016, 08:51 am Last Edit: Jun 14, 2016, 09:01 am by alex34000
j'ai fais ce que tu m'a dit, étrangement, ça a marché (les valeurs son fixe et ne varie plus constamment, enfin très légèrement et cela a grandement améliorer ma précision).

Je me suis fais un petit pont diviseur avec une R1 de 6 K et une R2 de 10K, et Us=(Ue*R1)/(R1+R2) et j'ai une mesure vraiment pas mal par rapport à un voltmètre.

Je me suis dit que j'allais faire un break sur cette partie pour le moment, car je commence à surchauffer et que grâce à vous je m'en sort pas trop mal :D.

Ce que j'aimerai faire maintenant c'est de piloter une entrée sortie numérique, et pour cela je me suis documenté ! (je ne viens pas les mains trop vide cette fois :P)

Il me faut utiliser la fonction suivante pour lire les donnée que j'envoie via la console de l'IDE : Serial.read()

Bon j'ai essayer de faire quelques essais, mais ça n'est pas très concluant.. j'aimerais savoir une seul chose, sans que on me mâche le travaille ^^'

disons que je veux bosser sur le pin digital D51 (cf schémat suivant : http://www.robgray.com/temp/Due-pinout-WEB.png  )

dans l'idéal je voudrais pouvoir dans un premiers temps, écrire un truc dans la console, qui irais à ce pin, le lire, et le renvoyer sur la console avec un petit Serial.print("ce que vous avez écrit : ")  afin de voir si j'ai bien lu ou pas les choses écrites.. pour le moment ce que j'ai tenter n'a rien donner de concluant en ce qui concerte l'écriture.. Je suis sur ce site pour m'aider : http://eskimon.fr/104-arduino-302-envoyer-recevoir-des-donnees-voie-serie mais quand j'essaie ces programmes ou que je les adapte a ma carte (car ils n'ont pas l'air d'être prévue pour une Arduino Due), je ne vois aucun message s'afficher quand j'envoie des caractères sur la console... Bref voila si j'ai plus d'infos je ferais une EDIT ! ;) merci à vous


EDIT :
j'ai un code qui fonctionne !!
Code: [Select]
void setup()
{
    Serial.begin(9600);
}

void loop()
{
    char carlu = 0; //variable contenant le caractère à lire
    int cardispo = 0; //variable contenant le nombre de caractère disponibles dans le buffer
   
    cardispo = Serial.available();
   
    while(cardispo > 0) //tant qu'il y a des caractères à lire
    {
        carlu = Serial.read(); //on lit le caractère
        Serial.println(carlu); //puis on le renvoi à l'expéditeur tel quel
        cardispo = Serial.available(); //on relit le nombre de caractères dispo
    }
    //fin du programme
}


sauf que il ne lis qu'un caractère à la fois, les chaines de caractères sont renvoyé un a un à la ligne (j'ai rajouter le "ln" au Serial.println() pour faire un retour a la ligne entre chaque écriture de la vairable "carlu" mais j'ai essayer de faire en sorte qu'une phrase entière soit lu et recopier, ça n'a pas marcher, faut-il stocker la chaine de caractère dans un tableau pour la recopier ensuite ?

kamill

Bonjour,

Utilises readString()
Code: [Select]
if (Serial.available())
{
  String str=Serial.readString();
  Serial.println(str);
}

alex34000

Merci, mais peut tu commenter pour que je sache ce que cela fais car "str" doit être une variable si j'ai compris, mais je ne connais pas vraiment la fonction string donc je n'ai pas envie de faire de bêtise :P

kamill

str c'est une chaine de caractères de type String qui va recevoir la chaine que tu envoies sur la liaison serie. Voir String

alex34000

#22
Jun 14, 2016, 09:47 am Last Edit: Jun 14, 2016, 10:58 am by alex34000
Super ça fonctionne parfaitement !!! j'ai compris comment m'en servir, merci beaucoup ça va vachement m'aider !! merci :)

EDIT : besoins d'aide :'(

Voila je m'explique : j'ai besoins d'aide pour 2 choses, primo, les résistances de pull up. Avec le micro de la carte, on peut régler des résistances de pull up (pas de pull down malheureusement mais bon je me contenterai d'un pull up).. j'ai rechercher un peut dans la datasheet, et aux alentours des pages 610 j'ai trouver ceci :
Quote
Pull-up Resistor Control
Each I/O line is designed with an embedded pull-up resistor. The pull-up resistor can be enabled or disabled by
writing respectively PIO_PUER (Pull-up Enable Register) and PIO_PUDR (Pull-up Disable Resistor). Writing in
these registers results in setting or clearing the corresponding bit in PIO_PUSR (Pull-up Status Register). Reading
a 1 in PIO_PUSR means the pull-up is disabled and reading a 0 means the pull-up is enabled.
Control of the pull-up resistor is possible regardless of the configuration of the I/O line.
After reset, all of the pull-ups are enabled, i.e. PIO_PUSR resets at the value 0x0.
et page 629 une Table 31-2. Programming Example.

Or quand j'entre "  PIO_PUER=0x0F0F FF0F;" pour essayer de mettre mes résistances de pull up... cela me dit que PIO_PUER est non déclarer.. Que faire ?
URL de la datasheet : http://download.siliconexpert.com/pdfs/2015/4/4/3/49/5/179/atm_/manual/254atmel-11057-32-bit-cortex-m3-microtroller-sam3x-sam3a_datashee.pdf


Et deuxio, j'ai fais beaucoup d'essay pour analyser les caractère reçu, afin de gerer mes ports part la suite, sauf que j'arrive pas.. je ne sais pas si il faut une table de caractère ASCII pour décoder le message que le PC envoie a la carte afin qu'elle voie ce qui est écrit et qu'en fonction, elle fasse ce que je veux avec une liste de mots bien définie pour des action, où si il faut faire autrement.. une idée  ?

kamill

Sauf si tu veux faire des choses vraiment spéciales pour activer les pullup utilises les fonctions de la bibliothèque arduino
Code: [Select]
pinMode(x,INPUT_PULLUP);

Pour la comparaison de la chaine reçue, avec String c'est très simple
Code: [Select]
if (str=="D0_ON")
{
 // actionner la sortie
 // ...
}

alex34000

Super ça fonctionne parfaitement, merci !

j'espère la dernière question :

Actuellement j'ai ce code :
Code: [Select]
int i=0;

void setup()
{
  Serial.begin(9600);
  pinMode (53, OUTPUT);
  pinMode (52, OUTPUT);
}

void loop()
{
  Serial.available();
  String str=Serial.readString();
  Serial.println(str);
  if (str=="D0_ON")
  {
    pinMode (52, HIGH);
  }
  else{digitalWrite (53, HIGH);}
  if (str=="D0_OFF")
  {
    pinMode (52, LOW);
  }
  else{digitalWrite (53, LOW);}
}



Pour faire simple : mon DigitalWrite(53, "etat") doit allumer une LED verte relié du pin 53 à ma masse, et elle doit clignoter contament SAUF quand il y a des messages transmit entre console et PC.
Mon pinMode(52, "etat") commande l'allumage d'une LED rouge relié entre le pin 52 et la masse, et je la commande grâce à la commande D0_OFF ou D0_ON (cela fonctionne)

Mais le temps de traitement de la commande est relativement long et ma LED verte ne clignote plus.. alors j'ai tester hors du "else"  et dedant et ça ne clignote pratiquement plus. Avant j'avais ce code et ça fonctionnait :

Code: [Select]
int i=0;

void setup()
{
  Serial.begin(9600);
  pinMode (53, OUTPUT);
  pinMode (52, LOW);
}

void loop()
{
  if (Serial.available())
  {
    String str=Serial.readString();
    Serial.println(str);
  }
  else
  {
    digitalWrite (53, HIGH);
    delay(50);
    digitalWrite (53, LOW);
    delay(50)  ;
  }
}


Des idées ? ^^'

kamill

Si ça te convenait avant (on peut discuter de l'utilisation de delay), pourquoi ne continues tu pas à faire la même chose.
Code: [Select]
void setup()
{
  Serial.begin(9600);
  pinMode (53, OUTPUT);
  pinMode (52, OUTPUT);
}

void loop()
{
  if (Serial.available())
  {
    String str=Serial.readString();
    Serial.println(str);
    if (str=="D0_ON")
    {
      digitalWrite(52, HIGH);
    }
    if (str=="D0_OFF")
    {
      digitalWrite(52, LOW);
    }
  }
  else
  {
    digitalWrite (53, HIGH);
    delay(50);
    digitalWrite (53, LOW);
    delay(50)  ;
  }
}

alex34000

#26
Jun 14, 2016, 01:28 pm Last Edit: Jun 14, 2016, 01:40 pm by alex34000
j'ai réussis a modifier pour avoir ma led qui clignotte !!!!! mais... le programme met 1 seconde à arriver au traitement de la partie "LED VERTE"... c'est du au temps de lecture etc ou mon programme n'est pas optimisée ?

Code: [Select]
int i=0;

void setup()
{
  Serial.begin(9600);
  pinMode (53, OUTPUT);
  pinMode (52, OUTPUT);
}

void loop()
{
  if (Serial.available());
  {
    String str=Serial.readString();
    Serial.println(str);
    if (str=="D0_ON")
    {
      pinMode (52, HIGH);
    }
    if (str=="D0_OFF")
    {
      pinMode (52, LOW);
    }
    else
    {
      digitalWrite (53, LOW);
      delay(1000);
      digitalWrite (53, HIGH);
    }
  }
}



EDIT : j'ai compris, c'est l'utilisation de pinMode qui fais cette lenteur. Ton programme utilise du digitalWrite et du coup le temps de traitement est clairement plus rapide !! merci !

kamill

C'est du au fait que tu as ajouté un ; après if (Serial.avalaible())
Enlèves le.

alex34000

#28
Jun 14, 2016, 01:54 pm Last Edit: Jun 14, 2016, 03:28 pm by alex34000
C'est du au fait que tu as ajouté un ; après if (Serial.avalaible())
Enlèves le.
Haha merci, j'ai passé 20 min a chercher et une fois que j'ai trouvé le ";" et un crochet au mauvais endroit, sa fonctionne bien mieux :)

Je vais donc implémenter ce programme annexe dans mon programme principal, et si c'est fonctionnel je verrais pour mettre le contrôle du port en interruption du programme principal pour ne pas perdre de temps lors des relevés de mesures :).

Si j'ai des question j'éditerais ce post :) merci à toi en tout cas !


EDIT : Bon j'ai un groooos soucis. Je viens de me rendre compte que le 1er programme (aquisition des valeurs des ports) que j'ai fais ne fais aucunement une moyenne...
Regardez le code (pour 1 pin) :

Code: [Select]
  /****************************************************
  *****************************************************
       !! TOLERANCE A INDIQUER MANUELLEMENT !!
  *****************************************************
  *****************************************************/
   
    float Tol_Min = 0.1 ;    float Tol_Max = 0.1;                    // Tolérances à modifier manuellement
   
    float TA0 = 0, TA1 = 0, TA2 = 0, TA3 = 0,
          TA4 = 0, TA5 = 0, TA6 = 0, TA7 = 0,
          TA8 = 0, TA9 = 0, TA10 = 0, TA11 = 0 ;                   // Variable sans la tolérance à tester
         
    float Tol_A0 =2.7,   Tol_A1 =2.7,   Tol_A2 =2.7,   Tol_A3 =2.7,
          Tol_A4 =2.7,   Tol_A5 =2.7,   Tol_A6 =2.7,   Tol_A7 = 2.7,
          Tol_A8 =2.7,   Tol_A9 =2.7,   Tol_A10 =2.7,  Tol_A11 =2.7 ;     // Variable fixe qui sert de base pour la tolérance.
  /*****************************************************
      Déclaration des Pins d'entrées analogiques
  ******************************************************/ 

  const int AI_A0 = A0, AI_A1 = A1, AI_A2 = A2, AI_A3 = A3,       // PIN d'entrées analogiques sur les quels
            AI_A4 = A4, AI_A5 = A5, AI_A6 = A6, AI_A7 = A7,       // sont reliés des composants
            AI_A8 = A8, AI_A9 = A9, AI_A10 = A10, AI_A11 = A11;                             
 
  /****************************************************
     Déclaration des Variables des data d'entrées
  *****************************************************/ 

  int sensorValue_A0 = 0, sensorValue_A1 = 0, sensorValue_A2 = 0,     //Déclaration des variables en INT
      sensorValue_A3 = 0, sensorValue_A4 = 0, sensorValue_A5 = 0,
      sensorValue_A6 = 0, sensorValue_A7 = 0, sensorValue_A8 = 0,
      sensorValue_A9 = 0, sensorValue_A10 = 0, sensorValue_A11 = 0;

  /****************************************************
  Déclaration des Variables pour la moyenne
  *****************************************************/
  int Table_A0[50]={}, Table_A1[50]={}, Table_A2[50]={}, Table_A3[50]={},
      Table_A4[50]={}, Table_A5[50]={}, Table_A6[50]={}, Table_A7[50]={},
      Table_A8[50]={}, Table_A9[50]={}, Table_A10[50]={}, Table_A11[50]={},
      i = 0;
                             
  /****************************************************
  Déclaration des Variables flottantes pour mesures
  *****************************************************/

  float V_A0 = 0, V_A1 = 0, V_A2 = 0, V_A3 = 0,         // Déclaration des variables en flotantes pour les port :
        V_A4 = 0, V_A5 = 0, V_A6 = 0, V_A7 = 0,         // A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11
        V_A8 = 0, V_A9 = 0, V_A10 = 0, V_A11 = 0;   
   
  float Vmoy_Table_A0 = 0, Vmoy_Table_A1 = 0, Vmoy_Table_A2 = 0, Vmoy_Table_A3 = 0,
        Vmoy_Table_A4 = 0, Vmoy_Table_A5 = 0, Vmoy_Table_A6 = 0, Vmoy_Table_A7 = 0,
        Vmoy_Table_A8 = 0, Vmoy_Table_A9 = 0, Vmoy_Table_A10 = 0, Vmoy_Table_A11 = 0;     
                                     
  /***********************************************
  ************************************************
          SETUP DU PROGRAMME
  ************************************************
  ************************************************/ 
  void setup()
  {
    Serial.begin(19200);                               // Initialise la comunication série à 9600 Bauds
    analogReadResolution(12);                         //règle la résolution sur 12 bits
  }
 
  /***********************************************
  ************************************************
          DEBUT DU PROGRAMME
  ************************************************
  ************************************************/
 
  void loop() {

     
  // *****************************************
  //      Port A0
  //******************************************
     

    if(i<=50)
    { 
    sensorValue_A0 = analogRead(AI_A0);                //Lis les valeurs analogiques du port AO et donne ces valeurs à sensorValue 
    V_A0 = sensorValue_A0;                             //Incrémente sensorValue dans la variale V_A0
    TA0 = V_A0*(3.3/4096);
    affiche_port_A0();
    Table_A0[i]=sensorValue_A0;
    Vmoy_Table_A0 = Vmoy_Table_A0 + Table_A0[i];
    i++;
    }
    else
    {
     V_A0=((Vmoy_Table_A0)/(i+1));
     i=0;
     Vmoy_Table_A0 = 0;
    }

    delay(1);                                          //Attente de 2MS pour laisser le temps de convertir et de traiter les datas
  }
 
 
 
  void affiche_port_A0()
  {
      Serial.print("A0_HEXA = " );                       //affiche "A0_HEXA="
    Serial.print(sensorValue_A0,HEX);                  //Affiche la valeur actuel du potentiomètre (sur une résolution de 12 bits)
    Serial.print("\t\t A0_3.3V = ");                   //Affiche "VA0_3.3V ="
    Serial.print(V_A0*(3.3145/4096),4);                   //Affiche la valeur de V_A0 en 3.3V (le nb après la "," augmente la précision).
    Serial.print("\t A0_6V = ");                       //Affiche "VA0_6V = "
    Serial.print(V_A0*(6.0/4096),4);                   //Affiche la valeur de V_A0 en 6V (le nb après la "," augmente la précision).
    Serial.print("\t\t A0_6V_Corr = ");                //Affiche "A0_6V_corr = "
    Serial.print(((V_A0*(6.0/4096))+0.1),4);         //Affiche la valeur de V_A0 en 6V + une correction. (le nb après la "," augmente la précision).
    if(TA0 > Tol_A0 + Tol_Max || TA0 < Tol_A0 - Tol_Min )
    {  Serial.println("\t N_OK "); }
    else
    { Serial.println("\t OK ");}
  }
   


C'est monstrueux.. en gros :

Je donne la valeur de analogRead à sensorValue.
Je donne la valeur de sensorValue à V_A0.
Je donne la valeur de V_A0*(un calcul) à TA0
         J'affiche. Et j'affiche quoi ? :
         Aff sensor value en hex, V_A0 en 3.3, V_A0 en 6v et en 6v + 0.1
puis j'incrémente ma valeur moyenne et quand i atteint enfin la valeur désiré pour la moyenne, je calcul ma moyenne et je remet mon tableau à 0

Je n'affiche donc pas ma moyenne mais les relevès de ma moyenne... Need help please j'y comprend plus rien :'(

alex34000

désolé pour le double post mais j'ai déjà fais une EDIT, j'ai modifier ceci :
Code: [Select]
     if(i<=10)
    { 
    sensorValue_A0 = analogRead(AI_A0);                //Lis les valeurs analogiques du port AO et donne ces valeurs à sensorValue 
    V_A0 = sensorValue_A0;                             //Incrémente sensorValue dans la variale V_A0
//    TA0 = V_A0*(3.3/4096);
//    affiche_port_A0();
    Table_A0[i]=sensorValue_A0;
    Vmoy_Table_A0 = Vmoy_Table_A0 + Table_A0[i];
    i++;
//    Serial.print("i=");
//    Serial.println(i);
    }
    else
    {
     V_A0=((Vmoy_Table_A0)/(i+1));
     affiche_port_A0();
     i=0;
     Vmoy_Table_A0 = 0;
    }


ce qui fais que mon affichage affiche maintenant la vrai moyenne, mais quand je met plus de 60 acquisition, le programme plante.... (d'ou l'affichage de la valeur de "i" pour savoir cela), vous avez une idée d'où cela peut provenir ?

Go Up