Sun 19 May 2013 In intermediate. tags: arduino alarm clock ds1307 lcd buzzer

Writing this article took somewhat longer than usual, since the scope expanded on the way. Originally, I planned to only show how to use a buzzer, but then I decided to add a DS1307 real-time clock chip to it. And of course, you need a LCD display for showing the time. But unluckily, my previous LCD shield was using conflicting pins with other stuff, so I had to redo it also.

In the end, this was the result:

There are three shields in the picture: buzzer shield, DS1307 shield, and LCD shield. And below them is Olimexino-328, an Arduino clone. You can also use normal Arduino, but I had one Olimexino-328 at hand, so I used it.

Buzzer For the buzzer, I used budget proto shield from oomlout. Other end of the buzzer goes to GND and another to digital pin 9 of Arduino (pin 1 on port B in AVR documentation). When assembling the shield, I used quite big buzzer and then had to be careful what to put above it so that another shield can be put on top of the buzzer shield. Code to make a sound via buzzer is quite simple: procedure Play_Alarm is C : Unsigned_8 := 0; begin MCU.DDRB_Bits (1) := DD_Output; MCU.PORTB_Bits (1) := False; loop for A in Unsigned_8 range 1 .. 100 loop MCU.PORTB_Bits (1) := True; delay 0.002; MCU.PORTB_Bits (1) := False; delay 0.002; end loop; delay 0.5; C := C + 1; exit when C > 5; end loop; end Play_Alarm;

DS1307 Real Time Clock To get the real time clock for the device, I combined DS1307 breakout board kit from Adafruit and Olimex proto shield. A sensible person would solder components directly on the proto shield, but since I had the breakout board ready, I simply soldered the complete board on the proto shield. The board requires wires to 5V, GND, analog pin 4, and analog pin 5. The communication happens via I2C. Since AVR-Ada does not have I2C or DS1307 routines by default, I used my existing I2C package and added DS1307 package, which used the I2C package. The DS1307 package specification is here: package DS1307 is subtype Year_Number is Interfaces.Unsigned_8; -- offset to the year 2000 subtype Month_Number is Interfaces.Unsigned_8 range 1 .. 12; subtype Day_Number is Interfaces.Unsigned_8 range 1 .. 31; subtype Hour_Number is Interfaces.Unsigned_8 range 0 .. 23; subtype Minute_Number is Interfaces.Unsigned_8 range 0 .. 59; subtype Second_Number is Interfaces.Unsigned_8 range 0 .. 59; type Date_Time is record Seconds : Second_Number; Minutes : Minute_Number; Hours : Hour_Number; Day : Day_Number; Month : Month_Number; Year : Year_Number; end record; procedure Init; function Is_Running return Boolean; procedure Set_Time (New_Time : Date_Time); procedure Read_Time (Current_Time : out Date_Time; Status : out Boolean); end DS1307; First, you need to call Init. After that you can check is the clock already running by calling Is_Running function. If the clock isn't running, calling Set_Time will start it. Finally, you can check the current time using Read_Time procedure. Status attribute will tell you was the time reading successful.

LCD Shield I had one LCD shield done previously, but its pin configuration conflicted with pins used by Olimexino-328 and other shields, so I had to create a new LCD shield. For LCD, I used a basic 16x2 display from Sparkfun. This protoshield is from And-Tech.pl/Anduino, but you can use pretty much any protoshield want. No need to try match my protoshields. Before soldering, I tested the connections on breadboard: And after that I made the shield: The LCD display itself goes to the female header. The pin layout is following: LCD PIN PROTOSHIELD PIN 1 GND 2 5V 3 10K TRIMPOT 4 DIGITAL 3 5 GND 6 DIGITAL 4 7 NONE 8 NONE 9 NONE 10 NONE 11 DIGITAL 8 12 DIGITAL 5 13 ANALOG 3 14 DIGITAL 12 15 5V 16 GND

Putting things together After I had all the shields assembled, I put them on top of each other like this: