Merging two codes - PIR Sensor & Firebase

Hi guys, I want to merge two codes adding some conditions.
Here the first one:

//Pin definition
int pirPin = 16;    //il PIN di Arduino a cui è collegato il sensore

// Calibration time
int calibrationTime = 30;

//How long the output is low
long unsigned int lowIn;

// Value in ms, how long we suppose there's "quiet"
long int pausa = 5000;

boolean lockLow = true;
boolean takeLowTime;

// Sensor settings
void setup() {
  Serial.begin(9600);
  pinMode(pirPin, INPUT);
  digitalWrite(pirPin, LOW);

  //Calibration phase
  Serial.print("PIR calibration ");
  for (int i = 0; i < calibrationTime; i++) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("Done");
  delay(50);
}

void loop() {

  // If condition to see if there's movement
  if (digitalRead(pirPin) == HIGH) {
    if (lockLow) {

      lockLow = false;
      Serial.println("---");
      Serial.print("Spotted movement at: ");
      Serial.print(millis() / 1000);
      Serial.println(" sec");
      delay(50);
    }
    takeLowTime = true;
  }
  // If condition to check if the movement ended
  if (digitalRead(pirPin) == LOW) {

    if (takeLowTime) {
      lowIn = millis();
      takeLowTime = false;
    }

    if (!lockLow && (millis() - lowIn > pausa)) {

      lockLow = true;
      Serial.print("Movement ended at ");      //output
      Serial.print((millis() - pausa) / 1000);
      Serial.println(" sec");
      delay(50);
    }
  }
}

and here the second one:

#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#include <Firebase_ESP_Client.h>

//Provide the token generation process info.
#include "addons/TokenHelper.h"
//Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"

//Libreries
#include <Adafruit_BMP085.h>
#include <TimeLib.h>

//Costants - Firebase
//Define the WiFi credentials - Define the API Key - Define the RTDB URL - Define the user Email and password that alreadey registerd or added in your project
#define WIFI_SSID "***"
#define WIFI_PASSWORD "***"
#define API_KEY "***"
#define DATABASE_URL "***" //<databaseName>.firebaseio.com or <databaseName>.<region>.firebasedatabase.app
#define USER_EMAIL "***"
#define USER_PASSWORD "***"

// Constants - Sensors
#define DELAY 1000 // Delay between two measurements in ms
#define VIN 3.3 // V power voltage
#define R 10000 // Ohm resistance value
#define sensorPin 35 // Pin connected to photoresistor

//Define Firebase Data object
FirebaseData fbdo;

FirebaseAuth auth;
FirebaseConfig config;

//Objects
Adafruit_BMP085 bmp;

//Variables
unsigned long sendDataPrevMillis = 0;
int16_t sensorVal; // Analog value from the sensor
int16_t lux; //Lux value
int16_t count = 0;

void setup() {
  Serial.begin(9600);
  pinMode(sensorPin, INPUT);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(300);
  }
  Serial.println();
  Serial.printf("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  config.api_key = API_KEY;

  auth.user.email = USER_EMAIL;
  auth.user.password = USER_PASSWORD;

  config.database_url = DATABASE_URL;
  config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h

  fbdo.setResponseSize(2048);  // Limit the size of response payload to be collected in FirebaseData

  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);

  Firebase.setDoubleDigits(5);

  config.timeout.serverResponse = 10 * 1000;

  bmp.begin();
}

void loop() {
  if (Firebase.ready() && (millis() - sendDataPrevMillis > 15000 || sendDataPrevMillis == 0))
  {
    sendDataPrevMillis = millis();
    float temp = bmp.readTemperature();
    int pres = bmp.readPressure();
    float alt = bmp.readAltitude(101500);
    lux = sensorRawToPhys(analogRead(sensorPin));

    String path = "/UsersData/";
    path += auth.token.uid.c_str(); //<- user uid of current user that sign in with Emal/Password
    path += "/Home/";

    Firebase.RTDB.setFloat(&fbdo, path + "RealtimeDataStream/Temperature", temp);
    Firebase.RTDB.setInt(&fbdo, path + "RealtimeDataStream/Pressure", pres);
    Firebase.RTDB.setFloat(&fbdo, path + "RealtimeDataStream/Altitude", alt);
    Firebase.RTDB.setInt(&fbdo, path + "RealtimeDataStream/Luminosity", lux);

    Firebase.RTDB.setTimestamp(&fbdo, path + "/Timestamp");
    Firebase.RTDB.getDouble(&fbdo, path + "/Timestamp");


    double timeStamp = fbdo.to<uint64_t>();

    Serial.println("- - - - - - - - - - - - -");
    char buff[32];
    sprintf(buff, "%02d.%02d.%02d %02d:%02d:%02d", day(timeStamp / 1000), month(timeStamp / 1000), year(timeStamp / 1000), hour(timeStamp / 1000) + 2, minute(timeStamp / 1000), second(timeStamp / 1000));
    Serial.println(buff);
    Serial.println("Temperature: " + (String)temp);
    Serial.println("Pressure: " + (String)pres);
    Serial.println("Altitude: " + (String)alt);
    Serial.println("Luminosity: " + (String)lux);
    Serial.println("Motion: " + (String)motion);

    if (count == 10)
    {
      FirebaseJson json;

      json.add("Temperature", temp);
      json.add("Pressure", pres);
      json.add("Altitude", alt);
      json.add("Luminosity", lux);
      json.add("Motion duration (sec)", (millis() - pausa) / 1000);
      json.add("Timestamp", timeStamp);

      Serial.printf("Set json... %s\n", Firebase.RTDB.push(&fbdo, path + "/DataCollection", &json) ? "ok" : fbdo.errorReason().c_str());

      json.clear();

      count = 0;
    }
    Serial.println("+" + (String)count);
    count++;
  }

  int sensorRawToPhys(int raw)
  {
    // Conversion rule
    float Vout = float(raw) * (VIN / float(4096));// Conversion analog to voltage
    float RLDR = (R * (VIN - Vout)) / Vout; // Conversion voltage to resistance
    int phys = 500 / (RLDR / 1000); // Conversion resitance to lumen
    return phys;
  }
}
  1. First question is: how do I need to modify my code for when the PIR sensor detect a movement? Maybe, adding a condition in the second code, first if condition, in the loop, a digitalRead and it will instantly update the realtime database (only one time -> adding a variable if I've already wrote set to 1, when the movement end set it to 0 again) but in this way I don't know how to update the other sensor values every 15sec and when the movement end.
  2. Second question is: how I can add a record every 15 cycle of measurements and also when the movement end with its duration? Since I'm already using the millis() function to update the the sensors values every 15sec but I also need it to know how long the movement lasted.

Thanks in advance,
Federico

millis() is just ‘the clock on the wall’
You can use it for as many things as you want.

For combining code, there are many previous threads on this.
Give it your best shot, see what happens, then ask specific questions with posted code and error messages - we’ll help.

Hi,
I tried solving my problem in this way:

#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif
#include <Firebase_ESP_Client.h>

//Provide the token generation process info.
#include "addons/TokenHelper.h"
//Provide the RTDB payload printing info and other helper functions.
#include "addons/RTDBHelper.h"

//Libreries
#include <Adafruit_BMP085.h>
#include <TimeLib.h>

//Costants - Firebase
//Define the WiFi credentials - Define the API Key - Define the RTDB URL - Define the user Email and password that alreadey registerd or added in your project
#define WIFI_SSID "***"
#define WIFI_PASSWORD "***"
#define API_KEY "***"
#define DATABASE_URL "***" //<databaseName>.firebaseio.com or <databaseName>.<region>.firebasedatabase.app
#define USER_EMAIL "***"
#define USER_PASSWORD "***"

// Constants - Sensors
#define sensorPin 35 // Pin connected to photoresistor
#define pirPin 16   //Pin connected to PIR sensor
#define VIN 3.3 // V power voltage
#define R 10000 // Ohm resistance value

//Define Firebase Data object
FirebaseData fbdo;

FirebaseAuth auth;
FirebaseConfig config;

//Objects
Adafruit_BMP085 bmp;

//Variables
unsigned long sendDataPrevMillis = 0;
int16_t sensorVal; // Analog value from the sensor
int16_t lux; //Lux value
int16_t count = 0;

int calibrationTime = 30;
unsigned long lowIn;
unsigned long pausa = 5000;
boolean lockLow = true;
boolean takeLowTime;

char buff[32];

void setup()
{
  Serial.begin(9600);
  pinMode(sensorPin, INPUT);
  pinMode(pirPin, INPUT);
  digitalWrite(pirPin, LOW);

  //Fase di calibrazione
  Serial.println("PIR sensor calibration. ");
  for (int i = 0; i < calibrationTime; i++) {
    Serial.print(".");
    delay(1000);
  }
  Serial.println("Done");
  Serial.println("PIR sensor calibrated");

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED)
  {
    delay(300);
  }
  Serial.println();
  Serial.printf("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  config.api_key = API_KEY;

  auth.user.email = USER_EMAIL;
  auth.user.password = USER_PASSWORD;

  config.database_url = DATABASE_URL;
  config.token_status_callback = tokenStatusCallback; //see addons/TokenHelper.h

  fbdo.setResponseSize(2048);  // Limit the size of response payload to be collected in FirebaseData

  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);

  Firebase.setDoubleDigits(5);

  config.timeout.serverResponse = 10 * 1000;

  bmp.begin();
}

void loop()
{
  String path = "/UsersData/";
  path += auth.token.uid.c_str(); //<- user uid of current user that sign in with Emal/Password
  path += "/Home/";

  double timeStamp;
  double timeStamp_mov1;
  double timeStamp_mov2;
  double hold;
  bool state;
  
  sendDataPrevMillis = millis();
  float temp = bmp.readTemperature();
  int pres = bmp.readPressure();
  float alt = bmp.readAltitude(101500);
  lux = sensorRawToPhys(analogRead(sensorPin));
  bool motion = digitalRead(pirPin);


  if (Firebase.ready() && count%250 == 0)
  {
    Firebase.RTDB.setFloat(&fbdo, path + "RealtimeDataStream/Temperature", temp);
    Firebase.RTDB.setInt(&fbdo, path + "RealtimeDataStream/Pressure", pres);
    Firebase.RTDB.setFloat(&fbdo, path + "RealtimeDataStream/Altitude", alt);
    Firebase.RTDB.setInt(&fbdo, path + "RealtimeDataStream/Luminosity", lux);
    Firebase.RTDB.setBool(&fbdo, path + "RealtimeDataStream/Motion", motion);
    Firebase.RTDB.setTimestamp(&fbdo, path + "/Timestamp");

    Firebase.RTDB.getDouble(&fbdo, path + "/Timestamp");
    timeStamp = fbdo.to<uint64_t>();

    Serial.println("- - - - - - - - - - - - -");
    sprintf(buff, "%02d.%02d.%02d %02d:%02d:%02d", day(timeStamp / 1000), month(timeStamp / 1000), year(timeStamp / 1000), hour(timeStamp / 1000) + 2, minute(timeStamp / 1000), second(timeStamp / 1000));
    Serial.println(buff);
    Serial.println("Temperature: " + (String)temp);
    Serial.println("Pressure: " + (String)pres);
    Serial.println("Altitude: " + (String)alt);
    Serial.println("Luminosity: " + (String)lux);
    Serial.println("Motion: " + (String)motion);
    Serial.println("- - - - - - - - - - - - -");
  }

  if (digitalRead(pirPin) == HIGH)
  {
    if (lockLow)
    {
      Firebase.RTDB.setTimestamp(&fbdo, path + "/Timestamp");
      Firebase.RTDB.getDouble(&fbdo, path + "/Timestamp");
      timeStamp_mov1 = fbdo.to<uint64_t>();

      lockLow = false;
      
      Serial.println("- - -");
      Serial.print("Movement detected at ");
      sprintf(buff, "%02d.%02d.%02d %02d:%02d:%02d", day(timeStamp_mov1 / 1000), month(timeStamp_mov1 / 1000), year(timeStamp_mov1 / 1000), hour(timeStamp_mov1 / 1000) + 2, minute(timeStamp_mov1 / 1000), second(timeStamp_mov1 / 1000));
      Serial.println(buff);
      Serial.println("- - -");
    }
    takeLowTime = true;
  }

  if (digitalRead(pirPin) == LOW) 
  {
    if (takeLowTime) {
      lowIn = millis();
      takeLowTime = false;
    }

    if (!lockLow && (millis() - lowIn > pausa))
    {
      Firebase.RTDB.setTimestamp(&fbdo, path + "/Timestamp");
      Firebase.RTDB.getDouble(&fbdo, path + "/Timestamp");
      timeStamp_mov2 = fbdo.to<uint64_t>();
      hold = (timeStamp_mov2 - timeStamp_mov1) / 1000;

      lockLow = true;
      Serial.println("- - -");
      Serial.print("Movement ended at ");
      sprintf(buff, "%02d.%02d.%02d %02d:%02d:%02d", day(timeStamp_mov2 / 1000), month(timeStamp_mov2 / 1000), year(timeStamp_mov2 / 1000), hour(timeStamp_mov2 / 1000) + 2, minute(timeStamp_mov2 / 1000), second(timeStamp_mov2 / 1000));
      Serial.println(buff);
      Serial.print("It lasted  ");
      Serial.print(hold);
      Serial.println(" sec");
      Serial.println("- - -");
      state = true;
    }
  }

  if (count == 3000 || state == true)
  {
    Firebase.RTDB.setTimestamp(&fbdo, path + "/Timestamp");

    Firebase.RTDB.getDouble(&fbdo, path + "/Timestamp");
    timeStamp = fbdo.to<uint64_t>() / 1000;
    
    FirebaseJson json;

    if (count == 3000)
    {
      json.add("Temperature", temp);
      json.add("Pressure", pres);
      json.add("Altitude", alt);
      json.add("Luminosity", lux);
      json.add("Motion", motion);
      json.add("Timestamp", timeStamp);

      Serial.printf("Set json... %s\n", Firebase.RTDB.push(&fbdo, path + "/DataCollection", &json) ? "ok" : fbdo.errorReason().c_str());
      count = 0;
    }
    if (state == true)
    {
      json.add("Temperature", temp);
      json.add("Pressure", pres);
      json.add("Altitude", alt);
      json.add("Luminosity", lux);
      json.add("Motion", true);
      json.add("Motion duration (sec)", hold);
      json.add("Timestamp", timeStamp_mov2);

      Serial.printf("Set json... %s\n", Firebase.RTDB.push(&fbdo, path + "/DataCollection", &json) ? "ok" : fbdo.errorReason().c_str());
      state = false;
    }

    json.clear();
  }
  // Serial.println("+" + (String)count);
  count++;

}

int sensorRawToPhys(int raw)
{
  // Conversion rule
  float Vout = float(raw) * (VIN / float(4096));// Conversion analog to voltage
  float RLDR = (R * (VIN - Vout)) / Vout; // Conversion voltage to resistance
  int phys = 500 / (RLDR / 1000); // Conversion resitance to lumen
  return phys;
}

And here I leave the output on the serial monitor:

21:48:39.144 -> ...........................Done
21:49:06.147 -> PIR sensor calibrated
21:49:08.663 -> 
21:49:08.663 -> Connected with IP: ***
21:49:08.703 -> 
21:49:08.703 -> Token info: type = id token, status = on request
21:49:10.687 -> Token info: type = id token, status = ready
21:49:12.052 -> - - - - - - - - - - - - -
21:49:12.105 -> 27.07.2022 21:49:11
21:49:12.105 -> Temperature: 30.70
21:49:12.152 -> Pressure: 99243
21:49:12.152 -> Altitude: 189.13
21:49:12.152 -> Luminosity: 0
21:49:12.206 -> Motion: 0
21:49:12.206 -> - - - - - - - - - - - - -
21:49:12.253 -> Set json... ok
21:49:12.453 -> Set json... ok
21:49:12.654 -> Set json... ok
21:49:12.908 -> Set json... ok
21:49:13.108 -> Set json... ok
21:49:13.324 -> Set json... ok
21:49:13.556 -> Set json... ok
21:49:13.757 -> Set json... ok
21:49:13.957 -> Set json... ok
21:49:14.211 -> Set json... ok
21:49:14.411 -> Set json... ok
21:49:14.658 -> Set json... ok
21:49:14.859 -> Set json... ok
21:49:15.059 -> Set json... ok
21:49:15.313 -> Set json... ok
21:49:15.514 -> Set json... ok
21:49:16.117 -> Set json... ok
21:49:16.318 -> Set json... ok
21:49:16.518 -> Set json... ok
21:49:16.866 -> Set json... ok
21:49:17.066 -> Set json... ok
21:49:17.321 -> Set json... ok
21:49:17.521 -> Set json... ok
21:49:17.722 -> Set json... ok
21:49:17.970 -> Set json... ok
21:49:18.170 -> Set json... ok
21:49:18.425 -> Set json... ok
21:49:18.626 -> Set json... ok
21:49:18.827 -> Set json... ok
21:49:19.074 -> Set json... ok
21:49:19.273 -> Set json... ok
21:49:30.385 -> Set json... ok
21:49:30.532 -> - - -
21:49:30.532 -> Movement detected at 27.07.2022 21:49:30
21:49:30.585 -> - - -
21:49:30.686 -> Set json... ok
21:49:30.887 -> Set json... ok
21:49:31.088 -> Set json... ok
21:49:31.336 -> Set json... ok
21:49:31.536 -> Set json... ok
21:49:31.737 -> Set json... ok
21:49:31.991 -> Set json... ok
21:49:32.192 -> Set json... ok
21:49:32.392 -> Set json... ok
21:49:32.640 -> Set json... ok
21:49:32.841 -> Set json... ok
21:49:33.042 -> Set json... ok
21:49:33.297 -> Set json... ok
21:49:33.498 -> Set json... ok
21:49:33.745 -> Set json... ok
21:49:34.000 -> Set json... ok
21:49:34.201 -> Set json... ok
21:49:34.438 -> Set json... ok
21:49:34.694 -> Set json... ok
21:49:34.942 -> Set json... ok
21:49:35.143 -> Set json... ok
21:49:35.350 -> Set json... ok
21:49:35.598 -> Set json... ok
21:49:35.799 -> Set json... ok
21:49:35.999 -> Set json... ok
21:49:36.247 -> Set json... ok
21:49:36.448 -> Set json... ok
21:49:36.703 -> Set json... ok
21:49:36.904 -> Set json... ok
21:49:37.050 -> - - -
21:49:37.104 -> Movement ended at 27.07.2022 21:49:36
21:49:37.104 -> It lasted  6.54 sec
21:49:37.151 -> - - -

Clearly it doesn't worked as expected :rofl:
The result that I want to obtain is to only set the JSON when the movement
definitely ends or every 3min c.ca.
In this solution I would like to share live data every 15sec c.ca or when it detects a movement.

I appreciate any help, thanks :grin:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.