Opciones con un solo pulsador sin usar case

Buenas compic, estoy realizando un proyecto en CCS Compiler y por cuestiones de espacio uso el 12F675, pero que pasa que necesito usar dos salidas para los led indicativos y tres entradas para el manejo pero como tengo que usar el oscilador de cristal externo a 16Mhz en Modo HS, hay dos patillas que les tengo que poner el cristal de cuarzo con sus respectivos condesadores de 30pF y entoces hay es cuando me he encontrado con el problema que me hacia falta patillas sean de entrada y sean de salida en el micro controlador Nano que he comentado y dandole vueltas estaba pensando y si me falta entradas porque en vez de usar un boton para una acción y otro para otra acción, porque no unificarlos de tal manera que al pulsar una sola vez realice esa acción y al pulsar dos veces realice la otra opición y claro en modo SWITCH y CASE, no me sirve porque bien sabeis que cada vez que el contador incrementa va desplazandose por la opciones CASE0, CASE1,CASE2 y sucesivamente, púes bien para mi aplicación no sirve según el número de pulso que reciba tiene que ir derecho.
Resumiendo con este framento del codigo que adjunto lo tengo casi, pero no vale, falla esta claro yo todo lo no se y por ello haber si puedo con vuestra ayuda terminar con mi proyecto y me olvido de que nu puedo usar el TIMER0 púes lo tengo ya trabajando.
Es hacer tan solo que si Pulso a ese unico pulsador dos veces encienda el Led Rojo que le he asignado y si le pulso solo una vez que encienda el Led Verde que le habia asignado, lo he encontrado buscado hilos pero en Arduino.
Un Saludo
 

Adjuntos

  • ButtonSelect.txt
    1.5 KB · Visitas: 10
Hacelo con el switch case, pero con un estado temporal de confirmación en el medio, ejemplo:

- Estado 1: se detecta un pulsado y pasa a Estado 2.
- Estado 2: se espera un timer un cierto tiempo hasta el pulsado 2. Si después del tiempo no hubo un nuevo pulsado, pasá al Estado 3 confirmando un único pulsado y tomá las acciones debidas, en cambio si se detecta otro pulsado, pasá a Estado 4.
- Estado 4: similar al Estado 2, se espera un timer. Si no se detecta nada pasa al Estado 5 confirmando acción 2, en cambio si se detecta otro pulsado, pasá a Estado 6 para otra posible acción.
.... etc.
 
Yo pienso que puedes usar contador

Si pisas botón.
Confirmas a que sueltes
Botón soltado?
Contador ++

Si contador = 1

Acción 1

Si contador = 2
Acción 2

Si contador >= 3

Contador = 0
 
Gracias Trilo-Byte en ello estoy pero falla.
Código:
//Opciones con un solo pulsador sin usar case para no pasar por toda la select Case
//Selección de Opciones con un solo pulsador sin usar case no me sirve
//Programacion en CCS Compiler

#include <12F675.H>
#fuses Hs,Nomclr
#use delay(clock=16000000)
#use fast_io(A)
#locate Puerto_A = 0x05

#bit elije = Puerto_A.1      //Entrada del Pulsador

boolean value1= false;
boolean value2= false;

int pulconta = 0;            //Inicio del Contador

void main()                  //Inicio del Programa             
   {

for (;;)                     //Bucle Infinito
   {
    if (elije == true)       //Condición del Pulsador incrementar
      {
       pulconta++;           //incrementa +1
       delay_ms(100);         
      }
    
    if (pulconta==1)         //Condición al Pulsar solo una vez
      {
       activar_uno;          //Ve hacia la opción activar_uno
       value1=true         
       pulconta = 0;         //Resetea la pulsaciones del Contador á 0
      }

    if (pulconta==2)         //Condición al Pulsar solo una vez
      {
       activar_dos;          //Ve hacia la opción activar_dos
       value2=true
       pulconta = 0;         //Resetea las pulsaciones del Contador á 0
      }

 }   //Cierra el Bucle

}    //Cierra el Void main


void activar_uno (void)
{
   while (value1==true);
   ejecuta acción del value1 ejemplo encender un led Verde
   //value1=false
}

void activar_dos (void)
{
   while (value2==true);
   ejecuta acción del value2 ejemplo encender un led rojo
   //value2=false
}
Mensaje automáticamente combinado:

Buenas cosmefulanito04, gracias de ante mano por tu aporte pero si no me indicas algo de codigo no termino de comprenderte, si puedes intenta agregar ó eliminar al codigo que he puesto para que yo y todos los que nos puedan seguir este hilo, se enteren de lo que estamos comentando y para futuras dudas que pudieran tener. Ya habia comentado que con switch no me sirve y tu dices que se podria, púes demuestramelo que yo lo aplique y te lo reconocere, porque con el detalle que has indicado por lo menos yo que no soy un fuera de serie , pero no me has dejado fuera de sitio sino todo lo contrario fuera de estado.
Mira ya hace unos años cuando yo me incorpore a este foro, abri un tema y nuestro compañero y moderador D@arbytes me cerro el tema y me dijo que este foro es para ayudar a los que no saben y para adquirir conocimientos y que si no se explican las cosas nadie sabe tus propositos y que tampoco somos adivimos. Y me calle la boca llevaba razón, a donde quiero llegar es que no quiero que me escribas el programa, yo la lo tengo escrito y lo he probado en un 16F628A y funciona pero como necesito espacio tengo que hacerlo es un recto para mi y lo bonito de la programación es ver todas las inconitas y es cuestion de tiempo de que lo saque con el 12F675 y tu explicación no me dice nada, por lo menos a mi que no soy experto en el tema de la programación y espero algún dia tener la suerte de saber como tú para poder ayudar a otros si puedo.
 
Mmmmm olvidate de usar delays en tu vida.
Un delay atora el micro el tiempo que le pongas, sin hacer absolutamente nada.

Otra usa switch case, es más eficiente que if.
Switch(contador)
{


Case 1:
Acción 1
Break;

Case 1:
Acción 2
Break;

Case 3:
Contador = 0
Break;

Default:
Break;


Así más o menos.
 
Sería algo así:

C:
....
//-------------- Variable y estados de la máquina de estado ----------------//
#define ESTADO_REPOSO           0
#define ESTADO_PULSADO_1     1
#define ESTADO_ESPERA_1         2
#define ESTADO_PULSADO_2     3
#define ESTADO_ESPERA_2         4
#define ESTADO_CANCELAR       5
uint8_t estado_pulsador=ESTADO_REPOSO;
//-------------- Variable y estados de la máquina de estado ----------------//

int main()
{
  ...
  MaquinaDeEstadoPulsador();
  ...
}

void MaquinaDeEstadoPulsador()
{
    switch(estado_pulsador)
    {
        case ESTADO_REPOSO:
        {
            if(pulsador_on)    //Espero a que se pulse por primera vez el pulsador
                estado_pulsador=ESTADO_PULSADO_1;            
         
            break;
        }
     
        case ESTADO_PULSADO_1:
        {
            if(!pulsador_on)    //Espero a que se suelte el pulsador
                estado_pulsador=ESTADO_ESPERA_1;            
            else
            {
                // Acá se podría evaluar el tiempo y después de un cierto período cancelar la acción usando un ESTADO_CANCELADO => Esto es a gusto personal
                if(timer_espera_hasta_considerar_cancelado_el_pulsado)
                    estado_pulsador=ESTADO_CANCELAR;
            }
         
            break;
        }
     
        case ESTADO_ESPERA_1:
        {
            if(timer_espera_hasta_considerar_el_segundo_pulsado)        
            {
                if(pulsador_on)
                    estado_pulsador=ESTADO_PULSADO_2;
                else
                {
                    //Tomar Acción 1 => se pulsó solo una vez
                 
                    estado_pulsador=ESTADO_REPOSO;    //Al finalizar la acción, reseteamos la máquina a su estado de reposo
                }
            }
                     
            break;
        }
     
        case ESTADO_PULSADO_2:
        {
            if(!pulsador_on)    //Espero a que se suelte el pulsador
                estado_pulsador=ESTADO_ESPERA_2;            
            else
            {
                // Acá se podría evaluar el tiempo y después de un cierto período cancelar la acción usando un ESTADO_CANCELADO => Esto es a gusto personal
                if(timer_espera_hasta_considerar_cancelado_el_pulsado)
                    estado_pulsador=ESTADO_CANCELAR;
            }
         
            break;
        }
     
        case ESTADO_ESPERA_2:
        {
            if(timer_espera_hasta_considerar_otro_pulsado) //Esto se podría seguir repitiendo en "N" acciones        
            {
                if(pulsador_on)
                    //estado_pulsador=ESTADO_PULSADO_3;     En caso de proceder con una acción 3
                else
                {
                    //Tomar Acción 2 => se pulsó dos veces
                 
                    estado_pulsador=ESTADO_REPOSO;    //Al finalizar la acción, reseteamos la máquina a su estado de reposo
                }
            }
                     
            break;
        }
     
        case ESTADO_CANCELAR:
        {
            if(!pulsador_on) //Esperó a que se suelte el pulsador para resetear la máquina de estado
                estado_pulsador=ESTADO_REPOSO;
         
            break;
        }
    }
}

Pude equivocarme en algo, pero la idea es esa. Como verás, la máquina es totalmente repetible en "N" acciones, incluso si se usará otra variable global, se podría usar solamente un ESTADO_PULSADO y un ESTADO_ESPERA y determinar con la segunda variable de que "N" acción se trata.

No estoy teniendo en cuenta los rebotes, esto es muy importante que SI lo tengas en cuenta.
 
Si así es también hay que tomar en cuenta los rebotes y hacer uso del timer.
Y olvidarse de usar delays.

¿Por qué no usas el oscilador interno?
 
Trilo-Byte si lees el PDF del microcontrolador en este caso el 12F675, el oscilador interno es una maximo de 4Mhz y como se necesitan 16Mhz para mi aplicación no llega como veras, para mi hubiera sido mejor porque de esa manera mis entradas y salidas estarian completas y no me haria falta usar lo que he llamado este Tema Button Select.
 
Trilo-Byte si lees el PDF del microcontrolador en este caso el 12F675, el oscilador interno es una maximo de 4Mhz y como se necesitan 16Mhz para mi aplicación no llega como veras, para mi hubiera sido mejor porque de esa manera mis entradas y salidas estarian completas y no me haria falta usar lo que he llamado este Tema Button Select.
Sigo sin entender para que necesitas tanta velocidad si de todos modos le pones delay 🤔.

Es como tener un Ferrari para solo ir al mercado.
Mensaje automáticamente combinado:

También puede usar un antirebotes por hardware, como armar un monoastable o flip-flop.
No se se me hace absurdo hacer anti rebote por hardware si lo puede hacer perfecto el micro.

Yo he usado estos micros con antirrebote y me han funcionado muy bien.
Y el timer lo saturó hasta que se me acaban las ideas.
 
Última edición:
Paliz lee desde el principio del inicio del terma, necesito espacio y no aunmentarlo
Mensaje automáticamente combinado:

Trilo-Byte, las acciones que toma el pulsador son puntuales, eso quiere decir que no voy a estar pulsando continuamente como si fuera un piano en modo ferrari, y el unico delay que lleva es el que captura el cambio que se produce en esa entrada.
 
Última edición:
Disculpe.

¿Por qué tan exigente compañero?
Yo podría pasarte el código que necesitas el problema es que ya a sido tratado N veces este tema en el foro.
 
Perdona si doy esa impresión no intento eso lo que pasa que estoy delante del equipo y estoy dale que dale y no veo manera, he intentado implantar lo que el compic cosmefulanito04 para poder darle la razón si el honbre por casualidad la llevara y para mi como no se ha ajustado a las etiquetas que habia utilizado no veo manera de acoplarlo.
Y si necesito bastante ayuda si puedes pasarme el código os lo agredeceria ati y al resto de compic. Si no ahora cuando podais, tampoco lleva tomate lo que pasa que esto de estar encerrado ya tanto tiempo me esta emparanoyando. De todas formas gracias y perdonar.
 
Pregunta ¿ En algún momento puede darse el caso de que estén los dos LED encendido o en algún momento se apaguen los dos ? Porque si solo esta encendido uno a la vez y jamas o bien los dos encendidos o los dos apagados se podría hacer por hardware.

por cierto, de curioso ¿ que es un compic ?
 
Perdona si doy esa impresión no intento eso lo que pasa que estoy delante del equipo y estoy dale que dale y no veo manera, he intentado implantar lo que el compic cosmefulanito04 para poder darle la razón si el honbre por casualidad la llevara y para mi como no se ha ajustado a las etiquetas que habia utilizado no veo manera de acoplarlo.
Y si necesito bastante ayuda si puedes pasarme el código os lo agredeceria ati y al resto de compic. Si no ahora cuando podais, tampoco lleva tomate lo que pasa que esto de estar encerrado ya tanto tiempo me esta emparanoyando. De todas formas gracias y perdonar.

Sería interesante ver como lo intentaste implementar.
 
Buenas compic, estoy realizando un proyecto en CCS Compiler y por cuestiones de espacio uso el 12F675, pero que pasa que necesito usar dos salidas para los led indicativos y tres entradas para el manejo pero como tengo que usar el oscilador de cristal externo a 16Mhz en Modo HS, hay dos patillas que les tengo que poner el cristal de cuarzo con sus respectivos condesadores de 30pF y entoces hay es cuando me he encontrado con el problema que me hacia falta patillas sean de entrada y sean de salida en el micro controlador Nano que he comentado y dandole vueltas estaba pensando y si me falta entradas porque en vez de usar un boton para una acción y otro para otra acción, porque no unificarlos de tal manera que al pulsar una sola vez realice esa acción y al pulsar dos veces realice la otra opición y claro en modo SWITCH y CASE, no me sirve porque bien sabeis que cada vez que el contador incrementa va desplazandose por la opciones CASE0, CASE1,CASE2 y sucesivamente, púes bien para mi aplicación no sirve según el número de pulso que reciba tiene que ir derecho.
Resumiendo con este framento del codigo que adjunto lo tengo casi, pero no vale, falla esta claro yo todo lo no se y por ello haber si puedo con vuestra ayuda terminar con mi proyecto y me olvido de que nu puedo usar el TIMER0 púes lo tengo ya trabajando.
Es hacer tan solo que si Pulso a ese unico pulsador dos veces encienda el Led Rojo que le he asignado y si le pulso solo una vez que encienda el Led Verde que le habia asignado, lo he encontrado buscado hilos pero en Arduino.
Un Saludo
Mensaje automáticamente combinado:

Hola amigo te doy una idea,, ese micro si mal no recuerdo tiene un conversor analógico digital al igual que el 16f819 que utilice, puedes conectar varios pulsadores a la entrada analógica digital de tu micro con un arreglo de resistencias para obtener diferentes valores en cada pulsador de esa manera le asigna el valor dado de ese pulsador a una acción, ahí le dices al micro si la instrucción correspondiente al convertidor analógico-digital vale x valor aceme tal cosa Sí vale otro valor haceme esta otra cosa y ese valor corresponderá al valor obtenido por la resistencia colocada en ese pulsador yo lo hice y funciona
Mensaje automáticamente combinado:

No lo tengo a mano, pero es asi
 

Adjuntos

  • Screenshot_20210302-075411_Gallery.jpg
    Screenshot_20210302-075411_Gallery.jpg
    66 KB · Visitas: 2
Última edición:
Gracias Richard ya lo se es el conversor ADC, las patilla nombradas como AN0,AN1, etc, lo he utilizado para otras aplicaciones con una resistencia variable en esa entrada ADC, y como diferencial de potencial con teclados, etc... pero no quiero eso porque estamos añadiendo pulsadores y resistencias.
Aqui muestro lo que estoy intentando hacer con el 12F675, este chico que lo ha hecho desde Arduino y mucha gente en su foro distinto del nuestro le decian que si patatin que si patatan y ahi teneis tambien el codigo fuente para quien lo quiera disfrutar. https://www.youtube.com/watch?v=FC_h7Gb994c
 
Trilo-Byte el programa de este chico hecho en arduino, lo he probado en el 12F675 y a mi no me funciona igual estoy haciendo algo mal, me hago mis pinitos pero tampoco me salgo para que me entiendas, bueno yo he seguido sus pasos más ó menos porque las etiquetas son diferentes eso esta claro, pero colocado, adaptado ó inplantado y no te rias, como ayer que dijistes que te gustaria saber como lo habia inplantado no se si por la frase ó por la chapuza que habia hecho con tanto estado. Pero en mi proyecto ni se inmuta. Cuando yo tengo dos pulsadores con esta definicion que pongo ahora si me funciona mi proyecto en el 16F628A sin problemas. Pero nada de nada si uso un solo pulsador :
Código:
void main()
{
for (;;)
{
if (elije1 == true)        //Boton Grabar en Eeprom
Graba ();
if (elije2 == true)        //Boton Borrar en Eeprom
Borra ();
}
}

void Graba (void)
{
   while (elije1==true);
   Led_Verde = 1;
   delay_ms(200);
   Led_Verde = 0;
   y continua con sus procedimientos siguientes etc.....
}

void Borra (void)
{
   while (elije2==true);
   Led_Rojo = 1;
   delay_ms(200);
   Led_Rojo = 0;
   y continua con sus procedimientos siguientes etc...
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
POR EL CONTRARIO SI REALIZO LOS POCOS HILOS QUE HE PILLADO ACONTINUACION NO ME FUNCIONA
///////////////////////////////////////////////////////////////////////////////////////////////////////////

Aqui he tenido claro esta en declara estas otras variables como ejemplo contador y los value1 y 2

int contador=0;
int value1 = false;
int value2 = false;

void main()
{
for (;;)
{
if (elije == true)        //Boton Grabar /Borrar en Eeprom
{
   if (elije == false)
      {
        contador++;
        delay_ms(100);
      }
}

if (contador==1);
{
    Graba ();
    value1 = true;
    value2 = false;
    contador = 0;
}

if (contador==2);
   {
    Borra ();
    value1 = false;
    value2 = true;
    contador = 0;
  }
}   //Cierra el Bucle

}    //Cierra el Void main

void Graba (void)
{
   while (value1==true);
   Led_Verde = 1;
   delay_ms(200);
   Led_Verde = 0;
   y continuaria con sus procedimientos si no fallara siguientes etc.....
}

void Borra (void)
{
   while (value2==true);
   Led_Rojo = 1;
   delay_ms(200);
   Led_Rojo = 0;
   y continuaria con sus procedimientos si no fallara siguientes etc...
}
 
Arriba