loading
This Instructable will show you how to build an binary alarm clock, with a touch sensor snooze button. This is my first instructable and my first real arduino project, I hope you like it!

I bought an arduino a while back and I think it's really nice, but I haven't really done anything useful with it yet, so now I thought it was time to make a bigger project. I decided to do an alarm clock since my old one is broken.

Here's a video of it in action:



There seems to be some problems with the video embedding,  If you can't see the video above, here's a link to it: binary alarm clock

Step 1: What Should Be Done?

To help me organize my thoughts about how I should build the clock I wrote down what I think an alarm clock should be able to do. I then tried to build the clock to meet the requirements.



An alarm clock should be able to:                 What I used:
- keep time                                                          - code
- display time                                                      - LEDs 5 for hours, 6 for minutes
- keep an alarm time                                         - code
- let the user set the time                                  - buttons
- let the user set the alarm                               - buttons
- make noise when the alarm goes off.         - speaker
- let the user snooze                                          - touch sensor "button"                     
- let the user turn on and off the alarm.          - touch sensor "button"

It would be nice if it also:
- looks reasonably good                                  - a nice box as case
- is cool and geeky                                           -  true binary display

Step 2: What You Need.


Parts:

For the display:
    - 11 LEDs
    - 11 1kΩ resistors ( don't need to be exact, anything between 300 and 2k should work (a lower value will give brighter light)
    - Perfboard (I used perfboard with separate solderpads for each hole)
For sound:
    - 1 Speaker (piezo or ordinary, if you use an ordinary speaker put a 1kΩ resistor in series with it)
For time and alarm setting:
    - 2 Buttons (Hour button and Minute button).
    - 1 Switch for changing between setting the time and setting the alarm.
    - A piece of thin plywood.
For the touch sensor:
    - Aluminum foil, or even better aluminum tape.
    - Tape or glue to attach the foil.
    - Paper in the same color as the box to hide the sensor
    - Glue for the paper.
    - 1MΩ resistor (you can play with this value a bit, depending on how thick your box is, a higher
       value gives a more sensitive sensor (it will also make it a bit slower).
For everything:
    - Hookup wire (solid core wire)
    - Electrical tape
    - Solder
    - A box to put everything in.

Tools:
- A soldering iron
- Wirecutter and wirestripper
- Drill, or something else to make holes in the case for buttons.
- Saw

Not a must, but good to have:
- A multimeter, for testing connections, etc.
- A solderless breadboard can be good to have to be able to test stuff easily.
- Header pins for connecting the wires to the arduino. I didn't have this and had some problems at first with getting good contact in the connections to the arduino at first, I solved it by securing the connections with tape.



Step 3: Code Structure

I have divided the code for the clock into functions, one for each important bit of functionality. The functions are in separate tabs in the sketch. these are then run in the main loop:

void loop()
{
  clock();       // keep track of time, i.e. update hours, minutes and seconds variables as needed.
  display();   // display the time, or the alarm time, depending on the state of the settings switch.
  alarm();     // checks if it's time for the alarm  to start.
  update_buttons_state();   // checks if the buttons and touch sensor states has changed
  buttons();  // does what the buttons should do
} 

The variables that are needed by several functions are declared in the first tab (where setup() and loop() is) and the variables that are needed only by one function is declared in the same tab as that function.

If you change the DEBUG constant to 1 you will get some output via serial that can be good for troubleshooting, e.g. the time and what value the touchsensor returns.

I have tried to comment and make the code understandable but if you have questions or suggestions for improvements just leave a comment.

Here are the pins I used for the different parts:

- 2 and 4:  Touchsensor (4 is the send pin, 2 is recieve)
- 6              Hour button
- 5              Minute button
- 7              Switch
- 14-18      Display hour pins
- 8-13        Display minute pins

You can use whatever pins you want, just change in the code accordingly.

Step 4: Time Keeping

To keep track of time I used only the arduino, and the standard arduino function millis(). This method won't be completely exact, because the 16Mhz crystal oscillator, that decides the clock frequency of the arduinos CPU, probably  won't be exactly 16 000 000 Hz. The good news is that you can measure how inexact your clock is and compensate for it in your code, because the offset should be constant for a given period of time.

Measure how inexact your arduino is:
As said earlier, the arduino will have a small time error, this error depends on the crystal oscillator and will be different for every arduino, to measure how much my arduino clock differed from the correct time, I programmed it to print out the time ( the hour, minute and second variables) via serial. I then let it run for a long time (Over night and more) and compared the arduino time with a clock I knew was exact, at the start and the end of my measuring period. Divide the time difference with the time the test took to calculate the error each hour. I found that my arduino is about 0.4 seconds to fast every hour. I used exacttimenow.com to get exact time, but if you have a watch you know is very exact, feel free to use that instead.
The code I used to keep the time is an adaptation of some code I found on the arduino forums. I rewrote it with if-statements instead of division and modulo, to see if there would be any speed difference and found that the if-version is more than 15 times faster (although both are still quite fast, more info about the test here).

Since I want the other stuff in my main loop (like checking the touch sensor, checking for button presses, etc.) to happen as often as possible, I used the faster version.

The code:

Every time the clock function is called it adds the time in milliseconds since last it was called to a variable m, when one second has passed (m>999) the second variable is increased by one and m is reset. When the seconds variable reaches 60, the minute variable will be increased by one, and seconds will be set to zero. The same thing happens with the minutes variable; when it reaches 60, add 1 to hours and reset minutes. The hour variable will be reset when it reaches 24.

To compensate that my arduino is 0.4 seconds faster evey hour, I decrease the seconds with two seconds every fifth hour.

____________________________________________________________________

The clock() function:

// CLOCK VARIABLES:
#define MAX_MILLIS_VALUE 34359738
unsigned long current_millis_value = 0;
unsigned long previous_millis_value = 0;
unsigned long m = 0;
int seconds = 0;
int minutes = 0;
int hours = 0;

void clock()
{
  current_millis_value = millis();
  if (current_millis_value < previous_millis_value) // if millis overflows
  {
    m += MAX_MILLIS_VALUE - previous_millis_value + current_millis_value;
  }
  else // if millis has not overflown
  {
    m += current_millis_value - previous_millis_value;
  }
  if (m>999)
  {
    seconds++;
    m = m-1000;
  }
  if (seconds>59) // if seconds == 60
  {
    minutes++;
    seconds = 0;
  }
  if (minutes>59) // if minutes == 60
  {
    hours++;
    minutes = 0;
    if(hours%5==0) // adjust the time with -2 seconds every 5th hour.
      seconds = seconds - 2;  // this will cause seconds to be -2,
                             // therefore seconds can't be unsigned.
  }
  if (hours>23) // if hours == 24
  {
    hours = 0;
  }
 
  previous_millis_value = current_millis_value;
}

______________________________________________________________________

Step 5: Reading the Display

Most binary clocks I've seen uses binary coded decimals (BCD), which means that each didgit is represented in binary separately. But I chose to use true binary representation, mostly because I think it's cooler with real binary, but also because it requires less LEDs, and therefore less pins on the arduino.

The clock uses 24-hour notation.

In the picture below you can see how the display shoud be read. Just add togheter the values of  the lit LEDs to get the time. The second picture in this step has some examples.

Step 6: Building the Display

This will be easier to follow if you look directly on the pictures instead. All text below is in the image notes too.

1. put the LEDs on a piece of perf-board. Remember that LEDs has polarty (long  lead should be connected to positive, short lead to ground (negative)), so put all the LEDs the same way to make it easier later.

2. Bend all short leads towards the middle.

3. Take a piece of wire and strip off the insulation a couple of centimeters, fasten it in the perfboard and put it over the short leads. This wire will later be connected to  the arduino so don't make it to short.

4. Solder the short leads to the perfboard and to the wire. Clip off the short leads.

5. add the 11 1kΩ resistors. One of the leads of each resistor should be next to the long leg of a LED.

6. Solder the resistors to the long leads of the LEDs and clip off the excess leads.

7. Attatch wires to the perfboard next to each  of the unsoldered resistor leads, and solder them togheter. these wires will be attatched to the arduinos pins.

8.  Bind the the wires togheter with cable ties, tape or by wrapping wirepieces around the wires.

I used tape to keep the wires togheter. It's not ideal for getting a good connection to put the wires directly in to the arduino, but it worked ok for me. If you have a row of headerpins, solder the wires to that and use it instead.

Step 7: The Display Code


The display() function works by checking if the hours variable can be divided by 16, if it can, it will turn on the LED representing 16, else turn it off. Then try dividing the remainder of the previous division with 8, turn the 8-led on if it could be divided, else off, divide the remainder of that division with 4 and so on.The same process is then repeated for minutes but starting at 32 instead of 16.

display() uses the hours_p and minutes_p pointers, that points to either the variables hours and minutes, or to the variables alarm_hours and alarm_minutes. What they are pointing to is decided in the settings switch code (in the buttons() function). So when the switch is turned to A (alarm), the display will automatically show the alarm time, and when it's turned back to T (time) the current time will be shown.
____________________________________________________________________

The display() function:

// "INTERNAL" VARIABLES FOR DISPLAY FUNCTION:
int remainder;
int led_value;

void display()
{
  // display() will display the ordinary time or the alarm time,
  // depending on what hours_p points to, this is decided
  // by the settings_switch_state, in the buttons() function
 
  // Display hours:
  remainder = *hours_p;
  for(int i = 0; i < 5; i++) // repeat four all five hour-LEDs
  {
    led_value = 16/round(pow(2,i)); // first LED = 16, second = 8, third = 4 etc.
   
    if(remainder/led_value == 1)
      digitalWrite(hour_pins[i], HIGH);
    else
      digitalWrite(hour_pins[i], LOW);
   
    // the remainder of the hours is saved for
    // the next LED that is displaying a lower value
    remainder=remainder%led_value;
  }
 
  // Display minutes:
  remainder = *minutes_p;
  for(int i = 0; i < 6; i++) // repeat for all six minute-LEDs
  {
    led_value = 32/round(pow(2,i)); // first 32, then 16, then 8 etc.
   
    if(remainder/led_value == 1)
      digitalWrite(minute_pins[i], HIGH);
    else
      digitalWrite(minute_pins[i], LOW);
   
    // the remainder of the minutes is saved for
    // the next LED that is displaying a lower value
    remainder=remainder%led_value;
  }
}
____________________________________________________________________

Step 8: The Snooze Touch Sensor

The principle behind the touch sensor is quite simple. It uses two pins; a send pin and a recieve pin. A resistor connects the two pins, and something conductive, e.g a piece of aluminum foil, is connected to the recieve pin. The foil will work as a capacitor

When the send pin toggles state, the recieve pin will also, but with a slight delay, depending on the size of the resistor and the capacitor. If something conductive, e.g your hand, comes close to the foil the capacitence will change. This will cause the delay to also change,  so by measuring the delay you will know if something is close to the sensor.

There's a good library that does all this measuring for you, called CapSense, written by Paul Badger. Info about the library and a better explanation of how the sensors work can be found here: CapSense library

Building the touch sensor:

1. Attach the aluminium tape or foil on the inside of the box lid.
2. Strip of the insulation from the end of a wire and tape it to the aluminum.
3. solder a 1 MΩ resistor to the other side of the wire. (The value of the resistor isn't critical, but has to be fairly high, just try with what you have handy and see if it works )
4. Cut out a piece of paper that covers the inside of the lid.
5. Glue the paper over the aluminum foil.


Step 9: The Setting Buttons Panel

For setting the time I used two buttons, one for setting hours and one for minutes, and one switch for changing between setting the clock and the alarm.

Building the button panel:

My box had a elevation in the middle that the panel could rest on. If your box don't, you can use four wooden sticks or strips taped/glued in the corners of the box and let the panel rest on those.

1. Measure the inside of your box to see how big you should make the panel.
2. Saw out the panel from a piece of thin plywood. To get a good fit, make the panel a bit bigger
    than the inside off the box and sand off the edges until it fits.
3. Cover the board with masking tape and measure out and mark where you want the holes
    for the buttons to be. The tape will help to prevent the edges of the hole to splinter.
4. Carefully remove the tape.
5. Attach the buttons and solder wires to them.
6. Make button labels. I used letters cut out in electrical tape.
7.First attatch the tape to something flat that you are not afraid of scratching.
8. Cut out the letters with an utility or exacto knife.
9. Carefully remove the letters.
10. Attach the letters to the panel.

 If you can get hold of letraset transfer sheets I think that could work even better.

Step 10: Button and Sensor Code

The code handling the buttons, the switch and the touch sensor is divided into two functions, one for checking if the buttons are pressed and one for doing what the buttons should do if they are pressed i.e. setting the time, setting the alarm, snooze and activate or deactivate the alarm.

I first wrote the code with debouncing for the buttons, but later when I tested my buttons I noticed that I didn't seem to need it, so I removed the debouncing to get less and easier to read code, however I included the function with debouncing in the tab f_comments_etc in the sketch.


Check for button presses:
The code that checks if the buttons are pressed are really simple. It just reads the state of the buttons pins. The arduinos internal pullup resistors are used so the buttons states are HIGH when they are not pressed and LOW when they are pressed.

The touch sensor is read with help of the CapSense library: touch_sensor.capSense(10) this will measure the capacitance 10 times and return an average. Depending on the value returned the snooze_button_state variable will be set to either HIGH or LOW. I have found that when I rest my hand on the lid of the clock i will get a value around 150 and with no hand about 30 ( if I recall correctly). so I used 100 as the limit to change the state of the snooze-"button". Change the value as needed.
______________________________________________________________________

The function that checks for button presses:

void update_buttons_state()
{
  hour_button_state    = digitalRead(hour_button_pin);
  minute_button_state  = digitalRead(minute_button_pin);
  setting_switch_state = digitalRead(setting_switch_pin);
 
  /* Read the snooze touch sensor: */
  if(touch_sensor.capSense(10) > 100) // adjust this value if needed
    snooze_button_state = LOW;
  else
    snooze_button_state = HIGH;
  // the if-else above I think could be written shorter as:
  // snooze_button_state = (touch_sensor.capSense(10) > 100) ? LOW : HIGH;
}
______________________________________________________________________


Do things if the buttons are pressed:
The settings switch will change the two pointers hours_p and minutes_p to point to either the variables hours and minutes, or alarm_hours and alarm_minutes. The code for the hour and minute buttons will use these pointers, so when the switch changes they will automatically set the right thing; alarm or time. The display function also uses the hours_p and minutes_p pointers so when the settings switch is on alarm, the alarm time is shown.

The hour and minute buttons increase the hours and minutes by one each time they are pressed.

The snooze button will turn off the alarm signal, and set a snooze off time (current time + 10 minutes) when the signal should start again. it also sets the variable snooze_on to true, this will cause the alarm function to start to check for when the snooze of time is.

If the snooze button is held down for 3 seconds it will toggle the alarm off or on. A high pitched tone is played when the alarm is turned on and a low pitched tone is played when the alarm is turned off.

______________________________________________________________________

The buttons function:

// "INTERNAL" VARIABLES FOR BUTTONS FUNCTION:
boolean first_time_hour = true;   // these are used to make sure that the hours
boolean first_time_minute = true; // and minutes only is increased once every keypress.
unsigned long snooze_button_timer; // used to keep track of how long the snooze button has
                                   // been held down. when the button has been held down
                                   // a certain amount of time, the alarm will be turned
                                   // of completely.
void buttons()
{
  // LOW == button pressed
  // HIGH == button released
  // (this is because pullup resistors is used)
 
  // Decide if we should set time or alarm:
  // (this also makes the display show the alarm time)
  if(setting_switch_state==LOW) // LOW = Set time
  {
    hours_p = &hours;
    minutes_p = &minutes;
  }
  else // HIGH = Set alarm
  {
    hours_p = &alarm_hours;
    minutes_p = &alarm_minutes;
  }

  // If hour button is pressed, increase hours:
  if(hour_button_state==LOW && first_time_hour) // only increase the hours once
  {                                             // every button press.
    if(*hours_p < 23)
      (*hours_p)++;
    else
      *hours_p = 0;
   
    first_time_hour = false;
   
    if(DEBUG)
    {
      Serial.println("hour increase");
      Serial.println(hour_button_state);
    }
  }
  else if(hour_button_state==HIGH)
  {
    first_time_hour = true; // reset when button is released,
  }                         // so that the next press will be registerd.
 
  // If minute button is pressed, increase minutes:
  if(minute_button_state==LOW && first_time_minute) // only increase the minutes
  {                                                 // once every button press.
    if(*minutes_p < 59)
      (*minutes_p)++;
    else
      *minutes_p = 0;
     
    first_time_minute = false;
  }
  else if(minute_button_state==HIGH)
  {
    first_time_minute = true; // reset when button is released,
  }                           // so that the next press will be registerd.

 
  if(snooze_button_state==LOW)
  {
    if(signal_on)
    {
      // set the time when the alarm signal will start again,
      // this will give 10 minutes snooze:
      if(minutes<50)
      {
        snooze_off_minutes = minutes+10;
        snooze_off_hours = hours;
      }
      else
      {
        snooze_off_minutes = minutes - 50;
        snooze_off_hours = hours + 1;
      }
      snooze_on = true;
      signal_on = false;
    }
    // if the snooze button has been held down for more than 3 seconds turn off/on the alarm
    if((millis() - snooze_button_timer) > 3000)
    {
      if(alarm_on) // if on, turn off
      {
        signal_on = false;
        alarm_on = false;
        // play tone so the user know the alarm turned off:
        tone_maker.play(NOTE_A3, 100);
      }
      else if(alarm_on==false) // if off, turn on
      {
        alarm_on = true;
        // play tone so the user know the alarm turned off:
        tone_maker.play(NOTE_A7, 100);
      }
      //reset the snooze button timer
      snooze_button_timer=millis();
    }
   
  }
  else
  {
    //reset the snooze button timer
    snooze_button_timer=millis();
  }
}
___________________________________________________________________

Step 11: Alarm and Snooze Code

If the alarm is active (alarm_on variable is set to true), the alarm() function will check if the current time is the same as the set alarm time. If it is, the signal_on variable will be set to true. If the signal_on variable is true, the function will call the play_melody() function.
 
If  snooze is active, the alarm function will also check if the current time is the same as the snooze off time, and if so, restart the alarm signal.
____________________________________________________________________

The alarm() function:

// "INTERNAL" VARIABLES FOR ALARM FUNCTION:
boolean first_time_signal_on = true; // used to make shure the signal is
                                    // only started once, so that you can
                                   // snooze without the alarm starting again
                                  // imidiately.

void alarm()
{
  if(alarm_on)
  {
    // Check if the time is same as alarm time:
    if(hours==alarm_hours && minutes==alarm_minutes && first_time_signal_on)
    {
      // if so, turn on the alarm signal:
      signal_on = true;
      first_time_signal_on = false;
    }
   
    if(signal_on)
    {
      play_melody();
    }
   
    // look in buttons() for snooze button and alarm off button
   
    if(snooze_on)
    {
      // Check if the time is same as snooze off time:
      if(hours==snooze_off_hours && minutes==snooze_off_minutes)
      {
        // if so, turn off snooze and restart alarm signal:
        snooze_on = false;
        signal_on = true;
      }
    } 
  }
  else
  {
    // reset so that the alarm will work next time:
    first_time_signal_on = true;
  }
}
_____________________________________________________________________

Step 12: Alarm Signal

It's quite easy to generate sound on the arduino by just using digitalWrite() and delay()  to toggle the state of the speaker pin in the right frequency. But for this project I need to constantly check the buttons, update the clock and update the display, even when the alarm signal is playing. Therefore the sound generation has to be non-blocking, which means you don't have to wait for the tones to end before you can do anything else.

Therefore I used the Tone library written by Brett Hagman to generate sound. It's a really nice library which makes it easy to play different tones, and best of all, it's non-blocking.

Because the the melody should be non-blocking I couldn't just use a for-loop to loop through the tones. Instead I used if-statements. everytime the melody function is called it checks if the last tone has stopped playing, if it has it will start the next one. The "melody" I've used is just C, D, E, F, G, A, B, C first played one after eachother, then every other, then every third, and so on.
_______________________________________________________________________

The play_melody() function:

// "INTERNAL" VARIABLES FOR PLAY_MELODY FUNCTION:
int melody[] = { NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4,
                 NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5 };
int melody_length = sizeof(melody) / 2; // Melody length, for looping.
// sizeof() returns the size of the array in bytes, and because
// an int is 2 bytes, sizeof will return 2*(number of array elements)

int i = 0;        //loop variable
boolean reset_loop = true;
int jump = 1;     // how many notes to jump in the melody array
int position = 0; // position in melody array

void play_melody()
{
  if(!(tone_maker.isPlaying())) // if the last tone has stopped
  {
    if(i    {
      //tone_maker.stop();
      tone_maker.play(melody[position], 300);
      // A pause between notes...
      //delay(300); // replace with nonblocking.
     
      if (DEBUG)
      { // If debugging, report loop, tone, beat, and duration
        Serial.print(position);
        Serial.print(":");
        Serial.print(melody[position]);
        Serial.print("\n");
      }
     
      position += jump;
      //if position is bigger than the array, start from beginning of array:
      position = position%melody_length;
      i++;
     }
     else
     {
       jump++;
       i = 0;
     }
  }
}
_______________________________________________________________________

Step 13: Upload the Arduino Sketch.


Make shure you have the CapSense Library and the Tone Library, they can be downloaded here, and here.
Unzip and place the folders in the folder libraries in your sketchbook folder.

Download the binary clock source code attached to this step, unzip it, and place the folder in your sketchbook folder too. Plug in your arduino, open the binary_clock_v1 sketch and press the upload button.

If you've done everything right you should now have a working binary alarm clock! If something seems wrong, double check all conections. Is everything connected? Is everything connected to the right pin?

Step 14: Put Everything in the Box

When you've made shure everything works as it should, you are ready to put everything into your box.

The box I used already had a window in it so I didn't have to make one. If your box don't have a window, drill four holes where you want the corners of your windows and the use a small saw, and saw between the holes. Then sand the edges.

Drill a hole in the backside of the box for the power cord. To be able to make the hole small, cut off the cord near the wallwart, where it won't be noticed, put it through the hole and then tape it togheter again with electrical tape.

If you like me didn't use header pins to connect all your wires I highly recommend you to secure all wires to the arduino with tape before you try to put the arduino into the box.

If you have an diecemilla or older arduino, remeber to change the power jumper to external power.

Step 15: Ideas for Improvement

Since I would want to use my arduino for other projects later and since tape isn't the ultimate way to attach wires, maybe I will do a separate circuitboard with an atmega with the arduino bootloader. The clock works good as it is however so we'll see when I find the time to do that. Another improvement would be to make the usb port easier to reach for when you want to update the code.

Step 16: Final Words

Thanks for reading! This has been a really fun project to make and I've learned a lot. I hope you enjoyed reading the instructable and that the instructions where clear.

If you have any questions just ask.


<p>Can i change the tone? </p>
if i want to add mp3 tones, can I do it ?!
<p>The code is not compiling. I've put both files in the library folder like you said. But I'm getting these errors...</p><p>binary_clock_v1:24: error: 'CapSense' does not name a type</p><p>binary_clock_v1.pde: In function 'void loop():</p><p>binary_clock_v1:123: error: 'touch_sensor' was not declared in this scope</p><p>d_button_code.pde: In function 'void update_buttons_state()':</p><p>d_button_code:8: error:'touch_sensor' was not declared in this scope</p><p>I would appreciate any help that can be given. I've been working on this all day. Thanks.</p>
<p>Hi, I'm thinking about making this project but I don't quite understand the touch sensor. Do I have to buy the pins? or is it only made of the auliminium foil, etc? How can I look for those pins in amazon, because when I look for touch sensor other stuff appear... Thanks btw</p>
<p>this is a great instructable! Very well documented, with exception that a schematic is missing, which makes it hard to understand how you hooked up the buttons. I was wondering, how would you modify the code for a momentary switch for the snooze. I'm building this in an old alarm clock housing that has the snooze switch built into the feet of the clock. A reply back would be greatly appreciated. </p>
This could be useful to detect individual differences from crystal to crystal, however, a crystal oscillator is affected by environmental factors as well. Mainly temperature, power supply ripples, even age of the crystal :( <br>I found this informative article http://kunz-pc.sce.carleton.ca/thesis/CrystalOscillators.pdf if you want super details. My latest arduino clock uses the DS3231SN chip (ChronoDot RTC product) which (in reasonable temperatures) is accurate to better than one minute per year drift. And the battery backup means you don't have to set the clock every time you loose power.
Really great project! Thanks a lot, this one inspired me to do my <a href="https://www.instructables.com/id/Arduino-Binary-Alarm-Clock-pocket-sized/ ">pocket binary alarm clock</a> !
Cool!
hi, <br>when i go to upload to my arduino and it verifys it first it comes up with an error saying 'CapSense' does not name a type. i am only trying to upload the binary_clock_v1 file am i doing something wrong or missing something?
Do you have the CapSense library?<br><br>&quot;Step 13: Upload the arduino sketch.<br><br>Make shure you have the CapSense Library and the Tone Library, they can be downloaded here, and here.<br>Unzip and place the folders in the folder libraries in your sketchbook folder. &quot;
Works like a charm.
Where are the wires from the buttons going? Great project!
To the arduino, look at the 5th picture in step 14. <br>From step 3:<br>&quot;Here are the pins I used for the different parts:<br><br>- 2 and 4: Touchsensor (4 is the send pin, 2 is recieve)<br>- 6 Hour button<br>- 5 Minute button<br>- 7 Switch<br>- 14-18 Display hour pins<br>- 8-13 Display minute pins&quot;
how can I not use the touch sensitive on/off/snooze feature? I am pretty new to electronics, so any help would be great.<br><br>Thank!, and great instructable
Where did you get that box from?
I got it when I bought a tie + napkin + cufflink kit. The little window was so you could see the color of the tie.
When ever you do find out please post it so it would be possible to&nbsp; compensate for it every 6 or so months.&nbsp; =-)
&nbsp;I'm not shure what you mean, but if you mean the clock error, then I have as you can read already compensated for it in the code, the discussion below is just about other possible ways to do it. I have however not tested a very long run of the clock (several weeks) without resetting yet because I have had some problems with the touchsensor being oversensitive and after a couple of days trigger alarm on/off constantly. I think I may have to ground the arduino better, the <a href="http://www.arduino.cc/playground/Main/CapSense" rel="nofollow">capsense page</a> say that it's important.
I&nbsp;just want to say how lovely this is, both the clock (which is aesthetically pleasing and clever), and the instructable. I'm a writer for my day job and I do textile crafting for my hobbies (sewing, knitting, spinning, etc.) but I actually understood what you were doing here, which means you did a great job.&nbsp; I used to know a little C++ and this and that, when I was way, way younger, and I followed along the code bits you show surprisingly well, too, because you were so clear what it was all about.<br /> <br /> I've always wanted to learn this kind of thing but don't know a single soul who knows much beyond not using the wrong adaptor for the printer (and some don't know that much!).&nbsp; The more instructables I read, though, the more convinced I am that I'll have to make one, some day.&nbsp; It's getting harder to resist.&nbsp; :)&nbsp; <br /> <br />
Thank you for the kind comment, I'm glad you liked it!<br /> <br /> I didn't know anyone that could help me much when I started learning about electronics etc. either, but the internet is full of information and you can ask at forums if you get stuck.<br />
Have you thought about using ternary operators?&nbsp; They're basically if() statements, but use a slightly lower-level structure.&nbsp; I'm not sure if they run faster under the Arduino, they may actually end up compiled the same since it's an embedded environment, but basically, it goes like this:<br /> <br /> condition ? run if true : otherwise run this;<br /> <br /> So you could do that first if() statement like this:<br /> <br /> current_millis_value &lt; previous_millis_value ? m += MAX_MILLIS_VALUE - previous_millis_value + current_millis_value : m += current_millis_value - previous_millis_value;<br /> <br /> It's not as pretty, but as always, C ignores whitespace, so you can write it like this if you want to organize it a little:<br /> <br /> current_millis_value &lt; previous_millis_value ?<br /> m += MAX_MILLIS_VALUE - previous_millis_value + current_millis_value :<br /> m += current_millis_value - previous_millis_value;<br /> <br /> It might run faster and eliminate some of the timing error.<br /> <br /> Also, you might be able to spread out the time correction a little more evenly than 2 seconds every 5 hours.&nbsp; Since it's .4 seconds, that's 400 milliseconds every 60 minutes.&nbsp; That goes down to 20 milliseconds every 3 minutes.&nbsp; Since you're counting milliseconds directly, and the overall count of seconds is a multiple of 3, it might be overall a little more accurate to the user to do the correction more often.<br /> <br /> Great tutorial though, I might have to try this!<br />
No I haven't thought about using ternary operators there. However I think if-statemets may be a bit easier to read. Maybe one should do a test of ifs vs. ternary, but I think they are equally fast.<br /> <br /> About the time compensation, yes I have thought about that and maybe I will add it later. Since the clock only shows minutes I don't think it matter that much. The advantage with that method is that it's easier to compensate for cases when you have for example 0.43 instead. <br /> <br /> Hmm, I somehow thought It would be more complicated to compensate the milliseconds, but now when I think about it, it should be as easy, one just have to make the millis variable signed, so the subtraction won't cause it to underflow. <br /> <br /> Thanks for the suggestions, I'm glad you like the instructable!<br />
Leave it unsigned.&nbsp; You could just as easily have it count up to 1001 instead of 999.&nbsp; This would save issues of the clock wondering what time it really is.<br /> <br /> Yeah, I'll have to see how ternary operators and if() statements compare when I finally get an Arduino (Christmas is coming, as my plan currently stands).&nbsp; For a lot of embedded environments, all those conditional structures get compiled down the same way anyway.&nbsp; I think&nbsp;I recall that the C18 compiler (for PIC microcontrollers, like the one in my VEX robot) compiles if() and switch() statements to the same thing.&nbsp; I wouldn't be surprised if it takes while() loops down to if()-goto structures.&nbsp; Or I guess I could just look at the avr-gcc manual, but that would be too easy :D<br /> <br /> I think I might eventually try this project, I've wanted a binary clock for a while, and I love the AVR line.&nbsp; One thing that I found last night is that the Arduino bootloader still allows you to use the lower-level avr-gcc commands.&nbsp; It turns out that digitalWrite() takes about 10 times longer to run than accessing the PORT register directly, because with each call of digitalWrite(), it turns off all of the PWM&nbsp;timers (and in the comments in the code, the guy is asking why that couldn't be moved up to pinMode(), which is interesting).&nbsp; Basically, digitalWrite() is just some safety mechanisms and a parser for the PORT register.&nbsp; It sets the PORT of your choice (lets say pin 13, which is under PORT B, pin 5) to an entire byte all at once (you can toggle 8 pins just about simultaneously).&nbsp; This would work like this, IIRC:<br /> <br /> PORT_B = 0b00010000;<br /> <br /> Or, to only affect that pin, you can use the | operator:<br /> <br /> PORT_B |= 0b00010000;<br /> <br /> You don't have to make these modifications, I realize it would take a long time to recalibrate, just thought you might be interested.&nbsp; I still love the tutorial.&nbsp; I think it might also be interesting to make a multiplexed or charlieplexed version, just for funsies.<br />
<em>&quot;Leave it unsigned.&nbsp; You could just as easily have it count up to 1001 instead of 999.&nbsp; This would save issues of the clock wondering what time it really is.&quot;</em><br /> <br /> Wouldn't that just work if you want to correct at least 1 millisecond every second (60ms per minute) wich is more than I want to?<br /> <em><br /> &quot;[...]<br /> It turns out that digitalWrite() takes about 10 times longer to run than accessing the PORT register directly, because with each call of digitalWrite(), it turns off all of the PWM&nbsp;timers (and in the comments in the code, the guy is asking why that couldn't be moved up to pinMode(), which is interesting).&nbsp; <br /> PORT_B = 0b00010000;<br /> [...]&quot;</em><br /> <br /> Actually there have been much discussion about how to make digitalWrite faster on the arduino developers mailinglist lately (<a href="http://arduino.cc/pipermail/developers_arduino.cc/2009-November/001764.html" rel="nofollow">link</a>), maybe digitalWrite compiled to one instruction will come in the next version of the arduino ide.<br /> I think I'll just wait for that since using digitalWrite makes the code cleaner and easier to understand*, and It works&nbsp; good as it is. I don't have much time now anyway to tinker with the clock, because I have calculus exam soon :S.<br /> <br /> * = for me at least, I'm not used to the PORT stuff since I have mostly used the arduino. I would like to learn more how microcontrollers really work sometime though. The arduino hides all complexity, which is really nice, and makes it easy to make stuff with it,&nbsp; but it would be intresting to learn how it works low-level.<br /> <br /> <em>&quot;You don't have to make these modifications, I realize it would take a long time to recalibrate&quot;</em><br /> <br /> I don't think I would have to recallibrate, the time error should come from the crystal oscillator frequency and not from how long it takes to execute the loop. <br /> <em><br /> &quot;I think it might also be interesting to make a multiplexed or charlieplexed version, just for funsies.&quot;</em><br /> <br /> Yes, I would like to experiment with charlieplexing too sometime. <br />
Oh, yeah, with the &quot;1001 instead of 999&quot; thing, I was thinking 2 milliseconds instead of 20.&nbsp; And actually, you could tack on 7 milliseconds every minute, and then 6 every 3 minutes, like so:<br /> <br /> if(seconds==59 &amp;&amp; m &gt; (!minutes%3 ? 999+6 : 999+7))&nbsp;{&nbsp; //If divisible by 3, add <br /> &nbsp;&nbsp;&nbsp; seconds++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; //18 ms, otherwise 19<br /> &nbsp;&nbsp;&nbsp; m = 0;<br /> }<br /> else if(m&gt;999) {&nbsp; //Normally, a second is just 1000ms<br /> &nbsp;&nbsp;&nbsp; seconds++;<br /> &nbsp;&nbsp;&nbsp; m = 0;<br /> }<br /> <br /> I&nbsp;think how you do it with the 2 seconds every 5 hours is fine by the way, this is more just a point of discussion.
Just wondering, why didn't you use a RTC for timekeeping? Nice guide btw.<br /> <br /> -Simon<br />
I didn't use one because I didn't have one, and it's cheaper to use just code :) but maybe I will add it in a later version if I can't get the clock to be as exact as I want, but It seems to work OK without for now.<br />
Yeah, it'll start drifting by a lot after a while. You should use <a href="http://macetech.com/store/index.php?main_page=product_info&amp;cPath=5&amp;products_id=8" rel="nofollow">this</a>. I read that it is very good. You can even get one that is the electrical equivalent, but the headers are soldered on the wrong way, for half of the price.<br />
It will drift a bit, but as you can see in the instructable I have compansated for the drift I could measure in the code so I don't think it will be more than a couple of minutes per year. I'll have to wait and see I guess. <br />
&nbsp;This is so cool! Thanks for posting this, this is amazing. I definitely like this binary clock system rather than Binary Coded Decimals.
Thank you! I'm glad that you liked it.<br />

About This Instructable

37,685views

96favorites

License:

More by njakol:Arduino Binary Alarm Clock 
Add instructable to: