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
-
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
-
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,
-
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
-
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.
-
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
-
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
-
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
-
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,
-
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
-
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
-
Obrigado pela dica mais uma vez! Posso enviar meu código para vc vê?
Grato
-
Pode ser? Para poder esclarecer + a dúvida.
Grato
[/quote]
-
Vinigusto,
Obrigado pela dica mais uma vez! Posso enviar meu código para vc vê?
Grato
Claro!! :) , pode mandar...
Abraços,
-
Olá, poderia confirmar se vc recebeu o anexo. Eu enviei. Me passa seu email por favor para confirmar.
Grato
-
Vinigusto,
Não recebi, se quiser mande como mensagem privativa do Forum.
-
Recebeu a mensagem personalizada?
-
Olá, posso enviar o código com algumas correções que eu fiz?
Grato
-
Ola Vinícius,
Pode mandar seu programa. Já foi atualizado?
Abraços,
-
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?
-
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,
-
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
-
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.
-
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?
-
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.
-
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.
-
(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.
-
(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!
-
[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
-
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.
-
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
//}
-
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.
-
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
-
Poderia enviar todo o seu código? O pedaço que enviou não permite verificar se está tudo correto.
-
Claro que posso! Segue em anexo. Este código é de outro projeto meu (que deu certo) por isso estou testando a comunicação nele.
-
Acho que falta a parte do RS232....
-
Qual parte?
Eu coloquei a #use rs232...
-
O use é uma inicialização da porta apenas. Onde estão os comandos de leitura, escrita, ...?
-
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();
}
//}
-
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?
-
O compilador é o CCS.
Essas funções que estou utilizando são do CCS (Kbhit, getc,...)
-
Tente os programas que eu sugeri.
-
Ok ! Vou testar...
e dou um retorno
-
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
-
Ok.
-
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
-
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.
-
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
-
Eu faria primeiro um teste apenas com ação proporcional, conforme o seu algoritmo.
-
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
-
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.
-
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;
?
-
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?
-
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.
-
Ao invés de casting, use funções de conversão específicas (int para float ou vice versa).
-
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;
-
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.
-
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
-
Ok.
-
Posso enviar para vc o código fonte?
-
Sim, pode enviar.
-
Enviado!!!
-
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).
-
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.
-
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).
-
...consequentemente teria que converter control_l da seguinte forma: control_l = control_l*(1023/360)
-
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).
-
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??
-
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.
-
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
-
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!!
-
Vou ficar aguardando os testes!!!
-
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
-
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?
-
O do controle mesmo. Acho que tenho que limita-lo antes de enviar para o pwm.
-
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?
-
Vinicius,
E controlador PID? Depois poste o seu avanço, fotos, ....
-
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
-
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.
-
Vinicius,
Te respondi via mensagem privada.
-
Enviei para seu email.
-
Minilathe, vc recebeu meu email?
Grato
-
Olá Vinícius,
Recebi sim, mas ainda não pude analisar...
-
Tranquilo, qualquer novidade posto ake.
-
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
-
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?
-
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.