At the tone, the time will be...

The 60 hertz AC signal (50 Hz for those of you in Yurp) is, in most cases, the most accurate timekeeping signal an electronic appliance will have available -- more so than any crystal. Because of this, appliances will often base their clocks (as in chronometers, not the processor's system clock) off of a zero cross detector.

As one might imagine, a zero cross detector detects each time the incoming AC signal crosses ground (zero volts). The power signal coming into the appliance is a sine wave that looks more or less like this:

+120v |   ...                 ...
      | ..   ..             ..   ..
      |.       .           .       .
 GND  |---------.---------.---------.---------   et cetera.
      |          .       .           .       .
      |           ..   ..             ..   ..
-120v |             ...                 ...

Now, if we feed this signal into an op amp with no feedback loop, the op amp acts as a comparator, returning Vcc when the signal is positive and Vee when the signal is negative. For example, if the Vcc and Vee powering the amplifier are +15 volts and -15 volts respectively, the op amp will return this:

+15v  |..........         ...........
      |                            
      |                             
 GND  |---------.---------.---------.---------   et cetera.
      |                                       
      |                                      
-15v  |         ...........         ..........

Now we have a square wave, but the voltage levels aren't right for your typical logic circuit, which will typically be using ground to represent a logic zero and +5 or +3.3 volts for a logic one. Running the signal through an optoisolator can scale the signal and shift the DC offset to give us the values we need:

+5v   |..........         ...........
      |                            
      |                             
      |         .         .         .            et cetera.
      |                                       
      |                                      
 GND  |_________..........._________..........

That signal is fed into an external interrupt pin on the microcontroller. The micro is configured to fire an interrupt every time the signal on the pin changes from a 0 to a 1 or vice versa -- this is called edge triggering. The interrupt handler in the program can then do things like update a counter variable; every time this counter hits 60 (50 across the pond) a second has elapsed.

Alert! Alert! Condition Red! MoveMoveMOVE!

Another use for zero-cross detection is determining if a power loss has occurred. A relatively large capacitor is placed across the microcontroller's power supply in order to retain power for a few dozen milliseconds if AC power is lost. Then the programmer sets up a different interrupt to fire based on an internal timer in the microcontroller; this timer is based on the micro's own clock crystal, and is set up to fire at a rate slower than the power frequency.

Each time the timer interrupt fires, it checks to see if at least one zero cross interrupt has fired since the last time it checked. Since the timer interrupt frequency is slower than the power frequency, this should always be the case as long as power is being supplied. If it hasn't, the microcontroller knows a power loss has occurred, and it had better do whatever housekeeping and shutdown tasks it can as fast as possible, before that capacitor is discharged! Often this means saving important information to an EEPROM, or deactivating relays or other mechanical devices.