[rtczero] quelle pin réveille le board

Bonjour à tous
Je m’interesse A cette librairie

J’arrive à la faire fonctionne correctement.
Simplement, je me demande quelle pin l’interrupt fonctionne

  zerortc.attachInterrupt(alarmMatch);

Ci-dessous, on ne défini pas la pin.

Je pose cette question parce que j’ai un p’uvionetre Connecte à une autre pin. A chaque fois qu’un goutte tombe, une variable est incrémentee. Je souhaiterai changer ce code pour qu’il fonctionne avec un interrupt. Quand une goutte tombe, il réveille le micro contrôleur.

Dans l’etat Actuel de mon PCB, je ne peux pas utiliser la pin ou est connecte mon pluviomètre.

Je me demandais, vu que dans le code ci-dessus, il n’y a pas de pin désignant l’interrupt de mon pluviomètre, s’il suffisant qu’une pin quelconque change d’etat Pour que RTCZero, réveille mon micro contrôleur qu’il a mis en veille préalablement?

Merci

Sur un zéro toutes les pins sauf la 4 supportent les interruptions

Salut J-M-L
Merci mais ca ne répond pas à ma question, mais peut-être que je n'ai pas été assez précis.
Déjà, j'utilise un Adafruit Feather MO avec un SMAD21.

Normalement, pour déclarer un interrupt, il faudrait faire ceci

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

On défini une pin surlaquelle l'interrupt se produira.

Avec la librairie RTCZero, on ne défini pas de pin
zerortc.attachInterrupt(alarmMatch);

Donc comment et ou se produit l'interrupt quand l'alarme est déclanchée? Normalement, une pin devrait être "stimulée"?

Etant donné que j'ai mon pluviomèetre sur une autre pin et pour compliquer le tout, sur une d'un carte SeeSaw, je me demandais si le fait qu'un pin change d'état, s'uffise pour revieller mon board, sans qu'elle soit nécessaire déclarée come interrupt.

pierrot10:
Donc comment et ou se produit l'interrupt quand l'alarme est déclanchée? Normalement, une pin devrait être "stimulée"?

Salut Pierrot

Souvenez vous que le processeur que vous utilisez dispose d'une RTC embarquée. il n'a donc pas besoin de parler à une certaine pin pour effectuer une interruption "RTC", tout se passe à l'intérieur du processeur.

Vous utilisez une librairie qui cache les choses pour vous. quand vous appelez begin() sur votre instance de RTCZero, le code de la méthode begin effectue ceci:

  NVIC_EnableIRQ(RTC_IRQn); // enable RTC interrupt 
  NVIC_SetPriority(RTC_IRQn, 0x00);

  RTC->MODE2.INTENSET.reg |= RTC_MODE2_INTENSET_ALARM0; // enable alarm interrupt
  RTC->MODE2.Mode2Alarm[0].MASK.bit.SEL = MATCH_OFF; // default alarm match is off (disabled)

on active donc l'interruption liée à l'alarme. Sur ce type de processeur, la fonction associé à cette interruption s'appelle RTC_Handler().

un peu plus loin dans le code source de la classe, vous verrez que cette fonction est implémentée et teste si le pointeur sur fonction RTC_callBack est non nul et si oui appelle cette fonction

 if (RTC_callBack != NULL) {
    RTC_callBack();
  }

La magie se trouve là, parce que si vous regardez comment on initialise RTC_callBack, c'est justement en appelant leur méthode attachInterrupt

void RTCZero::attachInterrupt(voidFuncPtr callback)
{
  RTC_callBack = callback;
}

Donc pour résumer votre code doit ressembler à cela:

include <RTCZero.h> // on importe la librairie
RTCZero rtc;  // on crée l'instance de la classe

void alarme() {
   // ici on fait ce que l'alarme doit faire
}

void setup()
{
  rtc.begin(); // initialise notre instance, et prépare l'alame

  // éventuellement mettre à l'heure

  rtc.setAlarmTime(17, 45, 10); // on dit quand on veut l'alarme
  rtc.enableAlarm(rtc.MATCH_HHMMSS); // et sur quoi on matche 
  rtc.attachInterrupt(alarme); // et on attache notre fonction ce qui initialise dans l'instance le pointeur sur fonction RTC_callBack
}

void loop() {}

quand vient le moment de sonner l'alarme, la RTC appelle son handler et comme vous avez bien initialisé le pointeur sur la fonction dans votre code, tout s'exécute


Pour l'autre question, non, vous voulez bien d'autres interruptions séparées (pas interne au microprocesseur) et donc il faudra bien déclarer ces interruptions comme d'habitude.

Notez qu'il y avait eu cette discussion concernant les interruptions en mode standby - donc à tester si ça fonctionne vraiment

Ho mille merci pour la peine que vous donnez et e m'excuse encore mille fois si je n'ai pas été précis.

Tout ceci, je l'ai fait et ca fonctionne.
Je peux initié l'insrence de RTCZero.
Je peux définir une alarme.
Par exemple j'ai une fonction qui reset mon alarme de manière à ce que toutes les 10 secondes, mon Adafruit feather MO (SAMD21) soit réveillé.

Donc tout ca s'est bon.

Par contre, c'est bien ceci que je ne comprends pas très bien

void RTCZero::attachInterrupt(voidFuncPtr callback)
{
  RTC_callBack = callback;
}

Si je veux faire un interrupt "normal", je dois le faire ainsi

attachInterrupt(digitalPinToInterrupt(pin), ISR, mode);

ou pin est la PIN qui est programmée comme interrupt
ISR est la fonction callback.

Dans ce bour de code lié à RTCZero

void RTCZero::attachInterrupt(voidFuncPtr callback)
{
  RTC_callBack = callback;
}

on ne définit pas de pin. Donc comment mon Adafruit MO est réveillé si de la façon "normal", on doit définir une pin?

Voyez-vous?

je ne vous pas pourquoi vous voulez absolument une pin pour la RTC...

c'est ce que j'explique ci dessus... La RTC tourne au sein du processeur, ce n'est pas un truc à côté. Donc quand la RTC décide qu'il est l'heure de sonner l'alarme, elle déclenche l'ISR au sein du processeur.

Là où peut-être vous êtes "enduit d'erreur" c'est que le concepteur de la classe RTCZero a jugé bon d'appeler sa méthode (au sein de sa classe hein.. il y fait ce qu'il veut, c'est la beauté des classes et du fait que tout est caché dedans) attachInterrupt() ce qui est le même nom que la fonction que vous connaissez dans le monde arduino... Mais les 2 n'ont rien à voir....

Si ça vous gêne, appelez la méthode reveilleToiFeignasse

 void RTCZero::reveilleToiFeignasse(voidFuncPtr callback)
{
  RTC_callBack = callback;
}

et dans mon code ci dessus au lieu de faire

  rtc.attachInterrupt(alarme); // et on attache notre fonction ce qui initialise dans l'instance le pointeur sur fonction RTC_callBack

vous allez faire

  rtc.reveilleToiFeignasse(alarme); // et on attache notre fonction ce qui initialise dans l'instance le pointeur sur fonction RTC_callBack

et comme ça vous serez moins confus :slight_smile:

Merci J-M-L

D'accord, je vois.

je ne vous pas pourquoi vous voulez absolument une pin pour la RTC...

En fait, je dois modifier mon code car j'ai aussi un compteur de goutte. Jusqu'à présent, dans ma loop(), je vérifie l'état de la pin où est connecté le signal du pluviomètre. Et je compte le nombre de fois que l'état change.

Mais vu que je mesure et envois les mesures toutes les heures, mon microcontrollor dort 58minutes. Donc pendant son sommeil, il ne va plus vérifier la pin où est connecté mon pluviomètre. Pour se faire, je dois donc (à moins que je em trompe) définir la pin du pluviomètre comme intterupt

volatile int goutes=0;
attachInterrupt(digitalPinToInterrupt(pin_pluviomètre), ilpleut, CHANGE);
void ilpleut(){
  gouttes++;
}

L'interrupt va receiller mon microcontrolleur, compter les gouttes (ou la quantité d'eau). Puis je remets mon microcontrolleur au repos.

De là, je me suis demandé pourquoi le RTCZero ne défini pas de pin, et donc comment il est reveillé puisqu'il utilise aussi le fonction

attachInterrupt()

ce qui est le même nom que la fonction que vous connaissez dans le monde arduino... Mais les 2 n'ont rien à voir....

D'accord, ça s'est important de le signaler :slight_smile:

C'est ca qui m'interpelle et je ne comprends pas.
Je croyais qu'un microcontrolleur ne pouvait etre réveillé que par un interrupt, dont il se définit sur une pin du microcontrolleur, non?

D'accord, mais alors comment il le réveille, avez-vous une idée?

Petite question

elle déclenche l'ISR au sein du processeur.

Qu'est-ce que l'ISR au sein du processeur?

ISRs are special kinds of functions that have some unique limitations most other functions do not have. An ISR cannot have any parameters, and they shouldn’t return anything.

Generally, an ISR should be as short and fast as possible. If your sketch uses multiple ISRs, only one can run at a time, other interrupts will be executed after the current one finishes in an order that depends on the priority they have. millis() relies on interrupts to count, so it will never increment inside an ISR. Since delay() requires interrupts to work, it will not work if called inside an ISR. micros() works initially, but will start behaving erratically after 1-2 ms. delayMicroseconds() does not use any counter, so it will work as normal.

ISR (ou un autre nom), je vois ceci comme le nom d'une fonction qui est appelée quand l'interrupt est déclanché.
Mais est-ce que c'est aussi une fonction interne au processeir qui va réveiller le microcontrolleur?

:o

Je croyais qu'un microcontrolleur ne pouvait etre réveillé que par un interrupt, dont il se définit sur une pin du microcontrolleur, non?
D'accord, mais alors comment il le réveille, avez-vous une idée?

oui il est réveillé par une interruption, mais une interruption n'a pas besoin d'arriver sur une pin dans le cas de ce processeur, car tout se passe à l'intérieur. quand vous le mettez en standby, la RTC continue en fait à tourner et c'est elle qui réveille le micro quand c'est l'heure

Qu'est-ce que l'ISR au sein du processeur?

ISR (ou un autre nom), je vois ceci comme le nom d'une fonction qui est appelée quand l'interrupt est déclanché.
Mais est-ce que c'est aussi une fonction interne au processeir qui va réveiller le microcontrolleur?

Sur ce type de processeur (dans le cadre d'Arduino) la fonction associé au signal de la RTC s'appelle RTC_Handler().

Si vous regardez dans ce fichier vous verrez tout un tas de "handlers" pour les différents sous Systèmes dont les fameux SERCOM

c'est l'implémentation de cette fonction RTC_Handler() qui est telle qu'elle appelle votre fonction à vous en testant si vous avez associé le call back

if (RTC_callBack != NULL) {
    RTC_callBack();
  }

. Techniquement donc votre fonction n'est pas en elle même ce qui est directement déclenché par l'alarme de l'horloge. Cette alarme appelle toujours en fait RTC_Handler() et c'est RTC_Handler() qui appelle votre fonction.

L'interrupt va receiller mon microcontrolleur, compter les gouttes (ou la quantité d'eau). Puis je remets mon microcontrolleur au repos.

Oui c'est bien cela qu'il faut faire.

une signal arrive sur un pin, donc ne pas prendre la pin 4 (cf mon premier post), et cela vous réveille, vous faites ce qu'il faut faire et dans la loop() (parce que une fois réveillé et l'interruption exécutée le programme va continuer là où il s'était endormi) vous devez vous rendormir

comme dit plus haut cependant, il y a eu quelques débats sur le fait que ça ne fonctionnait pas. il semblerait que ce soit corrigé mais à vérifier

--
Jean-Marc

oui il est réveillé par une interruption, mais une interruption n'a pas besoin d'arriver sur une pin dans le cas de ce processeur, car tout se passe à l'intérieur. quand vous le mettez en standby, la RTC continue en fait à tourner et c'est elle qui réveille le micro quand c'est l'heure

D'accord!

Cette alarme appelle toujours en fait RTC_Handler() et c'est RTC_Handler() qui appelle votre fonction.

Ca c'est cbien compris

le cas de ce processeur, car tout se passe à l'intérieur

Donc en effet, dans le cas de ce microcontrolleur, il est réveillé "en interne" ce qui permet de ne pas spécifié un pin grace à la fonction
RTC_Handler()
qui va elle appelé la fonction call back, que je défini.

cela vous réveille, vous faites ce qu'il faut faire et dans la loop()

dans mon cas, j'ai juste besoin d'incrémenter une variable qui va mémoriser les nombres de goutes versé par le système de goutte-à-goutte, dans l'espace d'une heure. Quand les mesures sont envoyéees, cette variable est remise à zéro pour ne compter que la quantité d'eau en une heure (ml/h ou mm/h)

Oui je vérifierai les sujets de ce débat. Mais je peux utiliser LOW ou HIGH.

Merci beaucoup J-M-L pour ces éclaircissements!!!!

J'ai une dernière question concernant les interrupts. J'ai lu, mais je peux me tromper, qu'on ne peut utiliser qu'un interrupt. Est-ce vrai? (j'ai un doute) Plus tard, j'en aurai besoin de deux. Un pour les pluviomètre qui compte les gouttes du goutteurs du verger, et l'autre pour le pluviomètre qui compte, .. comme le dit dit son nom, la pluie. Mais pour le moment compter la quantité d'eau tombée lors d'un orage n'est absolument pas important. Ce qui m'importe pour le moment est de compter la quantité d'eau (via le goutte-à-goutte) que l'arboriculteur vers dans son verger..... :slight_smile: