/************************************************************************************************************************************************************************
*************************************************************************************************************************************************************************
** Written By: Jesse Laprad **
** **
** This code is to be used with _3171_Extra_Credit_Slave_Photon. **
** **
** The purpose of this project is to use an Arduino Mega with an mpr121 capacitive touch sheild to disarm a door when the correct password is entered. **
** If the door is opened while an incorrect password is input, a signal is sent over the 315 MHz RF transmitter and recieved by the particle photon. **
** A Magnetic reed switch, located on the door hinge, senses the door is opened, tripping the reed switch. If tripped, a photoresistor and **
** temperature sensor are both checked in order to determine weather or not the light or fan needs to be turned on via relays. **
** **
** The remaining processes will be carried out on the _3171_Extra_Credit_Slave microcontroller. A Particle Photon board will use the 315 MHz RF reciever to recieve **
** the open door signal from the Arduino Uno. If the correct password was not entered, The Particle will then publish this event to the dashboard. **
** Using IFTT, when the event has been published, a text message is sent to the related phone to alert the user that the door has been opened. **
** **
** **
** Many segments of this code and the associated libraries have been developed by others and will be cited here: **
** Temperature sensor: https://github.com/PaulStoffregen/OneWire **
** 315MHz RF:https://github.com/mchr3k/arduino-libs-manchester **
** mpr121 touch sheild: https://code.google.com/archive/p/midtermchip-alexrush/ **
** **
*************************************************************************************************************************************************************************
************************************************************************************************************************************************************************/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*
+-----+
+----[PWR]-------------------| USB |--+
| +-----+ |
| GND/RST2 [ ] [ ] |
| MOSI2/SCK2 [ ] [ ] SCL[ ] | D0
| 5V/MISO2 [ ] [ ] SDA[ ] | D1
| AREF[ ] |
| GND[ ] |
| [ ]N/C 13[ ]~| B7
| [ ]IOREF 12[ ]~| B6 *MPR 121 Capacitive Touch Sheild on pins: N/C-A5 and SCL to RX0*
| [ ]RST 11[ ]~| B5
| [ ]3V3 +----------+ 10[ ]~| B4
| [ ]5v | ARDUINO | 9[ ]~| H6
| [ ]GND | MEGA | 8[ ]~| H5
| [ ]GND +----------+ |
| [ ]Vin 7[ ]~| H4
| 6[ ]~| H3
| [ ]A0 5[ ]~| E3
| [ ]A1 4[ ]~| G5
| [ ]A2 INT5/3[ ]~| E5
| [ ]A3 INT4/2[ ]~| E4
| [ ]A4 TX>1[ ]~| E1
| [ ]A5 RX<0[ ]~| E0
| [ ]A6 |
| [ ]A7 TX3/14[ ] | J1
| RX3/15[ ] | J0
| [ ]A8 TX2/16[ ] | H1
| [ ]A9 RX2/17[ ] | H0
| [ ]A10 TX1/INT3/18[ ] | D3
| [ ]A11 RX1/INT2/19[ ] | D2
| [ ]A12 I2C-SDA/INT1/20[ ] | D1
| [ ]A13 I2C-SCL/INT0/21[ ] | D0
| [ ]A14 |
LDR----> | [ ]A15 | Ports:
| RST SCK MISO | 22=315MHz RF transmitter 23=N/A
| ICSP [ ] [ ] [ ] | 24=Door Magnetic Reed switch 25=Door Switch Check LED
| [ ] [ ] [ ] | 26=N/A 27=N/A
| GND MOSI 5V | 28=Correct Password Green LED 29=N/A
| G | 30=Incorrect Password Red LED 31=N/A
| N 5 5 4 4 4 4 4 3 3 3 3 3 2 2 2 2 5 | 32=N/A 33=N/A
| D 2 0 8 6 4 2 0 8 6 4 2 0 8 6 4 2 V | 34=N/A 35=N/A
| ~ ~ | 36=N/A 37=N/A
| @ # # # # # # # # # # # # # # # # @ | 38=N/A 39=N/A
| @ # # # # # # # # # # # # # # # # @ | 40=DS18S20 Temp sens 41=Fan Relay
| ~ | 42=N/A 43=Light Relay
| G 5 5 4 4 4 4 4 3 3 3 3 3 2 2 2 2 5 | 44=N/A 45=N/A
| N 3 1 9 7 5 3 1 9 7 5 3 1 9 7 5 3 V | 46=N/A 47=N/A
| D | 48=N/A 49=N/A
| | 50=N/A 51=N/A
| 2560 ____________/ 52=N/A 53=N/A
\_______________________/
+-----+
+----------| USB |----------+
| +-----+ * |
| [ ] VIN 3V3 [ ] |
| [ ] GND RST [ ] |
| [ ] TX VBAT [ ] |
| [ ] RX [S] [R] GND [ ] |
| [ ] WKP D7 [*] |<-------------315MHz RF Reciever
| [ ] DAC +-------+ D6 [*] |<-------------DS18S20 Temp sens
| [ ] A5 | * | D5 [ ] |
| [ ] A4 |Photon | D4 [ ] |
| [ ] A3 | | D3 [ ] |
| [ ] A2 +-------+ D2 [ ] |
| [ ] A1 D1 [*] |<-------------Fan Relay
Photoresistor-------->| [*] A0 D0 [*] |<-------------Light Relay
| |
\ [] [______] /
\_______________________/
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////*/
//Including Libraries for all components
//315MHz RF lib
#include <Manchester.h>
//mpr121 touch sheild libs
#include "mpr121.h"
#include "i2c.h"
#include <OneWire.h>
float tempSense();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Defining preprocessor symbolic constants
//Touch Sheild
// 11 max digits used
#define DIGITS 11
// Match key inputs with electrode numbers
#define ONE 8
#define TWO 5
#define THREE 2
#define FOUR 7
#define FIVE 4
#define SIX 1
#define SEVEN 6
#define EIGHT 3
#define NINE 0
#define TX_PIN 22 //pin where your transmitter is connected
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//defining global variables
//interupt pin for touch sheild
int irqPin = 2; // D2
//Defining the Code
char MyCode[] = {'1', '2', '3', '4'}; //<===================================PASSWORD
char Pressed[] = {'15', '15', '15', '15'};
int touchcount = 0; //a count for how many buttons have been pressed
boolean Code = false;
boolean flashing = false;
//Assigns door switch to pin 24
const int DoorSwitchPin = 24;
const int DoorLED = 25;
const int KeyLEDGreen = 28;
const int KeyLEDRed = 30;
const int fanRelay = 41;
const int lightRelay = 43;
int lightPin = 15; //define a pin for Photo resistor
OneWire ds(40); // on pin 40 (a 4.7K resistor is necessary)
uint16_t transmit_data = 0;
/*********************************************************************************************************************************************************
**********************************************************************************************************************************************************
********************************************************************************************************************************************************/
void setup() {
//////////////////////////////////////////////////////////////
// TOUCH SHEILD SETUP ////////////////////////////////////////
//////////////////////////////////////////////////////////////
//make sure the interrupt pin is an input and pulled high
pinMode(irqPin, INPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
digitalWrite(irqPin, HIGH);
//configure serial out
Serial.begin(9600);
//output on ADC4 (PC4, SDA)
DDRC |= 0b00010011;
// Pull-ups on I2C Bus
PORTC = 0b00110000;
// initalize I2C bus. Wiring lib not used.
i2cInit();
delay(100);
// initialize mpr121
mpr121QuickConfig();
// Create and interrupt to trigger when a button
// is hit, the IRQ pin goes low, and the function getNumber is run.
attachInterrupt(0, getNumber, LOW);
// prints 'Ready...' when you can start hitting numbers
Serial.println("Ready...");
///////////////////////////////////////////////////////////////////////
// DOOR SWITCH SETUP //////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
pinMode(DoorSwitchPin, INPUT);
digitalWrite(DoorSwitchPin, HIGH);
pinMode(DoorLED, OUTPUT);
digitalWrite(DoorLED, LOW);
pinMode(KeyLEDRed, OUTPUT);
digitalWrite(KeyLEDRed, LOW);
pinMode(KeyLEDGreen, OUTPUT);
digitalWrite(KeyLEDGreen, LOW);
pinMode(fanRelay, OUTPUT);
digitalWrite(fanRelay, LOW);
pinMode(lightRelay, OUTPUT);
digitalWrite(lightRelay, LOW);
///////////////////////////////////////////////////////////////////////
// RF Transmitter SETUP ///////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
// Initialize the IO and ISR
man.setupTransmit(TX_PIN, MAN_1200);
}
void loop() {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;
if ( !ds.search(addr)) {
//Serial.println("No more addresses.");
//Serial.println();
ds.reset_search();
}
//Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
//Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
// Serial.println("CRC is not valid!");
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
//Serial.println(" Chip = DS18S20"); // or old DS1820
type_s = 1;
break;
case 0x28:
//Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
// Serial.println(" Chip = DS1822");
type_s = 0;
break;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(200); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
//Serial.print(" Data = ");
// Serial.print(present, HEX);
//Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
//Serial.print(data[i], HEX);
//Serial.print(" ");
}
//Serial.print(" CRC=");
//Serial.print(OneWire::crc8(data, 8), HEX);
//Serial.println();
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
if ((MyCode[0] == Pressed[0]) && (MyCode[1] == Pressed[1]) && (MyCode[2] == Pressed[2]) && (MyCode[3] == Pressed[3]) && (touchcount % 4 == 0)) {
Code = true;
}
else {
Code = false;
}
//checks to see if password is correct after every 4 keys entered
if ((touchcount % 4 == 0) && (Code == false) && (touchcount > 0)) { ///if password is incorrect
flashing = true;
for (int i = 0; i < 4; i++) { //flash led on/off 4 times
digitalWrite(KeyLEDRed, HIGH);
delay(500);
digitalWrite(KeyLEDRed, LOW);
}
touchcount = 0;
flashing = false;
}
else if ((touchcount % 4 == 0) && (Code == true)) { //if the password is correct
digitalWrite(KeyLEDGreen, HIGH);
if (digitalRead(DoorSwitchPin) == HIGH)
{
digitalWrite(DoorLED, HIGH);
if(fahrenheit > 82)
{
digitalWrite(fanRelay, HIGH);
}
else
digitalWrite(fanRelay, LOW);
if(analogRead(lightPin) < 300)
{
digitalWrite(lightRelay, HIGH);
}
else
digitalWrite(lightRelay, LOW);
}
else if(digitalRead(DoorSwitchPin) == LOW)
{
digitalWrite(DoorLED, LOW);
digitalWrite(fanRelay, LOW);
digitalWrite(lightRelay, LOW);
}
}
else { //if no code was entered
digitalWrite(KeyLEDGreen, LOW);
if (digitalRead(DoorSwitchPin) == HIGH)
{
transmit_data = 1;
digitalWrite(DoorLED, HIGH);
man.transmit(transmit_data);
if(fahrenheit > 75)
{
digitalWrite(fanRelay, HIGH);
}
else
digitalWrite(fanRelay, LOW);
if(analogRead(lightPin) < 300)
{
digitalWrite(lightRelay, HIGH);
}
else
digitalWrite(lightRelay, LOW);
}
else if(digitalRead(DoorSwitchPin) == LOW)
{
transmit_data = 0;
digitalWrite(DoorLED, LOW);
man.transmit(transmit_data);
digitalWrite(fanRelay, LOW);
digitalWrite(lightRelay, LOW);
}
}
Serial.println(analogRead(lightPin));
}
void getNumber()
{
if (flashing == false) {
int i = 0;
int touchNumber = 0;
uint16_t touchstatus;
char digits[DIGITS];
touchstatus = mpr121Read(0x01) << 8;
touchstatus |= mpr121Read(0x00);
for (int j = 0; j < 12; j++) // Check how many electrodes were pressed
{
if ((touchstatus & (1 << j)))
touchNumber++;
}
if (touchNumber == 1)
{
touchcount++;
if (touchstatus & (1 << SEVEN)) {
for (int i = 0; i < 3; i++) {
Pressed[i] = Pressed[i + 1];
}
Pressed[3] = '7';
digits[i] = '7';
}
else if (touchstatus & (1 << FOUR)) {
for (int i = 0; i < 3; i++) {
Pressed[i] = Pressed[i + 1];
}
Pressed[3] = '4';
digits[i] = '4';
}
else if (touchstatus & (1 << ONE)) {
for (int i = 0; i < 3; i++) {
Pressed[i] = Pressed[i + 1];
}
Pressed[3] = '1';
digits[i] = '1';
}
else if (touchstatus & (1 << EIGHT)) {
for (int i = 0; i < 3; i++) {
Pressed[i] = Pressed[i + 1];
}
Pressed[3] = '8';
digits[i] = '8';
}
else if (touchstatus & (1 << FIVE)) {
for (int i = 0; i < 3; i++) {
Pressed[i] = Pressed[i + 1];
}
Pressed[3] = '5';
digits[i] = '5';
}
else if (touchstatus & (1 << TWO)) {
for (int i = 0; i < 3; i++) {
Pressed[i] = Pressed[i + 1];
}
Pressed[3] = '2';
digits[i] = '2';
}
else if (touchstatus & (1 << NINE)) {
for (int i = 0; i < 3; i++) {
Pressed[i] = Pressed[i + 1];
}
Pressed[3] = '9';;
digits[i] = '9';
}
else if (touchstatus & (1 << SIX)) {
for (int i = 0; i < 3; i++) {
Pressed[i] = Pressed[i + 1];
}
Pressed[3] = '6';
digits[i] = '6';
}
else if (touchstatus & (1 << THREE)) {
for (int i = 0; i < 3; i++) {
Pressed[i] = Pressed[i + 1];
}
Pressed[3] = '3';
digits[i] = '3';
}
Serial.print(digits[i]);
i++;
}
//do nothing if more than one button is pressed
else if (touchNumber == 0)
;
else
;
}
}
Comments