RENÉ DESCARTES OLÍMPIO PEREIRA - DEE
Transcrição
RENÉ DESCARTES OLÍMPIO PEREIRA - DEE
UNIVERSIDADE FEDERAL DO CEARÁ CENTRO DE TECNOLOGIA DEPARTAMENTO DE ENGENHARIA ELÉTRICA RENÉ DESCARTES OLÍMPIO PEREIRA SISTEMA DE CONTROLE DE VELOCIDADE DIGITAL EMBARCADO DE MOTOR DE CORRENTE CONTÍNUA DE ÍMÃ PERMANENTE FORTALEZA 2013 RENÉ DESCARTES OLÍMPIO PEREIRA SISTEMA DE CONTROLE DE VELOCIDADE DIGITAL EMBARCADO DE MOTOR DE CORRENTE CONTÍNUA DE ÍMÃ PERMANENTE Monografia apresentada ao curso de Engenharia Elétrica da Universidade Federal do Ceará, como requisito parcial à obtenção do título de Engenheiro Eletricista. Orientadora: Profa. Dra. Laurinda Lúcia Nogueira dos Reis. FORTALEZA 2013 Dados Internacionais de Catalogação na Publicação Universidade Federal do Ceará Biblioteca de Ciências e Tecnologia P495s Pereira, René Descartes Olímpio. Sistemas de controle de velocidade digital embarcado de motor de corrente continua de imã permanente / René Descartes Olímpio Pereira. – 2013. 145f. : il. color., enc. ; 30 cm. Monografia(graduação) – Universidade Federal do Ceará, Centro de Tecnologia, Departamento de Engenharia Elétrica, Graduação em Engenharia Elétrica, Fortaleza, 2013. Orientação: Profa. Dra. Laurinda Lúcia Nogueira dos Reis. 1. Sistema de controle digital. 2. Controle de velocidade. 3. Sistemas embarcados. I. Título. CDD 621.3 Aos meus pais, Gabriel e Mércia. AGRADECIMENTO À minha família, em especial aos meus pais, pelo cuidado, apoio, e extrema paciência comigo nos meus momentos difíceis e pela motivação e reconhecimento nas minhas pequenas conquistas. À Profa. Dra. Laurinda Lúcia Nogueira dos Reis, pela excelente orientação e pelo tempo dedicado para fazer o desenvolvimento deste trabalho possível. Aos participantes da banca examinadora Prof. Dr. Bismark Claure Torrico e Msc. Wellington Assunção da Silva, pelo tempo, pelas valiosas colaborações e sugestões. Aos meus colegas de todas as turmas pelas quais passei do curso de Engenharia Elétrica, pelo convívio, troca de experiências e bons momentos, que fizeram a minha longa passagem pelo curso uma viagem de transformação única. “A criança é a inocência, e o esquecimento, um novo começar, um brinquedo, uma roda que gira sobre si, um movimento, uma santa afirmação.” Friedrich Nietzsche RESUMO Este trabalho apresenta um método de controle de velocidade digital de motores, onde se projeta um controlador PI, com realocação do ganho proporcional para o caminho de realimentação, para se obter uma resposta estritamente aperiódica com tempo de assentamento ótimo. Uma estratégia anti-wind-up é desenvolvida com o controlador na forma incremental. O método é aplicado com a implementação de um sistema de controle de velocidade digital de um motor de corrente contínua de ímã permanente. Ele é baseado na ferramenta de desenvolvimento eZ430-RF2500 da Texas Instruments e conta com um programa de interface gráfica para computador em Java. Simulações em Simulink/MATLAB do modelo do sistema de controle digital e resultados experimentais também são apresentadas. Palavras-chave: Controle PID. Controle de velocidade. Sistemas embarcados. ABSTRACT This work presents a digital speed control method of motors, where a PI controller is designed, with the relocation of the proportional gain to the feedback path, to obtain an aperiodic response with optimal settling time. An anti-wind-up strategy is developed with the controller in the incremental form. The method is applied with the implementation of a digital speed control system of a permanent magnet direct current motor. The system is based on the Texas Instrument’s eZ430-RF2500 development tool and count with a Java graphical user interface. Simulink/MATLAB simulations of the digital control system model and experimental results are presented too. Keywords: PID control. Speed control. Embedded systems. LISTA DE ILUSTRAÇÕES Figura 2.1 – Motor CC convencional (escovado) ................................................................16 Figura 2.2 – Circuito equivalente de um motor CC .............................................................18 Figura 2.3 – Reposta de um motor CC a uma elevação da tensão de armadura em degrau ............................................................................................................ 21 Figura 2.4 – Um sistema de engrenagens .......................................................................... 23 Figura 3.1 – Arquitetura da família MSP430F22x4 .......................................................... 25 Figura 3.2 – Gerador de frequência em USCI_A0 mostrando (a) modo de sobreamostragem com dois divisores e clock intermediário BITCLK16, e (b) modo de baixa frequência com apenas um divisor .................................. 37 Figura 4.1 – Diagrama de blocos de um sistema de controle de velocidade com implementação digital do algoritmo de controle ........................................... 43 Figura 4.2 – A variação na velocidade real (n) no eixo do motor durante um período de amostragem T ........................................................................................... 46 Figura 4.3 – Controlador de velocidade digital com atuador de torque ideal Ka = 1, controlador de velocidade discreto e subsistema mecânico no domínio contínuo ......................................................................................................... 47 Figura 4.4 – O diagrama de blocos de um sistema de controle de velocidade digital compreendendo sinais discretos .................................................................... 48 Figura 4.5 – Implementação discreta do controlador de velocidade com ação proporcional e integral ................................................................................... 49 Figura 4.6 – Controlador de velocidade com ação proporcional e integral implementado na forma incremental ..................................................................................... 50 Figura 4.7 – Controlador de velocidade discreto com o ganho proporcional realocado no caminho de realimentação ........................................................................ 53 Figura 4.8 – Uma resposta ao degrau estritamente aperiódica .......................................... 55 Figura 4.9 – Um controlador de velocidade digital indicando os coeficientes de escalonamento KFB e KA e estabelecendo a relação entre os sinais de velocidade e torque reais e suas representações digitais de comprimento de palavra finito T*DIG e *DIG, localizadas na RAM .......................................... 60 Figura 4.10 – O sistema de controle de velocidade digital com capacidade de torque limitada do atuador .......................................................................................... 61 Figura 4.11 – Resposta a um elevado degrau de entrada, levando o sistema à saturação ...... 63 Figura 4.12 – Forma incremental do controlador de velocidade digital com ação proporcional realocada no caminho de realimentação ..................................... 63 Figura 4.13 – Resposta a um degrau elevado obtida com um controlador de velocidade PI discreto na sua implementação incremental e com a estrutura AWU da Figura 4.12 ....................................................................................................... 64 Figura 5.1 – Imagem da interface gráfica do sistema de controle de velocidade digital ..... 67 Figura 5.2 – Apresentação do método de medição combinada de frequência e período ..... 76 Figura 5.3 – Modelo em Simulink do Controlador PI digital incremental com realocação do ganho proporcional para estratégia anti-wind-up ....................................... 80 Figura 5.4 – Modelo em Simulink do sistema de controle de velocidade digital com a componente de torque do atrito viscoso incluída no torque de perturbação .... 80 Figura 5.5 – Resposta de velocidade e sinal de controle, incluindo a componente de torque do atrito viscoso no torque de perturbação, para um degrau de 80 rpm (8,378 rad/s) em t = 0 e para uma perturbação de 0,3 N.m em t = 1 s ............. 81 Figura 5.6 – Resposta de velocidade em vazio e sinal de controle, incluindo a componente de torque do atrito viscoso no torque de perturbação, para um degrau de 80 rpm (8,378 rad/s) em t = 0 e um degrau de -80 rpm em t = 1 s, com o torque máximo TMAX = 0,05 N.m .......................................................... 83 Figura 5.7 – Modelo em Simulink do sistema de controle de velocidade digital com a componente de torque do atrito viscoso incluída no modelo do motor ........... 84 Figura 5.8 – Resposta de velocidade e sinal de controle, incluindo a componente de torque do atrito viscoso no modelo do motor, para um degrau de 80 rpm (8,378 rad/s) em t = 0 e para uma perturbação de 0,3 N.m em t = 1 s ............. 85 Figura 5.9 – Resposta de velocidade em vazio e sinal de controle, incluindo a componente de torque do atrito viscoso no modelo do motor, para um degrau de 80 rpm (8,378 rad/s) em t = 0 e um degrau de -80 rpm em t = 1 s, com o torque máximo TMAX = 0,3 N.m ............................................................ 87 Figura 5.10 – Resposta ao degrau de velocidade de 80 rpm (8,378 rad/s) e sinal de controle da simulação, com a tensão da bateria de 13,6 V .............................. 91 Figura 5.11 – Resposta ao degrau de velocidade de 80 rpm para -80 rpm e sinal de controle da simulação, com a tensão da bateria de 13,6 V .............................. 93 Figura 5.12 – Resposta ao degrau de velocidade de 70 rpm (7,33 rad/s) e sinal de controle da simulação, com a tensão da bateria de 10,7 V ............................................ 95 Figura 5.13 – Resposta ao degrau de velocidade de 70 rpm para -70 rpm e sinal de controle da simulação, com a tensão da bateria de 10,7 V .............................. 97 LISTA DE TABELAS Tabela 5.1 – Código Gray com a definição dos canais do encoder e dos padrões ........... 75 LISTA DE ABREVIATURAS E SIGLAS A/D Analógico/Digital AWU Anti-Wind-Up CA Corrente Alternada CC Corrente Contínua CMOS Complementary Metal-Oxide-Semiconductor CPU Central Processing Unit D/A Digital/Analógico DSP Digital Signal Processing fcem Força Contra-eletromotriz fem Força Eletromotriz FIR Finite Impulse Response I2C Inter-Integrated Circuit IrDA Infrared Data Association LCD Liquid Crystal Display LIN Local Interconnect Network MAB Memory Adress Bus MDB Memory Data Bus PI Proporcional e Integral PID Proporcional, Integral e Derivativo PWM Pulse Width Modulation RAM Random Access Memory RISC Reduced Instruction Set Computer SPI Serial Peripheral Interface TTL Transistor-Transistor Logic UART Universal Asynchronous Receiver/Transmitter USB Universal Serial Bus USCI Universal Serial Communication Interface ZOH Zero-Order Hold LISTA DE SÍMBOLOS Vs Tensão de armadura Ia Corrente de armadura Td Torque médio desenvolvido Kt Constante de torque p Fluxo magnético por polo Velocidade angular do rotor Ea Força contra-eletromotriz Ke Constante de força contra-eletromotriz Km Constante do motor Ra Resistência de armadura La Indutância de armadura TL Torque de carga km Constante do motor quando o fluxo por polo é constante em Constante de tempo eletromecânica a Constante de tempo elétrica m Constante de tempo mecânica Ângulo de deslocamento r Raio da engrenagem N Número de dentes da engrenagem T Período de amostragem * Velocidade de referência Erro de velocidade T* Torque de referência Ka Ganho do atuador de torque TMAX Torque máximo do limitador J Momento de inércia no eixo KP Ganho proporcional KI Ganho integral p Ganho proporcional normalizado i Ganho integral normalizado KFB Coeficiente de escalonamento da velocidade KA Coeficiente de escalonamento do torque amax Aceleração quando o torque é igual ao valor máximo VC Tensão no microcontrolador Vencoder Tensão no encoder Np Resolução do encoder Tsc Janela de observação básica T Janela de observação estendida N Número de pulsos do encoder capturados dentro da janela de observação Th Período de tempo entre o final da janela de observação e quando o ultimo pulso sc foi capturado dentro dela Thf Período de cada ciclo do temporizador Csc Total de ciclos da janela observável básica C sc Ch Soma total de ciclos para uma janela observável estendida Quantidade de ciclos quando ocorreu a captura do último pulso dentro da janela observável DPWM Ciclo de trabalho do PWM CTB Total de ciclos do temporizador CPWM Quantidade de ciclos que correspondem ao ciclo de trabalho do PWM Vs* Tensão de referência que deve ser aplicada ao motor Vn Tensão nominal do motor SUMÁRIO 1 INTRODUÇÃO ................................................................................................ 13 2 MOTORES DE CORRENTE CONTÍNUA .................................................. 15 2.1 Introdução ......................................................................................................... 15 2.2 Torque e força contra-eletromotriz (fcem) .................................................... 16 2.3 Circuito Equivalente ........................................................................................ 17 2.4 Velocidade de rotação a vazio ......................................................................... 18 2.5 Velocidade de rotação com carga ................................................................... 19 2.6 Motores de corrente contínua de ímã permanente ....................................... 19 2.7 Comportamento dinâmico e constantes de tempo ......................................... 20 2.8 Sistemas com engrenagens .............................................................................. 22 3 MICROCONTROLADORES MSP430 ......................................................... 24 3.1 Introdução ......................................................................................................... 24 3.2 Microcontrolador MSP430F2274 ................................................................... 3.3 Sistema de clock ................................................................................................ 27 3.4 Portas de entrada/saída digitais ...................................................................... 28 3.4.1 Registrador de entrada PxIN ............................................................................ 28 3.4.2 Registrador de saída PxOUT ............................................................................ 28 3.4.3 Registrador de direção PxDIR .......................................................................... 29 3.4.4 Registrador de habilitação dos resistores de pullup/pulldown PxREN .......... 29 3.4.5 Registradores de seleção de função PxSEL ..................................................... 29 3.4.6 Registradores de habilitação de interrupção P1EI e P2EI .............................. 29 3.4.7 Registradores de seleção de transição da interrupção P1IES e P2IES .......... 30 3.4.8 Registradores de flag de interrupções P1IFG e P2IFG .................................. 30 3.5 Temporizadores ................................................................................................ 30 3.5.1 Bloco temporizador ........................................................................................... 31 3.5.2 Canais de captura/comparação ........................................................................ 33 3.5.2.1 Modo de captura ................................................................................................ 33 3.5.2.2 Modo de comparação ......................................................................................... 34 3.6 Interface de Comunicação Serial Universal (USCI): modo assíncrono 25 (UART) .............................................................................................................. 35 3.6.1 Configurando a velocidade de comunicação com o módulo USCI_A0 .......... 36 3.6.1.1 Modo de baixa frequência do gerador de velocidade de comunicação ............. 37 3.6.2 Operação do módulo USCI_A0 ........................................................................ 3.7 Modos de operação em baixa potência ........................................................... 38 4 CONTROLE DE VELOCIDADE DIGITAL DE MOTORES .................... 41 4.1 Introdução ......................................................................................................... 41 4.2 Sistema com atuador de torque ideal e carga inercial .................................. 4.3 Função de transferência do subsistema mecânico ......................................... 44 4.4 Função de transferência do subsistema de medição de velocidade ............. 45 4.5 Função de transferência do sistema em malha fechada ............................... 46 4.5.1 Polos de malha fechada e efeitos de zeros de malha fechada ......................... 51 4.5.2 Realocação do ganho proporcional .................................................................. 52 4.6 Determinação de parâmetros de controladores de velocidade digitais ....... 54 4.6.1 Resposta estritamente aperiódica ..................................................................... 54 4.6.2 Formulação da função critério ......................................................................... 55 4.6.3 Cálculo dos valores otimizados dos ganhos normalizados .............................. 4.7 Estratégia anti-wind-up .................................................................................... 61 5 SISTEMA DE CONTROLE DE VELOCIDADE DIGITAL BASEADO NA FERRAMENTA EZ430-RF2500 ............................................................. 38 42 57 65 5.1 Introdução ......................................................................................................... 65 5.2 Interface gráfica ............................................................................................... 66 5.3 Módulo local ..................................................................................................... 69 5.3.1 Eventos provenientes da interface gráfica ....................................................... 70 5.3.2 Eventos provenientes do módulo remoto .......................................................... 71 5.4 Módulo remoto ................................................................................................. 71 5.4.1 Comunicação com o módulo local ................................................................... 72 5.4.2 Medição de velocidade ...................................................................................... 73 5.4.2.1 Circuito de interface do encoder ........................................................................ 73 5.4.2.2 Escolha do período de amostragem ................................................................... 74 5.4.2.3 Determinação do sentido de rotação ................................................................. 5.4.2.4 Medição combinada de frequência e período .................................................... 76 5.4.3 Controlador PI .................................................................................................. 77 5.4.3.1 Estimação dos parâmetros do modelo do motor CC ......................................... 78 5.4.3.2 Determinação dos parâmetros do controlador .................................................. 79 5.4.3.3 Avaliação de desempenho do controlador por meio de simulação 74 computacional .................................................................................................... 79 5.4.4 Acionamento do motor CC ................................................................................ 88 5.4.4.1 Circuito de acionamento do motor CC .............................................................. 5.4.4.2 Cálculo do número de ciclos do PWM ............................................................... 89 5.5 Resultados Experimentais ............................................................................... 89 6 CONCLUSÃO .................................................................................................. 99 REFERÊNCIAS ............................................................................................... 101 APÊNDICE A – CÓDIGOS FONTE ............................................................. 103 88 13 1 INTRODUÇÃO A modelagem de motores de Corrente Contínua (CC) no domínio contínuo é amplamente abordada na literatura, como em Ogata (2010), Dorf e Bishop (2011) e Golnaraghi e Kuo (2010). Nesses trabalhos são apresentados as equações diferencias do modelo do motor CC, o modelo em diagrama de blocos, as funções de transferência e as constantes de tempo. Uma análise do regime transitório do motor CC também pode ser encontrada em Hughes (2006). Nela, argumenta-se que para grande parte das aplicações de controle é possível desprezar-se o efeito da constante de tempo elétrica, pois esta é muito menor do que a constante de tempo eletromecânica. Uma técnica de controle de velocidade no domínio contínuo, por meio de um controlador Proporcional Integral (PI), pode ser encontrada em Haishui et al. (2010). Trabalhos sobre técnicas de controle de velocidade de motores CC no domínio discreto datam desde a década de 70, como os trabalhos de Lin e Koepsel (1977) e Wang e Chen (1979). Atualmente, pode-se encontrar vários trabalhos nessa área. Em especial, pode-se citar o trabalho de Vukosavić (2007), que aborda técnicas de controle de velocidade tanto no domínio contínuo como no discreto. Este trabalho tem o objetivo de descrever uma técnica de controle de velocidade digital de motores e sua aplicação no controle de velocidade de um motor CC de ímã permanente. O sistema de controle digital implementado foi desenvolvido utilizando a ferramenta de desenvolvimento eZ430-RF2500 da Texas Instruments, baseada no microcontrolador de 16 bits MSP430F2274. Também foi desenvolvido um programa de interface gráfica para computador implementado na linguagem Java. No capítulo 2 são abordados os fundamentos da teoria de motores CC, e de forma específica o motor CC de ímã permanente. São abordados os fundamentos para a operação tanto no regime permanente como no regime transitório. O capítulo 3 trata dos detalhes técnicos do microcontrolador MSP430, em especial do modelo MSP430F2274. São descritos a configuração e operação dos componentes utilizados no sistema de controle digital. São eles sistema de clock, portas de entrada/saída, temporizadores, interface de comunicação serial e modos de operação em baixa potência. O capítulo 4 descreve a teoria do controle de velocidade digital de motores. Uma técnica utilizando um controlador PI é apresentada. É mostrado como é possível projetar um controlador eliminando o sobressinal da resposta de velocidade e obtendo um tempo de 14 resposta óptimo. Também é apresentada uma estratégia anti-wind-up para o sistema de controle. No capítulo 5 é apresentado a aplicação do controlador projetado no capítulo 4 no controle de velocidade de um motor CC de ímã permanente. O sistema de controle implementado é dividido em três componentes. Uma interface gráfica, um módulo local e um módulo remoto. O desenvolvimento e operação de cada componente é mostrado em detalhes. O capítulo 6 é formado pelas conclusões deste trabalho. 15 2 MOTORES DE CORRENTE CONTÍNUA 2.1 Introdução Desde o final do século dezenove os sistemas elétricos de Corrente Alternada (CA) predominaram sobre os sistemas de Corrente Contínua (CC). No entanto, por várias décadas, os motores CC continuaram sendo uma grande parcela do consumo de equipamentos elétricos (Chapman, 2005). Sistemas de corrente contínua ainda são comuns em muitas aplicações. Por isso, nestes casos, faz sentido a utilização de motores CC. Porém, existem aplicações onde o custo adicional de comutadores e conversores CA/CC é justificado pelo desempenho superior que um motor CC pode apresentar, como elevado torque de partida e a operação em velocidades que não são alcançadas por motores CA (Guru; Hiziroglu, 2001). É nos sistemas de controle onde os motores CC encontram sua principal aplicação. Suas características de velocidade e torque permitem que essas grandezas sejam precisamente controladas dentro de uma ampla faixa de valores. Tal fato faz deles a escolha preferida em sistemas de posicionamento e controle de velocidade. No entanto, não se pode negar que da década de 1980 aos dias atuais, com a difusão dos inversores de frequência, os motores CA passaram a ser a nova escolha em muitas aplicações de controle de velocidade (Hughes, 2006). De acordo com Hughes (2006, tradução nossa), a estrutura básica de um motor CC pode ser vista na Figura 2.1 e é descrita da seguinte forma: O motor tem dois circuitos separados. Os pares de terminais menores conectam-se com os enrolamentos de campo, que envolvem cada polo e estão normalmente em série: no regime permanente toda potência de entrada para os enrolamentos de campo é dissipada como calor – nada é convertido em potência de saída mecânica. Os terminais principais transportam a corrente de “potência” ou “trabalho” para as escovas que fazem contato deslizante com o enrolamento de armadura no rotor. A alimentação para o campo é separada daquela para a armadura, por isso a descrição “excitação separada”. 16 Figura 2.1 – Motor CC convencional (escovado). Fonte: Adaptada de Hughes (2006). Existem cinco tipos principais de motores CC de acordo com a forma de excitação: a) excitação independente ou separada; b) excitação em paralelo; c) ímã permanente; d) excitação em série; e) excitação composta. Neste capítulo, trata-se apenas do motor CC com ímã permanente, pois é o tipo utilizado no sistema de controle de velocidade que será apresentado. 2.2 Torque e força contra-eletromotriz (fcem) Em um motor CC o campo magnético produzido pelos enrolamentos de campo é uniforme e praticamente constante. Quando alimenta-se o circuito da armadura com uma fonte de tensão constante Vs, os condutores da armadura, que conduzem uma corrente constante, são submetidos, dentre outras forças, a forças (forças de Lorentz) que tendem a movimentar o rotor da máquina CC. Enquanto o rotor está parado, a corrente de armadura Ia é limitada apenas pela resistência do circuito de armadura Ra. Como geralmente essa resistência 17 tem um valor muito baixo, a corrente de partida do motor é vinte a trinta vezes maior que a corrente à plena carga. Essa condição produz um torque de partida muito elevado em motores CC e consequentemente uma rápida aceleração do rotor. O torque médio desenvolvido Td pelas forças a que estão submetidos os condutores da armadura é diretamente proporcional ao produto do fluxo por polo p pela corrente de armadura Ia. Td Kt p I a , (2.1) onde Kt é a constante de torque do motor CC. À medida que o rotor acelera, cada espira na armadura sofre o efeito da variação de fluxo em seu plano. Assim, uma força eletromotriz (fem) é induzida no circuito da armadura. Pela lei de Lenz, essa fem é produzida de tal modo a se opor à variação de fluxo, tendo sentido contrário à tensão da fonte. Devido a esse fato, ela é chamada força contraeletromotriz (fcem). A fcem é diretamente proporcional ao fluxo por polo p e à velocidade angular do rotor . Assim, tem-se, Ea Ke p , (2.2) onde Ke é a constante de fcem do motor CC. No Sistema Internacional (SI) de unidades, as constantes de torque Kt e de fcem Ke são iguais. Desse modo, as Equações 2.1 e 2.2 podem ser simplificadas: Td Km p I a , (2.3) Ea Km p , (2.4) onde Km é a constante do motor CC. 2.3 Circuito Equivalente O circuito equivalente de um motor CC é mostrado na Figura 2.2. Nela, o circuito de armadura completo é representado por uma fonte de tensão Ea, um resistor Ra e uma indutância La. A tensão Vs é a tensão aplicada aos terminais da armadura. Para que a máquina CC opere como motor, Vs deve ser maior do que Ea. Desse modo, a corrente Ia tem o sentido indicado na Figura 2.2 e a equação da tensão de armadura é dada por Vs Ea Ra I a La dI a . dt (2.5) 18 Figura 2.2 – Circuito equivalente de um motor CC. Fonte : Adaptada de Hughes (2006). O último termo da Equação 2.5 representa a queda de tensão indutiva devida à auto-indutância da armadura, que é proporcional à taxa de variação da corrente de armadura. Em regime permanente (quando a corrente é constante), seu valor é igual a zero, podendo ser ignorado (Hughes, 2006). Nessas condições, a Equação 2.5 se torna: Vs Ea Ra I a ou I a Vs Ea . Ra (2.6) Essas equações permitem se calcular a corrente de armadura tendo posse de valores conhecidos previamente de tensão da fonte, resistência de armadura e velocidade (por onde pode-se obter Ea). De posse da corrente de armadura, pode-se calcular o torque desenvolvido pelo motor. De outro modo, tendo-se os valores de resistência de armadura, velocidade de referência (especificada pelo operador) e torque desejado (calculado), pode-se calcular a tensão da fonte necessária para atingir essas condições. A última abordagem é a utilizada no controlador de velocidade proposto. 2.4 Velocidade de rotação à vazio Considerando a Equação 2.6, quando o motor opera na condição à vazio, a queda de tensão devida à resistência de armadura Ra é muito pequena. Assim, a fcem Ea é aproximadamente igual à tensão nos terminais da armadura Vs (Wildi, 2002). Substituindo Ea por Vs na Equação 2.4, tem-se Vs . Km p (2.7) 19 Desse modo, pode-se observar que a velocidade do motor CC à vazio é diretamente proporcional à tensão de armadura e inversamente proporcional à intensidade de fluxo gerada pelo enrolamento de campo. 2.5 Velocidade de rotação com carga Na condição com carga, pode-se obter a expressão para a velocidade em regime permanente em função de duas variáveis que pode-se controlar, a tensão de armadura Vs e o torque da carga TL. Em regime permanente, não há aceleração, portanto, o torque do motor Td é igual a TL. Substituindo as Equações 2.3 e 2.4 na Equação 2.6 (Hughes, 2006), tem-se Vs K m p Vs Ra Ra TL ou TL . K m p ( K m p )2 Km p (2.8) 2.6 Motores de corrente contínua de ímã permanente Motores CC de ímã permanente são largamente usados em aplicações de baixa potência. As características construtivas desse tipo de motor são mais simples, onde no lugar do enrolamento de campo tem-se um ímã permanente. Pode-se citar várias vantagens desse motor. As principais delas são a ausência de excitação externa e suas baixas perdas no cobre associadas para criar campos magnéticos na máquina (Fitzgerald; Kingsley; Umans, 2003). A presença dos enrolamentos de campo também resulta em uma considerável quantidade de calor e na necessidade de grande volume de espaço para acomodar os polos do circuito de campo. Nos motores de ímã permanente essas características são superadas. Os resultados são um motor menor, com alta eficiência e que corre riscos menores de falhas relacionadas à produção de campo (Wildi, 2002). Entretanto, os motores CC de ímã permanente também têm desvantagens. Nestes motores o fluxo por polo é apenas o fluxo residual nos ímãs permanentes. Quando o enrolamento de armadura é submetido a excessivos valores de corrente, existe o risco de que a força magnetomotriz produzida pela mesma tenda a desmagnetizar os polos, permanentemente reduzindo e reorientando o seu fluxo residual. A desmagnetização dos polos também pode ocorrer por sobreaquecimento, ocasionado durante prolongados períodos de sobrecarga (Chapman, 2005). Além do mais, apesar dos avanços feitos nas últimas décadas, com o desenvolvimento de novos materiais com características desejáveis para a 20 fabricação de ímãs permanentes, estes componentes ainda apresentam um alto custo (Wildi, 2002). Um motor CC de ímã permanente é basicamente a mesma máquina que um motor CC com excitação independente com a diferença de que o seu fluxo do campo é sempre constante. Portanto, não é possível controlar a velocidade do motor variando o fluxo por polo p, através da corrente de campo. Os únicos métodos disponíveis neste caso são através da variação da resistência de armadura Ra ou da tensão de armadura Vs (Chapman, 2005). Assim, em regime permanente, as Equações 2.8 se tornam Vs km V R Ra TL ou s 2a TL . km km km (2.9) onde km é a constante do motor CC com fluxo por polo p constante. 2.7 Comportamento dinâmico e constantes de tempo De todos os tipos de motores, o motor CC é o que apresenta a teoria de dinâmica transitória mais simples. Todas as suas mudanças transitórias são determinadas por apenas duas constantes de tempo. A primeira é a constante de tempo eletromecânica, que governa o modo como a velocidade se acomoda a um novo patamar seguindo uma perturbação como uma mudança na tensão de armadura ou no torque da carga. A segunda é a constante de tempo elétrica (ou de armadura), que é geralmente muito menor e governa a taxa de mudança da corrente de armadura seguindo uma mudança na tensão de armadura (Hughes, 2006). Os motores CC podem ser vistos como um sistema com duas entradas, a tensão de armadura e o torque da carga. Quando desconsidera-se a indutância do motor CC, e varia-se uma destas duas entradas, as respostas transitórias da corrente de armadura e da velocidade são de primeira ordem (exponencial). Esta suposição é válida para a maioria dos motores CC, exceto os de capacidade muito elevada. Por exemplo, se subitamente aumenta-se a tensão de armadura de um motor sem atrito e sem carga, sua corrente e velocidade variam como mostrado na Figura 2.3. Como a indutância foi desprezada, há um instantâneo aumento de corrente, já que a diferença entre a tensão de armadura e a fcem aumentam. Essa variação na corrente dá origem a uma elevação do torque do motor, acelerando a máquina. A diferença entre a fcem e a tensão de armadura diminui com o aumento de velocidade, assim como a corrente. Com o tempo, a corrente chega 21 a zero e o torque também. A velocidade atinge seu novo valor de regime permanente neste ponto. Figura 2.3 – Reposta de um motor CC a uma elevação da tensão de armadura em degrau. Fonte: Adaptada de Hughes (2006). A expressão que descreve a variação da corrente de armadura com o tempo é V V I a 2 1 et / a . Ra (2.10) A constante de tempo elétrica do motor é definida como a La . Ra (2.11) A expressão para a velocidade é similar à da corrente, também dependente de um termo exponencial, et / em (Hughes, 2006). A constante de tempo eletromecânica é dada por em Ra J , km2 (2.12) onde J é a inercia total do rotor mais a carga. No caso de um motor com o rotor bloqueado, se é aplicada uma entrada tipo degrau para a tensão de armadura, a corrente aumentaria exponencialmente até atingir o valor final de Vs/Ra com uma constante de tempo a (Hughes, 2006). O motor CC é na verdade um sistema de segunda ordem. Desse modo, as duas constantes de tempo apresentadas influenciam a variação da corrente de armadura no período transitório. No entanto, a constante de tempo elétrica é muito menor (mais rápida) que a 22 constante eletromecânica. Assim, para a maioria dos motores CC e ampla gama de aplicações, seu modelo pode ser aproximado por um sistema de primeira ordem com a constante de tempo eletromecânica. No regime transitório, desprezando-se os efeitos da indutância de armadura La, a relação das tensões descrita pela Equação 2.5 se torna Vs Ea Ra I a . (2.13) Esta é a mesma equação para as tensões em regime permanente descrita anteriormente. Desse modo, a Equação 2.9 pode ser aproveitada para descrever a relação da tensão de armadura com a velocidade e o torque desenvolvido por um motor CC de ímã permanente, em regime transitório, pela equação Vs km Ra Td . km (2.14) No controlador de velocidade que será apresentado, pode-se especificar a velocidade angular como referência e o torque Td a ser desenvolvido pelo motor é calculado pelo algoritmo do controlador. Assim, utilizando-se a Equação 2.14 juntamente com outras equações, pode-se calcular o número de ciclos do temporizador do microcontrolador com Modulação por Largura de Pulso (do inglês Pulse Width Modulation – PWM) correspondente à tensão que deve ser aplicada ao motor, durante o atual período de amostragem, para se alcançar a velocidade de referência do sistema. 2.8 Sistemas com engrenagens Sistemas rotacionais raramente são vistos sem associação com caixa de engrenagens para acionar a carga. Engrenagens fornecem vantagens mecânicas para sistemas rotacionais. Como exemplo, tem-se uma bicicleta de 18 marchas. Quando sobe-se uma ladeira, muda-se a marcha para obter mais torque e menos velocidade. Em uma reta, a mudança é feita para se obter menos torque e mais velocidade. Desse modo, as engrenagens permitem adequar o sistema de acionamento e a carga – um compromisso entre velocidade e torque (Nise, 2011). Na Figura 2.4, uma engrenagem de entrada com ângulo de deslocamento 1(t), raio r1 e N1 dentes tem aplicado um torque T1(t). Na saída, tem-se uma engrenagem com ângulo de deslocamento 2(t), raio r2 e N2 dentes, com um torque resultante T2(t). Quando as engrenagens giram, o deslocamento ao longo das suas circunferências é igual. Desse modo, tem-se 23 r11 r22 . (2.15) Figura 2.4 – Um sistema de engrenagens. Fonte: Adaptada de Nise (2011). Pode-se observar que o número de dentes de cada engrenagem é diretamente proporcional ao seu raio. Obtém-se, então 2 r1 N1 . 1 r2 N 2 (2.16) Dividindo cada termo do centro pela variação de tempo t pode-se obter a relação para as velocidades angulares dada abaixo: 2 2 N1 . 1 1 N 2 (2.17) Considerando que as engrenagens são ideais e não absorvem nem armazenam energia, pode-se dizer que a energia na entrada é a mesma da saída. Assim, T11 T22 . (2.18) Substituindo a Equação 2.18 na Equação 2.17, finalmente tem-se T1 2 N1 . T2 1 N 2 (2.19) Pode-se perceber então que o torque é diretamente proporcional à relação do número de dentes e inversamente proporcional à relação das velocidades angulares. 24 3 MICROCONTROLADORES MSP430 3.1 Introdução O controlador digital de velocidade que foi desenvolvido é baseado em um sistema de hardware embarcado microcontrolado. Nesse caso, o microcontrolador escolhido foi o MSP430. A família de microcontroladores MSP430 é um produto da Texas Instruments (TI). Eles são microcontroladores de 16 bits, de arquitetura Computador com um Conjunto Reduzido de Instruções (do inglês Reduced Instruction Set Computer - RISC), que, dependendo do modelo, podem trabalhar com frequências de até 25 MHz e endereçar até 512 KB de memória. Os periféricos que se podem encontrar disponíveis nestes microcontroladores vão desde os mais básicos até os com relativa sofisticação, sempre focando na simplicidade. De acordo com o modelo, pode-se encontrar unidades de memórias flash, temporizadores, Interface de Comunicação Serial Universal (do inglês Universal Serial Communication Interface - USCI), interface de Barramento Serial Universal (do inglês Universal Serial Bus - USB), controladores de Tela de Cristal Líquido (do inglês Liquid Crystal Display - LCD), conversores Analógico/Digital (A/D) e Digital/Analógico (D/A), amplificadores operacionais, hardware multiplicador, relógio de tempo-real, controladores de supervisão de tensão de alimentação, sensor de temperatura e outros. Além disso, alguns modelos de MSP430 são suportados por sistemas operacionais de tempo-real. A principal vantagem dos microcontroladores MSP430 com relação a outros microcontroladores com características semelhantes é o seu baixo consumo de energia. Isso faz dele uma boa escolha para aplicações de sistemas embarcados com relativo desempenho e baixa potência (à bateria) ou sistemas de coleta de energia (sistemas autônomos reduzidos e sem fio). No entanto, microcontroladores MSP430 tem a desvantagem de serem mais caros do que outros microcontroladores de 16 bits. Então, dependendo da aplicação, deve-se avaliar a relação custo-benefício. A TI disponibiliza várias ferramentas de desenvolvimento para o MSP430. Para a implementação do controlador de velocidade que será apresentado, utilizou-se a ferramenta eZ430-RF2500. Ela é baseada no microcontrolador MSP430F2274. Desse modo, será descrita a operação dos periféricos utilizados no sistema de controle de velocidade. 25 3.2 Microcontrolador MSP430F2274 O MSP430 incorpora uma Unidade Central de Processamento (do inglês Central Processing Unit - CPU) tipo RISC, periféricos e um flexível sistema de clock que se interconectam usando um Barramento de Endereços de Memória (do inglês Memory Adress Bus - MAB) comum tipo von-Neumann e um Barramento de Dados de Memória (do inglês Memory Data Bus - MDB) (Figura 3.1). Compartilhando uma moderna CPU com periféricos analógicos e digitais modulares com mapeamento de memória, o MSP430 oferece soluções para aplicações de sinais mistos exigentes (Texas Instruments, 2013a). Figura 3.1 – Arquitetura da família MSP430F22x4. Fonte: Texas Instruments (2013b). As principais características do MSP430F2274 são dadas abaixo (Texas Instruments, 2013b): f) Faixa de tensão de alimentação: 1,8 a 3,6 V; g) Consumo de energia: modo ativo: 270 µA a 1 MHz e 2,2 V; 26 modo standby: 0,7 µA; modo desligado (retenção de Memória de Acesso Aleatório (do inglês Random Access Memory - RAM)): 0,1 µA; h) ativação do modo standby em menos de 1 µs; i) arquitetura RISC de 16 bits e tempo de ciclo de instrução de 62,5 ns; j) configurações do módulo de clock básico: frequências internas de até 16 MHz com quatro frequências calibradas com 1 % de erro; oscilador interno de baixa frequência e baixo consumo de energia; cristal de 32 kHz; cristal de alta frequência de até 16 MHz; ressonador; fonte de clock digital externo; resistor externo; k) Timer_A de 16 bits com três registradores de captura/comparação; l) Timer_B de 16 bits com três registradores de captura/comparação; m) Interface de Comunicação Serial Universal (USCI): Receptor/Transmissor Assíncrono Universal (do inglês Universal Asynchronous Receiver/Transmitter - UART) avançado com suporte a detecção automática de velocidade; codificador e decodificador infravermelho (do inglês Infrared Data Association - IrDA); Interface Periférica Serial (do inglês Serial Peripheral Interface - SPI) síncrona; interface Circuito Inter-integrado (do inglês Inter-Integrated Circuit - I²C); n) conversor A/D de 10 bits e 200 ksps, com referência interna, circuito Amostra e Segura, varredura automática e controlador de transferência de dados; o) dois amplificadores operacionais configuráveis; p) detector de queda de energia; q) programação onboard serial, sem necessidade de tensão de programação externa e proteção com código programável por meio de fusível de segurança; r) módulo de emulação on-chip; 27 s) memória: 32 KB + 256 B de memória flash; 1 KB de RAM. 3.3 Sistema de clock O Basic Clock Module+ suporta sistemas de baixo custo e baixo consumo de energia. Usando três sinais internos de clock, o usuário pode selecionar o melhor equilíbrio entre desempenho e baixo consumo de energia. No caso do MSP430F2274, o Basic Clock Module+ pode ser configurado para operar sem nenhum componente externo, com um resistor externo, com um cristal externo, ou com ressonadores, sob controle de software completo. Ele inclui três fontes de clock (Texas Instruments, 2013a): a) LFXT1: oscilador de baixa frequência/alta frequência que pode ser usado com cristais de relógio de baixa frequência ou fontes de clock externas de 32768 Hz ou com cristais padrão, ressonadores, ou fontes de clock externas na faixa de 400 kHz a 16 MHz; b) DCO: Oscilador Digitalmente Controlado interno. Disponível em todos os dispositivos e um dos componentes de mais destaque do MSP430. Basicamente, é um oscilador RC altamente controlável que inicia em menos de 1 µs; c) VLO: oscilador de baixa frequência, baixa potência, interno, de 12 kHz. Pode ser usado como alternativa a LFXT1 quando a precisão de um cristal não é necessária. Como saída, o Basic Clock Module+ fornece três clocks: a) Master clock, MCLK: sua fonte é selecionável por software como LFXT1, VLO ou DCO. Pode ser dividido por 2, 4 ou 8. O MCLK é usado pela CPU e alguns periféricos; b) Sub-main clock, SMCLK: assim como o MCLK, sua fonte é selecionável por software como LFXT1, VLO ou DCO e pode ser dividido por 2, 4 ou 8. É distribuído aos periféricos; c) Auxiliary clock, ACLK: sua fonte é selecionável por software como LFXT1 ou VLO. Pode ser dividido por 2, 4 ou 8. Também é distribuído aos periféricos. 28 3.4 Portas de entrada/saída digitais O MSP430 pode apresentar até oito portas de entrada/saída digitais, com oito pinos cada. Cada pino pode ser configurado individualmente como uma entrada ou uma saída por meio de software. O MSP430F2274 possui quatro portas de entrada/saída. As portas P1 e P2 possuem recurso de interrupção em todos os seus pinos. As interrupções podem ser ativadas tanto por uma mudança de bit ascendente como descendente. Na porta P1, tem-se um vetor de interrupção para atender todos os pinos. Já na porta P2, tem-se um vetor de interrupção diferente para cada pino. As portas de entrada/saída digitais apresentam as seguintes características (Texas Instruments, 2013a): a) entrada/saídas independentes controladas individualmente; b) qualquer combinação de entrada ou saída; c) interrupções de P1 e P2 configuráveis individualmente; d) registradores de dados de entrada e saída independentes; e) resistores de pullup e pulldown configuráveis individualmente; f) função de oscilador de pino configurável individualmente. No MSP430F2274 as portas P3 e P4 possuem cinco registradores de 8 bits cada, enquanto que as portas P1 e P2 têm oito registradores de 8 bits cada. As portas P1 e P2 possuem os seis registradores semelhantes aos das portas P3 e P4, mais três registradores associados às funções de interrupção. A seguir são descritas as funções de cada registrador. 3.4.1 Registrador de entrada PxIN Cada bit do registrador representa o nível lógico do respectivo pino quando este está configurado como entrada/saída digital. É um registrador somente de leitura e não precisa ser inicializado, já que seu conteúdo depende de sinais externos. 3.4.2 Registrador de saída PxOUT O nível lógico de cada pino da porta é conduzido para o valor armazenado no respectivo bit do registrador quando o pino está configurado como saída e o resistor de 29 pullup/pulldown está desabilitado. Quando o pino está configurado como entrada, o valor do respectivo bit é armazenado em um buffer e, quando posteriormente o pino é configurado como saída, sua saída é conduzida para este valor. Esse registrador não precisa de inicialização. No início de uma operação é necessário gravar o valor desejado no registrador antes de configurar a direção do pino. Além da sua função básica, quando o resistor de pullup/pulldown está ativado para um determinado pino (configurado como entrada), o valor do respectivo bit de PxOUT seleciona o tipo de conexão do resistor, se pulldown (bit = 0) ou pullup (bit = 1). 3.4.3 Registrador de direção PxDIR Cada bit configura um pino como entrada (bit = 0) ou saída (bit = 1). Esse registrador é utilizado quando o pino está configurado tanto como entrada/saída digital, quanto como uma função pertencente a outro periférico. No segundo caso, a direção do pino deve ser configurada de acordo com a função. 3.4.4 Registrador de habilitação dos resistores de pullup/pulldown PxREN Cada bit habilita (bit = 1) ou desabilita (bit = 0) o resistor de pullup/pulldown do pino correspondente, quando este está configurado como entrada. Por padrão, os resistores estão desativados. Quando habilitado, o respectivo bit de PxOUT seleciona o tipo de conexão. 3.4.5 Registradores de seleção de função PxSEL Pinos de portas geralmente compartilham conexões com funções de outros periféricos. Cada bit de PxSEL seleciona o pino como entrada/saída digital (bit = 0) ou uma função de outro periférico (bit = 1). No entanto, quando o pino está configurado para uma outra função, ainda é necessário selecionar a direção do pino por meio de PxDIR. 3.4.6 Registradores de habilitação de interrupção P1EI e P2EI Habilita (bit = 1) a capacidade de gerar interrupções quando ocorre uma transição de bit em um pino de entrada. Por padrão interrupções ficam desabilitadas na inicialização. 30 3.4.7 Registradores de seleção de transição da interrupção P1IES e P2IES Cada bit seleciona a transição que ativa a interrupção. Quando o bit é igual a zero, a interrupção é acionada por uma transição de nível lógico baixo para alto. O inverso ocorre para o bit igual a um. Esse registrador não é inicializado e, portanto, deve ser configurado antes das interrupções serem habilitadas. 3.4.8 Registradores de flag de interrupções P1IFG e P2IFG Indica (bit = 1) que ocorreu uma transição (de acordo com PxIES) no correspondente pino configurado como entrada quando PxIE está ativo. Quando a rotina de serviço de interrupção é chamada, o reset de PxIFG precisa ser realizado via software. Esse registrador é de leitura e gravação. Assim, pode-se gerar uma interrupção via software gravando o valor um no respectivo bit em que se deseja ativar a interrupção. 3.5 Temporizadores O MSP430F2274 possui dois módulos temporizadores: Timer_A e Timer_B. As características do Timer_A são descritas abaixo (Texas Instruments, 2013a): a) temporizador/contador de 16 bits assíncrono com quatro modos de operação; b) fonte de clock selecionável e configurável; c) três registradores de captura/comparação configuráveis; d) saídas configuráveis com recurso de Modulação por Largura de Pulso (do inglês Pulse Width Modulation - PWM); e) latchs de entrada e saída assíncronos; f) registrador de vetor de interrupção para decodificação rápida de todas interrupções do Timer_A. O Timer_B é idêntico ao Timer_A com as seguintes exceções: a) o período de duração do Timer_B pode ser programado como 8, 10, 12 e 16 bits; b) os registradores TBCCRx do Timer_B possuem buffer duplo e podem ser agrupados; c) todas as saídas do Timer_B podem ser postas em estado de alta impedância; 31 d) a função do bit SCCI (entrada de captura sincronizada) não é implementada no Timer_B. Como a configuração e operação dos dois temporizadores é muito semelhante, serão descritos os detalhes relacionados ao Timer_A. O hardware do Timer_A é dividido em duas partes principais (Davies, 2008): a) bloco temporizador: O núcleo, baseado no registrador de 16 bits TAR. A fonte do clock pode ser escolhida entre várias opções. Também possui divisores de frequência, permitindo escalonamento. Não possui nenhuma saída, mas uma flag TAIFG é ativada quando o contador retorna para zero; b) canais de captura/comparação: É onde a maioria dos eventos ocorre. Cada canal é baseado em um registrador TACCRx. Trabalham de forma semelhante com exceção de TACCR0. Cada canal pode: capturar uma entrada, que significa gravar o “tempo” (o valor de TAR) em TACCRx no qual a entrada sofre uma transição. A entrada pode ser externa (pino) ou interna (outro periférico ou via software); comparar o valor atual de TAR com o valor armazenado em TACCRx e, quando esses valores são iguais, atualizar uma saída. A saída também pode ser externa ou interna; solicitar uma interrupção, ocorrendo um dos dois eventos acima, ativando a flag de interrupção CCIFG de TACCRx; isso pode ser realizado mesmo sem nenhum sinal de saída sendo ativado; amostrar uma entrada em um evento de comparação; este recurso especial é particularmente útil se o Timer_A é usado para comunicação serial em um dispositivo onde falta uma interface dedicada. 3.5.1 Bloco temporizador Esse bloco contém o registrador do temporizador de 16 bits TAR e é crucial para a operação do Timer_A. Ele é controlado pelo registrador TACTL. Um temporizador nada mais é que um contador e não tem nenhum conceito direto de tempo (o relógio de tempo real é uma exceção). É trabalho do programador estabelecer uma relação entre o valor no contador e o tempo real. Isso depende essencialmente da 32 frequência do clock para o temporizador. Ela pode ser escolhida de quatro fontes através do campo de bits TASSELx em TACTL (Davies, 2008): a) SMCLK: é interno e geralmente muito rápido (da ordem de megahertz); b) ACLK: é interno e geralmente lento. Pode ser proveniente de um cristal (tipicamente 32 kHz) ou do VLO (12 kHz); c) TACLK: é externo; d) INCLK: é também externo. O clock selecionado pode ser aplicado diretamente ou ter sua frequência dividida por 2, 4 ou 8 através dos bits IDx. Quando se divide a frequência da fonte, diminui-se a resolução com que os eventos são registrados. Por outro lado, isso resulta em um período do temporizador maior. O divisor do temporizador é reiniciado quando TACLR é ativado. O temporizador possui quatro modos de operação selecionados pelos bits MCx: a) parada, MCx = 00: se o temporizador já foi iniciado, a contagem é interrompida e o valor de TAR é preservado até que o contador seja reiniciado; b) crescente, MCx = 01: a contagem vai de zero até o valor de TACCR0, repetidamente. O período é igual a TACCR0 + 1. A flag de interrupção CCIFG de TACCR0 é ativada quando o contador conta do valor de TACCR0 para zero. Se o temporizador for configurado para o modo crescente quando TAR for maior que o valor de TACCR0, o temporizador imediatamente reinicia a contagem a partir de zero; c) Contínuo, MCx = 10: a contagem vai de zero até FFFFh, repetidamente. A flag de interrupção do Timer_A TAIFG é ativada quando o contador conta de FFFFh para zero; d) Crescente/decrescente, MCx = 11: a contagem vai de zero até o valor de TACCR0 e depois de forma decrescente até zero, repetidamente. O período é igual a duas vezes o valor de TACCR0. A flag CCIFG de TACCR0 é ativada na contagem de TACCR0 – 1 para TACCR0 e a flag TAIFG é acionada na contagem de 0001h para 0000h. Quando é necessário um controle mais preciso do período de tempo, os modos crescente e crescente/decrescente são indicados. No entanto, com a utilização do registrador TACCR0, o canal zero do Timer_A fica indisponível. Alguns temporizadores mais modernos 33 utilizados em microcontroladores já incluem um registrador de módulo incluído no bloco temporizador. 3.5.2 Canais de captura/comparação O Timer_A do MSP430F2274 tem três canais de captura/comparação. Cada um deles é controlado por um registrador TACCTLx. O registrador principal de cada canal de captura/comparação é o TACCRx. No modo de captura, ele armazena o valor do contador TAR no momento que uma transição ocorre na sua entrada correspondente. No modo de comparação, ele armazena o valor da contagem em que sua respectiva saída deve mudar de valor e uma interrupção é solicitada. 3.5.2.1 Modo de captura O modo de captura é selecionado com o bit CAP = 1. Ele pode ser utilizado para medições de velocidade ou período de tempo. As entradas de captura CCIxA e CCIxB podem ser conectadas a pinos externos e sinais internos. No caso do MSP430F2274, somente CCI2B é conectado a um sinal interno, que é o clock ACLK. Todas as outras entradas estão conectadas a pinos externos. As entradas são selecionadas pelos bits CCISx. Os bits CMx selecionam o tipo de transição de captura do sinal de entrada, se de nível lógico baixo para alto, alto para baixo ou ambos. Quando uma captura ocorre, o valor de TAR é copiado para TACCRx e a flag de interrupção CCIFG é acionada. O nível lógico da entrada pode ser lida a qualquer momento pelo bit CCI. Quando a captura é realizada de forma assíncrona com relação ao clock do temporizador, uma condição de corrida (quando dois processos concorrentes perdem a sincronia) pode ser criada, ocorrendo a perda de captura de alguns pulsos. Desse modo, a opção de sincronizar a captura com o próximo pulso de clock é sempre recomendada. Isso é feito por meio do bit CSC = 1. 34 3.5.2.2 Modo de comparação O modo de comparação é selecionado quando CAP = 1 e é usado para gerar sinais de saída PWM ou interrupção em intervalos de tempo específicos. Quando TAR conta até o valor de TACCRx (Texas Instruments, 2013a): a) a flag de interrupção CCIFG é ativada; b) o sinal interno EQUx é ativado; c) EQUx afeta a saída de acordo com o modo de saída; d) o sinal de entrada CCI é carregado no bit SCCI. Cada canal de captura/comparação tem oito modos de saída que geram sinais baseados nos sinais EQU0 e EQUx. Os modos de saída são definidos pelos bits OUTMODx e são descritos abaixo: a) output, OUTMODx = 000: o sinal de sáida OUTx é definido pelo bit OUTx e é atualizado imediatamente após uma mudança neste bit; b) toggle, OUTMODx = 100: a saída é comutada quando o valor do temporizador é igual a TACCRx. Pode ser utilizado tanto no modo crescente como no crescente/decrescente. O período do sinal de saída é o dobro do período do temporizador; c) set, OUTMODx = 001 e reset, OUTMODx = 101: a saída é ativada (set) ou desativada (reset) quando o contador atinge o valor de TACCRx e permanecem imutáveis até que o temporizador seja reiniciado ou um novo modo seja configurado e afete a saída. São geralmente usados para realizar uma única mudança na saída; d) reset/set, OUTMODx = 111 e set/reset, OUTMODx = 011: geralmente usados para PWMs alinhados à borda no modo crescente e consistem de duas mudanças na saída durante o período do temporizador. A primeira ação ocorre quando o contador atinge o valor de TACCR0 e a segunda quando o contador retorna para zero; e) toggle/reset, OUTMODx = 010 e toggle/set, OUTMODx = 110: geralmente utilizados para sinais de PWM alinhados ao centro no modo crescente/decrescente. A primeira ação ocorre na contagem até o valor de TACCRx e a segunda na contagem até o valor de TACCR0. 35 Os modos 2, 3, 6 e 7 não são aplicáveis para o canal 0, poque EQUx = EQU0. 3.6 Interface de Comunicação Serial Universal (USCI): modo assíncrono (UART) Como foi visto no item (h) da seção 3.2, a USCI do MSP430F2274 possibilita vários tipos de comunicação serial. Assim, tratar de cada uma delas seria um trabalho muito amplo. Por isso, como o foco deste trabalho são apenas os tópicos relacionados com o controlador de velocidade que será apresentado, será tratada aqui apenas a comunicação serial assíncrona no modo UART. Mesmo este modo ainda é um tema muito abrangente, dadas as suas possibilidades de configuração. Sendo assim, serão abordadas apenas as funcionalidades deste modo de comunicação que estão relacionadas com o controlador de velocidade digital. O MSP430F2274 possui dois módulos USCI, o USCI_A0 e o USCI_B0. O USCI_B0 possibilita dois tipos de comunicação serial, SPI e I²C. Será utilizado o módulo USCI_A0, que possibilita comunicação serial dos tipos UART, IrDA, SPI e detecção automática de velocidade para protocolo Rede de Interconexão Local (do inglês Local Interconnect Network - LIN). O tipo de comunicação serial, se síncrona ou assíncrona, é selecionada pelo bit UCSYNC no registrador UCA0CTL0. Quando este bit é igual à zero, o módulo é configurado para comunicação assíncrona, possuindo quatro modos de comunicação selecionados pelos bits UCMODExx de UCA0CTL0 (Davies, 2008): a) modo UART padrão, UCMODExx = 00; b) modos de multiprocessador, UCMODExx = 01 ou 10. Esses modos são utilizados quando mais de dois processadores estão presente no mesmo barramento de comunicação; c) detecção automática de velocidade para LIN, UCMODExx = 11. Adicionalmente, fazendo o bit UCIREN do registrador UCA0IRTCTL igual a 1, o modo de comunicação infravermelho (IrDA) é selecionado. O modo de comunicação aplicado no projeto é o modo UART padrão. A seguir, é descrito como configurar a velocidade de comunicação e a operação neste modo. 36 3.6.1 Configurando a velocidade de comunicação com o módulo USCI_A0 A exata frequência do clock é critica para comunicações assíncronas. Por isso, o USCI_A0 possui opções sofisticadas para a seleção da velocidade de comunicação (baud rate) e é o aspecto mais complicado da sua configuração. Existem três clocks no USCI_A0 (Davies, 2008): a) BRCLK: é a entrada para o módulo (SMCLK, ACLK e UCA0CLK); b) BITCLK: controla a velocidade em que os bits são recebidos e transmitidos. Idealmente, sua frequência deveria ser igual a velocidade de comunicação, fBITCLK = fbaud; c) BITCLK16: é a frequência de amostragem no modo de sobreamostragem, com uma frequência fBITCLK16 = 16 fBITCLK. Os períodos desses clocks são TBITCLK = 1/fBITCLK e assim sucessivamente. Existem dois modos para configurar a velocidade de comunicação, ilustrados na Figura 3.2. Eles são selecionados pelo bit UCOS16 no registrador de controle de modulação UCA0MCTL: a) modo de sobreamostragem, UCOS16 = 1: primeiro, BRCLK é dividido para gerar BITCLK16, que depois é dividido por um fator de 16 para gerar BITCLK; b) modo de baixa frquencia, UCOS16 = 0: BRCLK é usado diretamente como a frequência de amostragem e é dividido para gerar BITCLK. Geralmente, fBRCLK ≠ 16 fBITCLK. Dividindo BRCLK por um inteiro não resulta em uma velocidade muito precisa na maioria dos casos. Desse modo, cada divisor do módulo USCI_A0 tem um modulador que permite a geração de uma frequência mais precisa para BITCLK. Alguns bits e registradores são utilizados para isso: a) UCA0BR0 e UCA0BR1: são registradores de 8 bits que juntos formam UCBR0, que é o principal divisor de BRCLK; b) UCBRF0: controla a modulação de primeiro estágio que gera BITCLK16 no modo de sobreamostragem. É um campo de quatro bits no registrador de controle de modulação UCA0MCTL; c) UCBRS0: controla a modulação de segundo estágio que gera BITCLK. É um campo de três bits no registrador UCA0MCTL. 37 Figura 3.2 – Gerador de frequência em USCI_A0 mostrando (a) modo de sobreamostragem com dois divisores e clock intermediário BITCLK16, e (b) modo de baixa frequência com apenas um divisor. Fonte: Adaptada de Davies (2008). Toda essa complicação é necessária porque a velocidade de comunicação é raramente próxima de ser um fator perfeito de fBRCLK, a frequência da fonte de clock para o módulo (Davies, 2008). Nesse ponto, continua-se a discussão apenas para o modo de baixa frequência. 3.6.1.1 Modo de baixa frequência do gerador de velocidade de comunicação O modo de baixa frequência geralmente é escolhido quando se tem fBRCLK < 16fbaud. No caso do sistema de controle de velocidade, a velocidade de comunicação fbaud é de 9600 bauds com BRCLK alimentado pelo clock ACLK de 12 kHz. Então, tem-se fBRCLK/fbaud = 1,25, o que justifica a escolha do modo de baixa frequência. Somente um divisor e um modulador são usados no modo de baixa frequência, como mostrado na Figura 3.2. Neste modo não é possível fazer o comprimento de cada ciclo de BITCLK correto. Para o projeto, deveriam ser 1,25 ciclos de BRCLK. No entanto, para esse caso, não se pode ter altas expectativas e o USCI_A0 procura alcançar o melhor valor médio da frequência durante oito ciclos de BITCLK (Davies, 2008). O divisor UCBR0 e o índice de modulação UCBRS0 são dados por 8 f BRCLK int fbaud (8 UCBRS0)UCBR0 UCBRS0(UCBR0 1) 8UCBR0 UCBRS0 (3.1) 38 Para o controlador de velocidade desenvolvido, a expressão da esquerda é igual a 10, o que resulta em UCBR0 = 1 e UCBRS0 = 2. Desse modo, cada conjunto de 8 ciclos de BITCLK contém seis de duração TBRCLK e dois ciclos de duração 2TBRCLK. 3.6.2 Operação do módulo USCI_A0 Depois de configurado o modo UART padrão e a velocidade de comunicação, a operação do módulo USCI_A0 é muito simples. Para transmissão, deve-se primeiro ativar o bit de habilitação de interrupção de transmissão UCA0TXIE do registrador de habilitação de interrupção UC0IE. Feito isso, a rotina de serviço da interrupção de transmissão é chamada e nela atribui-se a variável (um vetor) que contém o byte a ser enviado ao buffer de transmissão UCA0TXBUF. O byte é então enviado automaticamente. Caso haja mais um byte a ser enviado, o índice do vetor deve ser incrementado. Enquanto o bit UCA0TXIE permanece ativado, após o envio do primeiro byte, a rotina de serviço de interrupção é chamada novamente e o próximo byte do vetor é enviado. Quando não existem mais dados a serem enviados, no final da última chamada o bit UCA0TXIE deve ser desabilitado. O processo de recepção se inicia com a chegada de um quadro completo no buffer de recepção UCA0RXBUF e com a automática ativação da flag UCA0RXIFG. A rotina de serviço de interrupção é então chamada e a flag UCA0RXIFG é desabilitada automaticamente com a leitura de UCA0RXBUF. Como a comunicação é assíncrona, um outro quadro pode chegar em qualquer momento. Por isso a leitura de UCA0RXBUF deve ser realizada prontamente após a rotina de serviço de interrupção ser chamada. Caso um quadro seja sobrescrito, a flag de perda de dados UCOE no registrador de status UCA0STAT é ativada. 3.7 Modos de operação em baixa potência O projeto do MSP430 foi baseado desde o princípio no baixo consumo de energia. Ele possui cinco diferentes modos de operação que trabalham de acordo com um determinado perfil de economia de energia. No entanto, no caso do MSP430F2274, apenas quatro modos são geralmente utilizados. Estes modos são sumarizados a seguir (Texas Instruments, 2013b) para a operação com tensão de alimentação VCC = 3 V, DCO trabalhando com 1 MHz e LFXT1 em 32 kHz, de um cristal. 39 a) modo ativo: a CPU, todos os clocks habilitados e todos módulos habilitados estão ativos. O valor típico de corrente de consumo I é 390 µA, podendo chegar a um máximo de 550 µA. Considerando VCC = 3.6 V e DCO trabalhando a uma frequência de 16 MHz, tem-se uma corrente de consumo de aproximadamente 6,7 mA. Para VCC = 3 V e DCO = 12 MHz, tem-se I ≈ 4 mA. b) LPM0: CPU e MCLK estão desligados e SMCLK e ACLK estão ativos. Esse modo geralmente é utilizado quando a CPU não é necessária, mas algum módulo necessita de um clock rápido de SMCLK e do DCO. A corrente de consumo típica é I ≈ 90 µA e a máxima é I ≈ 120 µA. c) LPM2: CPU, MCLK, SMCLK e DCO estão desligados. O gerador de DCO e ACLK permanecem ativos. É um modo pouco usado e parecido com LPM3. A corrente de consumo típica é I ≈ 25 µA e a máxima é I ≈ 32 µA. d) LPM3: CPU, MCLK, SMCLK, DCO e o gerador de DCO estão desligados e ACLK está ativo. É o modo de operação utilizado quando se trabalha com um módulo de baixa frequência e se utiliza a CPU apenas por alguns instantes. Para modelos de MSP430 que possuem relógio de tempo real, esse é o modo necessário para mantê-lo funcionando. Sua corrente de consumo típica é I ≈ 0.9 µA e a máxima de I ≈ 1.5 µA. Caso utilize-se o VLO de 12 kHz ao invés de um cristal de 32 kHz, esses valores caem para I ≈ 0,6 µA e I ≈ 1,2 µA, respectivamente. e) LPM4: CPU e todos os clocks desligados. O dispositivo pode ser ativado apenas por um sinal externo. É também chamado de modo de retenção de RAM. A corrente de consumo típica é de I ≈ 0,1 µA e a máxima de I ≈ 0,5 µA. Os modos de baixa potência são configurados com os bits CPUOFF, OSCOFF, SCG0 e SCG1 no registrador de status SR. A vantagem de se por os bits de controle no registrador de status é que o modo de operação presente é salvo na pilha durante uma rotina de serviço de interrupção. O fluxo de programa retorna para o modo de operação anterior se o valor salvo de SR não é alterado durante a rotina de serviço de interrupção (Texas Instruments, 2013a). Quando são ativados qualquer um dos bits de controle, o modo de operação selecionado começa imediatamente. O MPS430 pode ser “acordado” somente por uma interrupção. Desse modo, as interrupções devem estar habilitadas pelo bit GIE no SR. Na linguagem C, a habilitação de interrupções e a entrada no modo de operação desejado é feito 40 por uma única função, presente no arquivo cabeçalho “intrinsics.h”: __low_power_mode_3();. Nesse caso, a função entra no modo LPM3, sendo uma função correspondente para cada modo. Para retornar-se de um modo de operação em baixa potência para o modo ativo, devese incluir o seguinte comando no final da rotina de serviço de interrupção: __low_power_mode_off_on_exit();. 41 4 CONTROLE DE VELOCIDADE DIGITAL DE MOTORES 4.1 Introdução Antes do advento dos microcontroladores, tarefas de controle de velocidade eram implementadas no domínio contínuo por meio de circuitos eletrônicos analógicos compreendendo amplificadores operacionais, resistores e capacitores. Um sinal proporcional a velocidade girante, era obtido de um tacogerador acoplado ao eixo do motor. De um amplificador operacional, a referência para o torque fornecido era obtida na forma de um sinal analógico padrão de +/- 10 V, aplicado ao circuito do atuador de torque (driver do motor) (Vukosavić, 2007). A implementação analógica coloca os seguintes limites na resposta em malha fechada (Vukosavić, 2007): a) a operação em baixa velocidade é prejudicada pelo offset intrínseco de amplificadores operacionais; b) os ganhos de realimentação, definidos por resistores e capacitores, variam com a temperatura e com o envelhecimento; c) os sensores do eixo, tal como o tacogerador CC, introduzem o ruído originado do comutador mecânico, com a frequência do ruído relacionada a velocidade de rotação. O ruído na linha de realimentação reduz o intervalo do ganho aplicável e, desse modo, a largura de banda de malha fechada; d) enquanto fornecendo um meio direto de implementação de ações de controle convencionais (controle Proporcional, Integral e Derivativo (PID)), esse tipo de implementação encontra grandes dificuldades implementando leis de controle nãolineares, compensadores de folga, filtros antiressonantes ou filtros de Resposta ao Impulso Finita (do inglês Finite Impulse Response – FIR); e) uma tarefa de controle de velocidade, onde parâmetros de realimentação ajustáveis tem que ser adaptados on-line para condições de operação específicas, dificilmente pode ser implementada por técnicas no domínio contínuo. Para esse caso, uma mudança nos parâmetros ou estrutura do controlador de velocidade requer substituição de resistores e capacitores. A implementação de tais substituições em tempo real é dificilmente praticável com ferramentas analógicas. Portanto, controladores de estrutura variável e adaptação de parâmetros requerem implementação em uma plataforma digital. 42 Comparada com a implementação analógica o controlador de velocidade digital experimenta deterioração de sinal devido à discretização de tempo e amplitude. Ao mesmo tempo, os cálculos numéricos envolvidos contribuem para atraso de transportes adicionais. Apesar disso, controladores de velocidade digital superam o desempenho das suas contrapartes analógicas (Vukosavić, 2007). Os efeitos de quantização e os atrasos de cálculo são suprimidos pelo uso de plataformas de Processamento Digital de Sinais (do inglês Digital Signal Processing – DSP) de controle de movimento especializadas e de alto processamento. Com sensores de eixo digitais, tais como encoders digitais, os sinais de realimentação são livres de offset e de ruído e mantêm sua relação sinal/ruído mesmo em velocidades girantes muito baixas. Um controlador de velocidade digital pode incluir compensadores não lineares, uma adaptação de parâmetros on-line e mecanismos de mudança estrutural; pode empregar filtros FIR e um número de outras características que não estão disponíveis na implementação analógica (Vukosavić, 2007). 4.2 Sistema com atuador de torque ideal e carga inercial Um diagrama de blocos de um sistema de controle de velocidade com um controlador digital é mostrado na Figura 4.1. A velocidade de referência no domínio do tempo *(t) é amostrada com período T. O sinal resultante é um trem de pulsos *DIG. Em um sistema microprocessado, *DIG é um valor armazenado na memória, que pode ser alterado a qualquer momento e atualizado no sistema de controle a cada período de amostragem T. O sinal de erro de velocidade é obtido pela diferença entre os sinais de velocidade de referência discreta *DIG e a velocidade medida discreta FBDIG. O valor de FBDIG é obtido através do sensor de realimentação no eixo do motor. O circuito de interface do sensor que faz a conversão do movimento rotativo do eixo do motor em um sinal elétrico é representado por WM(s). Na maioria dos casos, o sensor pode ser um tacogerador ou um encoder óptico ou eletromagnético. No caso de um tacogerador, o sinal FB é uma tensão com valor proporcional à velocidade. Esta tensão é amostrada por um conversor A/D com período T, resultando no trem de pulsos FBDIG. A conversão deste trem de pulsos de tensão para velocidade é representada por WSE(s). Quando utiliza-se um encoder, o sinal FB representa variações de posição. Geralmente, associado ao microprocessador tem-se um temporizador que captura de forma 43 assíncrona o tempo de cada novo pulso (ou conjunto de pulsos) digital que representa uma variação de posição. Desse modo, WSE(s) representa o cálculo da velocidade média FBDIG durante um período de amostragem T. Figura 4.1 – Diagrama de blocos de um sistema de controle de velocidade com implementação digital do algoritmo de controle. Fonte: Adaptada de Vukosavić (2007). O sinal de erro de velocidade é utilizado pelo controlador de velocidade digital WSC para se obter as amostras do torque de referência T*DIG necessárias para fazer o erro convergir para zero. Em um sistema discreto, o controlador WSC é caracterizado por uma equação de diferenças. A estrutura e os parâmetros de WSC determinam a característica e a largura de banda da resposta ao degrau em malha fechada (Vukosavić, 2007). O objetivo deste capítulo é fornecer um procedimento de projeto e a determinação dos parâmetros do controlador WSC. O circuito atuador de torque é representado pelo ganho Ka e por um limitador. Ele necessita como entrada de um torque de referência T*(t) contínuo. Desse modo, para realizarse a conversão do sinal discreto T*DIG para o sinal contínuo T*(t), utiliza-se um segurador de ordem zero (do inglês Zero-Order Hold – ZOH). Sua função de transferência é dada por (Fadali, 2009): WZOH 1 eTs . s (4.1) 44 O limitador do atuador restringe o torque de referência a ser desenvolvido Td em ± TMAX. Esse limite é determinado pela corrente máxima do circuito de acionamento do motor, assim como pela corrente máxima que o motor pode suportar. Após ter seu valor limitado, o torque que deve ser desenvolvido Td é aplicado ao subsistema mecânico WP, afetando a velocidade no eixo do motor (t). Como a constante de tempo eletromecânica geralmente é muito maior do que a constante de tempo elétrica do motor, considera-se que as amostras do torque a ser desenvolvido Td tem imediato efeito sobre a dinâmica eletromecânica do motor. 4.3 Função de transferência do subsistema mecânico A dinâmica do subsistema mecânico é representada pela Equação 4.2. O parâmetro J representa o momento de inércia no eixo do motor, Td representa o torque desenvolvido e TL é o torque da carga. J d Td (t) TL (t) dt (4.2) O torque TL pode ser considerado uma perturbação. Ele compreende além do torque da carga propriamente dito, a componente de atrito viscoso, a reação da transmissão (se presente), e outras componentes de torque parasitas. O que se assume na Equação 4.2 é que estas componentes parasitas estão desacopladas da dinâmica do subsistema mecânico (Vukosavić, 2007). No momento, considera-se o atuador de torque ideal, com Ka = 1 e sem o limitador. Desse modo, Td(t) = T*(t). Segundo Vukosavić (2007), uma das equações de diferenças que pode corresponder à Equação 4.2 é T J T J (n 1) (n) T * (n) TL (n) , (4.3) onde T*(n) corresponde ao valor na saída do ZOH entre os instantes t = nT e t = (n + 1)T e TL(n) é o valor médio do sinal TL(t) entre os instantes t = nT e t = (n + 1)T. Considerando TL(t) = 0 e aplicando a transformada z na Equação 4.3, a função de transferência do subsistema mecânico com relação à entrada T*(t) é dada por WP (z) (z) * T (z) TL (z) 0 T 1 . J z 1 (4.4) 45 De forma similar, pode-se calcular a função de transferência WPL(z) do subsistema mecânico com relação à entrada TL(t). Uma rápida observação na Equação 4.3 nos revela que WPL(z) = - WP(z). Quando as duas entradas estão presentes, a transformada z da saída se torna (z) WP (z)(T * (z) TL (z)) T 1 (T * (z) TL (z)) . J z 1 (4.5) 4.4 Função de transferência do subsistema de medição de velocidade Em sistemas de controle de velocidade digitais, na maioria dos casos, a medição da velocidade necessária à realimentação é realizada por meio de encoders ópticos ou eletromagnéticos. Como mencionado anteriormente, o encoder fornece informações de posição por meio de pulsos digitais. Pode-se supor, ainda, que não existem atrasos associados à geração destes pulsos. Assim, pode-se assumir que WM(s) = 1. Considerando a Figura 4.1, a posição do eixo do motor (t) (FB) é amostrada com período T, gerando o trem de pulsos DIG(n) (FBDIG). Em termos de sistemas microprocessados, isso se dá contando as variações de posição que cada pulso digital do encoder representa, dentro do período de amostragem. Quando se utiliza encoders como sensores de velocidade, a amostra de velocidade medida é a velocidade média dentro de um período de amostragem T. Para se obter a amostra da velocidade FB(n), utiliza-se a equação da derivada discreta da posição, que também corresponde à equação da velocidade média: FB (n) (n) (n 1) T . (4.6) Para se obter a função de transferência WSE(z), precisa-se determinar a relação entre a velocidade real do eixo do motor (n) e a velocidade média FB(n). Para esse fim, considera-se que o torque a ser desenvolvido Td e a o torque de perturbação da carga TL permanecem constantes durante o período de amostragem T. No caso da referência do torque a ser desenvolvido Td, ela é proveniente do ZOH, sendo assim constante durante o período T. E no caso da perturbação de carga TL, na maioria dos sistemas de controle de velocidade, pode-se considerar que ela permanece constante durante o período de amostragem T (Vukosavić, 2007). Os efeitos de uma perturbação de carga com variação muito rápida dentro do período de amostragem é abordado em uma seção posterior. 46 Nas condições supostas anteriormente, o gráfico da velocidade real (n) varia com uma inclinação constante (Vukosavić, 2007), como mostrado na Figura 4.2. Desse modo, a velocidade média FB(n) é proporcional à área S e é igual à média entre as velocidades reais (n) e (n - 1) espaçadas entre o período T. Figura 4.2 – A variação na velocidade real (n) no eixo do motor durante um período de amostragem T. Fonte: Adaptada de Vukosavić (2007). d dt (n) (n 1) nT ( n 1)T FB (n) dt FB (n) nT 1 dt T ( n 1)T (n) (n 1) 2 (4.7) (4.8) Aplicando a transformada z na Equação 4.8, finalmente obtém-se a função de transferência WSE(z). FB (z) WSE (z) (z) z 1 (z) 2 FB (z) z 1 (z) 2z (4.9) (4.10) 4.5 Função de transferência do sistema em malha fechada A função de transferência do sistema em malha fechada WSS(z) representa a relação entre a velocidade no eixo do motor (z) (saída) e a velocidade de referência *(z) 47 (entrada). Os polos e zeros de WSS(z) definem a característica da resposta do sistema e a sua largura de banda em malha fechada. O sistema da Figura 4.1 pode ser considerado de pequenos sinais. Desse modo, na presente análise, pode-se desconsiderar o bloco limitador de torque. Sem perda de generalidade, também pode-se incluir o bloco Ka em WSC, assumindo que o atuador de torque tem ganho unitário (Vukosavić, 2007). Um diagrama de blocos simplificado é dado na Figura 4.3. Figura 4.3 – Controlador de velocidade digital com atuador de torque ideal Ka = 1, controlador de velocidade discreto e subsistema mecânico no domínio contínuo. Fonte: Adaptada de Vukosavić (2007). Se introduz-se as funções de transferência WP(z) e WSE(z), obtidas nas seções anteriores, o diagrama de blocos compreendendo apenas sinais discretos resulta como na Figura 4.4. O controlador de velocidade digital WSC calcula as amostras do torque de referência T*DIG a partir do erro DIG. Segundo Vukosavić (2007), o controlador Proporcional e Integral (PI) garante rejeição de entrada e perturbações de carga na forma de degraus. Desse modo, assume-se que a função de transferência WSC(z) é uma versão discreta da função de transferência contínua do controlador PI. A equação no domínio do tempo que representa um controlador PI discreto é dada pela Equação 4.11, onde os ganhos proporcional e integral correspondem respectivamente a KP e KI. Os valores destes ganhos afetam a função de transferência WSC(z) e o desempenho do 48 sistema em malha fechada. O ajuste dos ganhos do controlador deve resultar em uma ação de controle que leve o erro de velocidade a zero através de consecutivos períodos de amostragem. j n T (n) K P (n) K I (j) * (4.11) j 0 Figura 4.4 – O diagrama de blocos de um sistema de controle de velocidade digital compreendendo sinais discretos. Fonte: Adaptada de Vukosavić (2007). Na prática, deve-se ter uma posição de memória que armazena a soma dos erros de velocidade (o acumulador de erro INT(n) na Figura 4.5). Multiplicando o acumulador de erro por KI, obtém-se a ação integral do controlador de velocidade. Na Figura 4.5, o torque de referência T*(n) é calculado por KP(n) + INT(n). Utilizando a função de transferência discreta para o integrador (1 – z-1)-1 na Equação 4.11, obtém-se a função de transferência WSC(z). T * (z) 1 WSC (z) KP KI (z) 1 z 1 (4.12) Uma outra implementação possível para o controlador de velocidade discreto é a forma incremental, como mostrada na Figura 4.6. A ação proporcional é calculada por KP((n) - (n - 1)) e a ação integral por KI(n). A soma da ação proporcional e da ação integral resulta no incremento do torque de referência T*(n). Amostra do torque de 49 referência T*(n) é então calculado por meio de um acumulador que armazena o valor da amostra anterior T*(n - 1). A equação de diferenças que representa o controlador PI na forma incremental é dada na Equação 4.13. Aplicando a transformada z obtém-se a Equação 4.14. Como pode-se observar, a função de transferência resultante da equação do controlador PI na forma incremental é a mesma obtida anteriormente para WSC(z) na forma direta. T * (n) T * (n) T * (n 1) K P ((n) (n 1)) K I (n) (4.13) T * (z)(1 z 1 ) K P (z)(1 z 1 ) K I (z). (4.14) Figura 4.5 – Implementação discreta do controlador de velocidade com ação proporcional e integral. Fonte: Adaptada de Vukosavić (2007). A forma incremental do controlador de velocidade tem algumas vantagens, que serão apresentadas mais adiante, quando se trabalha com condições de operação onde o torque a ser desenvolvido atinge os valores limite do atuador (Vukosavić, 2007). Portanto, esta é a implementação escolhida para o controlador PI. Para se obter a função de transferência do sistema em malha fechada WSS(z) com relação à velocidade de referência *, considera-se o torque de perturbação TLDIG igual a zero. Substituindo a Equação 4.4 para WP(z), a Equação 4.10 para WSE(z) e a Equação 4.12 para WSC(z) no sistema com realimentação simplificado da Figura 4.4, obtém-se a Equação 4.15 para WSS(z) (Vukosavić, 2007). 50 Figura 4.6 – Controlador de velocidade com ação proporcional e integral implementado na forma incremental. Fonte: Adaptada de Vukosavić (2007). WSS (z) (z) * (z) TL 0 WSC (z)WP (z) 1 1 WSC (z)WP (z)WSE (z) 2 z ( K P ( z 1) K I z ) T J T z ( z 1) ( K P ( z 1) K I z )( z 1) 2J T T (KP KI ) z 2 KP z J J T T T 2 z3 2 KP KI z 1 K I 2J 2J 2J (4.15) 2 T z KP 2J Do mesmo modo, considerando agora a velocidade de referência * igual a zero, pode-se obter a função de transferência de perturbação WLS(z), que representa a suscetibilidade da saída do sistema às perturbações de carga. Ela é apresentada na Equação 4.16 (Vukosavić, 2007). WLS (z) (z) L T (z) * 0 WP (z) 1 WSC (z)WP (z)WSE (z) T 2 T z z J J T T 2 T T z3 2 KP KI z 1 K I z KP 2J 2J 2J 2J (4.16) O denominador de WSS(z) e de WLS(z) é o polinômio característico f(z) do sistema. As raízes de f(z) são os polos de malha fechada do sistema. Observa-se também nas Equações 4.15 e 4.16 que os ganhos KP e KI são multiplicados pelo termo T/2J. Portanto, pode-se introduzir nestas equações os ganhos normalizados p e i, de acordo com as Equações 4.17 e 51 4.18 (Vukosavić, 2007). O resultado pode ser visto nas Equações 4.19 e 4.20 (Vukosavić, 2007). p KP i KI T 2J (4.17) T 2J (4.18) 2( p i) z 2 2 pz WSS (z) 3 z 2 p i z 2 1 i z p (4.19) T z2 z WLS (z) J z 3 2 p i z 2 1 i z p (4.20) 4.5.1 Polos de malha fechada e efeitos de zeros de malha fechada O polinômio característico do sistema em malha fechada f(z) possui três raízes. Portanto, têm-se três polos de malha fechada 1, 2 e 3, que determinam a característica e a velocidade da resposta do sistema. Na Equação 4.21 (Vukosavić, 2007), o polinômio característico f(z) é expresso em termos de seus zeros. f (z) z 3 (2 p i) z 2 (i 1) z p ( z 1 )( z 2 )( z 3 ) (4.21) Os polos de malha fechada dependem dos ganhos normalizados p e i. Portanto, não pode-se escolher os valores dos polos arbitrariamente. Tem-se dois parâmetros ajustáveis que determinarão os valores dos polos. Igualando os coeficientes de zn em ambos os lados da Equação 4.21, obtém-se três equações relacionando os polos de malha fechada com os ganhos normalizados p e i, como mostrado nas Equações 4.22, 4.23 e 4.24 (Vukosavić, 2007). 1 2 3 2 p i (4.22) 1 2 2 3 31 i 1 (4.23) 1 2 3 p (4.24) O polinômio do numerador de WSS(z) é dado na Equação 4.25 (Vukosavić, 2007). As raízes deste polinômio são os zeros do sistema. O zero z2 está localizado na origem e, portanto, adianta a resposta do sistema em um período de amostragem T. Esse efeito sobre a resposta do sistema é benéfico, pois reduz atrasos introduzidos pelo polinômio de terceira 52 ordem do denominador. O zero z1 é real e positivo e se localiza dentro do círculo unitário, sendo, portanto, mapeado no lado negativo do eixo real do plano s. num(z) 2( p 1) z 2 2 pz z1 p pi (4.25) (4.26) z2 0 (4.27) Com todos os polos de malha fechada sendo reais, é esperado que a resposta ao degrau do sistema seja aperiódica. No entanto, a presença do zero z1 contribui para a ação derivativa da função de transferência. Esta natureza diferencial de WSS(z) enfatiza a curva de subida da entrada e das perturbações de carga, causando o surgimento de sobressinal (Vukosavić, 2007). Em inúmeras aplicações de servomecanismos, ultrapassar a referência não é aceitável. O sobressinal pode levar a carga mecânica e suas partes vitais, como ferramentas, a uma posição onde eles podem colidir com outros objetos e eventualmente se danificar. Considerando uma resposta de velocidade com sobressinal, no final do período transitório é necessário que ocorra uma fase de desaceleração requerida para dissipar o excesso de velocidade. Nesta fase, o torque desenvolvido torna-se negativo. Frequentes mudanças de sinal do torque desenvolvido agravam a folga nos elementos de transmissão, resultando em desgaste e redução de controlabilidade da velocidade e da posição da carga mecânica (Vukosavić, 2007). Portanto, com o intuito de evitar respostas oscilatórias, o projeto do controlador deve produzir uma função de transferência em malha fechada com zeros apenas na origem. Isso pode ser alcançado com o artifício de realocação do ganho proporcional. 4.5.2 Realocação do ganho proporcional No controlador representado na Figura 4.5, o ganho proporcional está localizado no caminho direto e multiplica o erro de velocidade . Outra forma de se implementar o controlador PI é apresentada na Figura 4.7, onde o ganho KP está no caminho de realimentação e multiplica a amostra de velocidade . 53 Figura 4.7 – Controlador de velocidade discreto com o ganho proporcional realocado no caminho de realimentação. Fonte: Adaptada de Vukosavić (2007). Para a estrutura da Figura 4.7, considera-se agora que o torque de perturbação TL seja igual à zero. A relação no domínio da frequência entre a velocidade de saída (z) e a velocidade de referência *(z) é dada pela Equação 4.28 (Vukosavić, 2007). Desse modo, a função de transferência em malha fechada para o sistema com realocação do ganho proporcional pode ser derivada da Equação 4.28 e é dada pela Equação 4.29 (Vukosavić, 2007). (z) 1 K PWSE (z)WP (z) WSS (z) (z) * (z) TL 0 KI z K z WSE (z)WP (z) I WP (z) * (z) z 1 z 1 (4.28) WSC (z)WP (z) 1 WSC (z)WP (z)WSE (z) KI T 2 z J (4.29) T T 2 T T z3 2 KP KI z 1 K I z KP 2J 2J 2J 2J Introduzindo os ganhos normalizados p e i na Equação 4.29 atinge-se a Equação 4.30 (Vukosavić, 2007) para a função de transferência do sistema em malha fechada. Pode-se observar que a realocação do ganho proporcional não altera o polinômio característico do sistema. O numerador, no entanto, passa a possuir dois zeros na origem. A resposta do sistema resultante é aperiódica e não ultrapassa a referência (Vukosavić, 2007). 54 WSS (z) 2iz 2 z 3 (2 p i) z 2 (1 i) z p (4.30) Com o ganho proporcional no caminho de realimentação, as variações do sinal de erro de velocidade afetam o torque de referência TL através da ação integral. Portanto, grandes variações no sinal de erro resultarão em flutuações mais suaves no torque de referência e o esforço submetido ao subsistema mecânico será reduzido (Vukosavić, 2007). A implementação prática do controlador com realocação do ganho proporcional na forma incremental pode ser vista através das Equações 4.31 e 4.32 (Vukosavić, 2007). T * (n) T * (n) T * (n 1) K P ((n 1) (n)) K I (n) (4.31) T * (n) T * (n 1) T * (n) (4.32) 4.6 Determinação de parâmetros de controladores de velocidade digitais O procedimento de determinação de parâmetros do controlador de velocidade digital tem como objetivo encontrar valores para os ganhos normalizados p e i, tal que, seja alcançada uma resposta aperiódica mais rápida possível. Primeiro, o objetivo é expresso em uma função critério em termos dos parâmetros p e i. A partir daí, o processo de otimização encontra os valores de p e i que resultam no valor extremo da função critério. 4.6.1 Resposta estritamente aperiódica Para se obter uma resposta estritamente aperiódica é necessário obedecer certas condições no que diz respeito a natureza da função de transferência de malha fechada do sistema de controle de velocidade. Essas condições são a ausência de zeros de malha fechada reais e a presença de polos de malha fechada reais localizados no interior do círculo unitário (intervalo [0, 1]) do plano z. A ausência de zeros reais já foi obtida por meio da realocação do ganho proporcional do controlador. A obtenção dos polos de malha fechada 1, 2 e 3 nas condições desejadas é alcançada por meio do ajuste dos parâmetros p e i. Os polos de malha fechada estão relacionados com os ganhos normalizados pelas Equações 4.22, 4.23 e 4.24. Uma resposta estritamente aperiódica impõe as seguintes restrições aos polos de malha fechada (Vukosavić, 2007): 55 Im(1 ) 0, Im( 2 ) 0 e Im( 3 ) 0 (4.33) 0 Re(1 ) 1, 0 Re( 2 ) 1 e 0 Re( 3 ) 1 (4.34) Sob as restrições das Equações 4.33 e 4.34 e as relações dadas pelas Equações 4.22, 4.23 e 4.24, os ganhos normalizados p e i serão escolhidos para fornecer a resposta mais rápida possível e a máxima largura de banda de malha fechada. Uma ampla largura de banda permite a supressão com sucesso de flutuações causadas pelas perturbações de torque de carga. 4.6.2 Formulação da função critério A Figura 4.8 mostra uma resposta ao degrau da velocidade (t) estritamente aperiódica, para uma referência *. Como não há sobressinal, as amostras do erro de velocidade (n) = * - (nT) = (nT) são sempre positivas. Pode-se observar que quanto Figura 4.8 – Uma resposta ao degrau estritamente aperiódica. Fonte: Adaptada de Vukosavić (2007). mais rápida é a resposta do sistema, menor é a área sombreada da Figura 4.8. Portanto, essa superfície pode ser um indicador da velocidade da resposta de velocidade. O valor da área sombreada S pode ser calculada pela integral definida na Equação 4.35. Trabalhando com sistemas discretos, pode-se calcular a área sombreada através de uma somatória Q e em termos das amostras do erro de velocidade (n), como mostrado na Equação 4.36. O valor 56 de Q será utilizado como a função critério. Assim, busca-se os valores de p e i que correspondem ao menor valor possível de Q para as dadas restrições. S (t) dt (4.35) 0 Q (kT) (4.36) k 0 É necessário expressar a função critério Q em termos dos parâmetros p e i. Com esse intuito, considera-se o trem de amostras Q(n), mostrado na Equação 4.37. Cada amostra de Q(n) corresponde à soma dos erros de velocidade do instante 0 até o instante nT. Quando n tende ao infinito, Q(n) converge para a função critério Q. A transformada z de Q(n) em função de (z) pode ser obtida como mostra a Equação 4.38. n Q (kT) (4.37) k 0 Q(z) Q(n) z n k 0 1 (z) 1 z 1 (4.38) A função critério Q pode ser obtida então através do teorema do valor final aplicado a Q(z), como visto na Equação 4.39. z 1 Q Q() lim (z) Q(z) lim z 1 z 1 z (4.39) Pode-se expressar (z) em função da referência de velocidade *(z) e da função de transferência de malha fechada WSS(z) (Equação 4.40). Para uma resposta ao degrau, *(z) é dada como mostra a Equação 4.41. (z) * (z) (z) * (z)(1 WSS (z)) * (z) * 1 z 1 (4.40) (4.41) Substituindo as Equações 4.30 e 4.41 na Equação 4.33, a expressão para (z) fica como mostrado na Equação 4.42. Assim, a função critério Q é dada na Equação 4.43 (Vukosavić, 2007). 57 * 2iz 2 (z) 1 3 1 2 1 z z (2 p i ) z (i 1) z p z* z 3 z 2 ( p i 2) z (1 i ) p z 1 z 3 (2 p i ) z 2 (i 1) z p z* ( z 1)( z 2 z ( p i 1) p) z 1 z 3 (2 p i ) z 2 (i 1) z p (4.42) z* ( z 2 z ( p i 1) p) z 3 (2 p i ) z 2 (i 1) z p p 1 Q lim (z) * z 1 i 2 (4.43) Fazendo a relação p/i ser a menor possível, a função critério pode então ser minimizada. Para se obter a resposta estritamente aperiódica mais rápida possível, o valor mínimo da relação p/i deve ser obtido respeitando-se as relações das Equações 4.22, 4.23 e 4.24 e as restrições das Equações 4.33 e 4.34. Na próxima seção, os valores otimizados de p e i são encontrados por um procedimento buscando o valor máximo de Q1 = i/p = 1/Q. 4.6.3 Cálculo dos valores otimizados dos ganhos normalizados As Equações 4.22, 4.23 e 4.24 dão a relação entre os polos de malha fechada 1, 2 e 3 e os ganhos normalizados p e i. Somando as três expressões, obtém-se a Equação 4.44, que restringe a escolha dos polos. Dois dos três polos podem ser ajustados à vontade, enquanto que o terceiro é calculado da Equação 4.44. (1 2 3 ) (1 2 2 3 31 ) (1 2 3 ) 3 (4.44) Utilizando as Equações 4.23 e 4.24, pode-se relacionar a função critério Q1 = i/p com os polos de malha fechada (Equação 4.45). Q1 i 1 2 2 3 3 1 1 p 1 2 3 (4.45) Pode-se expressar os polos de malha fechada pelos seus valores inversos x = 1/1, y = 1/2 e v = 1/3. Pelas restrições nas Equações 4.33 e 4.34, tem-se que x, y e v são números reais positivos maiores do que um (x > 1, y > 1 e v > 1). A Equação 4.44 assume a forma dada na Equação 4.46. xy yv vx x y v 1 3xyv (4.46) A variável v pode ser expressa em termos de x e y como na Equação 4.47 abaixo. 58 v ( x, y ) xy x y 1 3xy x y 1 (4.47) A função critério é reformulada e dada em função de x e y na Equação 4.48. i x y v( x, y ) xyv( x, y ) p xy x y 1 x y (1 xy ) 3xy x y 1 Q1 (4.48) Deve-se então encontrar os valores de x e y que resultam no máximo valor da função critério. x e y possuem valores dentro do intervalo [1, +∞]. É necessário provar que o valor máximo de Q1(x,y) não ocorre nos limites deste intervalo. Através da Equação 4.44 pode-se concluir (Vukosavić, 2007): a) quando x = y = +∞, os polos de malha fechada 1 = 1/x e 2 = 1/y estão na origem, enquanto que o terceiro polo permanece fora do círculo unitário (3 = 3), causando instabilidade; b) quando x = y = 1, os polos de malha fechada 1 = 1/x e 2 = 1/y estão no círculo unitário no plano z. Eles estão mapeados no plano s em s1/2 = 0, introduzindo um integrador duplo na função de transferência de malha fechada e uma resposta ao degrau que não converge para a referência; c) quando x = 1 e y = +∞ ou y = 1 e x = +∞, o terceiro polo 3 = 1/v está no círculo unitário (3 = 1), resultando no plano s s3 = 0 e na não convergência da resposta da velocidade para a referência. Visto que o valor máximo da função critério não ocorre nos limites do intervalo [1, +∞], os valores otimizados xOPT e yOPT podem ser calculados fazendo as primeiras derivadas parciais de Q1(x,y) (Equações 4.49 e 4.50) iguais a zero. Desprezando a solução x = 1 e y = 1, é necessário encontrar as soluções que satisfazem as Equações 4.44 e 4.45. f 2 ( x, y) ( x 1)2 (2 yx 3xy 2 x y 2 2 y 1) (3xy x y 1)2 (4.49) f1 ( x, y ) ( y 1)2 (2 xy 3 yx 2 y x 2 2 x 1) (3xy x y 1)2 (4.50) 2 xy 3 yx2 y x 2 2 x 1 0 (4.51) 2 yx 3xy 2 x y 2 2 y 1 0 (4.52) Pela Equação 4.51, pode-se expressar y em termos de x: 59 y( x) x2 2x 1 . 3x 2 2 x 1 (4.53) Substituindo a Equação 4.53 na Equação 4.52, obtém-se: 3x 4 6 x 2 4 x 1 4x 0. (3x 2 2 x 1) 2 (4.54) A solução x = 0 corresponde a polos fora do círculo unitário, portanto, é desprezada. Através da Equação 4.55 obtém-se as quatro soluções restantes. H ( x) 3x 4 6 x 2 4 x 1 0 (4.55) x1 = 1,7024, (4.56) x2/3 = -0,3512 ± j0,2692 e (4.57) x4 = -1. (4.58) Tomando-se as restrições das Equações 4.33 e 4.34, e sabendo que 1 = 1/x, despreza-se as soluções x2, x3 e x4. Substituindo x1 = 1,7024 nas Equações 4.53 e 4.47, obtémse: xOPT = yOPT = vOPT = 1,7024. (4.59) Os valores de 1, 2 e 3 agora podem ser calculados (Equação 4.60) e substituídos nas Equações 4.23 e 4.24 para se obter os valores otimizados dos ganhos normalizados (Equações 4.61 e 4.62). 1 2 3 0,587 (4.60) pOPT 3 0, 2027 (4.61) iOPT 3 2 1 0,03512 (4.62) Os ganhos absolutos do controlador KP e KI são obtidos substituindo-se os valores de pOPT e iOPT nas Equações 4.17 e 4.18. Portanto, tem-se K P OPT 0, 2027 2J , T (4.63) 2J . T (4.64) K I OPT 0, 03512 Em aplicações práticas de controladores de velocidade digitais, sinais como a velocidade de referência, a velocidade medida do eixo do motor, o sinal de erro e a referência de torque são armazenados na RAM do microcontrolador. Na maioria dos casos, estes sinais são representados por inteiros com sinal de 16 bits. A relação entre a velocidade real expressa em [rad/s] e a palavra digital representando a velocidade é decidida pelo programador. Esta decisão é governada pelo requerimento para maximizar a resolução na representação da 60 velocidade e para minimizar o ruído de quantização produzido pelo comprimento de palavra finito (Vukosavić, 2007). O coeficiente de proporcionalidade entre a representação digital e a velocidade real pode ser representado por KFB. Do mesmo modo, a relação entre a referência de torque real e sua imagem digital podem ser representada por KA. A Figura 4.9 representa o diagrama de blocos do controlador de velocidade digital introduzindo-se os coeficientes de escalonamento KFB e KA. Estes coeficientes multiplicam a função de transferência de malha aberta e afetam a relação entre os valores otimizados dos ganhos do controlador KP e KI e suas contrapartes normalizadas p e i. As Equações 4.65 e 4.66 incluem a influência dos coeficientes de escalonamento nas expressões dos ganhos otimizados do controlador (Vukosavić, 2007). Portanto, para se realizar o ajuste do controlador PI digital, são necessários os valores do período de amostragem T, do momento de inércia no eixo do motor J e dos coeficientes de escalonamento KFB e KA. K P OPT 0, 2027 2J 1 T K A K FB (4.65) 2J 1 T K A K FB (4.66) K I OPT 0, 03512 Figura 4.9 – Um controlador de velocidade digital indicando os coeficientes de escalonamento KFB e KA e estabelecendo a relação entre os sinais de velocidade e torque reais e suas representações digitais de comprimento de palavra finito T*DIG e *DIG, localizadas na RAM. Fonte: Adaptada de Vukosavić (2007). 61 4.7 Estratégia anti-wind-up Uma alta capacidade de tolerância a sobrecargas é um requisito de muitas aplicações de controle de movimento. Isso acontece em casos onde se necessita alta aceleração, o que significa que os motores devem trabalhar com torques muito elevados durante um curto período de tempo. No entanto, o torque máximo ± TMAX que pode ser desenvolvido pelo motor é limitado pelas características dos semicondutores que compõem os conversores de potência (atuadores) associados ao motor, assim como por características do próprio motor. Um sistema de controle de velocidade digital com capacidade de torque limitada é mostrado na Figura 4.10. Enquanto a referência de torque T* está dentro dos limites impostos pelo torque máximo ± TMAX, o sistema opera na região linear. Variações na velocidade de referência ou no torque de perturbação irão resultar em transientes de torque proporcionais a estas variações. No entanto, variações muito elevadas nas entradas do sistema farão com que o torque de referência atinja o seu limite máximo, levando o sistema para um modo de operação não linear. Figura 4.10 – O sistema de controle de velocidade digital com capacidade de torque limitada do atuador. Fonte: Adaptada de Vukosavić (2007). A Figura 4.11 mostra a resposta de um sistema de controle de velocidade digital com um elevado degrau de entrada. Como o torque atinge seu limite positivo e permanece constante, tem-se uma aceleração constante. Assim, a velocidade do eixo aumenta com uma 62 inclinação constante. O torque oscila atingindo os limites máximos várias vezes, resultando em uma resposta de forma triangular, com decaimento de amplitude e aumento de frequência gradual. Esse tipo de resposta é característica de sistemas não-lineares e esse fenômeno é chamado de wind-up. Ele se dá pelo crescimento elevado do termo integral do controlador, que se diz estar carregado. O descarregamento do termo integral ocorre gradativamente somente quando, devido ao sobressinal, o erro se torna negativo. Os efeitos causados pelo wind-up não são aceitáveis. Portanto, o projeto do controlador de velocidade deve incluir estratégias para suprimir o carregamento do termo integral, que são conhecidas como anti-wind-up (AWU). As estratégias AWU aplicadas a controladores na forma posicional (Figura 4.5, Figura 4.7 e Equação 4.11) são complexas e apresentam várias desvantagens. No entanto, pode-se obter uma implementação simples e efetiva na forma incremental do controlador PI (Figura 4.6 e Equações 4.13, 4.31 e 4.32). As expressões para o controlador PI na forma incremental com realocação do ganho proporcional (Equações 4.31 e 4.32) podem ser reescritas na forma a seguir. A estrutura para esse controlador é mostrada na Figura 4.12. T * (n 1) T * (n 1) T * (n) K P ((n) (n 1)) K I (n 1) (4.67) n 1 T * (n 1) T * (k) (4.68) k 0 O integrador discreto abrangendo o limitador de torque, o bloco de atraso D2 e o somador S1 é responsável pela ação integral sobre o erro. A localização do limitador previne o carregamento da ação integral e suprime suas consequências negativas. Na Figura 4.13 tem-se um exemplo de simulação para um sistema com o controlador mostrado na Figura 4.2. Durante o período em que o torque atinge o valor máximo, a velocidade do eixo varia com aceleração amax = TMAX/J. A velocidade atinge a referência sem sobressinal. Do mesmo modo, quando a referência muda para zero, a velocidade diminui com aceleração constante até a parada, sem mudança de sinal. Segundo Vukosavić (2007), a estrutura da Figura 4.12 elimina o wind-up no integrador do erro e fornece um resposta estritamente aperiódica, mesmo em casos com elevadas perturbações de entrada. Com relação ao problema de controle de velocidade, estratégias AWU adicionais não são necessárias. 63 Figura 4.11 – Resposta a um elevado degrau de entrada, levando o sistema à saturação. Fonte: Adaptada de Vukosavić (2007). Figura 4.12 – Forma incremental do controlador de velocidade digital com ação proporcional realocada no caminho de realimentação. Fonte: Adaptada de Vukosavić (2007). 64 Figura 4.13 – Resposta a um degrau elevado obtida com um controlador de velocidade PI discreto na sua implementação incremental e com a estrutura AWU da Figura 4.12. Fonte: Adaptada de Vukosavić (2007). 65 5 SISTEMA DE CONTROLE DE VELOCIDADE DIGITAL BASEADO NA FERRAMENTA EZ430-RF2500 5.1 Introdução Baseado nos fundamentos expostos nos capítulos 2, 3 e 4, foi desenvolvido um sistema de controle de velocidade digital utilizando a ferramenta eZ430-RF2500 e um programa de interface gráfica. O material utilizado para a sua implementação é descrito a seguir: a) 01 ferramenta de desenvolvimento eZ430-RF2500 da Texas Instruments: 02 placas alvo eZ430-RF2500T; 01 interface de depuração USB eZ430-RF; 01 kit de baterias AAA com placa de extensão. b) 01 motor CC escovado de ímã permanente da Pololu Corporation: velocidade nominal a vazio do eixo de saída v0 = 80 rpm; caixa de transmissão 131,25:1; torque desenvolvido de rotor travado Tstall = 250 oz.in; tensão nominal Vn = 12V; corrente em vazio I0 = 300 mA; corrente de rotor travado Istall = 5 A; encoder em quadratura de efeito Hall de 64 pulsos por revolução (equivalente a 8400 pulsos por revolução com relação ao eixo de saída), 2 canais e tensão de alimentação entre 3,5 – 20 V; dimensão: 37 mm de diâmetro x 69 mm de comprimento. c) 01 driver de motor CC MC33926 Motor Driver Carrier da Pololu Corporation: tensão de chaveamento entre 5 – 28 V; máxima corrente em regime permanente de 3 A; máxima corrente de pico de 5 A; entradas com lógica compatível com padrões Lógica Transistor-Transistor (do inglês Transistor-Transistor Logic – TTL) 5 V e Semicondutor de Óxido de Metal Complementar (do inglês Semiconductor – CMOS) 3 V; suporta até 20 kHz de frequência PWM. Complementary Metal-Oxide- 66 d) 01 bateria selada de 12 V e 7 Ah; e) resistores: 02 resistores de 100 kΩ; 02 resistores de 33 kΩ. f) 01 placa de circuito impresso padrão tipo trilha; g) barras de pinos diversas; h) terminais e alojamentos para conectores tipo Modu diversos; i) cabos diversos. É importante mencionar o motivo da escolha de se usar uma bateria como fonte de alimentação para o motor CC. Em casos de grande redução de velocidade ou reversão, a fcem do motor CC pode se tornar maior do que a tensão de alimentação. Em fontes baseadas em circuitos eletrônicos comuns é possível que ocorra até mesmo a danificação da fonte. Quando se utiliza uma bateria, esse problema não ocorre, pois ela absorve a energia proveniente da fcem do motor CC. O sistema de controle de velocidade digital pode ser dividido em 3 componentes principais. A interface gráfica, o módulo local e o módulo remoto. A interface gráfica é um programa de computador que roda no sistema operacional Windows de 64 bits. O módulo local é composto por uma placa alvo eZ430-RF2500T conectada a interface de depuração USB eZ430-RF. O módulo remoto é composto por uma placa alvo eZ430-RF2500T conectada ao kit de baterias. A interface gráfica e o módulo local residem em um computador distante do módulo remoto. A comunicação entre a interface gráfica e o módulo local se dá por comunicação serial. A comunicação entre o módulo local e o remoto é sem fio. A comunicação sem fio é realizada através do protocolo de comunicação sem fio SimpliciTI. Ele é um protocolo proprietário da Texas Instruments. Para a implementação dos programas dos módulos local e remoto adaptou-se um exemplo de comunicação peer-to-peer que pode ser encontrado em Texas Instruments (2013c). 5.2 Interface gráfica A interface gráfica desenvolvida foi adaptada daquela encontrada em Henry Poon's Blog (2013). Ela foi desenvolvida utilizando a linguagem de programação Java e 67 realiza a comunicação serial através da versão de 64 bits da biblioteca RXTX. Uma imagem sua pode ser vista na Figura 5.1. Figura 5.1 – Imagem da interface gráfica do sistema de controle de velocidade digital. Fonte: Próprio autor. A interface gráfica é formada por três objetos: a) BlueSkyGUI: implementa a parte gráfica do programa; b) KeyBinding: implementa as funções que controlam o bloqueio e desbloqueio dos elementos da interface gráfica; c) SerialCommunication: implementa todas as funções que realizam o processo de comunicação serial. A interface gráfica é responsável pela transmissão de novas velocidades de referência e de comandos de resposta ao degrau e de desligamento para o módulo local e pela 68 recepção do status da comunicação sem fio, da velocidade atual medida e de confirmações de fim de resposta ao degrau e de desligamento. O programa inicia apenas com a caixa de combinação de seleção de porta serial, o botão “Conectar” e a caixa de texto ativos. Os outros itens ficam bloqueados até que a conexão serial com o módulo local e a comunicação sem fio entre o módulo local e o remoto sejam estabelecidas com sucesso. Mensagens de sucesso desses dois passos são mostradas na caixa de texto, assim como mensagens de erro. A partir daí o uso da interface gráfica é simples. Pode-se então colocar o motor em funcionamento com uma nova velocidade de referência ou executar um comando de resposta ao degrau e salvar as amostras de velocidade em um arquivo de texto. Para uma nova velocidade de referência, através do spinner da velocidade de referência, pode-se selecionar valores entre 80 e -80 rpm com um passo de 1 rpm. Enviada uma nova velocidade de referência para o módulo local, aguarda-se o início de rotação do motor e então a velocidade atual medida é mostrada a cada 0,5 segundo. Com o motor em movimento, pode-se enviar novas velocidades de referência, efetuar comandos de desligamento e desconexão ou realizar-se um comando de resposta ao degrau. Comandos de resposta ao degrau podem ser realizados com o motor inicialmente desligado ou com o motor já em movimento. Para realizar-se um comando de resposta ao degrau deve-se fornecer a velocidade inicial, a velocidade final, o tempo em segundos (entre 0,1 e 3 segundos) do degrau, selecionar se a as amostras devem ser salvas em rpm ou rad/s e clicar-se no botão “Iniciar”. O processo começa sendo enviada a velocidade inicial do motor. O motor permanece girando nessa velocidade por aproximadamente 2,5 segundos. Logo após, são enviados o comando de resposta ao degrau e a velocidade final. Após o período da resposta ao degrau, o motor é desligado, uma mensagem de final da resposta ao degrau é mostrada na caixa de texto e as amostras de velocidade são salvas em um arquivos de texto. Para salvar em arquivo, o programa cria automaticamente uma pasta no caminho “C:\BlueSky” e salva o arquivo com o título no formato "StepResponse_dd.MM.yyyy_HHmm-ss.txt”. O código após a primeira sublinha se refere à data atual e o código após a segunda sublinha se refere à hora local em que ocorreu o ensaio. Comandos de desligamento são seguidos por confirmação do desligamento, pois o motor é parado de forma controlada, não apenas desenergizado. Ao final do desligamento, uma mensagem é mostrada na caixa de texto. Comandos de desconexão são apenas comandos de desligamento seguidos pela interrupção da comunicação serial e do fechamento da porta 69 serial. Após a desconexão o fluxo do programa retorna ao estado inicial podendo ser fechado com segurança. Nesse ponto, caso seja desejado uma nova utilização do programa, é necessário reiniciar os módulos local e remoto e recomeçar o processo descrito anteriormente. 5.3 Módulo local O módulo local é responsável por realizar a comunicação entre a interface gráfica e o módulo remoto. No sentido interface gráfica – módulo remoto, ele transmite novas velocidades de referência e comandos de resposta ao degrau e de desligamento. No sentido módulo remoto – interface gráfica, são transmitidos o status da comunicação sem fio, a velocidade atual medida e confirmações de fim de resposta ao degrau e de desligamento. No início do programa é realizada a configuração de hardware pelo protocolo SimpliciTI através da função BSP_Init(). Esta função configura componentes como a frequência de clock, o watchdog timer e a temporização do protocolo pelo Timer_A ou via software. O próximo passo é a configuração da comunicação serial com o computador. Antes da configuração dos registradores de controle da USCI_A, é necessário configurar o registrador de seleção de função P3SEL da porta P3 para que os pinos P3.4 e P3.5 sejam usados pela USCI_A para transmissão e recepção, respectivamente, no modo UART. A comunicação da USCI_A é então configurada para sem paridade, bit menos significante primeiro, 8 bits de dados, 1 bit de parada, modo UART e modo assíncrono. A lógica da USCI_A é parada em reset, a fonte do clock é SMCLK = 12 MHz e a velocidade é configurada no modo de baixa frequência em 9600 baud. Ao final da configuração, a USCI_A é liberada do reset e interrupções na unidade de recepção são habilitadas. Depois das configurações iniciais o programa aguarda que o botão seja pressionado para que se inicie a comunicação sem fio. Após o botão ser pressionado, é gerado um endereço para o módulo local e são inicializados o rádio e a pilha de protocolos SimpliciTI. Os LEDs (do inglês Light Emissor Diode) ficam piscando até que o link de comunicação com o módulo remoto seja estabelecido. Estabelecido o link, o programa envia pela porta serial uma confirmação para a interface gráfica de que a comunicação sem fio foi estabelecida. O laço principal do programa é formado apenas por seis verificações condicionais de variáveis booleanas que indicam a ocorrência de algum evento iniciado por uma 70 interrupção. Esses eventos podem ser provenientes da interface gráfica ou do módulo remoto e para cada um deles uma ação é tomada. A lógica das ações é bem simples e é descrita a seguir. 5.3.1 Eventos provenientes da interface gráfica Como mencionado anteriormente, os eventos provenientes da interface gráfica têm como ação a transmissão para o módulo remoto de novas velocidades de referência e comandos de desligamento. Esses eventos são recebidos por comunicação serial e sua ocorrência é sinalizada pela rotina de serviço de interrupção que trata da recepção de dados na USCI_A. Quando um conjunto de bytes é recebido, é identificado a que classe de evento eles pertencem e uma variável booleana correspondente torna-se verdadeira. Tratada a interrupção, retorna-se ao laço principal do programa e a verificação condicional correspondente é satisfeita. A ação correspondente é então tomada, no caso, enviar algo para o módulo remoto. Todas as ações relacionadas com eventos provenientes da interface gráfica utilizam a função “smplStatus_t SMPL_Send(linkID_t lid, uint8_t *msg, uint8_t len)” para enviar dados para o módulo remoto. Ela retorna variáveis de status do protocolo SimpliciTI e os seus argumentos são a identificação do link “lid” para o qual os dados serão enviados, o ponteiro “msg” para os dados a serem enviados e o comprimento “len” desse ponteiro (número de bytes a ser enviado). Para o caso em que uma nova velocidade de referência ou um comando de resposta ao degrau devem ser enviados, três bytes são enviados para o módulo remoto. O primeiro byte é a identificação do evento. Os dois outros bytes, para uma nova velocidade de referência, correspondem ao valor da velocidade de referência e, para um comando de resposta ao degrau, correspondem a quantidade de amostras de duração da resposta. Para o evento de desligamento, é enviado apenas a correspondente identificação do evento. 71 5.3.2 Eventos provenientes do módulo remoto Os eventos provenientes do módulo remoto são o envio do status da comunicação sem fio, o envio da velocidade atual medida e o envio de confirmações de fim de resposta ao degrau e de que o motor está desligado. Esses eventos são recebidos pelo protocolo de comunicação sem fio SimpliciTI e têm caráter de interrupção. Eles são processados pela função “static uint8_t sRxCallback(linkID_t port)” que é especificada no início do programa como a função responsável por tratar as interrupções geradas pela recepção de novos pacotes pelo protocolo SimpliciTI. Ela retorna valores 0 ou 1, caso seja mal-sucedida ou não, respectivamente. Seu argumento é a identificação do link “port” de onde foi recebido o pacote. Como no caso anterior, após classificar que tipo de evento o conjunto de bytes recebidos representam, uma variável booleana torna-se verdadeira e o fluxo de programa retorna ao laço principal. Lá, uma verificação condicional é satisfeita e uma ação é tomada. Para este caso, o envio de algo para a interface gráfica. Todas estas ações utilizam a função “void writeData(uint8_t wCommand, uint8_t currentOmega0, uint8_t currentOmega1)”, onde ela é uma função de retorno vazio, que tem como argumentos o tipo de comando “wCommand” e os bytes “currentOmega0” e “currentOmega1”, que formam a velocidade atual medida (têm valor zero para os demais comandos). Após armazenar os dados a serem enviados em um vetor apropriado, o envio dos dados pela porta serial se dá pela habilitação da interrupção de transmissão. Na rotina de serviço de interrupção os bytes armazenados no vetor são atribuídos um de cada vez ao buffer de transmissão e automaticamente enviados. 5.4 Módulo remoto No módulo remoto é onde acontece o controle do motor propriamente dito. Além das tarefas de controle, ele se comunica por meio do protocolo SimpliciTI com o módulo local. O programa começa com a configuração do hardware do modulo remoto pelo protocolo SimpliciTI e com uma rotina de espera até que o botão do módulo seja pressionado. Feito isso, a comunicação sem fio é iniciada e entra-se em um novo laço onde se aguarda o 72 envio da primeira velocidade de referência. Recebida a velocidade, definem-se certas condições por meio de variáveis booleanas e abandona-se o laço. O passo seguinte é fazer algumas configurações iniciais para o Timer_A e o Timer_B. O Timer_A é responsável pela medição da velocidade do motor enquanto que o Timer_B gera o sinal PWM para o driver do motor. Em seguida, entra-se no laço principal do programa. Dentro deste laço existem outros dois laços colocados de forma sequencial. O primeiro, caso o motor esteja ligado e o segundo para o caso de o motor já houver sido ligado e foi desligado. O segundo caso nada mais é do que um laço vazio realizado enquanto uma nova velocidade de referência não for enviada. Sendo enviada uma nova velocidade o laço termina, algumas condições iniciais são definidas e entra-se no laço para o caso do motor ligado. É neste laço onde ocorrem todas as ações de controle. Nas seções seguintes são descritas as rotinas necessárias para se realizar o controle de velocidade e a comunicação com o módulo local. 5.4.1 Comunicação com o módulo local A comunicação com o módulo local se dá pela recepção de novas velocidades de referência e de comandos de resposta ao degrau e de desligamento e pela transmissão da velocidade atual e de confirmações de fim de resposta ao degrau e de desligamento. A recepção ocorre do mesmo modo como no módulo local e se dá pela função “sRxCallback”. Nela são armazenados os bytes recebidos em outras variáveis e atribuídos valores verdadeiros para variáveis booleanas correspondentes a cada evento. Retornando ao laço principal uma verificação condicional é realizada e uma ação é tomada. Para o caso de uma nova velocidade de referência, os bytes recebidos são unidos em uma variável de 16 bits para formar a velocidade angular multiplicada por mil. Esse valor será utilizado na próxima iteração do sistema de controle. Quando é recebido um comando de resposta ao degrau, une-se os bytes recebidos em uma variável de 16 bits para formar-se a quantidade de amostras que corresponde à duração do degrau. Todo comando de resposta ao degrau é sucedido por um comando de nova velocidade de referência (velocidade final). Quando a nova velocidade de referência é recebida, na próxima iteração do sistema de controle, em vez de ser enviada a cada 0,5 segundo, a velocidade atual passa a ser enviada a cada período de amostragem durante o 73 número de amostras recebido. Ao final desse período, a velocidade de referência é atribuída igual a zero e é enviada a confirmação de fim de resposta ao degrau ao módulo local. Para o caso de comandos de desligamento faz-se a nova velocidade de referência igual a zero e espera-se o motor parar. Quando a velocidade for igual a zero, o Timer_A e o Timer_B são parados, o driver do motor é desabilitado, é enviada uma confirmação de desligamento para o módulo local e abandona-se o laço para o estado do motor ligado. A velocidade atual é transmitida para o módulo local aproximadamente a cada 0,5 segundo. Essa escolha de frequência foi tomada para evitar o congestionamento do canal de comunicação com a interface gráfica. Dentro do fluxo de programa, a transmissão ocorre depois que o sinal de controle é aplicado ao motor. Como no caso do módulo local, ela é realizada pela função “SMPL_Send”. 5.4.2 Medição de velocidade Para a medição de velocidade utilizou-se o encoder de efeito Hall em quadratura de dois canais acoplado ao eixo no motor CC utilizado. Os canais do encoder passam por um circuito divisor de tensão antes de serem conectados às unidades de captura e comparação do MSP430F2274. A vantagem de se trabalhar com esse tipo de encoder é a possibilidade de, além de se medir a velocidade, detectar-se a variação do sentido de rotação. O método de medição de velocidade escolhido foi o método de medição combinada de frequência e período. 5.4.2.1 Circuito de interface do encoder O circuito de interface dos canais do encoder para os pinos das unidades de captura/comparação do MSP430F2274 é apenas um divisor de tensão. O encoder é alimentado com 12 V provenientes da mesma bateria que alimenta o motor CC. As saídas dos canais possuem a mesma tensão da alimentação. Portanto, para reduzir a tensão para a faixa de 2,4 – 3,3 V com que o microcontrolador (alimentado por 3 V) pode reconhecer um nível lógico alto, usa-se esse circuito. Assim, tem-se a relação V R2 C 0, 25 . R1 R2 Vencoder (5.1) 74 No entanto, a corrente consumida por cada canal do encoder deve ser mínima, para que não ocorra um afundamento de tensão. Assim, foram escolhidos os valores R1 = 100 kΩ e R2 = 33 kΩ. 5.4.2.2 Escolha do período de amostragem Para a escolha do período de amostragem levou-se em consideração valores usualmente utilizados no controle de motores CC. Foi necessário também lidar com as limitações da ferramenta eZ430-RF2500. Apesar de o MSP430F2274 possuir três canais de captura por temporizador, a eZ430-RF2500 tem pinos disponíveis apenas para dois canais de captura por temporizador. Além do mais, quando estes dois canais estão em uso não é possível utilizar o temporizador no modo crescente (conta até o valor de TACCR0), apenas no modo contínuo (conta até FFFFh), pois um destes canais é a unidade 0 de captura/comparação. Por isso, configurou-se o Timer_A no modo contínuo, com clock alimentado por SMCLK = 12 MHz e dividido por 2. Assim, um período completo do temporizador corresponde a 10,923 ms, que é o período de amostragem T. 5.4.2.3 Determinação do sentido de rotação Os encoders em quadratura possuem como saída nos seus canais ondas quadradas que variam de frequência de acordo com a velocidade do motor. A variação destas ondas, defasadas de 90° elétricos, apresentam sempre a mesma sequência de padrões entre seus pulsos para cada sentido de rotação. E estas sequências podem ser representadas pelo código Gray de dois bits. Assim, para a tabela verdade apresentada abaixo, pode-se estabelecer que no sentido horário o motor segue a sequência ...0, 1, 3, 2, 0, ... e para o sentido anti-horário segue a sequência ...0, 2, 3, 1, 0, ... Para que essas suposições estejam corretas, deve-se verificar no osciloscópio qual a sequência de canais do encoder é a correspondente ao sentido de rotação, mudando os canais nas entradas de captura quando necessário. 75 Tabela 5.1 – Código Gray com a definição dos canais do encoder e dos padrões. Canal B Canal A Padrão 0 0 0 0 1 1 1 1 3 1 0 2 Fonte: Próprio autor. Para determinar-se o sentido de rotação do motor de acordo com a sequência de padrões é necessário saber qual o padrão atual e qual o padrão anterior. Para esse fim, seria necessário uma tabela onde cada sequência de dois padrões correspondesse a uma direção. Uma forma mais simples de resolver esse problema é a implementação de um vetor onde cada elemento corresponde a um sentido de rotação para uma determinada sequência de dois padrões, podendo possuir alguns valores para sequências de padrões não permitidas e para casos em que a o padrão não mudou. Assim, o índice do elemento deste vetor correspondente a uma determinada sequência pode ser calculada por uma expressão matemática. O vetor de encoder em quadratura usado foi adaptado do vetor encontrado em Let’s Make Robots (2013), e é dado abaixo com sua expressão matemática para cálculo do índice. Vetor de Encoder em Quadratura[i] = {-1, 0, 1, -1, 1, -1, -1, 0, 0, -1, -1, 1, -1, 1, 0, -1}, i = 4x(padrão anterior) + padrão atual, (5.2) onde 0 corresponde ao sentido horário, 1 ao sentido anti-horário e -1 corresponde a estados não permitidos ou casos em que o padrão não mudou. No entanto, ainda é necessário determinar qual o padrão anterior quando o motor está parado e começa a se movimentar. É definido que de acordo com a velocidade de referência (positiva ou negativa) sabe-se se o motor inicia o movimento no sentido horário ou anti-horário. A unidade de captura deve ser configurada para ser ativada por transições de nível lógico, tanto de subida como de descida. Assim, de acordo com a leitura do nível lógico do pulso inicial em qualquer canal, observando a Tabela 5.1 pode-se obter o padrão atual e o anterior ao mesmo tempo. 76 5.4.2.4 Medição combinada de frequência e período O método escolhido para a medição de velocidade foi proposto por Faccio et al. (2004). Ele se baseia na medição tanto da frequência dos pulsos como no número de períodos entre dois pulsos (medição em baixas velocidades). A equação da velocidade angular é dada por N 2 Tsc Th1 Th N p (5.3) onde, Np é a resolução do encoder, Tsc é uma janela de observação básica, T sc é uma janela de observação estendida, N é o número de pulsos do encoder capturados dentro da janela de observação, Th é o período de tempo entre o final da janela de observação e quando o último pulso foi capturado dentro dela e Th-1 é seu equivalente para a janela de observação anterior. Assim, tem-se como variáveis para calcular a velocidade N, T sc , Th e Th-1. Na Figura 5.2 é possível observar melhor cada elemento da Equação 5.3. Figura 5.2 – Apresentação do método de medição combinada de frequência e período. Fonte: Adaptada de Faccio et al. (2004). O MSP430F2274 só realiza por hardware operações de soma e subtração de números inteiros. Desse modo, todos os cálculos envolvendo multiplicações e divisões são realizados por bibliotecas matemáticas via software. Além do mais, para uma melhor precisão, é necessária a utilização de variáveis de ponto flutuante. Tudo isso resulta em um custo computacional elevado. Assim, procura-se agrupar o máximo número possível de constantes dentro de cada expressão a ser calculada. 77 Outra questão que aparece é o fato de que a unidade de captura do Timer_A apenas conta o número de ciclos em que ocorreu a captura. A conversão em unidades de tempo deve ser realizada pela multiplicação com o período do temporizador. Além disso, como a velocidade nominal do motor CC é de 80 rpm ou 8,378 rad/s, para facilitar a transmissão ou recepção de valores desta ordem em bytes, multiplica-se a velocidade angular por 1000. Baseado nos fatos citados anteriormente, reescrevendo a Equação 5.3 tem-se 2 1000 N N T p hf , 1000 Csc Ch1 Ch (5.4) onde Thf é o período de cada ciclo do Timer_A, Csc é o total de ciclos da janela observável básica, C sc é a soma total de ciclos para uma janela observável estendida, Ch é a quantidade de ciclos quando ocorreu a captura do último pulso dentro da janela observável e Ch-1 é seu equivalente para a janela de observação anterior. O controle da velocidade do motor é realizado tanto com velocidades positivas (sentido horário) como negativas (sentido anti-horário). Assim para incluir o sinal na velocidade calculada estabelece-se que, para movimento no sentido horário, a quantidade de pulsos capturados é positiva e, no sentido anti-horário, ela é negativa. É necessário ainda contemplar o caso da reversão de velocidade. Neste caso, quando a velocidade está próxima de zero e o motor está prestes a mudar de sentido de rotação, dentro de uma janela observável ocorrem tanto pulsos positivos como negativos. Assim, pode-se obter a velocidade média dentro desta janela fazendo N ser calculado pela diferença entre a quantidade de pulsos positivos e negativos. 5.4.3 Controlador PI No capítulo 4 foi apresentado o controlador PI na forma incremental com realocação do ganho proporcional, suas expressões sendo dadas pelas Equações 4.67 e 4.68. Nesta seção, trata-se então da estimação dos parâmetros do modelo do motor e do cálculo dos parâmetros do controlador. É importante observar que o motor CC utilizado possui uma caixa de transmissão e que a velocidade com que se deve lidar é a do eixo da engrenagem de saída. Portanto, para 78 que todas as equações do controlador sejam válidas, é preciso calcular os parâmetros do motor com relação ao eixo de saída do motor. 5.4.3.1 Estimação dos parâmetros do modelo do motor CC Parâmetros como a constante do motor km, o momento de inércia J e atrito viscoso B não são fornecidos pelo fabricante do motor CC utilizado, portanto, precisam ser estimados. No modelo do subsistema mecânico considerado no capítulo 4 o único parâmetro a se determinar era o momento de inércia J, pois a componente do atrito viscoso B era incluída no torque de perturbação TL. No entanto, pelo método apresentado por Daher (2012), a estimação de J é dependente da estimação de B e de km. Os ensaios e cálculos realizados para se obter esses valores são descritos a seguir. Para a estimação da constante do motor km, primeiro mediu-se a resistência de armadura Ra = 2,2 Ω. com o motor a vazio e alimentado diretamente pela bateria, conectou-se um amperímetro em série com a alimentação, e mediu-se a corrente e a tensão da bateria. A corrente medida foi Ia = 310 mA e a tensão Vs = 13,04 V. Utilizando uma outra versão do programa apresentado aqui, em malha aberta alimentou-se o motor com um ciclo de trabalho de 100% e mediu-se sua velocidade angular em regime permanente. Obteve-se = 9,571 rad/s. Considerando que a tensão da bateria era a mesma no momento dos dois ensaios, calculou a constante do motor km pela Equação 5.5 (Daher, 2012). km Vs Ra I a . (5.5) O valor estimado foi km = 1,2901 V.s/rad. Para se obter o atrito viscoso B, seguiu-se a Equação 5.6 e utilizou-se os valores obtidos nos ensaios anteriores (Daher, 2012). B km I a . (5.6) Obteve-se B = 0,04179 N.m.s/rad. Para se estimar o momento de inércia J realizou-se o ensaio conhecido como rundown test. Para isso, alimenta-se o motor a vazio, em regime permanente interrompe-se a alimentação e mede-se o tempo que a velocidade levou para atingir 36,8% da velocidade de 79 regime permanente 0. Esse valor é a constante de tempo mecânica τm do motor e é dada pela Equação 5.7 (Daher, 2012). m J B (5.7) Utilizando o mesmo programa mencionado anteriormente realizou-se o rundown test, coletou-se as velocidades para cada período de amostragem até que o motor parasse e com o auxílio do MATLAB plotou-se o gráfico da velocidade. Obteve-se 0 = 9.567 rad/s, τm = 0,067 s. Portanto, J = 0,0028 kg.m2. 5.4.3.2 Determinação dos parâmetros do controlador De posse do momento de inércia J e do período de amostragem T = 10,923 ms, os parâmetros do controlador PI são calculados de acordo com as Equações 4.63 e 4.64 e são dados por KP = 0,10391 e (5.8) KI = 0,018004. (5.9) 5.4.3.3 Avaliação de desempenho do controlador por meio de simulação computacional Em Vukosavić (2007) pode ser encontrado um modelo em Simulink para o sistema de controle digital apresentado no capítulo 4. Adaptado dele, foi implementado um modelo em Simulink para o sistema de controle com os parâmetros encontrados. Na Figura 5.3 é mostrado o subsistema do controlador. Foram realizadas simulações para dois casos. Com o modelo do motor incluindo a componente de torque do atrito viscoso no torque de perturbação (Figura 5.4) e com a componente de torque do atrito viscoso incluída no modelo do motor (Figura 5.7). Isso foi feito com o intuito de mostrar as diferenças nos resultados das duas abordagens, visto que no projeto do controlador é levado em consideração apenas a primeira hipótese. 80 Figura 5.3 – Modelo em Simulink do Controlador PI digital incremental com realocação do ganho proporcional e estratégia anti-wind-up. Fonte: Próprio Autor. Figura 5.4 – Modelo em Simulink do sistema de controle de velocidade digital com a componente de torque do atrito viscoso incluída no torque de perturbação. Fonte: Próprio autor. Na primeira simulação aplicou-se ao sistema um degrau de 80 rpm ou 8,378 rad/s em t = 0 e, em t = 1 s, aplicou-se uma perturbação de 0,3 N.m. Os resultados para a resposta de velocidade e para o sinal de controle são apresentados na Figura 5.5. 81 Figura 5.5 – Resposta de velocidade e sinal de controle, incluindo a componente de torque do atrito viscoso no torque de perturbação, para um degrau de 80 rpm (8,378 rad/s) em t = 0 e para uma perturbação de 0,3 N.m em t = 1 s. Fonte: Próprio autor. 82 Correspondendo ao projeto do controlador, não houve sobressinal na resposta de velocidade. O tempo de assentamento com critério de 5% para a resposta ao degrau foi de Ts = 120,1 ms. O tempo de assentamento para a rejeição da perturbação foi de Ts = 125 ms. O sinal de controle é o torque eletromagnético de referência que deve ser desenvolvido pelo motor Td. Esse sinal é a saída do limitador de torque. O sinal de controle mostra que na resposta ao degrau de velocidade o torque a ser desenvolvido cresce até atingir o valor de Td = 0,3136 N.m e diminui até ficar em torno de zero em regime permanente. Para a rejeição de perturbação o torque a ser desenvolvido cresce até Td = 0,403 N.m e diminui para um valor em torno de 0,3 N.m em regime permanente. A segunda simulação tem o intuito de comprovar a eficácia da estratégia antiwind-up. Com o motor sem carga, o torque máximo TMAX foi ajustado para 0,05 N.m, em t = 0 foi aplicado um degrau de 80 rpm e em t = 1 s, realizou-se a reversão da velocidade para -80 rpm. A resposta da velocidade e o sinal de controle podem ser vistos na Figura 5.6. 83 Figura 5.6 – Resposta de velocidade em vazio e sinal de controle, incluindo a componente de torque do atrito viscoso no torque de perturbação, para um degrau de 80 rpm (8,378 rad/s) em t = 0 e um degrau de -80 rpm em t = 1 s, com o torque máximo TMAX = 0,05 N.m. Fonte: Próprio autor. 84 A resposta de velocidade mostra que não houve sobressinal mesmo com a saturação do sinal de controle. No entanto, devido ao valor constante que o torque a ser desenvolvido Td assume durante determinados momentos, a resposta tem uma inclinação constante durante esses períodos de tempo. Sempre após atingir a velocidade de referência, o torque de referência fica em torno de zero, pois não há torque de perturbação. O modelo em Simulink para o caso em que a componente de torque do atrito viscoso é incluída no modelo do motor é mostrado na Figura 5.7. Para este caso, foram realizadas simulações semelhantes às do caso anterior. Figura 5.7 – Modelo em Simulink do sistema de controle de velocidade digital com a componente de torque do atrito viscoso incluída no modelo do motor. Fonte: Próprio autor. Como no caso anterior, foi aplicado um degrau de 80 rpm em t = 0, e aplicado uma perturbação de 0,3 N.m em t = 1 s. A resposta de velocidade e o sinal de controle podem ser vistos na Figura 5.8. 85 Figura 5.8 – Resposta de velocidade e sinal de controle, incluindo a componente de torque do atrito viscoso no modelo do motor, para um degrau de 80 rpm (8,378 rad/s) em t = 0 e para uma perturbação de 0,3 N.m em t = 1 s. Fonte: Próprio autor. 86 Para a resposta de velocidade não ocorreu sobressinal e o tempo de assentamento da resposta ao degrau foi de Ts = 229,4 ms. Para a rejeição de perturbação Ts = 146,9 ms. Devido à inclusão do termo do atrito viscoso no modelo do motor, tanto na resposta ao degrau como na rejeição de perturbação, o sinal de controle cresce até um determinado valor e permanece em torno dele em regime permanente. Para a resposta ao degrau este valor é de Td = 0,3501 N.m e para a rejeição de perturbação é de Td = 0,6501 N.m. Na segunda simulação, com o motor a vazio, aplicou-se um degrau de 80 rpm em t = 0 e um degrau de -80 rpm em t = 1 s, com o torque máximo TMAX = 0,3 N.m. Os resultados para a resposta de velocidade e para o sinal de controle podem ser vistos na Figura 5.9. 87 Figura 5.9 – Resposta de velocidade em vazio e sinal de controle, incluindo a componente de torque do atrito viscoso no modelo do motor, para um degrau de 80 rpm (8,378 rad/s) em t = 0 e um degrau de -80 rpm em t = 1 s, com o torque máximo TMAX = 0,3 N.m. Fonte: Próprio autor. 88 Observando os resultados, nota-se que o torque a ser desenvolvido Td satura no seu valor máximo e permanece nele. O controlador não consegue fazer com que a velocidade atinja o seu valor de referência. Isso ocorre pois o valor máximo do torque TMAX = 0,3 N.m é menor do que o valor da componente de torque do atrito viscoso para a velocidade de referência TB = 0,3501 N.m. 5.4.4 Acionamento do motor CC Após o cálculo do sinal de controle é necessário ainda transformar esse sinal em um meio de acionamento do motor CC. Para realizar o acionamento escolheu-se o método PWM, utilizando um circuito de ponte H. A frequência do sinal PWM escolhida foi 10 kHz. 5.4.4.1 Circuito de acionamento do motor CC O circuito de acionamento do motor CC é o MC33926 Motor Driver Carrier desenvolvido pela Pololu Corporation. Ele utiliza uma ponte H e é baseado no circuito integrado MC33926 da Freescale Semiconductor. A corrente máxima que pode ser entregue continuamente é de aproximadamente 3 A, suportando picos de até 5 A. A conexão dele com a ferramenta eZ430-RF2500 é direta, pois o MC33926 trabalha com níveis lógicos entre 3 – 5 V. São necessárias três conexões entre o microcontrolador e a ponte H. O Pino de habilitação (EN) do MC33926 conecta-se à porta P4.6 do MSP430F2274. A habilitação da ponte H ocorre com nível lógico alto. O Pino de inversão (INV) do MC33926 conecta-se à porta P4.5 do MSP430F2274. A inversão do PWM é acionada com nível lógico alto. O Pino de entrada 1 (IN1) do MC33926 conecta-se ao pino da saída OUT1 da unidade de captura/comparação 1 do Timer_B do MSP430F2274. Para essa configuração a entrada (IN2) da ponte H deve permanecer sempre aterrada. Além dessas conexões são necessárias mais algumas configurações para o MC33926. É necessário conectar a alimentação do microcontrolador ao pino VDD do MC33926 Motor Driver Carrier. Depois, conecta-se jumpers entre os pinos D1 e GND e entre D2 e VDD. Para conectar os jumpers os pinos estão lado a lado. 89 5.4.4.2 Cálculo do número de ciclos do PWM O controlador apresentado calcula o torque de referência T* para um motor qualquer, desde que seja conhecido seu momento de inércia J e o período de amostragem T do sistema de controle. É necessário então tomar esse valor e calcular para um motor CC a referência do sinal que será aplicado ao circuito de acionamento. Para o sistema de controle proposto, esta referência é o número de ciclos do temporizador que correspondem ao ciclo de trabalho do sinal PWM, podendo ser obtida por CPWM DPWM CTB , (5.10) onde DPWM é o ciclo de trabalho do PWM, CTB é total de ciclos do temporizador e CPWM é quantidade de ciclos que correspondem ao ciclo de trabalho do PWM. CTB é um valor conhecido. Então o ciclo de trabalho do PWM é obtido por DPWM Vs* , Vn (5.11) onde Vs* é a tensão de referência que deve ser aplicada ao motor CC e Vn é a tensão nominal do motor e é um valor conhecido. A tensão de referência Vs* pode ser obtida através da Equação 2.14, sendo reescrita da forma Vs* km * Ra * T , km (5.12) onde * é a velocidade de referência. Baseado nas Equações 5.11 e 5.12 pode-se reformular a Equação 5.10 da seguinte forma: k C RaCTB CPWM * 1000 m TB T * 1000 . 1000 Vn 1000 kmVn (5.13) Deve-se lembrar que os valores de velocidade e torque são multiplicados por 1000. 5.5 Resultados Experimentais Aqui são mostrados resultados de respostas ao degrau para duas situações. A primeira, com a bateria totalmente carregada e a segunda com a bateria descarregada. A resposta obtida com o controlador implementado é comparada com a resposta de simulação para o modelo em Simulink da Figura 5.7, onde a componente de torque do atrito viscoso é 90 incluída no modelo do motor. Este modelo para a simulação foi escolhido pois não se pode quantificar com certeza a soma das componentes parasitas do torque de perturbação para o modelo da Figura 5.4, onde a componente de torque do atrito viscoso é incluída na perturbação. Com a bateria carregada, a sua tensão medida no momento dos experimentos foi 13,6 V. A Figura 5.10 mostra os resultados para uma resposta ao degrau de 80 rpm ou 8,378 rad/s. 91 Figura 5.10 – Resposta ao degrau de velocidade de 80 rpm (8,378 rad/s) e sinal de controle da simulação, com a tensão da bateria de 13,6 V. Fonte: Próprio autor. 92 Para a simulação não houve sobressinal e o tempo de assentamento com critério de 5 % foi de Ts = 229,32 ms. Na resposta experimental, o tempo de assentamento foi de Ts = 163,8 ms e ocorreu sobressinal de OS% = 1,66 %. Ainda com a bateria carregada, a Figura 5.11 mostra os resultados para uma reversão de velocidade de 80 rpm para -80 rpm. 93 Figura 5.11 – Resposta ao degrau de velocidade de 80 rpm para -80 rpm e sinal de controle da simulação, com a tensão da bateria de 13,6 V. Fonte: Próprio autor. 94 Na simulação não ocorreu sobressinal e o tempo de assentamento foi de Ts = 283,92 ms. Para o experimento, obteve-se um tempo de assentamento de Ts = 185,64 ms e ocorreu sobressinal de OS% = 3,14 %. O que se pode perceber dos resultados experimentais é que a sua resposta é sempre mais rápida do que a da simulação e que sempre ocorreu sobressinal. Este sobressinal se deve, provavelmente, ao valor da tensão de alimentação do sistema de controle maior do que a tensão nominal, que é considerada no cálculo do sinal de controle (ciclos do PWM). Com a bateria descarregada, a sua tensão medida foi de 10,7 V. A Figura 5.12 mostra os resultados para uma resposta ao degrau de 70 rpm ou 7,33 rad/s. 95 Figura 5.12 – Resposta ao degrau de velocidade de 70 rpm (7,33 rad/s) e sinal de controle da simulação, com a tensão da bateria de 10,7 V. Fonte: Próprio autor. 96 Não houve sobressinal em nenhuma das respostas. Para a simulação, o tempo de assentamento foi de Ts = 218,4 ms. Para o experimento, obteve-se Ts = 524,16 ms. Na segunda resposta ao degrau, fez-se uma reversão de velocidade de 70 rpm para -70 rpm. Os resultados são mostrados na Figura 5.13. 97 Figura 5.13 – Resposta ao degrau de velocidade de 70 rpm para -70 rpm e sinal de controle da simulação, com tensão da bateria de 10,7 V. Fonte: Próprio autor. 98 Não ocorreu sobressinal para nenhuma das respostas. Para a simulação o tempo de assentamento foi de Ts = 283,92 ms. Para o experimento, o tempo de assentamento foi de Ts = 764,4 ms. Com a bateria descarregada, pode-se perceber que, não ocorre sobressinal e que a resposta do experimento é sempre mais lenta do que a resposta simulada. No entanto, a presença da ação integral do controlador faz com que a referência ainda seja atingida. 99 6 CONCLUSÃO Como é comum em todas as baterias, ocorreu a variação dos valores de tensão de acordo com o seu carregamento (13,6 V carregada e 10,7 V descarregada). No entanto, mesmo com essas variações o sistema de controle digital conseguiu manter a velocidade de referência. A exceção ocorreu apenas com a bateria descarregada, quando a velocidade máxima alcançada foi de aproximadamente 76 rpm. O circuito completo que realiza as conexões entre microcontrolador e driver do motor e entre microcontrolador e encoder se mostrou muito simples para esse caso. O driver foi facilmente configurado através de jumpers e conexões com a tensão de alimentação do módulo remoto e com o terra do circuito. Adicionalmente, as conexões com o microcontrolador foram diretas. O MSP430F2274 apresentou fácil configuração e operação tanto para o módulo local como para o remoto. Trabalhando com um clock de 12 MHz apenas, ele apresentou desempenho satisfatório com comunicação serial, gerenciamento de comunicação sem fio, operações de captura e comparação através dos temporizadores e operações matemáticas de ponto flutuante via software. O único problema apresentado se deu com algumas poucas amostras do número de ciclos representando o momento da captura. Esse problema foi contornado limitando-se o número de ciclos do último pulso dentro de uma janela observável em 64000. Valores menores que esses eram considerados errôneos e era atribuído ao número de ciclos um valor de 65536, a borda de uma janela observável básica. O protocolo SimpliciTI, para a comunicação peer-to-peer, se apresentou simples de configurar e de se operar. Não houve problemas relacionados com seu uso e, em testes realizados, sempre todos os dados enviados entre os módulos local e remoto não se perderam. A utilização de um motor CC com caixa de engrenagens aparentemente afetaria muito as equações do sistema de controle e da medição da velocidade. Mas foi observado que a condição necessária para que as equações permaneçam válidas é que todas as estimações de parâmetros e cálculos sejam efetuados com relação a valores relacionados com o eixo de saída da caixa de engrenagens. As simulações realizadas em Simulink/MATLAB mostraram o comportamento do modelo do sistema de controle para condições a vazio, com carga e com saturação do torque de referência. Foram contempladas situações tanto com a inclusão da componente de torque de atrito viscoso no torque de perturbação como com o atrito viscoso incluído no modelo do 100 motor. A suposição feita no primeiro caso é que que a componente do atrito viscoso é descasada da dinâmica interna do sistema mecânico do motor. Os resultados experimentais comparados com os resultados de simulação mostraram o desempenho do controlador para respostas ao degrau quando a bateria está completamente carregada e quando está descarregada. Foi possível observar certas diferenças entre os resultados experimentais e simulados para cada caso. Com a bateria carregada a resposta experimental sempre é mais rápida, mas ocorre a presença de um pequeno sobressinal. Com a bateria descarregada não ocorre sobressinal e o sistema atinge a velocidade de referência, no entanto, a resposta experimental é bem mais lenta. Como trabalhos futuros, considera-se a implementação de uma interface gráfica em MATLAB. Isso possibilitaria o desenvolvimento mais simples de métodos de estimação dos parâmetros do motor baseados em respostas ao degrau e de métodos de auto-ajuste do controlador para diferentes tipos de carga. 101 REFERÊNCIAS CHAPMAN, Stephen J. Electric Machinery Fundamentals. 4. ed. New York: McGrawHill, 2005. DAHER, Sérgio. Disciplina de Máquinas Elétricas. Roteiro de Laboratório 6. Fortaleza, 2012. DAVIES, John H. MSP430 Microcontroller Basics. Burlington: Newnes, 2008. DORF, Richard C.; BISHOP, Robert H. Modern Control Systems. 12. ed. Upper Saddle River: Prentice Hall, 2011. FACCIO, Marco; GRANDE, Paolo; PARASILITI, Francesco; PETRELLA, Roberto; TURSINI, Marco. An Embedded System for Position and Speed Measurement Adopting Incremental Encoders. In: INDUSTRY APPLICATIONS CONFERENCE, 2004. 39TH IAS ANNUAL MEETING, 2004. Conference Record of the 2004 IEEE (Volume: 2). p. 1192 – 1199. FADALI, M. Sam. Digital Control Engineering. Burlington: Academic Press, 2009. FITZGERALD, A. E.; KINGSLEY, Charles; UMANS, Stephen D. Electric Machinery. 6. ed. New York: McGraw-Hill, 2003. GURU, Bhag S.; HIZIROGLU, Hüseyin R. Electric Machinery and Transformers. 3. ed. New York: Oxford University Press, 2001. GOLNARAGHI, Farid; KUO, Benjamin C. Automatic Control Systems. 9. ed. Hoboken: John Wiley & Sons, Inc., 2010. HAISHUI, Zhu; DAHU, Wang; TONG, Zhang; KEMING, Huang. Design on a DC Motor Speed Control. In: 2010 International Conference on Intelligent Computation Technology and Automation (ICICTA), 2010, Changsha. Record (Volume: 2). p. 59 – 63. HENRY POON'S BLOG. Serial Communication in Java with Example Program. Disponível em: <henrypoon.wordpress.com/2011/01/01/serial-communication-in-java-withexample-program/>. Acesso em: 4 out. 2013. HUGHES, Austin. Electric Motors and Drives: Fundamentals, Types and Applications. 3. ed. Oxford: Newnes, 2006. LET’S MAKE ROBOTS. How to use a quadrature encoder. Disponível em: <letsmakerobots.com/node/24031>. Acesso em: 7 nov. 2013. LIN, A. K.; KOEPSEL, W.W. A Microprocessor Speed Control System. IEEE Transactions on Industrial Electronics and Control Instrumentation, v. IECI-24, n. 3, ago. 1977. NISE, Norman S. Control Systems Engineering. 6. ed. Hoboken: John Wiley & Sons, Inc., 2011. 102 OGATA, Katsuhiko. Modern Control Engineering. 5. ed. Upper Saddle River: Prentice Hall, 2010. TEXAS INSTRUMENTS. MSP430x2xx Family User's Guide (Rev. J). Disponível em: <http://www.ti.com/lit/ug/slau144j/slau144j.pdf>. Acesso em: 11 jul. 2013a. TEXAS INSTRUMENTS. MSP430F22x2, MSP430F22x4 Mixed Signal Microcontroller (Rev. G). Disponível em: <http://www.ti.com/lit/ds/slas504g/slas504g.pdf>. Acesso em: 12 jul. 2013b. TEXAS INSTRUMENTS. TI E2E Community. Exemplo de Programa. Disponível em: <http://e2e.ti.com/cfs-file.ashx/__key/communityserver-discussions-componentsfiles/156/8080.SMPL_5F00_PeerToPeer_5F00_Ori.zip>. Acesso em: 13 jul. 2013c. VUKOSAVIĆ, Slobodan N. Digital Control of Electrical Drives. New York: Springer, 2007. WANG, H. C.; CHEN, J. N. A microcomputer-based digital system for DC motor speed control. In: 1979 Symposium on Automatic Control, 1979. Proceedings. WILDI, Theodore. Electrical Machines, Drives, and Power Systems. 5. ed. Upper Saddle River: Prentice Hall, 2002. 103 APÊNDICE A – CÓDIGOS FONTE CÓDIGOS FONTE DA INTERFACE GRÁFICA EM JAVA BlueSkyGUI.java package my.bluesky; import java.awt.Color; /** * * @author Rene Descartes Olimpio Pereira */ public class BlueSkyGUI extends javax.swing.JFrame { SerialCommunication serialCommunication = null; KeyBinding keyBinding = null; double pi = 3.14159, SamplePeriod = 0.01092267, SecondsStepTime = 0; long omega, LongInitialOmegax1000, LongFinalOmegax1000; int RpmSpeed, refOmega, InitialRpmSpeed, FinalRpmSpeed, InitialOmegax1000, FinalOmegax1000, StepResponseSamples, MilisecondsStepTime; private final static int TURN_OFF = 1, SEND_REF_OMEGA = 2, STEP_RESPONSE = 5; private String statusText = ""; public BlueSkyGUI() { initComponents(); createObjects(); serialCommunication.searchForPorts(); keyBinding.toggleControls(); } private void createObjects() { serialCommunication = new SerialCommunication(this); keyBinding = new KeyBinding(this); } /** * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jPanel1 = new javax.swing.JPanel(); 104 Portas = new javax.swing.JComboBox(); jLabel1 = new javax.swing.JLabel(); Conectar = new javax.swing.JButton(); Desconectar = new javax.swing.JButton(); VelocidadeRef = new javax.swing.JSpinner(); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); jLabel5 = new javax.swing.JLabel(); VelocidadeAtual = new javax.swing.JTextField(); Enviar = new javax.swing.JButton(); jScrollPane1 = new javax.swing.JScrollPane(); Status = new javax.swing.JTextArea(); Desligar = new javax.swing.JButton(); Fechar = new javax.swing.JButton(); jLabel6 = new javax.swing.JLabel(); InitialStepSpeed = new javax.swing.JSpinner(); jLabel8 = new javax.swing.JLabel(); jLabel9 = new javax.swing.JLabel(); FinalStepSpeed = new javax.swing.JSpinner(); jLabel10 = new javax.swing.JLabel(); jLabel11 = new javax.swing.JLabel(); StepResponseStart = new javax.swing.JButton(); OmegaOption = new javax.swing.JRadioButton(); jSeparator1 = new javax.swing.JSeparator(); jLabel13 = new javax.swing.JLabel(); StepTime = new javax.swing.JSpinner(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jPanel1.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED)); jLabel1.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel1.setText("Porta Serial:"); Conectar.setText("Conectar"); Conectar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { ConectarActionPerformed(evt); } }); Desconectar.setText("Desconectar"); Desconectar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { DesconectarActionPerformed(evt); } }); 105 VelocidadeRef.setModel(new javax.swing.SpinnerNumberModel(0, -80, 80, 1)); VelocidadeRef.setEditor(new javax.swing.JSpinner.NumberEditor(VelocidadeRef, "")); jLabel2.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel2.setText("Velocidade de"); jLabel3.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel3.setText("Referência (rpm):"); jLabel4.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel4.setText("Velocidade"); jLabel5.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel5.setText("Atual (rpm):"); VelocidadeAtual.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N VelocidadeAtual.setHorizontalAlignment(javax.swing.JTextField.CENTER); Enviar.setText("Enviar"); Enviar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { EnviarActionPerformed(evt); } }); Status.setColumns(20); Status.setRows(5); jScrollPane1.setViewportView(Status); Desligar.setText("Desligar"); Desligar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { DesligarActionPerformed(evt); } }); Fechar.setText("Fechar"); Fechar.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { FecharActionPerformed(evt); } }); jLabel6.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel6.setText("Resposta ao Degrau"); InitialStepSpeed.setModel(new javax.swing.SpinnerNumberModel(0, -80, 80, 1)); InitialStepSpeed.setEditor(new javax.swing.JSpinner.NumberEditor(InitialStepSpeed, "")); 106 jLabel8.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel8.setText("Velocidade"); jLabel9.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel9.setText("Inicial (rpm):"); FinalStepSpeed.setModel(new javax.swing.SpinnerNumberModel(0, -80, 80, 1)); FinalStepSpeed.setEditor(new javax.swing.JSpinner.NumberEditor(FinalStepSpeed, "")); jLabel10.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel10.setText("Velocidade"); jLabel11.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel11.setText("Final (rpm):"); StepResponseStart.setText("Iniciar"); StepResponseStart.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { StepResponseStartActionPerformed(evt); } }); OmegaOption.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N OmegaOption.setText("Salvar velocidade em rad/s"); jLabel13.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N jLabel13.setText("Duração (seg):"); StepTime.setModel(new javax.swing.SpinnerNumberModel(0.1d, 0.1d, 10.0d, 0.1d)); StepTime.setEditor(new javax.swing.JSpinner.NumberEditor(StepTime, "0.0")); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(jPanel1Layout.createSequentialGroup() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(91, 91, 91) .addComponent(Desligar) .addGap(109, 109, 109) .addComponent(Fechar, javax.swing.GroupLayout.PREFERRED_SIZE, 74, javax.swing.GroupLayout.PREFERRED_SIZE)) 107 .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) .addGap(0, 0, Short.MAX_VALUE)) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() 405, .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(VelocidadeAtual, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))) .addGroup(jPanel1Layout.createSequentialGroup() 75, .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILI NG, false) .addComponent(Portas, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(Conectar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(86, 86, 86) .addComponent(Desconectar)) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(1, 1, 1) .addComponent(jLabel11) 100, 108 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(FinalStepSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(OmegaOption) .addGap(0, 0, Short.MAX_VALUE)) .addGroup(jPanel1Layout.createSequentialGroup() 75, .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILI NG) .addComponent(jLabel6) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(VelocidadeRef, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(6, 6, 6) .addComponent(Enviar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(jPanel1Layout.createSequentialGroup() 75, 63, .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADI NG, false) .addComponent(jLabel9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(InitialStepSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(16, 16, 16) .addComponent(jLabel13, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(jLabel10))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) 75, 84, 109 .addComponent(StepTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) 75, .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(StepResponseStart, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))) .addContainerGap()) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(10, 10, 10) .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELI NE) .addComponent(Portas, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(Conectar) .addComponent(Desconectar)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELI NE) .addComponent(jLabel2) .addComponent(jLabel4)) .addGap(1, 1, 1) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELI NE) .addComponent(jLabel3) .addComponent(VelocidadeRef, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel5) .addComponent(VelocidadeAtual, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(Enviar)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel8) 110 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELI NE) .addComponent(jLabel9) .addComponent(InitialStepSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(StepResponseStart) .addComponent(jLabel13) .addComponent(StepTime, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel10) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELI NE) .addComponent(jLabel11) .addComponent(FinalStepSpeed, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(OmegaOption)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 132, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELI NE) .addComponent(Desligar) .addComponent(Fechar)) .addContainerGap()) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addContainerGap() 111 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addContainerGap()) ); pack(); }// </editor-fold> private void ConectarActionPerformed(java.awt.event.ActionEvent evt) { serialCommunication.connect(); if (serialCommunication.getConnected() == true) { if (serialCommunication.initIOStream() == true) { serialCommunication.initListener(); } } } private void EnviarActionPerformed(java.awt.event.ActionEvent evt) { RpmSpeed = (int)VelocidadeRef.getValue(); omega = Math.round(2*pi*RpmSpeed*1000/60); refOmega = (int)omega; serialCommunication.writeData(SEND_REF_OMEGA, refOmega); } private void DesconectarActionPerformed(java.awt.event.ActionEvent evt) { serialCommunication.disconnect(); } private void DesligarActionPerformed(java.awt.event.ActionEvent evt) { serialCommunication.writeData(TURN_OFF, 0); } private void FecharActionPerformed(java.awt.event.ActionEvent evt) { serialCommunication.disconnect(); System.exit(0); } private void StepResponseStartActionPerformed(java.awt.event.ActionEvent evt) { InitialRpmSpeed = (int)InitialStepSpeed.getValue(); LongInitialOmegax1000 = Math.round(2*pi*InitialRpmSpeed*1000/60); InitialOmegax1000 = (int)LongInitialOmegax1000; FinalRpmSpeed = (int)FinalStepSpeed.getValue(); LongFinalOmegax1000 = Math.round(2*pi*FinalRpmSpeed*1000/60); FinalOmegax1000 = (int)LongFinalOmegax1000; SecondsStepTime = (double)StepTime.getValue(); StepResponseSamples = (int)Math.ceil(SecondsStepTime/SamplePeriod); 112 if ((!serialCommunication.TurnedOff) || (InitialOmegax1000 != 0)) { serialCommunication.writeData(SEND_REF_OMEGA, InitialOmegax1000); try { Thread.sleep(2500); } catch(InterruptedException e) { statusText = "Falha em sleep. (" + e.toString() + ")"; Status.setForeground(Color.red); Status.append(statusText + "\n"); } } serialCommunication.writeData(STEP_RESPONSE, StepResponseSamples); try { Thread.sleep(500); } catch(InterruptedException e) { statusText = "Falha em sleep. (" + e.toString() + ")"; Status.setForeground(Color.red); Status.append(statusText + "\n"); } serialCommunication.writeData(SEND_REF_OMEGA, FinalOmegax1000); if (OmegaOption.isSelected()) serialCommunication.OmegaOption = true; serialCommunication.StepResponse = true; } /** * @param args the command line arguments */ public static void main(String args[]) { /* Set the Nimbus look and feel */ //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) "> /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel. * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html */ try { for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) { if ("Nimbus".equals(info.getName())) { javax.swing.UIManager.setLookAndFeel(info.getClassName()); break; } } } catch (ClassNotFoundException ex) { 113 java.util.logging.Logger.getLogger(BlueSkyGUI.class.getName()).log(java.util.logging.Level .SEVERE, null, ex); } catch (InstantiationException ex) { java.util.logging.Logger.getLogger(BlueSkyGUI.class.getName()).log(java.util.logging.Level .SEVERE, null, ex); } catch (IllegalAccessException ex) { java.util.logging.Logger.getLogger(BlueSkyGUI.class.getName()).log(java.util.logging.Level .SEVERE, null, ex); } catch (javax.swing.UnsupportedLookAndFeelException ex) { java.util.logging.Logger.getLogger(BlueSkyGUI.class.getName()).log(java.util.logging.Level .SEVERE, null, ex); } //</editor-fold> /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new BlueSkyGUI().setVisible(true); } }); } // Variables declaration - do not modify public javax.swing.JButton Conectar; public javax.swing.JButton Desconectar; public javax.swing.JButton Desligar; public javax.swing.JButton Enviar; private javax.swing.JButton Fechar; public javax.swing.JSpinner FinalStepSpeed; public javax.swing.JSpinner InitialStepSpeed; public javax.swing.JRadioButton OmegaOption; public javax.swing.JComboBox Portas; public javax.swing.JTextArea Status; public javax.swing.JButton StepResponseStart; public javax.swing.JSpinner StepTime; public javax.swing.JTextField VelocidadeAtual; public javax.swing.JSpinner VelocidadeRef; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel10; private javax.swing.JLabel jLabel11; private javax.swing.JLabel jLabel13; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; private javax.swing.JLabel jLabel5; private javax.swing.JLabel jLabel6; private javax.swing.JLabel jLabel8; 114 private javax.swing.JLabel jLabel9; private javax.swing.JPanel jPanel1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JSeparator jSeparator1; // End of variables declaration } SerialCommunication.java package my.bluesky; import gnu.io.*; import java.io.*; import java.awt.Color; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Enumeration; import java.util.HashMap; import java.util.Locale; import java.util.TooManyListenersException; import java.util.Date; import java.text.DateFormat; import java.text.SimpleDateFormat; /** * * @author Rene Descartes Olimpio Pereira */ public class SerialCommunication implements SerialPortEventListener{ //passed from main GUI BlueSkyGUI window = null; private Enumeration ports = null; private final HashMap portMap = new HashMap(); private CommPortIdentifier selectedPortIdentifier = null; private SerialPort serialPort = null; private InputStream input = null; private OutputStream output = null; public static final int TIME_OUT = 2000; public static final int DATA_RATE = 9600; private boolean bConnected = false, bLinked = false; public boolean TurnedOff = true, StepResponse = false, OmegaOption = false; 115 volatile int i = 0, CurrentSpeedCount = 0, RpmSpeedTextCount = 0; short CurrentOmegax1000 = 0; double pi = 3.14159, CurrentRpmSpeed = 0, FloatCurrentOmegax1000 = 0, FloatCurrentOmega = 0; final static char TURN_OFF = 1, SEND_REF_OMEGA = 2, RECEIVE_CURRENT_OMEGA = 3, LINKED = 4, STEP_RESPONSE = 5, STEP_RESPONSE_END = 6, END_OF_MESSAGE = 170; byte[] SendMsg = new byte[2]; char[] ReceptionMsg = new char[4]; String StatusText = ""; String RpmSpeedText = ""; String OmegaText = ""; String FilePath = ""; String FileName = ""; StringBuffer FileData = new StringBuffer(""); public SerialCommunication(BlueSkyGUI window) { this.window = window; } public void searchForPorts() { ports = CommPortIdentifier.getPortIdentifiers(); while (ports.hasMoreElements()) { CommPortIdentifier currPort = (CommPortIdentifier)ports.nextElement(); if (currPort.getPortType() == CommPortIdentifier.PORT_SERIAL) { window.Portas.addItem(currPort.getName()); portMap.put(currPort.getName(), currPort); } } } public void connect() { String selectedPort = (String)window.Portas.getSelectedItem(); selectedPortIdentifier = (CommPortIdentifier)portMap.get(selectedPort); try { serialPort = (SerialPort)selectedPortIdentifier.open(this.getClass().getName(), TIME_OUT); serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8, 116 SerialPort.STOPBITS_1, SerialPort.PARITY_NONE); setConnected(true); StatusText = selectedPort + " aberta com sucesso."; window.Status.setForeground(Color.black); window.Status.append(StatusText + "\n"); window.keyBinding.toggleControls(); } catch (PortInUseException e) { StatusText = selectedPort + " está em uso. (" + e.toString() + ")"; window.Status.setForeground(Color.RED); window.Status.append(StatusText + "\n"); } catch (Exception e) { StatusText = "Falha ao abrir " + selectedPort + "(" + e.toString() + ")"; window.Status.append(StatusText + "\n"); window.Status.setForeground(Color.RED); } } public boolean initIOStream() { boolean successful = false; try { input = serialPort.getInputStream(); output = serialPort.getOutputStream(); successful = true; return successful; } catch (IOException e) { StatusText = "I/O Streams falhou ao abrir. (" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); return successful; } } public void initListener() { try { serialPort.addEventListener(this); serialPort.notifyOnDataAvailable(true); 117 } catch (TooManyListenersException e) { StatusText = "Muitos listeners. (" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); } } public void disconnect() { try { writeData(TURN_OFF, 0); try { Thread.sleep(3000); } catch(InterruptedException e) { StatusText = "Falha em sleep. (" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); } serialPort.removeEventListener(); serialPort.close(); input.close(); output.close(); setConnected(false); window.keyBinding.toggleControls(); StatusText = "Desconectado."; window.Status.append(StatusText + "\n"); } catch (IOException e) { StatusText = "Falha ao fechar " + serialPort.getName() + "(" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); } } final public boolean getConnected() { return bConnected; } public void setConnected(boolean bConnected) { this.bConnected = bConnected; 118 } final public boolean getLinked() { return bLinked; } public void setLinked(boolean bLinked) { this.bLinked = bLinked; } public void serialEvent(SerialPortEvent evt) { if (evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) { try { ReceptionMsg[i] = (char)input.read(); if ((ReceptionMsg[0] == LINKED) && (char)END_OF_MESSAGE)) { setLinked(true); StatusText = "Comunicação sem fio estabelecida."; window.Status.append(StatusText + "\n"); window.keyBinding.toggleControls2(); ReceptionMsg[1] = 0; i = -1; } (ReceptionMsg[1] == if ((ReceptionMsg[0] == TURN_OFF) (char)END_OF_MESSAGE)) { TurnedOff = true; StatusText = "Motor desligado."; window.Status.append(StatusText + "\n"); ReceptionMsg[1] = 0; i = -1; } (ReceptionMsg[1] == && if ((ReceptionMsg[0] == RECEIVE_CURRENT_OMEGA) && (ReceptionMsg[3] == (char)END_OF_MESSAGE)) { if (StepResponse) { window.VelocidadeAtual.setText(""); CurrentOmegax1000 = (short)((ReceptionMsg[1] << 8) | ReceptionMsg[2]); if (OmegaOption) { FloatCurrentOmegax1000 = (double)CurrentOmegax1000; 119 FloatCurrentOmega = FloatCurrentOmegax1000/1000; OmegaText = String.format(Locale.US, "%.4f%n", FloatCurrentOmega); FileData.append(OmegaText); } else { CurrentRpmSpeed = (double)(CurrentOmegax1000*60/(2*pi*1000)); RpmSpeedText = String.format(Locale.US, "%.4f%n", CurrentRpmSpeed); FileData.append(RpmSpeedText); } } else { CurrentOmegax1000 = (short)((ReceptionMsg[1] << 8) | ReceptionMsg[2]); CurrentRpmSpeed = (double)(CurrentOmegax1000*60/(2*pi*1000)); RpmSpeedText = String.format("%.2f", CurrentRpmSpeed); window.VelocidadeAtual.setText(RpmSpeedText); } ReceptionMsg[3] = 0; i = -1; } if ((ReceptionMsg[0] == STEP_RESPONSE_END) && (ReceptionMsg[1] == (char)END_OF_MESSAGE)) { StepResponse = false; OmegaOption = false; createFile(); writeToFile(); StatusText = "Final de resposta ao degrau."; window.Status.append(StatusText + "\n"); ReceptionMsg[1] = 0; i = -1; } i++; } catch (IOException e) { StatusText = "Falha ao ler dados. (" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); } } } public synchronized void writeData(int comando, int Data) { try { 120 if ((comando == TURN_OFF) || (comando == SEND_REF_OMEGA && Data == 0)) { output.write((byte)1); output.flush(); output.write((byte)END_OF_MESSAGE); output.flush(); TurnedOff = true; } if (comando == SEND_REF_OMEGA && Data != 0) { SendMsg[0] = (byte)(Data >> 8); SendMsg[1] = (byte)Data; output.write((byte)2); output.flush(); output.write(SendMsg[0]); output.flush(); output.write(SendMsg[1]); output.flush(); //this is a delimiter for the data output.write((byte)END_OF_MESSAGE); output.flush(); TurnedOff = false; } if (comando == STEP_RESPONSE) { SendMsg[0] = (byte)(Data >> 8); SendMsg[1] = (byte)Data; output.write((byte)5); output.flush(); output.write(SendMsg[0]); output.flush(); output.write(SendMsg[1]); output.flush(); //this is a delimiter for the data output.write((byte)END_OF_MESSAGE); output.flush(); } } catch (Exception e) { StatusText = "Falha ao gravar dados. (" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); } } public void createFile() 121 { DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy_HH-mm-ss"); Date date = new Date(); String FileTime = dateFormat.format(date); FilePath = "C:"+File.separator+"BlueSky"; //(use relative path for Unix systems) FileName = FilePath+File.separator+"StepResponse_"+FileTime+".txt"; File p = new File(FilePath); File f = new File(FileName); //(works for both Windows and Linux) p.mkdirs(); try { f.createNewFile(); } catch (IOException e) { StatusText = "Falha ao criar arquivo. (" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); } } public void writeToFile() { try { FileWriter objFileWriter = new FileWriter(FileName); BufferedWriter objBufferedWriter = new BufferedWriter(objFileWriter); try { objBufferedWriter.write(FileData.toString()); try { objBufferedWriter.flush(); try { objBufferedWriter.close(); } catch (IOException e) { StatusText = "Falha ao fechar arquivo. (" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); } } catch (IOException e) { StatusText = "Falha ao realizar flush. (" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); } } catch (IOException e) { StatusText = "Falha ao escrever dados no arquivo. (" + e.toString() + ")"; window.Status.setForeground(Color.red); 122 window.Status.append(StatusText + "\n"); } } catch (IOException e) { StatusText = "Falha ao abrir arquivo. (" + e.toString() + ")"; window.Status.setForeground(Color.red); window.Status.append(StatusText + "\n"); } FileData.setLength(0); } } KeyBinding.java package my.bluesky; /** * * @author Rene Descartes Olimpio Pereira */ public class KeyBinding { BlueSkyGUI window = null; public KeyBinding(BlueSkyGUI window) { this.window = window; } public void toggleControls() { if (window.serialCommunication.getConnected() == true) { window.Desconectar.setEnabled(true); window.Conectar.setEnabled(false); window.Portas.setEnabled(false); } else { window.Enviar.setEnabled(false); window.Desligar.setEnabled(false); window.VelocidadeRef.setEnabled(false); window.VelocidadeAtual.setEnabled(false); window.Desconectar.setEnabled(false); window.InitialStepSpeed.setEnabled(false); window.FinalStepSpeed.setEnabled(false); window.StepTime.setEnabled(false); window.OmegaOption.setEnabled(false); window.StepResponseStart.setEnabled(false); 123 window.Conectar.setEnabled(true); window.Portas.setEnabled(true); } } public void toggleControls2() { if (window.serialCommunication.getLinked() == true) { window.Enviar.setEnabled(true); window.Desligar.setEnabled(true); window.VelocidadeRef.setEnabled(true); window.VelocidadeAtual.setEnabled(true); window.InitialStepSpeed.setEnabled(true); window.FinalStepSpeed.setEnabled(true); window.StepTime.setEnabled(true); window.OmegaOption.setEnabled(true); window.StepResponseStart.setEnabled(true); } } } PRINCIPAIS CÓDIGOS FONTE DOS MÓLULOS LOCAL E REMOTO main_LinkTo.c /*---------------------------------------------------------------------------* Local Module Program * * Rene Descartes Olimpio Pereira *---------------------------------------------------------------------------- */ #include "bsp.h" #include "mrfi.h" #include "nwk_types.h" #include "nwk_api.h" #include "bsp_leds.h" #include "bsp_buttons.h" #include "app_remap_led.h" #include "stdbool.h" #define SPIN_ABOUT_A_SECOND NWK_DELAY(1000) static _Bool TurnOffCommand = false, TurnOffCommandOK = false, NewRefOmega = false, NewCurrentOmega = false, StepResponse = false, StepResponseEnd = false; 124 static volatile uint8_t TXcount = 0, RXcount = 0; static uint8_t TX_MESSAGE_LENGTH = 0, TXdata[4], RXdata[4], CurrentOmega[2], SendData[3]; static linkID_t sLinkID1 = 0; const uint8_t TURN_OFF = 1, RECEIVE_REF_OMEGA = 2, SEND_REF_OMEGA = 2, SEND_CURRENT_OMEGA = 3, LINKED = 4, STEP_RESPONSE = 5, STEP_RESPONSE_END = 6, END_OF_MESSAGE = 170; const addr_t linkToAddr = {'L', 'I', 'T', 'O'}; void toggleLED(uint8_t); void writeData(uint8_t, uint8_t, uint8_t); /* application Rx frame handler. */ static uint8_t sRxCallback(linkID_t); void main (void) { BSP_Init(); P3SEL |= BIT4 | BIT5; // P3.4 - P3.5 used by USCI_A. // Defaults: no parity , lsb first , 8-bit data , 1 stop bit , UART , async. UCA0CTL1 |= UCSSEL_2 | UCSWRST; // Clock: SMCLK; hold in reset. // 9600 baud from 12Mhz. UCA0BR0 = 0xE2; UCA0BR1 = 0x4; UCA0MCTL = 0; UCA0CTL1 &= ~UCSWRST; // Release from reset UC0IE |= UCA0RXIE; // Enable interrupts on RX all time _enable_interrupts(); // turn on LEDs if (!BSP_LED2_IS_ON()) { toggleLED(2); } if (!BSP_LED1_IS_ON()) { toggleLED(1); } // wait for a button press do { 125 if (BSP_BUTTON1() || BSP_BUTTON2()) { break; } } while (1); SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, (addr_t*) &linkToAddr); SMPL_Init(sRxCallback); while (SMPL_SUCCESS != SMPL_Link(&sLinkID1)) { // blink LEDs until link successfully toggleLED(1); toggleLED(2); SPIN_ABOUT_A_SECOND; } // turn off red LED if (BSP_LED2_IS_ON()) { toggleLED(2); } // turn on RX if (SMPL_Ioctl(IOCTL_OBJ_RADIO, SMPL_SUCCESS) { toggleLED(1); } IOCTL_ACT_RADIO_RXON, // send confirmation to the GUI that the link is established writeData(LINKED, 0, 0); while (1) { if (TurnOffCommand) { *SendData = TURN_OFF; SMPL_Send(sLinkID1, SendData, 1); RXdata[0] = 0; RXdata[1] = 0; TurnOffCommand = false; } if (NewRefOmega) { *SendData = SEND_REF_OMEGA; *(SendData + 1) = RXdata[1]; *(SendData + 2) = RXdata[2]; 0) == 126 SMPL_Send(sLinkID1, SendData, 3); RXdata[0] = 0; RXdata[1] = 0; RXdata[2] = 0; RXdata[3] = 0; NewRefOmega = false; } if (NewCurrentOmega) { //send omega to the GUI writeData(SEND_CURRENT_OMEGA, CurrentOmega[1]); NewCurrentOmega = false; } if (TurnOffCommandOK) { //send confirmation to the GUI writeData(TURN_OFF, 0, 0); TurnOffCommandOK = false; } if (StepResponse) { *SendData = STEP_RESPONSE; *(SendData + 1) = RXdata[1]; *(SendData + 2) = RXdata[2]; SMPL_Send(sLinkID1, SendData, 3); RXdata[0] = 0; RXdata[1] = 0; RXdata[2] = 0; RXdata[3] = 0; StepResponse = false; } if (StepResponseEnd) { writeData(STEP_RESPONSE_END, 0, 0); StepResponseEnd = false; } } } void toggleLED(uint8_t which) { if (1 == which) { BSP_TOGGLE_LED1(); } else if (2 == which) CurrentOmega[0], 127 { BSP_TOGGLE_LED2(); } return; } void writeData(uint8_t wCommand, uint8_t currentOmega0, uint8_t currentOmega1) { if (wCommand == LINKED) { TXdata[0] = LINKED; TXdata[1] = END_OF_MESSAGE; TXcount = 0; TX_MESSAGE_LENGTH = 2; UC0IE |= UCA0TXIE; } if (wCommand == TURN_OFF) { TXdata[0] = TURN_OFF; TXdata[1] = END_OF_MESSAGE; TXcount = 0; TX_MESSAGE_LENGTH = 2; UC0IE |= UCA0TXIE; } if (wCommand == SEND_CURRENT_OMEGA) { TXdata[0] = SEND_CURRENT_OMEGA; TXdata[1] = currentOmega0; TXdata[2] = currentOmega1; TXdata[3] = END_OF_MESSAGE; TXcount = 0; TX_MESSAGE_LENGTH = 4; UC0IE |= UCA0TXIE; } if (wCommand == STEP_RESPONSE_END) { TXdata[0] = STEP_RESPONSE_END; TXdata[1] = END_OF_MESSAGE; TXcount = 0; TX_MESSAGE_LENGTH = 2; UC0IE |= UCA0TXIE; } } // handle received frames static uint8_t sRxCallback(linkID_t port) { uint8_t ReceivedData[3], length, LinkCommand; if (port == sLinkID1) 128 { if ((SMPL_SUCCESS == SMPL_Receive(sLinkID1, ReceivedData, &length)) && (length > 0)) { LinkCommand = *ReceivedData; if (LinkCommand == TURN_OFF) { TurnOffCommandOK = true; } if (LinkCommand == SEND_CURRENT_OMEGA) { CurrentOmega[0] = *(ReceivedData + 1); CurrentOmega[1] = *(ReceivedData + 2); NewCurrentOmega = true; } if (LinkCommand == STEP_RESPONSE_END) { StepResponseEnd = true; } return 1; } } return 0; } // ISR for USCI_A ,B0 TX #pragma vector = USCIAB0TX_VECTOR __interrupt void USCIAB0TX_ISR (void) // Acknowledge by write to TXBUF { while (!(UC0IFG & UCA0TXIFG)); UCA0TXBUF = TXdata[TXcount]; // Send next byte TXcount++; if (TXcount >= TX_MESSAGE_LENGTH) UC0IE &= ~UCA0TXIE; // Disable further interrupts. } // ISR for USCI_A ,B0 RX #pragma vector = USCIAB0RX_VECTOR __interrupt void USCIAB0RX_ISR (void) // Acknowledge by read of RXBUF { RXdata[RXcount] = UCA0RXBUF; // Store received data RXcount++; if ((RXdata[0] == TURN_OFF) && (RXdata[1] == END_OF_MESSAGE)) { TurnOffCommand = true; RXcount = 0; 129 } if ((RXdata[0] == RECEIVE_REF_OMEGA) && (RXdata[3] == END_OF_MESSAGE)) { NewRefOmega = true; RXcount = 0; } if ((RXdata[0] == STEP_RESPONSE) && (RXdata[3] == END_OF_MESSAGE)) { StepResponse = true; RXcount = 0; } } main_LinkListen.c /*---------------------------------------------------------------------------* Remote Module Program * * Rene Descartes Olimpio Pereira *---------------------------------------------------------------------------- */ #include "bsp.h" #include "mrfi.h" #include "nwk_types.h" #include "nwk_api.h" #include "bsp_leds.h" #include "bsp_buttons.h" #include "app_remap_led.h" #include "stdbool.h" #include "intrinsics.h" static _Bool TurnOnCommand = false, TurnedOff = false, TurnOffCommand = false, NewRefOmega = false, NewSample = false, ClockwiseStart = false, NewFirstPulse = false, Inversion = false, StepResponse = false, SendStepResponse = false, StepResponseEnd = false; static volatile uint8_t SendCurrentOmegaCount = 0, nBasicWindows = 0, PositiveDeltaN = 0, NegativeDeltaN = 0, SendStepResponseCount = 0; static uint8_t refOmegax1000[2] = {0}, SendData[3] = {0}, stepResponseSamples[2] = {0}, Sequence = 0, 130 PreviousSequence = 0, CCI0BCurrentPulse = 0, CCI1BCurrentPulse = 0; static int8_t Direction = 0; static volatile uint16_t TotalBasicWindows = 0; static uint16_t PWMCycles = 0, CaptureInput0 = 0, CaptureInput1 StepResponseSamples = 0; static int16_t RefOmegax1000 = 0, IntCurrentOmegax1000 = 0, DeltaN = 0; static uint32_t TotalCyclesTimerASum PreviousLastPulseCycles = 65536; = 65536, LastPulseCycles = = 0, 65536, static float CurrentOmegax1000 = 0, PreviousOmegax1000 = 0, OmegaErrorx1000 = 0, DeltaTorquex1000 = 0, RefTorquex1000 = 0, PreviousRefTorquex1000 = 0, FloatPWMCycles = 0; static linkID_t sLinkID2 = 0; const uint8_t TURN_OFF = 1, RECEIVE_REF_OMEGA = 2, SEND_CURRENT_OMEGA = 3, STEP_RESPONSE = 5, STEP_RESPONSE_END = 6; const int8_t QuadEncMatrix[16] = {-1, 0, 1, -1, 1, -1, -1, 0, 0, -1, -1, 1, -1, 1, 0, -1}; const uint16_t TotalCyclesTimerB = 1200; const uint32_t TotalCyclesTimerA = 65536; const float Pix2x1000_NpxTtimerA = 4487989, Kp = 0.10391, Ki = 0.018004, MaxTorquex1000 = 1290.147, KmxTotalCyclesTimerB_1000xRatedVoltage = 0.12901, RaxTotalCyclesTimerB_1000xKmxRatedVoltage = 0.17052; const addr_t linkListenAddr = {'L', 'I', 'L', 'I'}; // Rx callback handler static uint8_t sRxCallback(linkID_t); void toggleLED(uint8_t); void main (void) { BSP_Init(); // turn on LEDs if (!BSP_LED2_IS_ON()) { toggleLED(2); } if (!BSP_LED1_IS_ON()) { 131 toggleLED(1); } // wait for a button press do { if (BSP_BUTTON1() || BSP_BUTTON2()) { break; } } while (1); SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, (addr_t*) &linkListenAddr); SMPL_Init(sRxCallback); // listen for link while (1) { if (SMPL_SUCCESS == SMPL_LinkListen(&sLinkID2)) { break; } } // Turn off one LED toggleLED(1); // turn on RX SMPL_Ioctl(IOCTL_OBJ_RADIO, IOCTL_ACT_RADIO_RXON, 0); while (1) { if (NewRefOmega) { RefOmegax1000 = (refOmegax1000[0] << 8) | refOmegax1000[1]; if (RefOmegax1000 > 0) ClockwiseStart = true; else ClockwiseStart = false; NewFirstPulse = true; TurnOnCommand = true; NewRefOmega = false; break; } } P2DIR &= ~(BIT2 | BIT3); P2SEL = BIT2 | BIT3; P4DIR = BIT4 | BIT5 | BIT6; P4SEL = BIT4; _enable_interrupts(); // P2.2 - P2.3 input (capture) // P2.2 - P2.3 TAx options // P4.4 - P4.6 output // P4.4 TBx options 132 // Capture on both rising and falling edges, input: CCI0B, synchronize capture source, // capture mode and capture/compare interrupt enable. TACCTL0 = CM_3 | CCIS_1 | SCS | CAP | CCIE; TACCTL1 = CM_3 | CCIS_1 | SCS | CAP | CCIE; TBCCR0 = TotalCyclesTimerB; // Output mode: Reset/Set. TBCCTL1 = CCIS_1 | OUTMOD_7; while (1) { while (!TurnedOff) { if (TurnOnCommand) { // Clock = SMCLK, input divider = 2, continuous mode (until 0xFFFF), reset //and TAIFG interrupts enabled. TACTL = TASSEL_2 | ID_1 | MC_2 | TAIE; } OmegaErrorx1000 = (float)(RefOmegax1000 - CurrentOmegax1000); // Incremental PI speed controller with relocation of the proportional gain DeltaTorquex1000 = (float)(Kp*(PreviousOmegax1000 CurrentOmegax1000) + Ki*OmegaErrorx1000); - RefTorquex1000 = (float)(PreviousRefTorquex1000 + DeltaTorquex1000); if (RefTorquex1000 > MaxTorquex1000) RefTorquex1000 = MaxTorquex1000; if (RefTorquex1000 < -MaxTorquex1000) RefTorquex1000 = MaxTorquex1000; // PWM Cycles computation FloatPWMCycles (float)(RefOmegax1000*KmxTotalCyclesTimerB_1000xRatedVoltage RefTorquex1000*RaxTotalCyclesTimerB_1000xKmxRatedVoltage); if (FloatPWMCycles < 0) { FloatPWMCycles = -FloatPWMCycles; Inversion = true; } PWMCycles = (uint16_t)FloatPWMCycles; if (PWMCycles > TotalCyclesTimerB) PWMCycles = TotalCyclesTimerB; = + 133 TBCCR1 = PWMCycles; if (Inversion) { P4OUT |= BIT5; // Enable H-bridge inversion (INV = 1). Inversion = false; } else P4OUT &= ~BIT5; // Disable H-bridge inversion (INV = 0). if (TurnOnCommand) { // Clock: SMCLK, up mode (until TBCCR0). TBCTL = TBSSEL_2 | MC_1; P4OUT |= BIT6; // Enable H-bridge (EN = 1). TurnOnCommand = false; } PreviousRefTorquex1000 = RefTorquex1000; PreviousOmegax1000 = CurrentOmegax1000; if (SendStepResponse) { IntCurrentOmegax1000 = (int16_t)CurrentOmegax1000; *SendData = SEND_CURRENT_OMEGA; *(SendData + 1) = (uint8_t)(IntCurrentOmegax1000 >> 8); *(SendData + 2) = (uint8_t)IntCurrentOmegax1000; SMPL_Send(sLinkID2, SendData, 3); SendStepResponseCount++; if (SendStepResponseCount >= StepResponseSamples) { SendStepResponse = false; StepResponse = false; StepResponseSamples = 0; SendStepResponseCount = 0; RefOmegax1000 = 0; StepResponseEnd = true; } } else { SendCurrentOmegaCount++; if (SendCurrentOmegaCount >= 45) { IntCurrentOmegax1000 = (int16_t)CurrentOmegax1000; *SendData = SEND_CURRENT_OMEGA; *(SendData + 1) = (uint8_t)(IntCurrentOmegax1000 >> 8); *(SendData + 2) = (uint8_t)IntCurrentOmegax1000; SMPL_Send(sLinkID2, SendData, 3); SendCurrentOmegaCount = 0; } } 134 if (NewRefOmega) { RefOmegax1000 = (refOmegax1000[0] << 8) | refOmegax1000[1]; NewRefOmega = false; } if (TurnOffCommand) RefOmegax1000 = 0; while (!NewSample); NewSample = false; if (StepResponseEnd) { *SendData = STEP_RESPONSE_END; SMPL_Send(sLinkID2, SendData, 1); StepResponseEnd = false; } if ((TurnOffCommand) && CurrentOmegax1000 == 0) { TACTL &= ~MC_3; // Stop Timer_A. P4OUT &= ~BIT6; // Disable H-bridge (EN = 0). TBCTL &= ~MC_3; // Stop Timer_B. *SendData = TURN_OFF; SMPL_Send(sLinkID2, SendData, 1); PreviousOmegax1000 = 0; PreviousRefTorquex1000 = 0; TurnedOff = true; TurnOffCommand = false; } } while (!NewRefOmega); NewRefOmega = false; RefOmegax1000 = (refOmegax1000[0] << 8) | refOmegax1000[1]; if (RefOmegax1000 > 0) ClockwiseStart = true; else ClockwiseStart = false; NewFirstPulse = true; TurnOnCommand = true; TurnedOff = false; } } void toggleLED(uint8_t which) { if (1 == which) { 135 BSP_TOGGLE_LED1(); } else if (2 == which) { BSP_TOGGLE_LED2(); } return; } // handle received static uint8_t sRxCallback(linkID_t port) { uint8_t ReceivedData[3], length = 0, LinkCommand = 0; if (port == sLinkID2) { if (SMPL_SUCCESS == SMPL_Receive(sLinkID2, ReceivedData, &length) && length > 0) { LinkCommand = *ReceivedData; if (LinkCommand == TURN_OFF) { TurnOffCommand = true; } if (LinkCommand == RECEIVE_REF_OMEGA) { if (StepResponse) SendStepResponse = true; refOmegax1000[0] = *(ReceivedData + 1); refOmegax1000[1] = *(ReceivedData + 2); NewRefOmega = true; } if (LinkCommand == STEP_RESPONSE) { stepResponseSamples[0] = *(ReceivedData + 1); //MSB stepResponseSamples[1] = *(ReceivedData + 2); StepResponseSamples = (stepResponseSamples[0] << 8) | stepResponseSamples[1]; StepResponse = true; } return 1; } } return 0; } // ISR for Timer_A, CCR0 #pragma vector = TIMERA0_VECTOR 136 __interrupt void TIMERA0_ISR (void) // Flag cleared automatically { LastPulseCycles = (uint32_t)(TACCR0 + 1); CaptureInput0 = TACCTL0 & CCI; if (CaptureInput0) // CCI = 1. { if (NewFirstPulse) { if (ClockwiseStart) { Sequence = 1; PreviousSequence = 0; } else { Sequence = 3; PreviousSequence = 2; } } else CCI0BCurrentPulse = 0x01; } if (!CaptureInput0) // CCI = 0. { if (NewFirstPulse) { if (ClockwiseStart) { Sequence = 2; PreviousSequence = 3; } else { Sequence = 0; PreviousSequence = 1; } } else CCI0BCurrentPulse = 0x00; } if (!NewFirstPulse) Sequence = CCI1BCurrentPulse | CCI0BCurrentPulse; else NewFirstPulse = false; Direction = QuadEncMatrix[(PreviousSequence << 2) + Sequence]; if (Direction == 0) PositiveDeltaN++; if (Direction == 1) NegativeDeltaN++; PreviousSequence = Sequence; } // ISR for Timer_A, CCR1 137 #pragma vector = TIMERA1_VECTOR __interrupt void TIMERA1_ISR (void) // Flag cleared automatically { switch (TAIV) { case TAIV_TACCR1: // Vector 2: TACCR1_CCIFG LastPulseCycles = (uint32_t)(TACCR1 + 1); CaptureInput1 = TACCTL1 & CCI; if (CaptureInput1) // CCI = 1. { if (NewFirstPulse) { if (ClockwiseStart) { Sequence = 3; PreviousSequence = 1; } else { Sequence = 2; PreviousSequence = 0; } } CCI1BCurrentPulse = 0x02; } if (!CaptureInput1) // CCI = 0. { if (NewFirstPulse) { if (ClockwiseStart) { Sequence = 0; PreviousSequence = 2; } else { Sequence = 1; PreviousSequence = 3; } } CCI1BCurrentPulse = 0x00; } if (!NewFirstPulse) Sequence = CCI1BCurrentPulse | CCI0BCurrentPulse; else NewFirstPulse = false; Direction = QuadEncMatrix[(PreviousSequence << 2) + Sequence]; if (Direction == 0) PositiveDeltaN++; if (Direction == 1) NegativeDeltaN++; 138 PreviousSequence = Sequence; break; case TAIV_TAIFG: // Vector 10: TAIFG DeltaN = PositiveDeltaN - NegativeDeltaN; if (PositiveDeltaN == 0 && NegativeDeltaN == 0) { nBasicWindows++; if (nBasicWindows <= 2) TotalCyclesTimerASum += TotalCyclesTimerA; else { CurrentOmegax1000 = 0; PreviousLastPulseCycles = 65536; TotalCyclesTimerASum = TotalCyclesTimerA; nBasicWindows = 0; NewSample = true; } } else { if (LastPulseCycles < 64000) LastPulseCycles = 65536; CurrentOmegax1000 = (float)(DeltaN*Pix2x1000_NpxTtimerA/(TotalCyclesTimerASum - PreviousLastPulseCycles + LastPulseCycles)); DeltaN = 0; PositiveDeltaN = 0; NegativeDeltaN = 0; PreviousLastPulseCycles = LastPulseCycles; TotalCyclesTimerASum = TotalCyclesTimerA; NewSample = true; } break; } }
Documentos relacionados
Interfaces Gráficas (GUIs) em Java usando Swing
Interfaces Gráficas (GUIs) em Java usando Swing Profa. Flávia Cristina Bernardini
Leia mais