IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Arduino Discussion :

[Nano] Mise en veille profonde


Sujet :

Arduino

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    993
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 993
    Par défaut [Nano] Mise en veille profonde
    Bonjour à tous

    Je souhaitais dans un ancien projet composé d'un nano et d'un clavier à membrane
    réduire la consommation totale d'énergie en y ajoutant une mise en veille profonde au bout de 15s d'inactivité

    Si l'essai sur Wokwi semble satisfaisant par contre dans la réalité le programme refuse de sortir de sa léthargie
    l'action sur le clavier ne fait rien contrairement à la simu
    j'aurai donc besoin de votre éclairage car j'ai du louper un truc important concernant le WD pour le réveil de l'UC, semble-t-il
    en effet, car je n'utilise pas ici les pins d'interruption 2et 3 pour pouvoir réveiller le nano mais seulement le clavier

    lien Wokwi :
    https://wokwi.com/projects/387180332861550593

    merci mille fois
    pascal

  2. #2
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 921
    Par défaut
    Citation Envoyé par cobra38 Voir le message
    projet composé d'un nano et d'un clavier à membrane
    le clavier à membrane est lu de manière un peu spéciale par la bibliothèque.

    avant de vous endormir il faudrait modifier les pins pour qu'une interruption soit envisageable puis au réveil reconfigurer le keypad

  3. #3
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    993
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 993
    Par défaut
    Bonjour Jay M

    avant de vous endormir il faudrait modifier les pins pour qu'une interruption soit envisageable puis au réveil reconfigurer le keypad
    Utiliser par ex pin D2 ( pin D3 est déjà utiliser via le clavier ) pour faire une interruption ?

  4. #4
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 921
    Par défaut
    votre keypad (en 4x3) ressemble à cela d'un point de vue électrique

    Nom : keypad.png
Affichages : 553
Taille : 66,1 Ko

    si vous voulez qu'un appui sur une touche déclenche une interruption externe pendant le sommeil il faut configurer les pins pour que le bouton soit câblé comme il se doit. La bibliothèque keypad modifie pendant le scan l'état des pins.

  5. #5
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    993
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 993
    Par défaut
    Re..

    si vous voulez qu'un appui sur une touche déclenche une interruption externe pendant le sommeil il faut configurer les pins pour que le bouton soit câblé comme il se doit. La bibliothèque keypad modifie pendant le scan l'état des pins.
    Pour l'instant j'ai utilisé l'entrée D2 avec un bouton externe pour simuler le réveil de l'UC , mais dès que je relâche le bouton l'UC part en sommeil
    par contre je ne vois pas du tout comment associer l'entrée D2 càd "wakePin" à la touche du clavier par ex "#" pour réveiller l'UC

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
     
     
    //****************************************************************
    // -------------------- Bibliotheque -----------------------------
    //****************************************************************
    #include <EEPROM.h>
    #include <Wire.h>  // i2C Conection Library
    #include <LiquidCrystal_I2C.h>
    #include "Password.h"
    #include <Keypad.h>
    #include <SPI.h>
     
    #include "Arduino.h"
    #include <avr/sleep.h>
     
    #define sleepPin 8  // Lorsque le niveau est bas, le 328P se met en veille.
    #define wakePin 2   // lorsqu'elle est basse, réveille le 328P, doit être une broche d'interruption (2 ou 3 sur l'ATMEGA328P)
    //#define ledPin 2    // broche de sortie pour la LED (pour montrer qu'elle est éveillée)
     
    //****************************************************************
    //------------------- Raccordements ------------------------------
    //****************************************************************
     
    // Sorties ------------------- ----------------------------------
    // Buzzer : Pin 7 // buzzer passif en Pin D7 et GND
    // Relais : Pin 8 // Pilote selenoid de verrouillage de porte / entrée relais en broches D8
    //***************************************************************
     
    // Afficheur LCD I2C ----------------------------------------------
    // SDA : Pin A4
    // SCL : Pin A5
    LiquidCrystal_I2C lcd(0x27,16,2);
    //*****************************************************************
     
    // Clavier matrice 4x4 --------------------------------------------
    const byte ROWS = 4; // Lignes
    const byte COLS = 4; // Colonnes
    byte rowPins[ROWS] = { 6, 5, 4, 3 }; // Connexion clavier Lignes 1, 2, 3, 4 à ces broches Arduino.
    byte colPins[COLS] = { A3, A2, A1, A0 }; // Connexion clavier Colonnes 1, 2, 3, 4 à ces broches Arduino.
    char keys[ROWS][COLS] = { // Definition Clavier
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'*', '0', '#', 'D'}
    };
    Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // Creation du clavier
    Password password1 = Password("1234"); //<-- PASSWORD1
    //****************************************************************
     
    //****************************************************************
    //------------ Constantes & Variables ----------------------------
    //****************************************************************
     
    //bool access = false;
    const int buzzer = 7;   // buzzer passif en Pin D7 et GND
    const int doorLock = 8; // Pilote selenoid de verrouillage de porte / entrée relais en broches D8
     
    int nbalarm = 0;
    uint8_t alarmStat = 0;
    uint8_t maxError = 3;
     
    unsigned long previousMillis = 0;
    const long interval = 1000;
    uint8_t pwMode = 0;
    uint8_t pwPos = 0; 
    uint8_t adminMode = 0;
     
    // ******************************************************************
    // ------------------------ SETUP -----------------------------------
    // ******************************************************************
     
    void setup() {
      Serial.begin(115200);
      SPI.begin();
     
      lcd.init();
      lcd.backlight();
     
      keypad.addEventListener(keypadEvent); // ajouter événement pour le clavier
     
      // Maintenir les broches en position haute jusqu'à ce qu'elles soient mises à la terre
      pinMode(sleepPin, INPUT_PULLUP);
      pinMode(wakePin, INPUT_PULLUP);
      pinMode(doorLock, OUTPUT);
      digitalWrite(doorLock, LOW);
     
      tone (buzzer,1200,100);
      lcd.setCursor (0, 0);
      lcd.print(F(" - DOOR LOCK - "));
      lcd.setCursor (0, 1);
      lcd.print(F("   - INIT -   "));
      delay (2000);
      lcd.clear();
      noTone (buzzer);
    }
     
    //********************************************************************
    // ------------------------ LOOP  ------------------------------------
    //********************************************************************
     
    void loop() {
     
      keypad.getKey();  // Lecture du clavier
     
      // si nb de tentative max
      if (nbalarm >= maxError) {
      Serial.print("3ieme tentative");  
        ALARME()  ;
      }
     
      // si tentative en cours
      if (alarmStat == 0 && pwMode == 0 ) {
        unsigned long currentMillis = millis();
        lcd.backlight();  
        lcd.setCursor (0, 0);
        lcd.print(F("Code : '****'    "));
        lcd.setCursor (0, 1);
        lcd.print(F("                 "));
     
        if (currentMillis - previousMillis >= 15000) {
          lcd.noBacklight();
    	  delay (100);
    	  previousMillis = currentMillis;
    	} 
      } 
     
     
      // La broche "go to sleep" est-elle maintenant à l'état bas ?
      if (digitalRead(sleepPin) == LOW) {
     
        // Disable the ADC (Analog to digital converter, pins A0 [14] to A5 [19])
        static byte prevADCSRA = ADCSRA;
        ADCSRA = 0;
        set_sleep_mode (SLEEP_MODE_PWR_DOWN);
        sleep_enable();
        MCUCR = bit (BODS) | bit (BODSE);
        MCUCR = bit (BODS);
     
        // S'assurer que nous pouvons nous réveiller à nouveau en désactivant d'abord les interruptions (temporairement) de sorte que
        // le wakeISR ne s'exécute pas avant que nous soyons endormis et qu'il empêche les interruptions,
        // puis en définissant l'ISR (Interrupt Service Routine) pour qu'il s'exécute lorsque nous sommes réveillés.
        noInterrupts();
        attachInterrupt(digitalPinToInterrupt(wakePin), sleepISR, LOW);
     
        // Envoyer un message pour montrer que nous sommes sur le point de dormir
        Serial.println("Bonne Nuit!");
        Serial.flush();
     
        // Autoriser les interruptions maintenant
        interrupts();
     
        // Et passer en mode veille comme indiqué ci-dessus
        sleep_cpu();
     
        // --------------------------------------------------------
        // µLe contrôleur est maintenant endormi jusqu'à ce qu'il soit réveillé par une interruption.
        // --------------------------------------------------------
     
        // Se réveille à ce stade lorsque la broche wakePin est mise à l'état BAS - la routine d'interruption est exécutée en premier.
        Serial.println("Je suis réveillé !");
     
        // Réactiver l'ADC s'il était en cours d'exécution
        ADCSRA = prevADCSRA;
      }
     
     
    } // Fin Loop
     
    //*********************************************************************
    void keypadEvent(KeypadEvent eKey) {
      switch (keypad.getState()) {
     
        case PRESSED:
        lcd.setBacklight(255);
          Serial.print("Pressed: ");
          Serial.println(eKey);
        tone (buzzer,200,100);
          pwMode = 1;
          pwPos = pwPos + 1;
          if (pwPos == 1) {
             lcd.clear();
          }
        lcd.setCursor (0, 0);
          lcd.print(F("Validez avec '*'"));
        if (pwPos < 5) {
            lcd.setCursor (5 + pwPos, 1);
            lcd.print(F("*"));
        }
     
        switch (eKey) {
          case '*': checkPassword();
    	    break;
          case '#':
            pwPos =0 ;
            lcd.setCursor (5, 1);
            lcd.print(F("        "));
            password1.reset();
            break;  
         case 'A' : 
            lcd.noBacklight(); 
            lcd.clear();
            pwMode= 0 ;
            pwPos =0 ;  
         case 'B' : 
            lcd.Backlight(); 
            lcd.clear();
            pwMode= 0 ;
            pwPos =0 ;             
     
    		break;
         default:
            password1.append(eKey);
     
            }
        }
    }
     
    //*************************************************************************
    void checkPassword() 
       { // test si Mode Normal
       if (password1.evaluate()) {
        Serial.println("Mode NORMAL");
        lcd.setCursor (0, 1);
        lcd.print(F("   -Accepte-   "));
         ACCEPT ();
         password1.reset();
         pwPos = 0;  
       }else{
        Serial.println("MDP Incorrect");
        lcd.setCursor (0, 1);
        lcd.print(F("   -Rejete-   "));
        nbalarm = nbalarm + 1;
        REJECT ();
        password1.reset();
        pwPos = 0;
       }
    }
     
    //***********************************************************************
    void ACCEPT () {
      lcd.setBacklight(255);  
      lcd.clear();
      digitalWrite(doorLock, HIGH);
      tone (buzzer, 900);
      delay(100);
      tone (buzzer, 1200);
      delay(100);
      tone (buzzer, 1800);
      delay(200);
      noTone(buzzer);
      delay(600);
      lcd.setCursor (0, 1);
      lcd.print(F("Verrouillage:"));
      for (int i = 3; i > 0; i--) {
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis >= interval) {
          lcd.setCursor (0, 0);
          lcd.print(F("-PORTE OUVERTE-"));
        }
        if (currentMillis - previousMillis >= (2 * interval)) {
          previousMillis = currentMillis;
          lcd.setCursor (0, 0);
          lcd.print(F("               "));
        }
        lcd.setCursor (14, 1); lcd.print(i); lcd.print("s");
        delay (1000);
      }
      digitalWrite(doorLock, LOW);
      pwMode = 0;
      lcd.clear();
    }
     
    //***********************************************************************
    void REJECT () {
      tone (buzzer, 900);
      delay(200);
      noTone(buzzer);
      delay(200);
      tone (buzzer, 900);
      delay(200);
      noTone (buzzer);
      delay(500);
      pwMode = 0;
      }
     
     
    //*************************************************************************
    void ALARME() {
      lcd.setBacklight(255);  
      Serial.println(); 
      Serial.println("Mode ALARME");
      lcd.clear();
      lcd.setCursor (0, 1);
      lcd.print(F(" Attendre => "));
      for (int i = 30; i > 0; i--) {
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis >= interval) {
          lcd.setCursor (0, 0);
          lcd.print(F("- VERROUILLE -"));
        }
        if (currentMillis - previousMillis >= (2 * interval)) {
          previousMillis = currentMillis;
          lcd.setCursor (0, 0);
          lcd.print(F("               "));
        }
        tone(buzzer, 200, 500);
        lcd.setCursor (13, 1); lcd.print(i);
        if (i < 10) {
          lcd.setCursor (14, 1);
          lcd.print(F("s "));
        } else {
          lcd.setCursor (15, 1);
          lcd.print(F("s"));
        }
     
        delay (1000);
      }
      noTone (buzzer);
      alarmStat = 0;
      nbalarm = 0;
      lcd.clear();
    }
     
    // Lorsque la broche wakePin est mise à l'état bas, cette interruption est déclenchée en premier (même en cas de veille PWR_DOWN).
    void sleepISR() {
      // Empêcher le mode veille, afin de ne plus y entrer, sauf délibérément, par code
      sleep_disable();
     
      // Détacher l'interruption qui nous a fait sortir du sommeil
      detachInterrupt(digitalPinToInterrupt(wakePin));
     
      // Maintenant, nous continuons à exécuter la boucle principale() juste après que nous nous soyons endormis
    }

  6. #6
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 921
    Par défaut
    il y a un vieux post sur le forum arduino qui en parle

    https://forum.arduino.cc/t/keypad-sl...-help/414499/5

    et regardez la bible de nick Gammon http://www.gammon.com.au/forum/?id=11497&reply=4#reply4

  7. #7
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    993
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 993
    Par défaut
    merci mille fois Jay M

    voici une modification qui semble correctement fonctionner
    j'aurais besoin d'un dernier avis sur une erreur récurrente
    à savoir : sur la définition de password1 que je n'arrive pas à corriger
    warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
    par ailleurs j'ai gagné 50% d’énergie ( je suis passé de 60mA à 30mA) mais
    il faut que je supprime encore les 2 Leds de l'UC et du convertisseur I2C
    du LCD1602

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
     
    //****************************************************************
    // -------------------- Bibliotheque -----------------------------
    //****************************************************************
    #include <EEPROM.h>
    #include <Wire.h>  // i2C Conection Library
    #include <LiquidCrystal_PCF8574.h>
    #include <Password.h>
    #include <Keypad.h>
    #include <SPI.h>
     
    #include "Arduino.h"
    #include <avr/sleep.h>
    #include <avr/power.h>
    #include <avr/wdt.h>
     
    // nombre d'éléments d'un tableau
    #define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))
     
    //****************************************************************
    //------------------- Raccordements ------------------------------
    //****************************************************************
     
     
    // Sorties ------------------- ----------------------------------
    // Buzzer : Pin 7 // buzzer passif en Pin D7 et GND
    // Relais : Pin 8 // Pilote selenoid de verrouillage de porte / entrée relais en broches D8
    const byte ledPin = 13;
    //***************************************************************
     
     
     
    // Afficheur LCD I2C ----------------------------------------------
    // SDA : Pin A4
    // SCL : Pin A5
    LiquidCrystal_PCF8574 lcd(0x27);
    //*****************************************************************
     
    // Clavier matrice 4x4 --------------------------------------------
    const byte ROWS = 4; // Lignes
    const byte COLS = 4; // Colonnes
    byte rowPins[ROWS] = { 6, 5, 4, 3 }; // Connexion clavier Lignes 1, 2, 3, 4 à ces broches Arduino.
    byte colPins[COLS] = { A3, A2, A1, A0 }; // Connexion clavier Colonnes 1, 2, 3, 4 à ces broches Arduino.
    char keys[ROWS][COLS] = { // Definition Clavier
      {'1', '2', '3', 'A'},
      {'4', '5', '6', 'B'},
      {'7', '8', '9', 'C'},
      {'*', '0', '#', 'D'}
    };
    Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); // Creation du clavier
    Password password1 = Password("1234"); //<-- PASSWORD1
     
    //****************************************************************
     
    //****************************************************************
    //------------ Constantes & Variables ----------------------------
    //****************************************************************
     
    //bool access = false;
    const int buzzer = 7;   // buzzer passif en Pin D7 et GND
    const int doorLock = 8; // Pilote selenoid de verrouillage de porte / entrée relais en broches D8
     
    int nbalarm = 0;
    uint8_t alarmStat = 0;
    uint8_t maxError = 3;
     
     
    unsigned long previousMillis = 0;
    const long interval = 1000;
    uint8_t pwMode = 0;
    uint8_t pwPos = 0; 
    uint8_t adminMode = 0;
     
     
    /*
    Pin change interrupts.
     
    Pin               Mask / Flag / Enable
     
    D0	  PCINT16 (PCMSK2 / PCIF2 / PCIE2)
    D1	  PCINT17 (PCMSK2 / PCIF2 / PCIE2)
    D2	  PCINT18 (PCMSK2 / PCIF2 / PCIE2)
    D3	  PCINT19 (PCMSK2 / PCIF2 / PCIE2)
    D4	  PCINT20 (PCMSK2 / PCIF2 / PCIE2)
    D5	  PCINT21 (PCMSK2 / PCIF2 / PCIE2)
    D6	  PCINT22 (PCMSK2 / PCIF2 / PCIE2)
    D7	  PCINT23 (PCMSK2 / PCIF2 / PCIE2)
    D8	  PCINT0 (PCMSK0 / PCIF0 / PCIE0)
    D9	  PCINT1 (PCMSK0 / PCIF0 / PCIE0)
    D10	  PCINT2 (PCMSK0 / PCIF0 / PCIE0)
    D11	  PCINT3 (PCMSK0 / PCIF0 / PCIE0)
    D12	  PCINT4 (PCMSK0 / PCIF0 / PCIE0)
    D13	  PCINT5 (PCMSK0 / PCIF0 / PCIE0)
    A0	  PCINT8 (PCMSK1 / PCIF1 / PCIE1)
    A1	  PCINT9 (PCMSK1 / PCIF1 / PCIE1)
    A2	  PCINT10 (PCMSK1 / PCIF1 / PCIE1)
    A3	  PCINT11 (PCMSK1 / PCIF1 / PCIE1)
    A4	  PCINT12 (PCMSK1 / PCIF1 / PCIE1)
    A5	  PCINT13 (PCMSK1 / PCIF1 / PCIE1)
     
    */
     
    // désactiver les interruptions jusqu'à ce que nous soyons prêts
    ISR (PCINT0_vect)
      {
      PCICR = 0;  // annuler les interruptions de changement de broche
      } // end of ISR (PCINT0_vect)
     
    ISR (PCINT1_vect)
      {
      PCICR = 0;  // annuler les interruptions de changement de broche
      } // end of ISR (PCINT1_vect)
     
    ISR (PCINT2_vect)
      {
      PCICR = 0;  // annuler les interruptions de changement de broche
      } 
     
    // ******************************************************************
    // ------------------------ SETUP -----------------------------------
    // ******************************************************************
     
    void setup() {
      Serial.begin(115200);
      lcd.begin(16, 2);
      lcd.setBacklight(255);
      SPI.begin();
     
      keypad.addEventListener(keypadEvent); // ajouter événement pour le clavier
     
      pinMode(doorLock, OUTPUT);
      digitalWrite(doorLock, LOW);
     
      tone (buzzer,1200,100);
      lcd.setCursor (0, 0);
      lcd.print(F(" - DOOR LOCK - "));
      lcd.setCursor (0, 1);
      lcd.print(F("   - INIT -   "));
      delay (2000);
      lcd.clear();
      noTone (buzzer);
     
     
      // masques d'interruption en cas de changement de broche (voir liste ci-dessus)
      PCMSK2 |= bit (PCINT22);   // pin 6
      PCMSK2 |= bit (PCINT21);   // pin 5
      PCMSK2 |= bit (PCINT20);   // pin 4
      PCMSK2 |= bit (PCINT19);   // pin 3
     
    }
     
    //********************************************************************
    // ------------------------ LOOP  ------------------------------------
    //********************************************************************
     
     
    void loop() {
       unsigned long currentMillis = millis();
       keypad.getKey();  // Lecture du clavier
     
       byte key =  keypad.getKey();
       if (!key)
        {
    	 if (currentMillis - previousMillis >= 15000) {
    		previousMillis = currentMillis;	
    		password1.reset();
            pwPos = 0;
    		lcd.clear();
    		lcd.setBacklight(0) ;
    		goToSleep ();
    	    return;  
    	}
     
    		// si nb de tentative max
    		if (nbalarm >= maxError) {
    		Serial.print("3ieme tentative");  
    		ALARME()  ;
    		}
     
    		// si tentative en cours
    		if (alarmStat == 0 && pwMode == 0 ) {
    		lcd.setCursor (0, 0);
    		lcd.print(F("Code : '****'    "));
    		lcd.setCursor (0, 1);
    		lcd.print(F("                 "));
    		}
       }	
     
    } // Fin Loop
     
    //*********************************************************************
    void keypadEvent(KeypadEvent eKey) {
      switch (keypad.getState()) {
     
        case PRESSED:
    	  lcd.setBacklight(255);
          Serial.print("Pressed: ");
          Serial.println(eKey);
    	  tone (buzzer,200,100);
          pwMode = 1;
          pwPos = pwPos + 1;
          if (pwPos == 1) {
             lcd.clear();
          }
    	  lcd.setCursor (0, 0);
          lcd.print(F("Validez avec '*'"));
    	  if (pwPos < 5) {
            lcd.setCursor (5 + pwPos, 1);
            lcd.print(F("*"));
          }
     
          switch (eKey) {
            case '*': checkPassword(); break;
            case '#':
    		   	pwPos =0 ;
                lcd.setCursor (5, 1);
    			lcd.print(F("        "));
                password1.reset();
                break;	
            case 'A' :	
    		    lcd.clear();
    			password1.reset();
    		    pwMode= 0 ;
                pwPos =0 ;			
                lcd.setBacklight(255); break;
     
            default:
            password1.append(eKey);
     
            }
        }
    }
     
    //*************************************************************************
    void checkPassword() 
       { // test si Mode Normal
       if (password1.evaluate()) {
        Serial.println("Mode NORMAL");
        lcd.setCursor (0, 1);
        lcd.print(F("   -Accepte-   "));
         ACCEPT ();
         password1.reset();
         pwPos = 0;  
       } else {
        Serial.println("MDP Incorrect");
        lcd.setCursor (0, 1);
        lcd.print(F("   -Rejete-   "));
        nbalarm = nbalarm + 1;
        REJECT ();
        password1.reset();
        pwPos = 0;
       }
    }
     
    //***********************************************************************
    void ACCEPT () {
      lcd.setBacklight(255);	
      lcd.clear();
      digitalWrite(doorLock, HIGH);
      tone (buzzer, 900);
      delay(100);
      tone (buzzer, 1200);
      delay(100);
      tone (buzzer, 1800);
      delay(200);
      noTone(buzzer);
      delay(600);
      lcd.setCursor (0, 1);
      lcd.print(F("Verrouillage:"));
      for (int i = 3; i > 0; i--) {
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis >= interval) {
          lcd.setCursor (0, 0);
          lcd.print(F("-PORTE OUVERTE-"));
        }
        if (currentMillis - previousMillis >= (2 * interval)) {
          previousMillis = currentMillis;
          lcd.setCursor (0, 0);
          lcd.print(F("               "));
        }
        lcd.setCursor (14, 1); lcd.print(i); lcd.print("s");
        delay (1000);
      }
      digitalWrite(doorLock, LOW);
      pwMode = 0;
      lcd.clear();
    }
     
    //***********************************************************************
    void REJECT () {
      tone (buzzer, 900);
      delay(200);
      noTone(buzzer);
      delay(200);
      tone (buzzer, 900);
      delay(200);
      noTone (buzzer);
      delay(500);
      pwMode = 0;
      }
     
     
    //*************************************************************************
    void ALARME() {
      lcd.setBacklight(255);	
      Serial.println();	
      Serial.println("Mode ALARME");
      lcd.clear();
      lcd.setCursor (0, 1);
      lcd.print(F(" Attendre => "));
      for (int i = 30; i > 0; i--) {
        unsigned long currentMillis = millis();
        if (currentMillis - previousMillis >= interval) {
          lcd.setCursor (0, 0);
          lcd.print(F("- VERROUILLE -"));
        }
        if (currentMillis - previousMillis >= (2 * interval)) {
          previousMillis = currentMillis;
          lcd.setCursor (0, 0);
          lcd.print(F("               "));
        }
        tone(buzzer, 200, 500);
        lcd.setCursor (13, 1); lcd.print(i);
        if (i < 10) {
          lcd.setCursor (14, 1);
          lcd.print(F("s "));
        } else {
          lcd.setCursor (15, 1);
          lcd.print(F("s"));
        }
     
        delay (1000);
      }
      noTone (buzzer);
      alarmStat = 0;
      nbalarm = 0;
      lcd.clear();
    }
     
    /***************************************************/
    void reconfigurePins ()
    {
      byte i;
        // revenir à toutes les broches conformément à la bibliothèque du clavier
      for (i = 0; i < NUMITEMS (colPins); i++)
        {
        pinMode (colPins [i], OUTPUT);
        digitalWrite (colPins [i], HIGH); 
        }  // fin de chaque colonne 
     
      for (i = 0; i < NUMITEMS (rowPins); i++)
        {
        pinMode (rowPins [i], INPUT_PULLUP);
      }   // fin de chaque ligne
     
    }  // end of reconfigurePins
     
     
    void goToSleep ()
      {
      byte i;
     
      // configuré pour détecter une pression sur une touche
      for (i = 0; i < NUMITEMS (colPins); i++)
        {
        pinMode (colPins [i], OUTPUT);
        digitalWrite (colPins [i], LOW);   // colonnes basses
        }  // end of for each column
     
      for (i = 0; i < NUMITEMS (rowPins); i++)
        {
        pinMode (rowPins [i], INPUT_PULLUP);
        }  // end of for each row
     
       // vérifie maintenant qu'aucune broche n'est enfoncée (sinon nous nous réveillerons au relâchement d'une touche)
       for (i = 0; i < NUMITEMS (rowPins); i++)
        {
        if (digitalRead (rowPins [i]) == LOW)
           {
           reconfigurePins ();
           return; 
           } // end of a pin pressed
        }  // end of for each row
     
      // surmonter les délais de rebond intégrés dans la bibliothèque du clavier
      delay (50);
     
      // à ce stade, le fait d'appuyer sur une touche devrait relier le niveau haut de la ligne au niveau bas de la colonne et déclencher un changement de broche. 
      // au niveau bas de la colonne et déclencher un changement de broche.
     
      set_sleep_mode (SLEEP_MODE_PWR_DOWN);  
      sleep_enable();
     
      byte old_ADCSRA = ADCSRA;
      // désactiver l'ADC pour économiser de l'énergie
      ADCSRA = 0;  
     
      power_all_disable ();  // turn off various modules
     
      PCIFR  |= bit (PCIF0) | bit (PCIF1) | bit (PCIF2);   // efface toutes les interruptions en cours
      PCICR  |= bit (PCIE0) | bit (PCIE1) | bit (PCIE2);   // activer les interruptions de changement de broche
     
      // désactiver l'activation de la déconnexion par logiciel
      MCUCR = bit (BODS) | bit (BODSE);
      MCUCR = bit (BODS); 
      sleep_cpu ();  
     
      // annuler le sommeil par précaution
      sleep_disable();
      power_all_enable ();   // réactiver les modules
      ADCSRA = old_ADCSRA;   // réactivation de la conversion ADC
     
      // remettre les broches du clavier dans l'état où elles sont censées être
      reconfigurePins ();
     
      }  // end of goToSleep

  8. #8
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 921
    Par défaut
    Citation Envoyé par cobra38 Voir le message
    warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
    à quelle ligne exactement? (donnez le contexte quand vous mettez les erreurs, le compilateur donne plein d'infos)

    généralement c'est qu'une bibliothèque est mal écrite, elle attend un paramètre de type char * et on lui passe un texte du genre "coucou" entre guillemets. Le C++ dit que ce genre de text (un string literal) est constant (c'est un "const char *" et donc n'est pas compatible avec un "char *").


    EDIT: ce serait éventuellement la bibliothèque password

    https://github.com/trustcrypto/libra...password.h#L51

    le constructeur est défini comme cela
    et vous faites
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Password password1 = Password("1234"); //<-- PASSWORD1
    donc vous donnez un const char * là où un char * est attendu ==> le compilateur n'est pas d'accord. C'est la bibliothèque qui est mal écrite...

    soit vous modifiez la bibliothèque pour qu'elle fasse

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	Password(const char* pass)

    soit vous mangez un peu de mémoire sur votre arduino et faites
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    char motDePasse[]*= "1234";
    ...
    Password password1 = Password(motDePasse); //<-- PASSWORD1

    -----

    bravo pour le progrès!

  9. #9
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    993
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 993
    Par défaut
    à quelle ligne exactement? (donnez le contexte quand vous mettez les erreurs, le compilateur donne plein d'infos)
    ici
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    51 => Password password1 = Password("1234"); //<-- PASSWORD1
    j'avoue que vous m'aviez déjà expliqué cela mais je ne comprends pas
    d'après ce que j'avais compris c'est que le compilateur comprend une chaine constante que l'on veut modifier ou le contraire mais je ne vois comment résoudre ce problème
    d'autant que dans la librairie "password" que j'utilise, on n'a l'air de s'en préoccuper

    Par ailleurs, je viens de m'apercevoir que si ce programme résout mon problème d'interruption du clavier, cela devient problématique pour le RFID car lui ne voit plus rien ....


    ( Mille pardons nos messages se sont croisés )

  10. #10
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    993
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 993
    Par défaut
    bravo pour le progrès!
    Merci c'est surtout grâce à votre aide

  11. #11
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 921
    Par défaut
    Si la pin IRQ est bien connectée (ce n’est pas la cas sur tous les modules) oui vous pourriez vous en servir. Je n’ai jamais essayé, il faut voir si le module attend une requête pour fournir les données ou s’il démarre une transaction pour envoyer les infos. Dans ce second cas votre arduino ne serait sans doute pas prêt à recevoir les données car en cours de réveil.

    A tester.

    Avez vous regarder la consommation au repos du module? Il doit rayonner de l’énergie pour activer les badges qui passent à portée de l’antenne… ça doit consommer…

    Il y a des discussions sur GitHub pour la bibliothèque qui pourraient être pertinentes
    https://github.com/miguelbalboa/rfid/issues/269

  12. #12
    Membre éprouvé
    Inscrit en
    Juillet 2004
    Messages
    993
    Détails du profil
    Informations forums :
    Inscription : Juillet 2004
    Messages : 993
    Par défaut
    Si la pin IRQ est bien connectée (ce n’est pas la cas sur tous les modules) oui vous pourriez vous en servir. Je n’ai jamais essayé, il faut voir si le module attend une requête pour fournir les données ou s’il démarre une transaction pour envoyer les infos. Dans ce second cas votre arduino ne serait sans doute pas prêt à recevoir les données car en cours de réveil.
    j'ai quand même tenté de raccorder l'entrée D2 du nano ( la seule qui me restait de libre ) avec la broche IRQ du RFID
    et en ayant préalablement valider une interruption
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     PCMSK2 |= bit (PCINT18);   // pin 2
    j'ai réussi à réveiller le nano mais je ne jure pas de la fiabilité du procéder mais à 1ere vue çà a l'air de fonctionner

    Avez vous regardé la consommation au repos du module? Il doit rayonner de l’énergie pour activer les badges qui passa portée de l’antenne… ça doit consommer…
    Vous avez raison et le lien que vous m'avez indiqué est très intéressant mais complexe semble-t-il à mettre en œuvre pour moi , je pense donc au final de retirer le RFID et de me consacrer
    à la réduction des éléments comme les Leds du nano et du convertisseur I2C du LCD1602 çà devrait être plus efficace

  13. #13
    Expert confirmé

    Homme Profil pro
    mad scientist :)
    Inscrit en
    Septembre 2019
    Messages
    2 921
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : mad scientist :)

    Informations forums :
    Inscription : Septembre 2019
    Messages : 2 921
    Par défaut
    OK - c'est bien d'avoir essayé !

Discussions similaires

  1. Réponses: 4
    Dernier message: 03/10/2021, 23h26
  2. Mise en veille PC
    Par SteelBox dans le forum Administration système
    Réponses: 3
    Dernier message: 14/03/2006, 20h03
  3. mise en veille puis blocage au démarrage de win 98
    Par gsi dans le forum Windows 2000/Me/98/95
    Réponses: 7
    Dernier message: 17/11/2005, 11h09
  4. Réponses: 19
    Dernier message: 04/08/2005, 22h33
  5. Comment interdire la mise en veille d'une machine sous Win ?
    Par Soulama dans le forum API, COM et SDKs
    Réponses: 1
    Dernier message: 01/08/2005, 15h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo