Introduction: Turing Alarm for Arduino

About: I am a student.

NOTE: This Instructable is currently incomplete. I will finish it before September 19. 

I started this project after seeing Nick Johnson's Turing Alarm clock. I found that the PIC chip he used was a little too advanced for me, so I decided to use the Arduino microcontroller. The original project by Nick Johnson can be found on his blog here . All credits for the idea goes to Nick.

The turing alarm forces you to solve math problems when you wake up. If you get the math problem correct, the alarm stops, and if you don't, you will have to solve another one. My version also includes a 12V light dimmer using a MOSFET. A DS1307 real time clock (RTC) keeps track of the time and the menus are controlled with five buttons.



Future improvements:
Joystick control
Math problem level setting
battery backup power
two alarms


Step 1: Materials and Tools

Materials

• Arduino board
I used the Uno board for testing and the Pro Mini for the final project

• DS1307 RTC
You can use the DIP version; I used the breakout from SparkFun

• SparkFun Serial LCD 16x2 (Any serial LCD will work)
This is much easier to interface with than a parallel LCD

• Small 12mm buzzer (2.048 kHz)

• 5 SPST panel mount momentary switches

• 10k pull-down resistors
You will need seven of these

• 1 DC jack panel mount (two if you want light control)

• Project box
I used a 6 x 3 x 2" project box from Radioshack

• Mounting screws and nuts (4-40 ½ inch)
Mount LCD and slide potentiometer

• Female and male headers

• 10K slide potentiometer
Only if you want light control

• N-channel MOSFET
Only if you want light control

• Blank copper PCB
This is optional, but it makes layout easier


Tools

• Soldering iron
• Jumper wire
• FTDI Basic board
• USB-B cable
• Drill with bit
• Dremel / rotary tool
• Ruler
• Breadboard
• Mini push-button switches for testing
• PCB etching and drilling equipment 

Step 2: Solder Headers


You will need to solder headers onto the RTC and the LCD. There are two sets of connections on the LCD: one is already terminated with a JST connector, and the other is empty. They both do the same thing, so pick which one you want to use. I didn't have any JST cables so I desoldered them and attached hookup wires.

If your Pro Mini is new, you will also have to solder headers on them. Be careful with the Pro Mini because some SMT parts are really close to the header vias.


Step 3: DS1307RTC


The RTC module uses the Wire I2C interface to communicate with the Arduino on A4 and A5. The data line (SDA) is on A4, and the clock line (SCL) is on A5. With the coin-cell battery on the module, the RTC can run for up to 17 years without an outside power source. The datasheet recommends using pull-up resistors to 5V on the data lines. For this project ignore the square-wave output (SQW).
If you aren't using the SparkFun breakout make sure to connect a crystal on pins 1 and 2. You can read more about the chip on the datasheet here .

To set the time I used ladyada's example code from her RTC library and tutorial. You can get the library here on her github page. Her code sets the time using the current time on your computer. Make sure to uncomment this line of code:

// RTC.adjust(DateTime(__DATE__, __TIME__));



Step 4: Serial LCD

A serial LCD is easier to use for this project because it only uses one data line (TX). A 16*2 LCD is adequate for this project, but a 20*2 would be better. For beginners like me SparkFun's serial LCD is very easy to interface and use. Simply connect VCC to 5V, GND to GND, and RX to TX on the arduino board. To change a setting on the LCD like cursor position and backlight brightness, simply send a hex command line followed by the setting you want to change. For example, to clear the LCD you send this command line:

Serial.print(0xFE, BYTE);

followed by

Serial.print(0x01, BYTE);

For the turing alarm I used four commands: clear LCD, move to line 1, move to line 2, and set brightness. I wrote the ones used commonly into functions so it can be easily accessed. You can read more about the LCD and commands on the datasheet here .

Step 5: Libraries

In this project I used three libraries for the code: the RTC library from ladyada, the Wire library already included in the IDE, and the debounce (bounce) library from Thomas Fredericks. You can download them here:

RTClib : Ladyada's github page
Bounce : Arduino.cc playground
Wire : Already included in IDE; go to Sketch > Import Library > Wire

Step 6: Pin Layout

The turing alarm uses seven digital pins and two analog pins. The two analog pins are for I2C communication on the RTC and the digital pins are for the LCD, buttons, and the buzzer.

D1 – TX serial to LCD
D2 – increase button
D3 – decrease button
D4 – left button
D5 – right button
D8 – ok button
D9 – buzzer output
*D11 - 12V MOSFET control

A4 – SDA data
A5 – SCL clock
*A1 - Slide potentiometer

I used tactile switches instead of panel mount ones when breadboarding for simplicity. A fritzing breadboard layout is also attached to guide you with breadboarding.

*if you want light control

Step 7: Part 1 - the Code


The code uses seven different while loops for each menu. Within each of those while loops are if statements and display commands. The seven menus are:

• Main menu
• Choose set alarm, brightness, or IO monitor
• Set alarm time
• IO monitor
• Brightness control
• Alarm is on; turn off?
• Alarm math menu (this one is the menu when the alarm goes off)


When the the device is powered up, this function loops:
       displayCurrentTime();

This function gets the time from the RTC and writes it to the LCD screen in a two-line configuration. The date is displayed centered on line 1 and the time is centered on line two.

Setting the alarm is simple: use the up-down buttons to change the time, and the left-right buttons to change between hour, minute, and second. In the future I might increment each minute and second value by five for simplicity and add flashing cursors to which time value is being changed.

When the OK button is pressed, the time is set and this line of code runs:
      if (okDebounce == HIGH) {
      alarmSetting = 1;
      timePosition = 0;
      mathValOne = random(11, 20);
      mathValTwo = random(9, 15);
      mathValThree = random(20, 150);
      inputAnswer = (mathValOne * mathValTwo + mathValThree) - random(-35, 35);
      delay(20);
      MenuPosition = 7;
      delay(100);
      clearLCD();
      delay(500);
}


alarmSetting stores whether the alarm is on or off with a boolean variable: 1 for on, and 0 for off. This is used in other parts of the code to check if the alarm is on or not.
timePosition is simply a variable used to store which time value is being changed (second, minute or time). This resets it to 0, or second. (0 for second, 1 for minute, and 2 for hour).
The next three lines of code determines the math problem. It picks a random value between the values shown based on a seed from randomSeed(analogRead(2)) in the setup.
inputAnswer is a variable that stores what the user inputs as an answer. The line of code shown simply sets the variable to a value that is close to the actual answer.
The next five lines of code clears the LCD and changes the menu.

Step 8: Part 2 - the Code


After the alarm time is set, the loop constantly checks if the alarm time is equal to the real time with this line of code:

if(alarmSetting == 1 && alarmSecond == now.second() && alarmMinute == now.minute() && alarmHour == now.hour() )

The problem with this line is that it doesn't check for date, so the alarm goes off within 24 hours. For my application that is adequate, but if you need to set alarms for more than a day later add a set date function.


When the alarm goes off, this line of code runs:

alarmNoiseOn();
realAnswer = mathValOne * mathValTwo + mathValThree;
moveLineOne();
Serial.print(" Hello!");      // wakeup message

moveLineTwo();
Serial.print(mathValOne);
Serial.print("*");
Serial.print(mathValTwo);
Serial.print("+");
Serial.print(mathValThree);
Serial.print(" = ");
Serial.print(inputAnswer);
Serial.print(" ?");
delay(100);

if(debounceIncrease == HIGH) {
inputAnswer++;
}
if(debounceDecrease == HIGH) {
inputAnswer--;
}


AlarmNoise on is a tone function that loops the buzzer in a familiar "alarm " pattern. realAnswer stores the actual answer that will turn off the alarm. The last two functions check if the up or down buttons have been pressed, which in turn changes the input value.

When the OK button is pressed, the code checks if the input answer is equal to the actual answer:
if(digitalRead(buttonOK) == HIGH && inputAnswer == realAnswer)

If it is, noTone is called (turns off the buzzer) and all the variables are reset to 0. A wakeup message is displayed for five seconds then the alarm returns to the main time menu.

delay(500);
noTone(9);
clearLCD();
alarmSetting = 0;
moveLineOne();
Serial.print(" Good Morning!");
delay(5000);
MenuPosition = 0;
mathValOne = 0;
mathValTwo = 0;
mathValThree = 0;
alarmSecond = 0;
alarmMinute = 0;
alarmHour = 0;



If the input answer is not equal (!=) to the actual answer, then the math values are reset to a different random value, giving the user another problem to solve.

Step 9: Power

Power is currently supplied via a DC jack on the side. Anything between 7 and 12 volts will work for the Arduino. The clock consumes too much power for battery-power to be realistic. With the backlight at 100%, the device draws more than 55 mA of current. With six AA batteries in series (9V), that is still only 42 hours of operation. Without the backlight it still draws around 37 mA, which is better but is still only ~2.7 days.

The 12V light is directly wired to the 12V supply through a MOSFET. The power circuit looks like this:

+12V   >   Arduino RAW & LED positive   >   LED negative to MOSFET drain   >   MOSFET source to GND

The 0V side of the 12V supply and the source pin of the MOSFET are both tied to the GND of the Arduino.

In the future I am going to add a battery backup unit, which charges when the device is plugged in to a wall-wart and drains when it is unplugged. It will have a 7805 regulator that directly feeds into the VCC pin so the battery wont try to power the LED strip.


Step 10: Light Control

There is also a light control that outputs a varied voltage between 0 and 12 by reading a potentiometer and controlling a MOSFET. I included this to control some LED light strips that are in my room. The MOSFET actually receives pulse-width modulation signals from the Arduino, which turns the gate on and off very quickly, resulting in a effect of varied voltage. The function that controls the lighting is very simple:

void lightingFade() {
int val = map(analogRead(1), 0, 1023, 0, 255);
analogWrite(11, val);

if(val < 20) {
val = 0;
}
if(val > 1015) {
val = 1023;
}
}


Local variable val stores the digital PWM value that is mapped from a potentiometer. AnalogRead returns a 10-bit (10^2 - 1) integer, which is then scaled down to a digital 8-bit unsigned integer (2^8 - 1) and then writes it to the control pin on the MOSFET.

Step 11: PCB


I also drew a PCB design in EagleCAD for those who are too lazy to solder on a perfboard. The double-sided one is very densely populated, and is meant for a board-house to make. All the parts are squeezed in to a 5cm square to keep the price low ($9.90 at Seeed). There is also a schematic that comes with the PCB layout.

If you would rather etch your own circuit board (like me), use the single layer version that is much bigger (6*10 cm) and easier to etch. The picture is of the board I etched. Note that there is one jumper that you will need to connect with hookup wire; it is located at the top center of the board.


NOTE : If you open the files in Eagle, you must download my eagle library. There is a footprint for the Arduino Pro Mini and a few other parts in this project. A PDF is also available if you want to just print it out.

Step 12: Mount Buttons and LCD

All of the parts except for the buttons and the jack are mounted with 4-40 screws and nuts. The buttons and jacks are already threaded with a nut, so a 1/4 inch hole is all you need. For the 4-40 screws, I used a ~2.5 mm hole.

The LCD has four mounting holes, one on each corner. The LCD itself does not sit flush with the board, so you will need to use spacers on each hole. I found that two 4-40 nuts work well as spacers. You will need 12 nuts in total for the LCD: 8 for spacing, and 4 for securing.

The slide potentiometer is a little tricky because many spacers are needed. When the knob is attached, it sits much higher than where the mounting holes are. Just keep on adding spacers until the knob sits relatively flush on the box.


Mark where to drill the holes and mount the components. I attached a CorelDRAW file that you can measure dimensions with.

Step 13: Troubleshooting

If you have any questions or comments email me at XYKprojects   at   gmail dot com.

These are adapted from problems I had when debugging and trying to get the thing to work.


The serial LCD is displaying a black line/random text/nothing.
I got this problem very often when working with the LCD. Most of the time the problem fixes itself when you cycle the power or adjust the contrast. To prevent this from happening again, remove the serial wire from the Arduino when uploading code. Sometimes it sends a random serial message that could change the settings on the LCD or display random text. If cycling power does not fix the problem, upload and run Reset_Serial_LCD.pde attached below.


The time stays at 00:00:00 or doesn't change.
Sometimes the RTC stops itself when debugging. Rerun the set-time sketch and you should be fine.