Arduino Mega, A0 et changement d'IDE

Les cartes Arduino, les platines

Arduino Mega, A0 et changement d'IDE

Message non lude fred » Jeu 28 Juin 2012 10:17

Message d'un utilisateur :
Je suis munit actuellement d'un arduino ATMEGA2560 ainsi que de son shield Ethernet.
Sous la version IDE 0023 mon programme effectuant l'acquisition de l'entrée A0 (analogique) grâce a une interruption déclenché sur un bouton poussoir fonctionne parfaitement.
Une fois passé sur la version IDE 1.0.1 (ou 1.0 tout court) lorsque l'arduino entre dans l'interruption afin d'effectuer l'acquisition, celui-ci plante completement.
Pouvez-vous m'éclairer sur les différences entre ces 2 versions pouvant expliquer ce phénomène?
Merci d'avance
Avatar de l’utilisateur
fred
 
Messages: 220
Inscription: Lun 20 Déc 2010 15:32
Localisation: Toulouse

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Lionel » Jeu 28 Juin 2012 10:36

Bonjour,

Pourriez vous placer une copie du message d'erreur ?
Image - Distributeur officiel Arduino - Conception de shields
Avatar de l’utilisateur
Lionel
 
Messages: 734
Inscription: Mar 21 Déc 2010 09:52
Localisation: Toulouse

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Jeu 28 Juin 2012 13:35

Bonjour à tous.

Merci d'avoir posté ma demande.

Mon code est le suivant :

Code: Tout sélectionner
/*
Echantillonner un sinus de 50Hz
grâce à l'appuie d'un bouton
Une led permettra de connaitre l'activiter de la carte
led = ON echantillonnage en cours
led = OFF fin activitée echantillonnage
*/

const int nbrpoints               =    200;
volatile int led_echantillon     =     13; // Pin led
volatile int flag_interruption  =       0;
volatile int tab_echantillon[nbrpoints];

void setup() {
  Serial.begin(9600);
  pinMode(led_echantillon, OUTPUT);
 
/*  INTERRUPTION
 *  N°  0  1  2  3  4  5
 *  PIN 2  3 21 20 19 18
 *  LOW     appel le sous prog d'inter. tant que le bit est au niveau bas,
 *  CHANGE  appel le sous prog d'inter. à chaque changement d'état
 *  RISING  appel le sous prog d'inter. sur le front montant
 *  FALLING appel le sous prog d'inter. sur le front descendant.
 */
   attachInterrupt(2, callback, FALLING);
} // setup

void loop() {

  Serial.println("loop");
  delay(250);
  if (flag_interruption==1){
    for (int i=0;i<=nbrpoints;i++){
       if (i!=0) Serial.print(", ");
       Serial.print(tab_echantillon[i]);
    }
    flag_interruption=0;
  }
} // loop

void callback(){                 
  noInterrupts();
  flag_interruption = 1;
  digitalWrite(led_echantillon, HIGH);
  for (volatile int i=0;i<=nbrpoints;i++){
    tab_echantillon[i] = analogRead(A0);
  }
 
  digitalWrite(led_echantillon, LOW);
  interrupts();
} // callback                                 


Ce code fonctionne à présent avec les 2 versions de l'IDE.

L'ancienne version de ce code effectuai l'affichage sur le port Serie du Tableau de valeur dans le sous programme d'interruption callback.
Ce procédé fonctionnai sous l'IDE 0022/0023 mais plus sous l'IDE 1.0 ou il se trouve défendu d'effectuer des boucles avec des Serial.print dans les sous programme d'interruption ( je me demande pourquoi d'ailleurs).
Sur l'IDE 1.0 la compilation est bonne, l'arduino fonctionne mais dès qu'on remplie la condition pour entrer dans le sous programme d'interruption cela plante l'arduino.

La solution apportée en utilisant un flag afin de détecter si je suis passé dans mon sous programme d'interruption ne me satisfait pas.

En effet, la condition permettant de voir si je suis passé dans mon sous programme est un simple IF() qui sera effectué qu'à partir du moment ou mon programme passera dessus et non pas directement à la suite de mon interruption comme c'était le cas avec la version 0022.

Quelqu'un aurai une idée pour résoudre ce problème afin de retrouver le même comportement qu'avant?
Dernière édition par Cromelec le Jeu 28 Juin 2012 15:32, édité 2 fois.
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Jeu 28 Juin 2012 13:43

voilà le code qui fait planter l'arduino

Code: Tout sélectionner
/*
Echantillonner
grâce à l'appuie d'un bouton
Une led permettra de connaitre l'activiter de la carte
led = ON echantillonnage en cours
led = OFF fin activitée echantillonnage
*/

const int nbrpoints       = 200;
volatile int led_echantillon    =  13;
volatile int tab_echantillon[nbrpoints];

void setup() {
  Serial.begin(9600);
  pinMode(led_echantillon, OUTPUT);
 
/*  INTERRUPTION
 *  N°  0  1  2  3  4  5
 *  PIN 2  3 21 20 19 18
 *  LOW     appel le sous prog d'inter. tant que le bit est au niveau bas,
 *  CHANGE  appel le sous prog d'inter. à chaque changement d'état
 *  RISING  appel le sous prog d'inter. sur le front montant
 *  FALLING appel le sous prog d'inter. sur le front descendant.
 */
attachInterrupt(2, callback, FALLING);
} //setup

void loop() {
  Serial.println("loop");
  delay(250);
}

void callback(){   
  digitalWrite(led_echantillon, HIGH); 
  for (volatile int i=0;i<=nbrpoints;i++){
    tab_echantillon[i] = analogRead(0);   
    if (i == nbrpoints){
      for (i=0;i<=nbrpoints;i++){
        if (i!=0) Serial.print(", ");
        Serial.print(tab_echantillon[i]);
      }
    }
  }
  digitalWrite(led_echantillon, LOW);
}                             
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Ven 29 Juin 2012 10:33

Personne n'est embêté avec les interruptions sur l'IDE 1.0.x ?
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Re: Arduino Mega, A0 et changement d'IDE

Message non lude SesechXP » Ven 29 Juin 2012 10:43

Salut,

De manière générale, les routines d'interruption doivent faire le moins de choses possible. Dans ton cas, il serait judicieux de sortir tout ce qui sert à envoyer les données sur la sortie série et ne conserver que la lecture de l'entrée analogique.

Ensuite il est possible que tu aies un problème de ré-entrance : je ne vois pas de désactivation des interruptions au début de la routine...
SesechXP
 
Messages: 228
Inscription: Sam 28 Mai 2011 09:09
Localisation: 35

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Lionel » Ven 29 Juin 2012 11:30

Bonjour,

En fait, votre code 2ème version est bien meilleur que le premier... en effet, il faut restreindre au maximum les instructions effectuées dans un fonction d'interruption (comme l'a dit SesechXP)

Donc rien que pour ça, des lecture/écriture sur le port série sont donc a proscrire dans les interruptions.

D'autres raisons de type utilisation d'interruption internes existent il me semble (mais je ne retrouve pas l'info tout de suite) font qu'il ne faut pas utiliser de serial.print a cet endroit et il est possible que cette possibilité ait été bloquée dans la dernière version de l'IDE
Image - Distributeur officiel Arduino - Conception de shields
Avatar de l’utilisateur
Lionel
 
Messages: 734
Inscription: Mar 21 Déc 2010 09:52
Localisation: Toulouse

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Ven 29 Juin 2012 14:41

SesechXP a écrit:Salut,

De manière générale, les routines d'interruption doivent faire le moins de choses possible. Dans ton cas, il serait judicieux de sortir tout ce qui sert à envoyer les données sur la sortie série et ne conserver que la lecture de l'entrée analogique.

Ensuite il est possible que tu aies un problème de ré-entrance : je ne vois pas de désactivation des interruptions au début de la routine...


Même en ajoutant le noInterrupts() au début du sous program et le interrupts() à sa dernière ligne rien n'y fait.
Le problème lié à l'interruption est résolu.

Il se trouve que je souhaite stocker ces données sur carte SD.
Je pensai dans un premier lieu que l'interruption était la cause du problème mais il se trouve que l'ajout de l'écriture sur la carte SD pose problème. La première écriture s'effectue correctement alors que la 2eme fait planter le programme. :shock:

Afin de continuer mon debug j'ai réalisé le programme pas à pas en intégrant au fur et a mesure les fonctionnalitées.

L'esprit du code est le suivant :

loop {
if (flag ==1){
- affiche mes valeurs sur la console
- noInterrupts();
- ecrire sur la SD mon tableau
- interrupts();
- flag=0;
}
}


Interruption sur front descendant en utilisant l'interruption N°5 se trouvant sur la PIN 18. {
-Lecture de l'entrée Analogique A0.
- flag = 1
}

Code: Tout sélectionner




#include <SPI.h>

#include <Ethernet.h>

#include <EthernetUdp.h> // pour NTP

#include "Time.h"

#include <SD.h>

#include <Sensirion.h>



#define BUFSIZ 2800



byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};



unsigned int localPort = 8888;      // local port to listen for UDP packets

IPAddress timeServer(88,190,25,158);//IPAddress timeServer(192, 43, 244, 18); // time.nist.gov NTP server

const int NTP_PACKET_SIZE= 48;        // NTP time stamp is in the first 48 bytes of the message

byte packetBuffer[ NTP_PACKET_SIZE];// buffer to hold incoming and outgoing packets



byte mem_sauv_minute = 1;

byte mem_sauv_inter = 1;

///SENSIRION

/// blanc = data

/// jaune = clk

/// vert  = 5v

/// marron= gnd

const uint8_t dataPin  =  3;

const uint8_t clockPin =  2;

float temperature;

float humidity;

float dewpoint;

Sensirion tempSensor = Sensirion(dataPin, clockPin);



char date_heure[18];

int GTM;





char temp[100];

const int nbrbroche = 5;   

char analog[nbrbroche*6];



///// acquisition /////

const uint8_t interPin = 22;            // a enlever dans la version final

const int nbrpoints            = 200;

volatile int led_echantillon    =  40; // Pin led

volatile int flag_interruption  = 0;

volatile int tab_echantillon[nbrpoints];

///// acquisition /////



EthernetUDP Udp;



Sd2Card card;

SdVolume volume;

SdFile root;

SdFile file;



//byte ip[] = { 192,168,2,2 };

//byte gateway[] = { 255,255,255,0 };

//byte subnet[] = { 192,168,2,1 };



EthernetServer server(80);



#define error(s) error_P(PSTR(s))



///////////////////////// error_P ////////////////////////

//                                          //

void error_P(const char* str) {

  PgmPrint("error: ");

  SerialPrintln_P(str);

  if (card.errorCode()) {

    PgmPrint("SD error: ");

    Serial.print(card.errorCode(), HEX);

    Serial.print(',');

    Serial.println(card.errorData(), HEX);

    enregistreJ("SD error") ;

  }

  while(1);

}

//                                          //

///////////////////////// error_P ////////////////////////





const int chipSelect = 4;



void setup() {

  Serial.begin(9600);

  Serial.println("Arduino 1.0.1 ");

  Serial.print("Free RAM: ");

  Serial.println(FreeRam());

 

    pinMode(10, OUTPUT);                     // set the SS pin as an output (necessary!)

  digitalWrite(10, HIGH);                  // but turn off the W5100 chip!

  pinMode(53, OUTPUT);

 

    if (!card.init(SPI_HALF_SPEED, 4)){

   error("card.init failed!");

    enregistreJ("card.init failed!") ;

  }

 

    if (!volume.init(&card)){               // initialize a FAT volume

    error("vol.init failed!");

     enregistreJ("vol.init failed!") ;

  }

 

  Serial.print("Volume is FAT");

  Serial.println(volume.fatType(),DEC);

  Serial.println();

  pinMode(led_echantillon, OUTPUT);

 

    if (!SD.begin(chipSelect)) {            // see if the card is present and can be initialized:

    Serial.println("Card failed, or not present");

    enregistreJ("Card failed, or not present") ;

    // don't do anything more:

    return;

  }

  Serial.println("card initialized.");

 

 if (!root.openRoot(&volume)){

    error("openRoot failed");

    enregistreJ("openRoot failed") ;

  }

 

  PgmPrintln("Files found in root:");      // list file in root with date and size

  root.ls(LS_DATE | LS_SIZE);

  Serial.println();

 

  PgmPrintln("Files found in all dirs:");   // Recursive list of all directories

  root.ls(LS_R);

 

  Serial.println();

  PgmPrintln("Done"); 

 

 

 

 

/*  INTERRUPTION

 *  N°  0  1  2  3  4  5

 *  PIN 2  3 21 20 19 18

 *  LOW     appel le sous prog d'inter. tant que le bit est au niveau bas,

 *  CHANGE  appel le sous prog d'inter. à chaque changement d'état

 *  RISING  appel le sous prog d'inter. sur le front montant

 *  FALLING appel le sous prog d'inter. sur le front descendant.

 */

 

attachInterrupt(5, callback, FALLING);



 



} //setup



void loop() {



Serial.println("loop");

delay(250);



if (flag_interruption==1){

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

       if (i!=0) Serial.print(", ");

     Serial.print(tab_echantillon[i]);

      }

  flag_interruption=0;

 

  saveSd_inter();

}



}

void callback(){                          //---CALLBACK---------------------

noInterrupts();

flag_interruption = 1;



digitalWrite(led_echantillon, HIGH);

  for (volatile int i=0;i<=nbrpoints;i++){

    tab_echantillon[i] = analogRead(A0);

     }

digitalWrite(led_echantillon, LOW);

interrupts();

}                                          //---/CALLBACK----------------------





///////////////////////// saveSD_inter  ////////////////////////

//                                          //

void saveSd_inter(){

  noInterrupts();

  enregistreJ("Save SD inter");

  Serial.print("save inter ");

  char fichier_journee[13];

  boolean nouveau_fichier = false;

  String dataCPT = "";

  sprintf( fichier_journee, "A%02d%02d%02d.att", (year()-2000), month(),day() ); // nom du fichier court (8 caractères maxi . 3 caractères maxi

  if (!SD.exists(fichier_journee)) nouveau_fichier = true;

  File  stockdata = SD.open(fichier_journee, FILE_WRITE);

 

  if (stockdata) {// si le fichier est bien ouvert-> écriture

    if (nouveau_fichier)

    {   

      stockdata.println("Capture Analogique \n");

    }

    format_date_heure();

    dataCPT += date_heure;

   

    int flag =0;

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

      if (flag == 1) dataCPT += ", ";

      dataCPT += String(tab_echantillon[i]);     

      flag=1;

    }   

    stockdata.println(dataCPT);

    stockdata.close();   

  }

}

//                                          //

///////////////////////// saveSD_inter  ////////////////////////





///////////////////////// JOURNAL ////////////////////////

//                                          //

void enregistreJ(String msg)

{

  File dataFile = SD.open("journal.txt", FILE_WRITE);

  if (dataFile== 0) {    // permet init SD

    File dataFile = SD.open("journal.txt", FILE_WRITE);

  }

  if (dataFile) {

    format_date_heure();

    dataFile.print(date_heure);

    dataFile.print(" => ");

    dataFile.println(msg);

    dataFile.close();

  } 

  else {

    Serial.println("error opening journal.txt");

  } 

  interrupts();

}

//                                          //

///////////////////////// JOURNAL ////////////////////////



/////////////////////////form_date////////////////////////

//                                          //

void format_date_heure()

{

   sprintf(date_heure,"%02d/%02d/%d,%02d:%02d, ",day(), month(), year(), hour(), minute());

}

//                                          //

/////////////////////////form_date////////////////////////
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Lionel » Ven 29 Juin 2012 15:10

et donc quel est le problème ?
Image - Distributeur officiel Arduino - Conception de shields
Avatar de l’utilisateur
Lionel
 
Messages: 734
Inscription: Mar 21 Déc 2010 09:52
Localisation: Toulouse

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Dim 1 Juil 2012 00:24

Et bien qu à la 2ème écritures ça plante
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Lionel » Lun 2 Juil 2012 08:53

Bonjour,

vous serait il possible :
de mettre un lien vers chacune des librairies que vous utilisez,
d'indiquer si vous y avez apporté quelques modifications,
de détailler "plante",
de rappeller sous quel IDE votre code "plante"
afin qu'on puisse vous aider.
Image - Distributeur officiel Arduino - Conception de shields
Avatar de l’utilisateur
Lionel
 
Messages: 734
Inscription: Mar 21 Déc 2010 09:52
Localisation: Toulouse

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Lun 2 Juil 2012 09:44

Hardware: ATMEGA 2560 R3 avec son Shield Ethernet R3.
Logiciel: Arduino IDE 1.0.1


Liens vers les Libs que j'utilise:
http://www.terafiles.net/v-143142.html

Seul modification est pour passer de l'ancien au nouveau IDE
    #include "wiring.h"
    #include "WPrograms.h"
    #include "WConstants.h"
    #include "pins_arduino.h"
devient : #include "Arduino.h"

L'arduino plante à la suite d'un second appel du programme d'interruption.
Plus précisement il semble planter lors de la seconde écriture sur la carte SD vu que:

    - Il m'affiche les valeurs collectées par le sous programme d'interruption
    - l'affichage (serial.print) s'effectue dans le loop via un flag mis à 1 par le sous programme d'interruption
    - Il plante après avoir affiché les nouvelles valeurs (ce sont bien des nouvelles valeurs et non les même qu'à la première acquisition

J'ai testé mon programme en ajoutant un flag qui s'incrémente à chaque passage dans le sous programme d'interruption. celui-ci s'incrémente n'importe comment :? :? enfin ça c'est autre chose..
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Re: Arduino Mega, A0 et changement d'IDE

Message non lude SesechXP » Lun 2 Juil 2012 10:22

Salut,

Comme je l'écrivais plus haut, ça ressemble à un problème de ré-entrance. Il est possible qu'un nouveau flag d'interruption soit levé avant que le précédent n'ai été complètement traité.

Dans la routine d'interruption (et pas dans le loop ou ailleurs) :
- désactivation de l'interruption ;
- traitement de l'interruption ;
- réactivation de l'interruption.
SesechXP
 
Messages: 228
Inscription: Sam 28 Mai 2011 09:09
Localisation: 35

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Lun 2 Juil 2012 10:27

Oui mais si tu regardes le programme que j'ai posté je le fais déjà
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Re: Arduino Mega, A0 et changement d'IDE

Message non lude SesechXP » Lun 2 Juil 2012 10:37

Autant pour moi :oops: Par contre tu le fais à différents endroits dans différentes fonctions et je ne parierais pas sur l'état de l'interruption à tel ou tel endroit : je vois au moins 2 désactivations et 2 activations des interruptions...

Si le traitement est long :
- désactivation de l'interruption au début de la routine d'interruption ;
- traitement par les fonctions loop & co ;
- en fin de traitement, réactivation des interruptions.
SesechXP
 
Messages: 228
Inscription: Sam 28 Mai 2011 09:09
Localisation: 35

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Lun 2 Juil 2012 10:44

oui j'ai effectué divers tests, j'ai également testé la méthode que tu me proposes ;) résultat identique toujours :evil:
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Re: Arduino Mega, A0 et changement d'IDE

Message non lude SesechXP » Lun 2 Juil 2012 11:10

J'ai regardé plus en détails ton sketch et il fait beaucoup de choses. Ce n'est pas le plus simple pour déboguer :? Il faudrait le dégraisser au maximum et ne laisser que l'interruption et un traitement minimal qui envoie les données sur le port série.

Une fois cette partie validée on y va progressivement :
- ajout de la datation avec création du nom de fichier (sans enregistrement sur la SD) ;
- ajout de l'enregistrement sur SD ;
- ajout de l'ethernet ;
- etc...
SesechXP
 
Messages: 228
Inscription: Sam 28 Mai 2011 09:09
Localisation: 35

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Lun 2 Juil 2012 12:54

C'est pourquoi j'arrive ici avec un programme plus simple qui demande juste a effectuer une acquisition sur l'appuie d'un boutton poussoir (d'ou l'interruption) et de stoquer dans un fichier le resultat.

Mon projet fonctionne, il a tourné 1semaine sans problème.

Je souhaite réaliser en plus de ce que ma carte effectue deja grâce l'interruption une acquisition analogique qui elle aussi est a stoquer et horodater.

Cette fonction bug encore et je ne sais pas pourquoi ! :evil: :evil:
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Re: Arduino Mega, A0 et changement d'IDE

Message non lude SesechXP » Mar 3 Juil 2012 07:21

Si ton projet a tourné une semaine sans problème et que ça a déconné après, il semblerait que tes dernières modifications aient entraîné une régression... Si tu les enlèves, ça donne quoi ?

Peux-tu poster ton programme le plus simple possible sans SD, sans ethernet ? Je vais essayer de mon côté...
SesechXP
 
Messages: 228
Inscription: Sam 28 Mai 2011 09:09
Localisation: 35

Re: Arduino Mega, A0 et changement d'IDE

Message non lude Cromelec » Mar 3 Juil 2012 08:40

J'ai résolu mon problème !

J'effectuai une mesure de 200 acquisitions sur l'entrée analogique A0 que je stoquai dans un tableau
jusque la rien de spécial.

Cependant, lorsque je sauvegardai ce tableau en l'écrivant sur ma carte SD, j'écrivai l'intégralité de ma mesure sur 1 seul ligne.
cad : en moyenne, 200 points * 4 soir plus de 800caracteres sur une ligne

Hors, il semblerai que nous soyons limité à un nombre de caractère sur une même ligne lors de l'écriture sur la SD. Je devai dépasser cette limite et c'est pourquoi le programme plantai lors de l'écriture !

j'ai changé de stratégie même si cela est moins lisible, j'enregistre mon tableau de valeur en colonne. ( 1 valeur par ligne)
C'est moins simple à lire mais au moins, ça plante pas :lol:
Cromelec
 
Messages: 13
Inscription: Jeu 28 Juin 2012 12:51

Suivante

Retourner vers Arduino

Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 4 invités