# Con Duction

A thermal comparison tool that actuates a vent when dwellers are in its proximity.

0

## Problem:

My parents' house has a pretty antiquated ventilation system, resulting in drastic temperature differences on each floor. Whether doing chores, using the computer, or watching TV, they can stay in the finished basement for a sustained period of time. It can be stressful, especially when they care about the other floor temperatures as well.

The vent is the main problem, as it focuses heat, and can only be fully opened or closed. The vent can a hassle and easily forgotten until the difference is so great, the ventilation system cannot overcome the disparity, making for an uncomfortable home environment.

0

## Objectives:

- Device shall measure the ambient temperature in degrees Fahrenheit

- Device shall detect proximate motion and store such status for a period of time, indicating that a user is operating in its area

- Device shall visually indicate that motion is currently being detected

- Device must message the user that a significant temperature differential has been detected

- Device must not consecutively take action and message the user within a short period

0

## Process:

### Step 1:

- Wired the thermal sensor to D0 pin

0

- Laid out general framework of code

0
``````/*
* Project Thermal-Compare
* Description:
* Author: Nicholas Stone
* Date: 1/29/2017
* Version: 1
*/

#include "OneWire.h"
#include "spark-dallas-temperature.h"

//instances
OneWire oneWire(D0);
DallasTemperature dallas(&oneWire);

//vars
// double tempC = 0.0;
double tempF = 0.0;

void setup() {
//Register
// Particle.variable("tempC", &tempC, DOUBLE);
Particle.variable("tempF", &tempF, DOUBLE);

//start library
dallas.begin();

}

void loop() {
//request conversion
dallas.requestTemperatures();

//get temperature in Celsius and convert to Fahrenheit
tempF = (double)DallasTemperature::toFahrenheit(dallas.getTempCByIndex(0));

delay(5000);

}``````
Click to Expand
0

### Step 2:

- Wire PIR Sensor to D1

0
``````/*
* Project Thermal-Compare
* Description:
* Author: Nicholas Stone
* Date: 1/29/2017
* Version: 2
*/

#include "OneWire.h"
#include "spark-dallas-temperature.h"

//instances
OneWire oneWire(D0);
DallasTemperature dallas(&oneWire);

//vars
// double tempC = 0.0;
int tempF = 0;
int MasterTempF = 70;
int MaxTempDiff = 1;
//Sample Rate est (Loop Rate)
int sampleRate = 5000;
//Burst Rate of published messages (15 minutes)
int burstRate = 900000;
int timeSincePublish= 900000;

int motionPin = D1;
int motionValue = 0;
int motionState = 0;
int motionRate = 900000;
int timeSinceMotion = 0;

//LED
int ledPin = D2;

void setup() {
//Register
// Particle.variable("tempC", &tempC, DOUBLE);
Particle.variable("tempF", &tempF, INT);
//Particle.variable("motion",&motionValue,INT);
//Particle.variable("tSincePublish",&timeSincePublish,INT);
Particle.variable("tSinceMotion",&timeSinceMotion,INT);
Particle.variable("motionStatus",&motionState,INT);

pinMode(motionPin, INPUT);
pinMode(ledPin, OUTPUT);

//start library
dallas.begin();

}

void loop() {
//check motion
if(motionValue == 1) {
motionState = 1;
timeSinceMotion = 0;
digitalWrite(ledPin, HIGH);
} else{if(timeSinceMotion>=motionRate) {
motionState = 0;
digitalWrite(ledPin, LOW);
} else {
timeSinceMotion = timeSinceMotion + sampleRate;
digitalWrite(ledPin, LOW);
}
}

//request conversion
dallas.requestTemperatures();

//get temperature in Celsius and convert to Fahrenheit
tempF = (int)DallasTemperature::toFahrenheit(dallas.getTempCByIndex(0));

//check if difference exceeds configuration and enough time has passed since the last publication
if(abs(tempF - MasterTempF)>MaxTempDiff && timeSincePublish>=burstRate){
Particle.publish("TempDiffExceeded", "true");
// reset burst rate time counter
timeSincePublish = 0;
}

timeSincePublish = timeSincePublish + sampleRate;
delay(sampleRate);

}``````
Click to Expand
0

- Included Motion consideration in code

- Added framework for messaging (tested phone call, found it too annoying, migrated to email)

- Included LED light for later indication that motion was currently detected

0

### Step 3:

- Wire LED to PIR Sensor Output, D2

- Wire early prototype of half-rotation mini-servo

0
``````/*
* Project Thermal-Compare
* Description:
* Author: Nicholas Stone
* Date: 1/29/2017
* Version: 3
*/

#include "OneWire.h"
#include "spark-dallas-temperature.h"

//instances
OneWire oneWire(D0);
DallasTemperature dallas(&oneWire);

//vars
// double tempC = 0.0;
int tempF = 0;
int MasterTempF = 80;
int MaxTempDiff = 1;
//Sample Rate est (Loop Rate)
int sampleRate = 1000;
//Burst Rate of published messages (15 minutes)
int burstRate = 900000;
int timeSincePublish= 900000;

int motionPin = D1;
int motionValue = 0;
int motionState = 0;
int motionRate = 900000;
int timeSinceMotion = 0;

//LED
int ledPin = D2;

//Fan / Servo
int servoPin = D3;
Servo fanServo;
int servoPos = 0;

void setup() {
//Register
// Particle.variable("tempC", &tempC, DOUBLE);
Particle.variable("tempF", &tempF, INT);
//Particle.variable("motion",&motionValue,INT);
//Particle.variable("tSincePublish",&timeSincePublish,INT);
Particle.variable("tSinceMotion",&timeSinceMotion,INT);
//Particle.variable("motionStatus",&motionState,INT);

pinMode(motionPin, INPUT);
pinMode(ledPin, OUTPUT);

fanServo.attach(D3);

//start library
dallas.begin();

}

void loop() {
//check motion
if(motionValue == 1) {
motionState = 1;
timeSinceMotion = 0;
digitalWrite(ledPin, HIGH);
} else{if(timeSinceMotion>=motionRate) {
motionState = 0;
digitalWrite(ledPin, LOW);
} else {
timeSinceMotion = timeSinceMotion + sampleRate;
digitalWrite(ledPin, LOW);
}
}

//request conversion
dallas.requestTemperatures();

//get temperature in Celsius and convert to Fahrenheit
tempF = (int)DallasTemperature::toFahrenheit(dallas.getTempCByIndex(0));

//check if difference exceeds configuration and enough time has passed since the last publication
if(abs(tempF - MasterTempF)>MaxTempDiff && timeSincePublish>=burstRate
//&& motionState == 0
)
{
Particle.publish("TempDiffExceeded", "true");
// reset burst rate time counter
timeSincePublish = 0;

//run fan
fanServo.write(90);
fanServo.write(0);
fanServo.write(90);
fanServo.write(0);
}

timeSincePublish = timeSincePublish + sampleRate;
delay(sampleRate);

}

/*int fanControl(INT inAngle)
{
servoPos = constrain(inAngle,0,180);
fanServo.write(servoPos);

return 1;
}*/``````
Click to Expand
0

## Outcome:

Below is the final circuit design and code.

0

When the temperature differential exceeds the threshold and motion has been detected, the servo rotates (6s for effect) and emails the user as to the situation

0
``````/*
* Project Thermal-Compare
* Description:
* Author: Nicholas Stone
* Date: 1/29/2017
* Version: 4
*/

#include "OneWire.h"
#include "spark-dallas-temperature.h"

#include "glcdfont.h"

//instances
OneWire oneWire(D2);
DallasTemperature dallas(&oneWire);

//vars
int tempF = 0;
int MasterTempF = 70;
int MaxTempDiff = 5;
//Sample Rate est (Loop Rate)
int sampleRate = 1000;
//Burst Rate of published messages (15 minutes)
int burstRate = 900000;
int timeSincePublish= 0;

int motionPin = D5;
int motionValue = 0;
int motionState = 0;
int motionRate = 900000;
int timeSinceMotion = 0;

//LED
int ledPin = D4;

//Fan / Servo
int servoPin = D3;
Servo fanServo;

//LED Array

void setup() {

Particle.variable("tempF", &tempF, INT);
Particle.variable("motionStatus",&motionState,INT);

//negates burstRate at startup
timeSincePublish = burstRate;

pinMode(motionPin, INPUT);
pinMode(ledPin, OUTPUT);

fanServo.attach(servoPin);

//start interface
ledMatrix.begin(0x70);
ledMatrix.setCursor(0,0);

//start library
dallas.begin();

}

void loop() {

//check motion, run low if no motion after set time
if(motionValue == 1) {
motionState = 1;
timeSinceMotion = 0;
digitalWrite(ledPin, HIGH);
} else{if(timeSinceMotion>=motionRate) {
motionState = 0;
digitalWrite(ledPin, LOW);
} else {
timeSinceMotion = timeSinceMotion + sampleRate;
digitalWrite(ledPin, LOW);
}
}

//request conversion
dallas.requestTemperatures();

//get temperature in Celsius and convert to Fahrenheit
tempF = (int)DallasTemperature::toFahrenheit(dallas.getTempCByIndex(0));

ledMatrix.fillRect(2,2, 4,4, LED_ON);
ledMatrix.writeDisplay();

//check if difference exceeds configuration and enough time has passed since the last publication
if(abs(tempF - MasterTempF)>MaxTempDiff && timeSincePublish>=burstRate && motionState == 1
)
{
//Particle.publish("TempPhoneCall","true");
if(tempF<MasterTempF) {
Particle.publish("Colder", "true");
} else {
Particle.publish("Warmer", "true");
}
// reset burst rate time counter
timeSincePublish = 0;
//
ledMatrix.clear();
ledMatrix.print("NO");
ledMatrix.writeDisplay();

//run fan for 10 seconds
fanServo.write(180);
delay(10000);
fanServo.write(91);
}

timeSincePublish = timeSincePublish + sampleRate;
delay(sampleRate);

}``````
Click to Expand
0
Ambient Temperature
0
IFTTT Applets
0

### Final Required Inventory:

- Particle Photon Microcontroller

- Connection Wires

- 2 Prototype Boards

- 3-pin Thermal Sensor (Thermistor)

- 2 kOhm Resistor

- 3-pin PIR Sensor

- Continuous Rotation Servo Motor

- 1 White LED

(Optional / in-Progress) LED 8x8 Array soldered to Adafruit Backpack

0
Servo Actuation
0

Raw Motion Video

0

### Hardware Inspiration:

https://www.wired.com/2015/01/brilliant-air-vents-never-knew-needed/

### Software Inspiration:

The main inspiration used were the following libraries:

Spark Dallas Temperature

OneWire