Bonjour à tous,
Je me tourne vers ce forum après plusieurs jours, pour ne pas dire semaines, de frustration >:(
Afin de faire un démonstrateur sur batterie de BLE iBeacon, j'ai acheté et reçu une carte Adafruit Feather nRF52 Bluefruit LE - nRF52832 PRODUCT ID: 3406.
Mon montage et mon objectif étant relativement simple, je suis parti peut être un peu trop confiant.
Voici mes besoins, mon cahier des charges initial:
- une carte permettant de faire du BLE iBeacon (Adafruit_nRF52_Arduino)
-5 boutons poussoirs câblés sur 5 GPIO distincts avec pull down 10K
-une batterie 3.6Volts
-une librairie permettant de plonger en sommeil profond le µC pour économiser la batterie et de la réveiller sur interruption déclenché par les 5 boutons poussoirs.
Je précise que dans mon cas pour atteindre mes objectifs d'autonomie, j'utilise le mode SYSTEM_OFF. Cela implique qu'à la détection de l'interruption le système redémarre comme si appui sur bouton RESET.
Jusqu'à là, j'ai réussi à faire ce que je souhaitais sans trop de difficulté et j'en étais très content.
Mais voila, le cahier des charges à évolué.
En plus de tout ce qui est déjà décrit ci-dessus, il me faut déterminer lequel des 5 boutons a été pressé et donc a déclenché le réveil via interruption car chacun de ces boutons a une fonction bien précise. Je me suis dit, facile, un "digitalread" au plus tôt dans le programme, et le tour est joué.
Erreur... En effet, je me suis vite rendu compte que le système mettait environ 2 secondes à sortir de veille. Conclusion, si je réalise un appui "normal" (~0.5 à 1 seconde, car non maintenu pendant au moins deux secondes), impossible avec cette technique de déterminer quel bouton a été appuyé. Le résultat du digitalread est toujours "0" sauf si je maintiens l'appui pendant 3 secondes.
Ayant vu sur le net la possibilité sur les cartes Arduino à base de 328P de supprimer le bootloader pour un démarrage plus rapide, c'est la première piste que j'ai explorée mais sans succès. En effet, il faudrait pour cela programmer directement le NRF52832 avec un IDE de type Segger Embedded Studio et le SDK Nordic SemiConductor. Mais on sort de l'IDE Arduino et cela dépasse mes compétences (en tout cas à court terme ).
J'ai donc décidé de me plonger dans la doc du NRF52832, et j'ai découvert qu'il y avait plusieurs registres qui me permettraient peut-être d'atteindre mon objectif dont un en particulier le registre LATCH. Aprsè des échanges sur la DevZone Nordic cela m'a été confirmé.
Mais voila, malgré toutes mes tentatives, à chaque fois que je lis ce registre j'obtiens en hex : 0xFFFFFFFF que j'appuie ou non sur un bouton ou plusieurs boutons. On m'a donc conseillé avant de plonger le µC en sommeil de réinitialiser le registre LATCH avec le code :
NRF_GPIO->LATCH = NRF_GPIO->LATCH;
Mais cela ne change rien du tout, le résultat est toujours le même: 0xFFFFFFFF.
Voici la totalité de mon code de test :
//Liste de librairies nécessaires
#include <Arduino.h>
#include <Arduino_nRF5x_lowPower.h> // LowPower Library for nRF5x
typedef volatile uint32_t REG32;
#define pREG32 (REG32 *)
#define LATCHO (*(pREG32 (0x10000520)))
#define RESETREAS (*(pREG32 (0x10000400)))
//Interruption
#define interruptPin16 16 /*Bouton 1 clavier Smilio A = Pin 16*/
#define interruptPin15 15 /*Bouton 2 clavier Smilio A = Pin 15*/
#define interruptPin7 7 /*Bouton 3 clavier Smilio A = Pin 7*/
#define interruptPin11 11 /*Bouton 4 clavier Smilio A = Pin 11*/
#define interruptPin27 27 /*Bouton 5 clavier Smilio A = Pin 27*/
#define LOOP_CYCLES 100 // Nombre de cycle
#define CYCLE_TIME_MS 50 // Délai en ms de chaque cycle
// dans ce cas tempo avant mise off du système de 100*50=5000 ms soit 5 secondes
volatile int cycles = 0;
volatile bool int1 = false;
int button1 = 0;
void intHandlerone() {
cycles = 0;
int1 = true;
}
void setup() {
//Setup interruptions
//Définition du type d'entrée pour les interruptions
pinMode(interruptPin27, INPUT);
pinMode(interruptPin16, INPUT);
pinMode(interruptPin15, INPUT);
pinMode(interruptPin7, INPUT);
pinMode(interruptPin11, INPUT);
attachInterrupt(digitalPinToInterrupt(interruptPin27), intHandlerone, HIGH);
nRF5x_lowPower.enableWakeupByInterrupt(interruptPin27, HIGH);
attachInterrupt(digitalPinToInterrupt(interruptPin16), intHandlerone, HIGH);
nRF5x_lowPower.enableWakeupByInterrupt(interruptPin16, HIGH);
attachInterrupt(digitalPinToInterrupt(interruptPin15), intHandlerone, HIGH);
nRF5x_lowPower.enableWakeupByInterrupt(interruptPin15, HIGH);
attachInterrupt(digitalPinToInterrupt(interruptPin7), intHandlerone, HIGH);
nRF5x_lowPower.enableWakeupByInterrupt(interruptPin7, HIGH);
attachInterrupt(digitalPinToInterrupt(interruptPin11), intHandlerone, HIGH);
nRF5x_lowPower.enableWakeupByInterrupt(interruptPin11, HIGH);
}
void loop() {
if (cycles >= LOOP_CYCLES) {
Serial.begin(115200);
Serial.print("LATCH REGISTER : ");
Serial.println(LATCHO, HEX);
Serial.print("RESETREAS : ");
Serial.println(RESETREAS, BIN);
NRF_GPIO->LATCH = NRF_GPIO->LATCH;
nRF5x_lowPower.powerMode(POWER_MODE_OFF);
}
cycles++;
delay(CYCLE_TIME_MS);
}
En persistant et en fouillant je suis tombé sur cette note du fabricant : Errata.
Malgré mes tentatives, je n'arrive pas à ce jour soit a écrire correctement dans le registre LATCH pour le remettre à zéro, ou alors il faut donc configurer PIN_CNF[n].INPUT avnat PIN_CNF[n].SENSE, mais dans ce cas il faut supprimer mes commandes "pinMode" et configurer à la main les registres dans le bon ordre. Mais voila, je ne suis absolument pas sur de ma méthode/code pour configurer/écrire dans un registre.
Est-ce que quelqu'un saurait m'aider sur ce sujet en me suggérant des exemples de codes Arduino me permettant de réaliser cela.
Sinon quelqu'un aurait-t-il peut être une autre méthode pour détecter quel bouton a été appuyé pour sortir le µC de veille. J'ai même envisagé de rajouter une "bascule D de type flip-flop" pour mémoriser l'état du bouton le temps que le système démarre. Mais je me dis que cela doit être réalisable via le firmware, et que le seul obstacle à cela, c'est mon incompétence et méconnaissance et "C" et Arduino....
Merci d'avance à tous ceux qui répondront et pourront peut-être m'aider à me sentir moins frustré et à me sortir de ce mauvais pas ;D
@+
Christophe