Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
This is a low power clock project using the Arduino nano. The display I have used is the Oled SSD1306 0.9 inch (128x64) display and the time keeper is the rtc DS1302 module. I prefer this module as it will run happily on 3.3v. I have re-used certain previous codes from using a nokia display, to work with an Oled display so you may see some similarities.
I have used the 128x64 in 32 pixel mode for compatibility, and it seems quite happy.
The complete project uses 9 wires and running off 3.3v, it can be powered by one Li-ion battery connected to the Nano Vin. I have used the low power library to force the Nano to sleep for 250MS each second to further prolong battery life.
GitHub - rocketscream/Low-Power: Low Power Library for Arduino
Or use Code Version 2 for an updated display.
#include <Arduino.h>
#include <Ds1302.h>
#include <LowPower.h>
// DS1302 RTC instance
Ds1302 rtc(9,7,8); // RST , CLK , DAT
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const static char* WeekDays[] =
{
"Monday ",
"Tuesday ",
"Wednesday ",
"Thursday ",
"Friday ",
"Saturday ",
"Sunday "
};
void setup() {
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
rtc.init(); // initialize the RTC
display.clearDisplay(); // clears the screen and buffer
// display.drawRect(0, 0, 84, 30, BLACK);
// display.drawRect(0, 29, 84, 12, BLACK);
}
void loop()
{
// get the current time
Ds1302::DateTime now;
rtc.getDateTime(&now);
static uint8_t last_second = 0;
if (last_second != now.second)
{
last_second = now.second;
display.setTextColor(SSD1306_WHITE);
display.setTextSize(2);
display.setCursor(18,0);
if (now.hour <= 9) { //If Hour is single figures, put a 0 in front
display.print("0");
}
display.print(now.hour);
display.print(":");
if (now.minute <= 9) { //If Minute is single figures, put a 0 in front
display.print("0");
}
display.print(now.minute);
display.print(":");
if (now.second <= 9) { //If Seconds is single figures, put a 0 in front
display.print("0");
}
display.print(now.second);
display.setTextSize(1);
display.setCursor(27,20);
display.print(WeekDays[now.dow -1]);
display.print(now.day);
display.print("/");
display.print(now.month);
display.display();
display.setTextColor(SSD1306_BLACK);
display.setCursor(27,20);
display.print(WeekDays[now.dow -1]);
display.print(now.day);
display.print("/");
display.print(now.month);
display.setTextSize(2);
display.setCursor(18,0);
if (now.hour <= 9) {
display.print("0");
}
display.print(now.hour);
display.print(":");
if (now.minute <= 9) {
display.print("0");
}
display.print(now.minute);
display.print(":");
if (now.second <= 9) {
display.print("0");
}
display.print(now.second);
// No need to display the screen again
}
LowPower.powerDown(SLEEP_250MS,ADC_OFF,BOD_OFF);
}
#include <Arduino.h>
#include <Ds1302.h>
#include <LowPower.h>
// DS1302 RTC instance
Ds1302 rtc(9,7,8); // RST , CLK , DAT
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
// The pins for I2C are defined by the Wire-library.
#define OLED_RESET 4 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const static char* WeekDays[] =
{
"Monday ",
"Tuesday ",
"Wednesday ",
"Thursday ",
"Friday ",
"Saturday ",
"Sunday "
};
const static char* MonthText[] =
{
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
};
void setup() {
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
rtc.init(); // initialize the RTC
display.clearDisplay(); // clears the screen and buffer
display.drawLine(12,18,112,18,WHITE);
}
void loop()
{
// get the current time
Ds1302::DateTime now;
rtc.getDateTime(&now);
static uint8_t last_second = 0;
if (last_second != now.second)
{
last_second = now.second;
display.setTextColor(SSD1306_WHITE);
display.setTextSize(2);
display.setCursor(15,2);
if (now.hour <= 9) { //If Hour is single figures, put a 0 in front
display.print("0");
}
display.print(now.hour);
display.print(":");
if (now.minute <= 9) { //If Minute is single figures, put a 0 in front
display.print("0");
}
display.print(now.minute);
display.print(":");
if (now.second <= 9) { //If Seconds is single figures, put a 0 in front
display.print("0");
}
display.print(now.second);
display.setTextSize(1);
display.setCursor(17,22);
display.print(WeekDays[now.dow -1]);
display.print(now.day);
display.print(" ");
display.print(MonthText[now.month -1]);
display.display();
display.setTextColor(SSD1306_BLACK);
display.setCursor(17,22);
display.print(WeekDays[now.dow -1]);
display.print(now.day);
display.print(" ");
display.print(MonthText[now.month -1]);
display.setTextSize(2);
display.setCursor(15,2);
if (now.hour <= 9) {
display.print("0");
}
display.print(now.hour);
display.print(":");
if (now.minute <= 9) {
display.print("0");
}
display.print(now.minute);
display.print(":");
if (now.second <= 9) {
display.print("0");
}
display.print(now.second);
// No need to display the screen again
}
LowPower.powerDown(SLEEP_250MS,ADC_OFF,BOD_OFF);
}
Comments