APPENDIX A – BLOCK DIAGRAM - DOC - DOC by cuiliqing

VIEWS: 82 PAGES: 37

									                            APPENDIX A – BLOCK DIAGRAMS

                                                                Alarm Clock
                                                                  Module

                                                                     User
                                                                   Interface
                                   Signal
       EEG Module                Processing
                                   Module

                                                                    Alarm
         EEG                        Signal                          Clock
        Circuit                   Processing                        Circuit
                                    Circuit




                                                         Display               Relay
                                                         Circuit               Circuit




Figure A.1: Block Diagram of Project - block diagram demonstrating the modularity of our project.




                                               16
                                                      APPENDIX B – SCHEMATICS
                                       C                   R2
Left Electrode
                                       .1u                33k
                                                      R1          C
                                                      3.3mega                            U17
                                                                  .1u                    +                            U18
                                                                        0                      OUT                    +
                                                  0
                                                                                         -                                   OUT                Output
                                       C                   R2                                  AD622
Right Electrode                                                                                                       -         OPAMP
                                       .1u                33k           C
                                                      R1
                                                      3.3mega
                                                                            .1u
                                                                                                                0
Neck Electrode
                                                                        0
                                                  0

                  Figure B.1: Original Schematic - Schematic of original design for EEG Circuit


                                             C                        R2

                                             .1u                R1 33k                         C
                                                                3.3mega
                                                                                               .1u

                                                                                               0
                                                            0

                        Figure B.2: Old Filters - Original bandpass filter used in EEG Circuit

                                                 C

                                                 0.1u                                                                       R2
R1                R1                                  U7                                                                    3.3mega
                                                      +                           C                  C
 33k              33k                                                                                                       U6
                                                            OUT
                                C                                                                                           +
                                                                                  0.1u               0.1u    R2
                                0.1u                  -                                                                            OUT
                                                                OPAMP
                                                                                                            3.3mega
                                                                                                                            -           OPAMP


                            0

                                                                                                            0

                  Figure B.3: New Filters - Final design for bandpass filter used in EEG Circuit




                                                                             17
           +5 V



          4            3                         47 Kohm
                                     +5 V                              PIC16F877A
              F1100E
                                                                  1
                  2                  V(t)                         2




+5 V                       1N5822
          1 amp fuse                                                       9
                                                                          10
                                                                  11
                                                                  12
                                1N4734                            13
                                                                  14
                                                                  15




                                                  sigA     sigB

       Figure B.4: PIC Schematic - Schematic of final signal processing module




                                            18
19
     Figure B.5: Alarm Clock Schematic – Schematic of the Alarm clock module
                                   APPENDIX C – FLOW CHARTS

                                                      Start




                                                    Initialize
                                                    Average




            Update Average                     Get A/D Samples




                                                   Determine
                                               frequency and set
                                                   old_State =
                                                  current_State




                                                  Is frequency
                              No                   between 9
                                                   and 13 Hz?            Yes




                      Is frequency                                 Set current_State
                      between 13                                     = Alpha and
       No                                   Yes
                       and 50 Hz?                                    output A = 1




Set current_State                     Set current_State
                                                                         Yes
    = Default                              = Beta




                                                                     Is old_State
                         No
                                                                       = Beta?             Yes




                                                                                       Output B = 1




              Figure C.1: Flow Chart1 - Flow chart of signal processing pic.




                                                          20
                                                Clock and Alarm Time Flowchart


                                                                Start




                                                         Initialize interrupt
                                                            vectors and
                                                               I/O ports




                                                             Enable all
                                                             interrupts




No                                                         Display Time




                                                         Start Alarm_Signal
                                                          and Start Relay
                                                             sub-charts




                                                            Is Set_Time
                                                                                               Yes
                                                                = 1?

                                                                                                                          Yes



     Is Set_Alarm
                                Yes
         = 1?
                                                                                              Disable all
                                                                                              interrupts




                             Disable all
                             interrupts
                                                                                              Is Increment
                                                                                                   = 1?
                                                                   No
                                                                                                                Yes


                             Is Increment
                                  = 1?                                              No
     No
                                               Yes                                                            Increment
                                                                                                             Clock_Time


                    No
                                             Increment
                                            Alarm_Time

                                                                                Is Set_Time
                                                                                    = 0?




              Is Set_Alarm
                                                                                     Yes
                  = 0?


                              Figure C.2: Flow Chart2 - Flow chart for Alarm Clock pic.




                                                                            21
                                       Check ClockTime
Start Alarm_Signal
                                        and AlarmTime




                                    (AlarmTime - 90 minutes)
                                         < ClockTime <
                                          AlarmTime?                Yes




                                                                Is AlarmClock
                                        No
                         No                                        Enabled?
                                                                                   Yes



                                                                                Is signalA
                                               No
                                                                                   high?
                                                                                                 Yes




                     Don’t Sound
                                                                                             Sound Alarm
                       Alarm


                                                                                                             Yes



                                                                                             Is AlarmClock
                                                 No
                                                                                                Enabled?




                               Figure C.3: Flow Chart3 - Flow chart for buzzer.




                                                           22
                                   Relay conditions for turning on and off


                                                        Start Relay




                                                        Is Awake
                   No                                                            Yes
                                                           = 1?



                                                                            Is Alarm_EN
                        No                                                                     Yes
                                                                                = 1?




          Is Sleeping                                                                      Is Sleeping
                                                                           No
              = 1?                                                                             = 1?             Yes
                                  Yes




                               Is signal B                         Is signal A                            Is signal A
         No                                                                                  No
                                   = 1?                                = 1?                                   = 1?
                                                                                                                           Yes


                                                  Yes

                                                                                          Is signal B                   Is signal B
                                             No
                                                                                              = 1?                          = 1?



                                                                      No

                                                         No
No




                                                                                                          Yes



                                                                                                                                      Yes




              Turn off relay                                                              Turn on relay




The flowchart implements the following pseudocode conditions:

if (Awake = 0 and Sleeping = 0) turn off relay;
if (Awake = 0 and Sleeping = 1 and signal B = 0) turn off relay;
if (Awake = 0 and Sleeping = 1 and signal B = 1) turn on relay;
if (Awake = 1 and Sleeping = 0 and signal A = 0 and Alarm_EN = 1) turn on relay;
if (Awake = 1 and Sleeping = 0 and signal A = 1 and Alarm_EN = 1) turn off relay;
if (Awake = 1 and Sleeping = 1 and signal A = 0 and signal B = 0 and Alarm_EN = 1) turn off relay;
if (Awake = 1 and Sleeping = 1 and signal A = 0 and signal B = 1 and Alarm_EN = 1) turn on relay;
if (Awake = 1 and Sleeping = 1 and signal A = 1 and signal B = 0 and Alarm_EN = 1) turn off relay;
if (Awake = 1 and Sleeping = 1 and signal A = 1 and signal B = 1 and Alarm_EN = 1) turn on relay;

                               Figure C.4: Flow Chart4 - Flow chart for relays.




                                                                           23
          Interrupt Handler Flowchart




           From
          main to            Start Interrupt
         interrupt              Handler
          handler




                               Disable all
                               interrupts




                                Increment
                              timer1Count
                            and set Timer1 to
                                   3036




                             Is timer1Count
                                                    Yes
                                  = 120?




                                                Increment timeMin
                                                     and set
                       No                        timer1Count = 0




            Return
             from              Enable all
           interrupt           interrupts
            handler




Figure C.5: Flow Chart5 - Flow chart for interrupt handler.




                                24
                        APPENDIX D – SIMULATIONS & TEST DATA




Figure D.1: Frequency response - The red line is the frequency response for the passive filter design.
                The green line is the frequency response of the active filter design.




                                                 25
Figure D.2: Gain Verification I - The bottom signal represents the input signal of 1mVpp. The top signal
                           represents the output of approximately 3.31Vpp.




Figure D.3: LPF Verification I – The bottom signal represents the input signal of 1mVpp at 75 Hz. The
 top signal shows the effects of the low pass filter at 75 Hz with an output of only 2.56Vpp, rather than
                                                 3.31Vpp.




                                                   26
Figure D.4: HPF Verification I – The bottom signal represents the input signal of 1mVpp at 0.1 Hz. The
 top signal shows the effects of the high pass filter at 0.1 Hz with an output of only 1.76Vpp, rather than
                                                  3.31Vpp.




Figure D.5: EEG Comparison – The left plot is a recording of the EEG output from the final circuit on
  the PCB. The right plot is a recording of the EEG output from the demo circuit on the breadboard.




                                                    27
   Figure D.6: Gain Verification II – This signal represents the output of approximately 1.2Vpp.




Figure D.7: LPF Verification I – This signal shows the effects of the low pass filter at 75 Hz with an
                      output of only .47Vpp, rather than the expected 1.2Vpp.




                                                 28
Figure D.8: HPF Verification II - This signal shows the effects of the high pass filter at 0.1 Hz with an
                     output of only .231Vpp, rather than the expected 1.2 Vpp.



                                        Frequency Response

               1.4

               1.2

                1
 Voltage (V)




               0.8

               0.6

               0.4

               0.2

                0
                     0   10   20   30     40         50         60   70   80   90     100
                                               Frequency (Hz)



Figure D.9: Actual Frequency Response – Plot of data recorded from EEG circuit showing the actual
                              frequency response from 0.1-100 Hz.


                                                          29
Figure D.10: Signal Processing PIC Design - Desired response of sigA




Figure D.11: Signal Processing PIC results - Actual response of sigA




                                30
      PIC time       www.time.gov      PIC interval    www.time.gov      Difference
                                                         interval
        10:10           1:18:00           N/A              N/A              N/A
        10:20           1:28:00          10 min           10 min              0
        10:30           1:38:00          20 min           20 min              0
        10:40           1:48:00          30 min           30 min              0
        10:50           1:58:00          40 min           40 min              0
        11:00           2:08:00          50 min           50 min              0
        11:10           2:18:00            1h               1h                0
        02:36          17:43:48        16 h, 26 min   16 h, 25 m, 48s       +12 s
        10:10           1:17:44           24 h         23 h, 49m, 44s      + 16 s


Table D.1: Alarm Clock PIC Analysis - Comparison of PIC time with www.time.gov time, showing
                              how accurate our alarm clock is.




                                            31
                                      APPENDIX E – PICTURES




Figure E.1: Electrode Placement – This picture shows the placement of the electrodes on the user. Two
electrodes are place on the right and left side of the forehead, and a third electrode is placed on the neck
                                         which serves as a ground.

                                                                              HR & MIN Increment
                                                   4-position switch
                                                                              Push Buttons


                                                                                               Relay
                                                                                               Circuit



 Banana Jack
 Inputs from
 Electrodes
                                                                                              Appliance
                                                                                              Control
                                                                                              Switches


 Plexiglass
 Cover                                                 Display Circuit
                       EEG Circuit                     (Signal Processing Circuit and Alarm
                                                       Clock Circuit below)


    Figure E.2: Alarm Clock Box – This picture shows the front view of the alarm clock box and the
                           placement of most of the associated hardware.
                                                    32
Figure E.3: Bad PCBs - This figure shows the Display PCB. An area of the PCB has been enlarged in
                   order to show where the copper contacts were peeling off.




                                               33
                                  APPENDIX F – PARTS AND COST

Please note that Tables F.1-F.4 are tables listing all the parts and costs associated with the different
modules of the project. Each table includes a part #, description, quantity, price, and total price.

                 Part #                       Description        Qty.           Price        Total
                  N/A              Unomedical Ag/AgCl Electrodes  3             $0.19        $0.57
                  N/A                            PCB              1              3.29         3.29
               AD622AN                Instrumentation Amplifier   2             $5.15       $10.30
                MC3403                      Quad-Op Amp           1             $0.33        $0.33
                                         Miscellaneous Parts      1              5.00         5.00
                    *                       33 kΩ Resistor        4                -            -
                    *                      3.3 MΩ Resistor        4                -            -
                    *                        12 Ω Resistor        1                -            -
                    *                        39 Ω Resistor        1                -            -
                    *                       30 kΩ Resistor        1                -            -
                    *                      0.1 µF Capacitor       4                -            -
                    *                3 Conductor Shielded Cable   2                -            -
                    *                       Alligator clips       3                -            -
                    *                     Banana Jack Plugs       4                -            -
                                                                                         --------------
                                                TOTAL                                       $19.16
* Covered in Miscellaneous Costs

                            Table F.1: EEG - Parts and Cost for EEG Module


                 Part #                     Description                 Qty.    Price       Total
              PIC16F877A                 PIC Microcontroller             1      $4.76       $4.76
              FOX F1100E               4 MHz Crystal Oscillator          1      $1.58       $1.58
                1N5822                     Schottky Diode                1      $0.32       $0.32
                1N4734                      Zener Diode                  1      $0.11       $0.11
                  N/A                           PCB                      1      $3.29       $3.29
                  N/A                    Miscellaneous Parts             1
                   *                       47kΩ Resistor                 1
                   *                         1-amp Fuse                  1
                                                                                         --------------
                                                TOTAL                                       $10.06
* Covered in Miscellaneous Costs

          Table F.2: Signal Processing Module - Parts and Cost for Signal Processing Module




                                                     34
               Part #                       Description             Qty.   Price      Total
           PIC16F877A                   PIC Microcontroller          1     $4.76      $4.76
           FOX F1100E                4 MHz Crystal Oscillator**      1       -           -
                N/A                       47kΩ Resistor**            1       -           -
                N/A                        1-amp Fuse**              1       -           -
             1N58222                     Schottky Diode**            1       -           -
              1N4734                       Zener Diode**             1       -           -
        LSD3211-11 (MAN74)            7 Segment HEX Display          4     $1.62      $6.48
            CD4511BE                BCD-to-7 Segment Converter       4     $0.63      $2.52
           T77S1D10-05                          Relay                2     $2.11      $4.22
            74AC11000                    4 NAND Gate IC              1     $1.30      $1.30
            MCP320B2                        Piezo-Buzzer             1     $2.70     $2.70
                N/A                     Miscellaneous Parts                 $10        $10
                 *                         2-State Switch             4                ~*
                 *                          Push Button               2                ~*
                 *                       4 Position Switch            1                ~*
                 *                       900 nF Capacitor             9                ~*
                 *                         10 kΩ Resistor             9                ~*
                 *                         220 Ω Resistor            40                ~*
                 *                        15 pF Capacitor             2                ~*
                N/A                             PCB                   2    $3.29      $6.58
                                                                                   ------------
                                              TOTAL                                 $38.56
* Covered in Miscellaneous Costs
** Parts shared with Signal Processing Module

              Table F.3: Alarm Clock Module - Parts and Cost for Alarm Clock Module


                Part #                      Description             Qty.   Price      Total
                 N/A                      Aluminum Box               1     $6.99      $6.99
                 N/A                      Plexiglass cover           1     $3.99      $3.99
                 N/A                    Banana Jack Sockets          8     $1.20      $9.60
                 N/A                        Wall Outlet              1     $2.99      $2.99
                                                                                   ------------
                                              TOTAL                                     $23.57

                         Table F.4: Miscellaneous - Miscellaneous Parts and Cost




                                                   35
                            APPENDIX G – MISCELLANEOUS


                 Frequency (Hz)        Brain Wave        Sleep Stage
                     0.5 – 3              Delta          Deep Sleep
                      4–7                 Theta         Drowsy Sleep
                     8 – 13              Alpha           Light Sleep
                      14 +                Beta          Awake, REM

Table G.1: Brain Waves - shows the frequency ranges associated with each stage of sleep.




       Pin#   Label   I/O         Description         To/From          Part
         2     A0      I     Analog Signal from EEG
         4    Vref-                   GND
         5    Vref+                    Vdd
         6     E0     O          A (Light sleep)                Alarm Clock PIC
         7     E1     O          B (Fall Asleep)                Alarm Clock PIC

 Table G.2: Signal Processing I/O – mapping of I/O ports for the signal processing PIC




                                            36
Pin#   Label   I/O   Description                   To/From   Part               Label
  2    A0      I     A
  3    A1      I     B
  4    A2      I     ALARM_OFF                               four pos. switch
  5    A3            ALARM_ON                                four pos. switch
  6    A4      I     SET_TIME                                four pos. switch
  7    A5      I     SET_ALARM                               four pos. switch
 33    B0      O     MIN – ones digit                        7-Seg Decoder 1    A
 34    B1      O     MIN – ones digit                        7-Seg Decoder 1    B
 35    B2      O     MIN – ones digit                        7-Seg Decoder 1    C
 36    B3      O     MIN – ones digit                        7-Seg Decoder 1    D
 37    B4      O     MIN – tens digit                        7-Seg Decoder 2    A
 38    B5      O     MIN – tens digit                        7-Seg Decoder 2    B
 39    B6      O     MIN – tens digit                        7-Seg Decoder 2    C
 40    B7      O     MIN – tens digit                        7-Seg Decoder 2    D
 15    C0      O     HR – ones digit                         7-Seg Decoder 3    A
 16    C1      O     HR – ones digit                         7-Seg Decoder 3    B
 17    C2      O     HR – ones digit                         7-Seg Decoder 3    C
 18    C3      O     HR – ones digit                         7-Seg Decoder 3    D
 23    C4      O     HR – tens digit                         7-Seg Decoder 4    A
 24    C5      O     HR – tens digit                         7-Seg Decoder 4    B
 25    C6      O     HR – tens digit                         7-Seg Decoder 4    C
 26    C7      O     HR – tens digit                         7-Seg Decoder 4    D
 19    D0      I     Appl. 1 - Turn off at night             switch
 20    D1      I     Appl. 1 - Turn on in morn.              switch
 21    D2      I     Appl. 2 - Turn off at night             switch
 22    D3      I     Appl. 2 - Turn on in morn.              switch
 27    D4      I     Change HR                               push button
 28    D5      I     Change MIN                              push button
 13    OSC1          crystal oscillator
 14    OSC2          crystal osc. (not used)
  8    E0      O     Appliance 1 Relay                       Relay 1
  9    E1      O     Appliance 2 Relay                       Relay 2
 10    E2      O     BUZZER                                  piezo buzzer

  Table G.3: Alarm Clock I/O – mapping of I/O ports for the Alarm clock PIC




                                            37
    BCD inputs                       segment outputs
                                                                       display
D    C     B     A      a     b      c      d     e      f      g

0    0     0     0      1     1      1      1     1      1      0


0    0     0     1      0     1      1      0     0      0      0


0    0     1     0      1     1      0      1     1      0      1


0    0     1     1      1     1      1      1     0      0      1


0    1     0     0      0     1      1      0     0      1      1


0    1     0     1      1     0      1      1     0      1      1


0    1     1     0      0     0      1      1     1      1      1


0    1     1     1      1     1      1      0     0      0      0


1    0     0     0      1     1      1      1     1      1      1


1    0     0     1      1     1      1      0     0      1      1


           Table G.4: Hex Displays - Decoding table for 7-segment HEX displays




                                           38
                      APPENDIX H – PIC MICROCONTROLLER CODE

//////////////////////////////////////////////////////////////////////
////                        ADSignalAnalysis.C                    ////
////                                                              ////
//// This program calculates the frequency of an analog signal    ////
//// using zero-crossing analysis of A/D samples.                 ////
//// This version uses 8 bit ADC.                                 ////
////                                                              ////
//// I/O:                                                         ////
//// A0                 input analog signal                       ////
//// C0                 output bit A                              ////
//// C1                 output bit B                              ////
////                                                              ////
////                                                              ////
//// Written February 2006                                        ////
//// by Jonathan Santos                                           ////
//// partners: Kevin Lee, Daniel Kim                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////

#include <16F877A.h>

#device *=16 ADC=10         // Use 16-bit pointers, use 10-bit ADC

#fuses   HS                 // You may or may not want some of these ....
#fuses   NOWDT
#fuses   NOPROTECT
#fuses   NOLVP
#fuses   NODEBUG
#fuses   NOPUT
#fuses   NOBROWNOUT

#use delay(clock=4000000)

// These require use of Set_Tris_x()
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
// End Preprocessor Directives

#include "Include\ADSignalAnalysis.h"

// function declarations
void initTimers(void);
void initADC(void);
int16 initRunningAvg(void);

#pragma zero_ram
void main( void)
{
      // declare variables
      int16 zero_crossings;
      int16 newADC, oldADC;
      int16 runningAVG;
      int16 frequency;
      int16 time_interval;
      int8 signalB;
      int8 currentState;
      int8 oldState;

                                            39
       // initialize variables
       zero_crossings = 0;
       newADC = 0;
       oldADC = 0;
       runningAVG = 0;
       frequency = 0;
       time_interval = 0;
       signalB = 0;
       currentState = DEFAULTSTATE;
       oldState = DEFAULTSTATE;

       disable_interrupts(GLOBAL); // disable global interrupts
       delay_ms(500);        // wait for voltages to stablize
       Set_Tris_A(MY_TRISA);     // Pin A's I/O
       Set_Tris_C(MY_TRISC);    // Pin C's I/O
       initADC();

       output_low(SIGA);
       output_low(SIGB);

     while(FOREVER)
     {
              // initialize running average
              runningAVG = initRunningAVG();

               oldADC = read_adc();
               delay_ms(5);

//         while(time_interval < 1000)
           while(time_interval < 200*TIMEINTERVAL)
           {
                    newADC = read_adc();

                     if(((oldADC < runningAVG) && (newADC > runningAVG)) ||
                        ((oldADC > runningAVG) && (newADC < runningAVG)))
                           zero_crossings ++;

                     delay_ms(5);
                     time_interval ++;
                     oldADC = newADC;
           }

           frequency = (zero_crossings) >> 1;
           time_interval = 0;
           zero_crossings = 0;
//         oldState = currentState;

         // find the current state (alert or sleeping?) of the user
         if((frequency > (ALPHAWAVES_L)*TIMEINTERVAL-1) && (frequency <
ALPHAWAVES_H*TIMEINTERVAL-1)) // in alpha stage
               currentState = ALPHASTATE;
         else if(frequency > (BETAWAVES_L)*TIMEINTERVAL-1) // in beta stage
         {
               currentState = BETASTATE;
               oldState = BETASTATE;
         }
         else if((frequency < (ALPHAWAVES_L)*TIMEINTERVAL-1))
               currentState = DEEPSTATE;
         else
               currentState = DEFAULTSTATE;

                                            40
             // now send the output signals
             if(currentState == ALPHASTATE)
                   output_high(SIGA);
             else
                   output_low(SIGA);

             if(((currentState == DEEPSTATE)) && (oldState == BETASTATE) && (signalB ==
0))
             {
                   output_high(SIGB);
                   signalB = 1;
             }
             else if(signalB == 1)
                   output_high(SIGB);
             else
                   output_low(SIGB);

      }
}


// Purpose:          Initializes ADC
// Precondition:     None
// Postcondition:    ADC is configured
void initADC(void)
{
   setup_adc_ports(AN0); // A0, Vrefh = Vdd, Vrefl = gnd
   setup_adc(ADC_CLOCK_INTERNAL);
   set_adc_channel( 0 );
   delay_us(10);
}


int16 initRunningAvg(void)
{
      int16 j, samples;
      int16 avg;
      int32 sum;

          sum = 0;
          for(j = 0; j < 256; j++)
          {
                samples = Read_ADC();
                delay_ms(5);
                sum = sum + samples;
          }

          avg = sum >> 8;

          return (avg);
}




                                              41
//////////////////////////////////////////////////////////////////////
////                        ADSignalAnalysis.h                    ////
////                                                              ////
//// Function declarations used in ADSignalAnalysis.c             ////
//// Constants and definitions used in ADSignalAnalysis.c         ////
////                                                              ////
//// Written February 2006                                        ////
//// by Jonathan Santos                                           ////
//// partners: Kevin Lee, Daniel Kim                              ////
////                                                              ////
//////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////
//// constants and definitions

// A/D + Buttons
#define     MY_TRISA   0b11111111            // PinA[7:0] I/O all inputs
#define MY_TRISC 0b00000000            // PinC[7:0] I/O all outputs

#define    SIGA        PIN_C0
#define    SIGB        PIN_C1    // PinC0 signals that the person should wake up

#define       ALPHAWAVES_L       9
#define       ALPHAWAVES_H       13
#define       BETAWAVES_L        14
#define       BETAWAVES_H        30
#define       DELTAWAVES_L       1
#define       DELTAWAVES_H       3
#define       THETAWAVES_L       4
#define       THETAWAVES_H       8

#define FOREVER   1
#define     TIMEINTERVAL         1     // time interval for data collection

#define   DEFAULTSTATE 0
#define   ALPHASTATE         1
#define   BETASTATE 2
#define   DEEPSTATE 3




                                            42
/////////////////////////////////////////////////////////////
//
// AlarmClock.c
//
// Implements an alarm clock. Alarm will only sound
//    based on certain conditions of inputs A and B.
//
// Written March 2006 by Jonathan Santos
//    modified from Group18 Fall 2004, "Smart Alarm Clock"
//
//    Partners: Kevin Lee, Daniel Kim
//
//    first version: March 25, 2006 - program structure done
//    second version: March 28, 2006 - setting time/alarm and keeping time working
//    third version:    April 1, 2006 - changed method of timekeeping, all outputs
//                                       signals done and working
//    final version: ...
//
/////////////////////////////////////////////////////////////

#include <16F877A.h>
#device *=16 ADC=10     // Use 16-bit pointers, use 8-bit ADC
#fuses HS                 // You may or may not want some of these ....
#fuses NOWDT
#fuses NOPROTECT
#fuses NOLVP
#fuses NODEBUG
#fuses NOPUT
#fuses NOBROWNOUT
#use delay(clock=4000000)            //4MHz

// These require use of Set_Tris_x()
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)

#define DELAY_CHANGE_TIME              20000

// Global variables
int16 timeMin = 10;
int16 timeHour = 10;
int16 alarmMin = 0;
int16 alarmHour = 7;
//int8 timeMin;
//int8 timeHour;
//int8 alarmMin;
//int8 alarmHour;
//int8 testint = 0;
//int8 testint2 = 0;
int8 pina4;
int8 pina5;
int8 pina0;
int8 pina3;
int8 pina1;
int8 pina2;
                                               43
int8 pind1;
int8 pind0;
int8 pind2;
int8 pind3;
int8 pind4;
int8 pind5;
int8 timerCount1 = 0;
int8 increment = 0;
int16 counter = 0;
int8 tmin0, tmin1, thour0, thour1; // time variables
int8 amin0, amin1, ahour0, ahour1; // alarm variables

#include "Include\display.c"

// function declarations
void initTimers( void);
void timer1ISR( void);
void set_time( void);
void set_alarm(void);
void update_time( void);

// Purpose:           Initializes timer interrupts
// Precondition:      None
// Postcondition:     Timers and interrupts are enabled
void initTimers(void)
{
   setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 ); // timer1 will increment every
(32/4000000) = 8 microseconds
   set_timer1(3036);                                             // It will
overflow every 0.5 seconds
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   timerCount1 = 0;
}

// Purpose:          Timer1 ISR
// Precondition:     initTimers called
// Postcondition:    Timer1 counter updated
// This routine is called every 0.5 seconds
#INT_TIMER1
void Timer1ISR(void)
{
   disable_interrupts(GLOBAL);
   disable_interrupts(INT_TIMER1);
   set_timer1(3036);

     timerCount1 ++;

//     if(timerCount1 == 114) // 59.7679 seconds have passed
//         set_timer1(36520); // compensate for overcounting

     if(timerCount1 > 119)
     {
           timerCount1 = 0;
           increment = 1;

/*
              if(testint2 == 0){
                    output_high(PIN_E0);
              testint2 = 1;
              }
              else{
                                           44
                  output_low(PIN_E0);
                  testint2 = 0;
            }
*/
   }
/*
if(testint == 0){
      output_high(PIN_E1);
testint = 1;
}
else{
      output_low(PIN_E1);
testint = 0;
}
*/
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
}

void set_time(void)
{
      while(pina4) // do not leave while we are setting the real time
      {
            // allow time to increment also
            if(increment == 1){
                  timeMin ++;
                  increment = 0;
            }

            if(timeMin > 59){
                  timeMin = 0;
                  timeHour ++;
            }

            if(timeHour > 23)
                  timeHour = 0;

            pina4 = input(PIN_A4);
            pind5 = input(PIN_D5);
            pind4 = input(PIN_D4);
//          counter = 0;
//          while(counter < DELAY_CHANGE_TIME)
//                counter ++;

            // increment minute if button is pressed
            if(pind5 == 1){
                  timeMin ++;
                  timerCount1 = 0;
                  set_timer1(3036);
                  counter = 0;
                  while(counter < DELAY_CHANGE_TIME)
                        counter ++;
//                disable_interrupts(GLOBAL);
//                delay_ms(250); // delay for 0.25 seconds
//                enable_interrupts(GLOBAL);
            }

            // increment hour if button is pressed
            if(pind4 == 1){
                  timeHour ++;
                  timerCount1 = 0;
                  set_timer1(3036);
                                         45
                  counter = 0;
                  while(counter < DELAY_CHANGE_TIME)
                        counter ++;
//                disable_interrupts(GLOBAL);
//                delay_ms(250); // delay for 0.25 seconds
//                enable_interrupts(GLOBAL);
            }

            // check for time wraparound
            if(timeMin > 59)
                  timeMin = 0;

            if(timeHour > 23)
                  timeHour = 0;

            update_time();
            display(tmin0, tmin1, thour0, thour1);
     }
}

void set_alarm(void)
{
      while(pina5) // do not leave while we are setting the alarm time
      {
            // allow time to be incremented
            if(increment == 1){
                  timeMin ++;
                  increment = 0;
            }

            if(timeMin > 59){
                  timeMin = 0;
                  timeHour ++;
            }

            if(timeHour > 23)
                  timeHour = 0;

            pina5 = input(PIN_A5);
            pind4 = input(PIN_D4);
            pind5 = input(PIN_D5);
//          counter = 0;
//          while(counter < DELAY_CHANGE_TIME)
//                counter ++;

            // increment alarm if button is pressed
            if(pind5 == 1){
                  alarmMin ++;
                  counter = 0;
                  while(counter < DELAY_CHANGE_TIME)
                        counter ++;
//                disable_interrupts(GLOBAL);
//                delay_ms(250); // delay for 0.25 seconds
//                enable_interrupts(GLOBAL);
            }

            if(pind4 == 1){
                  alarmHour ++;
                  counter = 0;
                  while(counter < DELAY_CHANGE_TIME)
                        counter ++;
//                disable_interrupts(GLOBAL);
                                           46
//               delay_ms(250); // delay for 0.25 seconds
//               enable_interrupts(GLOBAL);
           }

           // check for time wraparound
           if(alarmMin > 59)
                 alarmMin = 0;

           if(alarmHour > 23)
                 alarmHour = 0;

           update_time();
           display(amin0, amin1, ahour0, ahour1);
     }
}

void update_time(void)
{
      // set time minute display
                  if(timeMin < 10){   tmin1 = 0; tmin0 = timeMin; }
                  else if(timeMin <   20){ tmin1 = 1; tmin0 = timeMin   -   10;}
                  else if(timeMin <   30){ tmin1 = 2; tmin0 = timeMin   -   20;}
                  else if(timeMin <   40){ tmin1 = 3; tmin0 = timeMin   -   30;}
                  else if(timeMin <   50){ tmin1 = 4; tmin0 = timeMin   -   40;}
                  else { tmin1 = 5;   tmin0 = timeMin - 50;}

     // set alarm minute display
                 if(alarmMin < 10){ amin1 = 0; amin0 = alarmMin; }
                 else if(alarmMin < 20){ amin1 = 1; amin0 = alarmMin        -   10;}
                 else if(alarmMin < 30){ amin1 = 2; amin0 = alarmMin        -   20;}
                 else if(alarmMin < 40){ amin1 = 3; amin0 = alarmMin        -   30;}
                 else if(alarmMin < 50){ amin1 = 4; amin0 = alarmMin        -   40;}
                 else { amin1 = 5; amin0 = alarmMin - 50;}

                 if(timeHour < 10){ thour1 = 0; thour0 = timeHour; }
                 else if(timeHour < 20){ thour1 = 1; thour0 = timeHour - 10;}
                 else { thour1 = 2; thour0 = timeHour - 20;}

                 if(alarmHour < 10){ ahour1 = 0; ahour0 = alarmHour; }
                 else if(alarmHour < 20){ ahour1 = 1; ahour0 = alarmHour - 10;}
                 else { ahour1 = 2; ahour0 = alarmHour - 20;}
}

// ============================================================
//                      MAIN SUBROUTINE
//
// Main subroutine controls the entire program. Set clock time
// and alarm time. Set off buzzer.
#pragma zero_ram
void main()
{
      disable_interrupts(GLOBAL);       // We don't want to be interrupted yet
    disable_interrupts(INT_TIMER1);
      delay_ms(500);       // wait for voltages to stablize

     // configure I/O
     setup_adc(ADC_OFF);
     setup_adc_ports(NO_ANALOGS);     // set portA   as all digital
     set_tris_a(0b11111111);                // all   inputs
     set_tris_b(0b00000000);                // all   outputs
     set_tris_c(0b00000000);                // all   outputs
     set_tris_d(0b11111111);                // all   inputs
                                           47
     set_tris_e(0b00000000);                // all outputs

//   port_b = 0;
//   port_c = 0;
//   port_e = 0;
//   timeMin = 10;
//   timeHour = 10;
//   alarmMin = 0;
//   alarmHour = 7;
     output_low(PIN_E2);              // buzzer off by default
     output_high(PIN_E0);       // relays on by default
     output_high(PIN_E1);

     delay_ms(50);
     initTimers();                // This is where the interrupts are enabled again

     output_low(PIN_E2);              // buzzer off by default
     output_high(PIN_E0);       // relays on by default
     output_high(PIN_E1);

     // start main   loop
     while(TRUE)
     {
           pina5 =   input(PIN_A5);
           pina4 =   input(PIN_A4);
           pina3 =   input(PIN_A3);
           pina0 =   input(PIN_A0);
           pina1 =   input(PIN_A1);
           pina2 =   input(PIN_A2);
           pind1 =   input(PIN_D1);
           pind0 =   input(PIN_D0);
           pind2 =   input(PIN_D2);
           pind3 =   input(PIN_D3);

           // first check if real time has to be incremented
           if(increment == 1){
                 timeMin ++;
                 increment = 0;
           }

           if(timeMin > 59){
                 timeMin = 0;
                 timeHour ++;
           }

           if(timeHour > 23)
                 timeHour = 0;

//         while(!pina2 && !pina3 && !pina4 && !pina5);
           counter = 0;
           while(counter < 5000)
                 counter ++;

//         counter = 0;
//         while(counter < DELAY_CHANGE_TIME)
//               counter ++;

           // display the real time or alarm time
//         if(input(PIN_A5) == 1) // call set_alarm routine
           if(pina5 == 1)
                 set_alarm();
//         else if(input(PIN_A4) == 1)   // call set_alarm routine
                                           48
//          else if(pina4 == 1)
            if(pina4 == 1)
                  set_time();
//          else{
      // display the real time and update it too
                  update_time();
                  display(tmin0, tmin1, thour0, thour1);
//          }

            ////////////////////////////////////// OUTPUTS
/////////////////////////////////////////
            // set buzzer and relay outputs depending on input signals and time

              if( pina3 && (timeHour*60+timeMin == alarmHour*60+alarmMin) ) // hard
time buzzer
              {
                     output_high(PIN_E2);
                     if(pind1)
                           output_high(PIN_E0);
                     else
                           output_low(PIN_E0);
                     if(pind3)
                           output_high(PIN_E1);
                     else
                           output_low(PIN_E1);
            }
            else if( pina3 && pina0 &&
                        (timeHour*60+timeMin > alarmHour*60+alarmMin-90) &&
                        (timeHour*60+timeMin < alarmHour*60+alarmMin) )       //
give 90 minutes for light sleep stage
            {
                  output_high(PIN_E2);
                  if(pind1)
                        output_high(PIN_E0);
                  else
                        output_low(PIN_E0);
                  if(pind3)
                        output_high(PIN_E1);
                  else
                        output_low(PIN_E1);
            }
            else if( pina3 && pina1 )     // if alarm is set and user has fallen
asleep
            {
                  if(pind0)
                        output_low(PIN_E0);
                  else
                        output_high(PIN_E0);
                  if(pind2)
                        output_low(PIN_E1);
                  else
                        output_high(PIN_E1);
            }

              else
              {
                     output_low(PIN_E2);
                     output_high(PIN_E0);
                     output_high(PIN_E1);
              }



                                            49
      } // end while loop
} // end main




/////////////////////////////////////////////////////////////
//
// display.c
//
// Displays functions for the alarm clock.
//
// Written March 2006 by Jonathan Santos
//    modified from Group18 Fall 2004, "Smart Alarm Clock"
//
//    Partners: Kevin Lee, Daniel Kim
//
/////////////////////////////////////////////////////////////

int8 port_b;
int8 port_c;
int8 port_e;

//=================================================================================
//          MAPPING FOR DECODER ON ROUTE TO 7 SEG LED DISPLAY

int8 CONST   LED_MAP0[10] = {0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09};
//0..
int8 CONST   LED_MAP1[10] = {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19};
//1..
int8 CONST   LED_MAP2[10] = {0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29};
//2..
int8 CONST   LED_MAP3[10] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
//3..
int8 CONST   LED_MAP4[10] = {0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49};
//4..
int8 CONST   LED_MAP5[10] = {0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59};
//5..

//=================================================================================
/*display_mins0, display_mins1, display_mins2, display_mins3, display_mins4.
display_mins5,
   display_hrs0, display_hrs1, display_hrs2 retrieves character mapping for
corresponding digit.
   It then sends that mapping to corresponding LED decoder through port b. If digit
is not between 0 and 9,
   nothing will be outputted (serves as precautionary step).
   Calls: none
   Input: int8 c - digit to be mapped
   Output: none
*/

// function declarations
void display_mins0(int8 c);
void display_mins1(int8 c);
void display_mins2(int8 c);
                                           50
void   display_mins3(int8 c);
void   display_mins4(int8 c);
void   display_mins5(int8 c);
void   display_hrs0(int8 c);
void   display_hrs1(int8 c);
void   display_hrs2(int8 c);
void   display(int8 minLSB, int8 minMSB, int8 hrLSB, int8 hrMSB);

// function definitions
void display_mins0(int8 c) {
  if((c>9)||(c<0))
    port_b=0x00;
  else
    port_b=LED_MAP0[c];
}

void display_mins1(int8 c) {
  if((c>9)||(c<0))
    port_b=0x00;
  else
    port_b=LED_MAP1[c];
}

void display_mins2(int8 c) {
  if((c>9)||(c<0))
    port_b=0x00;
  else
    port_b=LED_MAP2[c];
}

void display_mins3(int8 c) {
  if((c>9)||(c<0))
    port_b=0x00;
  else
    port_b=LED_MAP3[c];
}

void display_mins4(int8 c) {
  if((c>9)||(c<0))
    port_b=0x00;
  else
    port_b=LED_MAP4[c];
}

void display_mins5(int8 c) {
  if((c>9)||(c<0))
    port_b=0x00;
  else
    port_b=LED_MAP5[c];
}

void display_hrs0(int8 c) {
  if((c>9)||(c<0))
    port_c=0x00;
  else
    port_c=LED_MAP0[c];
}

void display_hrs1(int8 c) {
  if((c>9)||(c<0))
    port_c=0x00;
  else
                                           51
    port_c=LED_MAP1[c];
}

void display_hrs2(int8 c) {
  if((c>9)||(c<0))
    port_c=0x00;
  else
    port_c=LED_MAP2[c];
}

//=================================================================================
/*
Display subroutine gets character mapping for each digit
Calls: display_mins0, display_mins1, display_mins3, display_mins4, display_mins5
       display_hrs0, display_hrs1, display_hrs2
Inputs: minsLSB - least sig bit for minutes display
           minsMSB - most sig bit for minutes display
           hrLSB - least sig bit for hour display
           hrMSB - most sig bit for hour display
OutputsL none
*/

void display(int8 minLSB, int8 minMSB, int8 hrLSB, int8 hrMSB)
{

      //tie cathodes of LED to gnd
      //deal with minutes first
      if(minMSB==0){                      //look at MSB of minutes
            display_mins0(minLSB);
      }
      if(minMSB==1){
            display_mins1(minLSB);
      }
      if(minMSB==2){
            display_mins2(minLSB);
      }
      if(minMSB==3){
            display_mins3(minLSB);
      }
      if(minMSB==4){
            display_mins4(minLSB);
      }
      if(minMSB==5){
            display_mins5(minLSB);
      }

      if(hrMSB==0){
            display_hrs0(hrLSB);
      }

      if(hrMSB==1){
            display_hrs1(hrLSB);
      }

      if (hrMSB==2){
            display_hrs2(hrLSB);
      }

      output_b(port_b);
      output_c(port_c);
}

                                         52

								
To top