Contador de presencia

Buenas a todos, estoy montando una alarmar y se como hacer para que salte cuando detecta movimiento y hasta ahi de momento bien, ahora quiero conectar un sensor Pir al arduino y que me valla sumando cada vez que detecte movimiento para asi saber si salta con el perro que tengo e intentar regular la sensibilidad para que con el perro no salte.

He buscado ejemplos y no he dado con ninguno que me sirva lo mas cercano ha sido un video y nada de la programacion, en uno de los manuales que tengo pone usar X++ para sumar uno, pero no trae ejemplo y creo que lo hago mal.

// Alarma Chalet
#include <Wire.h>                   // Libreria para I2C
#include <LiquidCrystal_I2C.h>      // Libreria para LCD
#define DS1307_I2C_ADDRESS 0x68     // Direccion bus Reloj

LiquidCrystal_I2C lcd(0x27,16,2);  // Direccion de bus pantalla

const int pir1 = 4;            // Pin de entrada señal Pir 1

const int ledEstado = 13;      // Led en pin 13 salto Pir 1 y Pir 2
int estadoPir1 = 0;            // Estado de Pir 1 "0"


byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convierte BCD (binario decimal codificado) a números normales decimales 
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));    
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));      
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.endTransmission();
}

// Establece la fecha y la hora del reloj
void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{
  // Resetea el registro puntero
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // Alguno de estos necesitan enmascarar porque ciertos bits son bits de control    

  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);  
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

void setup()

{
  lcd.init();                  // Inicializacion LCD
  pinMode(ledEstado, OUTPUT);  // Funcion de salida LedEstado pin 13
  pinMode(pir1, INPUT);        // Funcion de entrada Pir 1 pin 2 
 
  
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  
  
 
  // la primera vez debemos poner en hora, active esta parte y luego vuelva a quitarla
  /*second = 00;
  minute = 33;
  hour = 15;
  dayOfWeek = 6;
  dayOfMonth = 11;
  month = 2;
  year = 12;
  
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); */
   
  
}

void loop()
{
  
   lcd.backlight();             // Iluminacion LCD
   lcd.setCursor(0,0);          // Seleccionamos posicion del cursor
   
  
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);  

  lcd.setCursor(6,0);
    lcd.print(year, DEC);
  lcd.setCursor(2,0);
  lcd.print("/");
  lcd.setCursor(3,0);
    if (month < 10) lcd.print("0");
  lcd.print(month, DEC);  
  lcd.setCursor(5,0);
  lcd.print("/");   
  lcd.setCursor(0,0);
    if (dayOfMonth < 10) lcd.print("0");
  lcd.print(dayOfMonth, DEC); 
  lcd.print("");
  lcd.setCursor(0,1);
    if (hour < 10) lcd.print("0");
  lcd.print(hour, DEC);
  lcd.setCursor(2,1);
  lcd.print(":");  
  lcd.setCursor(3,1);
    if (minute < 10) lcd.print("0");
  lcd.print(minute, DEC);
  lcd.setCursor(5,1);
  lcd.print(":");
    if (second < 10) lcd.print("0");
  lcd.print(second, DEC);  
  
     switch (dayOfWeek)
    
    {
     
    case 1:
      lcd.setCursor(9,0);
      lcd.print("Lunes"); 
      break;
    case 2:
      lcd.setCursor(9,0);
      lcd.print("Martes"); 
      break;
    case 3:
      lcd.setCursor(9,0);
      lcd.print("Miercoles"); 
      break;
    case 4:
      lcd.setCursor(9,0);
      lcd.print("Jueves"); 
      break;
    case 5:
      lcd.setCursor(9,0);
      lcd.print("Viernes"); 
      break;
    case 6:
      lcd.setCursor(9,0);
      lcd.print("Sabado"); 
      break;
    case 7:
      lcd.setCursor(9,0);
      lcd.print("Domingo"); 
      break;
   }
   
   

  delay(1000); //Pausa durante 1 segundo
  
  
  
  estadoPir1 = digitalRead(pir1);  // Leer estado Pir 1
 
  
  lcd.backlight();             // Iluminacion LCD
  lcd.setCursor(9,1);          // Seleccionamos posicion del cursor
  int x=0;

  if (estadoPir1 == HIGH) {        // Si esta sl sensor Pir 1 activado activa led Pin 13
  digitalWrite(ledEstado, HIGH);    //Pone led Estado pin 13 a nivel alto
  int x=++;     // Se inicia bucle cuenta atras desde 35s
  lcd.print(x);               // Se imprime bucle en puerto serie
  lcd.setCursor (9,1);            // Se establece el curso en el LCD
  lcd.print(x);                    // Se imprime el valor de x por donde va.
     
     
     
    
  
  }
 
  else {                           // Si no se da las condiciones anteriores pone led Estado a nivel bajo
  digitalWrite(ledEstado, LOW);
   
    
       
     
 
  
      
 }
}

Esta es una de las formas que he probado medio sacado de otro proyecto a ver si conseguia enteder algo o hacer funcionar algo y nada, cuando detecta movimiento parece en el 0, 1, 2 depende de cuandos x=++ ponga o como ahora se pone a contar como un loco en cuanto detecta movimiento una sola vez.

Saludoss

Creo que para lo que intentas hacer, necesitas plantearlo de otra manera.

Ahora mismo, en cada ejecución del loop() compruebas si se ha detectado presencia o no, y si es así, pones la variable x a 1 (o a 2 o a 3 depende de los x++ que pongas dentro del if) pero al volver a ejecutar el loop vuelves a inicializar la variable a o (int x=0).

Lo que tendrías que hacer es comprobar cuando se detecta presencia y cuando se deja de detectar, es decir, cuando estadoPir pasa de HIGH a LOW (para eso deberías guardar su estado en otra variable del tipo estadoPir_anterior y compararlos), y entonces aumentar el contador (x), además x debe ser variable global para que su valor no se reinicie cada vez que ejecuta el loop.

Yo la verdad que no entiendo muy bien este tipo de discriminación. Vamos, que como entre un ladrón y haga un par de paseitos como el del perro va a poder robar la casa tranquilamente.

Cheyenne:
Yo la verdad que no entiendo muy bien este tipo de discriminación. Vamos, que como entre un ladrón y haga un par de paseitos como el del perro va a poder robar la casa tranquilamente.

Es verdad, no creo que con el detector Pir se pueda discriminar entre un perro y una persona, ya que la detección es booleana (0 o 1) y un perro puede hacer casi cualquier cosa.

De todas maneras, te he modificado tu código para incluir la idea que te comentaba del contador de presencia:

// Alarma Chalet
const int pir1 = 4;             // Pin de entrada señal Pir 1
const int ledEstado = 13;       // Led en pin 13 salto Pir 1 y Pir 2

int estadoPir1 = 0;             // Estado de Pir 1
int estadoPir1_anterior = 0;    // Estado de Pir 1
int contadorPresencia = 0;      // Contador de presencias detectadas

void setup()

{
  pinMode(ledEstado, OUTPUT);  // Funcion de salida LedEstado pin 13
  pinMode(pir1, INPUT);        // Funcion de entrada Pir 1 pin 2 
}

void loop()
{
  estadoPir1 = digitalRead(pir1);  // Leer estado Pir 1

  // Led se enciende durante la detección de presencia
  if (estadoPir1 == HIGH) 
    digitalWrite(ledEstado, HIGH);  //Pone led Estado pin 13 a nivel alto
  else
    digitalWrite(ledEstado, LOW);   //Pone led Estado pin 13 a nivel bajo
    
  // Contador histórico de presencias detectadas
  if (estadoPir1 == LOW && estadoPir1_anterior == HIGH) 
    contadorPresencia++;
  estadoPir1_anterior = estadoPir1;
 }
}

Muchas gracias compañeros, los sensores tienen un potenciometro para cambiar la sensibilidad, entonces quiero ponerlo un par de dias a ver si puedo ajustarlo para que no salte con el perro y gatos, entonces habia pensado en montarlo de esta manera.

Cuando llegue a casa cargo el codigo a ver que tal me va.

Muchas gracias jorgepl

Para ajustar la sensibilidad y no tener que montar-desmontar el detector PIR un monton de veces del techo se me ocurre que puedes quitar el potenciometro de sensibilidad y conectarle un potenciometro digital de 50K.

flico:
Para ajustar la sensibilidad y no tener que montar-desmontar el detector PIR un monton de veces del techo se me ocurre que puedes quitar el potenciometro de sensibilidad y conectarle un potenciometro digital de 50K.

Buena idea, aunque nunca lo he usado, es mas ni sabia que existía jejejje.

volviendo al contador de presencia, tengo que ser tonto o algo porque con el codigo que modifico el compañero lo he integrado al mio para que funcione lcd, reloj... y nada lo ponga como lo ponga lo mas que aparece es 0 ni cuenta ni nada de nada...

// Alarma Chalet
#include <Wire.h>                   // Libreria para I2C
#include <LiquidCrystal_I2C.h>      // Libreria para LCD
#define DS1307_I2C_ADDRESS 0x68     // Direccion bus Reloj

LiquidCrystal_I2C lcd(0x27,16,2);  // Direccion de bus pantalla

const int pir1 = 4;            // Pin de entrada señal Pir 1

const int ledEstado = 13;      // Led en pin 13 salto Pir 1 y Pir 2
int estadoPir1 = 0;            // Estado de Pir 1 "0"
int estadoPir1_anterior = 0;    // Estado de Pir 1
int contadorPresencia = 0;      // Contador de presencias detectadas


byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

// Convierte BCD (binario decimal codificado) a números normales decimales 
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

// 1) Sets the date and time on the ds1307
// 2) Starts the clock
// 3) Sets hour mode to 24 hour clock

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.send(0);
   Wire.send(decToBcd(second));    
   Wire.send(decToBcd(minute));
   Wire.send(decToBcd(hour));      
   Wire.send(decToBcd(dayOfWeek));
   Wire.send(decToBcd(dayOfMonth));
   Wire.send(decToBcd(month));
   Wire.send(decToBcd(year));
   Wire.endTransmission();
}

// Establece la fecha y la hora del reloj
void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{
  // Resetea el registro puntero
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.send(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  // Alguno de estos necesitan enmascarar porque ciertos bits son bits de control    

  *second     = bcdToDec(Wire.receive() & 0x7f);
  *minute     = bcdToDec(Wire.receive());
  *hour       = bcdToDec(Wire.receive() & 0x3f);  
  *dayOfWeek  = bcdToDec(Wire.receive());
  *dayOfMonth = bcdToDec(Wire.receive());
  *month      = bcdToDec(Wire.receive());
  *year       = bcdToDec(Wire.receive());
}

void setup()

{
  lcd.init();                  // Inicializacion LCD
  pinMode(ledEstado, OUTPUT);  // Funcion de salida LedEstado pin 13
  pinMode(pir1, INPUT);        // Funcion de entrada Pir 1 pin 2 
 
  
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  
  
 
  // la primera vez debemos poner en hora, active esta parte y luego vuelva a quitarla
  /*second = 00;
  minute = 33;
  hour = 15;
  dayOfWeek = 6;
  dayOfMonth = 11;
  month = 2;
  year = 12;
  
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); */
   
  
}

void loop()
{
  
   lcd.backlight();             // Iluminacion LCD
   lcd.setCursor(0,0);          // Seleccionamos posicion del cursor
   
  
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);  

  lcd.setCursor(6,0);
    lcd.print(year, DEC);
  lcd.setCursor(2,0);
  lcd.print("/");
  lcd.setCursor(3,0);
    if (month < 10) lcd.print("0");
  lcd.print(month, DEC);  
  lcd.setCursor(5,0);
  lcd.print("/");   
  lcd.setCursor(0,0);
    if (dayOfMonth < 10) lcd.print("0");
  lcd.print(dayOfMonth, DEC); 
  lcd.print("");
  lcd.setCursor(0,1);
    if (hour < 10) lcd.print("0");
  lcd.print(hour, DEC);
  lcd.setCursor(2,1);
  lcd.print(":");  
  lcd.setCursor(3,1);
    if (minute < 10) lcd.print("0");
  lcd.print(minute, DEC);
  lcd.setCursor(5,1);
  lcd.print(":");
    if (second < 10) lcd.print("0");
  lcd.print(second, DEC);  
  
     switch (dayOfWeek)
    
    {
     
    case 1:
      lcd.setCursor(9,0);
      lcd.print("Lunes"); 
      break;
    case 2:
      lcd.setCursor(9,0);
      lcd.print("Martes"); 
      break;
    case 3:
      lcd.setCursor(9,0);
      lcd.print("Miercoles"); 
      break;
    case 4:
      lcd.setCursor(9,0);
      lcd.print("Jueves"); 
      break;
    case 5:
      lcd.setCursor(9,0);
      lcd.print("Viernes"); 
      break;
    case 6:
      lcd.setCursor(9,0);
      lcd.print("Sabado"); 
      break;
    case 7:
      lcd.setCursor(9,0);
      lcd.print("Domingo"); 
      break;
   }
   
   

  delay(1000); //Pausa durante 1 segundo
  
  
  
  estadoPir1 = digitalRead(pir1);  // Leer estado Pir 1
 
  
  lcd.backlight();             // Iluminacion LCD
  lcd.setCursor(9,1);          // Seleccionamos posicion del cursor
  
  lcd.print (contadorPresencia);

  // Led se enciende durante la detección de presencia
  if (estadoPir1 == HIGH) 
    digitalWrite(ledEstado, HIGH);  //Pone led Estado pin 13 a nivel alto
    
    
  
  else {
    digitalWrite(ledEstado, LOW);   //Pone led Estado pin 13 a nivel bajo
    
  // Contador histórico de presencias detectadas
  if (estadoPir1 == LOW && estadoPir1_anterior == HIGH) 
    contadorPresencia++;
  estadoPir1_anterior = estadoPir1;
  
  
 }
}

a ver que estoy poniendo mal, al final desistiré ya que seguramente el perro lo pille si o si ( es un mastin de 90kg ) y seguire con lo que es la alarma...

Saludos

Insisto que no sé qué tipo de discriminación quieres hacer para que detecte una persona y no lo haga con un perro de 90 kg.

Perdona, el código que te copie tenía un parentesis que no borre (seguro que te dió error de compilación :roll_eyes: ). Tú lo cerraste, cuando realmente había que quitarlo.

void loop()
{
  ...

  // Led se enciende durante la detección de presencia
  if (estadoPir1 == HIGH) 
    digitalWrite(ledEstado, HIGH);  //Pone led Estado pin 13 a nivel alto
  else
    digitalWrite(ledEstado, LOW);   //Pone led Estado pin 13 a nivel bajo
    
  // Contador histórico de presencias detectadas
  if (estadoPir1 == LOW && estadoPir1_anterior == HIGH) 
    contadorPresencia++;
  estadoPir1_anterior = estadoPir1;
}

Para que lo entiendas mejor, también puedes utilizar el siguiente donde pongo "todos" lo parentesis y veas que hay dentro y fuera de los if y los else

void loop()
{
  ...
  
  // Led se enciende durante la detección de presencia
  if (estadoPir1 == HIGH)
  {
    digitalWrite(ledEstado, HIGH);  //Pone led Estado pin 13 a nivel alto
  } 
  else 
  {
    digitalWrite(ledEstado, LOW);   //Pone led Estado pin 13 a nivel bajo
  }
    
  // Contador histórico de presencias detectadas
  if (estadoPir1 == LOW && estadoPir1_anterior == HIGH)
  { 
    contadorPresencia++;
  }
  estadoPir1_anterior = estadoPir1;
}

Cheyenne:
Insisto que no sé qué tipo de discriminación quieres hacer para que detecte una persona y no lo haga con un perro de 90 kg.

No es que no lo sepas, es que no se puede discriminar.

Buenas jorge, lo que quiero hacer es ver si regulando la sensibilidad con el potenciometro que tiene el sensor Pir, puedo hacer que no detecte al perro.

Si no detecta al perro y si a personas el sensor iria colocado en un porche que da acceso a la vivienda cubriendo con un solo sensor el acceso a puerta principal y 2 ventanas de manera que si va un CACO con solo entrar al porche ya se pondria la cuenta a tras de la alama.

Si detecta al perro pues tendria que desistir de colocarlo en el porche ya que estaria saltando cada 2 x 3 y lo pondria dentro de la vivienda.

Aunque creo que seria mucho mejor si lo puedo colocar en el poche ya que se anticipa la alarma a saltar antes de que lleguen a entrar o forzar nada.

Por eso quiero montar el contador de presencia, asi voy variando la sensibilidad, lo conecto por la noche y a la mañana siguiente veo si a saltado con el perrillo o si sigue a 0.

Otra solucion es cerrar el porche para que no entre el perro, pero hay es donde duerme el pobre porque esta mas resguardado de frio, lluvia, calor etc.

uno de los problemas es que en los manuales que encontrado no he visto como hacer para que muestre la variable del cuenta personas en el LCD, lo mas que consigo es que salga 0, pero solo la primera vez que te pilla el pir, el resto de las veces nada de nada.
Que tendria que poner para que me salga ya con la suma?

void loop()
{
  ...
  
  // Led se enciende durante la detección de presencia
  if (estadoPir1 == HIGH)
  {
    digitalWrite(ledEstado, HIGH);  //Pone led Estado pin 13 a nivel alto
  } 
  else 
  {
    digitalWrite(ledEstado, LOW);   //Pone led Estado pin 13 a nivel bajo
  }
    
  // Contador histórico de presencias detectadas
  if (estadoPir1 == LOW && estadoPir1_anterior == HIGH)
  { 
    contadorPresencia++;

lcd.backlight();             // Iluminacion LCD
lcd.setCursor(9,1);          // Seleccionamos posicion del cursor
lcd.print (contadorPresencia);

Jorgepl gracias por ayudarme con el codigo.

Saludos a gracias por vuestra ayuda a todos

PD: uso la version 0023 ya que la ultima me dio problemas con una libreria y al final use este, por si interfiere en algo.

Tiozes,

Al colocar el Pir ten en cuenta que no se pueda acceder a el desde atras, porque simplemente poniendole un trapo por encima deja de detectar y el trapo no es suficiente para hacerlo saltar. :wink:

Gracias por recordarmelo jeje, ira colocado en una caja y esta puesta dentro del porche atornillada a la pared, de manera que la unica forma de poder acceder a ella es entrar por el porche activando el pir y la alarma, eso si consigo hacer que me cuente cada vez que salta el pir y me lo muestre en el LCD jajaja.

Por cierto lo del potenciometro digital me estado informando y es una muy buena idea jejeje graciass

Para que te muestre el contador ¿No sería así?

lcd.setCursor(9,1);          // Seleccionamos posicion del cursor
lcd.print (contadorPresencia,DEC);

Puedes ponerlo al principio del loop con el resto de datos que muestras en el LCD (fecha, hora,...), no hace falta que lo pongas al final.

Por cierto el sensor PIR no diferencia entre formas, con lo que no creo que vayas a poder diferenciar entre una persona (que puede pesar entre 50 y 120 kilos y medir entre 1,50 y 2 metros, por ejemplo) y un perro grande (que con 90 kilos debe medir lo suyo también).

Imagina:
Tiozes,

Al colocar el Pir ten en cuenta que no se pueda acceder a el desde atras, porque simplemente poniendole un trapo por encima deja de detectar y el trapo no es suficiente para hacerlo saltar. :wink:

Me he acordado de un capitulo de cazadores de mitos de como engañar a un sensor de alarma ultrasonico.

El sensor infrarrojo lo engañaban entrando con un traje de estos que se usan en las fundiciones.

Tengo instalados Pir's con "Pet Friendly" que son ni más ni menos que lo que tu comentas de los animales, tengo una gata, la cual, por mucho que corra no hace saltar los sensores. También tengo un pastor belga el cual lo hace saltar en cuanto se mueve.

Los sistemas "Pet Friendly" creo que no detectan animales por debajo de 10 ~ 15 kilos.

tengo el mismo proyecto en mente quisiera saber si lo pudo solucionar de ante mano le agradeserìa si pudiera proporcionarme información yo no excluiré al perro