Go Down

Topic: Uno Chrono Interupt (Read 575 times) previous topic - next topic

maxmax39

Bonsoir,
je suis sur un problème.  Un uno avec un LCD03 (i2c), 2BP, 1led

Pour le cablage tout est ok.  J'aimerai faire un chronomètre qui démarre avec le BP0 (en I2) et qui se termine avec le BP1(en I3).  Le tout géré par des interruptions.

Code: [Select]

#include <MsTimer2.h> // inclusion de la librairie Timer2
#include <Wire.h>
#define adresseLcd 0x63               //adresse lcd03

const int LED=4; //declaration de la led
const int BtStart = 0; // Interrupt 0 est sur la pin 2
const int BtStop = 1; // Interrupt 0 est sur la pin 3
int Timer1, Timer2, TimerVal = 0;

void setup() 
{
  Serial.begin(9600);
 
  pinMode(LED, OUTPUT); //met la broche en sortie
  MsTimer2::set(1000, InterruptTimer2); // période 1000ms
  MsTimer2::start(); // active Timer 2

  attachInterrupt(BtStart, vStart, RISING); // attache l'interruption externe n°0 à la fonction vStart
  attachInterrupt(BtStop, vStop, RISING); // attache l'interruption externe n°1 à la fonction vStart

  Wire.begin();
  Wire.beginTransmission(adresseLcd);
  Wire.write((byte)(0x00)); //null
  Wire.write((byte)(0x01)); //go home
  Wire.write((byte)(0x13)); //turn on backlight
  Wire.write((byte)(0x0C)); //clear screen
  Wire.write("En attente...");
  Wire.endTransmission();
//c' est uniquement cela qui restera affiché...
}
void loop(){ // debut de la fonction loop()


}
void write2i2c ( )
{
  Serial.println("1er Passage");
  //Wire.begin();
  Wire.beginTransmission(adresseLcd);
  Wire.write((byte)(0x00)); //null
  Wire.write((byte)(0x01)); //go home
  //Wire.write((byte)(0x0C)); //clear screen
  Wire.write("1er Passage");
  Wire.endTransmission();
 
}

void InterruptTimer2() { // debut de la fonction d'interruption Timer2
  digitalWrite(LED, HIGH);
  delayMicroseconds(10000); // la fonction delayMicroseconds ne bloque pas les interruptions
  digitalWrite(LED, LOW);
  TimerVal +=1;
  Serial.println(TimerVal);
//dans mon com j'ai bien les valeurs
}

void vStart() // la fonction appelée par l'interruption externe n°0   BP start
{
  TimerVal =0;
  write2i2c();
}
void vStop() // la fonction appelée par l'interruption externe n°1  BP stop
{
  Timer1 = TimerVal;
  Serial.println(Timer1);
}


Sauf que quand j'appuie sur le BP0, le programme se fige.  Ou est le problème?  Faudrait-il mettre les interruptions en disable?

Merci
Maxmax

fdufnews

#1
Dec 18, 2012, 08:24 am Last Edit: Dec 18, 2012, 08:29 am by fdufnews Reason: 1
delayMicrosecond ne bloque peut être pas les interruptions mais comme tu es déjà dans une routine de traitement d'interruption elles sont masquées.
Il serait largement préférable de lever un drapeau et de le traiter le comportement de la LED dans loop.
Même chose pour le write2i2c qui est exécuté sous interruption
De manière générale sous interruption on positionne des drapeaux, on initialise des variables. Les traitements plus long, les communications sont gérées à temps perdu dans la boucle principale lorsqu'un drapeau particulier est détecté.
Penser à déclarer volatile les variables modifiées dans les routines de traitement d'interruption

maxmax39

Ok,
je vois le principe.  Je devrais donc surtout déclarer les flags comme volatiles.
Je vais un peu me renseigner la dessus.

Merci pour la réponse

Max

B@tto

De mémoire l'i2c ne fonctionne tout simplement pas pendant une interruption.
Blog électronique : http://battomicro.wordpress.com/
Photographie : www.interactive-celebration.fr

skywodd

Bonjour,


De mémoire l'i2c ne fonctionne tout simplement pas pendant une interruption.

La librairie Wire (qui cache en réalité la librairie Twi) travaille en utilisant des interruptions et des buffers, donc pas d'I2C dans une interruption.
Des news, des tutos et plein de bonnes choses sur http://skyduino.wordpress.com !

maxmax39

Oui je m'en suis rendu compte
mais fdufnews m'a rappelé les vieux principes des ucontroleurs
trop pris l'habitude avec les languages haut niveau ;-)

2 problèmes et 2 solutions avec le forum

Merci

Go Up