Microwave Detector, Temperature Sensor, Cooling Fan control


The power consumption of large room fans can be large more than 60W. I noticed we had lots of fans running and often the rooms were unoccupied.

I took this code by Kristian Gohlke and added additional logic for Temperature sensor DHT22 plus a few LEDs to confirm operation.

The unit will power on a FAN using a 433Mhz Remote socket and if there is no one around for 30 mins it powers off the fan. The FAN will turn on again if someone is detected and the apparent temperature is 23 degree C or higher. I could have used temperature only but as the DHT22 has humidity and the library offers an apparent temp which factors in rel humidity I used that.

I've tried some microwave sensors and the RCWL-0516 seems to work well with Arduino and ESP8266 (the RCWL-0516 is 3.3V logic but needs a 5V supply so an Wemos D1 works well as there is a 5V rail and the pins on the ESP8266 operate at 3.3V TTL) The RCWL-0516 is cheap you can get 2 for under $1 USD or £0.71p

Unlike PIR these Radar units do not need line of sight and can penetrate walls, untinted glass which can be a useful characteristic.



/* 
 * //////////////////////////////////////////////////
 * //making sense of the Parallax PIR sensor's output
 * //////////////////////////////////////////////////
 *
 * Switches a LED according to the state of the sensors output pin.
 * Determines the beginning and end of continuous motion sequences.
 *
 * @author: Kristian Gohlke / krigoo (_) gmail (_) com / http://krx.at
 * @date:   3. September 2006 
 * @ Code updated to work with Microwave sensor not PIR (code is the same as the triiger from a RCWL-0516 is the same as a PIR
 *
 * kr1 (cleft) 2006 
 * released under a creative commons "Attribution-NonCommercial-ShareAlike 2.0" license
 * http://creativecommons.org/licenses/by-nc-sa/2.0/de/
 *
 *
 * The Parallax PIR Sensor is an easy to use digital infrared motion sensor module. 
 * (http://www.parallax.com/detail.asp?product_id=555-28027)
 *
 * The sensor's output pin goes to HIGH if motion is present.
 * However, even if motion is present it goes to LOW from time to time, 
 * which might give the impression no motion is present. 
 * This program deals with this issue by ignoring LOW-phases shorter than a given time, 
 * assuming continuous motion is present during these phases.
 * 
 * June 15 2017
 * 
 *   Added code to power on a device for a preset time with retriggering.
 *   The code uses the millis() function and store the time of the last motion
 *   detection. The code waits for no motion for the defined period after this 
 *   time the power is turned off.
 *   
 *   Added code for an extermal Blue LED to show motion sense active
 *   Added code for an external Green LED to show DHT22 reading correctly
 *   Added code to ONLY  switch on if the Temperature is above 23 degrees
 *   Modified the code to use the heat index that works out the apparent temperature 
 *   
 *   "The Heat Index, sometimes referred to as the apparent temperature, 
 *   is a measure of how hot it really feels when relative humidity 
 *   is factored with the actual air temperature."
 *   
 */ 



#include "DHT.h"

#define DHTPIN 7     // what digital pin we're connected to

// Uncomment whatever type you're using!
//#define DHTTYPE DHT11   // DHT 11
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
//#define DHTTYPE DHT21   // DHT 21 (AM2301)

// Connect pin 1 (on the left) of the sensor to +5V
// NOTE: If using a board with 3.3V logic like an Arduino Due connect pin 1
// to 3.3V instead of 5V!
// Connect pin 2 of the sensor to whatever your DHTPIN is
// Connect pin 4 (on the right) of the sensor to GROUND
// Connect a 10K resistor from pin 2 (data) to pin 1 (power) of the sensor

// Initialize DHT sensor.
// Note that older versions of this library took an optional third parameter to
// tweak the timings for faster processors.  This parameter is no longer needed
// as the current DHT reading algorithm adjusts itself to work on faster procs.
DHT dht(DHTPIN, DHTTYPE);

#include
RCSwitch mySwitch = RCSwitch();

 void(* resetFunc) (void) = 0;//declare reset function at address 0
/////////////////////////////
//VARS
//the time we give the sensor to calibrate (10-60 secs according to the datasheet)
int calibrationTime = 6;        

//the time when the sensor outputs a low impulse
long unsigned int lowIn;         
long unsigned int elapsed=0;  

//the amount of milliseconds the sensor has to be low 
//before we assume all motion has stopped
long unsigned int pause = 5000, powerontime =0,idletime=0 ,idlethreshold=1200;  

boolean lockLow = true;
boolean takeLowTime;  
boolean poweron = false;
boolean warm=false;

int pirPin = 10;    //the digital pin connected to the PIR sensor's output
int ledPin = 13;
int greenLledPin=8;
int blueledPin=9;
float hic=0;


/////////////////////////////
//SETUP
void setup(){

  Serial.begin(9600);

  // Setup the Temperature & Humidity Sensor
  dht.begin();
  
  // Set up Remote Control socket 
  // Transmitter is connected to Arduino Pin #11
  // Use Zero for WeMos Mini D1  Pin D3 = Pin 0 in the IDE
  mySwitch.enableTransmit(11);

  // Define which Pins to use and turn off LEDs
  pinMode(pirPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(greenLledPin, OUTPUT);
  pinMode(blueledPin, OUTPUT);
  digitalWrite(pirPin, LOW);
  digitalWrite(greenLledPin, LOW);
  digitalWrite(blueledPin, LOW);

  //give the Microwave sensor some time to calibrate
  //Flash LEDs during calibration
  Serial.print("Calibrating sensor ");
    for(int i = 0; i < calibrationTime; i++){
      Serial.print(".");
      digitalWrite(greenLledPin, LOW);
      digitalWrite(blueledPin, HIGH);
      delay(1000);
      digitalWrite(greenLledPin, HIGH);
      digitalWrite(blueledPin, LOW);
      }
    Serial.println(" done");
    digitalWrite(greenLledPin, LOW);
     digitalWrite(blueledPin, LOW);
    Serial.println("WMicrowave Sensor: ACTIVE ");
    delay(50);
  }

////////////////////////////
//LOOP

void loop() {
  // Wait a few seconds between measurements.
  delay(2000);

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  digitalWrite(greenLledPin, LOW);
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  float t = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  digitalWrite(greenLledPin, HIGH);
  // Compute heat index in Fahrenheit (the default)
  //float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  hic = dht.computeHeatIndex(t, h, false);

  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.print(" *C ");
 // Serial.print(f);
  //Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hic);
  Serial.println(" *C ");
  if ( hic >23){
    warm=true;
  }
  else{
    warm=false;
  }
//  Serial.print(hif);
//  Serial.println(" *F");

  
     if(digitalRead(pirPin) == HIGH){
       digitalWrite(ledPin, HIGH);   //the led visualizes the sensors output pin state
       digitalWrite(blueledPin, HIGH);   //the led visualizes the sensors output pin state
       if ((poweron==false) && warm){
              poweron=true;
              mySwitch.setProtocol(1);
              mySwitch.setPulseLength(175);
              mySwitch.setRepeatTransmit(7);
              Serial.println("Fan On\n");
              mySwitch.send("000001010101010100110011"); // Fan on
              mySwitch.send("000001010101010100110011"); // Fan on
              delay(2000); 
              Serial.print("Power Switched On at");
              Serial.print(millis()/1000);
              Serial.println(" sec"); 
              powerontime=(millis()/1000);
              Serial.print("powerontime=t");
              Serial.print(powerontime);  
       }
       else
       {
              Serial.print("retriggerd at ");
              Serial.println(millis()/1000);
              powerontime=(millis()/1000);
              Serial.print("powerontime=");
              Serial.println(powerontime);           
       }
       
       idletime=    ((millis()/1000)-powerontime);
       Serial.print("idletime=");
       Serial.println(idletime);      
       
       if(lockLow){  
         //makes sure we wait for a transition to LOW before any further output is made:
         lockLow = false;            
         Serial.println("---");
         Serial.print("motion detected at ");
         Serial.print(millis()/1000);
         Serial.println(" sec"); 
         delay(50);
         }         
         takeLowTime = true;
     }
    

     if(digitalRead(pirPin) == LOW){    


       if (poweron==false){       
       Serial.println("Power off - Waiting for movement..");
       }
     
       digitalWrite(ledPin, LOW);  //the led visualizes the sensors output pin state
       digitalWrite(blueledPin, LOW); 

       if(takeLowTime){
        lowIn = millis();          //save the time of the transition from high to LOW
        takeLowTime = false;       //make sure this is only done at the start of a LOW phase
        }
       //if the sensor is low for more than the given pause, 
       //we assume that no more motion is going to happen
       if(!lockLow && millis() - lowIn > pause){  
           //makes sure this block of code is only executed again after 
           //a new motion sequence has been detected
           lockLow = true;  
           elapsed=   (millis() - pause)/1000;                   
           Serial.print("motion ended at ");      //output
           Serial.print(elapsed );
           Serial.println(" sec");
           delay(50);
          
           }
     }


      if (poweron) {
         idletime=    ((millis()/1000)-powerontime);
            Serial.println("Power ON");
            Serial.print("idletime=");
            Serial.println(idletime);
            if (idletime > idlethreshold ){ 
                poweron=false;
                Serial.print("idletime=");
                Serial.println(idletime);
                idletime=0;
                elapsed=0;
                powerontime=0;
                Serial.println("RF Powered Off");
                mySwitch.setProtocol(1);
                mySwitch.setPulseLength(175);
                mySwitch.setRepeatTransmit(7);
                Serial.println("Fan Off\n");
                mySwitch.send("000001010101010100111100"); // Fan Off
                mySwitch.send("000001010101010100111100"); // Fan Off
                delay(2000);    
                delay(50);
           }
      }
         else
            {
            Serial.println("Power Off");
            }
      
     
      //resetFunc(); //call reset   
    

      delay(3000);  
     
    }