Guia CNC Brasil - Tudo sobre CNC, Router, Laser, Torno e 3D Print

ELETRÔNICA / ELÉTRICA => Eletrônica Básica => Microcontroladores => Tópico iniciado por: vinigusto em 20 de Setembro de 2010, 12:03

Título: Controle_PID_PIC18F2480
Enviado por: vinigusto em 20 de Setembro de 2010, 12:03
Pessoal,
Estou desenvolvendo um projeto de Iniciação Científica na área de Controle embarcado. Cujo objetivo é controlar a posição do pescoço e dos olhos de um robô. Estas partes são formadas por motores CC com caixa de redução. Já fiz a modelagem e estou em fase de implementação do algoritmo no microcontrolador PIC. Estou usando o compilador CCS, já iniciei o código, até baseado  em um dos posts deste fórum.
Gostaria de uma ajuda nessa parte, algo como um material (já  pesquisei vários mas a maioria é em assembly que não eh o objetivo do projeto) ou de experiência de alguem que já desenvolveu um projeto semelhante. Posso postar o código depois.

Grato
Título: Re: Controle_PID_PIC18F2480
Enviado por: minilathe em 20 de Setembro de 2010, 15:28
Vinigusto,

Conforme conversamos, segue algoritmo PID num PIC.

http://ww1.microchip.com/downloads/en/AppNotes/00964A.pdf (http://ww1.microchip.com/downloads/en/AppNotes/00964A.pdf)

Para começar a pensar num controle de posição. Dependendo da velocidade, é necessário avaliar se a velocidade de processamento de um PIC com linguagem C é adequado a um controle de posição. Principalmente se for uma malha de controle rápida. Caso contrário, talvez o dsPIC seja uma opção melhor. Mas cabe a voce dizer a velocidade esperada em sua aplicação.

Abraço,
Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 30 de Setembro de 2010, 22:36
Obrigado pelo material, deu para compreender bem.
Gostaria de tirar uma dúvida quanto a questão da escolha para o tempo de amostragem (Ts) para esse meu contexto.

obrigado
Título: Re: Controle_PID_PIC18F2480
Enviado por: minilathe em 30 de Setembro de 2010, 23:06


O tempo de amostragem, que é também o intervalo de varredura do programa, Ts, deve ser menor que a constante de tempo do processo (Tp) que voce vai controlar. Idealmente falando: Ts < 2 Tp. Se Ts for menor ainda melhor.
Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 01 de Outubro de 2010, 19:13
Obrigado mais uma vez,
Deu para ter uma ideia, eu sei que a depender do valor de Ts pode gerar mais ruído ou não. No caso de sistemas robóticos tem que ser menor.
Mas não entendi como posso mensurar Tp, consequentemente Ts.

Grato
Título: Re: Controle_PID_PIC18F2480
Enviado por: minilathe em 01 de Outubro de 2010, 23:59
Vinigusto,

O valor de Tp pode ser medido ou estimado. A medição só é possível em sistemas existentes, onde será implantado um sistema de controle. Para sistemas inexistentes, que estão sendo projetados, o que se faz é estimar, através de hipóteses baseadas na dinâmica, na inércia e outras propriedades físicas do sistema, baseado no projeto do sistema. Também se pode estudar a dinâmica de um sistema, e fazer estimativas acerca do mesmo, usando simulações, através do Simulink, Matlab ou outras ferramentas de modelagem e simulação.

[]´s
Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 25 de Outubro de 2010, 13:35
Olá amigo,
Tow empacado em algumas partes, como por exemplo: como faço o tratamento das unidades das variavel setpoint e actual position, tipo se trabalho com elas em radianos/s ou não. A outra como mando/ou transformo o sinal de controle (do PID discreto) para o pwm.

Grato
Título: Re: Controle_PID_PIC18F2480
Enviado por: minilathe em 25 de Outubro de 2010, 21:10
Olá amigo,
Tow empacado em algumas partes, como por exemplo: como faço o tratamento das unidades das variavel setpoint e actual position, tipo se trabalho com elas em radianos/s ou não. A outra como mando/ou transformo o sinal de controle (do PID discreto) para o pwm.

Grato

Tanto faz, pode trabalhar em radianos, graus, grados, ....

Na verdade,nos cálculos do PID, o mais fácil é trabalhar com a própria leitura do conversor A/D de 10 bits, que é um numero inteiro de 0 a 1023. A leitura máxima é 1023 e a mínima é zero. Não precisa converter nada.

Para aumentar a precisão (resolução) do controle, o ideal é ajustar / montar o sistema de modo que a oscilação normal do eixo do potenciômetro gere uma variação de 0 a 1023 no conversor A/D.

Ao converter a saída do PID para PWM é necessário implementar um fator de escala, que pode ser igual a 1 (ou seja, não multiplicar nada). Explicando, o módulo PWM do PIC usa uma palavra de 10 bits e como voce já estará usando 10 bits para o conversor A/D, faz sentido pensar numa escala de 0 a 100% de 10bits, onde 100% é igual a 1023. Ok??

Abraços,
 
Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 25 de Outubro de 2010, 22:10
Eu entendi sua ideia. Mas no caso de eu trabalhar com variareis long int (set_point, actual_position, sinal_controle,etc) . O próprio copilador se encarregar da conversao (10 bits), ou eu teria que zerar 6 bits?
Outra dúvida como faço para lê um dado(set_point) de uma porta vindo pela serial utilizando o compilador CCS? Seria usando a função kbhit() e getc()? tipo:

while(true){
    if(kbhit()){ set_point = getc();}
    ...

Grato
Título: Re: Controle_PID_PIC18F2480
Enviado por: minilathe em 26 de Outubro de 2010, 19:54
Eu entendi sua ideia. Mas no caso de eu trabalhar com variareis long int (set_point, actual_position, sinal_controle,etc) . O próprio copilador se encarregar da conversao (10 bits), ou eu teria que zerar 6 bits?
Outra dúvida como faço para lê um dado(set_point) de uma porta vindo pela serial utilizando o compilador CCS? Seria usando a função kbhit() e getc()? tipo:

while(true){
    if(kbhit()){ set_point = getc();}
    ...

Grato

No caso, deve ser usada uma variável tipo unsigned int (vão de 0 a 65535) para ler do A/D. Assim, o valor será de 0 até 1023 apenas.

Ao ler a porta serial, serão necessários 2 bytes (duas leituras na serial) para montar um valor inteiro no programa em C. Exemplo:

set_point = 256 * getc();  // Lê e carrega byte mais significativo
set_point += getc();         // Lê e carrega byte menos significativo
Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 26 de Outubro de 2010, 23:03
Obrigado pela dica mais uma vez! Posso enviar meu código para vc vê?

Grato
Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 01 de Novembro de 2010, 11:26
Pode ser? Para poder esclarecer + a dúvida.

Grato
[/quote]
Título: Re: Controle_PID_PIC18F2480
Enviado por: minilathe em 01 de Novembro de 2010, 11:54
Vinigusto,

Obrigado pela dica mais uma vez! Posso enviar meu código para vc vê?

Grato

Claro!!  :) , pode mandar...

Abraços,
Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 01 de Novembro de 2010, 16:28
Olá, poderia confirmar se vc recebeu o anexo. Eu enviei. Me passa seu email por favor para confirmar.

Grato
Título: Re: Controle_PID_PIC18F2480
Enviado por: minilathe em 01 de Novembro de 2010, 19:09
Vinigusto,

Não recebi, se quiser mande como mensagem privativa do Forum.

Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 01 de Novembro de 2010, 21:50
Recebeu a mensagem personalizada?
Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 11 de Novembro de 2010, 22:51
Olá, posso enviar o código com algumas correções que eu fiz?

Grato
Título: Re: Controle_PID_PIC18F2480
Enviado por: minilathe em 12 de Novembro de 2010, 00:46
Ola Vinícius,

Pode mandar seu programa. Já foi atualizado?

Abraços,
Título: Re: Controle_PID_PIC18F2480
Enviado por: vinigusto em 13 de Novembro de 2010, 02:46
Na verdade fiz pequenas atualizações, queria tirar um dúvida quanto ao anti-windup. Eu tinha feito na função setPWM mas acho que não viu. Acho que fica o mesmo efeito. Eu gostaria de saber se precisa add mais alguma coisa nesta função, tipo a questao do sentido da rotação do motor. Seria necessario duas portas configuradas para o PWM? uma para o lado + e outra para o -. Quanto aos valores de kp,kd e ki ainda não foram definidos pois meu orientador não me passou os dados da planta (resistencia,momento de inercia, coeficiente viscoso,...)

Grato

ps: Posso te enviar o código por onde?
Título: Re: Controle_PID_PIC18F2480
Enviado por: minilathe em 13 de Novembro de 2010, 08:19
Vinicius,

Na verdade fiz pequenas atualizações, queria tirar um dúvida quanto ao anti-windup. Eu tinha feito na função setPWM mas acho que não viu. Acho que fica o mesmo efeito. Eu gostaria de saber se precisa add mais alguma coisa nesta função, tipo a questao do sentido da rotação do motor. Seria necessario duas portas configuradas para o PWM? uma para o lado + e outra para o -.

Basta um bit do PIC (uma saída PWM), onde o controle PWM associado ao controlador PID podem ser implementados com alguns cuidados:

Assumindo que, numa saída PWM:
(1) Ciclo de trabalho 5% - motor em máxima velocidade no sentido horário-CW (por exemplo)
(2) Ciclo de trabalho 50% - motor parado
(3) Ciclo de trabalho 95% - motor em máxima velocidade no sentido anti-horário-CCW

Isso é facilmente implementado usando uma ponte H de transistores comandando o motor.

O controlador PID:

(1) Em des-equilibrio (erro<0), tem: saída < 50% (motor rodando em CW)
(2) Em equilibrio (erro=0), tem: saída = 50% (motor parado)
(3) Em des-equilibrio (erro>0), tem: saída > 50% (motor rodando em CCW)


ps: Posso te enviar o código por onde?

Não sendo "secreto".... pode mandar nesse tópico, assim, mais pessoas podem acompanhar o assunto.

Senão..., pode mandar em PVT.

Abraços,
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 11 de Fevereiro de 2011, 23:24
Oi minilathe
No momento estou de ferias, aproveitei e trabalhei na sintonia do PID para calcular Kp e Kd com bases nas especificações. Queria testar o algoritmo no proteus, só que não ainda como. Também ainda não tenho de como escolher Ts. Queria realizar este teste no proteus.

Grato
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 12 de Fevereiro de 2011, 00:08
Olá Vinicius,

Para testar no Proteus é necessário desenhar um circuito, sugiro usar um potenciômetro que possa simular a entrada e monitorar a saída num osciloscópio.
 
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 21 de Fevereiro de 2011, 23:16
Vou tentar montar o circuito e entro em contato com vc?
Em relação ao algoritmo que desenvolvi foi para o PID em geral. Só que eu fiz o projeto para planta do motor CC um P&D com realimentação de Velocidade visto que a planta já contem um integrador e que o PD clássico acrescenta um zero (causando instabilidade).
Então precisarei ajustar um pouco o algoritmo por conta da mudança do sinal de controle.

//---- Principal---------
  while (true)
  {
      if(kbhit()) //verifica se tem um dado no buffer da Usart, espera receber 10 bits
      {
         
         setPoint = getc(); // recebe o valor do  buffer - recebe o byte mais significativo
         setPoint = (setPoint >> 8) + getc(); // recebe outro byte
         
      }
 
      set_adc_channel(0);
      delay_us(20);
      actual_position = read_adc();
     
      //printf("A Posicao atual e: %Ld\r\n",actual_position);
      //printf("A Saida atual e: %Ld\r\n", control);
     
      error = setPoint - actual_position;
      integral = integral + erro*Ts;
      derivative = (error - previous_error)/Ts;
      control = Kp*error + Ki*integral + Kd*derivative + control; (Terei que mudar esta linha)
     // para control = Kp*error - Kd*derivative + control;
      previous_error = error
     
      setPWM(control); // envia para saída PWM a posicao controlada
     
      delay_us(Ts);
     
  }
Concorda?
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 22 de Fevereiro de 2011, 11:23
Vinicius,

Pelo que entendi, seu controlador atuará como controlador mestre de um segundo controlador (arranjo tipo cascata)?

O seu algoritmo PID precisa algumas melhorias:
(1) Falta uma limitação da ação integral, para que esta não passe de 100%  ou vá abaixo de 0% na escala de saída
(2) Implemente uma escala consistente de saída do PID, do tipo 0 a 100%
(3) É necessário compatibilizar a saída com o sinal de entrada de comando do PWM, para que a coisa funcione, ou seja, 100% de saída do PID corresponda a 100% do PWM e o mesmo com o 0%.
(4) Qual a frequência de execução do seu PID? Ts?
(5) Ao interromper o laço de controle para ler o SP, ocorre uma descontinuidade no controle, que pode não ser nada grave, mas causa uma interrupção de sua execução, ocasionando instabilidades no controle. Melhor seria fazer a comunicação de maneira concorrente com o controle, usando interrupções. Ou escalonamento de tempo, uma fatia fixa do tempo (período do Scan Time - Ts) para comunicar, a outra para controlar.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 22 de Fevereiro de 2011, 20:05
Obrigado por responder,
Em relação a configuração do P&D está no anexo da mensagem anterior.
Em relação as melhorias:

(1) Não vou usar o integrador (Ki) pois a planta já a contém. Por isso somente o proporcional e derivativo.
(2)(3) Vc fala quando uso o setPWM? Se sim, esta acho que já faz isto.
(4) Isso ainda realmente escolhir, não conseguir achar algum material para q eu possa tomar uma decisão. Por enquanto o valor seria escolhido empiricamente.
(5) Concordo com vc mas por enquanto queria resolver os problemas anteriores para depois verificar se esta questao vai interferir (muito) ou não no resultado.
Em relação a linha //control = Kp*error + Ki*integral + Kd*derivative + control; (Terei que mudar esta linha).
Concorda que seria atualmente control = (Kp*error) - (kd*derivative*control) + control; ?

Posso te mandar o código completo.
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 23 de Fevereiro de 2011, 06:55
(1) Não vou usar o integrador (Ki) pois a planta já a contém. Por isso somente o proporcional e derivativo.

Precisa da ação derivativa? O que seria "a planta"?

(4) Isso ainda realmente escolhir, não conseguir achar algum material para q eu possa tomar uma decisão. Por enquanto o valor seria escolhido empiricamente.

Deve ser escolhido em função da velocidade de resposta do seu sistema a ser controlado (sua planta??)

(Em relação a linha //control = Kp*error + Ki*integral + Kd*derivative + control; (Terei que mudar esta linha).
Concorda que seria atualmente control = (Kp*error) - (kd*derivative*control) + control; ?

Posso te mandar o código completo.

A linha esta correta.

Ok.

Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 04 de Março de 2011, 21:36
(1) A planta é um Motor CC, onde a função de transferencia é a posição em relacao a tensao.
(4) Como assim? Em função da velocidade de resposta do seu sistema?.

Obrigado pela ajuda!
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 03 de Abril de 2011, 09:43
[Ts] Como assim? Em função da velocidade de resposta do seu sistema?.
Já trabalhou com comunicação usb? No momento estou utilizando o protocolo CDC (emula a serial).


Grato
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 03 de Abril de 2011, 12:20
Vinicius,

[Ts] Como assim? Em função da velocidade de resposta do seu sistema?.

Todo sistema físico / químico, ... possui um tempo de reação. De modo que, se você aplicar um degrau na variável manipulada, a variável controlada variará com uma certa curva de reação. Dessa curva, é possível determinar o tempo de reação do sistema.

Tomando como premissa o que você disse, que seu motor já possui um controlador de posição, ou seja, é um sistema onde a posição varia com a tensão, conforme você disse.
 
Nesse caso, imaginemos que o controlador do seu motor opera com um sinal de  0 a 10V e a carga movida está numa determinada posição. Ao aplicar +10V, a posição de seu motor muda ao longo do tempo até atingir a posição correspondente a 10V. Medindo o tempo que o motor leva de uma posição até a outra dá uma noção do tempo de reação do seu sistema.

O seu sistema de controle mestre, que vai comandar o controle de posição do motor, deverá ter um tempo de varredura (Ts) no máximo a metade do tempo determinado acima.

 
Já trabalhou com comunicação usb? No momento estou utilizando o protocolo CDC (emula a serial).

Ainda não, no microcontrolador diretamente, mas já usei conversores USB/Serial com microcontroladores. Atente que em muitas aplicações o pessoal usa a interface USB como se fosse uma porta serial RS-232, inclusive limitada a 115 kbps, devido ao tipo de driver disponível no PC.  Nesse caso, não vejo vantagem, a não ser economizar num conversor. Acho que o esforço vale a pena se for trabalhar num modo mais rápido da USB, aí a velocidade vai para a casa dos Mega bps e requer drivers de USB especiais do lado do PC.

Mas é necessário avaliar se é necessário partir para uma comunicação USB rápida. Uma porta RS232 operando a 115 kbps envia ou recebe 10 bits (1 start + 8 data bits + 1 stop) em 87 micro segundos,  Se o programa for bem planejado, é possível fazer o ciclo de leitura, processamento e escrita em centenas de microsegundos, que poderia ser mais que suficiente para a sua aplicação.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 03 de Abril de 2011, 18:13
Obrigado pela resposta.
Acho que entendi a questão do tempo de amostragem.

Fiz um teste ake em casa pra testar a comunicação usb entre o micro e software (em java). A leitura por parte do software funcionou (apesar de oscilar um pouco ante de se estabilizar) mas a recepção por parte do micro não funcionou adequadamente. Não sei ainda ao certo se o erro está por parte do metodo de enviar do software ou de recepção do micro. No momento estou enviando o dado numerico como string. No micro capturo como string e converto para long.
No micro estou fzd da seguinte forma: Parte de recepção
===== Rs232 normal
 if(kbhit()){     
               gets(setPoint);
               setPointt = atol(setPoint);
         }
======================= Usb CDC
//if(usb_cdc_kbhit()) //verifica se tem um dado no buffer da Usart, espera receber 10 bits
        //    {
         
               //setPoint = usb_cdc_getc(); // recebe o valor do  buffer - recebe o byte mais significativo
               //setPoint = (setPoint >> 8) + usb_cdc_getc(); // recebe outro byte

               //setPoint = get_long(); //Deu erro de compilação
               //setPoint = get_float_usb(); // Deu erro de compilação

               //setPoint = getc(); // recebe o valor do  buffer - recebe o byte mais significativo
               //setPoint = (setPoint >> 8) + getc(); // recebe outro byte
       

            //} 
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 03 de Abril de 2011, 20:53
Vinicius,

Eu tentaria primeiramente usar um programa emulador de terminal antes, para ver se a comunicação com o microcontrolador está ok, usando caracteres ASCII. Ex.: Hyperterminal, Tera Term, ... E depois fazer o seu programa em Java.

Eu já fiz vários programas de comunicação usando Python (RS232, TCP/IP, Modbus-RTU, ...), é simples e funciona bem. Há uma biblioteca chamada PySerial que funciona muito bem e permite escrever programas simples e funcionais, de maneira portável (Linux, Windows,...), assim como o Java. Já programei em Java, mas hoje prefiro o Python.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 04 de Abril de 2011, 12:19
No momento estou testando a parte de recepção do micro. Utilizei o software Advanced Serial Port Terminal. E tentei enviar uma string mas não aconteceu nada. Gostaria de saber se o código que postei anteriormente está com algum problema?.

Obrigado
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 04 de Abril de 2011, 16:04
Poderia enviar todo o seu código? O pedaço que enviou não permite verificar se está tudo correto.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 04 de Abril de 2011, 19:00
Claro que posso! Segue em anexo. Este código é de outro projeto meu (que deu certo) por isso estou testando a comunicação nele.
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 04 de Abril de 2011, 23:34
Acho que falta a parte do RS232....
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 05 de Abril de 2011, 23:34
Qual parte?
Eu coloquei a #use rs232...
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 06 de Abril de 2011, 01:04
O use é uma inicialização da porta apenas. Onde estão os comandos de leitura, escrita, ...?
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 06 de Abril de 2011, 01:13
A escrita:
 printf(usb_cdc_putc," %f\r\n",temp_medio); (Consigo enviar normalmente)

A Leitura:
Com usb cdc (emula serial) e normal.  Está comentados algumas linhas devido aos testes.

if(usb_cdc_kbhit()) //verifica se tem um dado no buffer da Usart, espera receber 10 bits
           {
         
               //setPointt = usb_cdc_getc(); // recebe o valor do  buffer - recebe o byte mais significativo
               //setPointt = (setPointt >> 8) + usb_cdc_getc(); // recebe outro byte
               setPointt = get_long();
               //setPoint = get_float_usb();
               //setPoint = getc(); // recebe o valor do  buffer - recebe o byte mais significativo
               //setPoint = (setPoint >> 8) + getc(); // recebe outro byte

         //if(kbhit()== true){     
               //gets(setPoint);
               output_high(pin_b0);
               //setPointt = atol(setPoint);
               //setPointt = getc(); // recebe o valor do  buffer - recebe o byte mais significativo
               //setPointt = (setPointt >> 8) + getc(); // recebe outro byte
               //setPointt = get_long();
         }
            //}
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 06 de Abril de 2011, 06:24
O que parece não funcionar, ou não estar sendo usado corretamente, é a função kbhit().

Faça um programa bem simples, sem kbhit(), que apenas envia e recebe pela UART, do tipo:

int      c;

while( TRUE ) {
     c = getchar();
     putchar( c );
}

ou então:

char     c;

while( TRUE ) {
     c = getch();
     putch( c );
}

Note que a função kbhit não é padronizada (não é ANSI C), portanto o uso e o comportamento desta devem ser entendidos na leitura do manual do seu compilador. Existem outras funções de entrada, getc(), getcUART() e getch(), algumas não padronizadas, que leem da UART e podem ser avaliadas. Entender o que o compilador faz é essencial nesse caso.

Qual é o seu compilador?

Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 06 de Abril de 2011, 12:40
O compilador é o CCS.
Essas funções que estou utilizando são do CCS (Kbhit, getc,...)
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 06 de Abril de 2011, 14:24
Tente os programas que eu sugeri.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 21 de Abril de 2011, 14:34
Ok ! Vou testar...
e dou um retorno
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 27 de Abril de 2011, 01:17
Testei seu exemplo e deu certo. Conseguir adequar (receber uma string) para usb também. Utilizei o hyperterminal, vou utilizar agora como teste o software em java. Dando certo, vou colocar a comunicação no firmware do projeto (controle do motor) para enfim realizar os testes "finais".
Qualquer dúvida ou sucesso postarei ake.

Grato
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 27 de Abril de 2011, 04:34
Ok.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 01 de Maio de 2011, 19:20
Oi amigo,
descobrir um erro no algoritmo do controlador PD por realimentação de velocidade, pois

o sinal de controle do PD clássico é u(t) = Kp*erro+ Kd*de(t)/dt,
onde derivada = (erro-erro_anterior)/Ts

só que o sinal de controle do PD por realimentação de velocidade é u(t) = Kp*erro -  kd*dy(t)/dt
onde y(t) é a saída.
então o algoritmo certo seria:

erro = setPoint - actualPosition(lido do adc);
derivative = (actualPosition - previous_actualPosi tion)/Ts;
control = kp*error -  Kd*derivative + control;
previous_actualPosi tion = actualPosition;

correto?

Fiz o teste com o Proteus e com software supervisorio e pude verificar que o software não estar enviando corretamente. Vou tentar consertar.

grato
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 01 de Maio de 2011, 20:22
Vinícius,

Oi amigo,
descobrir um erro no algoritmo do controlador PD por realimentação de velocidade, pois

o sinal de controle do PD clássico é u(t) = Kp*erro+ Kd*de(t)/dt,
onde derivada = (erro-erro_anterior)/Ts

só que o sinal de controle do PD por realimentação de velocidade é u(t) = Kp*erro -  kd*dy(t)/dt
onde y(t) é a saída.
então o algoritmo certo seria:

erro = setPoint - actualPosition(lido do adc);
derivative = (actualPosition - previous_actualPosi tion)/Ts;
control = kp*error -  Kd*derivative + control;
previous_actualPosi tion = actualPosition;

correto?

Fiz o teste com o Proteus e com software supervisorio e pude verificar que o software não estar enviando corretamente. Vou tentar consertar.

grato

Inicialmente você mencionou que o seu controlador PID (mestre), usando um PIC18F2480, acionará um outro controlador (escravo), enviando o SP para esse controlador. Aos leitores, essa arquitetura de controle, do tipo cascata, ou mestre - escravo, é frequentemente usada na indústria, e tem suas vantagens, quando adequadamente implementada. Neste caso:

(1) Pela teoria de controle, um controlador de posição é um controle de primeira ordem e o de velocidade de segunda ordem (é a derivada do primeiro). Para obter-se maior estabilidade, num controle em cascata, o usual é a malha de maior ordem ser o controlador mestre. Nesse caso, o controle de velocidade deveria ser o mestre.
(2) Caso o seu controlador escravo seja de velocidade e o seu controlador mestre, de posição, o controlador escravo (a ação proporcional apenas desse controlador) vai "correr atrás" da derivada da posição. E o seu controlador escravo, a ação proporcional apenas, vai acrescentar um zero no controle de posição mestre. Podendo instabilizar a coisa toda!!
(3) É necessário saber se o seu controlador escravo atua (é realimentado) com a velocidade ou a posição do motor.
(4) O seu controlador mestre controlará a posição, correto?
(5) "Agir por partes", .... aconselho a usar SOMENTE a ação proporcional primeiramente, para verificar se tudo está correto. Somente após o controle proporcional se mostrar funcional, colocar as ações integral e derivativa para funcionar.  Isso vale para os controladores mestre e escravo, com isso, a ordem do sistema se reduz. E consequentemente, a análise e a sintonia dos controladores fica +fácil.
(6) Se a coisa ficar complicada, difícil fazer o controle estabilizar... Considere usar o controle de posição como escravo, ou o controlador único.
 
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 01 de Maio de 2011, 21:09
O objetivo é controlar a posição do motor.
A função de transferencia (posição/tensao) é de segunda a ft (velocidade/tensao) é de primeira.
Fiz o projeto utilizando o matlab tbm. Para isso utilizei PD por realimentacao de velocidade (P&D). Não utilizei o PD clássico pois este acrescenta um zero, ou seja, instabilidade, no caso.

Então tem somente um controlador (P&D) e uma planta de segunda ordem. Pelo matlab deu certo, controlou.
Refaço a pergunta do post anterior.

Valeu pela ajuda.
Grato
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 01 de Maio de 2011, 23:03

Eu faria primeiro um teste apenas com ação proporcional, conforme o seu algoritmo.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 02 de Maio de 2011, 00:03
Uma outra dúvida ake,

O conversor A/D e PWM trabalha com 10 bits.
e minhas variaveis (control, derivative, actual_position( recebe do programa em Java, ou qq outro) são long int, inclusive a que recebe do A/D.

O melhor seria uniformizar tudo (10 bits), ou deixando como tá long int, o compilador já trata automaticamente. Lembrando que kp e kd são floats, pois seus valores são bem pequenos o,oo alguma coisa.

Grato
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 02 de Maio de 2011, 05:40
Vinícius,

O algoritmo PID é melhor fazer em Float, para facilitar os cálculos.

É melhor uniformizar as entradas e saídas com inteiro de 10 bits (0 a 1024), o que inclui o A/D e o PWM. Converta-os em 0 a 100% Float para compatibilizar com o algoritmo PID.

Por exemplo, se a saída do A/D for 512, o sinal de posição para o PID será de 50.000%.

O Set-Point do PID será também 0 a 100% Float, para compatibilizar com o sinal oriundo do sensor, já convertido. Você pode
até usar uma escala de unidades de engenharia (posição em mm, velocidade em mm/s) em sua IHM (Interface Homem Máquina), mas aí converta em 0 a 100% Float. Para isso, deverá ser estabelecida uma faixa de trabalho ("range") para cada variável.

Também devem ser Float os ganhos (kp, kd, ki). O sinal de saída do PID, sendo Float de 0 a 100%, será convertido para 0 a 1024, para ser carregado no PWM.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 02 de Maio de 2011, 11:18
Valeu pela dica, mas como converto todas as variaveis para float.
Tipo long int são 16 bits.
faria assim para ser 10 bits:
long int var;
var =  var & 0000001111111111;
?
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 02 de Maio de 2011, 11:41
Sim, para usar 10 bits tem que ser "int" mesmo. Como só vai usar a parte positiva do "int",  e apesar de não ser indispensável, eu usaria "unsigned int".

O "long int" possui 16 bits?
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 02 de Maio de 2011, 13:19
Pelo compilador CCS

int , 8 bits ,  0 a 255

unsigned int , 8 bits, 0 a 255

long int , 16 , 0 a 65535

float , 32 bits, 3.4E-38 a 3.4E+38

A idéia é o seguinte: vou tomar transformar as variaveis para 10 bits e dá um casting para float? e depois terei que transformar em 10 bits de novo para o PWM.
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 02 de Maio de 2011, 14:10

Ao invés de casting, use funções de conversão específicas (int para float ou vice versa).
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 02 de Maio de 2011, 15:52
Tem esse tipo de função no CCS? Vc conhece alguma função?
Eu estava pensando desta forma:

long int var;
float var2;

var2 = (float) var;

Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 02 de Maio de 2011, 16:58
Voce pode testar o uso do "casting", conforme sua mensagem anterior. Sugeri as funções de conversão, pois em algumas conversões o "cast" não funciona corretamente, inclusive quando há arredondamento (int <- float), mas pensando melhor, acho que não será o seu caso.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 02 de Maio de 2011, 19:28
Mais uma vez obrigado pela ajuda! Vai desculpando pelas perguntas bestas.
Vou ajetar o código ake, posso te mandar a versão "final"? Para verificar estas questões de compatibilidade.

Att
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 03 de Maio de 2011, 09:47
Ok.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 04 de Maio de 2011, 00:01
Posso enviar para vc o código fonte?
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 04 de Maio de 2011, 00:08
Sim, pode enviar.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 04 de Maio de 2011, 01:16
Enviado!!!
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 04 de Maio de 2011, 08:15
Vinícius,

Tirei alguns erros e acho melhor usar "unsigned long int" ao invés de "long int", pois os registros do ADC e PWM são sempre positivos (0 a 1023).

Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 04 de Maio de 2011, 08:35

Outra coisa, em sistemas de controle bem construídos, é usual separar as tarefas de tempo real das tarefas que possuem latência (como a comunicação USB, que depende do Windows no lado da IHM), de modo a não criar um intervalo de varredura (Ts) variável. Apesar disso não afetar na temporização da varredura, agrupei as tarefas de comunicação, para que o processamento do PID seja previsível.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 04 de Maio de 2011, 22:53
Oi, valeu. Entendi as modificaçoes.
Por exemplo, vou usar um potenciometro (0 a 5 V) para lê do ADC. Tem a necessidade de fzr a seguinte conversao?
 5 volts - 1023 - 360 graus.

entao um valor x para ser em graus é: x*(360/1023).
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 04 de Maio de 2011, 23:07
...consequentemente teria que converter control_l da seguinte forma: control_l = control_l*(1023/360)
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 05 de Maio de 2011, 01:30

Voce só precisa converter x (lido do A/D) para graus se for apresentar o valor numa tela. A saída de controle (para o PWM) é a mesma coisa, só converte para 0 a 100% ao invés de 0 a 360 graus. Lembre que a saída (PWM) vai para o controlador seguinte (numa faixa de 0 a 1023 e depois numa tensão de 0 a 5V?), portanto, ao apresentar numa tela usar um fator de conversão compatível (mm/s ou graus/s).
Título: Re:Controle_PID_PIC18F2480
Enviado por: geancoelho em 05 de Maio de 2011, 08:10
Vinigusto

Seu hardware esta pronto??

Caso seja passivel de mudança em meus projetos que preciso de uma saida analogica uso o MCP4921C.

Este tem resolução de 12 bits e comunicação em I2C.

Tenho biblioteca em CCS para ele caso precise e posso ajudar em outras coisas tambem.

Venho Acompanhando a memoravel aula de implementação de PID que nosso amigo minilathe vem ministrando e sempre tive muita curiosidade de implementalo pois sempre usei o mesmo no MATLAB mas é muito mais simples.

Minilathe Estes programas em pyton podem gerar graficos de tempo X dado?? é muito complicado de geralos??
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 05 de Maio de 2011, 13:22
Gean,

O Python pode gerar gráficos de tendência, apesar de eu nunca ter feito nessa linguagem. Mas há várias bibliotecas gráficas compatíveis que poderiam ser usadas. Um exemplo é o software EMC2, que usa o Tcl/Tk para isso, que são perfeitamente utilizáveis junto com o Python.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 05 de Maio de 2011, 13:41
Gean:
Está quase, falta o mais importante, testar!.

minilathe:
Eu falei de converter tanto o valor lido do adc para graus quanto converter control_l de graus para 0 a 100%. Pensei nisso pq o valor que vou lê do software já vai vim em graus.
Mas vc acha que não precisa alterar mais alguma coisa não? Do jeito que está já pode realiazar os testes?

Grato
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 05 de Maio de 2011, 14:02
Vinícius,

minilathe:
Eu falei de converter tanto o valor lido do adc para graus quanto converter control_l de graus para 0 a 100%. Pensei nisso pq o valor que vou lê do software já vai vim em graus.
Mas vc acha que não precisa alterar mais alguma coisa não? Do jeito que está já pode realiazar os testes?

A saída lida na sua interface (IHM) não será em graus, mas em unidades compatíveis com o set-point do controlador escravo. Mas a nível de sinal e do software, tudo se passa na escala de volts e nos fatores aplicados aos conversores A/D e D/A.
 
Não precisa alterar mais nada, manda bala!!
Título: Re:Controle_PID_PIC18F2480
Enviado por: geancoelho em 05 de Maio de 2011, 14:17
Vou ficar aguardando os testes!!!
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 23 de Maio de 2011, 00:39
Olá minilathe, realizei os testeis através do software proteus mas não obtive um bom resultado. Na verdade saíram valores muitos estranho (crescentes). Queria saber se vc tem alguma ideia do que poderia ser? Dei uma parada semana passada mas voltar por agora.

Grato
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 23 de Maio de 2011, 00:53
Olá minilathe, realizei os testeis através do software proteus mas não obtive um bom resultado. Na verdade saíram valores muitos estranho (crescentes). Queria saber se vc tem alguma ideia do que poderia ser? Dei uma parada semana passada mas voltar por agora.

Grato

Quais valores eram crescentes?
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 23 de Maio de 2011, 21:48
O do controle mesmo. Acho que tenho que  limita-lo antes de enviar para o pwm.
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 23 de Maio de 2011, 22:30

Você tem que analisar o que está acontecendo, a saída do controlador é para saturar mesmo (valor menor ou igual a 100%) se o erro persistir, isso é normal. Consegue enviar um gráfico com as variáveis SP, PV e Saída?

Pode enviar um diagrama de blocos de sua simulação?
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 29 de Junho de 2011, 22:44
Vinicius,

E controlador PID? Depois poste o seu avanço, fotos, ....
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 13 de Julho de 2011, 23:43
Olá minilathe,
fiquei ausente por algum tempo no projeto. Ainda estou na parte dos teste. Vou lhe mostrar como estou tentando fzr no proteus e tabela de dados. Acho que o modo que eu estou fzd não tem como dá certo (acho) devido a leitura do posicionamento atual através do potenciômetro não está sendo "automatico".

Valeu
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 23 de Julho de 2011, 21:52
Olá minilathe,
como faço para te enviar uma mensagem privada com os dados da simulação, código e o arquivo do proteus? Como disse na mensagem anterior que o modo que eu estou simulando não está adequado.
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 24 de Julho de 2011, 09:29
Vinicius,

Te respondi via mensagem privada.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 25 de Julho de 2011, 09:44
Enviei para seu email.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 29 de Julho de 2011, 21:00
 Minilathe, vc recebeu meu email?

Grato
Título: Re:Controle_PID_PIC18F2480
Enviado por: minilathe em 29 de Julho de 2011, 22:36
Olá Vinícius,

Recebi sim, mas ainda não pude analisar...
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 30 de Julho de 2011, 18:25
Tranquilo, qualquer novidade posto ake.
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 18 de Agosto de 2011, 10:37
Fiz umas modificações no código. Fiz um pequeno teste e as saídas estão coerentes. Como estou usando um potenciômetro na entrada do ADC (como posição atual), a medida que vou aproximando da referência o sinal do erro e de controle vão diminuindo. O que eu achei estranho na simulação no proteus foi o fato de "ativar" o PWM só quando posiciona o potenciômetro na referência. Pelo código não tem como acontecer isto, pode algo do proteus ou so. Usei o hyperterminal tbm.
Quando o senhor puder, eu lhe envio os arquivos.

Att
Título: Re:Controle_PID_PIC18F2480
Enviado por: vinigusto em 22 de Novembro de 2011, 10:47
Olá minilathe, o teste na prática ainda não foi feito, pois não um problema no driver no motor. Conseguir definir um tempo de amostragem analiticamente com base na constante de tempo do processo. Falta realizar só o teste prático. Estou ansioso para ver se realmente vai funcionar.

Quando tiver resultados posto ake.

ps: Você chegou a analisar os dados da simulação, código e o arquivo do proteus?
Título: Re:Controle_PID_PIC18F2480
Enviado por: geancoelho em 08 de Fevereiro de 2012, 12:12
Boa tarde Vinicius

Como nunca mais deu resposta vou perguntar, como esta o seu controlador PID???
Ja tentei por varias vezes implementalo e nunca tive sucesso, por isso venho acompanhando seu topico, pois se o seu funcionar gostaria de estudalo para ver como foi implementado.

Fico grato de sua resposta.