TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: mariacontenis en 23 de Abril de 2023, 02:30:02

Título: DTMF ccs c
Publicado por: mariacontenis en 23 de Abril de 2023, 02:30:02
Tengo un código que enciende tres led (rojo, naranja y verde), uno a la ves con diferente código de 6 digitos.
Eneciende el led que quiero correctamecte.

Lo malo es que despues de encender el led seleccionado dura encendido algunos minutos y posteriormente se apaga solo.
Por favor me pueden ayudar y decirme por que se apaga solo?.

Código: C#
  1. #define StD pin_b0
  2.          #define Q1  pin_b4
  3.          #define Q2  pin_b3
  4.          #define Q3  pin_b2
  5.          #define Q4  pin_b1
  6.          
  7.          #define Led_Apagados    output_a(0);
  8.          #define Led_verde       output_a(1);
  9.          #define Led_naranja     output_a(2);
  10.          #define Led_rojo        output_a(4);
  11.          
  12.          int Dig[6]={0,0,0,0,0,0};
  13.          int numero=0, contador=0;
  14.          
  15.          void main()
  16.          {
  17.          porta=0x00; set_tris_a(0b00000000); portb=0x00; set_tris_b(0b11111111); portc=0x00; set_tris_c(0b00000000);
  18.          while(input(StD));
  19.    
  20.          while(TRUE)
  21.          {
  22.          if(input(StD)){
  23.          numero=0;
  24.  
  25.          while(input(StD));
  26.          if(input(Q1)){ numero += 1; }
  27.          if(input(Q2)){ numero += 2; }
  28.          if(input(Q3)){ numero += 4; }
  29.          if(input(Q4)){ numero += 8; }
  30.          Dig[contador]=numero;
  31.          contador++;
  32.          
  33.          if(contador>=6)
  34.          {
  35.          contador=0; numero=0;
  36.          if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12)){ Led_verde    Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }      
  37.          if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12)){ Led_naranja  Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }            
  38.          if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12)){ Led_rojo     Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }      
  39.          if((Dig[0]==11)&&(Dig[1]==3)&&(Dig[2]==1)&&(Dig[3]==2)&&(Dig[4]==3)&&(Dig[5]==1 )){ Led_Apagados Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }      
  40.          
  41.          //Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;
  42.          }
  43.          }
  44.          }
  45.          }
Título: Re:DTMF ccs c
Publicado por: Nocturno en 23 de Abril de 2023, 07:26:40
Si se apagan ellos solitos sin meter ningún código, puede que en realidad esté ocurriendo un RESET del micro.
Puedes confirmarlo metiendo al principio del programa una secuencia de luces, por ejemplo, rojo 1s, naranja 1s, y verde 1s. Así, si ves que se produce esta secuencia en medio del programa sabrás que ha habido un reset.

Otra cosa diferente es evitarlo: habría que ver qué micro es, cuál es el esquema, los fuses del programa, el watchdog...
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 23 de Abril de 2023, 10:20:54
Así es como tengo esta el encabezado del código.

Código: C#
  1. #define VERSION "1.0"
  2.          #if getenv("VERSION") < 5.114                                                 // Realizado con compilador CCS v5.104
  3.          #Warning "COMPILADOR ANTIGUO, ESTE CODIGO FUE DESARROLLADO CON LA VERSION _5_114 DE CCS C"
  4.          #endif
  5.          #include <18f2550.h>                                                          // #include <18f2550.h>                              
  6.          #fuses HS,PROTECT,PUT,WDT,NOBROWNOUT,NOLVP,NOCPD,WRT,MCLR
  7.          #use delay(clock=20000000, crystal=20000000)  
  8.          #if getenv("CLOCK") != 20000000
  9.          #ERROR La velocidad del PIC debe ser de igual a 20Mhz
  10.          #endif

Citar
Si se apagan ellos solitos sin meter ningún código, puede que en realidad esté ocurriendo un RESET del micro.
Puedes confirmarlo metiendo al principio del programa una secuencia de luces, por ejemplo, rojo 1s, naranja 1s, y verde 1s. Así, si ves que se produce esta secuencia en medio del programa sabrás que ha habido un reset.
Me parare bien probar también de esta forma, lo voy hacer y comento.

Algo más en los #fuses si está el watchdog declarado aunque en el cuerpo del programa en ningún momento lo activo. No sé si con solo declararlo en los fuses está realizando el reset.
Título: Re:DTMF ccs c
Publicado por: Nocturno en 23 de Abril de 2023, 11:21:31
Este WDT es la respuesta a tu problema:
Código: [Seleccionar]
#fuses HS,PROTECT,PUT,WDT,NOBROWNOUT,NOLVP,NOCPD,WRT,MCLR
Como comentaba al principio, una de las posibilidades era que el watchdog te estuviera reseteando el micro.
Si el fuse WDT está activado, el watchdog está activo. Su misión es sacar al micro de un posible bucle infinito reseteándolo si no le "das de comer".
Por tanto, tienes dos opciones:
1.- Darle de comer: pones en medio de tu bucle principal el comando restart_wdt(). Yo lo pondría detrás del while (TRUE), como primer comando del bucle.
2.- Evitar que esté activo, cambiando ese fuse por NOWDT. Obviamente con esto perderás la posibilidad del reset si el micro se cuelga, por lo que la opción recomendable es la primera.
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 23 de Abril de 2023, 11:54:50
Gracias Mr. Nocturno. 

Por favor podrías indicarme en el código donde colocarle el restart_wdt(). Dices que detrás del while (true)... Entonces estaría dentro del Main()?.

O correcto como lo entendí?...
Título: Re:DTMF ccs c
Publicado por: Nocturno en 23 de Abril de 2023, 11:58:25
Sí, por ejemplo, aquí:

Código: C
  1. #define StD pin_b0
  2.          #define Q1  pin_b4
  3.          #define Q2  pin_b3
  4.          #define Q3  pin_b2
  5.          #define Q4  pin_b1
  6.          
  7.          #define Led_Apagados    output_a(0);
  8.          #define Led_verde       output_a(1);
  9.          #define Led_naranja     output_a(2);
  10.          #define Led_rojo        output_a(4);
  11.          
  12.          int Dig[6]={0,0,0,0,0,0};
  13.          int numero=0, contador=0;
  14.          
  15.          void main()
  16.          {
  17.          porta=0x00; set_tris_a(0b00000000); portb=0x00; set_tris_b(0b11111111); portc=0x00; set_tris_c(0b00000000);
  18.          while(input(StD));
  19.    
  20.          while(TRUE)
  21.          {
  22.          restart_wdt();
  23.          if(input(StD)){
  24.          numero=0;
  25.  
  26.          while(input(StD)) restart_wdt();;
  27.          if(input(Q1)){ numero += 1; }
  28.          if(input(Q2)){ numero += 2; }
  29.          if(input(Q3)){ numero += 4; }
  30.          if(input(Q4)){ numero += 8; }
  31.          Dig[contador]=numero;
  32.          contador++;
  33.          
  34.          if(contador>=6)
  35.          {
  36.          contador=0; numero=0;
  37.          if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12)){ Led_verde    Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }       // * 1 2 3 4 #
  38.          if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12)){ Led_naranja  Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }       // * 1 9 3 7 #        
  39.          if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12)){ Led_rojo     Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }       // * 4 8 6 2 #
  40.          if((Dig[0]==11)&&(Dig[1]==3)&&(Dig[2]==1)&&(Dig[3]==2)&&(Dig[4]==3)&&(Dig[5]==1 )){ Led_Apagados Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }       // * 3 1 2 3 1
  41.          
  42.          //Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;
  43.          }
  44.          }
  45.          }
  46.          }

Lo he metido en dos sitios, porque ese bucle while que tienes dentro, podría quedarse dando vuelta mucho rato si el usuario deja alguna tecla pulsada mucho tiempo, y también provocaría un reset del micro.
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 23 de Abril de 2023, 12:01:38
Sí, por ejemplo, aquí:

Código: C
  1. #define StD pin_b0
  2.          #define Q1  pin_b4
  3.          #define Q2  pin_b3
  4.          #define Q3  pin_b2
  5.          #define Q4  pin_b1
  6.          
  7.          #define Led_Apagados    output_a(0);
  8.          #define Led_verde       output_a(1);
  9.          #define Led_naranja     output_a(2);
  10.          #define Led_rojo        output_a(4);
  11.          
  12.          int Dig[6]={0,0,0,0,0,0};
  13.          int numero=0, contador=0;
  14.          
  15.          void main()
  16.          {
  17.          porta=0x00; set_tris_a(0b00000000); portb=0x00; set_tris_b(0b11111111); portc=0x00; set_tris_c(0b00000000);
  18.          while(input(StD));
  19.    
  20.          while(TRUE)
  21.          {
  22.          restart_wdt();
  23.          if(input(StD)){
  24.          numero=0;
  25.  
  26.          while(input(StD)) restart_wdt();;
  27.          if(input(Q1)){ numero += 1; }
  28.          if(input(Q2)){ numero += 2; }
  29.          if(input(Q3)){ numero += 4; }
  30.          if(input(Q4)){ numero += 8; }
  31.          Dig[contador]=numero;
  32.          contador++;
  33.          
  34.          if(contador>=6)
  35.          {
  36.          contador=0; numero=0;
  37.          if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12)){ Led_verde    Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }       // * 1 2 3 4 #
  38.          if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12)){ Led_naranja  Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }       // * 1 9 3 7 #        
  39.          if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12)){ Led_rojo     Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }       // * 4 8 6 2 #
  40.          if((Dig[0]==11)&&(Dig[1]==3)&&(Dig[2]==1)&&(Dig[3]==2)&&(Dig[4]==3)&&(Dig[5]==1 )){ Led_Apagados Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0; }       // * 3 1 2 3 1
  41.          
  42.          //Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;
  43.          }
  44.          }
  45.          }
  46.          }

Lo he metido en dos sitios, porque ese bucle while que tienes dentro, podría quedarse dando vuelta mucho rato si el usuario deja alguna tecla pulsada mucho tiempo, y también provocaría un reset del micro.

¿No debería estar también dentro de while(input(StD))?

Así:

Código: C
  1. while(input(StD))
  2. {
  3.    restart_wdt();
  4. }
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 23 de Abril de 2023, 12:04:25
Gracias, lo pruebo y comento que pasa. La verdad me estubo dando vueltas la cabeza toda la noche y me hizo levantar muy temprano para comentar dónde podría estar el error. Gracias nuevamente.
Título: Re:DTMF ccs c
Publicado por: Nocturno en 23 de Abril de 2023, 12:07:12
¿No debería estar también dentro de while(input(StD))?

Así:

Código: C
  1. while(input(StD))
  2. {
  3.    restart_wdt();
  4. }


Se podría poner también ahí, pero he considerado que daría más o menos lo mismo porque en ese bucle sólo se entra si, cuando el micro se enciende por primera vez, el usuario está manteniendo una tecla pulsada. Si eso ocurriera, daría lo mismo que se provocara un RESET porque el programa todavía no ha entrado en el bucle principal.
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 23 de Abril de 2023, 13:30:36
¿No debería estar también dentro de while(input(StD))?

Así:

Código: C
  1. while(input(StD))
  2. {
  3.    restart_wdt();
  4. }


Se podría poner también ahí, pero he considerado que daría más o menos lo mismo porque en ese bucle sólo se entra si, cuando el micro se enciende por primera vez, el usuario está manteniendo una tecla pulsada. Si eso ocurriera, daría lo mismo que se provocara un RESET porque el programa todavía no ha entrado en el bucle principal.

No he analizado el código, pero el OP debería determinar cuando tiempo se queda el CP en ese bucle y también el tiempo de desborde del perro guardián.
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 23 de Abril de 2023, 15:52:25
Gracias Sr. Nocturno
Ahí estaba el detalle diría Cantinflas #fuses WDT  :mrgreen: me estaba reseteando el PIC.

Ya quedo funcionando como requiero.
Título: Re:DTMF ccs c
Publicado por: Nocturno en 23 de Abril de 2023, 16:27:08
Me alegro
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 24 de Abril de 2023, 09:33:00
Cómo casi siempre, me surge otra pregunta... ❓.

Cómo hacerle para guardar los estados de los tres led en la eeprom del pic?....

Código: C#
  1. #define Led_verde       output_a(1);
  2.          #define Led_naranja     output_a(2);
  3.          #define Led_rojo        output_a(4);

En el código una vez confirmado el dato correcto con IF, enciende o apagó alguno de los 3 led. Ahora sí el equipo se apaga por cualquier razón como guardo el estado del led encendido en eeprom para cuando vuelva a energizar se quede en su último estado?.


Título: Re:DTMF ccs c
Publicado por: Nocturno en 24 de Abril de 2023, 10:28:47
Lo haces con el comando write_eeprom y luego recuperas lo escrito con read_eeprom.

La escritura tarda un poco, ten cuidado si tienes interrupciones en tu código que puedan ocurrir durante el proceso.
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 24 de Abril de 2023, 10:42:04
Lo haces con el comando write_eeprom y luego recuperas lo escrito con read_eeprom.

La escritura tarda un poco, ten cuidado si tienes interrupciones en tu código que puedan ocurrir durante el proceso.

¿Qué pasa si cuando esté guardando la info, hay un corte de energía? Me imagino que existe la posibilidad de que se grabe cualquier cosa (datos corrompidos) en la eeprom  ;-)
Título: Re:DTMF ccs c
Publicado por: Nocturno en 24 de Abril de 2023, 11:11:33
Claro, siempre es buena idea leer lo escrito y comprobar errores.
Título: Re:DTMF ccs c
Publicado por: Robert76 en 24 de Abril de 2023, 16:53:51
Cuándo tengo que guardar datos en la EEPROM, lo que hago es monitorear la tensión SIN  REGULAR de la fuente a través de un divisor resistivo, para acondicionarla al ADC.
Entonces cuándo la tensión cae un porcentaje crítico, se activa la rutina de Back-Up. y los datos se guardan en cuestión de milisegundos, antes de que la tensión regulada caiga. :mrgreen:
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 24 de Abril de 2023, 17:09:06
Entonces cuándo la tensión cae un porcentaje crítico, se activa la rutina de Back-Up. y los datos se guardan en cuestión de milisegundos, antes de que la tensión regulada caiga. :mrgreen:

¿Y usas una batería o supercapacitor para taner un poco de energía antes del colapso o con los capacitores de comunes es suficiente?
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 24 de Abril de 2023, 17:11:28
Cuándo tengo que guardar datos en la EEPROM, lo que hago es monitorear la tensión SIN  REGULAR de la fuente a través de un divisor resistivo, para acondicionarla al ADC.

Tal vez sólo el comparador analógico es suficiente en lugar de usar el ADC.
Título: Re:DTMF ccs c
Publicado por: Robert76 en 24 de Abril de 2023, 22:24:33
En realidad luego del condensador de la fuente conecto un diodo y luego otro condensador que se dedica sólo a la alimentación del uP. Con sólo eso, sobra muchísimo tiempo para que el PIC almacene todo lo necesario.
Dije ADC, por dar un ejem. Pero cómodamente se puede hacer con el comparador interno o bien usando un op-amp externo y conectar a una entrada que dispare por interrupción.
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 24 de Abril de 2023, 22:27:29
En realidad luego del condensador de la fuente conecto un diodo y luego otro condensador que se dedica sólo a la alimentación del uP. Con sólo eso, sobra muchísimo tiempo para que el PIC almacene todo lo necesario.
Dije ADC, por dar un ejem. Pero cómodamente se puede hacer con el comparador interno o bien usando un op-amp externo y conectar a una entrada que dispare por interrupción.

En algunos proyectos, yo he recurrido a un EERAM para salvaguardar la información ante una interrupción de la energía.

https://www.microchip.com/en-us/products/memory/serial-eeram (https://www.microchip.com/en-us/products/memory/serial-eeram)
Título: Re:DTMF ccs c
Publicado por: Robert76 en 24 de Abril de 2023, 23:06:43
Es una buena opción la EERAM. Nunca usé una como tal. Salvo la NVRAM, que incluyen los viejos RTC muy usados en los PCs 386.
Y la info está asegurada mientras la pila esté ok :D
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 24 de Abril de 2023, 23:22:16
Es una buena opción la EERAM. Nunca usé una como tal. Salvo la NVRAM, que incluyen los viejos RTC muy usados en los PCs 386.
Y la info está asegurada mientras la pila esté ok :D

Las ocupo porque trabajo con microcontroladores PIC32 y no poseen una EEPROM.

También hay la opción de usar una zona de la memoria de programa (flash) para almacenar datos de usuario, pero me parece que no sería óptimo el proceso que mencionas de un capacitor de respaldo sólo para el microcontrolador y el ADC o Comparador "sintiendo" el estado de la red.

Generalmente hay muchas tareas o hilos que deben entrar en pausa para dar prioridad alta al proceso de almacenar la información.

Y es posible que, algún proceso tome más tiempo del necesario y cuando al fin se pueda proceder a salvaguardar la información, el capacitor ya no tenga suficiente voltaje.

Ahora claro, con un supercapacitor sería otra historia.

 
Título: Re:DTMF ccs c
Publicado por: Robert76 en 25 de Abril de 2023, 06:44:39
En los proyectos que he hecho, y que he necesitado monitorear la red para saber cuándo salvaguardar,  activaba la alerta por interrupción. Por lo tanto NO hay procesos que demanden más tiempo del debido. Ya que he calculado el tiempo que demanda una escritura completa de datos en EEPROM, para conocer el valor del condensador de respaldo, en función del consumo de esa etapa.
Tengo proyectos que llevan más de 10 años funcionando con ese mecanismo, sin problemas. No entiendo porque dices que NO es óptimo, sin tener un esquema electrónico de como lo implementé y sin analizar el código que utilicé.
Está claro, que con el tiempo, los condensadores se degraden y posiblemente haya problemas.
Pero utilizar una EERAM también está condenado al tiempo de vida útil de una pila. Pero eso ya es otra historia.
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 25 de Abril de 2023, 07:49:17
En los proyectos que he hecho, y que he necesitado monitorear la red para saber cuándo salvaguardar,  activaba la alerta por interrupción. Por lo tanto NO hay procesos que demanden más tiempo del debido. Ya que he calculado el tiempo que demanda una escritura completa de datos en EEPROM, para conocer el valor del condensador de respaldo, en función del consumo de esa etapa.
Tengo proyectos que llevan más de 10 años funcionando con ese mecanismo, sin problemas. No entiendo porque dices que NO es óptimo, sin tener un esquema electrónico de como lo implementé y sin analizar el código que utilicé.
Está claro, que con el tiempo, los condensadores se degraden y posiblemente haya problemas.
Pero utilizar una EERAM también está condenado al tiempo de vida útil de una pila. Pero eso ya es otra historia.

Hola, lamento el mal entendido,  me refería a mi caso en particular.

Al no tener una EEPROM interna, debería usar la FLASH, la cual no es tan sencillo acceder, se debe cumplir una serie de pasos para lograr escribir datos en ella.

También, como trabajo en procesos cooperativos, debería verificar primero que todas las tareas entren en pausa o reposo.

Y también al ser un MCU de 32 bits, generalmente suelen funcionar el CPU a altas velocidades (200MHz) y el consumo de energía es grande.

Todas estas razones, digo que en mi caso particular, posiblemente no me permitan seguir tu idea, sería de probarlo, tal vez sea funcional.

Por eso, para evitarme todo lo que expliqué, prefiero usar la EERAM, que básicamente es una RAM donde puedes escribir y leer información de manera rápida. El chip ese necesita tan solo un capacitor de 15 uF, y ante un corte de energía, el contenido de la RAM se guarda en la EEPROM de manera automática.

Al retornar la energía, también de manera automática, el contendió de la EERPOM regresa a la RAM.
Título: Re:DTMF ccs c
Publicado por: Robert76 en 25 de Abril de 2023, 10:31:54
Ok, seguramente no se aplique a todo propósito.
Escribir 1 byte en una EEPROM puede llevar como máximo unos 4ms. A partir de ahí se calcula la constante RC del condensador, con 50% más de margen, sobra.
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 25 de Abril de 2023, 20:49:29
Aquí de nuevo.

E probado el código físicamente y funciona (pero con un pero...), por ahora e dejado aun lado la parte de la eeprom por que recién me di cuenta de un detalle que sucedió probando físicamente.

Les comento que cuando envió las secuencias por ejemplo *1234# enciendo mi LED, mas cuando envió una secuencia incorrecta por ejemplo *12344 el pic se me queda bloqueado y ya no obedece a nada hasta que no lo reinicio. Pense en limpiar el buffer o aplicar quizás el watchdog para reiniciarlo, mas me gustaría saber su opinión como gente de mucha mas experiencia.


Código: C++
  1. if(contador>=6)
  2. {
  3. contador=0;
  4. if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12)) { Led_verde    }       // * 1 2 3 4 #        
  5. if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12)) { Led_naranja  }       // * 1 9 3 7 #        
  6. if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12)) { Led_rojo     }       // * 4 8 6 2 #
  7. if((Dig[0]==11)&&(Dig[1]==2)&&(Dig[2]==6)&&(Dig[3]==8)&&(Dig[4]==4)&&(Dig[5]==12)) { Led_Apagados }       // * 2 6 8 4 #
  8.      
  9. else Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;
  10. }

agregando ese else Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;

o quizás este mal desde if(contador>=6) por que si envió una secuencia menor a 6 dígitos o mayor desde ahí tampoco se cumple la condición :?

Gracias por sus aportes, aprendo mucho de ustedes.

Por favor su ayuda...

Título: Re:DTMF ccs c
Publicado por: DominusDRR en 25 de Abril de 2023, 22:32:53
Aquí de nuevo.

E probado el código físicamente y funciona (pero con un pero...), por ahora e dejado aun lado la parte de la eeprom por que recién me di cuenta de un detalle que sucedió probando físicamente.

Les comento que cuando envió las secuencias por ejemplo *1234# enciendo mi LED, mas cuando envió una secuencia incorrecta por ejemplo *12344 el pic se me queda bloqueado y ya no obedece a nada hasta que no lo reinicio. Pense en limpiar el buffer o aplicar quizás el watchdog para reiniciarlo, mas me gustaría saber su opinión como gente de mucha mas experiencia.


Código: C++
  1. if(contador>=6)
  2. {
  3. contador=0;
  4. if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12)) { Led_verde    }       // * 1 2 3 4 #        
  5. if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12)) { Led_naranja  }       // * 1 9 3 7 #        
  6. if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12)) { Led_rojo     }       // * 4 8 6 2 #
  7. if((Dig[0]==11)&&(Dig[1]==2)&&(Dig[2]==6)&&(Dig[3]==8)&&(Dig[4]==4)&&(Dig[5]==12)) { Led_Apagados }       // * 2 6 8 4 #
  8.      
  9. else Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;
  10. }

agregando ese else Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;

o quizás este mal desde if(contador>=6) por que si envió una secuencia menor a 6 dígitos o mayor desde ahí tampoco se cumple la condición :?

Gracias por sus aportes, aprendo mucho de ustedes.

Por favor su ayuda...

¿Y agregando ese else  (else Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;), también se cuelga el micro?

Porque en teoría, la condición *12344, no cumpliría ningún if, y el contador de programa debería salir del if(contador>=6).
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 25 de Abril de 2023, 22:38:49

¿Y agregando ese else  (else Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;), también se cuelga el micro?


No e probado aún. Antes quince saber su opinión.
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 25 de Abril de 2023, 22:42:45

¿Y agregando ese else  (else Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;), también se cuelga el micro?


No e probado aún. Antes quince saber su opinión.

En teoría no sería necesario, pero parece un error del compilador. Simulando o depurando se podría avanzar paso a paso en el código para determinar el porque se cuelga.

También analizando el desensamblado se podría descartar un error o no del compilador.
Título: Re:DTMF ccs c
Publicado por: Nocturno en 26 de Abril de 2023, 01:58:55
Código: C++
  1. if(contador>=6)
  2. {
  3. contador=0;
  4. if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12)) { Led_verde    }       // * 1 2 3 4 #        
  5. if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12)) { Led_naranja  }       // * 1 9 3 7 #        
  6. if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12)) { Led_rojo     }       // * 4 8 6 2 #
  7. if((Dig[0]==11)&&(Dig[1]==2)&&(Dig[2]==6)&&(Dig[3]==8)&&(Dig[4]==4)&&(Dig[5]==12)) { Led_Apagados }       // * 2 6 8 4 #
  8.      
  9. else Dig[0]=0; Dig[1]=0; Dig[2]=0; Dig[3]=0; Dig[4]=0; Dig[5]=0;
  10. }


Tu programa tiene algunos errores de notación que pueden provocar que el funcionamiento no sea el que se desea. Básicamente después de cada instrucción debes poner ";", y los bloques que quieras que se ejecuten juntos, tienen que estar encerrados entre llaves.
Te falta el ";" al final de cada sentencia if, y te falta encerrar entre llaves el bloque en el que se inicializan los dígitos.
Aparte, aunque no afecta al funcionamiento, a mí me gusta poner cada instrucción en una línea, y las acciones después de los if en la línea posterior y con sangría, lo que mejora la legibilidad.
Quedaría así:

Código: C++
  1. if(contador>=6)
  2.    {
  3.    contador=0;
  4.    if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12))
  5.       { Led_verde    };       // * 1 2 3 4 #        
  6.    if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12))
  7.       { Led_naranja  };       // * 1 9 3 7 #        
  8.    if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12))
  9.       { Led_rojo     };       // * 4 8 6 2 #
  10.    if((Dig[0]==11)&&(Dig[1]==2)&&(Dig[2]==6)&&(Dig[3]==8)&&(Dig[4]==4)&&(Dig[5]==12))
  11.       { Led_Apagados };       // * 2 6 8 4 #  
  12.    else {
  13.       Dig[0]=0;
  14.       Dig[1]=0;
  15.       Dig[2]=0;
  16.       Dig[3]=0;
  17.       Dig[4]=0;
  18.       Dig[5]=0;
  19.    }
  20. }
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 26 de Abril de 2023, 08:28:36

Así me marco error el compilador.
   
Citar
if(contador>=6)
   {
   contador=0;
   if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12))
      { Led_verde    };       // * 1 2 3 4 #       
   if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12))
      { Led_naranja  };       // * 1 9 3 7 #       
   if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12))
      { Led_rojo     };       // * 4 8 6 2 #
   if((Dig[0]==11)&&(Dig[1]==2)&&(Dig[2]==6)&&(Dig[3]==8)&&(Dig[4]==4)&&(Dig[5]==12))
      { Led_Apagados };       // * 2 6 8 4 #   
   else {
      Dig[0]=0;
      Dig[1]=0;
      Dig[2]=0;
      Dig[3]=0;
      Dig[4]=0;
      Dig[5]=0;
   }
}


Deje el else fuera de la condición if(contador>=6) y ahora compila y acepta los ;. Espero este bien de esa manera.

Quedaría así...

Código: C++
  1. if(contador>=6)
  2.          {
  3.          contador=0;
  4.          if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12))
  5.          { Led_verde    };       // * 1 2 3 4 #
  6.          if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12))
  7.          { Led_naranja  };       // * 1 9 3 7 #
  8.          if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12))
  9.          { Led_rojo     };       // * 4 8 6 2 #
  10.          if((Dig[0]==11)&&(Dig[1]==2)&&(Dig[2]==6)&&(Dig[3]==8)&&(Dig[4]==4)&&(Dig[5]==12))
  11.          { Led_Apagados };       // * 2 6 8 4 #
  12.          }
  13.          else {
  14.          Dig[0]=0;
  15.          Dig[1]=0;
  16.          Dig[2]=0;
  17.          Dig[3]=0;
  18.          Dig[4]=0;
  19.          Dig[5]=0;
  20.          }

Título: Re:DTMF ccs c
Publicado por: Nocturno en 26 de Abril de 2023, 08:30:06
¿Qué error?
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 26 de Abril de 2023, 08:38:09
Con el else fuera no enciende ningun led jejejeje, creo que por que si es menor de 6 digitos los eta limpiando. Por lo tanto esto que puese esta mal.  :( entonce el else si debe estar dentro del  if(contador>=6){.



Citar
if(contador>=6)
         {
         contador=0;
         if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==2)&&(Dig[3]==3)&&(Dig[4]==4)&&(Dig[5]==12))
         { Led_verde    };       // * 1 2 3 4 #
         if((Dig[0]==11)&&(Dig[1]==1)&&(Dig[2]==9)&&(Dig[3]==3)&&(Dig[4]==7)&&(Dig[5]==12))
         { Led_naranja  };       // * 1 9 3 7 #
         if((Dig[0]==11)&&(Dig[1]==4)&&(Dig[2]==8)&&(Dig[3]==6)&&(Dig[4]==2)&&(Dig[5]==12))
         { Led_rojo     };       // * 4 8 6 2 #
         if((Dig[0]==11)&&(Dig[1]==2)&&(Dig[2]==6)&&(Dig[3]==8)&&(Dig[4]==4)&&(Dig[5]==12))
         { Led_Apagados };       // * 2 6 8 4 #
         }
         else {
         Dig[0]=0;
         Dig[1]=0;
         Dig[2]=0;
         Dig[3]=0;
         Dig[4]=0;
         Dig[5]=0;
         }
Título: Re:DTMF ccs c
Publicado por: Nocturno en 26 de Abril de 2023, 10:40:12
Ok, ¿ya te funciona?
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 26 de Abril de 2023, 12:15:46
Citar
Ok, ¿ya te funciona?

No funciona, así como mente. Creo que mi código es muy básico y sigue sin funcionar si envío una secuencia por ejemplo 345 es decir, con menos dígitos.

Creo que faltan más condiciones.

Gracias por preguntar..
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 26 de Abril de 2023, 12:21:52
Citar
Ok, ¿ya te funciona?

No funciona, así como mente. Creo que mi código es muy básico y sigue sin funcionar si envío una secuencia por ejemplo 345 es decir, con menos dígitos.

Creo que faltan más condiciones.

Gracias por preguntar..

Sube el desensamblado para ver si es problema del compilador
Título: Re:DTMF ccs c
Publicado por: Nocturno en 26 de Abril de 2023, 14:43:38
Citar
Ok, ¿ya te funciona?

No funciona, así como mente. Creo que mi código es muy básico y sigue sin funcionar si envío una secuencia por ejemplo 345 es decir, con menos dígitos.

Creo que faltan más condiciones.

Gracias por preguntar..


Pero cuéntanos qué debe ocurrir cuando se metan menos dígitos. ¿Cuál sería el objetivo deseable en ese caso?
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 26 de Abril de 2023, 15:09:34
Citar
Pero cuéntanos qué debe ocurrir cuando se metan menos dígitos. ¿Cuál sería el objetivo deseable en ese caso?

Bueno el sistema solo debe de encender uno de los LED si su código que entra es correcto.

Si entra un código incorrecto debe de ignorar. Ayer probando físicamente entiende el led correspondiente al código de entrada. Pero si entra una DTMF diferente o si no llega a leer correctamente el dtmf el pic ya no responde si vuelvo a enviar un código correcto.

Lo que quiero es que ignore cualquier.otro código que no sea el correcto al que enciende el led correspondiente. Y si llega cualquier código menor o mayor o diferente al correcto que lo ignore y que no se quede  bloqueado mi pic. Por qué vuelve a funcionar hasta que lo reinicie.

Una disculpa quizás hablo mucho y no me doy a entender..

Título: Re:DTMF ccs c
Publicado por: Nocturno en 26 de Abril de 2023, 15:14:31
Vale, en ese caso, como la primera condición que tu programa comprueba es que el Contador sea mayor o igual que 6, al meter menos dígitos, no se ejecuta ese bloque.

Yo cambiaría esa condición por:
Código: C
  1. if(contador==6)
y abajo del todo pondría un
Código: C
  1. else {
  2.   // Aquí debes poner lo que quieras que ocurra cuando se pulsen menos o más dígitos
  3. }

Otra cosa que debes tener en cuenta es si este bloque de código se ejecuta siempre, mientras el usuario está tecleando, o sólo cuando ha terminado.
Si se trata de lo primero, ¿cómo sabemos que ha terminado de teclear?, ¿porque tarda demasiado o por meter el dígito #?
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 26 de Abril de 2023, 16:07:22
Citar
Pero cuéntanos qué debe ocurrir cuando se metan menos dígitos. ¿Cuál sería el objetivo deseable en ese caso?

Bueno el sistema solo debe de encender uno de los LED si su código que entra es correcto.

Si entra un código incorrecto debe de ignorar. Ayer probando físicamente entiende el led correspondiente al código de entrada. Pero si entra una DTMF diferente o si no llega a leer correctamente el dtmf el pic ya no responde si vuelvo a enviar un código correcto.

Lo que quiero es que ignore cualquier.otro código que no sea el correcto al que enciende el led correspondiente. Y si llega cualquier código menor o mayor o diferente al correcto que lo ignore y que no se quede  bloqueado mi pic. Por qué vuelve a funcionar hasta que lo reinicie.

Una disculpa quizás hablo mucho y no me doy a entender..

Creo que deberías usar la tecla # como un "enter" es decir que cuando se ingrese una serie de números, el momento que presiones # se ejecute el analices de los datos ingresados, entonces si ingresas menos, por ejemplo 1, 3, la tecla # desencadena todo el proceso.
Título: Re:DTMF ccs c
Publicado por: mariacontenis en 27 de Abril de 2023, 09:29:19
Ya quedo solucionado :mrgreen:

Gracias Nocturno y gracias DominusDRR, por su apoyo, aunque esto sigue y espero no enfadarlos. Esto lo tome de los dos y así quedo la condición para que ya no se bloqueara:

Código: C++
  1. if(contador==6)

Código: C++
  1. if((contador>6 || Dig[0]!=11) || (Dig[5]!=12)){ goto inicio; }
Título: Re:DTMF ccs c
Publicado por: DominusDRR en 27 de Abril de 2023, 09:31:24
Ya quedo solucionado :mrgreen:

Gracias Nocturno y gracias DominusDRR, por su apoyo, aunque esto sigue y espero no enfadarlos. Esto lo tome de los dos y así quedo la condición para que ya no se bloqueara:

Código: C++
  1. if(contador==6)

Código: C++
  1. if((contador>6 || Dig[0]!=11) || (Dig[5]!=12)){

Está raro ese compilador, solo por curiosidad quisiera ver el código ensamblador del proyecto que se quedaba "colgado"