interruption, plantage

bonjour,
j’ai simplifié mon code actuelle pour être plus lisible,
avant ça plantait au bout de quelque temps,mains maintenant j’arrive ale faire planter a chaque fois en modifiant le code, en espérant que ce soit le même problème…
je l’ai fait a partir de bout de code fait ici :o)
j’ai un lcd qui affiche la température quand j’appuis sur un bouton, si j’appuis a nouveau l’écran s’éteint
en parallèle, il affiche la température sur la sortie série.

#include <Wire.h>      
#include <LiquidCrystal_I2C.h>
#include "cactus_io_DHT22.h"
#define DHT22_PIN 2     // what pin on the arduino is the DHT22 data line connected to
DHT22 dht(DHT22_PIN);
LiquidCrystal_I2C lcd(0x27,20,4);  
int photocellPin = 0;     // La photo-résistaance raccordée sur la PIN A0 (avec une résistance Pull-Down de 10K Ohms)
int lumiere;
int boutonPin  = 3 ;
boolean affiche=false;
long debouncing_time=15;
volatile unsigned long last_micros;

void setup(void)
{
  lcd.init();                      
  dht.begin();
  Serial.begin(9600);  
  pinMode(boutonPin, INPUT_PULLUP);
  attachInterrupt(1, debounceinterrupt, FALLING);
}

void debounceinterrupt(){
  if ((long)(micros()-last_micros)>=debouncing_time*1000){
    interrupt();
    last_micros=micros();
  }
}

void interrupt(){
  affiche = not(affiche);
  Serial.println("affiche");
  if (!affiche)  {
    lcd.noBacklight(); //eteindre le retro-eclairage
    lcd.noDisplay(); 
  }
   else  {
   lcd.backlight(); //eteindre le retro-eclairage
   lcd.display(); 
   lcd.clear();
   lcd.setCursor(0,0); lcd.print("Lumiere=");
   lcd.setCursor(9,0); lcd.print(lumiere); 
  };
}

le programme affiche la température par le port série et quand j’appuies sur le bouton, il affiche “af” (le début de “affiche”) sur la sortie série et ça fige.

si je supprime Serial.println(“affiche”); c’est pareil, ça fige

qu’est ce que je fait de pas bien du tout ? :o)

merci

Bonjour,

Première chose : Il manque la fonction loop() qui est la boucle principale du programme... Sans celle-ci il est compliqué pour un programme de s'exécuter.

Deuxième chose : Dans une routine d'interruption, il faut faire un minimum de choses.
Comme l'indique le mot "interruption", il s'agit d'un arrêt momentané du déroulement du programme pour traiter quelque chose qui ne peut attendre.

Il faut donc que ce code soit le plus court possible. Tu détectes que l'on a appuyé sur un bouton ? Tu peux stocker l'info dans une variable et traiter celle-ci dans ta boucle principale. (Qui manque, je le rappelle )

Voilà deux pistes à explorer à mon sens...

Bonne continuation,

Coyotte

Bonjour,
La fonction interrupt est appelée par l'ISR (debounceinterrupt) donc interrupt fait partie de l'ISR et à ce titre les IT sont masquées. Problème Serial.print fonctionne sous interruption.
Ensuite comme expliqué ci-dessus l'ISR doit être concise. Comme nous n'avons qu'une vue parcellaire de ton programme c'est difficile d'en dire plus.

oups, désolé, un problème de de copie.
je vais décrire mon problème du début.
dans le loops j’ai la lecture d’une sonde ds1820, d’un dht22, et j’enregistre toutes les 5 secondes sur une carte sd, j’ai un bouton qui me permet d’allumer le lcd et de l’éteindre.
hier j’ai mis l’arduino en marche pour voir combien de temps il pouvait marcher avec mes piles, donc de tps en tps, j’appuyais sur le bouton pour voir les données sur le lcd mais parfois le lcd répondait pas a l’appuis du bouton comme s’il avait planté, obligé d’appuyer sur reset pour que ça remarche…
ça pouvait marcher plusieurs heure, donc je me demandais si c’était pas l’appuis du bouton qui faisait planter…
dans la fonction d’interruption, j’avais juste un “entier” qui s’incrémentait genre:

compteur = compteur + 1
if compteur==3 {compteur=0}

et dans le loop, j’éteins le ldc si compteur=0, affiche les données température si compteur=1 et l’humidité si compteur=2.

après, je voulais plus de “réactivité” a l’appuis du bouton du mon code ou je mets direct l’affichage du lcd dans l’interruption. (j’avais essayé d’enlever le “print” de l’interruption mais ça fige pareil), il faut aussi les enlever partout ailleurs du programme quand il y a une interruption ?

hello
je n’avais pas lu tout le post

voici donc ton bout de code modifié pour qu’il tourne sans les sondes et le reste
charge le et regarde le moniteur ( en 115200)

j’ai modifié un long par unsigned long.
j’ai modifié le nom des fonctions ( pour moi, tes noms prêtent à confusion)
j’ai initialisé last_time dans le setup
j’ai rajouté une loop
j’ai rajouté un flag pour que l’interruption soit la plus courte possible
j’ai allongé le temps d’anti rebonds pour ce test car le temps d’affichage sur moniteur était plus long que l’anti rebonds
j’ai testé sur nano et lcd16*2, et bien sur le moniteur.

à toi de remettre en ordre pour ta configuration
j’ai modifié l’entrée 3 pour la 2
j’ai modifié le lcd

#include <Wire.h>     
#include <LiquidCrystal_I2C.h>
//#include "cactus_io_DHT22.h"
//#define DHT22_PIN 3     // what pin on the arduino is the DHT22 data line connected to
//DHT22 dht(DHT22_PIN);
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
int photocellPin = 0;     // La photo-résistaance raccordée sur la PIN A0 (avec une résistance Pull-Down de 10K Ohms)
int lumiere;
int boutonPin  = 2 ;
boolean affiche=false;
long debouncing_time=50;
volatile unsigned long last_time;
volatile boolean flag=false;
void setup(void)
{
  lcd.begin(16, 2);                 
 // dht.begin();
  Serial.begin(115200); 
  pinMode(boutonPin, INPUT_PULLUP);
  attachInterrupt(0, isr_anti_rebonds, FALLING);
  last_time=millis();
}

void isr_anti_rebonds(){Serial.print("I");
  if ((unsigned long)(millis()-last_time)>=debouncing_time)
  {
    flag=true;
    last_time=millis();
  }
}
void loop(){if (flag) {aiguillage();flag=false;}}

void aiguillage(){
  affiche = !affiche;
  Serial.println("affiche");
  if (!affiche)  {
   Serial.println("lcd off");//eteindre le retro-eclairage
   // lcd.noDisplay();
  }
   else  {
  Serial.println("lcd on");
   lcd.clear();
   lcd.setCursor(0,0); lcd.print("Lumiere=");
   lcd.setCursor(9,0); lcd.print(lumiere);
  };
}
}

merci, je vais essayer les modif

sinon, je veux bien comprendre que l'interruption doit être la plus courte possible au cas ou il y aurait plusieurs appuie sur le bouton, mais pourquoi ça plante quand je mets

  lcd.setCursor(0,0); lcd.print("Lumiere=");

dans l’interruption dès le premier passage ?