Pages: [1]   Go Down
Author Topic: Faire une raz d'un programme par une interruption  (Read 1734 times)
0 Members and 1 Guest are viewing this topic.
France S-O
Offline Offline
Edison Member
*
Karma: 41
Posts: 2231
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Mon projet est le suivant : gestion d'une activité sportive.
- au repos le module ne fait rien
- par le changement d'état sur une Entrée digitale je lance un dé-comptage ( il y aura l'électronique et le nombre de pins qui vont bien pour faire un affichage)
- Si tous les concurrents ont fini avant le temps limite je stoppe le dé-comptage et je fais une RAZ a l'aide d'une  interruption : je veux stopper DEFINITIVEMENT le dé-comptage en cours.

Mes premiers essais me laissent a penser que l'interruption avec un  Atmega 328 ne stoppe pas le programme en cours mais le suspend simplement ce qui fait qu'il reprend son cours dès que l'interruption cesse.

Sur le web j'ai trouvé cette solution :

//fonction pour un reset logiciel
void (*resetFunc)(void)=0; //Déclare resetFunc à l'adresse @ adress 0

Qui s'appelle dans la fonction qui va bien :
resetFunc();

Ma question :
Avez vous trouvé des pièges dans cette méthode et connaissez vous d'autres méthodes ?

PS dans la doc de l'ATmega328 il est précisé qu'il ne peut y avoir qu'une seule interruption active à la fois. Donc si "0" est déclenchée "1" ne pourra être actif que lorsque "0" cessera.

module arduino UNO R2
Merci et bonne soirée
Logged

Cergy
Offline Offline
Full Member
***
Karma: 0
Posts: 137
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,
si tu peux nous donner le lien que tu as trouvé, ça nous évitera de faire les mêmes recherches que toi smiley-wink

Que veux-tu réellement quand tu parles de raz de programme ? que le sketch soit supprimé de l'Arduino ?

Est-ce que par "arrêter définitivement le programme", tu espères quand même pouvoir le relancer lors d'une session ultérieure sans réinstallation préalable ?
Veux-tu conserver la valeur présente sur l'afficheur lors de l'arrêt définitif ?

En fonction de tes besoins, une solution pourrait être d'alimenter ton Arduino via un relais par exemple. Celui-ci  ne démarrerait que lorsque le relais colle (par une action extérieure), l'arrêt se ferait de la même manière, ou même par un changement d'état d'une sortie de l'Arduino (qui provoquerait le décollement du relais donc l'arrêt de l'Arduino). Avec ce système, l'arrêt est bien définitif ... tant que tu ne ralimentes pas l'Arduino
Logged

Tous les jours, je roule en Electrique
Arretons de polluer !

Moi & mon Ardu

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonsoir,

Mon projet est le suivant : gestion d'une activité sportive.
- au repos le module ne fait rien
- par le changement d'état sur une Entrée digitale je lance un dé-comptage ( il y aura l'électronique et le nombre de pins qui vont bien pour faire un affichage)
- Si tous les concurrents ont fini avant le temps limite je stoppe le dé-comptage et je fais une RAZ a l'aide d'une  interruption : je veux stopper DEFINITIVEMENT le dé-comptage en cours.
Il doit y avoir une méthode bien mieux que de faire un reset.

Mes premiers essais me laissent a penser que l'interruption avec un  Atmega 328 ne stoppe pas le programme en cours mais le suspend simplement ce qui fait qu'il reprend son cours dès que l'interruption cesse.
C'est le principe même d'une interruption smiley-wink le programme principal est mis en pause et une fois le programme d'interruption finit on retourne au prog principal comme on la laisser avant l'interruption.

Sur le web j'ai trouvé cette solution :

//fonction pour un reset logiciel
void (*resetFunc)(void)=0; //Déclare resetFunc à l'adresse @ adress 0

Qui s'appelle dans la fonction qui va bien :
resetFunc();

Ma question :
Avez vous trouvé des pièges dans cette méthode et connaissez vous d'autres méthodes ?
N'utilise JAMAIS cette méthode ! Ceci n'est pas un reset hardware ! C'est un reset SOFTWARE, la mémoire n'est pas réinitialiser les registres restent en états, etc ... cela ne peut entrainer que des problémes. Si ton but est de forcer un reset hardware, active le watch dog et crée un boucle infini c'est radical.
 
PS dans la doc de l'ATmega328 il est précisé qu'il ne peut y avoir qu'une seule interruption active à la fois. Donc si "0" est déclenchée "1" ne pourra être actif que lorsque "0" cessera.
Comme pour tous µc il ne peut y avoir qu'une seule interruption simultané mais il est possible de d'arrêté une interruption par une autre interruption moyennant la fonction qui va bien.

Que veux-tu réellement quand tu parles de raz de programme ? que le sketch soit supprimé de l'Arduino ?

Est-ce que par "arrêter définitivement le programme", tu espères quand même pouvoir le relancer lors d'une session ultérieure sans réinstallation préalable ?
Veux-tu conserver la valeur présente sur l'afficheur lors de l'arrêt définitif ?
Je ne pense pas qu'il veut effacer le programme mais juste le faire repartir en mode "attente".
Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

France S-O
Offline Offline
Edison Member
*
Karma: 41
Posts: 2231
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Je précise :
- la fonction loop scrute en permanence l'état d'une entrée par exemple la pin8, tant que la pin 8 lit un état bas rien ne se passe, si la pin 8 détecte un état haut (fugitif mais de durée suffisante pour être pris en compte) la fonction décomptage est appelée par exemple de 100s à 0.
void loop()
{
lecture_de_la_pin8;
if (pin8==haut) decompte();
}

void decompte()
{
}
- si tous les concurrents ont terminé avant les 100s où qu'il se passe un incident, je veux arrêter le décomptage et revenir dans l'état initial où la pin 8 attend de trouver un état haut pour relancer un décompte.
Il ne s'agit donc pas de suspendre ni de faire un reset hardware mais de "tuer" une fonction qui a été lancée par la boucle principale à partir d'un if, c'est donc un reset software c'est pour cela que j'avais pensé que la solution proposée pouvait me convenir.
Comme l'analogique c'est bon pour moi mais les micros je n'y connais encore rien, j'ai préféré recueillir vos avis avant de faire une manœuvre bloquante sur le micro.
Pourrait-tu préciser tes réserves sur l'état des registres ? Est ce suffisant  de réinitialiser toutes les variables.
Quote
Comme pour tous µc il ne peut y avoir qu'une seule interruption simultané mais il est possible d'arrêter une interruption par une autre interruption moyennant la fonction qui va bien.
Cela m'intéresse, as tu des liens pour je me documente, merci.
Logged

Celtic Kingdom
Offline Offline
Sr. Member
****
Karma: 2
Posts: 455
hard oui no!!!
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Est-ce vraiment nécessaire de faire un reset ?
Parce qu'à la lecture de la description du projet il est possible de gérer les événements d'arrêt et de RAZ sans faire de reset, à priori. Avec un système de "flags" permettant de savoir que le programme a été arrêté.

En même temps, à propos du reset je m'étais déjà posé la question et j'avais trouvé cela :
-> ATmega Software Reset
Si cela peut aider...
Logged

France
Offline Offline
Faraday Member
**
Karma: 55
Posts: 5347
Arduino Hacker
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Un simple while conditionné par une variable et amplement suffisant ...

Exemple:
Code:
void setup(){
pinMode(8,INPUT);
pinMode(9,INPUT);
}

int pin8 = 0; // pin 8 = trigger de décompte
boolean run = true; // flag d'accident (exemple)

void loop()
{
pin8 = digitalRead(8);
if (pin8 == HIGH) decompte();
}

long previousMillis = 0; // temps précédant
void decompte()
{
while(run){
   unsigned long currentMillis = millis(); // temps courant

   pin8 = digitalRead(8); // check pin8
   if (pin8 == HIGH) run = false; // si la pin8 = HIGH ya un probléme STOPPPPP! ps:run pourrai etre remplacer par un return; mais c'est un exemple !
  
   if(currentMillis - previousMillis > 1000) { // décompte 1sec
     previousMillis = currentMillis;   // on enregistre le temps courant
// faire quelque chose ici
   }
run = true; // on rearme le systéme
}

}


Cela m'intéresse, as tu des liens pour je me documente, merci.

Regarde du coté de sei() mais attention quand ça bug avec plusieurs interruptions qui s'entrecroise c'est monstrueux à debuger.
Je tient à précisez qu'une seul fonction s'exécute en même temps, cette fonction permet juste de lancer un interruption pendant un autre interruption.
« Last Edit: June 29, 2011, 05:09:25 am by Jean-François » Logged

Des news, des tuto et plein de bonne chose sur http://skyduino.wordpress.com !

France S-O
Offline Offline
Edison Member
*
Karma: 41
Posts: 2231
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci à tous,
Je me prépare à rejoindre mes quartiers d'été, une fois mon PC local mis à jour je testerai vos solutions.
Bon courage à ceux qui restent au boulot.
Logged

Orleans
Offline Offline
Jr. Member
**
Karma: 1
Posts: 88
Macbidouilleur
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Il y'a aussi l'instruction break qui permet de sortir d'une boucle "infini".
quelque chose du genre :

while (1){
  while(1) {
  // faire un truc en boucle ici
  if (pin8==true) break; // Sort de la boucle
  }
// faire l'autre truc ici
} Retourne dans la première boucle.

C'est plus "propre" que d'utiliser les interruptions.
Logged


Pages: [1]   Go Up
Jump to: