Je voudrais utiliser une interruption... Pour cela, j'ai branché un interrupteur sur la broche d'interruption.
Ce n'est pas l'interrupteur ni son branchement qui pose problème car ils fonctionnent si je les branche sur une autre interruption.
Voici ma commande pour initialiser l'interruption :
Quelle carte UNO, MEGA, autre ?
Quel numéro de broche d'interruption ?
Avec l'inter il y a bien une résistance de tirage soit au Vcc soit au GND ? ou sans résistance externe la pull-up interne du micro est bien activée ?
Excusez moi... Je reconnais que j'avais rien mis dans mon post... ^^
Donc, le schéma est en pièce jointe.
(par contre, l'interrupteur est un inter normalement fermé...)
La carte est une carte UNO.
Le numéro de l'interruption est le 0 (donc broche D2 de la carte Arduino).
Voici mon programme (j'ai enlevé tout ce que je pensais inutile :
/*
* Numéros des interruptions
*/
#define INT_CHANG_MODE 0
/*
* Mode :
* 0 - arrêt
* 1 - manuel
* 2 - automatique
*/
int mode = 0;
/*
* Variable contenant les noms de modes pour afficher le menu
*/
static const char modesAff[3][17] = {
" 1. Arret ",
" 2. Manuel ",
" 3. Auto " };
void setup() {
/*
* Choix du mode
*/
mode = 0;
changerMode();
attachInterrupt(INT_CHANG_MODE, changerMode, RISING);
}
void loop() {
// Boucle principale
}
/**
* Interruption permettant de changer le mode
*/
void changerMode () {
// Menu de sélection du mode (pas de problème ici)
// On initialise les interruptions en fonction du mode choisi
switch (mode) {
// Arrêt de la machine
case 0:
detachInterrupt(INT_PAS);
break;
// Mode manuel => aucune interruption
case 1:
detachInterrupt(INT_PAS);
break;
// Mode automatique => interruption des pas
case 2:
attachInterrupt(INT_PAS, MA_addPas, RISING);
break;
default:
detachInterrupt(INT_PAS);
break;
}
}
Mon problème est que l'interruption ne marche pas... J'ai l'impression que le fait d'appuyer sur le bouton (et donc d'ouvrir le contact) fait planter entièrement le programme...
Tu déclenche une interruption.
Tu fais un gros traitement dans l'interruption, déjà ce n'est pas bien : dans une interruption on fait le strict minimum, par exemple juste positionner une variable "drapeau" . Le vrai traitement se faisant dans loop() en fonction de la valeur du "drapeau".
Mais en plus dans la fonction appelée par l'interruption tu désactive l'interruption alors que tu n'es pas encore sorti de l'interruption. Ce n'est peut être pas étonnant que ça plante.
Si tu fais le traitement dans loop() tu sera déjà sorti de l'interruption donc il sera possible de la désactiver.
sawok:
Par contre, je désactive une autre interruption... Celle dont je vous parle reste active tout le temps !
Il y a peut-être autre chose, mais plus ce sera clair plus cela aura de chance de fonctionner.
A ta place, n'étant pas un grand programmeur moi-même, je découperais le programme en tout petit tests.
D'abord une interruption qui ne fait qu'afficher un message par un SerialPrint() , puis 2 interruptions et si cela fonctionne je ferais faire un traitement plus conséquent par les interruptions. La méthode des petits pas est souvent, au final, la plus rapide.
Effectivement, c'est la meilleure solution et c'est celle que j'utilise depuis le début :
tester petit morceau par petit morceau
Donc, alors, le problème est résolu pour l'interruption de changement de mode...
C'était bien le problème du 'trop de choses à faire'.
Cependant, je viens de me rendre compte que j'ai le même pour l'autre interruption (celle qui me permet de compter les pas)...
En fait, au début, avec cette seconde interruption (celle qui marchait, je n'avais pas le problème
car l'interruption ne faisait qu'incrémenter un int...
Maintenant, il me faut pouvoir mesurer l'angle (à partir d'une boussole) dans cette interruption de mesure du nombre de pas...
Mais ça ne marche pas (trop de choses à faire)..
Voici l'interrruption qui ne marche plus (car ajout de fonctionnalité) :
/**
* Interruption permettant d'incrémenter le nombre de pas
*/
void MA_addPas () {
// Si on ne peut plus enregistrer de pas, on arrête la fonction d'ajout de pas
if (MA_nbPas > MA_NB_PAS_MAX)
return;
// Sinon, on ajoute un pas au nombre de pas
MA_nbPas++;
// Et on enregistre la direction actuelle
MA_angles[ MA_nbPas - 1 ] = COMPASS_lire();
Serial.println(MA_nbPas);
Serial.println(MA_angles[ MA_nbPas - 1 ]);
}
Et voici ma fonction de lecture de la boussole :
//-----------------------------------------
// Préfixe pour la boussole : "COMPASS_"
//-----------------------------------------
/*
* Offsets sur les différents axes
*/
#define COMPASS_xOffSet -29.5
#define COMPASS_yOffSet 110
#define COMPASS_zOffSet 0
/*
* Variable de vérification d'erreur de la boussole
*/
int COMPASS_error = 0;
/*
* Variables contenant les valeurs sur les différents axes
*/
int16_t COMPASS_x, COMPASS_y, COMPASS_z;
/**
* Fonction de lecture de la direction
* @return dir Retourne la direction actuelle de la boussole en degré
*/
int COMPASS_lire () {
// On lit les valeurs sur les différents axes
boussole.getHeading(&COMPASS_x, &COMPASS_y, &COMPASS_z);
// Ajout des offsets
COMPASS_x += COMPASS_xOffSet;
COMPASS_y += COMPASS_yOffSet;
COMPASS_z += COMPASS_zOffSet;
// On calcule l'angle
float heading = atan2(COMPASS_y, COMPASS_x);
// On rectifie si c'est inférieur à 0
if(heading < 0)
heading += 2 * M_PI;
// On retourne la valeur en degré
return (int) (heading * 180 / M_PI);
}
D'après vous, comment puis-je faire, sachant qu'il faut que je mesure l'angle à chaque fois que le nombre de pas est incrémenté de 1 ?
Alors, finalement, ce que j'ai fais, c'est que quand on fait un pas, on change le nombre de pas.
Ce nombre de pas est aussi enregistré dans une variable ancienNbPas.
Lorsque les 2 valeurs sont différentes, en début du loop, je fais la mesure de la direction.
Merci pour votre aide précieuse sur cette erreur de conception des interuptions.