Ir ao conteúdo

Posts recomendados

Postado

Pessoal, estou com um problema na programação de um dispositivo que detecta quedas de tensão da rede acima de 4%. Eu preciso que a programação calcule as quedas de 4% a 7%, ligando um led verde se está abaixo de 4%, um led amarelo se está entre 4% e 7% e um led vermelho acima de 7%.

Segue abaixo o que consegui fazer até agora.

//armazenamento das tensões
int tensao1 = 0x00;
int tensao2 = 0x00;

// declara as variáveis
int a, b, x, y;

void volts()
{
 if (tensao1==0)//tensao1 igual a zero
 {
 tensao1 = ADC_Read(0);
 }
 //Lê canal AN0 apenas uma vez e transfere seu valor para tensao1
 
 else if (tensão==1)//tensão1 diferente de 0
 {
 tensao2 = ADC_Read (0);//Lê o canal AN0
 delay_ms(100);//atualiza a cada 100ms
 }
}//end função volts

void main()
{
  ANSEL = 0x01;// AN0 como entrada analogica
  ADCON0 = 0x01;// seleciona a entrada AN0
  ADCON1 = 0x0E;
  CMCON0 = 0x07;//desliga os comparadores

  //configura PORTA
  TRISA = 0xFF;// AN0 entrada
  PORTA = 0x00;// PORTA em nvl baixo

  //configura PORTC
  TRISC = 0xFF;// PORTC como saída
  PORTC = 0x00;// PORTC em nvl baixo
  
  a = (tensao1*(4/100));//4% da tensão nominal
  b = (tensao1*(7/100));//7% da tensão nominal
  x = tensao1-a;//tensão nominal-4%
  y = tensao1-b;//tensão nominal-7%

    if (tensao2>x)// se a queda estiver menor que 4%, liga o led verde
    {
  
      RA1_bit = 1;//led verde ligado
      RA2_bit = 0;//led amarelo desligado
      RC0_bit = 0;//interrupção desligada
    }

       else if (tensao2>y && tensao2<=x)// se a queda estiver entre 4% e 7%, liga o led amarelo
      {
            RA2_bit = 1;//led amarelo ligado
            RA1_bit = 0;//led verde desligado
            RC0_bit = 0;//interrupção desligada
      }

      else (tensao2<y);// se a queda for maior que 7%, liga o circuito de interrupção e o led vermelho
      {
            RC0_bit = 0;//interrupção ligada
            RA1_bit = 0;//led verde desligado
            RA2_bit = 0;//led amarelo desligado

      }
 }// end função principal

 

  • Membro VIP
Postado

Falta o loop na função principal

 

1 hora atrás, Grupo de TCC disse:

detecta quedas de tensão da rede acima de 4%. Eu preciso que a programação calcule as quedas de 4% a 7%, ligando um led verde se está abaixo de 4%, um led amarelo se está entre 4% e 7% e um led vermelho acima de 7%.

Penso que isso se resolve em poucas linhas. De fato de posse dos sabidos valores em ad, nem é necessária nenhuma conversão para porcentagem. Dica: envie primeiro os valores pra um terminal pra visualizá-los e anotá-los

 

#define ledVerde Ra1bit;
#define ledVAmarelo Ra2bit;
#define ledVemelho Rc0bit;
#define _4pc 20 //p.ex.
#define _7pc 35 //p.ex.
unsigned int Vok,V;
main()
{
//setup do hw
Vok=adcread(0);//registra valor correto. Consideremos que 512, a metade dos 10 bits, é 100%
for(;;)
	{
	V=adcread(0);
	if (V>Vok-_4pc) ledVerde=1; else {ledVerd=0;ledAmarelo=1;}
	if (V>Vok-_7pc) { ledVemelho=1;ledAmarelo=0;} else ledVermelho=0;
	}
}

Ou algo do gênero

A parte menos fácil é achar os valores das constantes _4pc e _7pc. Registre-se: registrar na eeprom é um opção

adicionado 7 minutos depois

Pensando melhor... (se é que me é possível)...

unsigned int _4pc,_7pc

...

Vok=adcread(0); //valor correto

_4pc=(Vok*4)/100; //4%

_7pc=(Vok*7)/100; //7%

...

Sei lá... 1/2 de ressaca ainda....

  • Curtir 1
  • Membro VIP
Postado
1 hora atrás, Grupo de TCC disse:

Não entendo muito de programação

sem problema amigo. Permita-me dar-lhe uma microaula...

você precisa colocar o programa dentro de um loop (laço) eterno ou melhor um loop dentro do programa. Ele começa e volta ao começo automaticamente. No seu programa não tem isso. Perceba que o seu  end da função principal (main) e não vemos loop: laço com retorno.

Tentemos na sua língua...

 

tensao1=adcread(0);//precisa ler pra registrar
a = ((tensao1*4)/100));//4% da tensão nominal ... tinha um engano no seu fonte
  b = ((tensao1*7)/100));//7% da tensão nominal ... compare pra você ver. 4/100 ia dar sempre zero para inteiros
  x = tensao1-a;//tensão nominal-4%
  y = tensao1-b;//tensão nominal-7%

for(;;) //ou while(1) 
{ // o que estiver entre esta chave e "aquela", vai ser executado eternamente
tensao2=adcread(0); //precisa ler pra comparar
if (tensao2>x)// se a queda estiver menor que 4%, liga o led verde
    {
  
      RA1_bit = 1;//led verde ligado
      RA2_bit = 0;//led amarelo desligado
      RC0_bit = 0;//interrupção desligada
    }

       else if (tensao2>y && tensao2<=x)// se a queda estiver entre 4% e 7%, liga o led amarelo
      {
            RA2_bit = 1;//led amarelo ligado
            RA1_bit = 0;//led verde desligado
            RC0_bit = 0;//interrupção desligada
      }

      else (tensao2<y);// se a queda for maior que 7%, liga o circuito de interrupção e o led vermelho
      {
            RC0_bit = 0;//interrupção ligada
            RA1_bit = 0;//led verde desligado
            RA2_bit = 0;//led amarelo desligado

      }
}// "aquela"
 }// end função principal

Perceba o engano da conta que fizeste.

 

Mas penso que estamos no caminho certo sim amigo. Por gentileza cogite não queimar a etapa do pisca led. Também aprenda a ler o adc e colocar numa porta observando no proteus o valor binário p.ex.

for(;;) PORTB=adcread(0); //só isso e portas se abrirão

um loop de um comando só...

  • Curtir 1
Postado
//armazenamento das tensões
int tensao1 = 0x00;
int tensao2 = 0x00;

// declara as variáveis
int a, b, x, y;

void main()
{
  ANSEL = 0x01;// AN0 como entrada analogica
  ADCON0 = 0x01;// seleciona a entrada AN0
  ADCON1 = 0x0E;
  CMCON0 = 0x07;//desliga os comparadores

  //configura PORTA
  TRISA = 0x01;// AN0 entrada
  PORTA = 0x00;// PORTA em nvl baixo

  //configura PORTC
  TRISC = 0xFF;// PORTC como saída
  PORTC = 0x00;// PORTC em nvl baixo

  tensao1=ADC_Read(0);//leitura registrada
  
  a = ((tensao1*4)/100));//4% da tensão nominal
  b = ((tensao1*7)/100));//7% da tensão nominal
  x = tensao1-a;//tensão nominal-4%
  y = tensao1-b;//tensão nominal-7%

while(1)
{
  
  tensao2=ADC_Read(0); //leitura comparada
  
   if (tensao2>x)// se a queda estiver menor que 4%, liga o led verde
    {

      RA1_bit = 1;//led verde ligado
      RA2_bit = 0;//led amarelo desligado
      RC0_bit = 0;//interrupção desligada
    }

       else if (tensao2>y && tensao2<=x)// se a queda estiver entre 4% e 7%, liga o led amarelo
      {
            RA2_bit = 1;//led amarelo ligado
            RA1_bit = 0;//led verde desligado
            RC0_bit = 0;//interrupção desligada
      }

      else (tensao2<y);// se a queda for maior que 7%, liga o circuito de interrupção e o led vermelho
      {
            RC0_bit = 0;//interrupção ligada
            RA1_bit = 0;//led verde desligado
            RA2_bit = 0;//led amarelo desligado

      }
      return 0;
}
 }// end função principal

Ficou assim, porém no meu circuito os leds não acendem... seria uma má configuração das portas?

adicionado 4 minutos depois

esse é o circuito.

bbbbbbbuuuuu.png

adicionado 5 minutos depois

O pic não está mandando sinal high para os leds...

  • Membro VIP
Postado
1 hora atrás, Grupo de TCC disse:

seria uma má configuração

Pode ser sim amigo. Não vejo a configuração dos fuses.

 

1 hora atrás, Grupo de TCC disse:

TRISC = 0xFF;// PORTC como saída

Apesar de não ter conexão com o problema, o comentário está errado. E não deve acionar o scr quando precisar.

Dica: corrija para TRISC=0x00; e coloque um led em RC5 pra ver se pisca. Veja com osciloscópio.

RC5_bit^=1; dentro do loop.. agora sabe o que é né?

 

 

  • Curtir 1
Postado

Não configurei os fuses pois estou usando o MikroC.

11 minutos atrás, Isadora Ferraz disse:

.. agora sabe o que é né?

 

 

sim, obrigada...

adicionado 5 minutos depois

Testando aqui no proteus... os leds ainda não acenderam, configurei o trisc conforme você disse

  • Curtir 1
  • Membro VIP
Postado

ele está pulsando o port rc5 depois que fizestes RC5_bit^=1? Os fuses extão coerentes com o circuito? reset? watch dog? power good? etc? Pra simular:

-nem precisa cristal

-o pino reset deve estar no vcc e não no ponto R1(1) Conecte no power: tem no menu lateral. fica perto do gnd -

abç

  • Curtir 1
Postado

Os fuses foram configurados sim, porém o programa continua não funcionando... Preciso disso pronto pra esse mês

 

adicionado 1 minuto depois
//armazenamento das tensões
int tensao1 = 0x00;
int tensao2 = 0x00;

// declara as variáveis
int a, b, x, y;

void main()
{
  ANSEL = 0x01;// AN0 como entrada analogica
  ADCON0 = 0x01;// seleciona a entrada AN0
  ADCON1 = 0x00;
  CMCON0 = 0x07;//desliga os comparadores

  //configura PORTA
  TRISA = 0x01;// AN0 entrada
  PORTA = 0x00;// PORTA em nvl baixo

  //configura PORTC
  TRISC = 0x00;// PORTC como saída
  PORTC = 0x00;// PORTC em nvl baixo

  tensao1=ADC_Read(0);//leitura registrada
  
  a = ((tensao1*4)/100));//4% da tensão nominal
  b = ((tensao1*7)/100));//7% da tensão nominal
  x = tensao1-a;//tensão nominal-4%
  y = tensao1-b;//tensão nominal-7%

while(1)
{
  tensao2=ADC_Read(0); //leitura comparada

   if (tensao2>x)// se a queda estiver menor que 4%, liga o led verde
    {
      RA1_bit = 1;//led verde ligado
      RA2_bit = 0;//led amarelo desligado
      RC0_bit = 0;//interrupção desligada
    }

       else if (tensao2>y && tensao2<=x)// se a queda estiver entre 4% e 7%, liga o led amarelo
      {
            RA2_bit = 1;//led amarelo ligado
            RA1_bit = 0;//led verde desligado
            RC0_bit = 0;//interrupção desligada
      }

      else if(tensao2<y)// se a queda for maior que 7%, liga o circuito de interrupção e o led vermelho
      {
            RC0_bit = 0;//interrupção ligada
            RA1_bit = 0;//led verde desligado
            RA2_bit = 0;//led amarelo desligado

      }
      return 0;
}
 }// end função principal

 

  • Membro VIP
Postado
5 horas atrás, Grupo de TCC disse:

programa continua não funcionando

isso tá muito vago. Dica: rode passo a passo e veja onde para. Além do + você nem confirmou se

Em 07/11/2017 às 09:55, Isadora Ferraz disse:

um led em RC5 pra ver se pisca. Veja com osciloscópio.

RC5_bit^=1; dentro do loop

... te deu algum resultado

 

5 horas atrás, Grupo de TCC disse:

Preciso disso pronto pra esse mês

Creia-me: isso é importante pra você e não necessariamente motiva mais. No entanto mesmo assim sinta nossa boa vontade

 

Com tem algum tempo ainda, experimente colocar o resultado do ad direto num port pra ver o "trem andar" um pouco e te dar alguma luz

 

for (;;) PORTC=adcread(0);

Use um pot na entrada ad

  • Curtir 1
Postado
11 horas atrás, Grupo de TCC disse:

Os fuses foram configurados sim, porém o programa continua não funcionando... Preciso disso pronto pra esse mês

 

adicionado 1 minuto depois

//armazenamento das tensões
int tensao1 = 0x00;
int tensao2 = 0x00;

// declara as variáveis
int a, b, x, y;

void main()
{
  ANSEL = 0x01;// AN0 como entrada analogica
  ADCON0 = 0x01;// seleciona a entrada AN0
  ADCON1 = 0x00;
  CMCON0 = 0x07;//desliga os comparadores

  //configura PORTA
  TRISA = 0x01;// AN0 entrada
  PORTA = 0x00;// PORTA em nvl baixo

  //configura PORTC
  TRISC = 0x00;// PORTC como saída
  PORTC = 0x00;// PORTC em nvl baixo

  tensao1=ADC_Read(0);//leitura registrada
  
  a = ((tensao1*4)/100));//4% da tensão nominal
  b = ((tensao1*7)/100));//7% da tensão nominal
  x = tensao1-a;//tensão nominal-4%
  y = tensao1-b;//tensão nominal-7%

while(1)
{
  tensao2=ADC_Read(0); //leitura comparada

   if (tensao2>x)// se a queda estiver menor que 4%, liga o led verde
    {
      RA1_bit = 1;//led verde ligado
      RA2_bit = 0;//led amarelo desligado
      RC0_bit = 0;//interrupção desligada
    }

       else if (tensao2>y && tensao2<=x)// se a queda estiver entre 4% e 7%, liga o led amarelo
      {
            RA2_bit = 1;//led amarelo ligado
            RA1_bit = 0;//led verde desligado
            RC0_bit = 0;//interrupção desligada
      }

      else if(tensao2<y)// se a queda for maior que 7%, liga o circuito de interrupção e o led vermelho
      {
            RC0_bit = 0;//interrupção ligada
            RA1_bit = 0;//led verde desligado
            RA2_bit = 0;//led amarelo desligado

      }
      return 0;
}
 }// end função principal

 

 

Qual a função do "return 0;" dentro do while? seu while só vai executar 1x,pois aquele return 0 vai sair da função.Como precisa terminar esté mês,deveria ver minha reposta anterior e não demorar quase uma semana para responder um tópico.

  • Curtir 2

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...