Dernière modification par antek ; 18/03/2017 à 13h36.
En étant de mauvaise fois, c'est une discussion qui peut durer longtemps !
Tout projet flou conduit à une connerie précise !
...personnellement j'en compte deux, qui ont été fournies aux messages #2&3. La première avec l'inconvénient que cela rend la programmation moche, la seconde avec l'inconvénient que cela réinitialise les variables. Est-ce que tu vois d'autres inconvénients qui te font dire que la demande n'a pas de solution?
#2...personnellement j'en compte deux, qui ont été fournies aux messages #2&3. La première avec l'inconvénient que cela rend la programmation moche, la seconde avec l'inconvénient que cela réinitialise les variables. Est-ce que tu vois d'autres inconvénients qui te font dire que la demande n'a pas de solution?
En langage haut niveau ça à l'air de marcher, mais on ne sait pas ce que ça donne dans le vrai déroulement du programme machine.
#3
Entre le début du "main" et l'adresse de reset il y a une grande différence
Dans tous les cas les µC 8 bits n'ont pas d'adresse de retour d'interruption modifiable.
C'est un programme qui peut effectuer un branchement.
Le mécanisme, dans le micro, ne permet pas de faire ça.
Lorsqu'une interruption est déclenché, le compteur programme est empilé ainsi que les variables en cours. Le programme d'interruption s'exécute. Puis à la fin tout est depilé ; le compteur programme, pour revenir où on était avant le programme d'interruption et évidemment ainsi que l'état des variables pour revenir sainement.
S'amuser avec le compteur programme, c'est possible mais c'est comme s'amuser à faire des débordement de pile contrôlé avec tous les problèmes que ça peut amener (perdre la valeur d'une variable au retour de l'interruption etc)... Autrement dit, lorsqu'on en est à envisager cette solution, c'est qu'on s'est planter dans l'algorithme ou la conception global de son programme.
Oui, c'est amusant en effet et à pratiquer dans un but formateur !
Et en assembleur de préférence, pas avec Arduino.
Dernière modification par antek ; 18/03/2017 à 16h52.
Bonjour Forhorse,
Je vois que mon sujet pose plusieurs quiproquos, c'est pourquoi je voudrais vous clarifier un peu ce que je voulais faire par cette interruption.
Etant amateur de programmation, j'ai eu besoin de faire une réinitialisation de mon système dès que j'appuie sur un bouton précis, mais le problème résidait dans le fait que j'avais plusieurs conditions et délais dans mon programme ce qui nécessitait le besoin d'une interruption pour bloquer touts les instructions.
Je pense que tu confonds avec Pinguino, du même genre qu’Arduino, mais pour PIC. De toute façon, toutes ces cartes sont programmables dans le langage qu’on veut...
Je pensais à ces truc là :
https://software.intel.com/en-us/iot.../curie/dev-kit
Ben oui.
Pour répondre à ta question : tu actives le watchdog et tu entres dans un while(1). Tu auras un reset qui va te faire redémarrer depuis le début.
Je ne m’étalerais pas sur le débat IT ou pas IT pour les boutons poussoirs ni sur la qualité du programme que se propose de réaliser l'auteur du post ...
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
Ce serait bien que tu précises à qui/quoi tu réponds.
Idem tu devrais préciser si c'est simplement par manque de compétence pour répondre ou s'il y a d'autres raisons... elles sont peut-être claires dans ta tête, mais on n'est pas dans ta tête.
la réponse m'intéresse au plus haut point : si on fait un polling du bp ou tout changement sur une pin digitale dédiée dans le loop, changement qui appelle la fonction qui est mon pgme principal : en assembleur c'est quoi : un call, un goto, un gosub ?
tant que ma fonction qui contient des delay n'est pas terminée, le changement sur la pin n'est pas pris en compte
inverse: le loop est mon programme principal, et apres chaque delay, appel de la fonction"changement d'état pin d2"
je voudrais ajouter un bp : l'arduino est alimenté, rien ne se passe tant qu'on n'a pas appuyé sur le bp, appui+relache : l arduino lance son pgme, si on appuie de nouveau il devrait s'arreter, il y a desà part un toggle bp externe a base de 4093 et transistor qui alimente ou coupe le 5v de l'arduino à n'importe quel moment..Code:delay(4000) dans le "loop" void loop() { myGLCD.drawBitmap(0, 0, arduino_logo, 84, 48); delay(4000); for (int i=0; i<2; i++) { myGLCD.invert(true); delay(500); myGLCD.invert(false); delay(500); } delay(4000); myGLCD.clrScr(); myGLCD.drawBitmap(0, 0, arduino_logo, 84, 48); delay(4000); for (int i=0; i<2; i++) { myGLCD.invert(true); delay(500); myGLCD.invert(false); delay(500); } delay(4000); }
Merci
Dernière modification par Antoane ; 24/03/2017 à 08h12. Motif: Ajout balises code
merci
Tout sauf un gosub.
Pour le programme, j'avais mis un seul main et une fonction d'interruption reset.
Enfin je crois que plus facile que ça tu meurs X)
Bonne journée et merci tout le monde )
@elektrax,
Je ne comprends pas bien ta question, tant elle est noyée dans ton explication.
Quoi qu'il en soit, tu viens de mettre en évidence les limites de la méthode du polling :
Tant que tu attends dans une boucle delay() et ton micro est complétement figé pendant ce temps là. Je ne dis pas que la méthode du polling ne fonctionne pas ! Je dis que là tu as le cas de figure où c'est très embêtant.
Si tu ajoutes un événement via un bp, il faudra que l'utilisateur appui dessus au bon moment.... entre tous les delay() ce qui est foutu d'avance ici.
Avec la méthode polling, même sans tempo, plus le programme s'allonge et plus on s'approche du problème inévitable ; qui est que l'utilisateur ne peut appuyer sur le bouton que pendant un moment très précis dans le programme. Cette méthode fonctionne que pour des programmes cours (dans le sens du temps.)
Personnellement, dans tous mes développements, j'abuse des interruptions le plus possible comme ça je n'ai plus les problèmes du polling et lorsque le micro a fini ce qu'il devait faire, au lieu d'attendre dans une tempo moi je le mets en veille et il se réveillera par une interruption.
En pseudo code ça donnerait un truc comme ça (attention le delay de Arduino bloque peut être toutes les interruptions, faut peut être refaire une tempo sur mesure ) :
Avec une approche de ce genre, si tu appuies sur bp2 et même si tu es dans bp1 avec tous les tempo, ça sera pris en compte lors du prochain tour de boucle du switch.Code:int etat; fonction_interruption_bp() { switch(quel_flag_du_port_a_été_levé) { case 0 : etat = 1; break; /* bp1 appuyé */ case 1 : etat = 2; break; /* bp2 appuyé */ case 2 : etat = 3; break; /* bp3 appuyé */ case 3 : etat = 4; break; /* bp4 appuyé */ default : etat = 0; } } fonction_bp1() { myGLCD.drawBitmap(0, 0, arduino_logo, 84, 48); delay(4000); for (int i=0; i<2; i++) { myGLCD.invert(true); delay(500); myGLCD.invert(false); delay(500); } delay(4000); myGLCD.clrScr(); myGLCD.drawBitmap(0, 0, arduino_logo, 84, 48); delay(4000); for (int i=0; i<2; i++) { myGLCD.invert(true); delay(500); myGLCD.invert(false); delay(500); } delay(4000); } fonction_bp2() { eteindre_afficheur(); } int main () { while(1) { switch(etat) { case 1 : fonction_bp1(); break; /* bp1 appuyé */ case 2 : fonction_bp2(); break; /* bp2 appuyé */ case 3 : fonction_bp3(); break; /* bp3 appuyé */ case 4 : fonction_bp4(); break; /* bp4 appuyé */ default : veille(); } } }
ps : ta fonction qui affiche peut être optimisé
Là où il n'y a pas de solution, il n'y a pas de problème.
Merci Vincent
Je saisis à peu pres le sens de ton code, je n'ai pas étudié la fonction switch case d'arduino , j'y ai bien pensé un jour...
j'expérimenterai ton exemple de code dans les prochaines semaines, merci
merci
En pseudo code ça donnerait un truc comme ça (attention le delay de Arduino bloque peut être toutes les interruptions, ) :
C'est l'inverse. Dans le cas de l'Arduino, delay() utilise des interruptions de priorité inférieure à celles disponibles pour le programme. Donc les interruptions modifient les temporisations produites par delay().
Un civet, un plat de côtes et puis, glissez-moi une petite paupiette avec.( Lino Ventura)
Merci pour l'info, ne me servant pas de Arduino, je ne suis jamais allé voir comment cette fonction delay était faite. Cest pour ça que j'avais écrit peut être dans ma phrase.
Ps: il manque "état=0;" à la fin des fonctions bp1 et bp2 dans le pseudo code. Sans ça il n'y a jamais de mise en veille.
Dernière modification par Vincent PETIT ; 25/03/2017 à 08h37.
Là où il n'y a pas de solution, il n'y a pas de problème.
bonjour,
état=0 pour les trois boutons poussoirs ? si oui comment cela fonctionne ?
Cependant, je souhaitait l'ajouter pour un bouton avec 2 fonctions (Premier appui = fonction 1; Deuxième appui = fonction 2).
Faut pas tout confondre ... pooling ne veut pas dire delay() ... la limitation n'est pas dû au polling mais à l'utilisation de delay() (le delay() c'est le mal...)Quoi qu'il en soit, tu viens de mettre en évidence les limites de la méthode du polling :
Tant que tu attends dans une boucle delay() et ton micro est complétement figé pendant ce temps là. Je ne dis pas que la méthode du polling ne fonctionne pas ! Je dis que là tu as le cas de figure où c'est très embêtant.
refais la même chose avec des millis() et oh miracle, le pooling fonctionne à merveille et laisse les IT pour les choses vraiment urgentes ...
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>
1) La variable etat change de valeur dans fonction_interruption_bp(), une fois sortie de cette fonction tu repars dans le programme principale main et là le switch va choisir l’exécution qui va bien.
2) Imagine que le switch t'envoie dans la fonction fonction_bp1() et qu'a la fin de celle-ci tu as état=0; alors une fois sortie de cette fonction tu repars dans le programme principale main et là le switch va choisir la mise en vieille du micro.
3) Si tu appuies sur un bouton, tu créais une interruption, le micro sort de veille et te voilà à l'étape 1)
Justement, je ne confonds pas tout, bien au contraire, et je vois que tu n'as pas lu tout ce que j'ai écrit :Faut pas tout confondre ... pooling ne veut pas dire delay() ... la limitation n'est pas dû au polling mais à l'utilisation de delay() (le delay() c'est le mal...)
refais la même chose avec des millis() et oh miracle, le pooling fonctionne à merveille et laisse les IT pour les choses vraiment urgentes ...
Le polling ne fonctionne pas ou fonctionne très mal dès lors que ton programme fait quelque chose de long (ou attend c'est le pire des cas).Envoyé par Vincent PETITAvec la méthode polling, même sans tempo, plus le programme s'allonge et plus on s'approche du problème inévitable ; qui est que l'utilisateur ne peut appuyer sur le bouton que pendant un moment très précis dans le programme
Exemple :
Dans ce pseudo code, aucune tempo ! Et on est pourtant bien dans du polling.Code:int main () { while(1) { if(boutton1 == 1) { // faire quelque chose } ... ... // Faire un long calcul // Faire de l'affichage graphique // Remplir une mémoire EEPOM // Faire des trucs tout simplement !!! SANS TEMPO delay() ou millis() ... ... } }
Quel est le problème ?
Si on est hors du if le micro est occupé et tu peux rester debout les pieds joints sur le bouton, on est d'accord qu'il ne se passera rien.
Donc pour rentrer dans le if il faut soit- Que l'utilisateur garde le doit appuyé sur le bouton jusqu'à ce que le micro arrive au if. Sensation de non réactivité.
- Que l'utilisateur appuie sur le bouton pile poils quand le micro arrive au if. En apparence ça fonctionne super bien mais c'est un super coup de bol.
En revanche si le programme est court ou s'exécute rapidement alors la fréquence de passage sur le if sera tellement grande que cela ne posera pas de problème. D'où ce que j'ai écrit :
Envoyé par Vincent PETITCette méthode fonctionne que pour des programmes cours (dans le sens du temps.)
Là où il n'y a pas de solution, il n'y a pas de problème.
OK, pour des cas simples (sans que ce sois péjoratif) je suis d'accord avec ce que tu dis, mais je trouve dommage de renoncer à :
> un filtrage des entrées BP
> pouvoir détecter un double appui
> un appui long
> un appuis BP1+BP2
> etc.
En fait, pour moi (ce n'est donc que mon avis) un main() doit s’exécuter en un temps donné au maximum (la granularité de ton système), la boucle est cadencée via l'IT d'un timer, cela implique donc de gérer un % de CPU.
La granularité est donnée par tes contraintes temps réel (10us ? ... 1ms ? ... 10ms ? ... 1s? ... 30 minutes ?)
NB: je prends souvent 1ms.
C'est je pense juste une question de point de vue et de savoir ce que l'on veut pouvoir faire ou pas.
Dernière modification par Seb.26 ; 02/05/2017 à 11h46. Motif: un 's' qui écorche mon oeil ...
<< L'histoire nous apprend que l'on apprend rien de l'histoire. >>