# APPENDIX A – BLOCK DIAGRAM - DOC - DOC by cuiliqing

VIEWS: 82 PAGES: 37

• pg 1
```									                            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
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

//////////////////////////////////////////////////////////////////////
////                                                              ////
//// 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>

#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

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

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

39
// initialize variables
zero_crossings = 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

output_low(SIGA);
output_low(SIGB);

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

delay_ms(5);

//         while(time_interval < 1000)
while(time_interval < 200*TIMEINTERVAL)
{

zero_crossings ++;

delay_ms(5);
time_interval ++;
}

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);

}
}

// Precondition:     None
{
setup_adc_ports(AN0); // A0, Vrefh = Vdd, Vrefl = gnd
delay_us(10);
}

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

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

avg = sum >> 8;

return (avg);
}

41
//////////////////////////////////////////////////////////////////////
////                                                              ////
//// 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>
#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_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