Parallax Propeller Basic Security System
{{
This code example simulates a very basic security system.
Written by Grant Jenks
http://www.grantjenks.com/
DISCLAIMER
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE
LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY
SERVICING, REPAIR OR CORRECTION.
Copyright
This work is licensed under the
Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.
To view a copy of this license, visit
http://creativecommons.org/licenses/by-nc-nd/3.0/
or send a letter to Creative Commons, 171 Second Street, Suite 300,
San Francisco, California, 94105, USA
Pin map:
0 red light
1 yellow light
2 green light
16 button 1
17 button 2
18 button 3
19 button 4
File: BasicSecuritySystem.spin
Exercises:
(1) The current code is 1 2 1. Change the code to 2 1 1.
(2) The current code is three button presses long, change the code to 5
button presses.
(3) The board is wired for 3 buttons but the program recognizes only
2 buttons. Add support for the third button and change the code
to be 2 1 3.
(4) Currently, the system waits 30 seconds before sounding the alarm. Change
the wait time to 15 seconds.
}}
CON 'Global constants
STATUS_WAIT = 0
STATUS_PASS = 1
STATUS_FAIL = 2
DOOR = 16 'Button pin maps
BUTTON_1 = 17
BUTTON_2 = 18
BUTTON_3 = 19
BUTT_MIN = 16
BUTT_MAX = 19
LED_RED = 0 'LED pin maps
LED_YEL = 1
LED_GRE = 2
LED_MIN = 0
LED_MAX = 2
CODE_LEN = 3 'Length of security code
_xinfreq = 6_250_000 'Printed on the oscillator
_clkmode = xtal1 + pll16x 'Will clock at 100MHz
VAR 'Global variables
long stack[200] 'Stack space for cogs
long cog_code 'Cog ids for code/wait routines
long cog_wait
long status 'Communicate between cogs
long code[CODE_LEN] 'Store entered code
OBJ
pst : "Parallax Serial Terminal"
PUB BasicSecuritySystem
pst.Start(115200)
pst.Str(String(pst#NL, "Security System Monitoring..."))
dira[LED_MIN..LED_MAX]~~ 'Set LED pins for output
dira[BUTT_MIN..BUTT_MAX]~ 'Set button pins for input
outa[LED_MIN..LED_MAX]~ 'Turn LEDs off
repeat
pst.Str(String(pst#NL, "Door is shut")) 'Note: the door must begin closed
outa[LED_GRE] := 1 'Turn on green LED
repeat while ina[DOOR] == 1 'Do nothing while door shut
waitcnt(clkfreq / 1000 + cnt)
pst.Str(String(pst#NL, "Door opened"))
outa[LED_GRE] := 0 'Turn off green LED
outa[LED_YEL] := 1 'Turn on yellow LED
status := STATUS_WAIT
cog_code := cognew(ReadCode, @stack[0]) 'Start cogs
cog_wait := cognew(Wait, @stack[100])
repeat while status == STATUS_WAIT 'Wait for status change
waitcnt(clkfreq/1000 + cnt)
cogstop(cog_code) 'Stop cogs
cogstop(cog_wait)
outa[LED_YEL] := 0 'Turn off yellow LED
if status == STATUS_FAIL or ina[DOOR] == 0 'Sound alarm if status is fail or door is open
quit
pst.Str(String(pst#NL, "Alert! Alert! Alert! Sound door alarm..."))
outa[LED_RED] := 1 'Turn on red LED
repeat 'Loop forever doing nothing
PUB ReadCode | pos, pressed
pst.Str(String(pst#NL, "Reading code..."))
pos := 0 'Position in the code array
pressed := 0 '0 if no button is pressed
'Note that "pressed" is used to eliminate the jitter that occurs with
'button press/release. Because the jitter occurs at a frequency less
'than 1KHz, we'll just sleep at the end of the loop and use "pressed"
'to recognize the state change.
repeat until pos == CODE_LEN
if ina[BUTTON_1] == 1 and pressed == 0
pst.Str(String(pst#NL, "Button 1 pressed"))
'Store the button press code, advance the position in the array and
'indicate a pressed button
code[pos] := 1
pos := pos + 1
pressed := 1
elseif ina[BUTTON_2] == 1 and pressed == 0
pst.Str(String(pst#NL, "Button 2 pressed"))
'Store the button press code, advance the position in the array and
'indicate a pressed button
code[pos] := 2
pos := pos + 1
pressed := 1
elseif ina[BUTTON_1] == 0 and ina[BUTTON_2] == 0
pressed := 0
'The buttons have a jitter that requires we sleep here before
'sampling again.
waitcnt(clkfreq/1000 + cnt)
if code[0] == 1 and code[1] == 2 and code[2] == 1
pst.Str(String(pst#NL, "Code is correct!"))
status := STATUS_PASS
else
pst.Str(String(pst#NL, "Code is incorrect!"))
status := STATUS_FAIL
PUB Wait
waitcnt(clkfreq * 30 + cnt) 'Wait 30 seconds
pst.Str(String(pst#NL, "30 seconds have passed; sound alarm!"))
status := STATUS_FAIL