Last Updated:25/10/2021
How To 4 - Creating a Project
Lessons >> How To >> How To 4 - Creating a Project
Overview
This is a guide as to how to go about creating a project.
This project will be a simple alarm project that requires a pass code to be input through a key pad.
The system will first detect movement., for this a PIR sensor will be used.
If movement is detected the person will be challenegd to insert a pass code on the keypad with a warning beep and flashing LED (keypad, LED and Buzzer).
If the person does not enter the code in time or enters the wrong code the alarm sounds (LED and buzzer) .
If the movement stops, either the person uns away or an animal has walked by, the alarm or warning needs to stop.
If the correct code is entered the alarm/warning is stopped and the sensor deactivated for 60 seconds before it resets.
Now we have defined what we want the system to do we need to start to think about the interactino of the components.
If we want wanring sounds and leds flashing while the person is enetering a value into the keypad we need to write the code in such a way that each item does not interfere with another item. This means we cannot uses function like delay() as delay stops the Arduino from doing anything else.
If delay() was in our keypad code the LED/Alarm sounds could not play. If delay() was in the alarm system, the keypad would not work.
his mean all the components will need to be able to work at the same time so any timings will need to use milis() as a timer rather than delay().
As this can get complicated, the easiest way to do this is break down the project into the individual components and build a function to control the different parts of the project.
Below shows a break down of how the code will work. Most items because they are on millis() timers will not use up much processor power, allowing the Arduino to switch between tasks very quickly.
Example 1: alarmLedv1.ino
I decided to work on the LED's and Alarm sound first. For the example I am using the Arduino built in LED on pin13 and connecting a simple buzzer to pin 11.
I wanted 2 sets of sounds.
A warning sound with a quick blinking LED to warn the user to input a code.
An alarm sound with two tones from the buzzer and flashing LED
The individual functions can be triggered by setting:
soundAlarm
= 1 or soundWarn = 1
.
Both functions use millis() for their timings.
Click to Download code:alarmLedv1.ino
/* 25/10/2021
* alarmLedv1
*
* create 2 functions,
*
* one to sound alarm
* one to warn operator to enter passcode
*
*
* pins
* 11 buzzer
* 13 led
*/
const int buzzerPin = 11;
const int ledPin = 13;
int soundAlarm = 0;//0 alarm is off, 1 alarm is on
int alarmState;//used to flash the leds/tone
unsigned long alarmTimer;
int alarmDelay = 1000;
void myAlarm(){
if(soundAlarm > 0){//sound alarm
if(millis() > alarmTimer){
alarmTimer = millis() + alarmDelay;
if(alarmState < 1){
alarmState = 1;
digitalWrite(ledPin,HIGH);
tone(buzzerPin,500);
}else{
alarmState = 0;
digitalWrite(ledPin,LOW);
tone(buzzerPin,1000);
}
}
}
}
int soundWarn = 0;//0 warn is off, 1 warn is on
int warnState;//used to flash the leds/tone
unsigned long warnTimer;
void myWarn(){
if(soundWarn > 0){//sound alarm
if(millis() > warnTimer){
if(warnState < 1){
warnState = 1;
digitalWrite(ledPin,HIGH);
tone(buzzerPin,500);
warnTimer = millis() + 100;
}else{
warnState = 0;
digitalWrite(ledPin,LOW);
noTone(buzzerPin);
warnTimer = millis() + 500;
}
}
}
}
void setup() {
Serial.begin(9600);
Serial.println("alarmLedv1...");
pinMode(buzzerPin,OUTPUT);
pinMode(ledPin,OUTPUT);
}
void loop() {
myAlarm();//sets alarm sound off
myWarn();//sets passcode warning sound
}
Example 2: keypadv1.ino
Next I just checked that my key pad code was working with this simple sketch based on the examples in the Keypad library but altered to use the pins I want to use.
Click to Download code:keypadv1.ino
/* 25/10/2021
* keypadv1
* basic control of a keypad
*
* pins used
* 2
* 3
* 4
* 5
* 6
* 7
* 8
* 9
*/
#include "Keypad.h"
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
Serial.begin(9600);
}
void loop(){
char customKey = keypad.getKey();
if (customKey){
Serial.println(customKey);
}
}
Example 3: pirv2.ino
Next I sorted out the PIR sensor on pin12.
This checks the status of the PIR sensor every 0.1 seconds using a millis() timer.
Click to Download code:pirv2.ino
/* 25/10/2021
* pirv2
* changed to a millis() timed function
*
*
* pins used
* 12
*
*
*/
const int pirPin = 12;
int myMovement = 0;
unsigned long pirTimer;
int pirScanDelay = 100;//time in milliseconds until the next pir scan takes place
//function is now controlled by a millis() timer
void pirScan(){
if(millis() > pirTimer){
pirTimer = millis() + pirScanDelay;
myMovement = digitalRead(pirPin);
Serial.println(myMovement);
}
}
void setup() {
Serial.begin(9600);
Serial.println("pirv2...");
pinMode(pirPin,INPUT);
}
void loop() {
pirScan();
}
Example 4: alarmSystemv1.ino
The next stage was to link the PIR and LED/Buzzer functions together in a single sketch.
This meant adding a new function called alarmControl(), this is the linking fucntion that tells the alarms when to sound.
I now had a system that would sense movement and prompt for a code and after a few seconds sound an alarm while movement was present. If the movement stopped the system reset.
Click to Download code:alarmSystemv1.ino
/* 25/10/2021
* alarmSystemv1
*
* Put the led/buzzer and PIR
*
*
*
*
* pins
* 11 buzzer
* 12 pir
* 13 led
*/
const int buzzerPin = 11;
const int pirPin = 12;
const int ledPin = 13;
int soundAlarm = 0;//0 alarm is off, 1 alarm is on
int alarmState;//used to flash the leds/tone
unsigned long alarmTimer;
int alarmDelay = 1000;
//alarm sounding function
void myAlarm(){
if(soundAlarm > 0){//sound alarm
if(millis() > alarmTimer){
alarmTimer = millis() + alarmDelay;
if(alarmState < 1){
alarmState = 1;
digitalWrite(ledPin,HIGH);
tone(buzzerPin,500);
}else{
alarmState = 0;
digitalWrite(ledPin,LOW);
tone(buzzerPin,1000);
}
}
}
}
int soundWarn = 0;//0 warn is off, 1 warn is on
int warnState;//used to flash the leds/tone
unsigned long warnTimer;
//warning sounding function
void myWarn(){
if(soundWarn > 0){//sound alarm
if(millis() > warnTimer){
if(warnState < 1){
warnState = 1;
digitalWrite(ledPin,HIGH);
tone(buzzerPin,500);
warnTimer = millis() + 100;
}else{
warnState = 0;
digitalWrite(ledPin,LOW);
noTone(buzzerPin);
warnTimer = millis() + 500;
}
}
}
}
int myMovement = 0;
unsigned long pirTimer;
int pirScanDelay = 100;//time in milliseconds until the next pir scan takes place
//pir
//function is now controlled by a millis() timer
void pirScan(){
if(millis() > pirTimer){
pirTimer = millis() + pirScanDelay;
myMovement = digitalRead(pirPin);
//Serial.println(myMovement);
}
}
//this function controls what is happening
unsigned long controlTimer;
int controlState; //0 = no movement, 1 = movement prompt keypad, 2 = alarm sound, 3 = disarmed
void alarmControl(){
if(myMovement > 0){//movement detected
Serial.print("controlState: ");
Serial.println(controlState);
switch(controlState){
case 0://if no movement this is a new moment detected...warn to enter code
if(millis() > controlTimer){
controlState = 1;
controlTimer = millis() + 5000;//5 seconds to enter a code
soundWarn = 1;
soundAlarm = 0;
}
break;
case 1://ongoing movement... no code entered
if(millis() > controlTimer){
controlTimer = millis() + 20000;//alarm to sound 20 seconds
controlState = 2;
soundWarn = 0;
soundAlarm = 1;
}
break;
case 2://alarm is sounding
if(millis() > controlTimer){// if the alarm has been sounding for 20 secs...give neigbours a break
controlTimer = millis() + 10000;//10 second break in the noise
controlState = 0;//start again...could be set to 1 to prompt keycode
}
break;
default:
Serial.println("Error...invalid state");
break;
}
}else{//turn any sounds or leds off as no movement
digitalWrite(ledPin,LOW);
noTone(buzzerPin);
soundWarn = 0; //warning off
soundAlarm = 0; //alarm off
controlState = 0;
}
}
void setup() {
Serial.begin(9600);
Serial.println("alarmSystemv1...");
pinMode(buzzerPin,OUTPUT);
pinMode(ledPin,OUTPUT);
pinMode(pirPin,INPUT);
}
void loop() {
pirScan();//checks for movement
alarmControl();//functino controls the system state
myAlarm();//sets alarm sound off
myWarn();//sets passcode warning sound
}
Example 5: alarmSystemv2.ino
The final part was to add in the keypad monitoring system.. This all takes place in a function called keyInput().
It monitors keypresses with * = reset code, # = enter code.
All other buttons can make up the code.
Entering the wrong code sets off the alarm.
Entering the correct code stops the PIR sensor by changing it's timer to allow 60 seconds of movement to allow the person in through the door.
The keypad function outputs results to the serial monitor but could easily be altered to output to an LCD screen
Click to Download code:alarmSystemv2.ino
/* 25/10/2021
* alarmSystemv2
* Adds the keypad to v1
*
*
*
*
*
* pins
* 2 Keypad
* 3 Keypad
* 4 Keypad
* 5 Keypad
* 6 Keypad
* 7 Keypad
* 8 Keypad
* 9 Keypad
* 11 buzzer
* 12 pir
* 13 led
*/
#include "Keypad.h"
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {9, 8, 7, 6};
byte colPins[COLS] = {5, 4, 3, 2};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
const int buzzerPin = 11;
const int pirPin = 12;
const int ledPin = 13;
int soundAlarm = 0;//0 alarm is off, 1 alarm is on
int alarmState;//used to flash the leds/tone
unsigned long alarmTimer;
int alarmDelay = 1000;
//alarm sounding function
void myAlarm(){
if(soundAlarm > 0){//sound alarm
if(millis() > alarmTimer){
alarmTimer = millis() + alarmDelay;
if(alarmState < 1){
alarmState = 1;
digitalWrite(ledPin,HIGH);
tone(buzzerPin,500);
}else{
alarmState = 0;
digitalWrite(ledPin,LOW);
tone(buzzerPin,1000);
}
}
}
}
int soundWarn = 0;//0 warn is off, 1 warn is on
int warnState;//used to flash the leds/tone
unsigned long warnTimer;
//warning sounding function
void myWarn(){
if(soundWarn > 0){//sound alarm
if(millis() > warnTimer){
if(warnState < 1){
warnState = 1;
digitalWrite(ledPin,HIGH);
tone(buzzerPin,500);
warnTimer = millis() + 100;
}else{
warnState = 0;
digitalWrite(ledPin,LOW);
noTone(buzzerPin);
warnTimer = millis() + 500;
}
}
}
}
int myMovement = 0;
unsigned long pirTimer;
int pirScanDelay = 100;//time in milliseconds until the next pir scan takes place
//pir
//function is now controlled by a millis() timer
void pirScan(){
if(millis() > pirTimer){
pirTimer = millis() + pirScanDelay;
myMovement = digitalRead(pirPin);
//Serial.println(myMovement);
}
}
//this function controls what is happening
unsigned long controlTimer;
int controlState; //0 = no movement, 1 = movement prompt keypad, 2 = alarm sound, 3 = disarmed
void alarmControl(){
if(myMovement > 0){//movement detected
//Serial.print("controlState: ");
//Serial.println(controlState);
switch(controlState){
case 0://if no movement this is a new moment detected...warn to enter code
if(millis() > controlTimer){
controlState = 1;
controlTimer = millis() + 5000;//5 seconds to enter a code
soundWarn = 1;
soundAlarm = 0;
}
break;
case 1://ongoing movement... no code entered
if(millis() > controlTimer){
controlTimer = millis() + 20000;//alarm to sound 20 seconds
controlState = 2;
soundWarn = 0;
soundAlarm = 1;
}
break;
case 2://alarm is sounding
if(millis() > controlTimer){// if the alarm has been sounding for 20 secs...give neigbours a break
controlTimer = millis() + 10000;//10 second break in the noise
controlState = 0;//start again...could be set to 1 to prompt keycode
}
break;
default:
Serial.println("Error...invalid state");
break;
}
}else{//turn any sounds or leds off as no movement
digitalWrite(ledPin,LOW);
noTone(buzzerPin);
soundWarn = 0; //warning off
soundAlarm = 0; //alarm off
controlState = 0;
}
}
//deal with codes being input
//* = reset
//# = enter
char myPasscode[4] = {'1','2','3','A'};
char inputCode[4]; //the code being input
int codeLength = 4; //change this if you want a lnoger code
int inputCounter;//counts how many chars have been entered
char getKeyPress;
void keyInput(){
int q;
getKeyPress = keypad.getKey();
if (getKeyPress){
//Serial.println(getKeyPress);
if(getKeyPress == '*'){
for(q=0;q < codeLength;q++){
inputCode[q] = ' ';
}
inputCounter = 0;
}else{
if(getKeyPress == '#'){
int myCheck = 0;
for(q=0;q < codeLength;q++){
if(inputCode[q] != myPasscode[q]){
myCheck++;//error so increment
}
}
if(myCheck > 0){//wrong code so sound alarm
controlState = 1;
controlTimer = 0;//go straight to alarm
Serial.println("Invalid Code");
}else{//correct code...turn system off for 60 seconds
Serial.println("Correct Code");
myMovement = 0;
pirTimer = millis() + 60000;//turn pir sensor off for 60 seconds
//reset password input for next person
for(q=0;q < codeLength;q++){
inputCode[q] = ' ';
}
inputCounter = 0;
}
}else{
Serial.println(getKeyPress);
inputCode[inputCounter] = getKeyPress;
Serial.print(inputCode[inputCounter]);
inputCounter++;
if(inputCounter > 3){
inputCounter = 0;
}
}
}
Serial.print("passcode: ");
for(q=0;q < codeLength;q++){
Serial.print(inputCode[q]);
}
Serial.println(" XX ");
}
}
void setup() {
Serial.begin(9600);
Serial.println("alarmSystemv2...");
pinMode(buzzerPin,OUTPUT);
pinMode(ledPin,OUTPUT);
pinMode(pirPin,INPUT);
}
void loop() {
pirScan();//checks for movement
alarmControl();//functino controls the system state
myAlarm();//sets alarm sound off
myWarn();//sets passcode warning sound
keyInput();//deals with keypresses
}
Additional Resource Links
Lesson 3: Using "if else" to control code 19/07/2021
Lesson 7: delay() v's millis(), controlling timing of programs 23/07/2021
Lesson 10: Using Global and Local variables 11/08/2021
Lesson 11: Arrays 28/08/2021
Functions 1 : digitalWrite() Using digital pins to turn things on and off 05/08/2021
Functions 2 : digitalRead() Reading a digital pin and pullup resistors 11/08/2021
Comments
This site has been designed to be child friendly, this means that comments cannot be added to videos or directly to the site. To add a comment or ask a question please email the address in this image: and use How To 4 - Creating a Project as a reference.