Introduction: DS3231 OLED Alarm Clock With 2-button Menu Setting and Temperature Display

UPDATE: V1.3 of clock packages uploaded with bug fix and enhancements. See below for details,

Video at:: http://youtu.be/ikNw1iLE9vg

Alarm demo video: http://youtu.be/jlZBCuQeswA

This is an OLED alarm clock I built using an Arduino Micro, a tiny OLED 128x64 display using the SSD1306 controller and I2C interface, and a precision DS3231-based real-time clock module with rechargeable battery backup. It features a menu system for setting the RTC (no serial port or USB required)

Two versions are shown - the basic digital/analog clock and a version with "Pusheen" graphics and animation.

It uses the Adafruit graphics libraries and DS3231 library, included in the distribution.

Code for both, including needed libraries, may be downloaded directly from the link below in Step 4.

v1.3

I fixed a problem with the v1.2 code that would cause compilation errors for any non-ATmega32U4 Arduino. I had added a compact "note" function to generate a frequency on Pin 10 if the "speaker" alarm output option was selected. The function I included uses the timer structures for ATmega32U4. In v1.3, I added a non-ATmega32U4 version of the "note" function and added conditional compilation directives to automatically compile the correct version. I also compile the "note" function only if the "speaker" output is selected, saving memory if any other output option is selected. I tested the code with all board types in the IDE and received no compilation errors.


v1.2

I fixed a bug that would cause the alarm to timeout after less than the full 60 seconds if the previous alarm was silenced with a button press.

The status of alarm enable/disable is now stored in EEPROM and will survive a power failure. Previously, the alarm was always enabled after a power failure.

If the clock is left in setting mode, it will return to the normal display after 30 seconds without a button press.

I moved the alarm enable/disable indicator from the analog clock to between the time and temperature.

When the alarm sounds, the entire display now flashes in inverse/normal video at 5 Hz until the alarm is silenced. Previously, an asterisk flashed within the analog clock.

There is an optional feature to dim the display between 10 PM and 5 AM. Uncomment this line at the beginning of the program to enable this feature.

//#define dimming

The behavior of the alarm output at Pin 10 of the Arduino can be selected by uncommenting ONE of the following lines at the beginning of the code:

The first option is the default and supplies an intermittent (5 Hz) voltage on pin 10 when the alarm is triggered.

//#define beeper //Uncomment if 5 volt continuous tone beeper or buzzer is connected to pin 10 (5 Hz output)

The second option supplies an intermittent (5 Hz) 1580 Hz tone on pin 10 when the alarm is triggered. Pin 10 should be connected to the + terminal of the speaker through a 0.5 to 1.0 microfarad capacitor and possibly a 150 ohm resistor. The capacitor blocks DC voltage from the speaker to preserve the magnet in the speaker from damage. Piezo speakers may be connected directly to Pin 10. Use the resistor for low-impedance (< 150 ohm) speakers.

//#define speaker //Uncomment if speaker is connected to pin 10 through 1 microfarad capacitor and 100 ohm resistor in series (1480 Hz at 5 Hz output)

The final option provides a steady +5 volts on Pin 10 as long as the alarm is active. The voltage drops to zero when the alarm is silent.

//#define voltage //Uncomment if pin 10 is connected to alarm device requiring steady output while alarm is activated

Step 1: Connect the DS3231 Module and 128x64 OLED Module to the Arduino

Picture of Connect the DS3231 Module and 128x64 OLED Module to the Arduino
  • Connect ground connection from Arduino to the DS3231 RTC module and OLED display.
  • Connect +5v from the Arduino to the +5v connections on the DS3231 RTC module and OLED display.
  • Connect the pin assigned to the SCL function on your Arduino to the SCL pins on both the DS3231 module and the OLED display.
  • Connect the pin assigned to the SDA function on your Arduino to the SDA pins on both the DS3231 module and the OLED display.
  • Connect one side of two SPST normally open push buttons to an Arduino ground connection.
  • Connect the other side of one push button to pin 8 of the Arduino. This is the time/date/alarm set mode select button.
  • Connect the other side of the other push button to pin 9 of the Arduino. This is the time/date/alarm set change button.
  • Connect the black wire on a piezo 5 volt buzzer/beeper to the Arduino ground connection. Connect the red wire from the piezo buzzer/beeper to pin 10 of the Arduino. Be sure to use a piezo beeper (NOT a piezo speaker) that generates its own tone when 5 volts is applied. If you use a piezo speaker instead of a piezo beeper, it will only click rapidly when the alarm is triggered. A unit that sounds continuously when power is applied is best, as the code generates a 5Hz interrupted voltage source to pin 10 on its own. NEW!!! Speaker and continuous alarm output now supported. See Step 1 for details on how to enable.
  • Download either the regular or "Pusheen" version of the clock code from here or the link in the introduction.
  • Install the Arduino libraries in the software distribution .zip file.
  • Compile and download the code to your Arduino. The clock and display will start to run. NEW!!! Optional night display dimming supported. See Step 1 for details on how to enable.
  • Set the clock and alarm per the instructions in the next step.

Step 2: Set Your Clock

  • Press the mode set button , then release. The cursor will flash on the day-of-week field. Press and hold the set button to advance the day-of week to the next day at a 5Hz rate, or do a short press to advance to the next setting. Note: the RTC will use whatever day-of-week you set. It will not automatically calculate the day-of-week for the date and year.
  • Press and release the mode set button to advance the cursor to the month field. Press and hold the set button to scroll through the months quickly, or do a short press to advance to the next setting.
  • Press and release the mode set button to advance the cursor to the date field. Press and hold the set button to scroll through the dates quickly, or do a short press to advance to the next setting. Note that the clock chip knows the correct number of days in each month. However, you can set an illegal date for months with less than 31 days, like "February 30". If you do, the clock will advance the date at midnight until the 31st is reached, then roll over to the first. Thereafter, the date will roll over to 1 at the correct date for the set month. Just don't set an illegal date and all will be well!
  • Press and release the mode set button to advance the cursor to the year field. Press and hold the set button to scroll through the years quickly, or do a short press to advance to the next setting. Valid ranges are 2000 to 2099. The RTC keeps track of leap years automatically. When you first power up the clock, the date will be January 1, 1900. Just advance the year to the correct value as normal.
  • Press and release the mode set button to advance the cursor to the hour field. Press and hold the set button to scroll through the hours quickly, or do a short press to advance to the next setting. The clock uses only the 12--hour mode with AM/PM indications.
  • Press and release the mode set button to advance the cursor to the minutes field. Press and hold the set button to scroll through the minutes quickly, or do a short press to advance to the next setting.
  • Press and release the mode set button to advance the cursor to the seconds field. Press the button momentarily to reset the seconds to zero, or hold the button to freeze the seconds at zero and release to synchronize with an external time source.
  • Press and release the mode set button to advance to the alarm setting screen. Press and hold the set button to scroll through the alarm hours setting quickly, or do a short press to advance to the next setting.
  • Press and release the mode set button to advance to the alarm minutes setting field.Press and hold the set button to scroll through the alarm minutes setting quickly, or do a short press to advance to the next setting.

  • Press and release the mode set button to advance to the alarm enable/disable field. Press and hold the set button to toggle repeatedly between alarm on and off settings, or do a short press to advance to the alternate setting. Note that when the alarm is on, an asterisk appears between the time and temperature. When the alarm is triggered, the entire display flashes in inverse video. The piezo buzzer will also beep at a 5 Hz rate (default option). The alarm will time out after 60 seconds if not manually silenced. A short press of the set button silences the alarm, leaving it on for the next day. In the event of a power failure, the alarm enable flag state is stored in EEPROM and restored on power-up. If an alarm has occurred during the power failure and the alarm was enabled, the alarm will sound immediately when power is restored. The alarm will sound, even if the clock is left in the setting modes.

  • Press and release the mode set button to return to normal mode. The display will automatically exit setting mode 30 seconds after the last button press.

Step 3: Technical Details

The software enables a very accurate 1Hz PPS signal on the "SQW" pin of the DS3231 module.

The DS3231 module uses the temperature sensor to compensate for clock drift, keeping time accurate to 1 or 2 minutes/year.

The temperature is normally checked and updated by the RTC once every 64 seconds. However, the software forces a temperature reading and oscillator adjustment as often as 5 times/second. This results in better accuracy and faster updating of the temperature display.

The on-board battery is not a disposable Lithium, but a rechargeable Lithium Ion unit. When connected to power, the RTC module charges the battery. A fully charged battery will maintain the time setting for up to one year without applying additional power.

You can "freeze" the display at any point by pressing and holding the mode set button. When the button is released, updating will resume. Clock accuracy is not affected.

The clock module contains a 32K EEPROM chip that can be used for data storage. It has an independent I2C address. It is not used for this project.

The code should work with the Sparkfun Chronodot module.

Step 4:

Code and library downloads, in .zip archive.....

Comments

john_aek (author)2015-05-18

Arduino: 1.6.3 (Windows 7), Board: "Arduino Uno"

Build options changed, rebuilding all

Pusheen_Clock_Generic.ino: In function 'void set_alarm()':

Pusheen_Clock_Generic.ino:759:54: error: cannot convert 'boolean* {aka bool*}' to 'const uint8_t* {aka const unsigned char*}' for argument '5' to 'void DS3231_set_a1(uint8_t, uint8_t, uint8_t, uint8_t, const uint8_t*)'

Multiple libraries were found for "Adafruit_GFX.h"

Used: C:\Users\johnp51\Documents\Arduino\libraries\GFX

Not used: C:\Users\johnp51\Documents\Arduino\libraries\Adafruit-GFX-Library-master

Multiple libraries were found for "Adafruit_SSD1306.h"

Used: C:\Users\johnp51\Documents\Arduino\libraries\Adafruit_SSD1306-master

Not used: C:\Users\johnp51\Documents\Arduino\libraries\oled

Error compiling.

This report would have more information with

"Show verbose output during compilation"

enabled in File > Preferences.

df99 (author)john_aek2015-05-18

I uploaded new packages with both errors fixed. It should work with old and new IDE versions.

df99 (author)df992015-11-14

The code for both versions is found on the last step of the Instructable. I tested just now. Both download links work fine.

fkhan56 (author)df992017-04-27

Nice work! I just made one on proto board. Could you please kindly tell me where I can find the generic code with alarm and without pusheen? both codes are same on this page. I would like to incorporate it in an application with rotary encoder and data input with one hour to 24 hour alarm duration. That would be very useful in animal feed management. I have a feeder designed to feed my pigeons and dogs while I am away.

Hope to hear from you soon.

My best regards.

Felix

JohnO77 (author)df992015-11-13

the code links are broken - can you provide the link for the non pusheen code?

df99 (author)JohnO772015-11-14

The code for both versions is found on the last step of the Instructable. I tested just now. Both download links work fine.

df99 (author)john_aek2015-05-18

It appears the latest IDEs have stricter type checking and require the changes mentioned in these board postings

http://forum.arduino.cc/index.php?topic=309872.0

http://forum.arduino.cc/index.php?topic=309119.0

Try this:

Change this line in both of the clock sketches within the set_alarm() function::

boolean flags[5] = { 0, 0, 0, 1, 1 }; //Set alarm to trigger every 24 hours on time match

...to this:

byte flags[5] = { 0, 0, 0, 1, 1 }; //Set alarm to trigger every 24 hours on time match

ALSO:

In the Adafruit_SSD1306.h header file in the Adafruit library, change:

void dim(uint8_t contrast);

to:

void dim(boolean contrast);

The clock sketches now compile and run correctly with IDE v1.6.4.

In both cases the issue is a type mismatch between "boolean" and "uint8_t". v1.06 of the IDE allowed it, but the newer IDE versions do not.

Best,

Don

lkndave (author)df992016-04-30

that fixed it. thanks v1.6.5

VladimirV37 (author)2017-12-08

Hi there! Im making an alarm clock playing custom song, because my gf hates the digital beep beep sound (being jazz singer). It will be all luxurious encased in ebony wood... You know, when you love her...

Im using DFPlayer mini (https://www.dfrobot.com/wiki/index.php/DFPlayer_Mini_SKU:DFR0299) and i've implemented additional menu functions to choose the mp3 (saved in eeprom) to wake you up and some sort of snooze function.

I have managed to turn on the DFPlayer in setup(): "mp3.begin();" But the problem is when i call the "mp3.playFolderTrack(1, tracknum);" function to play the song and actually wake my love up, the OLED goes nuts and either freezes, displays random dots or blinks the "wake_SET" inficator snowflake ("*"). I've googled the hell out of it and found nothing helpfull.

Can you help? Christmas is coming!

- The cause may be something around the OLED buffer not being cleared.
- DFPlayer uses UART serial (Software Serial in this case), may it interfere with I2C?
- I am able to call the mp3 playback in setup() and it starts playing fine, but not anywhere else
- I've tested both libraries for DFPlayer (DFRobotDFPlayerMini.h, DFMiniMp3.h) with similar "OLED goes bannanas" result
- After googling "OLED random dots" many people claim the problem is with something around the I2C bus
- Is it possible that the problem is with the alarm clock being so repetitive in operation and DFPlayer is such a one time "call the mp3 function to play" system?

My code (if alarmTrig is 0, play the song and set alarmTrig to 1, woks fine...)

SoftwareSerial secondarySerial(10, 11); // RX, TX
DFMiniMp3<SoftwareSerial, Mp3Notify> mp3(secondarySerial);

if(wake_SET && DS3231_triggered_a1()){
beepcount = beepcount + 1;
if(beepcount <= 600){
if (alarmTrig == 0) {playMp3();}
if(!flash){display.invertDisplay(1);}
}
else{beepcount = 0; DS3231_clear_a1f(); alarmTrig = 0;}
}
_____________________________________________
void playMp3(){
mp3.playFolderTrack(1, tracknum); // sd:/01/001.mp3
Serial.print("ALARM TRIGGERED");
alarmTrig = 1;
}

df99 (author)VladimirV372017-12-11

The clock has an inner loop that runs every 500ms based upon the millis counter the code outside this loop rubs at full speed. The normal alarm beeper uses the alarm flag to toggle the alarm output on/off every time the inner loop executes, resulting in a 1/2 second on, 1/2 second off activation of the alarm.

I think your issue is that you are checking the alarm flag and calling the playback function every time the 500ms inner loop executes, retriggering it every half-second! You need some kind of flag that allows it to be called once when the alarm trigger occurs, and never again until the alarm is silenced manually or times out. Also, the playback function and library may be incompatible with the Adafruit graphics library.

Lacybad made it! (author)2017-11-01

Awsome clock!

Thank you for sharing!

Thank you for sharing!

robotjam (author)2017-04-27

I am pretty new to these Arduino's and OLed displays but I just wanted to say thank you for posting this great little alarm clock project. I have tried hundreds of sketches from different online sources and I cant get most of them to work but when yours worked the first time I got excited again and optimistic for future projects. I had some spare parts lying around and in about 10 minutes I had this working perfectly. I used the Arduino 1.8.1 IDE (the newest version at this time). I also tried compiling to a couple different boards, the Nano, the Pro Mini, and the Uno, and they also had no problem. I would like to change the Pusheen graphic to a silhouette of the B9 robot or of the Jupiter 2 but when I tried the LCD Assistant I get nothing is there anything else I could try. As you can see i used a two color OLed but i am considering the larger 1.33 OLed because I don't see that well without my glasses do you have any ideas on how to do that? Again thank you for this cool little alarm clock.

df99 (author)robotjam2017-04-27

Thanks! It was a fun project to make.

Rescaling the code for a bigger display is a bit tricky since I hard-coded the screen coordinates of many of the elements. Bad coding practice, but I never intended to port to another display.

For LCD Assistant, the final image you import must be a monochrome bitmap and must be a multiple of 8 bits in both the x and y axis. You must check the "horizontal" box before exporting to make the data structure compatible with the Adafruit library. Of course the image size must not be larger than the OLED display pixel dimensions.

robotjam (author)df992017-04-29

I followed your ideas for the LCD Assistant and with the use of the Paint program that came with my computer I think I have this figured out. Sorry but I have one more question, the animated Pusheen scenes on the clock, were they also done with the LCD Assistant or another program. I am a big Lost in Space fan and wanted some moving graphics of the Jupiter 2 taking off and flying and maybe some of the robot doing things. Thank you

robotjam (author)df992017-04-27

Thank you for the tips, I now think I know what I was doing wrong. That seems like a lot of restrictions for a picture but I will try. Sorry but 1 last question, when you hit the export button can it just be exported into a general folder or must it be exported straight into the sketch?

df99 (author)robotjam2017-04-27

I seem to recall that it outputs to a .data text file. You need to incorporate the data into the proper structure at the beginning of the sketch. The output looks like this when saved correctly.

const unsigned char pusheen_teacup [] = {

0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00,

0x00, 0x38, 0x03, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00,

0x00, 0xE6, 0x0C, 0x61, 0xFE, 0x00, 0x00, 0x00, 0x00, 0xC7, 0xFC, 0x3F, 0xFF, 0xC0, 0x00, 0x00,

0x00, 0x83, 0xF8, 0x3E, 0x3D, 0xF0, 0x00, 0x00, 0x01, 0x80, 0x00, 0x00, 0x38, 0xF8, 0x00, 0x00,

0x0F, 0x80, 0x00, 0x3C, 0x00, 0xFC, 0x00, 0x00, 0x3F, 0x9C, 0xC7, 0x3F, 0x00, 0x6E, 0x00, 0x00,

0x0F, 0x1C, 0xE7, 0x3D, 0x00, 0x03, 0x00, 0x00, 0x1F, 0x1D, 0xF3, 0x1E, 0x00, 0x03, 0x80, 0x00,

0x13, 0x01, 0x80, 0x02, 0x00, 0x01, 0x80, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x00,

0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,

0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00,

0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xC0,

0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xE0, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,

0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x08,

0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x8C, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC4,

0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0xC4, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0xC6,

0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xC6, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xC4,

0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x8C, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x88,

0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCE, 0x18, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x38,

0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0xE0, 0x70, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x80, 0xC0,

0x00, 0xC0, 0x00, 0x00, 0x00, 0x03, 0x07, 0x80, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x06, 0x3E, 0x00,

0x00, 0x60, 0x00, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00,

0x00, 0x18, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00,

0x00, 0x07, 0x00, 0x00, 0x00, 0xE0, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x03, 0x80, 0x00, 0x00,

0x00, 0x00, 0xE0, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFE, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

};

robotjam made it! (author)2017-04-27

I also wanted to ask about the line in the instructions that states "Step 3: Technical Details The software enables a very accurate 1Hz PPS signal on the "SQW" pin of the DS3231 module". I did not see anywhere in the instructions where it says to hook up that particular pin. Are we supposed to hook it up and if so which pin on the Arduino do we plug it to? Thank you

Again great little project thank you for posting it. Projects like this are a great way for us to learn with.

df99 (author)robotjam2017-04-27

The DS3231 supports a 1 pulse-per-second square wave signal that is brought out to one of the pins on the module. It must be enabled in software. I turn the feature on during initialization, but no connection is needed to that pin for normal clock operation. If you put a voltmeter on that pin, you will see it go high once per second. Some devices need a 1 PPS signal to sync to an accurate time source. Many GPS receivers have such a signal. This is nowhere near as accurate as a GPS unit, but it is a temperature-compensated time source and good enough to serve as a reference for other devices.

AlanGP made it! (author)2016-12-27

Made a perf-board clock with the basic sketch loaded. I apologise for the crap photos, never used the iPad for this before. I am running the project off a single lipo cell with a small battery management board, which looks after the under/over voltage and charging issues. I added a 2N2222 NPN small signal transistor to the piezo buzzer circuit (1k resistor from base to Arduino pin and a 10k resistor from base to emitter/ground with the piezo between collector and VCC. This was to take account of the 3 volt Arduino Pro Mini in use and got rid of the squeak caused by 3.3 volts and a 5 volt piezo. The lipo is connected to the raw pin of the pro mini but directly to the I2C devices. There are no external I2C pull-ups. (The compiler also complained about running short of memory but it uploaded and works without a problem) The additional green button is in parallel with the "set" button to allow easier alarm disable and the black button is an on/off switch to save the battery. The major modules can be removed and used elsewhere if required. The circuit works fine and now it's built, I will check out the sketch to understand what I have built. Since I am in Europe, I have already commented out the line that converts temperature to Fahrenheit and the display is now in Celsius. I'm very grateful to df99 for the work he has put into this project. I think I will eventually remix this with a larger display. Many Thanks, A Merry Christmas and a Happy New Year. AlanGP

robotjam (author)AlanGP2017-04-27

Hi ,great work on your alarm clock. I hope you don't mind but I would be very interested in how you made all these changes, do you have some sort of wiring diagram or something a noob could understand? I especially would like to know the LiPo battery connections and voltage, is it a 3.7 volt battery. Also the on/off switch how was that wired. Sorry for the questions but I am relatively new to these devices and am just trying to learn. Thank you

df99 (author)AlanGP2016-12-27

Hi, Alan. Your build looks very nice! The 2N2222 trick is a great way to boost the drive to a more power-hungry speaker. Permanent magnet (non-piezo) speakers can eventually demagnetize if a DC current is fed to them too long, so a series capacitor of a microfarad or two is recommended.

As you found, the DS3231 temperature sensor returns its value natively in Celsius. I have to convert it for Farenheit, but just eliminating the conversion in the code works fine for a Celsius display.

I never used I2C pullups, I believe the DS3231 module does have them installed, however. I believe I checked this once.

After I made a few minor software updates, I built and gave a clock to each of my daughters for Christmas a few days ago. I put them in a box covered with Pusheen stickers (see new pics at the beginning of this Instructable). I powered it from a dual-USB port cell phone charger so they can charge their Iphones with it as well. I can easily change the code if needed by unplugging the charger and plugging into the USB port on my computer.

AlanGP (author)df992016-12-28

Hi df99, im going to look at the pusheen variant with a view to changing the graphics to suit my personality. Again, gratitude for your work - its a lot easier when someone else (brighter) takes the slog out of the programming.

df99 (author)AlanGP2016-12-28

There is an application floating around on the web and Adafruit called LCD Assistant that allows you to import a monochrome bitmap image and generate an Arduino/Adafruit-compatible data structure. The imported bitmap must be a multiple of 8 bits in both the x and y axis. You must check the "horizontal" box before exporting to make the data structure compatible with the Adafruit library.

AlanGP (author)df992016-12-28

Aha! someone else brighter than me - thank you

AlanGP (author)AlanGP2016-12-28

The only remaining problem is that, in this form and as can be seen in the photo, the two "on" LEDs on the Arduino and DS3231 boards are very bright - they may have to go - pointless dimming the screen at night otherwise. Since this is rapidly turning into my favourite alarm clock and becoming a "keeper" this would not represent a problem.

df99 (author)AlanGP2016-12-28

I have my Arduino and RTC in a box or I would have removed those SMD LEDs. They are way too bright. On my other "Four Letter Word Clock" Instructable I had to do that as the light leaking from the enclosure was annoying.

run7 (author)2017-03-09

doesnt work at all for code

please update the code

PaulI38 (author)2017-01-16

Hi df99

I would like to add the second wake up, I know it is possible on the DS3231. But I am not so Asse like you. Could you assist... I am not sure will it correct or not...

//Subroutine to set alarm 2

void set_alarm2()

{

// flags define what calendar component to be checked against the current time in order

// to trigger the alarm - see datasheet

// A2M2 (minutes) (0 to enable, 1 to disable)

// A2M3 (hour) (0 to enable, 1 to disable)

// A2M4 (day) (0 to enable, 1 to disable)

// DY/DT (dayofweek == 1/dayofmonth == 0)

byte flags[4] = { 0, 0, 1, 1 }; //Set alarm to trigger every 24 hours on time match

// set Alarm2

DS3231_set_a2(wake_MINUTE, wake_HOUR, 0, flags); //Set alarm 2 RTC registers

}

//Subroutine to get alarm 2

void get_alarm2()

{

uint8_t n[3];

uint8_t t[3]; // minute,hour,day

uint8_t f[4]; // flags

uint8_t i;

Wire.beginTransmission(DS3231_I2C_ADDR);

Wire.write(DS3231_ALARM2_ADDR);

Wire.endTransmission();

Wire.requestFrom(DS3231_I2C_ADDR, 3);

for (i = 0; i <= 2; i++) {

n[i] = Wire.read();

f[i] = (n[i] & 0x80) >> 7; // 0x80 - 128

t[i] = bcdtodec(n[i] & 0x7F); // 0x7F - 127

}

f[3] = (n[2] & 0x40) >> 6;

t[2] = bcdtodec(n[2] & 0x3F); // 0x3F - 63

wake_MINUTE = t[0];

wake_HOUR = t[1];

}

Thank you in advance

Pimv1 (author)2016-12-28

Hello fd99......

I have a question, is it possible to add a "snooze" option to the code?

rdmyldrmr (author)2016-09-15

Hi and thanks for the instructable. Everything works great.

I tried to set multiple alarms which second alarms goes off ten minutes after the first and the third goes 20 minutes later. But I couldnt do it with DS3231_triggered_a2 and DS3231_triggered_a3.

What do you think I'm doing wrong? Is there a smarter way of doing this without using 'triggered' method?

df99 (author)rdmyldrmr2016-12-28

Try adding counters that are triggered by the existing alarm that count the number of inner 100ms timed loops through the code. That would allow additional alarms at intervals after the initial alarm

AlanGP (author)2016-12-27

Additionaly, Arduino IDE 1.6.13 using the libraries supplied with the sketch. I was previously using the Sodaq DS 3231 library but the alarm clock sketch would not compile so I changed to the supplied libraries, which fixed it. I think the compiler must be more case sensitive and generally more picky than previously. The other RTC/DS3231 sketches I had been running previously also compile on this library without issue - odd, but if it ain't broke don't fix it. ?

df99 (author)AlanGP2016-12-27

I recall I needed a very specific DS3231 library for some reason, settling on the one in the distribution. I think it had to do with a function to force more frequent temperature readings, which some libraries lack, Not 100% certain though.

maxorama (author)2016-12-19

Hi, is it possible to set the alarm duration in the menu? I'd like to use the timer for a pump and need to change the duration. Also interval alarm would be nice, like every 2nd day, ever 6 hours etc

df99 (author)maxorama2016-12-27

The alarm duration cannot current be set in a menu item. If you would like to change it in the latest non-Pusheen version of the code, look at line 133:

if(beepcount <= 600){ //Sound alarm for 60 seconds

The alarm duration is set by counting the number of 100ms iterations through the main "inner loop" of the code. Just set the comparison number (currently 600 for 60 seconds) for the number of 100ms intervals you'd like and recompile.

ЕвгенийП8 (author)2016-11-02

where download circuit?

Press the "next" button above the comments section.
There you will find a description of the circuit and pictures of it on a breadboard. You will also find the code there.

martinhui (author)2016-03-30

I have this error, how to fix it?

#if (SSD1306_LCDHEIGHT != 64)

#error("Height incorrect, please fix Adafruit_SSD1306.h!");

#endif

I found your code like many others. because I got the same error, I would follow because I found the OLED has same pin out with mine, others are interchanged the VCC and GND

GavinF2 (author)martinhui2016-05-19
The Adafruit_SSD1306.h file is initially setup for a 128x32 display.
One part of it looks like this.

/*=========================================================================
SSD1306 Displays
-----------------------------------------------------------------------
The driver is used in multiple displays (128x64, 128x32, etc.).
Select the appropriate display below to create an appropriately
sized framebuffer, etc.

SSD1306_128_64 128x64 pixel display

SSD1306_128_32 128x32 pixel display

SSD1306_96_16

-----------------------------------------------------------------------*/
// #define SSD1306_128_64
#define SSD1306_128_32
// #define SSD1306_96_16

Change the last three lines in this part of the library to look like this.

#define SSD1306_128_64
// #define SSD1306_128_32
// #define SSD1306_96_16

martinhui (author)GavinF22016-05-21

Thanks VM

df99 (author)martinhui2016-12-14

Note that if you use the copy of the Adafruit library I included in the distribution, this error will not occur. It is happening because you are using an Adafruit graphics library obtained elsewhere, with the default display type set to 128x32.

StuartS9 (author)2015-11-29

Please could you tell me which version of Aduino works with this project.

I have tried to verify both the files you have provided. With Arduino v1.0.2-r2 and v1.6.6. I get numerous errors?

This is one of them:-

Arduino: 1.6.6 (Windows 10), Board: "Arduino/Genuino Uno"

Pusheen_Clock_Generic:12: error: #error ("Height incorrect, please fix Adafruit_SSD1306.h!");

#error("Height incorrect, please fix Adafruit_SSD1306.h!");

^

exit status 1

#error ("Height incorrect, please fix Adafruit_SSD1306.h!");

This report would have more information with

"Show verbose output during compilation"

enabled in File > Preferences.

Hope you can help.

Many hanks.

Stuart.

GavinF2 (author)StuartS92016-05-19

The problem is in the Adafruit_SSD1306.h being for 128x32 by default. I have left a solution in this comment page

df99 (author)GavinF22016-12-14

Note that if you use the copy of the Adafruit library I included in the distribution, this error will not occur. It is happening because you are using an Adafruit graphics library obtained elsewhere, with the default display type set to 128x32.

smokiethebear912 made it! (author)2016-11-22

I am wondering if there is a way to make it just turn pin 10 high for the 60 seconds of alarm duration vs it switching at 5 hz. I am hooking it to the gate of a mosfet to switch a fire alarm on but because of the 5 hz switching rate of the alarm pin it isn't working as intended.

df99 (author)smokiethebear9122016-11-22

Oops. That change required the RTC alarm flag to be reset (happens after 600 seconds) AND the manual alarm enable to be off, which is wrong. The solution is to turn off the alarm only when the alarm flag is cleared (after 600 seconds, if the alarm silence button is pressed, or if the alarm has not yet set).

Try using this line for line 72:

if(!DS3231_triggered_a1()){digitalWrite(10, LOW);} //Turn off external alarm for flashing if RTC alarm flag clear

That only shuts off the alarm every loop if the RTC alarm flag is cleared. That will prevent the intermittent output on pin 10 and allow proper operation of the 600 second alarm timeout and silencing the alarm with the button.

Don

smokiethebear912 (author)df992016-11-22

That works a treat. No more sleeping in for me... and to think it will be even louder when i feed it from 12v vs testing with the 9 volt battery :D

df99 (author)smokiethebear9122016-12-01

I just discovered a bug that may affect your project. There is an alarm timeout function which shuts off the alarm after 600 100ms loops through the timed loop, or 1 minute. If the user resets the alarm with the "set" button, the counter does not get reset. The effect is that the NEXT time the alarm sounds, it will time out before 60 seconds (60 second less the time elapsed before the set button was pressed from the previous alarm cycle). The fix is to change this code block:

if(!digitalRead(9)){DS3231_clear_a1f();}

to

if(!digitalRead(9)){DS3231_clear_a1f(); beepcount = 0;}

I have updated code that allows alarm operation with a normal speaker rather than a buzzer. It dims the display from 10 PM to 5 AM. It also returns the display to normal after being left in setting mode after no button activity. I changed the alarm "on" indicator to be between the time and temperature display. I also flash the entire display into inverse mode at 5 Hz when the alarm sounds, rather than flashing the asterisk in the analog clock. I fixed the bug mentioned here as well. I may post the changes here, but will definitely fix the bug in the posted code soon.

smokiethebear912 (author)df992016-12-02

I updated that line and re-uploaded it. Thank you for your assistance in this project. Sadly my car is broken currently, so I'm not working, therfore I haven't had a chance to use it for it's intended purpose yet. I also still need to figure out how i want to enclose it as it's now just on a breadboard.

df99 (author)smokiethebear9122016-12-03

Check the updated code with bug fixes and selectable output modes. Also selectable night dimming.

About This Instructable

83,061views

253favorites

License:

More by df99:Four Letter Word Clock With Akafugu Word Generator and Inspirational PhrasesArduino Coffee Brewer Water Fill SystemDS3231 OLED alarm clock with 2-button menu setting and temperature display
Add instructable to: