Página 1 de 3

BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 04 Jul 2014 15:00
por eloyfm
Ola Pessoal..

Já faz um tempo que estou tentando fazer um codigo para utilizer com um botao, onde ele deve ter duas funções.

Tentei varias formas mas inclusive o Switch case não funiona correto ( tipo, tenho qu eapertar mais vezes do qu eo previsto no codito ) para que seja reconhecido..

Preciso que uma tecla funcione normalmente acendendo e apagando um LED ( liga e desliga )..
Se segura por 2 segundos ela acende esse LED e entra em tipo modo MEnu, ou programação.
Dependendo das quantidades que apertar ( maximo de 9 ) ela terá que acender outros leds pela mudança de valores de uma variavel..

Quase consegui fazer funcionar, mas não vai nem a pau...

Alguem pode me dar uma luz pelo menos para eu encontrar o caminho desse problema e continuar com o meu projetinho ?

Como falei, eu já tentei com o Switch Case, mas não funciona direito.. As vezes tem que apertar 3 vezes para ele pular para a linha que
só deveria ir se fosse apertado uma vez..

com esse monte de IF eu até consegui fazer alguma cois afuncionar, mesmo assim aparece uns BUGs que acendem leds errados etc...

cpp code
void main()
{
set_tris_B(0b00000000);
output_B(0b00000000);
set_tris_A(0b00010000);
while(true)
{
while(!input(botao)) //ENQUANTO SEGURO O BOTÃO
{
cont=cont+10;
delay_ms(22);
if(cont ==3000)
{
led2=~led2;
output_bit(pin_B0,led2); // LED ACESSO
prog=~prog;
delay_ms(100);
amp=0;
}
}
cont=0;

if (!input(botao)&& va3==0 &&( prog == 1 ))
{
delay_us(50);
va3++;
}
if (input(botao) && va3 == 1 )
{
delay_ms(100);
amp++;
va3=0;
}
if(amp == 1 )va1=3;
if(amp == 2 )va1=4;
if(amp == 3 )va1=5;
if(amp == 4 )va1=6;
if(amp == 5 )va1=7;
if(amp == 6 )va1=8;
if(amp == 7 )va1=9;

if(va1 == 3 ) output_bit(pin_b1,1);
if(va1 == 4 ) output_bit(pin_b2,1);
if(va1 == 5 ) output_bit(pin_b3,1);
if(va1 == 6 ) output_bit(pin_b1,0);
if(va1 == 7 ) output_bit(pin_b2,0);
if(va1 == 8 ) output_bit(pin_b3,0);

if(va1 >=9 )
{
amp=1;
}


Agradeço a ajuda..

Eloy

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 04 Jul 2014 16:55
por andre_luis
Uma boa prática em programação é estruturar o código em funções separadas de acordo com o que fazem, ainda que tendo de abrir várias camadas em hierarquia, e preferencialmente sendo bem descritivas no nome quanto ás tarefas que executam.

Segue abaixo uma dica de algo que acabei de fazer, mas me parece um pouco mais fácil de debugar:

cpp code
#define TECLA_MODO_PADRAO				1
#define TECLA_MODO_MENU 2

#define TEMPO_MAXIMO_MODO_PADRAO xxxx // xxxx definido empiricamente

#define TEMPO_INTERVALO_CADA_FUNCAO yyyy*(TEMPO_MAXIMO_MODO_PADRAO) // yyyy definido empiricamente

#define TEMPO_INTERVALO_FUNCAO_1 1*(TEMPO_INTERVALO_CADA_FUNCAO) // ajustar '1' empiricamente
#define TEMPO_INTERVALO_FUNCAO_2 2*(TEMPO_INTERVALO_CADA_FUNCAO) // ajustar '2' empiricamente
#define TEMPO_INTERVALO_FUNCAO_3 3*(TEMPO_INTERVALO_CADA_FUNCAO) // ajustar '3' empiricamente
#define TEMPO_INTERVALO_FUNCAO_4 4*(TEMPO_INTERVALO_CADA_FUNCAO) // ajustar '4' empiricamente
#define TEMPO_INTERVALO_FUNCAO_5 5*(TEMPO_INTERVALO_CADA_FUNCAO) // ajustar '5' empiricamente
#define TEMPO_INTERVALO_FUNCAO_6 6*(TEMPO_INTERVALO_CADA_FUNCAO) // ajustar '6' empiricamente
#define TEMPO_INTERVALO_FUNCAO_7 7*(TEMPO_INTERVALO_CADA_FUNCAO) // ajustar '7' empiricamente
#define TEMPO_INTERVALO_FUNCAO_8 8*(TEMPO_INTERVALO_CADA_FUNCAO) // ajustar '8' empiricamente
#define TEMPO_INTERVALO_FUNCAO_9 9*(TEMPO_INTERVALO_CADA_FUNCAO) // ajustar '9' empiricamente

#define FUNCAO_TECLA_ACIONADA_LED 0
#define FUNCAO_TECLA_ACIONADA_1 1
#define FUNCAO_TECLA_ACIONADA_2 2
#define FUNCAO_TECLA_ACIONADA_3 3
#define FUNCAO_TECLA_ACIONADA_4 4
#define FUNCAO_TECLA_ACIONADA_5 5
#define FUNCAO_TECLA_ACIONADA_6 6
#define FUNCAO_TECLA_ACIONADA_7 7
#define FUNCAO_TECLA_ACIONADA_8 8
#define FUNCAO_TECLA_ACIONADA_9 9

char ModoOperacaoTecla = TECLA_MODO_PADRAO ;
char FuncaoAcionada = FUNCAO_TECLA_ACIONADA_LED ;
int TempoDeAcionamento = 0 ;

//////////////////////////////////////////////////////////////////////
void AnalisaTeclaPressionada ( void )
{
if (input(botao)) // ENQUANTO SEGURO O BOTÃO APENAS MEDE O TEMPO
{
if ( TempoDeAcionamento < ((2^16)-1) ) TempoDeAcionamento++ ; // EVITA QUE CONTAGEM TRANSBORDE MAGNITUDE DO TIPO "INT"
DelayMS ( zzzz ) ; // DELAY PODE SER NECESSARIO, AVALIAR EMPIRICAMENTE
}
else // BOTAO FOI LIBERADO, DECIDE A FUNCAO SELECIONADA
{
if ( TempoDeAcionamento < TEMPO_MAXIMO_MODO_PADRAO )
{
ModoOperacaoTecla = TECLA_MODO_PADRAO ;
FuncaoAcionada = FUNCAO_TECLA_ACIONADA_LED ;
}
else
{
ModoOperacaoTecla = TECLA_MODO_MENU ;
if ( TempoDeAcionamento < TEMPO_INTERVALO_FUNCAO_2 ) FuncaoAcionada = FUNCAO_TECLA_ACIONADA_1 ;
if ( TempoDeAcionamento < TEMPO_INTERVALO_FUNCAO_3 ) FuncaoAcionada = FUNCAO_TECLA_ACIONADA_2 ;
if ( TempoDeAcionamento < TEMPO_INTERVALO_FUNCAO_4 ) FuncaoAcionada = FUNCAO_TECLA_ACIONADA_3 ;
if ( TempoDeAcionamento < TEMPO_INTERVALO_FUNCAO_5 ) FuncaoAcionada = FUNCAO_TECLA_ACIONADA_4 ;
if ( TempoDeAcionamento < TEMPO_INTERVALO_FUNCAO_6 ) FuncaoAcionada = FUNCAO_TECLA_ACIONADA_5 ;
if ( TempoDeAcionamento < TEMPO_INTERVALO_FUNCAO_7 ) FuncaoAcionada = FUNCAO_TECLA_ACIONADA_6 ;
if ( TempoDeAcionamento < TEMPO_INTERVALO_FUNCAO_8 ) FuncaoAcionada = FUNCAO_TECLA_ACIONADA_7 ;
if ( TempoDeAcionamento < TEMPO_INTERVALO_FUNCAO_9 ) FuncaoAcionada = FUNCAO_TECLA_ACIONADA_8 ;
else FuncaoAcionada = FUNCAO_TECLA_ACIONADA_9 ;
}
TempoDeAcionamento = 0 ;
RealizaAcaoEmFuncaoDaTeclaPressionada() ;
}
}
//////////////////////////////////////////////////////////////////////
void RealizaAcaoEmFuncaoDaTeclaPressionada ( void )
{
switch ( ModoOperacaoTecla )
{
case TECLA_MODO_PADRAO :
led2=~led2;
output_bit(pin_B0,led2); // LED2 INVERTE STATUS ANTERIOR
break;

case TECLA_MODO_MENU :
// INSERIR SUAS ROTINAS AQUI
switch ( FuncaoAcionada )
{
case FUNCAO_TECLA_ACIONADA_1 : { } break ;
case FUNCAO_TECLA_ACIONADA_2 : { } break ;
case FUNCAO_TECLA_ACIONADA_3 : { } break ;
case FUNCAO_TECLA_ACIONADA_4 : { } break ;
case FUNCAO_TECLA_ACIONADA_5 : { } break ;
case FUNCAO_TECLA_ACIONADA_6 : { } break ;
case FUNCAO_TECLA_ACIONADA_7 : { } break ;
case FUNCAO_TECLA_ACIONADA_8 : { } break ;
case FUNCAO_TECLA_ACIONADA_9 : { } break ;
}
break;
}
}
//////////////////////////////////////////////////////////////////////
void main()
{
set_tris_B(0b00000000);
output_B(0b00000000);
set_tris_A(0b00010000);
while(true)
{
AnalisaTeclaPressionada() ;
}
}


+++

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 04 Jul 2014 21:35
por eloyfm
André,
A coisa parece ser bem maix complexa do que pensei que estava fazendo. Certamente terei que estudar esse exemplo para pescar
a ideia que voce postou. Realmente sou Novato demais, mas sou teimoso tambem..rs... vou tentar entender tudo isso e retorno com
os meus achados.. rs... obrigado..

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 05 Jul 2014 19:15
por ze
com relação a tempo de pressão num botão, veja esta conversa recente...
viewtopic.php?f=10&t=15994
vc pode implementar + funções no botão com algo como...
Código: Selecionar todos
#define TECLA GPIO2
#define LED GPIO0
void main(void)
{
unsigned char x;
//...
while(true) {
if(!TECLA)// pro gnd
{
x++;
delayms(1000); //1 segundo
if (x==2) {LED=1;MEnu();}//"Se segura por 2 segundos ela acende esse LED e entra em tipo modo MEnu, ou programação."
if (x==3) LED^⁼1;//output_toggle(pin_a0);
if (x==4) LED⁼1;
if (x==5) LED⁼0;
if (x==6) funcao1();
if (x==7) funcao2();
if (x==8) funcao3();
}
else x=0;//reinicializa
}

espero que seja norte++;
de fato vc vai perceber que o que está debaixo do if (x==2) pode não ocorrer. Caso entenda a essência, podemos fazer uma função que retorna o tempo de tecla pressionada. Tenta aí e se não conseguir... continue tentando . rs. (brinc. tamozaí...)
abç

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 05 Jul 2014 19:58
por eloyfm
A parte que acende o LED depois de algum tempo apertado funcionou bem. Eu nao sei se esta correto, ou se pode criar algum problema no resto do
programa, pois após tudo ainda terei que fazer uma matriz para acender e apagar 27 leds com a variaveis modificadas com os resultados dos cases,
mas o meu problema maior é o "switch".. EM principio eu fiz como esta aqui abaixo e depois de quebrar a cabeça eu resolve fazer com IFs..
só que se eu tiver qu efazer varios botoes, ou seja, multimplicar tudo isso por 9 não sei se a coisa vai acabar dando problema..

Esse abaixo é o primeito que eu fiz e o problema é que nunca cai na quantidade correta que foi apertada.. Pensei que pudesse ser o Proteus,
e montei uma placa, mas mesmo assim o problema persiste.. As contagens das pressionadas não coincide com as linhas cos Cases..

Abs

cpp code
void main()
{
set_tris_B(0b00000000);
output_B(0b00000000);
set_tris_A(0b00010000); // usando o A4 para o botao..
while(true)
{
while(!input(botao)) //ENQUANTO SEGURO O BOTÃO
{
cont=cont+10; // incrementa a variavel cont até chegar em 3000.
delay_ms(22);
if(cont ==3000) // somente quando cegar a 3000 entra na função
{
led2=~led2; // inverte estado e acende led
output_bit(pin_B0,led2); // LED ACESSO
prog=~prog; // inverte estado variavel prog só para habilitar a outra funcão que vem adiante.
delay_ms(100);
amp=0; // coloca a variavel amp em um para iniciar o incremento na função abaixo
}
}
cont=0; // zera a variavel para nao entrar novamente


if(!input(botao)&& prog <= 1 ) // so deve entrar nessa função se o botao for pressionado e e avariavel prog estiver em um.

{
delay_ms(100);
prog1++; // incrementa a variavel para escolher uma abaixo


switch (prog1) //switch case
{
case 1:output_bit(pin_d3,1); // se o incremento acima chegar em 1 acende o led D3
break;

case 2:output_bit(pin_d4,1); // se contagem chegou em 2 acende o led D4
break;

case 3:output_bit(pin_d5,1); // se contagem chegar em3 acende led D5
break;

case 4:output_bit(pin_d6,1); // se contagem chegou em 4 acende o led D6
break;

default:output_bit(pin_d7,1); // acende o led D7 se for diferente..
}
}
}
}

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 05 Jul 2014 22:59
por MOR_AL
Neste sítio, o sujeito usa apenas um botão para selecionar diversas funções.
Vai depender de quanto tempo o botão fica pressionado.
Veja o fluxograma.
http://www.pcbheaven.com/picpages/A_Clever_Button/
MOR_AL

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 05 Jul 2014 23:31
por andre_luis
eloyfm escreveu:o problema é que nunca cai na quantidade correta que foi apertada..


Conta pra mais ou pra menos ?



+++

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 06 Jul 2014 10:56
por edsont
MOR_AL escreveu:Neste sítio, o sujeito usa apenas um botão para selecionar diversas funções.


Isso me lembra código morse...

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 06 Jul 2014 18:16
por eloyfm
To tentando fazer para cima,
Como comentei.
O Bloco que acende o led depois de 3 Segundo eu consegui. Logo dentro do mesmo bloco eleva o valor de uma variavel para ser reconhecida no proximo bloco.
Depois que o LED esta aceso e a variavel em 1


1- while(!input(botao)) //ENQUANTO EU PRESSIONO O BOTÃO

2- cont=cont+10;
3- delay_ms(22);

4- if(cont ==3000)
5- {
6- led2=~led2;
7- delay_ms(200);
8- output_bit(pin_B0,led2);
9- delay_ms(100);
10- prog=~prog; ******************
11- }
===================================até aqui é o bloco que espera 3 segundos para acender o led e mudra a variavel PROG p/1
===================================fim do modulo que entra em programação e acende o LED ========================

12- if (!input(botao)&& prog==1 && va3==0) ========se a variavel ( for PROG==1 ) ele entra no IF.. aí tem que incrementar a variavel (AMP++ ) mas isso
13- { ===============não esta acontecendo ============== se eu mudo a variavel para PROG=1 fora do
(while-botao) ai entra no bloco abaixo e funciona, mas dentro do while a função prog=~prog nao funciona.

14- delay_us(50);
15- va3=1;
16- }

17- if (input(botao) && va3 == 1 )
18- {
19- delay_ms(50);
20- amp++;
21- va3=0;
22- }

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 06 Jul 2014 18:27
por MOR_AL
edsont escreveu:
MOR_AL escreveu:Neste sítio, o sujeito usa apenas um botão para selecionar diversas funções.


Isso me lembra código morse...


Não é o código morse, mas poderia até ser utilizado, caso fossem necessárias muitas funções distintas.
Com o código morse haveriam apenas dois períodos; um menor que T1 e outro maior que T2, sendo T2 maior que T1.
Aí o código poderia ser constituído por, digamos 3 unidades, que poderiam gerar 8 funções diferentes.
Bem lembrado, Edsont.
MOR_AL

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 06 Jul 2014 18:36
por eloyfm
Resumindo eu preciso de algo bem mais simples.

Segura o botao ( muda uma variavel de 0 para 1 com o ~) e vice versa se apertado novamente pra 0.
Depois um IF ou outra coisa que funcione só se apertar esse botao novamente e que essa variavel esteja em 1.
Se estiver em 0 nao funciona.. quer dizer ( saiu do modo )..

Obrigado

Eloy..

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 06 Jul 2014 19:03
por MOR_AL
eloyfm escreveu:Resumindo eu preciso de algo bem mais simples.

Segura o botao ( muda uma variavel de 0 para 1 com o ~) e vice versa se apertado novamente pra 0.
Depois um IF ou outra coisa que funcione só se apertar esse botao novamente e que essa variavel esteja em 1.
Se estiver em 0 nao funciona.. quer dizer ( saiu do modo )..

Obrigado

Eloy..


Se eu entendi bem, siga este fluxograma em pseudo código.
Imagem
Depois do bloco Var = ~Var, você pode incluir o que desejar, desde que Var seja '0' ou '1'.
MOR_AL

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 06 Jul 2014 19:11
por andre_luis
eloyfm escreveu:Segura o botao ( muda uma variavel de 0 para 1 com o ~) e vice versa se apertado novamente pra 0.
Depois um IF ou outra coisa que funcione só se apertar esse botao novamente e que essa variavel esteja em 1.
Se estiver em 0 nao funciona.. quer dizer ( saiu do modo )


A lógica que sugeri mais acima, baseado no tempo de pressionamento do botão não funcionou ?
Te confesso que olhando agora com mais calma, não realiza exatamente do modo que voce quer, mas chega perto, tendo de alterar pouca coisa.

eloyfm escreveu:Preciso que uma tecla funcione normalmente acendendo e apagando um LED ( liga e desliga )..
Se segura por 2 segundos ela acende esse LED e entra em tipo modo MEnu, ou programação.
Dependendo das quantidades que apertar ( maximo de 9 ) ela terá que acender outros leds pela mudança de valores de uma variavel..




+++

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 06 Jul 2014 20:04
por eloyfm
Pessoal.. Obrigão pela força....

Eu to vendo que o programa não sai de dentro do laço - while(!input(botao)) depois que entra..
Se eu coloco somente esse laço while para dar o tempo do botao , isso funciona.
Se eu coloco somente o bloco qu evai incrementar as variaveis ( tbem funciona beleza O
Quando eu coloco o Segundo bloco dependendo do bloco while botao aí a cois apega.. Me parece que quando ele inverte a variavel ( prog=~prog) ela não sai de dentro do laço. Tudo que foi feito la dentro fica assim.. Ex. é o LEd2.. Ele inverte e acendede o RB0 e depois inverte e apaga. Mas eu não posso por exemplo usar essa
variavel for a do while que não vai funcionar..

O problema esta para SAIR DO LAÇO WHILE.. e usar o o estado que ficou a variavel PROG.

Será que eu não estou fazendo algo errado para sair do while ?

Re: BOTAO COM MAIS DE UMA FUNÇÃO

MensagemEnviado: 06 Jul 2014 21:14
por andre_luis
eloyfm escreveu:Eu to vendo que o programa não sai de dentro do laço - while(!input(botao)) depois que entra..


Como comentei antes, seu programa não está bem estruturado, laços infinitos não são recomendados.
Na verdade, parece que você está utilizando da velha prática de elaborar o código conforme vai escrevendo.

Repare que no modelo que apresentei acima, o while não é usado na leitura do botão, exceto obviamente no main().
Sugiro você desenhar um esboço do fluxograma no papel tal como fez o MOR_AL, e depois irmos fazendo passo a passo.




+++