RTC Flash FeatherWing


#1

MCP79410 RTC, SPI NOR flash, and Grove connector FeatherWing

You typically insert this FeatherWing in a Adafruit FeatherWing Doubler or Tripler along with your device. It also works in the Particle Ethernet FeatherWing.

One of the limitations of the Gen 3 (nRF52) hardware is that it cannot wake up from SLEEP_MODE_DEEP based on time. That’s because the nRF52 real-time-counter does not run in standby sleep mode. Also, when you wake up from SLEEP_MODE_DEEP, the Time object is not set until it’s synchronized from the cloud again.

My solution to this is a simple Adafruit FeatherWing board with a MCP79410 real-time clock chip. It’s inexpensive ($0.93 in single quantities) and tiny.

Since I had so much room left on the FeatherWing, I also added:

  • A CR1220 battery to power the chip with all external power removed (optional)
  • 3 Grove expansion connectors (1 digital, 1 analog, 1 I2C, optional)
  • A SPI NOR flash memory chip (optional)

Using RTC to wake from SLEEP_MODE_DEEP

Here’s a simple program to wake from SLEEP_MODE_DEEP:

#include "MCP79410RK.h"

SerialLogHandler logHandler;

MCP79410 rtc;

void setup() {
	// Make sure you call rtc.setup() from setup!
	rtc.setup();
}

void loop() {
	// Make sure you call rtc.loop() from loop!
	rtc.loop();


	// Wait 20 seconds after boot to try sleep
	if (millis() > 20000) {
		if (rtc.setAlarm(10)) {
			Log.info("About to SLEEP_MODE_DEEP for 10 seconds");
			System.sleep(SLEEP_MODE_DEEP);
		}
		else {
			Log.info("Failed to setAlarm, not sleeping");
			delay(10000);
		}
	}
}

For Gen 2 devices, you might do something like:

System.sleep(SLEEP_MODE_DEEP, 10);

but using the RTC it would be:

if (rtc.setAlarm(10)) {
    System.sleep(SLEEP_MODE_DEEP);
}

The reason for the error check around setAlarm is that the alarm can only be set after the RTC has been set to the correct time. Upon cold boot (no 3V3, no battery) the RTC won’t be set and sleep cannot be used until the first clock synchronization. This is true even when delaying by seconds.

MCP79410

The MCP79410RK library is used for the real-time clock (RTC) chip, and also to access the SRAM and EEPROM features.

There is extensive documentation in that Github for using it. You can find the full browsable API docs here.

SPI Flash

You can use a variety of SPI NOR flash chips:

The SPI chip select (CS) is connected to pin A5.

I recommend the SpiFlashRK to access the flash memory at block level and SpiffsParticleRK library for using the flash as a file system.

Using a Winbond flash chip with SpiFlashRK, you’d declare an object like:

SpiFlashWinbond spiFlash(SPI, A5);

The Eagle CAD files and BOM are available here:


#2

Where can I buy these ?


#3

Where can I buy these ?


#4

It’s just an instructional tutorial. It’s not available for sale.


#5

@rickkas7,

I am trying to test my new carrier board and am using your library. I know this is a basic question but, I noticed that you are keeping logs that could help me figure out what is going on with the board.

The commend is : SerialLogHandler logHandler;

How do I access this log? Again, sorry for the basic question.

Chip


#6

This will log out any Log.xxxx() calls via USB Serial.


#7

@ScruffR,

Thank you. I noticed that in @rickkas7’s code there are a number of these log statements. Once the device is tested and I want to use the code in production, should I comment them out? Is there a memory or performance penalty for serial calls when you do not have a serial connection open?

Thanks, Chip


#8

Nope, you’d merely limit the scope of the SerialLogHanlder object to LOG_LEVEL_NONE which will cause the Log.xxx() statements to be ignored and optimised away.

Since no flow control is used it’s irrelevant whether or not a connection exists - unless, of course your code is waiting for the connection :wink:


#9

For my learning - I normally comment out the SerialLogHandler logHandler; when I no longer need the Log output, is it better to set to LOG_LEVEL_NONE?


#10

I think commenting out the log hanlder may be even better.


#11

Can the MFP from the RTC be wired to the WKP (A7) of the electron to successfully wake it up?

The datasheet for the RTC states that it needs an external pullup on the MFP pin.
The datasheet for the Electron is unclear,

  1. Electron datasheet states that it detects a rising edge on the WKP pin (which it wouldn’t get from the RTC if it has a pullup)
  2. Electron datasheet states that the WKP pin can be disabled.
  3. Electron datasheet states that the A7 (WKP) pin can be configured to wake the device.
  4. Electron datasheet states that the same A7 Pin limitations apply as attachInterrupt (which would have falling edge)

I only have A7 and A6 available for the MFP of the RTC, I would prefer use A6 (DAC) but would like to know the above.

Thanks


#12

This is true for deep sleep, but stop mode sleep allows you to select the detection edge.
Not sure why you mention 2, 3 & 4 tho’.

BTW, the Electron has its own onboard RTC, what’s the purpose of using a FeatherWing RTC for a non-FeatherWing formfactor controler?
I’d understand if you wanted to use this board with a Boron, but for an Electron?


#13

I’m making a PCB with PSRAM and an SD card on it, based on @rikkas7 example above. While at it I thought that I might as well chuck on the RTC.

As with the builtin WDT on the Electron, yes it’s there, yes it works, but if you have an external one then you know it is going to work…


#14

I have laid out a similar one using the RTC from this thread RTC Flash FeatherWing