Autor Tema: Como aumentar variable al dejar de presionar boton  (Leído 8661 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado jorgec1996

  • PIC10
  • *
  • Mensajes: 11
Como aumentar variable al dejar de presionar boton
« en: 28 de Mayo de 2015, 03:32:13 »
Buenas, me llamo Jorge y soy nuevo en esto de programar en Pic, me pidieron un proyecto en la prepa, lo que quiero hacer es un contador de personas que suben a un camión y mostrarlo en una lcd, algo facil pero a la hora de que una persona pasa por el sensor la variable de personas va aumentando demasiado rapido
aquí esta lo que llevo...

Código: [Seleccionar]
#include <16f877a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#define LCD_DB4   PIN_D4
#define LCD_DB5   PIN_D5
#define LCD_DB6   PIN_D6
#define LCD_DB7   PIN_D7
#define LCD_RS    PIN_D2
#define LCD_E     PIN_D3
#include<lcd1.c> //libreria manejo lcd
#byte portb=6


short sensor = 0;
int personas = 0;

void main(){

while(1){




//-------------------------------------------------------------lcd---------
lcd_init ();

 lcd_gotoxy(1,1);
      printf (lcd_putc,"datos               ");
      lcd_gotoxy(1,2);
      printf (lcd_putc,"%u:%u:%u           ",sensor,personas,pe);

//---------------------------------------------------------------lcd---


 if (input(pin_b0)){
sensor = 1;}
else{
sensor = 0;}
 
if (sensor == 1){
personas++;
delay_ms(100); }
 
}
}

en la parte donde la variable "personas" aumenta, pasa que aumenta contantemente, le pongo un delay y aumenta cada que pase la cantidad de tiempo que le pongo al delay, pero lo que yo quiero es que la variable aumente cuando el sensor deje de detectar algo, suponinedo pasa juanito se para en el sensor pero la variable no aumenta hasta que juanito se quita del sensor, y asi cada que va pasando y se quita del sensor se aumenta la variable, quiza sea algo facil para ustedes pero la verdad es que soy demasiado nuevo en esto, gracias de antemano

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #1 en: 28 de Mayo de 2015, 04:55:26 »
Cortito que ya es tarde xD


2 formas:

1- Que puede molestarte segun tengas que hacer otras cosas
Código: C
  1. if (input(pin_b0))   // Si esta en 1 entra
  2. {
  3.  while(input(pin_b0));  // Si sigue en 1 se mantiene aca, sale cuando se pone a 0 y cuenta una persona.
  4.  personas++;
  5. }

2- por interrupciones. flanco descendente por RB0

Desconectado jorgec1996

  • PIC10
  • *
  • Mensajes: 11
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #2 en: 29 de Mayo de 2015, 21:02:23 »
Muchas gracias ya logre lo que queria hacer, si quiero preguntar hago otro tema o te puedo preguntar, esque quiero saber como hacer que aumente una variable cuando una entrada se mantenga 30 segundos pero si se corta antes de los 30 no se active, gracias:)

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #3 en: 30 de Mayo de 2015, 00:39:20 »
Tendrias que usar un TIMER para eso.

lo cual lo podes hacer de 2 formas, o utilizando una interrupcion o simplemente leyendo el flag de interrupcion sin tener activadas las interrupciones.

Al timer le cargas un valor, cada tantos ciclos de reloj este va a incrementar en 1. pero como conoces el ciclo de reloj entonces sabes cuanto va a tardar hasta que llegue al valor 0xFF y este pase a 0x00 que es cuando se activa el flag.

Por ejemplo si utilizas el TMR1 , le pones un preescaler de 1/8 ( es decir cada 8 ciclos de reloj suma 1 en el registro del timer1 ) y lo cargas con el valor 3036
Se va a activar el flag de interrupcion (TMR1IF) cada 0.5s si es que tenes un cristal u oscilador de 4Mhz

Y en tu programa podrias hacer algo asi (ojo el programa es modelo nomas, CCS tiene algunas funciones para configurar los timers, cargar el timer y limpiar el flag):

Código: C
  1. if (input(pin_b0))   // Si esta en 1 entra
  2. {
  3.  if(TMR1IF==1)  
  4.  {
  5.     TMR1IF=0;
  6.     TMR1 = 3036;
  7.     vuelta++;
  8.     if (vuelta==60)
  9.     {
  10.       personas++;
  11.     }
  12.   }
  13. }
  14. else
  15. {
  16.  vuelta=0;
  17. }

Explico el codigo, este esta realizado sin interrupciones.
Como dije el flag del timer se va a poner en 1 cada 0.5s asi que si quisiera 30 segundos deberia contar 60 de esos.
Apenas se pone a 1 el flag, lo borro y cargo nuevamente el TMR1 con el mismo valor para que vuelva a contar 0.5s de nuevo. Y asi continuamente.
Esto ocurre unicamente mientras se mantiene presionado el boton, si por alguna casualidad se suelta el boton reinicio el contador de los 30 segundos (vuelta).
En caso que se llegue a 60, incrementa la variable personas.

Si fuera con interrupcion serian 2 funciones, una del main y otra la de interrupcion, pero el procedimiento es igual, en la interrupcion incrementaria el valor de vuelta, cargaria de nuevo el valor en el TMR, limpiaria flag y preguntaria si supero los 60.
En el main solo preguntaria si esta en 0 el boton, si esta en 0 borro vueltas.

Desconectado jorgec1996

  • PIC10
  • *
  • Mensajes: 11
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #4 en: 03 de Junio de 2015, 00:09:54 »
Gracias, entiendo algunas cosas, pero la verdad es que voy empezando apenas y nunca he tocado un timer, nos han enseñado variables y las sentencias, apenas tenemos 2 meses y llevamos poco, no entiendo que es flag ni como poner un timer ni donde poner exactamente el codigo que me dejastes, he estado leyendo algunos cursos en internet pero los veo un poco complicados, porque ninguno me explica el timer desde 0, podrias explicarme un poco como va eso, o algun curso que me explique bien el timer como es, porque el profesor que nos esta enseñando no sabe, o no me quiere decir como  :? ...
Gracias :)

Modificacion agregada
Ya entendí un poco la función de los timers leyendo y viendo videos, como es la interrupción y varias cosillas, pero aun no entiendo eso de flag, con el project wizard puse un timer, el timer ya esta acomodado con el calculo que me dijiste y funciona cada .5 seg, ahora sigue el codigo que me dijiste pero no se como acomodarlo y como es lo de flag, porque me tira error en el TMR1IF y TMR1, no entiendo como acomodar esos en el programa.
« Última modificación: 03 de Junio de 2015, 02:41:11 por jorgec1996 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #5 en: 03 de Junio de 2015, 03:56:42 »
Tu problema es que le estan explicando como programar antes de enseñarle lo que tiene el PIC.
Hay muchas guias que explican que es un Timer por internet pero voy a tratar de explicarlo de una forma resumida.

El Timer es un modulo del PIC ( esto lo podes ver en el datasheet ). El timer es un contador, cuenta pulsos. ¿Que pulsos cuenta? Ahi tenes que ver como es el timer que se encuentra en tu PIC. Algunos permite contar los pulsos que entran por un pin externo, y  todos permiten contar los pulsos del oscilador, si por ejemplo tenes un cristal de 4Mhz vas a tener un pulso cada ( 4/4Mhz = 1us ) 1micro segundo.

Ahora existen Timer de 8 y 16 bits en la gama media de PICs, esto es importante de saber ya que tenes que conocer la cantidad maxima que puede contar, con 8 bits el maximo esta dado por 28-1=255 y con 16 bits, 216-1=65535
Vamos a suponer que es de 8 bits que es lo mas comun. Usando el dato de antes tengo que cada pulso es de 1us, y puede contar un maximo de 255, es decir que cuando llegue a ese valor pasaron 255us

Como dije el Timer posee un registro de 8 bits, cuando este esta en su maximo que es 255 y llega un nuevo pulso pasa a tener el valor de 0, es decir se produjo un overflow, al ocurrir eso se activa un flag,
un flag no es nada mas que un bit de algun registro que me esta indicando algo. Por ejemplo el flag TMR1IF del registro PIR1 se pone a 1 cuando se produce el overflow y esta en 0 mientras no ocurre eso. Una ves puesto en 1 el usuario deberia de asegurarse de borrar ese flag, es decir ponerlo a 0. Entonces ahora yo se que cada ves que se pone a 1 eso, es por que se rebalso, si cuento cuantas veces se pone a 1, es lo mismo que contar cuantas veces pasaron 255us

Hay otras cosas en los timers como los preescalers y postscalers.
El preescaler permite asignar un divisor a esos pulsos, por ejemplo si pongo un preescaler de 1/4 , eso quiere decir que mi contador (timer) va a contar 1 recien cuando ocurran 4 pulsos.
El postscaler funciona de otra forma y suelen tenerlo algunos pocos timer, este determina la cantidad de overflows antes de activar el flag que indica el overflow

Creo que eso es todo lo que tenes que saber del timer.

Con respecto a donde poner el programa y como leer las flags y esas cosas, depende mucho del compilador que estes usando.
Por ejemplo , Esta linea:

TMR1 = 3036;

Si usas CCS seria:

set_timer_1(3036);

Si usas XC8:

TMR1 = 3036;

Donde TMR1 corresponde a los registros TMR1H:TMR1L, ya que son registros de 8 bits pero el timer maneja 16bits, asi que se carga en 2 registros,
Existen mas compiladores pero creo que son los 2 mas usados.

El codigo de ejemplo que puse yo es para ponerlo en el while{} del main() , es decir en tu bucle infinito de tu funcion principal.
Como setear los flags y leer los flags ?

XC8:
Preguntar:    if (PIR1bits.TMR1IF==1)
Borrar:         PIR1bits.TMR1IF=0;

CCS:
Preguntar:    if (interrupt_active(INT_TIMER1)==1)
Borrar:        clear_interrupt(int_timer1);

En CCS tambien se puede hacer como en XC8 pero implica tener que definir los registros y bits. Personalmente me gusta mas XC8 ya que si observas el datasheet del micro, se correlaciona con los registros que involucra cada modulo. Y no tenes que aprenderte o estar buscando las funciones del compilador.
En el datasheet al ultimo de cada explicacion del modulo aparecen todos los registros y bits involucrados de ese modulo. Lo que si, esta en ingles.
« Última modificación: 03 de Junio de 2015, 04:02:47 por KILLERJC »

Desconectado jorgec1996

  • PIC10
  • *
  • Mensajes: 11
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #6 en: 03 de Junio de 2015, 05:02:51 »
Muchas gracias, ya entendí, me explicaste mil veces mejor que cualquier video o tutorial que estuve leyendo, tenia todo el código bien acomodado, pero nunca me funciono, tuve que usar la segunda opción que me diste de usar la interrupción del timer 1 y así funciono muy bien, el error que tenia en las flag es que en el compilador ccs ponia TMR1=3036; , cuando al ser ccs el codigo debia ser set_timer1(3036); como me dijiste al igual que los otros, no utilizaba codigo ccs, por eso me daba error, y por eso no tenia claro bien eso, pero ya quedo resuelto todo y funciona muy bien, tantas gracias :) encerio que me ayudaste demasiado, espero algun dia saber tanto sobre esto como tu, porque me esta gustando mucho lo poco que llevo de microcontroladores...
Saludos y denuevo gracias  : :grin:

Por si alguien llega a tener la misma duda dejo el codigo abajo de como quedo :)


Código: [Seleccionar]
#include <16F877A.h>
#device adc=8
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay(clock=4000000)
#define LCD_DB4   PIN_D4
#define LCD_DB5   PIN_D5
#define LCD_DB6   PIN_D6
#define LCD_DB7   PIN_D7
#define LCD_RS    PIN_D2
#define LCD_E     PIN_D3
#include<lcd1.c> //libreria manejo lcd

//---------------variables----------------------------------------------------//
short sensor = 0;
LONG personas = 0;
short alarma = 0;
int vuelta;
//----------------Fin variables-----------------------------------------------//

#int_TIMER1    
void  TIMER1_isr(void)
{
vuelta++; /// aumenta la vuelta cada .5 seg
set_timer1(3036);
clear_interrupt(int_timer1); // limpio flag
if(vuelta==60)  //si la vuelta da 60, en segundos 30,
{alarma++;}  //se activa la alarma porque el sensor esta siendo tapado
}


void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

while(1){

//------------------------lcd----------------------------------------------

lcd_init ();
 lcd_gotoxy(1,1);
      printf (lcd_putc,"datos               ");
      lcd_gotoxy(1,2);
      printf (lcd_putc,"%u:%Lu:%u          ",sensor,personas,alarma);
//-----------------------lcd fin--------------------------------------------


//------------------------sensor--------------------------------------------
if(input(pin_b0)){
sensor = 1;}
else{
sensor = 0;}
//---------------------------sensor fin---------------------------------------

if (input(pin_b0))   // Si esta en 1 entra
{
 while(input(pin_b0));  // Si sigue en 1 se mantiene aca, sale cuando se pone a 0 y cuenta una persona.
 personas++;
 write_eeprom(01,personas);
 }


if (input(pin_b0)==0)   // Si esta en 1 entra
{
 vuelta=0;
}



}
}
« Última modificación: 03 de Junio de 2015, 05:08:32 por jorgec1996 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #7 en: 03 de Junio de 2015, 13:36:40 »
Si es posible te voy a acomodar y corregir algunas cosas.

Código: C
  1. #include <16F877A.h>
  2. #device adc=8
  3. #FUSES NOWDT                    //No Watch Dog Timer
  4. #FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
  5. #FUSES NOPUT                    //No Power Up Timer
  6. #FUSES NOPROTECT                //Code not protected from reading
  7. #FUSES NODEBUG                  //No Debug mode for ICD
  8. #FUSES NOBROWNOUT               //No brownout reset
  9. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  10. #FUSES NOCPD                    //No EE protection
  11. #FUSES NOWRT                    //Program memory not write protected
  12. #FUSES RESERVED                 //Used to set the reserved FUSE bits
  13. #use delay(clock=4000000)
  14. #define LCD_DB4   PIN_D4
  15. #define LCD_DB5   PIN_D5
  16. #define LCD_DB6   PIN_D6
  17. #define LCD_DB7   PIN_D7
  18. #define LCD_RS    PIN_D2
  19. #define LCD_E     PIN_D3
  20. #include<lcd1.c> //libreria manejo lcd
  21.  
  22. //---------------variables----------------------------------------------------//
  23. LONG personas = 0;
  24. short alarma=0,sensor=0;
  25. int vuelta;
  26. //----------------Fin variables-----------------------------------------------//
  27.  
  28. #int_TIMER1    
  29. void  TIMER1_isr(void)
  30. {
  31. vuelta++; /// aumenta la vuelta cada .5 seg
  32. set_timer1(3036);
  33. clear_interrupt(int_timer1); // limpio flag
  34. if(vuelta==60)  //si la vuelta da 60, en segundos 30,
  35. {alarma=1;}  //se activa la alarma porque el sensor esta siendo tapado
  36. }
  37.  
  38.  
  39. void main()
  40. {
  41.  
  42.    setup_adc_ports(NO_ANALOGS);
  43.    setup_adc(ADC_CLOCK_DIV_2);
  44.    setup_psp(PSP_DISABLED);
  45.    setup_spi(SPI_SS_DISABLED);
  46.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  47.    setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
  48.    setup_timer_2(T2_DISABLED,0,1);
  49.    setup_comparator(NC_NC_NC_NC);
  50.    setup_vref(FALSE);
  51.    enable_interrupts(GLOBAL);
  52.  
  53. while(1){
  54.  
  55. //------------------------lcd----------------------------------------------
  56.  
  57. lcd_init ();
  58.  lcd_gotoxy(1,1);
  59.       printf (lcd_putc,"datos               ");
  60.       lcd_gotoxy(1,2);
  61.       printf (lcd_putc,"%u:%Lu:%u          ",sensor,personas,alarma);
  62. //-----------------------lcd fin--------------------------------------------
  63.  
  64.  
  65.  
  66.  
  67.         if (input(pin_b0))                              //El sensor detecto algo
  68.         {
  69.                 sensor = 1;                             // Pongo a 1 esa variable no se para que.
  70.                 set_timer1(3036);                       // Cargo el timer con el valor correspondiente, limpio flags y activo su interrupcion
  71.                 clear_interrupt(int_timer1);
  72.                 enable_interrupts(INT_TIMER1);
  73.                 while(input(pin_b0));                   // Mientras este atrapado en este bucle, es decir mientras no se suelte el sensor va a estar atrapado aca y va a funcionar la interrupcion
  74.                 personas++;                             // Si se solto cuento como que atravezo una persona, vera si luego cuando se activa la alarma si cuenta exactametne como persona o no.
  75.                 write_eeprom(01,personas);              // Esto lo considero malo, ya que grabar continuamente en la EEPROM es malo
  76.         }
  77.         else
  78.         {
  79.                 disable_interrupts(INT_TIMER1);         // Se solto el boton? entonces deshabilito las interrupciones del TIMER1 ya que no las necesito mas
  80.                 alarma=0;                               // Apago la alarma por que ya no hay nada atascado en el sensor
  81.                 sensor = 0;                             // Pongo a 0 esa variable
  82.                 vuelta=0;                               // Y Pongo a 0 mi variable vueltas por si llega a ocurrir de nuevo y quiero que comienze de 0
  83.         }
  84.  
  85.  
  86.  
  87. }
  88. }

El funcionamiento esta explicado ahi, me parece que la variable "sensor" es redundante y si no esta no afectaria en nada. A no ser que lo uses en otro parte del programa.
Desactivo las interrupciones mientras no se presione nada, ya que no tiene sentido que este entrando y saliendo de las mismas mientras no este presionado nada. Aunque tu programa funciona bien igual, ya que va a seguir entrando, incrementando la variable vueltas y luego poniendola a 0. Asi que no se va a ver afectado para nada.
Acomode los if para que estuvieran juntos.
la variable personas incrementa si o si. Incluso cuando se detecta que esta parado por 30 segundos y se activa la "alarma"  esto luego podes ver si deseas que aumente o no mientras esta activo.

Y por ultimo y mas importante... La EEPROM, esta tiene un numero limitado de escrituras.
1,000,000 erase/write cycle Data EEPROM memory typical

Tenes que darte cuenta que si pasan 10 objetos por minuto, al dia son 14.400, lo cual en 2 meses tu proyecto fallaria.
Cuando son cosas que se actualizas continuamente conviene hacerlo en una RAM, y si queres que se mantenga el dato luego que se corte la alimentacion, podrias realizar algo externo que detecte la falta de tension y mediante algun capacitor mantener alimentado al micro hasta grabar en la EEPROM. Esto reduciria muchisimo la cantidad de escrituras a la EEPROM
Es para que lo tengas en consideracion nomas. Si es para probar ahi nomas o un proyecto simple entonces no vas a tener problemas. Pero si es algo que tiene que durar mucho mas tiempo ahi si.

Desconectado jorgec1996

  • PIC10
  • *
  • Mensajes: 11
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #8 en: 05 de Junio de 2015, 04:16:41 »
Gracias por todo, ya quite la escritura de la eeprom, mas tarde se la agregare, pero ya solo por si se desconecta el pic, pero ahora me tope con un problema un poco mas complicado, al menos para mi, este proyecto lo dividimos en 2 partes y un compañero hizo lo otro que es poner un código con un teclado matricial y al poner ese código, ya puedes entrar a ver y modificar los pasajeros, todo lo de la contraseña y el teclado funciona perfectamente, pero el problema es que una vez que el pin donde esta el sensor que ahora es el e0, al ser utilizado aunque sea 1 vez, ya se queda bloqueado todo el programa no puede iniciarse, pero si pongo el programa y le doy al pin e1 inicia lo de la contraseña la pongo y puedo ver datos, pero al presionar el botón del sensor el programa se bloquea, que puede estar pasando, tiene que ver con la interrupción del timer 1? Muchas gracias

Código: [Seleccionar]
#include <16F877A.h>
#device adc=8
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES RESERVED                 //Used to set the reserved FUSE bits
#use delay(clock=4000000)
#define LCD_DB4   PIN_D4
#define LCD_DB5   PIN_D5
#define LCD_DB6   PIN_D6
#define LCD_DB7   PIN_D7
#define LCD_RS    PIN_D2
#define LCD_E     PIN_D3
#include<lcd1.c> //libreria manejo lcd
#include<KBD1.c>
#rom 0x2100={'2','6','1','2'} // escribir en la memoria eeprom
#define use_portb_kbd TRUE



//---------------variables----------------------------------------------------//
LONG personas = 0,personas1=0, pasajeros=0;
short alarma=0, inicio;
int vuelta;
int a;
int i;
int j=0;  // contador
char k; // lectura del teclado
char dato[4],clave[4]; //dato: almacena los digitos, clave: es la contraseña
int ingresos;
//----------------Fin variables-----------------------------------------------//
 
 
 
#int_TIMER1   
void  TIMER1_isr(void)
{
vuelta++; /// aumenta la vuelta cada .5 seg
set_timer1(3036);
clear_interrupt(int_timer1); // limpio flag
if(vuelta==60)  //si la vuelta da 60, en segundos 30,
{alarma=1;}  //se activa la alarma porque el sensor esta siendo tapado
}
 


void todo (void){

while(1){




//------------------------lcd----------------------------------------------//

 lcd_gotoxy(1,1);
      printf (lcd_putc,"Sensor:%lu       ",personas);
      lcd_gotoxy(1,2);
      printf (lcd_putc,"Pasa:%lu A:%u %lu        ",pasajeros,alarma,personas1);
//-----------------------lcd fin--------------------------------------------//

pasajeros = personas / 2;
 personas1=read_eeprom(01);
 
 //---------------este deberia ser 0, es para el apagado de emergencia--------//
 if (input(pin_e1))   // Si esta en 1 entra
{ write_eeprom(01,personas);
  delay_ms(200);}
//---------------------------------------fin----------------------------------//

if(input(pin_e2)){
alarma = 0;
personas= 0;
pasajeros = 0;
}
}
}


void main()
{
   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   enable_interrupts(GLOBAL);
 enable_interrupts(INT_TIMER1);
 
 
 
while(1){
 lcd_init ();
kbd_init();
port_b_pullups(TRUE);

if (input(pin_e0))            //El sensor detecto algo
   {
      set_timer1(3036);         // Cargo el timer con el valor correspondiente, limpio flags y activo su interrupcion
      clear_interrupt(int_timer1);
      enable_interrupts(INT_TIMER1);
      while(input(pin_b0));         // Mientras este atrapado en este bucle, es decir mientras no se suelte el sensor va a estar atrapado aca y va a funcionar la interrupcion
      personas++;            // Si se solto cuento como que atravezo una persona, vera si luego cuando se activa la alarma si cuenta exactametne como persona o no.
   }
   else
   {
      disable_interrupts(INT_TIMER1);      // Se solto el boton? entonces deshabilito las interrupciones del TIMER1 ya que no las necesito mas
      vuelta=0;            // Y Pongo a 0 mi variable vueltas por si llega a ocurrir de nuevo y quiero que comienze de 0
   }
   
if (input(pin_e1))
{inicio=1;}

if(inicio==1)
{
   



//-----------------------clave-----------------------------------------------

printf(LCD_putc, "\f");
lcd_putc("\fINGRESE SU CLAVE  ");
 
i=0;
while(i<4){
k=kbd_getc(); // leer la tecla presiono
if(k!=0){
      dato[i]=k;
      i++;
      lcd_gotoxy(i,2); // posicion i de la segunda linea
      lcd_putc('*');
         }
         }
         
   for(i=0;i<4;i++)
   clave[i]=read_eeprom(i); //guarda la constraseña  en el vector clave
   
   if( dato[0]==clave[0] &&  dato[1]==clave[1] && dato[2]==clave[2] && dato[3]==clave[3])
   { 
lcd_gotoxy(1,1);
      printf (lcd_putc,"\fClave correcta");
lcd_gotoxy(1,2);
      printf (lcd_putc,"Adelante!");
      ingresos = ingresos +1;
         delay_ms(200);
lcd_gotoxy(1,1);
      printf (lcd_putc,"\fHas entrado %u",ingresos);
      lcd_gotoxy(1,2);
      printf (lcd_putc,"veces");
      delay_ms(500);
        todo ();
   
   }
   else{
      lcd_putc("\fClave incorrecta ");
      lcd_putc("\n        ");
      j++;
      if(j==3){
      lcd_putc("\fTecladoBloqueado ");
      lcd_putc("\n        ");
      delay_ms(60000);
      j=0;
      }
      delay_ms(2000);
   }

//---------------clave fin------------------------------------------------------

   







 
}
 
}
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #9 en: 05 de Junio de 2015, 04:45:49 »
Ahora que mencionas el programa completo no va a funcionar como vos queres.

Yo hubiera realizado:

1 Timer con entrada exterior para contar los pulsos
1 Timer para detectar si esta 30 segundos o mas, esto funcionaria constantemente. Y evita todos esos delays, ademas hicimos una "trampa" con un while, que no sale hasta que se pone a 0 el sensor.
El programa que haga lo que quiera xD ya que no molestaria para nada.

Otra cosa... OJO con los delays, estos tienen que ser cortos. Un delay no significa que el micro va a estar haciendo otras cosas mientras. Si no que el micro no hace NADA, se pone a hacer saltos o ejecutar instrucciones que no molestan hasta que pasa ese tiempo. Y tenes en tu codigo algo asi:


delay_ms(60000);

60 segundos el micro COLGADO, que esta trabado ahi.
Como lo plantee al comienzo de este post, esa forma te ahorraria muchos dolores de cabeza, intenta evitar en lo posible TODO delay

Desconectado jorgec1996

  • PIC10
  • *
  • Mensajes: 11
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #10 en: 05 de Junio de 2015, 05:29:25 »
Si surgieron ya varios problemitas, pero entonces lo que haria seria poner por ejemplo el timer 0 como contador externo, que este directamente al sensor? Y el timer 1 dejarlo tal como esta no? O como seria?

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #11 en: 05 de Junio de 2015, 13:28:24 »
Exacto el TMR0 como contador, solo eso no es necesario ninguna interrupcion del mismo

El TMR1 como esta y que revise el RA4 que es el pin de entrada del TMR0, si este se mantiene en 1 mucho tiempo activas la alarma, esto lo podes hacer: Comparando el valor del registro, con un valor viejo del registro y tambien leyendo la entrada.
Si el valor viejo que tenias guardado es igual al valor nuevo del TMR (es decir no conto mas nada ) y tenes un 1 de entrada, empezas a incrementar la varaible vueltas. Sino la pones a 0, esto por si existe la casualidad que entre interrupcion e interrupcion del TMR1 venga otro pulso, pero cuando vos entres y leas el pin siga en 1, pero realmente cambio.

Ademas te fijas si el flag del TMR0 se activo, recorda que en un registro de 8bits solo puede haber 255 pulsos. si se activo quiere decir que ya hubo 256 pulsos y vas a tener que incrementar una variable para mantener cuantos overflows tuvo el TMR0
Luego para saber cuanto  es el total serian (VariableContador * 256) + TMR0 = Total de pulsos

Esto hace que tengas todo el micro para lo que vos quieras y ante un delay como los que pusieron no se vea afectado el tema del LCD.


PD: Si quieren hacer algo continua y un menu mejor una maquina de estado, busca en el foro menu CCS y hay varios ejemplos

Desconectado jorgec1996

  • PIC10
  • *
  • Mensajes: 11
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #12 en: 06 de Junio de 2015, 02:33:44 »
y como hago el timer0 como contador? me puse a leer un poco pero no acabo entendiendo, vi algo de un registro option_reg, pero no entiendo porque encuentro codigos en assambler y ninguno en ccs, ya use el picwizard del pic c compiler, active el timer 1 y el timer0, ,puse ext_h_to_l, que agrego en el codigo:
Código: [Seleccionar]
   setup_timer_0(RTCC_EXT_H_TO_L|RTCC_DIV_4);
y ahora que hago para hacerlo contador de pulsos? gracias

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #13 en: 06 de Junio de 2015, 14:28:55 »
El timer es un contador xD

 setup_timer_0(RTCC_EXT_H_TO_L|RTCC_DIV_4);

Si lees supuestamente ahi dice:

RTCC haciendo referencia al TMR0
EXT externo
H_TO_L  alto a bajo, es decir cuenta cuando esta el flanco descendente

RTCC_DIV_4,  Preescaler 1/4 ,  es decir cuando entren 4 pulsos va a contar 1 solo. Mejor tener un preescaler 1/1 , fijate si podes ponerlo con RTCC_DIV_1

Las opciones para poner ahi dentro las vas a encontrar en tu archivo.h , es decir aca:
#include <16F877A.h>
o si buscas desde windows:
c:\Program Files\PICC\Devices\16F877a.h

Ahi deberian aparecerte todas las opciones.
Y la funcion setup_timer_0() deberia modificar los registros OPTION_REG y los demas involucrados


Te pido disculpas que no puedo decirte exactamente como es ya que no uso CCS, soy de los que prefiere el manejo de registros directo y hacerme yo las librerias. Por lo cual prefiero XC8 (Aunque tambien se puede hacer en CCS). Pero CCS es muy bueno para realizar proyectos rapidamente, ya que con una o 2 lineas haces funcioanr las cosas.

Desconectado jorgec1996

  • PIC10
  • *
  • Mensajes: 11
Re: Como aumentar variable al dejar de presionar boton
« Respuesta #14 en: 07 de Junio de 2015, 02:28:11 »
ya tengo casi todo, el timer0 cuenta, no se si lo hice como me decías, la verdad es que intente muchas formas distintas pero no funciono, pero intente ponerlo que la interrupción empiece del 255 asi como esta en codigo:

 
Código: [Seleccionar]
#int_TIMER0
void  TIMER0_isr(void)
{
 personas++;
 set_timer0(255);  
}

y se desborda al 256 y aumenta con un solo pulso del botón, esa manera me funciono bien y no necesito nada mas, la variable aumenta en cualquier parte del programa, ahora en el timer1, lo tengo como estaba, el problema es que no se como hacerle porque habilito las interrupciones en el timer1 y se congela todo el programa, no se que sea, quiza no deba activar las interrupciones en el void main, pero si no es asi cuando las activo y como es lo que dices de comparar un valor viejo del registro con uno nuevo?  Gracias:)