Automatic Room Freshener using nodemcu esp8266

Hi There,

I am new to arduino.Currently i am working project automatic room freshener using nodemcu and dcmotor driver l293d.

I am not good in coding just taken codes from sites, with instruction on it .

I would like to join below two codes.

My objective is that Room freshener should spray if it senses someone in the room using PIR,Also it should follow code 1

Code 1 :

/************************ Adafruit IO Configuration *******************************/

// visit io.adafruit.com if you need to create an account,
// or if you need your Adafruit IO key.
#define IO_USERNAME    "pass"
#define IO_KEY         "key"

/******************************* WIFI Configuration **************************************/

#define WIFI_SSID       "ssid"
#define WIFI_PASS       "pass"

#include "AdafruitIO_WiFi.h"
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);

/************************ Main Program Starts Here *******************************/
#include <ESP8266WiFi.h>
#include <AdafruitIO.h>
#include <Adafruit_MQTT.h>
#include <ArduinoHttpClient.h>
#include "Servo.h"
#include <Adafruit_NeoPixel.h>


#define BUTTON_PIN 14 // Pin connected to the pushbutton

#define PIXELS_PIN 15   // Pin connected to the NeoPixel data input
#define NUM_LEDS   16   // Number of NeoPixels
#define BRIGHTNESS 30
#define PIXEL_TYPE NEO_GRB + NEO_KHZ800   // Type of the NeoPixels (see strandtest example).

Adafruit_NeoPixel ring = Adafruit_NeoPixel(NUM_LEDS, PIXELS_PIN, PIXEL_TYPE);// + NEO_KHZ800);

AdafruitIO_Feed *command = io.feed("IoT Airfreshener Commands"); // set up the 'command' feed

void setup() {
 //Initialize Digital pin 16 as an output
 pinMode(16, OUTPUT);
 ring.setBrightness(BRIGHTNESS);
 ring.begin();
 ring.show(); // Initialize all pixels to 'off'

 // start the serial connection
 Serial.begin(115200);

 // connect to io.adafruit.com
 Serial.print("Connecting to Adafruit IO");
 io.connect();
 
 // set up a message handler for the 'command' feed.
 // the handleMessage function (defined below)
 // will be called whenever a message is
 // received from adafruit io.
 command->onMessage(handleMessage);  

 // wait for a connection
 int i = NUM_LEDS - 1;
 int color = 255;
 // animate LEDs while waiting for connection
 while(io.status() < AIO_CONNECTED) {
   Serial.print(".");
   ring.setPixelColor(i, 0, 0, color);
   ring.show();
   i = i - 1;
   if (i < 0) {
     if (color == 255) {
       color = 0;
     }
     else {
       color = 255;
     }
     i = NUM_LEDS - 1;
   }
   delay(50);
 }
 lightPixels(ring.Color(0, 0, 0, 0)); // reset all pixels to off when connected

 // we are connected
 Serial.println();
 Serial.println(io.statusText());

 // move motor to neutral position
 digitalWrite(16, HIGH);
 delay(1000);
 digitalWrite(16, LOW);
 delay(1000);
 
 // set button pin as an input
 pinMode(BUTTON_PIN, INPUT_PULLUP);

}

void loop() {

 // io.run(); is required for all sketches.
 // it should always be present at the top of your loop
 // function. it keeps the client connected to
 // io.adafruit.com, and processes any incoming data.
 io.run();

 if(digitalRead(BUTTON_PIN) == LOW) {
   command->save("button");
 }

}

// this function is called whenever a message
// is received from Adafruit IO. it was attached to
// the feed in the setup() function above.
void handleMessage(AdafruitIO_Data *data) {
 
 lightPixels(ring.Color(0, 0, 0, 0)); // reset all pixels to off when new info is received

 String commandStr = data->toString(); // store the incoming commands in a string
 
 Serial.print("received <- ");
 Serial.println(commandStr);
 
 // These if statements compare the incoming weather variable to the stored conditions, and control the NeoPixels accordingly.
 
 // if virtual push button was pressed
 if (commandStr.equalsIgnoreCase("button")){
   Serial.println("Virtual push button");
   rotatingPixels(ring.Color(255, 255, 0, 0)); // display animation
   lightPixels(ring.Color(255, 255, 0, 0)); // display animation
   launch(1);
   lightPixels(ring.Color(0, 0, 0, 0)); // reset all pixels to off when new info is received
 }
 
 // if it's time
 if (commandStr.equalsIgnoreCase("timer")){
   Serial.println("it's time");
   rotatingPixels(ring.Color(0, 0, 255, 0)); // display animation
   lightPixels(ring.Color(0, 0, 255, 0)); // display animation
   launch(2);
   lightPixels(ring.Color(0, 0, 0, 0)); // reset all pixels to off when new info is received
 }
 
 
 
 
 } 


// Function to set all the NeoPixels to the specified color.
void lightPixels(uint32_t color) {
 for (int i=0; i<NUM_LEDS; ++i) {
   ring.setPixelColor(i, color);
 }
 ring.show();
}


//Funcion NeoPixels full rotation
void rotatingPixels(uint32_t color) {
 for (int j = 0; j < 3; j++) {
   for (int i=NUM_LEDS-1; i>=0; i--) {
     ring.setPixelColor(i, color);
     ring.show();
     delay(50);
     ring.setPixelColor(i, 0, 0, 0);//ring.Color(0, 0, 0, 255));
     ring.show();
   }
 }
}

//Activate the motor
void launch (int number) {
   for (int i = 0; i < number; i++) {    
   digitalWrite(16, HIGH);
   delay(1000);
   digitalWrite(16, LOW);
   delay(1000);
   digitalWrite(16, HIGH);
   delay(1000);
   digitalWrite(16, LOW); 
 }
 
}

Code 2:

const int pirIn = 13;
int motorPin1 = 16;


void setup(){

pinMode(13, INPUT);
pinMode(16, OUTPUT);
digitalWrite(16, LOW);

}

void loop(){
 int value= digitalRead(13); 
   if (value == HIGH){
     digitalWrite(16, HIGH);
     delay(500); 
     digitalWrite(16, LOW);
   }
}

Please help advice guys,Thanks in advance

Also it should follow code 1

What does THAT mean?

What have you tried? Code 2 is dirt-simple to incorporate into code 1.

Hi,

I have modified and inserted code 2 in to code 1 as follows.Please let me know if its correct.

void loop() {

  // io.run(); is required for all sketches.
  // it should always be present at the top of your loop
  // function. it keeps the client connected to
  // io.adafruit.com, and processes any incoming data.
  
  io.run();

  if(digitalRead(BUTTON_PIN) == LOW) {
    command->save("button");
  }
   else{
  long state = digitalRead(13);
  if(state == HIGH){
    digitalWrite (16,HIGH);
    Serial.println("Motion Detected!");
    rotatingPixels(ring.Color(255, 0, 0,0)); // display animation
    lightPixels(ring.Color(255, 0, 0,0)); // display animation     
    delay(1000);
    lightPixels(ring.Color(0, 0, 0, 0));
  }
    else {
      digitalWrite (16,LOW);
      Serial.println("Motion absent!");
      delay(1000);
    }

}

}

PaulS:
What does THAT mean?

What have you tried? Code 2 is dirt-simple to incorporate into code 1.

Like merging the codes in to single one and The circuit should work based on it

    else {
      digitalWrite (16,LOW);
      Serial.println("Motion absent!");
      delay(1000);
    }

So, if there is no motion, ignore EVERYTHING for one full second. Why on earth would you do that?

PaulS:

    else {

digitalWrite (16,LOW);
      Serial.println("Motion absent!");
      delay(1000);
    }



So, if there is no motion, ignore EVERYTHING for one full second. Why on earth would you do that?

Yes got it,To be frank this is the first time i am working on codes.Is everything else ok

Thanks for the reply.

DonnyWhyte:
PIR doesn't sense presence, it senses movement.

Surely you don't mean to spray all the time someone is in the room?- do you mean maybe while they are in the room but moving? That doesn't sound right either, since if they move a lot you will choke them with spray :wink:

Maybe you could use PIR in conjunction with time, so if there's motion in the room, and it's been (say) 5 minutes since last spray, do a spray. Only downside there is, if the person/s is/are very still, there will be no spray.

I think this is a good example of using PIR.

Maybe you really mean, when someone enters the room?

Yes it goes high on detecting the movement.I have adjusted the time in the PIR so that there is some time gap
between each movement detection.

Thanks for your reply

void loop() {

  // io.run(); is required for all sketches.
  // it should always be present at the top of your loop
  // function. it keeps the client connected to
  // io.adafruit.com, and processes any incoming data.
  
  io.run();

  if(digitalRead(BUTTON_PIN) == LOW) {
    command->save("button");
  }
   else{
  long state = digitalRead(13);
  if(state == HIGH){
    digitalWrite (16,HIGH);
    Serial.println("Motion Detected!");
    rotatingPixels(ring.Color(255, 0, 0,0)); // display animation
    lightPixels(ring.Color(255, 0, 0,0)); // display animation     
    delay(1000);
    lightPixels(ring.Color(0, 0, 0, 0));
  }
    else {
      digitalWrite (16,LOW);
      Serial.println("Motion absent!");
      delay(1000);
    }

}

}

Asper the above loop if the PIR pin goes high it sprays and repeats in loop whenever motion detected.

My objective is :

When PIR first detect the motion it should spray.For next immediate motion detection it should not spray it should wait for said time.Then it should spray on detecting the motion.

For the above objective what code change i need to do.Came to know boolean latch would work, but don't know how to code it

Thanks in advance ,Please advice