Dudas con contador de objetos PIC18F4550 y CCS

Me indicaron que hiciera un contador de objetos por medio del pic 18f4550 pero tengo 2 problemas.

1. He olvidado como implementar un vector par por medio de un teclado matricial 4*3 escribir dos números.
Es para que una persona decida hasta que número quiere contar, este en realidad cuentas cajas,
y una caja son 4 paquetes (mas o menos por cada 4 objetos se cuenta +1 )
Si me ayudaran sería de grana ayuda.

2. Utilizo un botón para el cambio de estado, y digo que paso un objeto, pero no se puede utilizar un botón.
Yo pensé en un foto diodo pero no se como implementarlo en la programación, así que sería de gran ayuda.

Código:
#include "C:\Users\User\Desktop\timer conteo de piezas\pic c\main.h"
#include "kbd_lib.c"
#include "flex_lcd.c"




void timer0_isr()
{
 output_toggle(PIN_A0);
 set_TIMER0(26474);
}


void main()
{
  int x,i;
  int b;
  char x1;
   port_b_pullups(true);
   
//utilizo el timer 0 como contafor y que los pulsos van de abajo hacia arriba ademas los div son 2 es decir cada 2 pulsos es conta 1+
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_4|RTCC_8_BIT);
set_timer0(0);
//0xff significqa que los ocho pines son entradas
set_tris_a(0xff);
set_tris_d(0x00);
set_tris_b(0x00);
lcd_init();
kbd_init();
   
    lcd_gotoxy(1,1);
      LCD_PUTC ("Bienvenido");
      delay_ms(500);
      for (i=1;i<=16;++i)
         {
         lcd_gotoxy(i,2);
         printf(LCD_PUTC, "*");
         delay_ms( 50 );
         lcd_putc('\f');
         }
   
   while(TRUE)
   {
   
   //agarra el numero
   lcd_gotoxy(1,1);
       printf(LCD_PUTC,"ingrese su numero");
       lcd_gotoxy(2,2);
      printf(LCD_PUTC,"");
       delay_ms(500);
      lcd_putc('\f');
      
      lcd_gotoxy(1,1);
       printf(LCD_PUTC,"0=30 1=31 3=32");
       lcd_gotoxy(2,2);
      printf(LCD_PUTC,"3=33 4=34 5=35");
       delay_ms(500);
      lcd_putc('\f');
       lcd_gotoxy(1,1);
       printf(LCD_PUTC,"6=36 7=37 8=38");
       lcd_gotoxy(2,2);
      printf(LCD_PUTC,"9=39 *=40 #=41");
       delay_ms(500);
      lcd_putc('\f');
      
      
      while(true)
      {
         x1=kbd_getc();
      if(x1!=0)
      {
         lcd_gotoxy(1,2);
      lcd_putc("*");
   delay_ms(80);
   break;
   }
}
   
 switch (x1)
  {

    
 case '0':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==30)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
   break;    
  
  
 
  case '1':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==31)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;




 case '2':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==32)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;

case '3':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==33)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;








case '4':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==34)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;




case '5':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==35)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;


case '6':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==36)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;

case '7':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==37)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;



case '8':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==38)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;




case '9':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==39)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;



case '*':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==40)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;




case '#':

  //get_timer agarra el valor del timer
      while(TRUE)
   {
     x=get_timer0();
     b=x;
     lcd_gotoxy(1,1);
     lcd_putc("\fEL VALOR ES");
     lcd_gotoxy(2,2);
     printf(LCD_PUTC,"%d",x);
     delay_ms(100);
    
     if(b==41)
     {
    
      lcd_gotoxy(1,1);
      printf (lcd_putc,"CONTEO FINALIZADO");
      delay_ms (500);
      lcd_putc ('f');
        
      output_low(PIN_D3);
      delay_ms(300);
      output_high(PIN_D3);
      delay_ms(300);
      output_low(PIN_D3);
      delay_ms(300);
      
       set_timer0(0);
     }
    
   }   
 
break;




}
   }
   }
Gracias.
 
Última edición por un moderador:
hola @andres1594, al microcontrolador no le interesa si es un pulsador o un fotodiodo, solo importa que le llege al pin respectivo los niveles 0 o 1, asi que no hay lio en la programacion. respecto del programa, "como que te esforsaste mucho", adjunto una sujerencia para que puedas tener una mejor idea de como podras mejorar tu proyecto.
 

Adjuntos

  • cont_cajas.rar
    82.4 KB · Visitas: 56
primero muchísimas gracias por responder tengo varias preguntas con respecto a tu programcion (a proposito la tuya es mucho mas eficiente ) pero para futuros ejercicios que pueda yo necesitar me gustaria una pequeñas preguntas
1. veo que no utilizar un vector al menos como yo los he visto que es definiendo el nuemro de espacios en la memoria y al contrario en la parte de la interrupcion utilizas algo asi:

void leer_tecla()
{
do
{
tecla=kbd_getc();
delay_ms(1);
}
while(!tecla);
}

mas o menos lo que haces ahi esque despues de que pida el numero el regrese a la interrupcion y lea los dos numeros???


2. y con respcto a donde guarda los numeros como puedo eso implementarlo en el switch (es para futuros ejercicios) por yo pongo switch (tecla) y lee el ultimo numero ingresado
GRACIAS DE NUEVO
 
Hola andres1594.
1) la librería que maneja el teclado (kbd.c) es la que tiene incorporado el vector de "valores de las teclas" en código ascii ("0123456789#*"), por tanto no hay necesidad de implementar otro vector en el programa principal.
La función kbd_getc() hace la lectura del teclado una sola vez y si no se encuentra una tecla presionada retorna un 0, el bucle do-while hace que el programa se quede esperando hasta que se oprima una tecla y así en la variable tecla se recupera el valor en codigo acsii de la tecla presionada.
void leer_tecla() no es una interrupción, es una subrutina que es llamada dos veces (por el ciclo for de la rutina principal) y así en cada vez que es llamada retorna un valor (el valor de la tecla presionada).
En este programa no se habilita ninguna interrupción por que no se necesita, pero si se habilita al timer0 como contador de eventos externos.
La pregunta 2 no la comprendo bien así que si pudiera aclararlo un poco más podría orientarte mejor.
Un saludo.
 
primero gracias por responder
en la pregunta numero 2 quiero decir que yo implemento el
switch(tecla)
{
case 30:
break;

}

pero no me reconoce y al compilarlo me da error en el 30 (cuando pongo ejemplo 1 no me da error)


y si no es mucha molestia me podes decir si es lo mas probable y mejor utilizar un fototransistor para utilizarlo como pulsador o cual me aconsejas (nunca he utilizado un fototransistor) no tengo mucho tiempo para armar algo muy sofisticado
 
hola andres11594, lo del foto transistor en una buena idea (tambien puede ser un fotodiodo), para el caso del forotransistor necesitas hacer que entre en corte y saturacion (mediante un led infrarrojo), quiza esta informacion te sirva. http://heli.xbot.es/fd/ir.htm
Respecto de la pregunta 2.
no deberia haber ningun erro al usar la sentencia switch(tecla), implemente este codigo y no me dio ningun error.

Código:
void leer_tecla()
{
   do
   {
      tecla=kbd_getc();
      delay_ms(1);
   }
   while(!tecla);
   switch (tecla)
   {
      case 0x30:  //'0'
      {
         tecla='@';
         break;
      }
      case 0x31:  //'1'
      {
         tecla='A';
         break;
      }
      case 0x32:  //'2'
      {
         tecla='B';
         break;
      }
      case 0x33:  //'3'
      {
         tecla='C';
         break;
      }
      case 0x34:  //'4'
      {
         tecla='D';
         break;
      }
      //.
      //.
      //.
   }
}
.
 
Última edición:
muchas gracias por contestar y la verdad lo del switch me ayudo mucho ya que yo utilizaba
swich (tecla)
case '1'
break;


pero lo tuyo me ayudo mucho pero cuando intento hacer el caso 0x40 (ya que puedo elegir del 30 a 50 cajas)me lo toma como si fueran 30 cajas sabes por que puede suceder esto??'
 
Ni idea, que tal si subes todo el proyecto otra vez con las modificaciones que hiciste + una descripcion detallada de en que situacion y como ocurre la falla y asi con codigo en mano podre darte una respuesta mas puntual.
 
como veras el programa utiliza los cases (es una forma menos eficiente) para seleccionar cada caso si por ejemplo presiono 30 hasta 39 funciona prefectamente pero al momento de presionar 40 me sale el conteo hasta 30 gracias
 

Adjuntos

  • timer conteo de piezas.rar
    91.1 KB · Visitas: 53
hola andres1594, te comento que la razon por la cual solo cuenta desde el 30 hasta el 39 a pesar que le introduscas un 45 es. Cuando se hace la lectura del teclado si buen lee dos valores, solo recuperas el ultimo valor presionado.
Por ejemplo.
se oprimen las teclas 4 - 5, el primer valor (4) se recupera como '4' (0x34) y se imprime en el LCD.
el segundo valor (5) se recupera como '5' (0x35), se imprime en el LCD (tecla=0x35) y este es el numero que se usa en la sentencia switch (tecla), dando como maximo valor de conte el 35, esto debido a la condicio if(b=35)
para solucionar esto se debe recuperar los dos valores algo asi como xx=4*10+5. adjunto una sujerencia de como podrias solucionar el problema.
PD. la rutina de interrupcion del timer1 que tienes en tu codigo a pesar que habilitas la interrupcion, no tiene efecto.
 

Adjuntos

  • nuevo.rar
    74.2 KB · Visitas: 38
Buenas noches. Espero no estar equivocandome en preguntar por aca. Pero tengo un problema: estoy diseñando un ssitema mecatronico de empaque de latas, y una de las etapas incluye una cinta transportadora, en la que debo contar de a 4 latas, para activar un actuador, y al 3er ciclo de 4 latas, hacer actuar un manipulador. He encontrado demasiadas cosas, pero como no soy electronico, sino mecanico, me cuesta demasiado. Encontre el siguiente circuito,
https://www.forosdeelectronica.com/proyectos/contador-fotoelectrico.htm
el sistema no termina de convencerme, porque necesito que el sensor sea insensible a la luz normal, por lo que habia decidido utilziar un CNY70. Alguien podria guiarme?
 
Atrás
Arriba