Hardware components | ||||||
| × | 2 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 2 | ||||
Software apps and online services | ||||||
| ||||||
|
My partner and I decided to create a dryer temperature and power sensor after thinking of more practical uses of a temperature sensor than just reading the ambient temperature. Not only is measuring the power consumption and temperature of a dryer a neat gimmick, but it has practical applications as well. For industrial purposes, it can help to measure the overall efficiency of the system with a relatively cost effective method. The temperature sensor works by using a DHT11 temperature sensor connected to a particle argon and sticking it into the dryer exhaust vent. The DHT11 measures the temperature while the argon records the data and publishes it to a Thingspeak page located here Temperature - ThingSpeak IoT. To measure the power consumption of the dryer, an ammeter is used. The ammeter works by using a DFRobot Analog AC Current sensor which can measure the current from a wire and convert it to voltage so the argon can read it. The argon converts the voltage reading from the current sensor and then converts it back to current and publishes the data to the same Thingspeak page. By using two sensors we are able to see which sensor is the most accurate and also which one will require less maintenance for long periods of time. The combination of two sensors gives the advantage of trouble shooting one or the other. If one sensors goes out or stops publishing data, you are able to catch it by the use of the other sensor.
Argon Temperature Sensor
Current Sensor
// This #include statement was automatically added by the Particle IDE.
#include <Adafruit_DHT.h>
#define DHTPIN D2
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(9600);
dht.begin(); // initialize the sensor
// Subscribe to the integration response event
Particle.subscribe("hook-response/Temperature", myHandler, MY_DEVICES);
Particle.subscribe("Current", AC, MY_DEVICES); // subscribe to the current sensor
pinMode(D7, OUTPUT);
}
void myHandler(const char *event, const char *data) {
// Handle the integration response
}
void AC(const char *event, const char *data){
digitalWrite(D7,HIGH); // turn on the D7 LED whenever data is being sent
}
void loop() {
// read temperature as Celsius
float tempC = dht.getTempCelcius();
// read temperature as Fahrenheit
float tempF = dht.getTempFarenheit();
Serial.print("Temperature: ");
Serial.print(tempC);
Serial.print("°C ~ ");
Serial.print(tempF);
Serial.println("°F");
// Get some data
String data = String(tempF);
String Celsius = String(tempC);
// Trigger the integration
Particle.publish("Temperature", data, PRIVATE);
// Wait 20 seconds
delay(20000);
}
const int ACPin = A2; //set argon signal read pin
#define ACTectionRange 20; //set Non-invasive AC Current Sensor tection range (5A,10A,20A)
// VREF: Analog reference
// For Argon UNO, Leonardo and mega2560, etc. change VREF to 5
// For Argon Zero, Due, MKR Family, ESP32, etc. 3V3 controllers, change VREF to 3.3
#define VREF 5.0
float readACCurrentValue()
{
float ACCurrtntValue = 0;
float peakVoltage = 0;
float voltageVirtualValue = 0; //Vrms
for (int i = 0; i < 5; i++)
{
peakVoltage += analogRead(ACPin); //read peak voltage
delay(1);
}
peakVoltage = peakVoltage / 5;
voltageVirtualValue = peakVoltage * 0.707; //change the peak voltage to the Virtual Value of voltage
/*The circuit is amplified by 2 times, so it is divided by 2.*/
voltageVirtualValue = (voltageVirtualValue / 1024 * VREF ) / 2;
ACCurrtntValue = voltageVirtualValue * ACTectionRange;
return ACCurrtntValue;
int AC = ACCurrtntValue;
}
void setup()
{
// Subscribe to the integration response event
Particle.subscribe("hook-response/Current", myHandler, MY_DEVICES);
Particle.subscribe("Temperature", tempF, MY_DEVICES);
pinMode(D7, OUTPUT);
}
void myHandler(const char *event, const char *data) {
// Handle the integration response
}
void tempF(const char *event, const char *data){
digitalWrite(D7,HIGH);
}
void loop()
{
float ACCurrentValue = readACCurrentValue(); //read AC Current Value
Serial.print(ACCurrentValue);
// trigger the integration
Particle.publish("Current", String(ACCurrentValue), PRIVATE);
Serial.println(" A");
// wait 20 seconds
delay(20000);
}
Adafruit_DHT.ccp
C/C++/* DHT library
*
* MIT license
* written by Adafruit Industries
* modified for Spark Core by RussGrue
* */
#include "Adafruit_DHT.h"
DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) {
_pin = pin;
_type = type;
_count = count;
firstreading = true;
}
void DHT::begin(void) {
// set up the pins!
pinMode(_pin, INPUT);
pinSetFast(_pin);
_lastreadtime = 0;
}
float DHT::readTemperature() {
float f;
if (read()) {
switch (_type) {
case DHT11:
f = data[2];
return f;
case DHT22:
case DHT21:
f = data[2] & 0x7F;
f *= 256;
f += data[3];
f /= 10;
if (data[2] & 0x80)
f *= -1;
return f;
}
}
return NAN;
}
float DHT::getHumidity() {
return readHumidity();
}
float DHT::getTempCelcius() {
return readTemperature();
}
float DHT::getTempFarenheit() {
return convertCtoF(readTemperature());
}
float DHT::getTempKelvin() {
return convertCtoK(readTemperature());
}
float DHT::getHeatIndex() {
return convertFtoC(computeHeatIndex(convertCtoF(readTemperature()), readHumidity()));
}
float DHT::getDewPoint() {
return computeDewPoint(readTemperature(), readHumidity());
}
float DHT::convertFtoC(float f) {
return (f - 32) * 5 / 9;
}
float DHT::convertCtoF(float c) {
return c * 9 / 5 + 32;
}
float DHT::convertCtoK(float c) {
return c + 273.15;
}
float DHT::readHumidity(void) {
float f;
if (read()) {
switch (_type) {
case DHT11:
f = data[0];
return f;
case DHT22:
case DHT21:
f = data[0];
f *= 256;
f += data[1];
f /= 10;
return f;
}
}
return NAN;
}
float DHT::computeHeatIndex(float tempFahrenheit, float percentHumidity) {
// Adapted from equation at: https://github.com/adafruit/DHT-sensor-library/issues/9 and
// Wikipedia: http://en.wikipedia.org/wiki/Heat_index
return -42.379 +
2.04901523 * tempFahrenheit +
10.14333127 * percentHumidity +
-0.22475541 * tempFahrenheit * percentHumidity +
-0.00683783 * pow(tempFahrenheit, 2) +
-0.05481717 * pow(percentHumidity, 2) +
0.00122874 * pow(tempFahrenheit, 2) * percentHumidity +
0.00085282 * tempFahrenheit * pow(percentHumidity, 2) +
-0.00000199 * pow(tempFahrenheit, 2) * pow(percentHumidity, 2);
}
float DHT::computeDewPoint(float tempCelcius, float percentHumidity) {
double a = 17.271;
double b = 237.7;
double tC = (a * (float) tempCelcius) / (b + (float) tempCelcius) + log( (float) percentHumidity / 100);
double Td = (b * tC) / (a - tC);
return Td;
}
boolean DHT::read(void) {
uint8_t laststate = HIGH;
uint8_t counter = 0;
uint8_t j = 0, i;
unsigned long currenttime;
// Check if sensor was read less than two seconds ago and return early
// to use last reading.
currenttime = millis();
if (currenttime < _lastreadtime) {
// ie there was a rollover
_lastreadtime = 0;
}
if (!firstreading && ((currenttime - _lastreadtime) < 2000)) {
return true; // return last correct measurement
// delay(2000 - (currenttime - _lastreadtime));
}
firstreading = false;
/*
Serial.print("Currtime: "); Serial.print(currenttime);
Serial.print(" Lasttime: "); Serial.print(_lastreadtime);
*/
_lastreadtime = millis();
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
// pull the pin high and wait 250 milliseconds
pinSetFast(_pin);
delay(250);
// now pull it low for ~20 milliseconds
pinMode(_pin, OUTPUT);
pinResetFast(_pin);
delay(20);
noInterrupts();
pinSetFast(_pin);
delayMicroseconds(40);
pinMode(_pin, INPUT);
// read in timings
for ( i=0; i< MAXTIMINGS; i++) {
counter = 0;
while (pinReadFast(_pin) == laststate) {
counter++;
delayMicroseconds(1);
if (counter == 255) {
break;
}
}
laststate = pinReadFast(_pin);
if (counter == 255) break;
// ignore first 3 transitions
if ((i >= 4) && (i%2 == 0)) {
// shove each bit into the storage bytes
data[j/8] <<= 1;
if (counter > _count)
data[j/8] |= 1;
j++;
}
}
interrupts();
/*
Serial.println(j, DEC);
Serial.print(data[0], HEX); Serial.print(", ");
Serial.print(data[1], HEX); Serial.print(", ");
Serial.print(data[2], HEX); Serial.print(", ");
Serial.print(data[3], HEX); Serial.print(", ");
Serial.print(data[4], HEX); Serial.print(" =? ");
Serial.println(data[0] + data[1] + data[2] + data[3], HEX);
*/
// check we read 40 bits and that the checksum matches
if ((j >= 40) &&
(data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF)) ) {
return true;
}
return false;
}
Adafruit_DHT.h
C/C++/* DHT library
*
* MIT license
* written by Adafruit Industries
* modified for Spark Core by RussGrue
* */
#ifndef DHT_H
#define DHT_H
#include "application.h"
#include "math.h"
// how many timing transitions we need to keep track of. 2 * number bits + extra
#define MAXTIMINGS 85
#define DHT11 11
#define DHT22 22
#define DHT21 21
#define AM2301 21
class DHT {
private:
uint8_t data[6];
uint8_t _pin, _type, _count;
unsigned long _lastreadtime;
boolean firstreading;
float readTemperature();
float convertFtoC(float);
float convertCtoF(float);
float convertCtoK(float);
float computeHeatIndex(float tempFahrenheit, float percentHumidity);
float computeDewPoint(float tempCelcius, float percentHumidity);
float readHumidity(void);
boolean read(void);
public:
DHT(uint8_t pin, uint8_t type, uint8_t count=6);
void begin(void);
float getHumidity();
float getTempCelcius();
float getTempFarenheit();
float getTempKelvin();
float getHeatIndex();
float getDewPoint();
};
#endif
Comments