Arduino Nano Every with ATMega4809 not waking up properly after putting it to sleep

The goal of my project is to read a RFID tag and activate a relais, which opens a door. The part of reading the UID of an tag works properly.

Because this construction should be battery powerd and last a long time, I tried to lower the powerconsumption.

The programm i have, first checks if a RFID tag is available, if so it reads the UID and displays it on the serial monitor. After that or if no RFID tag is available the programm waits 2 seconds before putting the Arduino to sleep. After 5 seconds in sleepmode the Arduino wakes up and checks again for RFID tags.

The Arduino is put into PWR_DOWN mode and several other none used peripherals are turned of.

I have been measuring the powerconsumption of the Arduino with a Multimeter.

The lowest the Arduino goes is 25mA but only if i disconnect everything from the Arduino. If i connect everything back the current goes up to 52mA in sleep mode.

52mA is obviously to much power draw to power the Arduino for a long time via batteries.

I have read, that the arduino only uses so micro amps when in deep sleep, which mine is far off.

I already searched the forum and the internet but could only find solutions for the older version of the Arduino Nano with the ATMega3809 i think it was.

The other thing is, that if i put the Arduino to sleep he will stay in sleep mode. I know that I could use a Interrupt pin to wake him back up again but thats not what i want. The Arduino should wake up check for a RFID tag and go back to sleep in a specific intervall.

Here is the code I am using:

#include <SPI.h>
#include <MFRC522.h>
#include <avr/sleep.h>

const unsigned long awakeInterval = 5000; // Time in milliseconds in which the Arduino should stay awake
const unsigned long sleepInterval = 8000; // Time in milliseconds after which the Arduino should sleep
const unsigned long wakeupDelay = 2500; // Time in milliseconds that the Arduino should wait after waking up
#define SS_PIN 9
#define RST_PIN 5
#define RELAY_PIN A5 // the Arduino pin connects to relay

MFRC522 rfid(SS_PIN, RST_PIN);

byte managerKeyUID[4]   = {0x28, 0x0F, 0xA0, 0x6E}; //28 0F A0 6E
byte secretaryKeyUID[4] = {0x30, 0x01, 0x8B, 0x15};  

int k = 0, led = 2;



void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  SPI.begin(); // init SPI bus
  rfid.PCD_Init(); // init MFRC522
  pinMode(RELAY_PIN, OUTPUT); // initialize pin as an output.
  digitalWrite(RELAY_PIN, HIGH); // lock the door

  Serial.println("Tap RFID/NFC Tag on reader");
}



void loop() {
if (rfid.PICC_IsNewCardPresent()) { // new tag is available
    if (rfid.PICC_ReadCardSerial()) { // NUID has been readed
      MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);

      if (rfid.uid.uidByte[0] == managerKeyUID[0] &&
          rfid.uid.uidByte[1] == managerKeyUID[1] &&
          rfid.uid.uidByte[2] == managerKeyUID[2] &&
          rfid.uid.uidByte[3] == managerKeyUID[3] ) {
        Serial.println("Access is granted for manager");
        digitalWrite(RELAY_PIN, LOW);  // unlock the door for 2 seconds
        delay(2000);
        digitalWrite(RELAY_PIN, HIGH); // lock the door
      }
      else
      if (rfid.uid.uidByte[0] == secretaryKeyUID[0] &&
          rfid.uid.uidByte[1] == secretaryKeyUID[1] &&
          rfid.uid.uidByte[2] == secretaryKeyUID[2] &&
          rfid.uid.uidByte[3] == secretaryKeyUID[3] ) {
        Serial.println("Access is granted for secretary");
        digitalWrite(RELAY_PIN, LOW);  // unlock the door for 2 seconds
        delay(2000);
        digitalWrite(RELAY_PIN, HIGH); // lock the door
      }
      else
      {
        Serial.print("Access denied for user with UID:");
        for (int i = 0; i < rfid.uid.size; i++) {
          Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
          Serial.print(rfid.uid.uidByte[i], HEX);
        }
        Serial.println();
      }

      rfid.PICC_HaltA(); // halt PICC
      rfid.PCD_StopCrypto1(); // stop encryption on PCD
    }
  } else {
  delay(2000); // 2-second delay before going to sleep
  Serial.println("Going to sleep.");
  goToSleep();
  }

  
}


void goToSleep() {
  Serial.flush(); // Wait for all output to finish

  // Activate sleep mode
  set_sleep_mode(SLEEP_MODE_PWR_DOWN); // Deep sleep mode
  sleep_enable(); // Activate sleep mode 

  // Activate the System-Timer
  _PROTECTED_WRITE(CLKCTRL_MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc);
  
  // Set the Prescalers auf 1/2, to increase the clock frequenzy to 10MHz
  _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, CLKCTRL_PDIV_2X_gc | CLKCTRL_PEN_bm);

   //Deactivate unused peripherals
  ADC0.CTRLA &= ~ADC_ENABLE_bm; // Deactivate ADC
  SPI0.CTRLA &= ~SPI_ENABLE_bm; // Deactivate SPI
  USART0.CTRLA &= ~USART_RXEN_bm & ~USART_TXEN_bm; // Deactivate USART0
  TWI0.MCTRLA &= ~TWI_ENABLE_bm; // Deactivate TWI

  RTC.CLKSEL = RTC_CLKSEL_INT1K_gc;        // Run low power oscillator (OSCULP32K) at 1024Hz for long term sleep
  RTC.PITINTCTRL = RTC_PI_bm;              // PIT Interrupt: enabled */


  // Sleep for the specified time
  sleep_mode();



  // Waiting time after waking up
  delay(wakeupDelay);



  // Turn off sleep mode 
  sleep_disable();
  Serial.println("Deactivate sleep mode.");


  
    // Activating the System Timer
  _PROTECTED_WRITE(CLKCTRL_MCLKCTRLA, CLKCTRL_CLKSEL_OSC20M_gc);
  
  // Set the prescaler to 1/64 to increase the clock speed to 20 MHz
  _PROTECTED_WRITE(CLKCTRL_MCLKCTRLB, 0);
  
  // Activate unused peripherals
  ADC0.CTRLA |= ADC_ENABLE_bm; // Activate ADC
  SPI0.CTRLA |= SPI_ENABLE_bm; // Activate SPI
  USART0.CTRLA |= USART_RXEN_bm | USART_TXEN_bm; // Activate USART0
  TWI0.MCTRLA |= TWI_ENABLE_bm; // Activate TWI

  RTC.CLKSEL = RTC_CLKSEL_INT1K_gc;

  RTC.PITINTCTRL = RTC_PI_bm;
}

I am new to the forum, so if I did something wrong with my post please let me know

I have a number of remarks on you post. Some are facts, some are assumptions about your project, please correct me if I got those wrong.

  1. You claim to have the Nano Every with the ATmega4809 processor. You mentioned the ‘old’ Nano, having the ATmega328 processor. It is suggested that the Nano Every is a replacement for the ‘old’ Nano, but that is only partially true. You do need to double check pin numbers.
  2. At first glance, the file MRFC522.h seems to be written in a way that might survive the transition from the 328 to the 4809 (it does compile).
  3. The file MRFC522.h expects a connection to your PC as it contains a lot of Serial.prints. It might stop working if disconnected. You might add flashing the LED_BUILTIN once in a while to indicate proper working.
  4. You initialize the RTC when you want to go to sleep. You better initialize in setup(), don’t worry about the current consumption, which is very low.
  5. You initialize the RTC without checking the busy-bits. And you missed several other steps.
  6. You don’t need to mess with the main oscillator, it will be switched off during sleep anyway.
  7. All peripherials will be switched off during PowerDownMode (except RTC/PIT), no need to do that in the program.
  8. It would be nice if you could use a power-down-mode in the MFRC522 (I hope it’s supported by the file MRFC522.h). In that case you could use the StandBySleepMode and use the SPI to wake up the processor, no need to wake up every 5 seconds (which is annoyingly long for the user, but takes a lot of power from the battery).
  9. You might consider reversing the working of the magnet, as it is it will consume power for 99.99% of the time.

@stitech
Thank you for helping me.

  1. Yes i bought the Arduino Nano Every Board with headers and on the Packaging it says that the chip is the ATMEGA4809. I found some posts on forums, where they were talking about the Arduino Nano but it had a ATMega328 and theyre programms that they posted didn't work in my case.

  2. The MFRC522 works fine with the ATMega4809 I get the output I want.

  3. It is currently connected to the PC, for testing purposes. If everything works I will delete all the Serial.prints. I also programmed, that the LED_BUILTIN turns on if a new RFID-Tag is present and read.

  4. Im not sure if I did it right but i put the: RTP.PITINTCTRL = RTC_PI_bm; in setup, if this was the wrong line of code please let me know, as I am new to programming such things.

  5. I don't understand what you mean by busy-bits, could you explain that?
    And what are these other steps I missed, as I rely on your knowledge because I hit a dead end.

  6. I deleted the lines in the code that switched the oscillator off.

  7. I also removed the lines from Deactivate unused peripherals.

  8. What about using a transistor and cutting the power to the MFRC522-Board everytime the Arduino goes to sleep?
    5 second wake up delay is also only for testing purposes

  9. Thank you for pointing out. I corrected it.

With the MFRC522 part of the programm nothing is wrong. Everything works as intended. But putting it to sleep seems to cause a lot of problems. For example if I tried to use the SLEEP_MODE_PWR_DOWN the Arduino would never wake up again. Only in SLEEP_MODE_IDLE. I also measured the current consumption of the board alone in PWR_DOWN mode and it was still 23mA.

I made some changes to the code as you suggested:

#include <SPI.h>
#include <MFRC522.h>
#include <avr/sleep.h>

#define SS_PIN 9
#define RST_PIN 5
#define RELAY_PIN 2 // the Arduino pin connects to relay

MFRC522 rfid(SS_PIN, RST_PIN);

const unsigned long sleepInterval = 8000; // Time in milliseconds after which the Arduino should sleep
const unsigned long wakeupDelay = 2500; // Time in milliseconds that the Arduino should wait before waking up

byte Key1UID[4] = {0x28, 0x0F, 0xA0, 0x6E}; //28 0F A0 6E
byte Key2UID[4] = {0x30, 0x01, 0x8B, 0x15};  

int led = 2;

void setup() {
  pinMode(led, OUTPUT);
  Serial.begin(9600);
  SPI.begin(); // init SPI bus
  rfid.PCD_Init(); // init MFRC522
  pinMode(RELAY_PIN, OUTPUT); // initialize pin as an output.
  digitalWrite(RELAY_PIN, LOW); // lock the door

  rfid.PCD_WriteRegister(MFRC522::RFCfgReg, 0x7F); // Set the antenna gain to maximum
  
  RTC.PITINTCTRL = RTC_PI_bm;              // PIT Interrupt: enabled */

  Serial.println("Tap RFID/NFC Tag on reader");
}


void loop() {
if (rfid.PICC_IsNewCardPresent()) { // new tag is available
    if (rfid.PICC_ReadCardSerial()) { // NUID has been readed
      digitalWrite(led, HIGH);
      MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);

      if (rfid.uid.uidByte[0] == Key1UID[0] &&
          rfid.uid.uidByte[1] == Key1UID[1] &&
          rfid.uid.uidByte[2] == Key1UID[2] &&
          rfid.uid.uidByte[3] == Key1UID[3] ) {
        Serial.println("Access granted");
        digitalWrite(RELAY_PIN, HIGH);  // unlock the door for 2 seconds
        delay(2000);
        digitalWrite(RELAY_PIN, LOW); // lock the door
      }
      else
      if (rfid.uid.uidByte[0] == Key2UID[0] &&
          rfid.uid.uidByte[1] == Key2UID[1] &&
          rfid.uid.uidByte[2] == Key2UID[2] &&
          rfid.uid.uidByte[3] == Key2UID[3] ) {
        Serial.println("Access granted");
        digitalWrite(RELAY_PIN, HIGH);  // unlock the door for 2 seconds
        delay(2000);
        digitalWrite(RELAY_PIN, LOW); // lock the door
      }
      else
      {
        Serial.print("Access denied for user with UID:");
        for (int i = 0; i < rfid.uid.size; i++) {
          Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
          Serial.print(rfid.uid.uidByte[i], HEX);
        }
        Serial.println();
      }

      rfid.PICC_HaltA(); // halt PICC
      rfid.PCD_StopCrypto1(); // stop encryption on PCD
    }
  } else {
  delay(2000); // 2-second delay before going to sleep
  Serial.println("Going to sleep.");
  goToSleep();
  }

  
}

void goToSleep() {
  Serial.flush(); // Wait for all output to finish

  // Activate sleep mode
  set_sleep_mode(SLEEP_MODE_IDLE); // Deep sleep mode
  sleep_enable(); // Activate sleep mode 


  // Sleep for the specified time
  sleep_mode();


  // Waiting time after waking up
  delay(wakeupDelay);


  // Turn off sleep mode 
  sleep_disable();
  Serial.println("Deactivate sleep mode.");
}

In the mean time I found out that the module has an output named IRQ (InterruptRequest). Apparently the maker of the chip anticipated on not having a card nearby most of the time. You can use that to wake up the controller board, doing away with the delays (you used the blocking delay() function, causing it to stay awake longer than the sleep time).

Some pins have specific functions assigned to: D13 – SCK, D12 – MISO, D11 – MOSI. The other connections are free to choose. Why not keep it in a row? D10 – SS, D9 – RST, D8 – IRQ. (On the ‘old’ Nano only D2 and D3 have the functionality for waking up the CPU from sleep modes.)

D13 is the pin that has the orange LED connected to it.

About the busy-bits: the RTC runs on another oscillator than the CPU, making synchronization necessary for some of the registers. Read the datasheet!

I wrote a sketch to showcase the RTC. If you can understand what’s happening, you can use the RTC. (Though you may not need it.)

Running this sketch I expect the board to consume about 7mA.

// Flashing a led, 500 ms every 8 seconds, Nano Every, sleeping

#include <avr/sleep.h>

ISR(RTC_PIT_vect) {
  RTC.PITINTFLAGS = 1;                    // reset interrupt
  digitalWrite(LED_BUILTIN, HIGH);        // led on
  while (RTC.STATUS & RTC_CNTBUSY_bm) {}  // wait if busy
  RTC.CNT = 0;                            // reset timer
}

ISR(RTC_CNT_vect) {
  RTC.INTFLAGS = RTC_CMP_bm;       // reset interrupt
  digitalWrite(LED_BUILTIN, LOW);  // led off
}

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);  // led output = PB0
  // settings RTC
  RTC.CLKSEL = RTC_CLKSEL_INT1K_gc;            // 1kHZ from OSCULP
  while (RTC.STATUS & RTC_CMPBUSY_bm) {}       // wait if busy
  RTC.CMP = 500;                               // 500ms on-time
  RTC.INTFLAGS = RTC_CMP_bm | RTC_OVF_bm;      // reset possible previous interrupts
  RTC.INTCTRL = RTC_CMP_bm;                    // enable interrupt at compare
  while (RTC.STATUS & RTC_CTRLABUSY_bm) {}     // wait if busy
  RTC.CTRLA = RTC_RUNSTDBY_bm | RTC_RTCEN_bm;  // start RTC, with run in STDBY mode, no prescaler
  // PIT is not completely defined in iom4809.h
  while (RTC.PITSTATUS) {}     // wait if busy
  RTC.PITCTRLA = 0b01100001;   // 8192 cycles, enable
  RTC.PITINTCTRL = RTC_PI_bm;  // enable periodic interrupt
  // setting SleepControl
  SLPCTRL.CTRLA = SLPCTRL_SMODE_STDBY_gc | SLPCTRL_SEN_bm;  // standby mode, enable
}

void loop() {
  sleep_cpu();
}

The IRQ is currently not conncted, because I used a scematic of a website I found to connect the RFID-Module to the Arduino. I will have a look at how the IRQ works and connect it afterwards. If this works, it would make things a whole lot easier.

You were right witch your assumption. The arduino consumes only 7.3 mA when connected to everything. But only when he gets 21 V input. At the 12 V I'm using the arduino it consumes double that, 14.6 mA. Which is still much lower than before, but still way to high for batterie power.

Should I consider powering the whole thing with 21 V for lower consumption?

In the meantime I'l have a look at your programm and try to understand and implement it into my program.

Up till today I never actually measured the current consumption of my Nano Every. I just trusted my understanding of the documentation. But: I can’t get under 25mA at 5V either.
There are only a few current user on the board:

  1. ATmega4809: I see a difference between sleep mode or not, so sleep mode works.
  2. The green LED: should take about 3mA.
  3. A few signal converters 5V-3.3V, taking 1mA max each, if any.
  4. ATsamD11: according the datasheet it should take 2 or 3mA.
    I can’t explain where the rest of the current goes.

I sense that you confuse current consumption and power consumption. When you feed 7.4mA at 21V that means that the board consumes 31mA at 5V. The power stays the same (ignoring the loss from the efficiency of the regulator).
If you add more batteries to obtain a higher voltage, of course it will take longer to drain them.

Another question is: is battery power a viable solution? The datasheet of the MFRC522 gives a lot of numbers for supply currents.
When the Reset pin is low: 5μA.
In soft power down state: 10μA. It says receiver on, probably meaning it can detect if you approach it with the NFC signal from your phone.
A keyfob requires an electromagnetic field to get the power to send anything, and this field needs to be generated by the MFRC522. This costs 60mA at continuous wave. The fact that the manufacturer adds the term continuous wave makes me think that in normal use it can be set to intermittent.
I don’t know how low it can actually get, but according to what I found at various vendors 10mA is a low limit, though they don’t state the conditions.

Arduino boards were never meant to be used in sleep mode, they are listed as development boards. The file <avr/sleep.h> isn’t even included normally.
I lean towards designing a custom board for using sleep modes.
If you want to keep it simple, consider using a wall wart.

I can help you with knowledge of the Nano Every and general electronics, but I can’t do measurements on an actual MFRC522 card as I don’t own one.
Oh, and I forgot the power consumption of the lock magnet.

If connected to your PC the arduino draws more current because he's communicating with the PC. If you power it via the VIN GND pins it consumes way less current. In my case it dropped from 26mA, when connected to the PC to 7mA when connected to VIN GND.

You were right, I really confused current consumption with power consumption.

I downloaded a NFC Tool app on my phone to try it out but it didn't work. Althoug there could be an error in my current program.

I really didn't realise, that the keyfob needs a electromagnetic field to send information but now it makes sense, why it won't work.

At this point I really need to consider a wall wart, as my knowledge and understanding of arduino boards isn't that good. That's why I'm on this forum. Designing a custom board is probably too much for me, as I never done anything like that before.

I will take a closer look at both solutions and tell you my choice.

I decided to use a wall wart.

Althoug current consumption isn't as much as a problem as it was before, it's still important as it saves money. Thats why im trying to implement your programm because it only used 7mA.

7mA at 5V for a year works out around 0.3kWh, which costs about 10p in the UK. Don't stress yourself over the consumption of this project, there's a lot more to be saved elsewhere.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.