Ir ao conteúdo
  • Cadastre-se

PIC Problema com programação de dispositivo simples


Posts recomendados

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

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP

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
Link para o comentário
Compartilhar em outros sites

  • Membro VIP
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
Link para o comentário
Compartilhar em outros sites

//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...

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
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
Link para o comentário
Compartilhar em outros sites

  • Membro VIP

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
Link para o comentário
Compartilhar em outros sites

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

 

Link para o comentário
Compartilhar em outros sites

  • Membro VIP
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
Link para o comentário
Compartilhar em outros sites

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
Link para o comentário
Compartilhar em outros sites

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...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!