Recapitulation

One thing I didn’t find clearly over the internet is how to make an Arduino Pro Mini bare bones, that is, from the scratch, and how to make one on the breadboard. This is really useful if you want to make a custom pcb/smd circuit, because you will be able to test your hardware ans software before sending the schematics and the layout of the board to the manufacturer. Also, it will make your circuit Arduino compatible. If you read my previous article, here, I showed how to make a simple circuit with the PCF8563 real-time clock, reading and writing it. Now it is time to put your Atmega 328p on the breadboard and complete a simple read of the clock, maintaining the power consumption low, and for that I will use the LowPower library.

First steps

All over the internet there are numerous tutorials about how to make an Arduino Uno bare bones, but it is hard to find a Pro Mini. For our lucky, they are really similar, and a good start can  be made by looking for the original Arduino Pro Mini schematic, here. The main circuit is as the next image shows.

atmega schematic pro mini arduino 3V bare bones

From the circuit above, the only part that is not clear are those capacitors on the oscillator pins, one on OSC1 and one on OSC2. For those, I used 22 pF each. The next thing we need to do is to eliminate the voltage regulator from the schematic, because we are going to use this circuit in our smartwatch, and will use a CR2032 or LIR2032, which don’t need them. The voltage regulator and the LED make our power consumption go up a bit, so we can leave them behind.

atmega schematic pro mini arduino 3VThe red box of the image shows what we don’t want in our breadboard. As for example, we don’t need a LED just to show the Atmega is on, because that would be a terrible waste of precious mA. The green box, however, is very welcome. Watch out not to place the capacitor C13 upside down!

Take a note: watch out that, although this is the schematic for the Arduino Pro Mini, the number of the pin which you will connect each part may vary according to the packet size of the chip you have chosen. To know better about each pin of each packet size you have to check the datasheet.

Placing the RTC

Now, if you read my previous article, you just have to connect A5 to SCL pin on the PCF8563, and the A4 to the SDA pin. Use pull-up resistors on both wires. These resistors can be between 2K and 10K Ohms. In my case I stayed with 2K. The only different pin I used was a button (without any resistors) on the Atmega pin number 4 (or digital input 2), because as we are going to use the power down mode, I want it to wake up via external interrupt.

protoboard arduino pro mini bare bones with pcf8563

So now if you bought the Atmega already programmed with the bootloader, you are ready to program it. If not, you still need to insert the bootloader in it. You can program the bootloader many ways, but I found easier to do things this way (although this is for the Mini, the process is very similar), and you will need an ISP Programmer, like this on Ebay. Really cheap, and you will use it a lot in the future.

Setting up the low power and power down mode

The Atmega 328p has six sleep modes: idle, ADC noise reduction, power-save, power-down, standby, and extended standby.

  • The idle mode stops the CPU while allowing the SRAM, timer/counters, USART, 2-wire serial interface, SPI port, and interrupt system to continue functioning;
  • The power-down mode saves the register contents but freezes the oscillator, disabling all other chip functions until the next interrupt or hardware reset. This is the mode with the least power consumption possible;
  • In power-save mode, the asynchronous timer continues to run, allowing the user to maintain a timer base while the rest of the device is sleeping;
  • The ADC noise reduction mode stops the CPU and all modules except asynchronous timer and ADC, to minimize switching noise during ADC conversions;
  • In standby mode, the crystal/resonator oscillator is running while the rest of the device is sleeping. This allows very fast start-up combined with low power consumption;

It is possible to take advantage of all these modes with the library LowPower.h, available for download here. With this library the user have to call the functions to activate the mode he desires:

void adcNoiseReduction(period_t period, adc_t adc, timer2_t timer2);
void powerDown(period_t period, adc_t adc, bod_t bod);
void powerSave(period_t period, adc_t adc, bod_t bod, timer2_t timer2);
void powerStandby(period_t period, adc_t adc, bod_t bod);
void powerExtStandby(period_t period, adc_t adc, bod_t bod, timer2_t time     r2);
void idle(period_t period, adc_t adc, timer2_t timer2, timer1_t timer1, t     imer0_t timer0, spi_t spi, usart0_t usart0, twi_t twi);

Where “period_t period” can be:

SLEEP_15Ms
SLEEP_30MS	
SLEEP_60MS
SLEEP_120MS
SLEEP_250MS
SLEEP_500MS
SLEEP_1S
SLEEP_2S
SLEEP_4S
SLEEP_8S
SLEEP_FOREVER //this will wake up only with interrupt

And the other arguments are ON/OFF values such as “adc_t adc” for “ADC_ON” or “ADC_OFF”. Now if we want the chip to wake up after an external pin change, we can call attatchInterrupt(), then Lowpower.powerDown() will put it to sleep. When the pin 2 state changes, it will call the interrupt function and then the program will continue from where it was. The complete code for the Arduino Pro Mini to access the PCF8563:

//PCF8563.ino
//INCLUDES
#include <LowPower.h>
#include <Wire.h>
#include <avr/sleep.h>
#include <avr/power.h>
#include <avr/wdt.h>

//GLOBAL
#define LED_PIN 13

//BUTTON
#define BUTTON 2

//TIME
#define PCF8563address 0x51
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
String days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",                 "Friday", "Saturday" };

byte bcdToDec(byte value){
 return ((value / 16) * 10 + value % 16);
}

byte decToBcd(byte value) {
 return (value / 10 * 16 + value % 10);
}

void readPCF8563() {
 Wire.beginTransmission(PCF8563address);
 Wire.write(0x02);
 Wire.endTransmission();
 Wire.requestFrom(PCF8563address, 7);
 second = bcdToDec(Wire.read() & B01111111); 
 minute = bcdToDec(Wire.read() & B01111111); 
 hour = bcdToDec(Wire.read() & B00111111);
 dayOfMonth = bcdToDec(Wire.read() & B00111111);
 dayOfWeek = bcdToDec(Wire.read() & B00000111);
 month = bcdToDec(Wire.read() & B00011111); 
 year = bcdToDec(Wire.read());
}

void wakeUp(){
 // Just a handler for the pin interrupt.
 while (!digitalRead(BUTTON)) {};
}

void setup() {
 pinMode(BUTTON, INPUT_PULLUP);
 pinMode(LED_PIN, OUTPUT);
 pinMode(0, OUTPUT);
 pinMode(1, OUTPUT);
 pinMode(3, OUTPUT);
 pinMode(4, OUTPUT);
 pinMode(5, OUTPUT);
 pinMode(6, OUTPUT);
 pinMode(7, OUTPUT);
 pinMode(8, OUTPUT);
 pinMode(9, OUTPUT);
 pinMode(10, OUTPUT);
 pinMode(11, OUTPUT);
 pinMode(12, OUTPUT);

 digitalWrite(0, LOW);
 digitalWrite(1, LOW);
 digitalWrite(3, LOW);
 digitalWrite(4, LOW);
 digitalWrite(5, LOW);
 digitalWrite(6, LOW);
 digitalWrite(7, LOW);
 digitalWrite(8, LOW);
 digitalWrite(9, LOW);
 digitalWrite(10, LOW);
 digitalWrite(11, LOW);
 digitalWrite(12, LOW);
 digitalWrite(LED_PIN, LOW);

 Wire.begin();
 Serial.begin(9600);
 delay(100);
}

void loop(){
 attachInterrupt(0, wakeUp, LOW);
 LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
 detachInterrupt(0);
 readPCF8563();
 Serial.print(hour);
 Serial.print(":");
 Serial.print(minute);
 Serial.print(":");
 Serial.println(second);
 delay(1000);
}

Power Consumption

power consumption arduino power down

The result was a code with 20% usage of ROM and 25% of RAM. The power consumption was measured as 16 uA. Because of this, a simple battery with 120 mAh would last 312 days on standby (not counting the backup battery for the clock, which would last for years).

Last week I was happy with this result, but I found out Sparkfun’s blog post, located here, on which the author, named Nate, wrote he was able to reduce the current even further to 1.01 uA. That was incredible and my jaw dropped. Therefore, I went again for the datasheet to look for information.

atmega328p power current brown-out disabled

As stated above, it is possible to reduce the power even more, and the current the circuit had (16 uA) was because the brownout detector was probably turned on. Consequently, I needed to disable it to reach lower values.

As mentioned on the same blog article, Nate did that by altering the fuse bits of his Atmega328. It happens that our chip here is the Atmega328p-pu, a little different from his, and he had an AVR programmer name MKII, while I did not have any.

fuse bits

I went to look over the internet about how to make an Arduino Uno as an ISP programmer in order to bootload an Arduino Pro Mini, altering its fuse bits and disabling the BOD all at the same time. Needless to say, I went through a hell of trouble, but I was successful. There are many threads about people having the same issue, so I am writing another blog post on how to do that: how to bootload an Arduino Pro Mini if you do not have any programmers at all. The problem with this is that, while the Arduino Uno is a good AVRISP, it fails to change the fuse bits of its slave, for some reason I still do not know yet. It took me an afternoon to find out, but you can check it here.

Conclusion

power consumption arduino power down 2Incredible! It was possible to reduce the power consumption even better than expected, 26 times lower than before, to amazing 0.6 uA. A tipical 240 mAh CR2032 would last more than the watch itself, more than a decade. Good work! Now it is time to get our watch better, adding an Atmel non-volatile memory such as the AT24C64. This IC will be very useful to our watch because we want to add a step and calorie counter to it, and we want to store the data in a way we wont lose it. But that will be covered in my next tutorial.

Where to go from here

8 thoughts on “How to make an Arduino Pro Mini bare bones with Real-time Clock

  1. Great article Ben. Just need help with the arduino wakeup. Is it possible to wakeup the arduino from sleep using an alarm from the pcf8563? You wakeup the arduino using a push button switch. I want to take it 1 step further and automate it by making the pcf8563 generate an alarm (/sq wave) on the CLKOUT pin every 10mins or so and hence wakeup the arduino using an ISR on pin2. Thank u.

    Like

      1. Thanks for the tip Kevin. The arduino FB group would come in handy. I’ve searched all over the internet for using the pcf8563 INT_ pin as an interrupt to wakeup the arduino. Guess I’ll have to figure this one out myself. 🙂

        Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s