Offline
Jr. Member
Karma: 0
Posts: 77
|
 |
« on: June 27, 2012, 02:31:25 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Spain
Offline
Full Member
Karma: 0
Posts: 191
|
 |
« Reply #1 on: June 27, 2012, 02:49:08 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
God Member
Karma: 2
Posts: 511
|
 |
« Reply #2 on: June 27, 2012, 02:53:15 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Spain
Offline
Full Member
Karma: 0
Posts: 191
|
 |
« Reply #3 on: June 27, 2012, 02:59:47 am » |
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; } }
|
|
|
|
« Last Edit: June 27, 2012, 03:01:34 am by jorgepl »
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 77
|
 |
« Reply #4 on: June 27, 2012, 04:06:37 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Edison Member
Karma: 8
Posts: 1040
Arduino rocks
|
 |
« Reply #5 on: June 27, 2012, 05:43:07 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 77
|
 |
« Reply #6 on: June 28, 2012, 02:15:54 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Offline
God Member
Karma: 2
Posts: 511
|
 |
« Reply #7 on: June 28, 2012, 02:33:34 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Spain
Offline
Full Member
Karma: 0
Posts: 191
|
 |
« Reply #8 on: June 28, 2012, 02:36:17 am » |
Perdona, el código que te copie tenía un parentesis que no borre (seguro que te dió error de compilación  ). 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; }
|
|
|
|
|
Logged
|
|
|
|
|
Spain
Offline
Full Member
Karma: 0
Posts: 191
|
 |
« Reply #9 on: June 28, 2012, 02:37:53 am » |
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.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 77
|
 |
« Reply #10 on: June 28, 2012, 03:26:29 am » |
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.
|
|
|
|
« Last Edit: June 28, 2012, 03:36:12 am by tiozes »
|
Logged
|
|
|
|
|
Alicante
Offline
Full Member
Karma: 0
Posts: 148
Arduino rocks
|
 |
« Reply #11 on: June 28, 2012, 03:45:58 am » |
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. 
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Jr. Member
Karma: 0
Posts: 77
|
 |
« Reply #12 on: June 28, 2012, 04:01:57 am » |
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
|
|
|
|
|
Logged
|
|
|
|
|
Spain
Offline
Full Member
Karma: 0
Posts: 191
|
 |
« Reply #13 on: June 28, 2012, 04:16:49 am » |
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).
|
|
|
|
« Last Edit: June 28, 2012, 04:19:37 am by jorgepl »
|
Logged
|
|
|
|
|
0
Offline
Edison Member
Karma: 8
Posts: 1040
Arduino rocks
|
 |
« Reply #14 on: June 28, 2012, 05:37:49 am » |
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.  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.
|
|
|
|
|
Logged
|
|
|
|
|
|