Loading...
Pages: [1]   Go Down
Author Topic: Deuligne Snootlab et Interruptions  (Read 255 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Full Member
***
Karma: 0
Posts: 137
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

J'ai un problème de fonctionnement de mon programme quand j'essaie d'utiliser les interruptions avec le Deuligne.

Ci joint mon code :
Code:
#include "Wire.h"
#include <Deuligne.h>
#include <Button.h>

#define SWI 2 // Intr 0 = Pin 2
#define CHA 6
#define CHB 7
#define REDLED 13

// initialize the library with the numbers of the interface pins
Deuligne lcd;

// valeur determinee par la rotation de l'encodeur
int encoderPos = 0;
// precedente position de A
int previousStatus = LOW;
// etat actuel de A
int currentStatus = LOW;
// etat actuel de S
int S = HIGH;
// position du servomoteur (angle)
int servoPos = 90;

//create a button object at pin 2
/*
|| Wiring:
|| GND -----/ ------ pin 2
*/
Button button = Button(SWI,PULLUP);

void setup()
{
  pinMode(CHA, INPUT);
  pinMode(CHB, INPUT);
  pinMode(SWI, INPUT);
  pinMode(REDLED,OUTPUT); //debug to led 13
 
  Wire.begin(); // join i2c bus (address optional for master)
  lcd.init(); // initialisation du panneau LCD (obligatoire)
 
  // print a welcome message
  lcd.clear();
  lcd.print("*** WELCOME! ***");
  lcd.setCursor(0,1);
  lcd.print("Initializing");
 
  attachInterrupt(0, menu, FALLING);
 
}

void loop()
{
 
  lcd.setCursor(0, 0);
  checkValue();
  lcd.print(encoderPos);
 
  /*if(button.isPressed()){
digitalWrite(13,HIGH);
  }else{
digitalWrite(13,LOW);
  }*/
}

void checkValue()
{
  // on regarde ce qu'on recoit sur la pin A de l'encodeur
  currentStatus = digitalRead(CHA);
  // si on a un front montant (passage de LOW a HIGH)
  if ((previousStatus == LOW) && (currentStatus == HIGH))
  {
    // on regarde l'etat de B pour connaitre le sens :
    if (digitalRead(CHB) == HIGH)
    {
      encoderPos++;
    }
    else
    {
      encoderPos--;
    }
  }
  // on reinitialise prevA pour le prochain tour
  previousStatus = currentStatus;
}


void menu() {
  /*int selected = 3;
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Turn the knob to");
  lcd.setCursor(0,1);
  lcd.print("select an option");*/
  digitalWrite(13,HIGH);
 
  lcd.clear();
  delay(2000);
  // display options
  /*while (!button.isPressed()) {
    selected += encoderPos;
    if (selected<0) selected=3;
    if (selected>3) selected=0;
    if (moved) {
      lcd.clear();
      lcd.setCursor(0,0);
      switch(selected) {
        case 0:
          lcd.print("Change Units    ");
          break;
        case 1:
          lcd.print("Backlight On/Off");
          break;
        case 2:
          lcd.print("Logging On/Off  ");
          break;
        case 3:
          lcd.print("Exit Settings   ");
          break;
      }
    }
  }
  // when button is pressed...
  lcd.clear();
  switch(selected) {
    case 0:
      settingsChangeUnits();
      break;
    case 1:
      settingsChangeBacklight();
      break;
    case 2:
      settingsChangeLogging();
  }*/
}

Quand le programme commence en bougeant le rotatif j'ai bien la valeur de encoderPos qui change sur le LCD.
Mais quand j'appuie sur le bouton de l'encodeur (SWI), j'ai l'impression que le programme se fige, soit il ne fait rien, soit il est dans une boucle infinie mais quoi que je fasse il ne se passe rien.
Je suis obligé de faire un reset pour récupérer la main.

Quelqu'un aurait une idée?
Logged

France
Offline Offline
Edison Member
*
Karma: 12
Posts: 1801
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Pas de delay() dans les routines de traitement d'interruption.

De manière générale, une routine d'interruption doit être courte car elle bloque l'exécution de tout le reste. Donc, la bonne pratique veut que dans la routine d'interruption on positionne un drapeau qui indique que l'on a reçu une interruption, on traite ce qui doit être traité immédiatement (opération critique d'un point de vue temporel). En suite on rend la main (retour à l'exécution de loop normalement) et dans loop on test périodiquement (à chaque itération ou pas) si le drapeau est levé et là on appelle les fonctions liées au traitement de cette interruption.

Typiquement dans ton cas l'affichage n'a pas besoin d'être fait sous interruption d'autant que cela risque d'interférer avec l'affichage que tu fais déjà dans loop. Imagine ce qui peut se passer si tu es interrompu pendant la mise à jour de la valeur sur l'afficheur.
Logged

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

Ok, mon idée est "d'appeler" un menu quand j'appuie sur le bouton poussoir de mon encodeur, et après de sélectionner les éléments du menu en le tournant à gauche ou à droite.

J'ai essayé de m'inspirer de ce code où il utilise une interruption pour rentrer dans son menu:

https://gist.github.com/3783602

Quel est la solution pour réaliser ce que je veux alors?

Du coup, en réfléchissant, il vaut mieux que je fasse un:

If (bouton poussoir pressé)
{entrer dans le menu en appelant la fonction menu()}

Non?

Mais j'aurais bien aimé comprendre pourquoi dans son code il a choisit l'interruption et la classe Button
« Last Edit: January 25, 2013, 06:04:59 am by john_lenfr » Logged

France
Offline Offline
Edison Member
*
Karma: 12
Posts: 1801
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Une interruption c'est une cause de complication. Cela peut arriver n'importe quand et donc cela interrompt ce qui était en cours.
C'est justifié si il y a des contraintes temporelles fortes. Sinon c'est plutôt une source de tracas.
S'il n'y a rien qui dans loop risque d'être bloquant il sera 1000 fois plus facile de gérer le poussoir par scrutation que par interruption. Cela évitera le genre d'asynchronisme dont je parlais dans le post précédent.
Logged

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

Je pense que sur le coup je n'ai pas trop réfléchi je me suis dit je vais copier le code pour essayer de faire quelque chose mais j'ai mal copié et ce n'était pas approprié.

Par exemple, dans quel cas il est judicieux d'utiliser l'interruption, je veux dire un cas concret?
Logged

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

Bonjour,

Par exemple, dans quel cas il est judicieux d'utiliser l'interruption, je veux dire un cas concret?
Un tachymètre pour compter un nombre d'impulsion, un bouton d'arrêt d'urgence, un capteur de vide sur un robot, ...
Logged

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

Pages: [1]   Go Up
Print
 
Jump to: