interuption que dans un sous programme possible ?

Bonjour, j'aimerai savoir si il est possible de faire une interuption externe (par une input de l'arduino) que dans un sous programme... ?

Je m'explique que l'interuption ne soit valide que si l'arduino execute un void() precis.

Merci de vos réponses

hello oui, ton interruption arme un flag à true

et tu ne testes ce flag que dans ta fonction

une autre façon: en debut de fonction : attach interrupt (.................); et avant de sortir de la fonction, detach interrupt (.............);

Il suffit d'interdire les interruptions par noInterrupts(), puis de les autoriser dans ton void() par interrupts() et en fin du void() faire à nouveau noInterrupts(). Il faudra évidement faire un attachInterrupt() dans le setup() ou dans loop(), cela dépend de ce que tu veux faire.

super ca m’aide bcp !! ah la jsuis content !!
En fait le probleme est simple… en théorie

J’ai trois fonctions (ouvrir, fermer, et stop) qui chaqune actionne different relais avec différents delays .
Lorsquen que j’appuis sur la telecomande si le portail bouge pas, je veux qu’il souvre ou qu’il se ferme en fonction de l’etat précedent… jusque la tout vas bien ! mais si j’appuis sur la telecommande et qu’il est en mouvement je veux qu’il stoppe… et la ca marche pas puis qu’il y a des tempos entre chaque relay…du coup arduino ecoute plus l’entrée >:(

Donc si j’ai bien compris je peux declarer une interuption qui fait la fonction stop des que le pin 3 ( barriere ir) est a l’état haut mais que sur mon void fermer() ? c’est bien ca ?

Dans ce cas apres si interuption externe interviens (qui stoppe tout) pendans ma fonction fermer le programme ne reprendras t il pas a sa position dans la fonction fermer ?

Bon je débute sous arduino et j’ai utiser ardublock et blocly arduino pour faire mes premières lignes de code !!

C'est peut être un peu violent d'interdire ou d'autoriser les interruptions en bloc. Il peut y avoir des effets de bord indésirables. Exemple au hasard : les timers sont des générateurs d'interruptions.

Les interruptions peuvent se gérer plus finement, une par une.

L'organisation du micro est la suivante : 1) sei() ou cli(), renommées par Wiring (va savoir pourquoi) interrup() et nointerrupt(), permettent d'autoriser ou de bloquer les interruptions mais ce n'est pas suffisant. 2) Des interruptions dans un micro il en existe un grand nombre et pas seulement int0 et int1. Chaque "type" d'interruption doit être expressément autorisé individuellement.

La fonction attachinterrupt active sei() s'il n'est pas déjà activé et active ausi les interruptions spécifiques à int0 et int1.

Donc si les interruptions qui doivent être "bloquées" sont int0 ou int1, il " faut et il suffit" de lire la datasheet du micro et de modifier le bit qui va bien dans le registre qui gère int1 et int2.

Le problème ce n'est pas l'usage de l'interruption, c'est l'usage de delay(). Lorsque tu vas sortir de l'interruption tu reprendra l'exécution là ou elle c'était arrêtée c'est-à-dire dans ton delay(). Lorsqu'on veut des fonctions qui répondent à plusieurs actions à n'importe quel moment il faut faire en sorte qu'il n'y ait pas de fonction bloquante. Il ne faut pas utiliser delay(). Il faut gérer les événements liés au temps avec millis() qui permet de continuer le déroulement du code et le contrôle des entrées/sorties. Cela implique aussi une architecture de ton programme légèrement différente.

ozitoune: Bonjour, j'aimerai savoir si il est possible de faire une interuption externe (par une input de l'arduino) que dans un sous programme... ?

Je m'explique que l'interuption ne soit valide que si l'arduino execute un void() precis.

Merci de vos réponses

Bonjour,

Je pense qu'il y a une erreur d'analyse. Tu veux que ton portail stoppe lors de la réception de la télécommande uniquement lors de la fermeture/ouverture? Et tu en deduis que tu dois interdire les interruption dans les autres cas. En fait sauf cas particulier il est déconseillé de jongler avec les sei() cli() et autres attach/detach interrupt en cours d'exécution.

En fait ton cas très banal, tu veux que ton interruption n'exécute cette action que dans certains cas. Pour cela il suffit d’informer l'interruption de l'état du programme principal. Par exemple: tu déclares une variable globale:

bool mouvementEnCours=false;

au début de la procédure de fermeture

mouvementEnCours=true;

à la fin de la procédure de fermeture

mouvementEnCours=false;

Dans le programme d'it

if (mouvementEnCours)
 Stop();

Remarque: je ne sais pas ce que c'est qu'un 'void()'. Tu veux dire une procédure?

Autre remarque: je ne vois pas en quoi ce serait gênant d'arrêter le moteur même s'il est déjà arrêté. Ce serait même plus sécurisant car tu ne te poses pas de question, tu arrêtes.

Il suffit, comme il a été dit, de valider l'interruption qui t'intéresse tout le temps, et de définir un drapeau lorsqu'elle intervient, drapeau que tu remets à zéro dès que tu as lancé le traitement ad hoc. Par exemple:

ISR(){
  button_flag = 1;
}

void traitement_interruption(){
  if (button_flag){
    ...
  }
}

Pour ce qui est de la gestion de cet appui, tu as plusieurs solutions: tu peux arrêter le moteur quoi qu'il arrive, un excès de sécurité ne peut nuire, surtout sur un projet qui peut broyer quelqu'un. Je dirais même que dans ce cas comme dans d'autre (je bosse sur un truc avec un laser de 200mW en ce moment), la sécurité doit passer avant. C'est à dire qu'il faudrait tester en priorité les capteurs, actionneurs et cas liés à la sécurité avant ceux liés au fonctionnement lui-même. Fin de la parenthèse.

Tu peux définir une variable d'état qui "boucle" d'un état à l'autre. Par exemple:

byte door_state = 0;
// état 0 == fermé
// état 1 == en cours d'ouverture
// état 2 == ouvert
// état 3 == en cours de fermeture

Tu peux même gérer le truc plus finement si tu en as besoin, faire des états pour les moments transitoires, comme: fermé, ouverture demandée, en cours d'ouverture, ouverture terminée (capteur détecté), ouvert, etc. Ensuite il ne te reste plus qu'à tester au cas par cas et adapter la manière dont ton programme réagit.

Et pour finir, comme des chiffres c'est vite délicat à gérer, des #defines seront bienvenus:

#define DOOR_CLOSED        0
#define DOOR_OPENNING      1
#define DOOR_OPENED        2
#define DOOR_CLOSING       3

byte door_state  = DOOR_CLOSED

ISR(){
  button_flag = 1;
}

void loop(){
  if (button_flag){
    if (door_state == DOOR_CLOSED){
      // open the door
    } else if (door_state == DOOR_OPENNED){
      // close the door
    } else if (door_state == DOOR_OPENNING || door_state == DOOR_CLOSING){
      // stop the move
    }
  }
}

Je persiste et signe l'interruption n'est à mon sens pas la bonne solution pour gérer ce type de problème. A la fin de l'interruption on retourne dans la fonction qui a été interrompue et on risque donc de rallumer (sauf à coder comme un cochon en réinitialisant tout). C'est un bête problème d'automate qui peut être traité simplement en bannissant les delay(à remplacer par millis) et en analysant avant de coder toutes les conditions de fonctionnement.

Merci de vos réposes !

C'est un peu ce que j'avais fait sauf que je n'avais pas differencier ouverture de fermeture pour simplifier ! Et c'est meme plus de sécurité...

Par contre le probleme c'est qu'il dois y avoir des tempo dans mes actions (phare s'allume avant , retard d'un venail sur l'autre, et duré d'alimentation des moteurs)

Du coup je ne comprend pas si il n'y a plus le boouton appuyé il n'y a plus le flag a 1 donc le programme bouclera sur le premier if et ne fera rien. Donc si je comprends bien dans ton exemple il faut que j'utilise delay et non millis ? car avec millis cela fera un passage mais apres vu qu'on ne sera plus dans le second if on bouclera sur le premier et millis ne s'incerementeras pas non ?

Sinon fdufnews comment faire sans interuption ? en sachant que le portail va souvrir une fois par jour ou 2 a tout casser ?

Merci