Implementando rotinas de controle digital

Seja um controlador digital como o mostrado no diagrama a seguir:

malha_controle_unitario_digital

onde a equação genérica seja dada por:

\(C(z)=\dfrac{K(z-a)}{(z-b)} \quad\) (eq. 1)

O objetivo pretendido aqui é isolar a ação de controle \(U(z)\) e descobrir como implementar esta lei de controle num algoritmo (spftware). Então, isolando termos:

\(C(z)=\dfrac{U(z)}{E(z)}\quad\) (eq. 2)

Juntando eq. (1) com (2) temos:

\(\dfrac{U(z)}{E(z)}=\dfrac{K(z-a)}{(z-b)}\)

Passando para notação com termos negativos em \(z\):

\(\dfrac{U(z)}{E(z)}=\dfrac{K(z-a)}{(z-b)} \cdot \dfrac{z^{-1}}{z^{-1}}\)

\(\dfrac{U(z)}{E(z)}=\dfrac{K(1-a\cdot z^{-1})}{(1-b\cdot z^{-1})}\)

Isolando o termo \(U(z)\) (para mais tarde obter \(u[k]\)):

\(U(z)(1-b\cdot z^{-1})=E(z)\cdot K(1-a\cdot z^{-1})\)

\(U(z)=E(z)\cdot K -K\cdot a \cdot z^{-1}E(z) +b\cdot z^{-1}U(z)\)

Transformando eq. anterior em equações de diferenças obtemos:

\(u[k]=K \cdot e[k] - K \cdot a \cdot e[k-1] + b \cdot u[k-1]\)

Onde:
\(u[k]\): sinal de controle atual \(\quad \rightarrow\) variável (escalar: \(1 \times 1\)) u;
\(u[k-1]\): amostra passada do sinal de controle; \(\rightarrow\) outra variável escalar u1 (variável que guarda valor de 1 amostra passada de \(u[k]\);
\(e[k]\): sinal do erro (instantêneo) \(\quad \rightarrow\) variável e;
\(e[k-1]\): 1 amostra passada do erro \(\quad \rightarrow\) variável e1.

Note que:
\(e[k]=r[k]-y[k]\) \(\quad \leftarrow\) calculado pelo \(\mu\)C: e=r-y;.


No \(\mu\)C (ou sistema embarcado dedicado), organizamos algumas rotinas separadas:

No \(\mu\)C seria ainda implementada dentro do algoritmo principal da aplicação, algo como:

void main(){
  // prepara variaveis 
  Init();
  // inicializa interrupção por software
  // associa um timmer do uC para gerar o meu "T" (periodo de amostragem)
  set_timmer0=20000; // gerar overflow a cada 100 ms
  isr_AlgoCtr(timmer0); // associo rotina de tratamento de interrupção com
  // overflow do timmer0
  start_isr_AlgoCtrl(); // efetivamente libera timmer0 e interrupção associada
  // para funcionar
  while(not("ESC")){
    // lê teclado
    tecla=le_teclado();
    if tecla=="↑" K++;
    if tecla=="↓" K--;
    if tecla=="r↑" r++;
    if tecla=="r↓" r--;
    // atualiza display
    update_display();
  }
  disable_isr_control(); /* desabilita interrupção do controle, "desliga" algoritmo de controle */
  set_pwm(0); // garante que o motor seja desacionado.
}

Onde:

Em termos de ciclos de processamento de um \(\mu\)C neste caso, se espera algo como:

implementa_algo_controle_time_slice.png


Fernando Passold, em 28/10/2020