APPENDIX A – BLOCK DIAGRAM

44
EEG Circuit Signal Processing Circuit Alarm Clock Circuit Display C ircuit User Interface Alarm Clock Module Relay Circuit Signal Processing Module EEG Module APPENDIX A – BLOCK DIAGRAMS Figure A.1: Block Diagram of Project - block diagram demonstrating the modularity of our project. 16

Transcript of APPENDIX A – BLOCK DIAGRAM

Page 1: APPENDIX A – BLOCK DIAGRAM

EEGCircuit

Signal Processing

Circuit

AlarmClockCircuit

Display Circuit

UserInterface

Alarm Clock Module

RelayCircuit

Signal Processing

ModuleEEG Module

APPENDIX A – BLOCK DIAGRAMS

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

16

Page 2: APPENDIX A – BLOCK DIAGRAM

R13.3mega

C

.1u

0

R2

33k

.1u

0

+

-

OUT

U17

AD622

+

-

OUT

U18

OPAMP

0

Output

Left Electrode

Right Electrode

Neck Electrode

R13.3mega

C

.1u

0

R2

33k

.1u

0

C

C

R13.3mega

C

.1u

0

R2

33k

.1u

0

C

R2

3.3mega

R2

3.3mega

C

0.1u

C

0.1u

R1

33k

R1

33k

C

0.1u

C0.1u

0

0

+

-

OUT

U6

OPAMP

+

-

OUT

U7

OPAMP

APPENDIX B – SCHEMATICS

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

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

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

17

Page 3: APPENDIX A – BLOCK DIAGRAM

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

18

Page 4: APPENDIX A – BLOCK DIAGRAM

Fig

ure

B.5

: A

larm

Clo

ck S

chem

atic

– S

chem

atic

of

the

Ala

rm c

lock

mod

ule

19

Page 5: APPENDIX A – BLOCK DIAGRAM

APPENDIX C – FLOW CHARTS

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

20

Page 6: APPENDIX A – BLOCK DIAGRAM

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

21

Page 7: APPENDIX A – BLOCK DIAGRAM

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

22

Page 8: APPENDIX A – BLOCK DIAGRAM

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

23

Page 9: APPENDIX A – BLOCK DIAGRAM

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

24

Page 10: APPENDIX A – BLOCK DIAGRAM

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

Page 11: APPENDIX A – BLOCK DIAGRAM

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

Page 12: APPENDIX A – BLOCK DIAGRAM

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

Page 13: APPENDIX A – BLOCK DIAGRAM

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

Page 14: APPENDIX A – BLOCK DIAGRAM

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.

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

Frequency Response

0

0.2

0.4

0.6

0.8

1

1.2

1.4

0 10 20 30 40 50 60 70 80 90 100

Frequency (Hz)

Vo

ltag

e (V

)

29

Page 15: APPENDIX A – BLOCK DIAGRAM

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

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

30

Page 16: APPENDIX A – BLOCK DIAGRAM

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

31

PIC time www.time.gov PIC interval www.time.gov interval

Difference

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 1 h 1 h 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

Page 17: APPENDIX A – BLOCK DIAGRAM

EEG CircuitDisplay Circuit (Signal Processing Circuit and Alarm Clock Circuit below)

4-position switchHR & MIN IncrementPush Buttons

Relay Circuit

ApplianceControlSwitches

Banana JackInputs from Electrodes

Plexiglass Cover

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.

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

Page 18: APPENDIX A – BLOCK DIAGRAM

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

Page 19: APPENDIX A – BLOCK DIAGRAM

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 TotalN/A Unomedical Ag/AgCl Electrodes 3 $0.19 $0.57N/A PCB 1 3.29 3.29

AD622AN Instrumentation Amplifier 2 $5.15 $10.30MC3403 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 TotalPIC16F877A 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.321N4734 Zener Diode 1 $0.11 $0.11

N/A PCB 1 $3.29 $3.29N/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

Page 20: APPENDIX A – BLOCK DIAGRAM

Part # Description Qty. Price TotalPIC16F877A 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.48CD4511BE BCD-to-7 Segment Converter 4 $0.63 $2.52

T77S1D10-05 Relay 2 $2.11 $4.2274AC11000 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 TotalN/A Aluminum Box 1 $6.99 $6.99N/A Plexiglass cover 1 $3.99 $3.99N/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

Page 21: APPENDIX A – BLOCK DIAGRAM

APPENDIX G – MISCELLANEOUS

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 EEG4 Vref- GND5 Vref+ Vdd6 E0 O A (Light sleep) Alarm Clock PIC7 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

Frequency (Hz) Brain Wave Sleep Stage0.5 – 3 Delta Deep Sleep4 – 7 Theta Drowsy Sleep8 – 13 Alpha Light Sleep14 + Beta Awake, REM

Page 22: APPENDIX A – BLOCK DIAGRAM

Pin# LabelI/O Description To/From Part Label

2 A0 I A3 A1 I B4 A2 I ALARM_OFF four pos. switch5 A3 ALARM_ON four pos. switch6 A4 I SET_TIME four pos. switch7 A5 I SET_ALARM four pos. switch

33 B0 O MIN – ones digit 7-Seg Decoder 1 A34 B1 O MIN – ones digit 7-Seg Decoder 1 B35 B2 O MIN – ones digit 7-Seg Decoder 1 C36 B3 O MIN – ones digit 7-Seg Decoder 1 D37 B4 O MIN – tens digit 7-Seg Decoder 2 A38 B5 O MIN – tens digit 7-Seg Decoder 2 B39 B6 O MIN – tens digit 7-Seg Decoder 2 C40 B7 O MIN – tens digit 7-Seg Decoder 2 D15 C0 O HR – ones digit 7-Seg Decoder 3 A16 C1 O HR – ones digit 7-Seg Decoder 3 B17 C2 O HR – ones digit 7-Seg Decoder 3 C18 C3 O HR – ones digit 7-Seg Decoder 3 D23 C4 O HR – tens digit 7-Seg Decoder 4 A24 C5 O HR – tens digit 7-Seg Decoder 4 B25 C6 O HR – tens digit 7-Seg Decoder 4 C26 C7 O HR – tens digit 7-Seg Decoder 4 D19 D0 I Appl. 1 - Turn off at night switch20 D1 I Appl. 1 - Turn on in morn. switch21 D2 I Appl. 2 - Turn off at night switch22 D3 I Appl. 2 - Turn on in morn. switch27 D4 I Change HR push button28 D5 I Change MIN push button13 OSC1 crystal oscillator14 OSC2 crystal osc. (not used)

8 E0 O Appliance 1 Relay Relay 19 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

Page 23: APPENDIX A – BLOCK DIAGRAM

BCD inputs segment outputsdisplay

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

Page 24: APPENDIX A – BLOCK DIAGRAM

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 declarationsvoid initTimers(void);void initADC(void);int16 initRunningAvg(void);

#pragma zero_ram void main( void)

// declare variablesint16 zero_crossings;int16 newADC, oldADC;int16 runningAVG;int16 frequency;int16 time_interval;int8 signalB;int8 currentState;int8 oldState;

39

Page 25: APPENDIX A – BLOCK DIAGRAM

// initialize variableszero_crossings = 0;newADC = 0;oldADC = 0;runningAVG = 0;frequency = 0;time_interval = 0;signalB = 0;currentState = DEFAULTSTATE;oldState = DEFAULTSTATE;

disable_interrupts(GLOBAL); // disable global interruptsdelay_ms(500); // wait for voltages to stablizeSet_Tris_A(MY_TRISA); // Pin A's I/OSet_Tris_C(MY_TRISC); // Pin C's I/OinitADC();

output_low(SIGA);output_low(SIGB);

while(FOREVER)

// initialize running averagerunningAVG = 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

Page 26: APPENDIX A – BLOCK DIAGRAM

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

Page 27: APPENDIX A – BLOCK DIAGRAM

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

Page 28: APPENDIX A – BLOCK DIAGRAM

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

Page 29: APPENDIX A – BLOCK DIAGRAM

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 variablesint8 amin0, amin1, ahour0, ahour1; // alarm variables

#include "Include\display.c"

// function declarationsvoid 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 enabledvoid 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_TIMER1void 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

Page 30: APPENDIX A – BLOCK DIAGRAM

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 alsoif(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 pressedif(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 pressedif(pind4 == 1)

timeHour ++;timerCount1 = 0;set_timer1(3036);

45

Page 31: APPENDIX A – BLOCK DIAGRAM

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 wraparoundif(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 incrementedif(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 pressedif(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

Page 32: APPENDIX A – BLOCK DIAGRAM

// delay_ms(250); // delay for 0.25 seconds// enable_interrupts(GLOBAL);

// check for time wraparoundif(alarmMin > 59)

alarmMin = 0;

if(alarmHour > 23)alarmHour = 0;

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

void update_time(void)

// set time minute displayif(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 displayif(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/Osetup_adc(ADC_OFF);setup_adc_ports(NO_ANALOGS); // set portA as all digitalset_tris_a(0b11111111); // all inputsset_tris_b(0b00000000); // all outputsset_tris_c(0b00000000); // all outputsset_tris_d(0b11111111); // all inputs

47

Page 33: APPENDIX A – BLOCK DIAGRAM

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 defaultoutput_high(PIN_E0); // relays on by defaultoutput_high(PIN_E1);

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

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

// start main loopwhile(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 incrementedif(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

Page 34: APPENDIX A – BLOCK DIAGRAM

// else if(pina4 == 1)if(pina4 == 1)

set_time();// else

// display the real time and update it tooupdate_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);

elseoutput_high(PIN_E0);

if(pind2)output_low(PIN_E1);

elseoutput_high(PIN_E1);

else

output_low(PIN_E2);output_high(PIN_E0);output_high(PIN_E1);

49

Page 35: APPENDIX A – BLOCK DIAGRAM

// 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 declarationsvoid display_mins0(int8 c);void display_mins1(int8 c);void display_mins2(int8 c);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);

50

Page 36: APPENDIX A – BLOCK DIAGRAM

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

// function definitionsvoid 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 port_c=LED_MAP1[c];

void display_hrs2(int8 c) if((c>9)||(c<0)) port_c=0x00;

51

Page 37: APPENDIX A – BLOCK DIAGRAM

else port_c=LED_MAP2[c];

//=================================================================================/*Display subroutine gets character mapping for each digitCalls: display_mins0, display_mins1, display_mins3, display_mins4, display_mins5 display_hrs0, display_hrs1, display_hrs2Inputs: 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 displayOutputsL none*/

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

//tie cathodes of LED to gnd//deal with minutes firstif(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