Autor Tópico: Ajuda - PIC 18F2550 (controlo de posição)  (Lida 2662 vezes)

Description:

0 Membros e 1 Visitante estão vendo este tópico.

Offline LuisC

  • Novato
  • *
  • Posts: 60
  • Sexo: Masculino
  • GUIA-CNC
Ajuda - PIC 18F2550 (controlo de posição)
« Online: 13 de Novembro de 2014, 21:28 »
Boas Pessoal,

Estou para começar a desenvolver um projecto para controlar a posição/rotação de um eixo.
Passo a explicar, queria usar a PIC para ler as varias posições de um eixo de uma alavanca e mostrar num display de 7 segmentos. Para isso pretendo colocar um potenciómetro acoplado ao eixo e quando o eixo roda, também vai fazer rodar o potenciómetro. A rotação máxima ultrapassa os 300 graus.

Depois pretendia fazer ligar esse potenciómetro a uma entrada analógica e ter dois modos de funcionamento. Um modo de "programação", em que eu pudesse colocar manualmente o eixo na posição 1, clicar num botão e guardar essa posição, o mesmo para a posição 2, 3, ... até 8. Para isso teria de ter 4 botões,  2 botões para incrementar/decrementar o display para colocar o digito correspondente à posição, depois salvar a posição com um terceiro botão e o 4º para os modos de funcionamento.

Quando terminasse a programação das 8 posições, comutaria o 4º botão para modo "normal" em que está sempre em ciclo infinito a mostrar a posição do eixo.

Para isso gostava de pedir a vossa ajuda, gostava de saber se alguém de vós já fez alguma coisa parecida e possa dar opiniões de como eu devo fazer para criar a estrutura para um código destes.

Eu tenho algumas luzes de mikroC, ja tenho feito algumas coisas simples, mas não são suficientes para definir uma estrutura para este programa. Já consigo fazer incrementar/decrementar um display, ler as portas analógicas, mas tenho muitas duvidas de como fazer o ciclo do modo "programação".

Se alguém me puder dar uma ajuda de por onde começar, indicar alguns exemplos de código com funções semelhantes, links,  etc, eu agradecia.

Obrigado!

Abraço



 

Offline RMilani

  • Novato
  • *
  • Posts: 34
  • Sexo: Masculino
  • Na omissão não há erro, exceto a própria omissão
  • Nome:: Renato Milani
  • Profissão: Eletrônico
Re:Ajuda - PIC 18F2550 (controlo de posição)
« Resposta #1 Online: 14 de Novembro de 2014, 09:46 »
Oi Luis.
Seria mais fácil e mais preciso do que o uso de um potenciometro, adotar um disco raiado com um ponto (tipo 2 furos alinhados), como referência e um acoplamento ótico. Use algum dos pinos do PIC para contar (pode usar a função INT).
Para a programação, use uma rotina para mudar o modo de operação, com 1 só tecla (1º toque - prog ponto 1, 2º toque prosição 2 e assim sucessivamente). No mesmo botão, pode utilizar um tempo maior de acionamento (defina isso por exemplo num dos timers), para retornar ao modo de execução. Outros 2 botões para elevar ou diminuir  a variável de posicionamento.
Não esqueça de usar para chaves de toque, uma função "debonce". Sou da antiga e uso o Mikro Pascal e o programa já tem essa função pronta, mas acredito que o MikroC também tenha.
Boa sorte.

Offline minilathe

  • How to ask questions - The Smart Way...
  • Moderadores
  • CNCMASTER
  • ******
  • Posts: 4295
  • Sexo: Masculino
  • http://science-lakes.com/article43-html.html
  • Cidade - UF: Rio de Janeiro - RJ
  • Nome:: Gil Pinheiro
  • Profissão: Engenheiro e professor universitário
Re:Ajuda - PIC 18F2550 (controlo de posição)
« Resposta #2 Online: 14 de Novembro de 2014, 11:50 »
Boas Pessoal,

Estou para começar a desenvolver um projecto para controlar a posição/rotação de um eixo.
Passo a explicar, queria usar a PIC para ler as varias posições de um eixo de uma alavanca e mostrar num display de 7 segmentos. Para isso pretendo colocar um potenciómetro acoplado ao eixo e quando o eixo roda, também vai fazer rodar o potenciómetro. A rotação máxima ultrapassa os 300 graus.

Depois pretendia fazer ligar esse potenciómetro a uma entrada analógica e ter dois modos de funcionamento. Um modo de "programação", em que eu pudesse colocar manualmente o eixo na posição 1, clicar num botão e guardar essa posição, o mesmo para a posição 2, 3, ... até 8. Para isso teria de ter 4 botões,  2 botões para incrementar/decrementar o display para colocar o digito correspondente à posição, depois salvar a posição com um terceiro botão e o 4º para os modos de funcionamento.

Quando terminasse a programação das 8 posições, comutaria o 4º botão para modo "normal" em que está sempre em ciclo infinito a mostrar a posição do eixo.

Para isso gostava de pedir a vossa ajuda, gostava de saber se alguém de vós já fez alguma coisa parecida e possa dar opiniões de como eu devo fazer para criar a estrutura para um código destes.

Eu tenho algumas luzes de mikroC, ja tenho feito algumas coisas simples, mas não são suficientes para definir uma estrutura para este programa. Já consigo fazer incrementar/decrementar um display, ler as portas analógicas, mas tenho muitas duvidas de como fazer o ciclo do modo "programação".

Se alguém me puder dar uma ajuda de por onde começar, indicar alguns exemplos de código com funções semelhantes, links,  etc, eu agradecia.

Obrigado!

Abraço

Poste seu programa para que algo mais objetivo seja sugerido.

Offline LuisC

  • Novato
  • *
  • Posts: 60
  • Sexo: Masculino
  • GUIA-CNC
Re:Ajuda - PIC 18F2550 (controlo de posição)
« Resposta #3 Online: 14 de Novembro de 2014, 17:39 »
Ola a todos,

Sim, também pensei em usar um disco de um rato, mas continuei a alimentar a ideia do potenciómetro pelo facto de ser mais robusto mecanicamente.
A função de der o botão estou a usar o exemplo do mikroC, mas o meu problema é mesmo timers e  interrupções, estou leigo nessa materia, tenho andado a ler um pouco sobre como configura-los e usa-los.

Aproveito para postar o código que já tenho, mas que ainda está muito crú....


int i, cont, temp, aux_R, aux_0, aux_1, aux_2, aux_3, aux_4, aux_5, aux_6, tol_A=100, tol_B=300;
unsigned short oldstate, oldstate1,contador, modo_prog = 0, modo_RUN, xx;



void mem_R(){

     PORTB = 0x08;
     Delay_ms(50);
     aux_R = ADC_Read(2);
     Delay_ms(200);
     PORTB = 0x88;
     Delay_ms(200);
     PORTB = 0x08;

    }
void mem_0(){

     PORTB = 0x40;
     Delay_ms(50);
     aux_0 = ADC_Read(2);
     Delay_ms(200);
     PORTB = 0xC0;
     Delay_ms(200);
     PORTB = 0x40;

    }
void mem_1(){

     PORTB = 0x79;
     Delay_ms(50);
     aux_1 = ADC_Read(2);
     Delay_ms(200);
     PORTB = 0xF9;
     Delay_ms(200);
     PORTB = 0x79;

    }

void mem_2(){

     PORTB = 0x24;
     Delay_ms(50);
     aux_2 = ADC_Read(2);
     Delay_ms(200);
     PORTB = 0xA4;
     Delay_ms(200);
     PORTB = 0x24;

    }

void mem_3(){

     PORTB = 0x30;
     Delay_ms(50);
     aux_3 = ADC_Read(2);
     Delay_ms(200);
     PORTB = 0xB0;
     Delay_ms(200);
     PORTB = 0x30;

   }

void mem_4(){

     PORTB = 0x19;
     Delay_ms(50);
     aux_4 = ADC_Read(2);
     Delay_ms(200);
     PORTB = 0x99;
     Delay_ms(200);
     PORTB = 0x19;

   }

void mem_5(){

     PORTB = 0x12;
     Delay_ms(50);
     aux_5 = ADC_Read(2);
     Delay_ms(200);
     PORTB = 0x92;
     Delay_ms(200);
     PORTB = 0x12;
     }

void mem_6(){
     PORTB = 0x02;
     Delay_ms(50);
     aux_6 = ADC_Read(2);
     Delay_ms(200);
     PORTB = 0x82;
     Delay_ms(200);
     PORTB = 0x02;
    }
unsigned short digitos_RUN(unsigned short num)
{
  switch (num)
  {
    case 0 : return 0x08;  //R.
    case 1 : return 0x40;  //0.
    case 2 : return 0x79;  //1.
    case 3 : return 0x24;  //2.
    case 4 : return 0x30;  //3.
    case 5 : return 0x19;  //4.
    case 6 : return 0x12;  //5.
    case 7 : return 0x02;  //6.

  }
}

void main()
{
TRISA = 0xFF;          // Configura para ser Entrada
TRISB = 0x00;          // Configura para ser saída
TRISC = 0xFF;          // Configura para ser Entrada

PORTA = 0x00;           //Inicializa as portas
PORTB = 0x00;          //Inicializa as portas
PORTC = 0x00;          //Inicializa as portas




do{
   if (Button(&PORTC,0,20,1))               //botão do RC0 (incrementa) pressionado?
     {
      modo_RUN = (1);
      modo_PROG = (0);
      //PORTB = (0xBF);
       PORTB = (0xB6);

     }

   
   
  // modo Programação
   
   
    else {
    modo_RUN = (0);
    modo_PROG = (1);
  if (Button(&PORTC,7,1,0))               //botão do RA0 (incrementa) pressionado?
  {
  oldstate = 1;
  }
  if (oldstate && Button(&PORTC,7,1,1))
  {
    contador++;
    oldstate = 0;
  }
  if(contador>=7) contador = 7;                   //testa para ver se chegou no valor máximo
  PORTB = digitos_RUN(contador);                  //faz a conversão de binário para 7 segmentos
  if (Button(&PORTC,2,1,0))
   oldstate1 = 1; 
  }
  if (oldstate1 && Button(&PORTC,2,1,1))
  {
    contador--;
    oldstate1 = 0; 
  }
  if(contador>=14) contador = 0;                   //testa para ver se chegou no valor mínimo
  PORTB = digitos_RUN(contador);                  //faz a conversão de binário para 7 segmentos
     

     if (PORTC.F1==0 && contador==0 )
     {
       mem_R();
     }
     if (PORTC.F1==0 && contador==1 )
     {
       mem_R();
     }
     if (PORTC.F1==0 && contador==2 )
     {
       mem_1();
     }
     if (PORTC.F1==0 && contador==3 )
     {
       mem_2();
     }
     if (PORTC.F1==0 && contador==4 )
     {
       mem_3();
     }
     if (PORTC.F1==0 && contador==5 )
     {
       mem_4();
     }
     if (PORTC.F1==0 && contador==6 )
     {
       mem_5();
     }
     if (PORTC.F1==0 && contador==7 )
     {
       mem_6();
     }



 
} while (modo_prog = 1);

O que dizem? Façam os vossos comentários...

Obrigado.

Offline minilathe

  • How to ask questions - The Smart Way...
  • Moderadores
  • CNCMASTER
  • ******
  • Posts: 4295
  • Sexo: Masculino
  • http://science-lakes.com/article43-html.html
  • Cidade - UF: Rio de Janeiro - RJ
  • Nome:: Gil Pinheiro
  • Profissão: Engenheiro e professor universitário
Re:Ajuda - PIC 18F2550 (controlo de posição)
« Resposta #4 Online: 14 de Novembro de 2014, 18:01 »
Boas Pessoal,

Estou para começar a desenvolver um projecto para controlar a posição/rotação de um eixo.
Passo a explicar, queria usar a PIC para ler as varias posições de um eixo de uma alavanca e mostrar num display de 7 segmentos. Para isso pretendo colocar um potenciómetro acoplado ao eixo e quando o eixo roda, também vai fazer rodar o potenciómetro. A rotação máxima ultrapassa os 300 graus.

Depois pretendia fazer ligar esse potenciómetro a uma entrada analógica e ter dois modos de funcionamento. Um modo de "programação", em que eu pudesse colocar manualmente o eixo na posição 1, clicar num botão e guardar essa posição, o mesmo para a posição 2, 3, ... até 8. Para isso teria de ter 4 botões,  2 botões para incrementar/decrementar o display para colocar o digito correspondente à posição, depois salvar a posição com um terceiro botão e o 4º para os modos de funcionamento.

Quando terminasse a programação das 8 posições, comutaria o 4º botão para modo "normal" em que está sempre em ciclo infinito a mostrar a posição do eixo.

Para isso gostava de pedir a vossa ajuda, gostava de saber se alguém de vós já fez alguma coisa parecida e possa dar opiniões de como eu devo fazer para criar a estrutura para um código destes.

Eu tenho algumas luzes de mikroC, ja tenho feito algumas coisas simples, mas não são suficientes para definir uma estrutura para este programa. Já consigo fazer incrementar/decrementar um display, ler as portas analógicas, mas tenho muitas duvidas de como fazer o ciclo do modo "programação".

Se alguém me puder dar uma ajuda de por onde começar, indicar alguns exemplos de código com funções semelhantes, links,  etc, eu agradecia.

Obrigado!

Abraço

Olhando o seu programa, me parece que poderia ser otimizado em duas etapas principais, executadas em sequência:
(1) Ler entrada (leitura do conversor A/D)
(2) Escrever no display

Seu programa me pareceu meio confuso e poderia ser mais curto. As duas tarefas acima listadas, as únicas necessárias, em seu programa estão encadeadas (Lê A/D,escreve se display for 0, Lê A/D,escreve se display for 1, Lê A/D,escreve se display for 1, ... Lê A/D,escreve se display for 7) e não em sequência.

Conforme eu sugeri acima, seu programa ficaria assim:
(1) Lê conversor A/D (mede a resistência do potenciômetro)
(2) Escreve no display (mostra a posição do eixo na escala de 0 a 7)
(3) Vai para o passo (1)

É indispensável colocar um filtro passa baixa (do tipo RC, de primeira ordem) na saída do potenciômetro e antes do conversor A/D (filtro anti-aliasing) para minimizar os ruídos.

Agora é com você....
« Última modificação: 14 de Novembro de 2014, 18:03 por minilathe »

Offline LuisC

  • Novato
  • *
  • Posts: 60
  • Sexo: Masculino
  • GUIA-CNC
Re:Ajuda - PIC 18F2550 (controlo de posição)
« Resposta #5 Online: 14 de Novembro de 2014, 20:11 »
Obrigado Gil, agora lendo o seu post, vejo que o que aconselha faz mais sentido e torna-se mais intuitivo.
Vou reorganizar este código segundo o que me está a dizer.

Quanto ao filtro, não me lembrei desse pormenor, já fiz alguns trabalhos com entradas analógicas e até funcionavam bem, mas com alguns bugs de leitura que provavelmente seriam resolvidos com um filtro...

Obrigado pela dica!


 

/** * */