software para la simulación del comportamiento del...

103
Software para la simulación del comportamiento del conjunto Motor DC - Encoder TITULACIÓ: Enginyeria en Automàtica i Electrònica Industrial. AUTOR: Jacob Pié Vallvé. DIRECTOR: Esteban del Castillo Pérez. DATA: Juny / 2012

Upload: lebao

Post on 26-Sep-2018

214 views

Category:

Documents


0 download

TRANSCRIPT

Software para la simulación del comportamiento del conjunto Motor DC - Encoder

TITULACIÓ: Enginyeria en Automàtica i Electrònica Industrial.

AUTOR: Jacob Pié Vallvé.

DIRECTOR: Esteban del Castillo Pérez.

DATA: Juny / 2012

Proyecto final de carrera Página 2

Índice

1 Memoria Descriptiva ........................................................................................... 4

1.1 Introducción ................................................................................................. 5

1.2 Objetivo ....................................................................................................... 5

1.3 Descripción de la Planta .............................................................................. 6

1.4 Modelado de la Planta ................................................................................ 16

1.4.1 Modelo del Motor de corriente continua ................................................ 16

1.4.2 Análisis del modelo obtenido del Motor de corriente continua ............. 20

1.4.3 Excitación PWM y sus efectos ............................................................... 23

1.4.4 Conjunto Excitación PWM + motor DC ................................................ 29

1.4.5 El control PID......................................................................................... 32

1.4.6 Lazo de Control ...................................................................................... 35

1.4.7 Sintonización Controlador PID .............................................................. 36

1.4.8 Errores del sistema ................................................................................. 39

1.5 Emulador de la Planta ................................................................................ 42

1.6 Software de simulación de la Planta .......................................................... 47

1.6.1 Descripción del Software ....................................................................... 48

1.6.2 Librería Q5.h .......................................................................................... 49

1.6.3 Librería k1.h ........................................................................................... 54

1.7 Modo de Uso .............................................................................................. 60

2 Anexo A ............................................................................................................ 65

2.1 El motor de corriente continua ................................................................... 66

3 Anexo B............................................................................................................. 72

3.1 Código Librería Q5.h ................................................................................. 73

3.2 Código Librería K1.h ................................................................................. 74

Proyecto final de carrera Página 3

4 Anexo C............................................................................................................. 78

4.1 Librería 8259.h ........................................................................................... 79

4.2 Librería Ini_IRQ.h ..................................................................................... 80

4.3 Librería PID.h ............................................................................................ 81

4.4 Librería Printer.h ........................................................................................ 82

4.5 Librería PWM.h ......................................................................................... 84

4.6 Librería Timer.h ......................................................................................... 84

4.7 Librería Main.c .......................................................................................... 86

4.8 Librería Ini_IRQ.c ..................................................................................... 90

4.9 Librería PID.c ............................................................................................ 94

4.10 Librería PWM.c ......................................................................................... 96

4.11 Librería Timer.c ......................................................................................... 98

5 Anexo D: Referencias ..................................................................................... 103

Proyecto final de carrera Página 4

1 Memoria Descriptiva

Memoria descriptiva

Proyecto final de carrera Página 5

1 Memoria Descriptiva

1.1 Introducción

Dentro del marco de asignaturas que se imparten en el plan de estudios de primer ciclo de la Ingeniería Técnica Industrial en Electrónica Industrial se encuentra la asignatura Informática Industrial II.

En esta asignatura se forma al alumnado para que obtenga los conocimientos de hardware y software necesarios para la elaboración de software de control en un PC. Dentro de los créditos de la asignatura, se realizan unas prácticas en los laboratorios habilitados, donde se ejercitan los conocimientos adquiridos. Estas prácticas consisten en implementar un control de velocidad y de posición del eje de un motor de corriente continua, a través del interfaz del puerto paralelo de un PC bajo el sistema operativo MS-DOS, utilizando como lenguaje de programación el lenguaje C.

Para el desarrollo de las prácticas se dispone de una “planta”, la cual está formada por un motor de corriente continua, un encoder relativo y un circuito electrónico que realiza la función de interface entre el puerto paralelo del PC y el conjunto motor-encoder. Desafortunadamente, esta planta sólo está disponible en los laboratorios habilitados para la asignatura. Para facilitar el desarrollo de las prácticas, el profesor titular de la asignatura realizo un circuito electrónico que emulaba la planta en cuestión, de esta manera el alumnado podía avanzar en el desarrollo de las practicas fuera de la universidad.

Desgraciadamente, a causa de la tendencia en los últimos años en la utilización de ordenadores portátiles para el desarrollo individual de las prácticas por parte del alumnado, surge el problema de que estos nuevos equipos raramente tengan accesible externamente el puerto paralelo, aunque este esté implementado la placa base como PC compatible, con lo que comporte que el emulador pierda su funcionalidad.

Para desarrollar la parte teórica de este proyecto se ha utilizado como referencia bibliográfica el libro escrito por el sr Esteban del Castillo – Control de Procesos, donde describe la implementación de una plataforma hardware/software aplicada al conjunto motor dc-encoder.

1.2 Objetivo

El objetivo del presente proyecto es implementar un simulador software a base de librerías basadas en lenguaje de programación C que simule el comportamiento de la “planta” disponible en los laboratorios de la asignatura.

Memoria descriptiva

Proyecto final de carrera Página 6

1.3 Descripción de la Planta

La “planta” utilizada en los laboratorios de la asignatura está formada por 3 piezas bien diferenciadas:

- Motor de corriente continua - Encoder relativo - Placa electrónica interface puerto paralelo – PC

Figura 1. “Planta” utilizada en los Laboratorios

1.3.1.1 Motor de corriente continua

La máquina motriz utilizada es un motor de corriente continua de imanes permanentes del fabricante Maxon, de la serie F2140, concretamente el modelo 2140.937-58.236-050. Obtener el modelo concreto del motor es interesante para poder realizar un estudio de la planta, obteniendo dados particulares de su comportamiento de su hoja de características.

Cabe destacar el tipo de motor utilizado es un motor de corriente continua de imanes permanentes. Este tipo de motores están clasificados como máquinas especiales

Memoria descriptiva

Proyecto final de carrera Página 7

dentro del campo de las máquinas eléctricas, este hecho nos dificultara su estudio, ya que gran parte de simuladores de circuitos eléctricos no contempla este tipo de motores, sólo los motores de excitación independiente.

En la figura nº 2 mostramos las principales especificaciones del motor, donde podremos observar los datos necesarios para su posterior modelado, pudiendo de esta manera comprobar que el modelo realizado se aproxima a la realidad.

Figura 2. Características principales motor dc

De la hoja de características podemos obtener los datos para el modelado del motor los cuales son los siguientes:

Resistencia óhmica en bornes armadura (Ra)

Inductancia en bornes armadura (La)

Constante de tiempo mecánica (τm)

Inercia del rotor (J)

Constante de velocidad

Constante mecánica (km)

Velocidad en vacío

A modo de información para el alumnado, hemos descrito las principales

características de los motores de corriente continua en el anexo A, para así comprender el

significado de estos.

Más adelante realizaremos un estudio para obtener un modelo aproximado del

motor para poder realizar una simulación de la “planta”.

Memoria descriptiva

Proyecto final de carrera Página 8

1.3.1.2 Encoder relativo

Para un control de velocidad o posición del motor se necesita posicionar el eje de este a través de algún elemento que nos proporcione la información necesaria para determinarlo. Una forma sencilla de obtener esta posición o velocidad es conectando el eje del motor a un encoder.

En el mercado existen muchos tipos de encoders con características factibles para realizar esta operación.

En este caso, la planta disponible en el laboratorio está equipada con un encoder relativo bidireccional de dos canales de salida A y B, el cual permite detectar el sentido de rotación del eje. Este es de la marca Hohner, de la serie 21, modelo 21-122-200 de 200 pulsos por vuelta.

En la figura 3 mostramos el interior de un encoder relativo para podernos hacer una idea de cómo están construidos.

Figura 3. Interior teórico Encoder incremental

Es de gran importancia comprender el funcionamiento del encoder y las señales que nos proporcionará, para poder realizar las prácticas del laboratorio de la asignatura Informática Industrial II, tanto las rutinas que tendremos que implementar nosotros en el presente proyecto para simular el comportamiento de este.

En la figura nº 4 mostramos las señales A y B con el paso del tiempo. Como podemos observar, éstas están desfasadas entre ellas 90 º. A través de esta característica podremos observar el sentido de giro del motor. Por ejemplo, si la lectura actual de las señales A y B es 01 y la anterior era 11, el sentido de giro será hacia la derecha, en cambio, si la lectura anterior era 00, el sentido de giro será hacia la izquierda.

Memoria descriptiva

Proyecto final de carrera Página 9

Figura 4. Señales A y B del encoder

1.3.1.3 Placa electrónica interface puerto paralelo – PC

Para poder utilizar el motor y el encoder a través de nuestro PC tenemos que tener un interface que comunique ambas partes.

La placa electrónica montada en el conjunto motor-encoder está formada por dos partes bien diferenciadas. La primera tiene la función de atender las salidas de nuestro PC a través del puerto paralelo y adecuar estas señales con la suficiente potencia para atacar al motor de corriente continua. La segunda, adapta las señales generadas por el encoder para que esa información pueda ser utilizada y leída por puerto paralelo.

Cabe puntualizar que el motor de corriente continua es un actuador que modifica la velocidad de salida según el valor medio de la tensión de excitación. A razón de esto, nuestra etapa de potencia tiene que ser capaz de realizar pequeñas variaciones del valor medio de la tensión de salida. Generalmente cuando se debe realizar esta operación en las aplicaciones de control se utiliza la técnica de la modulación de anchura de pulsos, o más bien conocido por PWM.

En la figura nº 11 mostramos el esquema de este interface. Si analizamos el esquema de potencia, podemos observar que el circuito de excitación de motor está formado por un puente en H de transistores. Estos transistores se han escogido con especial cuidado, ya que deben que tener unas características especiales.

Si recordamos como está formado constructivamente el interior de un motor de corriente continua, veremos que está compuesto por unas bobinas. Éstas, durante el período se cargan de energía, el problema surge en el período de . Cuando llega el período el transistor no conduce, pero por la inductancia sigue circulando una IL, encontrándose la necesidad de dar continuidad a la corriente magnetizante. Para evitar la rotura del transistor, estos tienen que llevar incorporado un diodo volante para poder realizar la descarga de la corriente de la bobina en los periodos de desconexión.

Otro punto a tener en cuenta es el aislamiento galvánico de la placa electrónica. Las corrientes inducidas por las bobinas del motor provocan ruidos en las tensiones de alimentación, al igual que la conmutación de los devanados del inducido sobre su colector

Memoria descriptiva

Proyecto final de carrera Página 10

de delgas, que se podrían propagar a las señales del puerto paralelo del PC, pudiendo dar a errores de lectura o escritura en la salida del puerto. [1]

Sin dejar de analizar la parte de potencia, podemos ver que se ha implementado una protección eléctrica en el circuito de control del puente de transistores para evitar la conexión simultánea de los dos ramales de alimentación.

Pin DB2 Pin DB3 Señal

Derecha

Señal

Izquierda

0 0 1 1

0 1 1 0

1 0 0 1

1 1 1 1

Figura 5. Tabla Verdad Pins DB2 y DB3

Para poder activar cada ramal individualmente, el diodo del optoacoplador debe entrar en modo de conducción. Este sólo entrará en este modo si la señal proporcionada por el bloque lógico es cero, tal y como mostramos en la tabla de la verdad descrita anteriormente, de lo contrario restará abierto.

Por otra parte, como hemos dicho con anterioridad, el encoder que tenernos instalado en nuestra planta entrega dos señales en cuadratura, a partir de la cuales podremos detectar el sentido de giro del motor.

Para poder detectar un cambio de sentido se deberá realizar un seguimiento de la secuencia proporcionada por el encoder de las señales A y B, tal y como mostramos en la figura nº 6.

Figura 6. Señales de salida circuito acondicionador encoder

Proyecto final de carrera

Como podemos ver, cada vez que alguna de las señales A y B cambia de estado, través de un flanco de subida o bajada, encoder detecta el cambio y genera la Los valores que se observan justo en el flanco en que se provoca la interrupción son los valores de las señales A y B, de esta manera podremos observar el sentido de giro del eje del motor.

Donde la secuencia a seguir seria:

Para poder seguir la secuencia generada por el encoder, el interface motor incorporado un bloque lógico que genera una señal adecuada para interrumpir la CPU del PC justo cuando acontecen los flancos de subida y bajada de las señales A

Para poder detectar los flancos originados por el encoder se ha utilizado un circuito lógico basado en un diferenciador.

Como se observa en la figura 7 el circuito diferenciador ascendentes y descendentes. Esta será la base para crear el bloque lógico.

Para poder calcular la red RC tenemos que tener en cuenta la frecuencia máxima en que el encoder nos entregara las señales. A razón de una velocidad máxima de nuestro motor de 3980 rpm y que el encoder utilizado provoca 800 flancos por revolución, tendremos:

Memoria descriptiva

Como podemos ver, cada vez que alguna de las señales A y B cambia de estado, través de un flanco de subida o bajada, el bloque lógico del interface del conjunto motorencoder detecta el cambio y genera la correspondiente interrupción en el puerto parLos valores que se observan justo en el flanco en que se provoca la interrupción son los valores de las señales A y B, de esta manera podremos observar el sentido de giro del eje

Donde la secuencia a seguir seria:

Figura 7. Sentido de giro

Para poder seguir la secuencia generada por el encoder, el interface motor incorporado un bloque lógico que genera una señal adecuada para interrumpir la CPU del PC justo cuando acontecen los flancos de subida y bajada de las señales A

Para poder detectar los flancos originados por el encoder se ha utilizado un circuito lógico basado en un diferenciador.

Figura 7. Circuito diferenciador

Como se observa en la figura 7 el circuito diferenciador detecta los flancos endentes y descendentes. Esta será la base para crear el bloque lógico.

Para poder calcular la red RC tenemos que tener en cuenta la frecuencia máxima en que el encoder nos entregara las señales. A razón de una velocidad máxima de nuestro

y que el encoder utilizado provoca 800 flancos por revolución,

Memoria descriptiva

Página 11

Como podemos ver, cada vez que alguna de las señales A y B cambia de estado, a el bloque lógico del interface del conjunto motor-

correspondiente interrupción en el puerto paralelo. Los valores que se observan justo en el flanco en que se provoca la interrupción son los valores de las señales A y B, de esta manera podremos observar el sentido de giro del eje

Para poder seguir la secuencia generada por el encoder, el interface motor – PC lleva incorporado un bloque lógico que genera una señal adecuada para interrumpir la CPU del PC justo cuando acontecen los flancos de subida y bajada de las señales A y B del encoder.

Para poder detectar los flancos originados por el encoder se ha utilizado un circuito

detecta los flancos endentes y descendentes. Esta será la base para crear el bloque lógico.

Para poder calcular la red RC tenemos que tener en cuenta la frecuencia máxima en que el encoder nos entregara las señales. A razón de una velocidad máxima de nuestro

y que el encoder utilizado provoca 800 flancos por revolución,

Proyecto final de carrera

Por lo cual tendremos un flanco cada encoder no están todas alineadas, nos podría llegar un flanco en un intervalo solventar deficiencias mecánicas podemos reducir este tiempo a seguridad.

Por otra parte, cabe puntualizar que para preservar los estados de la señal en su tránsito por los cables, debemos acotar la anchura del pulsode es adecuado.

En la siguiente figura mostramos el bloque lógico detector de responde a la siguiente ecuación:

dondecaída igual a 1.8 V, entonces viable es una y

Figura

Memoria descriptiva

Por lo cual tendremos un flanco cada . Si suponemos que las ventanas del encoder no están todas alineadas, nos podría llegar un flanco en un intervalo solventar deficiencias mecánicas podemos reducir este tiempo a como coeficiente de

Por otra parte, cabe puntualizar que para preservar los estados de la señal en su tránsito por los cables, debemos acotar la anchura del pulso de bajada. Un valor del orden

En la siguiente figura mostramos el bloque lógico detector de responde a la siguiente ecuación:

Figura 8. Bloque lógico

donde siendo el umbral del inversor en caída igual a 1.8 V, entonces para implicara una , donde una solución

y . [1]

Figura 9. Detector de flancos ascendentes y descendentes

Memoria descriptiva

Página 12

. Si suponemos que las ventanas del encoder no están todas alineadas, nos podría llegar un flanco en un intervalo menor. Para

como coeficiente de

Por otra parte, cabe puntualizar que para preservar los estados de la señal en su de bajada. Un valor del orden

En la siguiente figura mostramos el bloque lógico detector de flancos, el cual

el umbral del inversor en , donde una solución

Detector de flancos ascendentes y descendentes

Memoria descriptiva

Proyecto final de carrera Página 13

En la figura nº 9 mostramos el bloque lógico correspondiente a la señal A del encoder para poder detectar tanto los flancos ascendentes y descendentes de la señal en cuadratura.

La resistencia y limitan la corriente derivada por el diodo interno de la puerta inversora a valores inferiores a 1 mA si el valor de la resistencia es de 5,6 kΩ. [1]

En la siguiente figura podemos observar las señales generadas por el bloque detector de flancos, donde la señal azul corresponde a la señal en cuadratura del encoder llamada A, y en cada flanco la correspondiente detección por parte de cada bloque detector, detectando tanto el flanco ascendente como el descendente. Nótese la amplitud del pulso generado por el bloque, siendo de 4 para suplir las deficiencias de los conductores de transporte de la señal.

Figura 10. Señales resultantes del bloque de detención de flancos.

El bloque lógico implementado tiene que ser lo suficientemente rápido para poder generar la solicitud a las interrupciones adecuadamente. Es importante que el tiempo en nivel cero de la señal generada sea el menor posible, de esta manera el tiempo de esta en nivel 1 será el más grande posible. De esta manera si tenemos una velocidad elevada del motor el bloque lógico tendrá tiempo de generar los dos pulsos de interrupción entre las ventanas de cuadratura del encoder, ya que la señal de solicitud tendrá un pulso por paso por cero muy pequeño.

En la figura nº 11 mostramos todo el montaje del interface para utilizar el conjunto motor-encoder, compuesto por las partes de potencia que alimenta al motor y lógica de control, que adapta las señales del encoder al puerto paralelo del PC.

Proyecto final de carrera

Figura

En la tabla nº 1 mostramos la asociación de señales y pins del puerto paralelo. Podemos observar la dirección de la información de cada pin.

En la Tabla nº 2 mostramos los registros propios del puerto paralelo y la asociación con el conector de la Tabla nº 1.de las direcciones 0x378, 0x278 o 0x3BC.

Los pines utilizados por el interface motor

Pins 2 y 3 del Registro Base + 0 (ataque puente transistores) Pins 12 y 13 del Registro Pin 10 del Registro Base + 2 (activación de la IRQ del Puerto)

Memoria descriptiva

Figura 11. Esquema placa Interface con el PC

tabla nº 1 mostramos la asociación de señales y pins del puerto paralelo. Podemos observar la dirección de la información de cada pin.

En la Tabla nº 2 mostramos los registros propios del puerto paralelo y la asociación con el conector de la Tabla nº 1. El registro base de un puerto paralelo está ubicado en

las direcciones 0x378, 0x278 o 0x3BC.

Los pines utilizados por el interface motor – PC son los siguientes

Pins 2 y 3 del Registro Base + 0 (ataque puente transistores)Pins 12 y 13 del Registro Base + 1 (información del encoder)Pin 10 del Registro Base + 2 (activación de la IRQ del Puerto)

Memoria descriptiva

Página 14

tabla nº 1 mostramos la asociación de señales y pins del puerto paralelo.

En la Tabla nº 2 mostramos los registros propios del puerto paralelo y la asociación l registro base de un puerto paralelo está ubicado en una

los siguientes:

Pins 2 y 3 del Registro Base + 0 (ataque puente transistores) Base + 1 (información del encoder)

Pin 10 del Registro Base + 2 (activación de la IRQ del Puerto)

Memoria descriptiva

Proyecto final de carrera Página 15

Señal Pin Dirección

/Strobe 1 OUT

Data 0 2 OUT

Data 1 3 OUT

Data 2 4 OUT

Data 3 5 OUT

Data 4 6 OUT

Data 5 7 OUT

Data 6 8 OUT

Data 7 9 OUT

/Acknowledge 10 IN

Busy 11 IN

Paper End 12 IN

Select 13 IN

/Auto Feed 14 OUT

/Error 15 IN

/Inicialize Printer 16 OUT

/Select Input 17 OUT

Ground 18-25 -

Tabla 1. Puerto DB25 PC

Base + 0: Registro de lectura/escritura

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

Pin 9 Pin 8 Pin 7 Pin 6 Pin 5 Pin 4 Pin 3 Pin 2

Base + 1: Registro de solo lectura

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

/Pin 11 Pin 10 Pin 12 Pin 13 Pin 15 - - -

Base + 2: Registro de lectura/escritura

Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0

- - - IRQ /Pin 17 Pin 16 /Pin 14 /Pin 1

Tabla 2. Registros del puerto paralelo

Proyecto final de carrera

1.4 Modelado de la Planta

Durante el transcurso de la carrera se han realizado asignaturas donde se imparte teoría para modelar plantas controladores para su control

Encontramos interesante realizar un estudio del modelado de una planta real donde podremos simular elementos concretos, estudiar sus respuestas y comprobar las aproximaciones realizadas encontrándonos con problemas reales del modelado y la correcta identificación de los parámetros suministrados por los fabricantes

En la referencia bibliográfica nº 2 podemos encontrar identificación de los parámetros y modelado de un pequeño motor de corriente continua.

1.4.1 Modelo del Motor de corriente conti

En la figura nº 12 mostramos el esquema de corriente continua de imanes permanentesrepresentándolo en el programa de simulación Matlab.

Partimos de las siguientes expresiones en el dominio de Laplace, las cuales representan el comportamiento eléctrico del motor:

Combinando las ecuaciones 1 y 2 obtendremos la corriente de armadura

Memoria descriptiva

Modelado de la Planta

Durante el transcurso de la carrera se han realizado asignaturas donde se imparte teoría para modelar plantas en el espacio del control continuo y la implementación de ontroladores para su control.

Encontramos interesante realizar un estudio del modelado de una planta real donde podremos simular elementos concretos, estudiar sus respuestas y comprobar las

durante el modelado respecto al elemento realndonos con problemas reales del modelado y la correcta identificación de los

parámetros suministrados por los fabricantes de los elementos (motor dc, encoder …)

En la referencia bibliográfica nº 2 podemos encontrar en un pequeño resumen de la ción de los parámetros y modelado de un pequeño motor de corriente continua.

delo del Motor de corriente continua

mostramos el esquema del cual partiremos para modelar el motor de imanes permanentes, obteniendo su modelo matemático y

en el programa de simulación Matlab.

Figura 12. Motor DC imanes permanentes

Partimos de las siguientes expresiones en el dominio de Laplace, las cuales representan el comportamiento eléctrico del motor:

Combinando las ecuaciones 1 y 2 obtendremos la corriente de armadura

Memoria descriptiva

Página 16

Durante el transcurso de la carrera se han realizado asignaturas donde se imparte en el espacio del control continuo y la implementación de

Encontramos interesante realizar un estudio del modelado de una planta real donde podremos simular elementos concretos, estudiar sus respuestas y comprobar las

durante el modelado respecto al elemento real. De esta manera ndonos con problemas reales del modelado y la correcta identificación de los

de los elementos (motor dc, encoder …).

en un pequeño resumen de la ción de los parámetros y modelado de un pequeño motor de corriente continua.

para modelar el motor su modelo matemático y

Partimos de las siguientes expresiones en el dominio de Laplace, las cuales

Combinando las ecuaciones 1 y 2 obtendremos la corriente de armadura

Memoria descriptiva

Proyecto final de carrera Página 17

4

Por otra parte, el par generado por el motor es el siguiente:

5

El par mecánico neto en el eje del motor será el resultante de:

6

Combinando las ecuaciones 4 y 6 obtenemos la relación entre el torque neto con la corriente de armadura.

7

En la siguiente figura, mostramos el esquema de bloques el modelo matemático del motor de corriente continua con excitación permanente a través de los imanes de su estator.

Figura 13. Modelo matemático Motor DC

Memoria descriptiva

Proyecto final de carrera Página 18

Por otro lado, utilizando la segunda ley de Newton, obtenemos que el par neto del motor es:

! " 8

donde ! corresponde al momento de inercia del eje del motor y su carga y " la fricción de estos.

Si consideramos que el par perturbador es nulo e igualamos las ecuaciones 7 y 8 obtendremos:

! " 9

operando la ecuación 9:

! " 10

'! " ( 11

obteniendo la función de transferencia del motor a partir de la ecuación nº 11

'! " ( 12

identificando los términos:

! * '! " ( " 13

donde tendríamos que tener una función normalizada de la forma:

, -** 2 . - -*

Memoria descriptiva

Proyecto final de carrera Página 19

Esta función de transferencia es la que describe la figura de bloques nº 8, siendo un sistema de segundo orden. Generalmente llegados a este punto, se suele simplificar la ecuación de transferencia despreciando frente de y la / frente la / obteniendo así una función de transferencia de primer orden.

Quedando la función de transferencia descrita en la ecuación nº 13 de la siguiente manera:

! " 14

Al igual que en el sistema de segundo orden, deberíamos buscar la función de transferencia equivalente normalizada.

, ,0/ 1

entonces:

! "

" ! " 1 15

de forma que:

,0 " 16

/ ! " 17

Memoria descriptiva

Proyecto final de carrera Página 20

1.4.2 Análisis del modelo obtenido del Motor de corriente continua

Una vez realizado el modelado del comportamiento físico del motor podemos pasar a simular los resultados obtenidos en los sistemas de primer y segundo y contrastarlos con las características proporcionadas por el fabricante.

De esta manera podremos comprobar la diferencia entre modelos, si la hubiera, y los diferentes resultados según la inclusión u omisión de ciertos parámetros.

1.4.2.1 Simulación sistema segundo orden

El sistema a simular en este apartado está representado en la figura nº 13. Este es un modelo de segundo orden sin realizar ninguna apreciación o simplificación, excepto la de considerar el torque perturbador nulo.

La simulación de este se realizará en lazo abierto para observar la respuesta de este a un escalón unitario.

Los parámetros subministrados por el fabricante los podemos encontrar en la figura nº 2 de la memoria descriptiva de este proyecto. Estos parámetros son los siguientes:

- 41,5 2

- 5,02 34

- 55,2 353/7

- ! 22,1 893²

- ; ?

- == 24

Podemos observar que el fabricante, en los datos proporcionados, no habla en ningún momento del coeficiente de fricción que tiene el rotor. Considerando que es un motor muy pequeño, podemos estimar que este coeficiente debe ser nulo. Entonces realizaremos una primera aproximación de este modelo y efectuaremos la simulación del sistema sin este parámetro.

En la figura nº 14 podemos observar el resultado obtenido de la simulación del sistema. Podemos apreciar que este no se ajusta del todo a la realidad según los parámetros entregados por el fabricante.

Memoria descriptiva

Proyecto final de carrera Página 21

Figura 14. Simulación modelo 2º orden sin coeficiente de fricción.

Según los datos de la figura nº 2 la velocidad del motor en vacío es de 3980 rpm, en la simulación del modelo obtenemos una velocidad en vacío de 4151,5 rpm, lo que supone una diferencia entre el modelo y los datos reales del 4,3 %.

Esta diferencia entre los datos del fabricante y los obtenidos en la simulación puede venir causada por la aproximación realizada en la omisión del coeficiente de fricción del modelo.

Para obtener el valor del coeficiente de fricción del rotor tenemos una aproximación matemática:

; > !/ 18

que nos relaciona la inercia del rotor y la constante mecánica del sistema para obtener el coeficiente de fricción. Aplicando la formula, obtenemos:

; !/ 22.1 10@A

30 10@B 7.36 10@C

Con este término, deberían coincidir los resultados de una nueva simulación con el modelo completo del motor, pero debemos ajustar este valor hasta 3,17 10@D para que los resultados obtenidos sean iguales al del fabricante.

Memoria descriptiva

Proyecto final de carrera Página 22

1.4.2.2 Simulación sistema primer orden

La ecuación nº 15 de la memoria descriptiva representa la simplificación del modelo del motor a un sistema de primer orden. La ecuación de transferencia normalizada de un sistema de primer orden, como hemos descrito anteriormente, es:

, ,0/ 1

Si paramos atención a la ecuación, podremos identificar los términos que la definen en los datos proporcionados por el fabricante. Siendo más sencillo realizar la simulación del sistema con estos datos que no a través de la ecuación encontrada mediante el modelado.

Donde ,0 es la ganancia del sistema en E F ∞ que podemos identificar con el parámetro denominado como constante de velocidad (definido en el Anexo A) con un valor de 173 rpm/V. Por otra parte, la / del sistema la podemos identificar con la / del motor, con un valor de 30 10@Bsegundos.

Con estos datos podemos proceder a realizar la simulación del sistema de primer orden, obteniendo estos resultados mostrados en la figura nº 15.

Estos resultados son muy semejantes a los resultados obtenidos en la primera simulación del modelo de segundo orden, mostrados en la figura nº 14, donde no se tenía en cuenta el coeficiente de fricción del rotor.

Si leemos con detenimiento la definición del parámetro de la constante de velocidad podremos ver que el valor suministrado por el fabricante no tiene en cuenta las pérdidas por fricción, de ahí la semejanza de resultados.

Figura 15. Simulación modelo 1º orden.

Memoria descriptiva

Proyecto final de carrera Página 23

Teniendo en cuenta la definición de esta constante y realizando un pequeño ajuste de esta en el modelo, obtendremos los siguientes resultados:

Figura 16. Simulación modelo 1º orden con parámetros ajustados.

Con la constante de velocidad ajustada a 165,83 rpm/V, obtenemos un modelo aceptable del motor de corriente continua de imanes permanentes. A partir de este punto utilizaremos este modelo para la realización del resto de simulaciones.

1.4.3 Excitación PWM y sus efectos

Como ya hemos descrito con anterioridad, el motor de corriente continua está alimentado a través de un puente en H de transistores con diodo volante y controlados por una excitación PWM.

Este tipo de excitación provoca unos efectos sobre el motor dependiendo del tiempo de HI y HJJ en que nos encontremos, los cuales se traducen en una alimentación pulsante con periodos de KK y 0V respectivamente. Durante el periodo de HI el transistor está en modo de conducción y por las bobinas del motor circula , pero en HJJel transistor corta la alimentación del motor y anula la corriente a su través. En consecuencia, se abre camino a través del diodo volante del transistor.

Proyecto final de carrera

Este tipo de excitación hasta ahora [1]. Para comprobar este efectosimulación PSIM y Pspice para

Inicialmete hemos simulado la midad del puente en transitores sin diodo volante, paraconectado una red RL de caracteristicas similares al modelo de primer orden.

En la siguiente figura se pueden observar la evintensidad en la carga en volantes).

Figura

Memoria descriptiva

e tipo de excitación modifica el comportamiento del modelo del motor estudiado . Para comprobar este efecto, hemos simulado el motor en el programa de

y Pspice para observado su comportamiento.

simulado la midad del puente en H con el programa Pspice con transitores sin diodo volante, para verificar la hipotesis inicial. Como carga hemos conectado una red RL de caracteristicas similares al modelo de primer orden.

Figura 17. Ramal derecho puente H.

En la siguiente figura se pueden observar la evolución temporal de la tensión y de la la simulación del ramal derecho del puente en H (sin diodos

Figura 18. Resultado simulación Ramal derecho puente H.

Memoria descriptiva

Página 24

modifica el comportamiento del modelo del motor estudiado el motor en el programa de

con el programa Pspice con Como carga hemos

conectado una red RL de caracteristicas similares al modelo de primer orden.

de la tensión y de la del ramal derecho del puente en H (sin diodos

Resultado simulación Ramal derecho puente H.

Memoria descriptiva

Proyecto final de carrera Página 25

Podemos observar que justo en el flanco de bajada donde se produce la desconexión por parte del transistor darlingthon se genera un pico negativo de tensión, que corresponde a la corriente magnetizante de la carga intentando abrise camino por las uniones de los transistores. En el caso de no incorporar diodo volante, estos transistores podrían dañarse.

La simulación realizada es a titulo informativo y no es comparable en magnitud al estudio realizado del modelo del motor y su excitación, y a que la carga simulada no se ajusta totalmente al modelo anterior.

Siguiendo con el estudio, realizaremos una comparación para encontrar la diferencia entre ambas excitaciones, Pero cabe nombrar que el programa de simulación PSIM no incluye la librería para simular el motor de DC de imanes permanentes, soló el motor DC de excitación independiente, el cual hemos tenido que adaptar para conseguir las mismas características que el motor de nuestro modelo. Seguidamente especificamos los parámetros empleados.

Figura 19. Parámetros modelo motor DC para PSIM .

En la figura nº 20.1 mostramos el esquema de la excitación PWM sin diodo volante y en la figura nº 20.2 el esquema con el diodo incorporado.

Memoria descriptiva

Proyecto final de carrera Página 26

Figura 20. Circuito simulación comportamiento PWM sobre motor dc.

En la figura nº 21 podemos observar el resultado de la simulación sin diodo volante en los transistores de alimentación al motor. Se puede ver el pico de tensión negativa justo en la desconexión por parte de los transistores.

Figura 21. Tensión transistor de la excitación PWM sin diodo volante.

En la figura nº 22 se muestra la tensión del transistor con diodo volante incorporado. Se observa que el pico negativo justo en la desconexión del transistor se ha reducido considerablemente, concretamente a 1.4V que corresponde a la suma de la tensión en cada diodo en modo de conducción.

Cabe puntualizar que las magnitudes de los valores mostrados en las graficas 21 y 22 son magnitudes aproximadas ya que ha utilizado una carga de 1º orden similar al modelo del motor.

Memoria descriptiva

Proyecto final de carrera Página 27

Figura 22. Comparación entre modelos de la corriente armadura motor dc.

Visto que la alimentación del motor es de tipo pulsante y no de forma continua a causa del tipo de excitación, modificaremos el modelo para incluir esta variación del comportamiento.

Si reemprendemos el estudio del modelo de primer orden encontrado en la ecuación nº 15 e incluimos este efecto, tendremos el siguiente modelo [1]:

Figura 23. Esquema modelo + excitación.

Donde la función de transferencia es:

, " ! " 1 18

Memoria descriptiva

Proyecto final de carrera Página 28

Despreciando los términos resultantes del producto de frente al producto de " tendremos la ecuación:

, " !" 1 19

Donde sustituiremos las variables A y B para poder trabajar con más claridad en el modelo, quedando:

7 " L M !" 20

Si resolvemos el lazo de control del circuito anterior, obtendremos:

7M 11 7M 1

7M 1 7

77 1M7 1 1 21

Substituyendo con los datos obtenidos en los análisis anteriores tendremos como resultado final:

! 22,1 10@A 3² , " 4 10@D , 41,5 2 , 55,2 353/7

1959,73

0.35 1 22

Volviendo al tema que nos ocupaba al inicio del capítulo, la excitación PWM debe convertir una señal analógica con valor de == a una señal digital de periodo y amplitud constantes, obteniendo como resultado una señal con valor medio proporcional a la señal de entrada. Esta proporción se alcanza variando el tiempo de E y ajustando el tiempo de E conservando de esta manera el tiempo T constante sin variar el periodo de la señal.

La función de transferencia del sistema será:

3 ==E 23

Memoria descriptiva

Proyecto final de carrera Página 29

y su modelo en Simulink:

Figura 24. Esquema modelo PWM.

1.4.4 Conjunto Excitación PWM + motor DC

Como ya habremos podido intuir con los resultados vistos en el apartado anterior, la velocidad instantánea de nuestro motor se ve influida directamente por la frecuencia de la excitación PWM. Si observamos la figura nº 25 vemos unas fluctuaciones de velocidad que vienen causadas por los periodos de E y E del PWM.

Si alimentamos la entrada (m) del modulador PWM con una rampa unitaria observaremos en la respuesta del conjunto una amplia zona con fluctuaciones de velocidad [1]. En la figura nº 25 se muestra la gráfica de la velocidad de salida del sistema frente al ciclo de trabajo del la excitación PWM en forma de rampa con pendiente unitaria (multiplicando el eje X por un factor de 100 para observar mejor el efecto) donde se hacen presentes estas fluctuaciones.

Figura 25. Respuesta del sistema.

Memoria descriptiva

Proyecto final de carrera Página 30

Las fluctuaciones de velocidad que se observan son a consecuencia de una frecuencia relativamente baja de la excitación PWM. Conociendo que la constante mecánica del motor es de 30 ms y que el periodo del PWM es de 20 ms, surge este efecto a causa de la proximidad de ambos tiempos. Este efecto puede ser reducido aumentando la frecuencia de conmutación de la excitación.[1]

En la figura nº 24 se expone la evolución de la velocidad del motor y la señal del PWM de forma idealizada.

Figura 26. Evolución de la velocidad del motor

La evolución de la velocidad entre ambos tramos viene dada por la siguiente ecuación:

N O N NNP Q@R STU 24

donde N es la velocidad final a que llegaría el motor para tWX T y V[[ 10 , siendo N 1640 \]3 y zero en tW^^ T y V[[ 0 , NN es la velocidad inicial de partida y /es la constante de tiempo mecánica del motor.

Si consideramos que la constante de tiempo mecánica del motor es la misma para cuando el motor aumenta su velocidad que cuando disminuye, se deducen las siguientes ecuaciones:

_ N O N P Q@R STU ]`\` 0 a E a tWX 25

* Q@R STU ]`\` tWX a E a T 26

Considerando que para E tWX , _ * y que para E T, nos queda:

N 1 71 7 M 27

Memoria descriptiva

Proyecto final de carrera Página 31

* M 28

donde:

7 Q= bST 29

M Q@= bST 30

En la figura nº 27 mostramos el resultado de la simulación de las anteriores ecuaciones, obteniendo la relación existente del rizado de la velocidad * frente al ciclo de trabajo (dc).

Se puede observar claramente que cuanto mayor es la frecuencia de la excitación del PWM, menor es el rizado del motor, con lo que comporta que la frecuencia de conmutación no puede ser escogida a la ligera. A priori podríamos pensar que cuanto más elevada sea esta mejor, ya que tendríamos un rizado muy pequeño, pero se tienen que tener en cuenta otros factores, como por ejemplo, la resolución temporal de nuestro sistema…

En este caso, debemos tener en cuenta que el tic del sistema se utiliza para generar la onda de la excitación PWM, siempre que la frecuencia del PWM sea del orden de magnitud de 10 veces mayor que la resolución del sistema no se intuyen problemas en la generación de la onda de excitación del PWM. Por ejemplo un tic de 50μ y una frecuencia PWM de 0.53.

Figura 27. Rizado de velocidad en función del ciclo de trabajo

Memoria descriptiva

Proyecto final de carrera Página 32

1.4.5 El control PID

Las siglas del controlador responden a la identificación de las partes activas de este, definido por las letras PID (Proporcional – Integral – Derivativo). [2]

Donde:

- P es la acción de control proporcional y da una salida del controlador que es proporcional al error actual, respondiendo a la siguiente función de transferencia:

LE d QE 31

donde d es la constante proporcional ajustable.

- I es la acción de control integral y da una salida del controlador que es proporcional al error acumulado, respondiendo a la siguiente función de transferencia:

LE 1N e QE fR

0E 32

El bloque integral tiene como propósito disminuir y eliminar el error en estado estacionario provocado por el modo proporcional. El control integral actúa cuando hay una desviación entre la variable y el punto de consigna, integrando esta desviación en el tiempo y sumándola a la acción proporcional.

- D es la acción de control derivativo, la cual tiene un carácter de previsión al error con lo que hace más rápida la acción del controlador, aunque tiene la desventaja de amplificar las señales de ruido y provocar la saturación en el actuador. Esta responde a la siguiente función de transferencia:

LE f QEf E 33

Memoria descriptiva

Proyecto final de carrera Página 33

La suma de estas tres acciones responde a la función de transferencia:

LE d gQE 1N e QE fR

0E f QE

f E h 34

Este algoritmo será implementado por el alumnado dentro de las practicas de la asignatura, y formará parte del software que se elabore, no siendo una parte física de nuestra planta.

El algoritmo del controlador PID se tendrá que discretizar ya que será ejecutado en un sistema de procesado digital. De esta manera, la ecuación del controlador quedará de la siguiente manera:

∆L L LO 1 P 35

∆L Q *Q 1 BQ 2 36

d j1 N k , * d j1 2 k L B d 37

La ecuación nº 36 proporcionará al alumno el incremento que debe aplicar a la salida actual para corregir la respuesta del sistema. Si observamos la ecuación podremos ver que el controlador utiliza muestras anteriores del error para determinar el nuevo incremento en la salida, de esta forma sigue su evolución.

Para poder utilizar la función discretizada en Simulink debemos emplear la transformada zeta. Simulink ya dispone de bloques preestablecidos para la discretización de ecuaciones, veamos el esquema de bloques.

Figura 28. Unidad de retardo transformada zeta

A través de este bloque podremos realizar el retardo de una muestra, consiguiendo por ejemplo Q 1.

Memoria descriptiva

Proyecto final de carrera Página 34

En la siguiente figura mostramos la suma de todos los bloques del controlador, ya discretizados y en formato Simulink. Hemos enmarcado los bloques por funcionalidad para una mejor identificación.

Figura 29. Controlador PID discretizado

De la ecuación nº 36 podemos desgranar directamente este esquema, donde el bloque integrador multiplica el error actual por la constante /N, el bloque proporcional resta al valor actual del error el error anterior, resultando el incremento de error desde 1 a , y la parte diferencial tiene en cuenta la evolución de los incrementos en 1 y 2 y lo multiplica por la constante /.

Para un sistema de control con un amplio rango de condiciones de operación, puede suceder que la variable de control alcance los límites prefijados del actuador. Cuando esto pasa, el bucle realimentado permanece en su límite independientemente de la salida del proceso. Si se usa un controlador con acción integral, el error continuará siendo integrado, incrementando aún más su valor. Esto significa que el término integral puede volverse muy grande. Para evitar esta situación se inserta el bloque de saturación, el cual implementa el concepto de la saturación integral del controlador. Éste está ubicado al final del controlador para evitar entregar a la etapa siguiente cualquier valor superior al máximo de operación, pero por otro lado, este bloque también permite una operatividad permanente del controlador, al evitar la saturación de la variable controlada. Por otra parte, el bloque de retardo colocado en el bloque integrador tiene la función de implementar la integral, ya que tenemos que recordar que este algoritmo entrega a su salida en incrementos.

Las constantes ld, N, L juegan un papel importante en el comportamiento del controlador, pudiendo llevar el sistema a un error próximo a zero o por lo contrario llevarlo a la inestabilidad. La sintonización de estas variables no es una tarea fácil, por suerte hay herramientas para averiguar sus valores. Por ejemplo la técnica Ziegler-Nichols.

Memoria descriptiva

Proyecto final de carrera Página 35

1.4.6 Lazo de Control

La suma de todos los bloques anteriores forman el modelo completo de la planta y su realimentación para el lazo de control.

Figura 30. Modelo simulink lazo de control

Si procedemos a la simulación del conjunto global a una consigna concreta de 500 rpm observamos los siguientes resultados:

Figura 31. Salida modelo completo con control PI con PWM 50 Hz

Memoria descriptiva

Proyecto final de carrera Página 36

Este resultado se ha obtenido mediante un control proporcional e integral. Se puede observar que el resultado obtenido es muy próximo a la consigna al sistema. Existe un pequeño rizado que puede venir provocado por la frecuencia de la excitación PWM como ya se explico en su momento en el apartado nº 1.4.4, que en este caso es de 50 Hz

Si en cambio aumentamos la frecuencia de conmutación de la excitación a 100 Hz veremos que el rizado se reduce sensiblemente, y sin haber cambiado las constantes del controlador.

Figura 32. Salida modelo completo con control PI con PWM 100 Hz

1.4.7 Sintonización Controlador PID

Para sintonizar el controlador de la planta podemos utilizar el método diferentes métodos. [2]

Método basado en la respuesta temporal a un escalón en lazo abierto (Ziegler-Nichols).

Es un método grafico. Consiste en encontrar la respuesta del sistema en lazo abierto a un escalón. Seguidamente tendremos que observar el resultado y extraer los siguientes parámetros

Memoria descriptiva

Proyecto final de carrera Página 37

A través de la siguiente tabla podremos encontrar las diferentes constantes del controlador.

Controlador Kp Ti Td

P 1/a

PI 0.9/a 3·L

PID 1.2/a 2·L L/2

Método de la respuesta en lazo cerrado

Este método consiste en conocer la ubicación de los polos del sistema utilizando el criterio de Nyquist, e ubicar estos justo encima del eje imaginario, encontrando entonces los parámetros lm (ultima ganancia) y m (útimo periodo)

Para encontrar estos parámetros podemos proceder de la siguiente manera:

1. Eliminar las acciones integral y derivativa.

2. Aumentar k lentamente hasta que la planta empiece a oscilar. En el momento que se produzca la oscilación obtendremos los parámetros lm L m

A través de la siguiente tabla podremos encontrar los parámetros del

controlador:

Controlador Kp Ti Td

P 0,5·lm

PI 0,4·lm 0,8· m

PID 0,6·lm 0,5· m 0,125· m

Memoria descriptiva

Proyecto final de carrera Página 38

Método Empírico

Procederemos de la siguiente manera:

1. Eliminar del controlador las acciones integral y derivativa (Td=0, Ti=inf)

2. Aumentar K hasta que encontremos una respuesta de la planta satisfactoria, sin tener en cuenta el error estacionario.

3. Aumentar K y con la acción derivativa intentar recuperar la respuesta obtenida en el apartado anterior..

4. Repetir el anterior apartado hasta que k sea lo más grande posible.

5. Agregar la acción integral para eliminar el error en estado estacionario.

Memoria descriptiva

Proyecto final de carrera Página 39

1.4.8 Errores del sistema

1.4.8.1 PWM

Para poder obtener el menor rizado de velocidad en el eje del motor deberemos tener una excitación PWM con una regulación muy precisa. Este tipo de regulación implicará tener unos incrementos de E y E muy pequeños, en consecuencia necesitaremos un tic del sistema adecuado para poder generar estos tiempos [1].

Figura 33. Onda PWM

En la figura anterior se puede observar el efecto que provocaría el incremento de un tic en la velocidad del motor. Claramente, si el tiempo E es más grande el motor alcanzara una mayor velocidad, y su media se verá modificada.

Para examinar mejor este efecto, volveremos al estudio realizado en el apartado 1.4.4. donde extrajimos las siguientes formulas:

N 1 71 7 M 27

* M 28

donde:

7 Q= bST 29

M Q@= bST 30

Memoria descriptiva

Proyecto final de carrera Página 40

Las cuales nos ayudaran a través de una simulación de Matlab a ver la influencia de un tic en el tiempo de E.

dc=[0:0.01:1]; Taus=30e-3; Taub=500e-3; T=10e-3; A=exp(dc*(T/Taus)); B=exp((1-dc)*(T/Taub)); Wfin=1640; for n=1:101, W1(n)=Wfin*((1-A(n))/(1-A(n)*B(n))); W2(n)=B(n)*W1(n); end T=10e-3; tic=0.5e-3; x=(dc+(tic/T)); for m=1:101, if x(m)>1 x(m)=1; end end A=exp(x*(T/Taus)); B=exp((1-x)*(T/Taub)); Wfin=1640; for n=1:101, W3(n)=Wfin*((1-A(n))/(1-A(n)*B(n))); W4(n)=B(n)*W3(n); end figure(1) hold on; plot(dc,(W4-W2)); xlabel( 'Ciclo de Trabajo' ) ylabel( 'incremento (rpm)' ) hold off ;

Código 1. Simulación incremento velocidad respecto dc

En la siguiente figura podemos observar la influencia que tiene un incremento del ciclo de trabajo de dc de un solo tic frente a la velocidad del motor, pasando a ser un ciclo de trabajo de dc a n9 o Ep9/.

Memoria descriptiva

Proyecto final de carrera Página 41

Figura 34. Incremento de velocidad respecto el punto de trabajo y el tic

Dependiendo de la base de tiempo del sistema un solo incremento de E en una magnitud de tic, para un ciclo de trabajo pequeño causa un incremento de velocidad muy grande. Este efecto provoca una mala regulación de la velocidad y la posición del eje del motor. El objetivo deseado es la mayor resolución de la excitación PWM posible, para poder evitar estos saltos de velocidad en un solo incremento. Cuanto más pequeño sea el tic más resolución obtenemos y en consecuencia tenemos una mejor regulación.

Figura 34.1. Incremento de velocidad a causa del incremento de un tic

La frecuencia de la excitación PWM viene dada por:

1 1

q Ep9

la cual es la inversa de n veces la base de tiempos tic de nuestro sistema. Si disminuimos el valor de tic, aumentaremos el valor de n, consiguiendo una mejor resolución al tener un tiempo base tic más pequeño.

Memoria descriptiva

Proyecto final de carrera Página 42

En cuanto al error producido por un incremento de tic en el tiempo de E, cuanto más pequeño sea éste, menor desviación tendremos en el punto de trabajo dc de la excitación PWM.

Por ejemplo, con una frecuencia de excitación del PWM de 50 Hz y un ciclo de trabajo de 0,05 el error causado por un tic de 50μ es de:

n9 ∆Ep9 0,05 50μ

203 0,0525 F rs |0,05 0,0525|0,05 5%

En cambio, para un tic de 10μ, el error causado por el incremento del tic es de:

n9 ∆Ep9 0,05 10μ

203 0,0505 F rs |0,05 0,0505|0,05 1%

1.5 Emulador de la Planta

A causa del coste de los equipos del conjunto Motor-Encoder se dispone de unas unidades limitadas. Con el fin de facilitar al alumno la realización de las prácticas en los laboratorios o bien en horas no lectivas se decidió crear un emulador para substituir el equipo principal.

Este emulador es una placa electrónica de medidas reducidas que puede conectarse al puerto paralelo del PC, de forma que es substituible un equipo por otro sin realizar ningún cambio.

Este nuevo equipo debe generar las señales Ay B del encoder según la tensión media que aplique la excitación PWM, y la señal de petición de interrupción al puerto paralelo. Para facilitar el diseño se utilizó el modelo de primer orden de respuesta lineal, sin contemplar el efecto del PWM y el diodo volante del puente de alimentación [1].

En la siguiente figura mostramos la base del diseño para la creación de este emulador. En la fase inicial se decidió que el emulador no diferenciaría entre el giro de derechas e izquierdas. De aquí que los pines 2 y 3 de salida del PWM desde el PC se les aplica la función OR.

Memoria descriptiva

Proyecto final de carrera Página 43

Figura 35. Conversión señal PWM a frecuencia a través C.I 555

La siguiente etapa se instalo para realizar una separación entre el integrador y las señales de entrada.

Para dotar al emulador de unas características similares a las del motor se ha insertado un integrador con la misma constante de tiempo que tenía el sistema original, dotando de esta manera una dinámica parecida al conjunto del motor-encoder.

La tensión media del integrador responderá a la siguiente ecuación:

N 1 e N nE N v E 31

y su evolución temporal seguiría a una forma de onda parecida a la siguiente figura. (Orden y magnitud no comparables, sólo como ejemplo)

Figura 36. Señal de salida integrador

Memoria descriptiva

Proyecto final de carrera Página 44

Si fijamos que la función de transferencia del sistema de primer orden del motor es:

, 1150.03 1 32

y la función de transferencia del integrador:

,N 1w 1 1

/ 1 10.033 1 33

Donde las dos funciones de transferencia anteriores deberían de ser parecidas para poder tener una dinámica comparable.

La etapa de la fuente de corriente proporcionara la ganancia necesaria para equiparar las dos funciones de transferencia, donde esta suministrara una corriente de colector con valor:

= x y yzz x N 0.73300 34

El espejo de corriente se encargara de cargar el condensador de 33 nF con la misma intensidad que el colector de la fuente de corriente. Entonces la corriente de este dependerá de la tensión de salida del integrador, siendo:

= 1w e p=nE 1

w = E 35

Si consideramos que la corriente del condensador sigue una evolución con pendiente constante, tendremos que la tensión entre bornes será:

Figura 37. Tensión en bornes del condensador

Memoria descriptiva

Proyecto final de carrera Página 45

Donde nombraremos la amplitud de la señal entre 1/3 y 2/3 de Vcc con el nombre de A, que corresponderá a:

7 =w 36

donde despejaremos:

7 w= 37

y en consecuencia la frecuencia de la señal:

" =7 w 38

donde substituiremos el valor de =:

" 17 w N yzz 1

7 w N v E yzz 39

En este punto, si configuramos el oscilador C.I. 555 en formato de multivibrador estable obtendremos una señal de salida de este con una frecuencia de " 23.7 4, siendo w 33 q|,z 3,3 2, yz 0.7 y == > N v 5

Realizando este circuito hemos creado un oscilador controlado por tensión, que en consecuencia relaciona el ciclo de trabajo del PWM con la frecuencia de salida del oscilador.

El motor real considerado para la realización del emulador tiene una velocidad máxima de 1725 rpm, el cual tiene unido el encoder relativo con una resolución de 200 pulsos/revolución. Esta unión de elementos, a su máxima velocidad de funcionamiento según una tensión de alimentación de 15 V, nos supondría una frecuencia de " 200 AC0

D0 5750 4.

Esta frecuencia es del orden de 4 veces menor que la frecuencia del oscilador C.I.555, por lo que tendremos que dividir esa frecuencia para conseguir una frecuencia parecida al conjunto del motor-encoder.

Memoria descriptiva

Proyecto final de carrera Página 46

Para dividir esta frecuencia se han instalado unos biestables tipo D en cascada, los cuales dividirán la señal por 4 y generaran la señal en cuadratura parecida a la del encoder. También se tiene que incluir la detención de flancos para provocar la señal de la solicitud de interrupción IRQ-7, donde utilizaremos los circuitos estudiados en la figura nº 9.

Figura 38. Circuito Emulador

En la siguiente figura podemos observar la evolución de las señales que genera el emulador. Vemos la señal producida por el oscilador C.I.555 y cómo el biestable A1 reduce su frecuencia a la mitad, luego los biestable A2 y A3 generan la señal en cuadratura, y los detectores de flanco generan la señal para la petición de la interrupción IRQ-7.

Memoria descriptiva

Proyecto final de carrera Página 47

Figura 39. Relación de la evolución de las señales Emulador

1.6 Software de simulación de la Planta

La premisa del software realizado en el presente proyecto es la de simular el “comportamiento” de la planta descrita en el anterior apartado, facilitando la tarea de desarrollo de las practicas de la asignatura en horas no lectivas.

Figura 40. Concepto Simulador

Memoria descriptiva

Proyecto final de carrera Página 48

No es objeto del proyecto realizar una simulación del modelo matemático del conjunto motor dc + encoder, sino el crear unas librerías que simulen el comportamiento de la velocidad del motor respecto la alimentación recibida por la etapa de la excitación PWM, obteniendo como resultado las correspondientes señales del encoder.

El camino fijado para la realización del presente simulador ha sido el componer un código que interactúe el mínimo posible con el alumno que realiza las prácticas de la asignatura, de modo que éste no desvíe su atención en la utilización/comprensión del código del simulador.

De esta manera, el éxito del simulador será proporcional a su sencillez de utilización, pretendiendo confundir lo mínimo posible al alumno. Desafortunadamente, para el flujo de información entre el código creado del emulador y el código del alumno habrá una serie de restricciones, las cuales serán descritas más adelante.

1.6.1 Descripción del Software

Siguiendo por el camino de la sencillez, el código del simulador se ha implementado en ficheros de cabecera *.h para facilitar su uso. Estas librerías están formadas por un código fuente en forma de macros, siguiendo al estilo de las librerías facilitadas en la asignatura para la realización de las prácticas. Este hecho ha condicionado el desarrollo del simulador.

También se ha tenido en cuenta los diferentes modos de programación que se pueden utilizar en el entorno de Turbo C. Si el alumno ha realizado todo el código fuente directamente en el archivo main ( ), o por lo contrario, si el alumno ha escogido realizar un proyecto, separando en archivos el código fuente.

Para facilitar la realización del código del simulador se han atacado los diferentes problemas en dos librerías diferentes, desglosando en cada archivo las macros pertinentes. Formando 2 librerías nombradas Q5.h y k1.h donde en ellas reside tanto el código del simulador, como las funciones que debe utilizar el alumno para emplearlo.

Figura 41. Concepto Simulador

Memoria descriptiva

Proyecto final de carrera Página 49

El archivo nombrado Q5.h aborda el problema del modo de programación utilizado por el alumno (archivo main ( ) o proyecto) y el modo de funcionamiento del simulador (ON – OFF)

Por otra parte el archivo k1.h aborta al completo el código fuente para la simulación del comportamiento de la planta, incluyendo las macros de comunicación con el puerto paralelo “virtualizado”.

Debemos recordar que la razón de este proyecto reside en el problema de la accesibilidad del puerto paralelo. Por este motivo hemos “virtualizado” los registros del puerto paralelo ubicados en Base+0, Base+1 y Base+2 a un array de las mismas dimensiones, un array de 8+8+8 bits, como mostramos en la figura nº 42.

Figura 42. Virtualización del Puerto Paralelo

1.6.2 Librería Q5.h

La librería Q5.h tiene principalmente dos propósitos, solucionar:

- “Modo” de programación

- “Modo” de operación

Dependiendo de la opción escogida por el alumno en la realización del código fuente de las prácticas, tenemos que amoldar nuestro código para que él pueda compilar el código sin ningún error. En el entorno de Turbo C tenemos las siguientes opciones para realizar un archivo ejecutable:

- Realizar todo el código fuente en un archivo con extensión *.c el cual contendrá la función main ( ).

- Realizar un proyecto con diferentes archivos con extensión *.c y otro archivo con extensión *.c que contenga la función main ( )

Memoria descriptiva

Proyecto final de carrera Página 50

Para poder escoger entre las diferentes opciones de programación sin que fuera de difícil aplicación para el alumno, se creó la definición project. Mediante la inserción de esta definición, el alumno escoge de una manera simple y fácil el modo que utilizará.

La única diferencia entre las dos opciones es la declaración de las variables a utilizar por nuestro emulador. En el caso que el alumno sólo programara en un único archivo, este problema no existiría, pero si el alumno realizaba un proyecto, podría llegar el caso que durante la compilación del código surgiera un error por no tener las variables del emulador declaradas en diferentes archivos de código fuente.

Figura 43. Modo de Programación

#ifndef project hard_motor virtual_motor; //Declaració variable simulador void interrupt (*old_handler_prn2)(); /* mantiene el manejador original */ #else extern hard_motor virtual_motor;

#endif

Código 1. Parte código librería Q5.h

Mediante el código descrito anteriormente solucionamos el problema de la compilación. En el caso de haber utilizado un proyecto, se inserta la declaración #define Project, de esta manera, automáticamente se declara el puntero de la estructura de datos de forma externa en los diferentes archivos del proyecto realizado.

Inicio

Project defined?

Archivo Principal

Definir Variable como local

Archivo Secundario

Definir Variable como externa

Fin

NO SI

Memoria descriptiva

Proyecto final de carrera Página 51

En el anexo B se detalla las operaciones a realizar en cada caso, para facilitar el uso al alumno.

El otro problema abordado en esta librería es la funcionalidad del emulador. La premisa más importante de este proyecto era la de crear un simulador de la planta, donde fuese extremadamente sencillo cambiar de modo real a modo simulación.

Al inicio de las prácticas de la asignatura se hace entrega del tutorial de prácticas. En este tutorial se incluye una librería llamada “printer.h”, donde residen las macros necesarias para comunicarse con el puerto paralelo del PC, y así poder leer y escribir en el puerto. El problema surge cuando estamos utilizando un ordenador portátil, ya que normalmente no tienen accesible el puerto paralelo. De esta manera, nuestro simulador tendría que tener total compatibilidad con las macros existentes, de tal forma que a la hora de compilar no se produjeran errores.

Mediante la definición de una etiqueta pudimos reparar en la solución al problema. En el caso de que el alumno defina la etiqueta #define simula, nuestro código substituirá la librería “printer.h” por la nuestra llamada “k1.h”, equipada con las mismas declaraciones de macros para no provocar errores en la compilación. En caso contrario, si esta etiqueta no se ha definido, nuestro código incluirá la librería “printer.h” y sustituirá las declaraciones de las funciones utilizadas por el simulador por macros vacías, de esta forma no se tendrá que borrar la línea de dentro del código del alumno cada vez que pase de modo simulación a modo real.

Figura 44. ON-OFF simulador

Inicio

Simula defined?

Simulador RUN

Adjuntamos librería simulación

Simulador OFF

Adjuntamos Liberia printer.h

Fin

SI NO

Memoria descriptiva

Proyecto final de carrera Página 52

#ifdef simula #include "k1.h" #else #include "printer.h" #define ini_datos_sim() #define sim_motor() #define restaura()

#endif

Código 2. Parte código librería Q5.h

Por otra parte, en esta librería se define la estructura de datos hard_motor donde se declaran las variables necesarias para realizar la simulación.

typedef struct long count; //interval abans d'executar la funci¢ associada (micro seg) long recarga; //valor de recarrega double tic; //interval entre interrupcions(microseg) int direction; //direccion motor;izquierda- derecha-0 int vel_max_motor; //velocidad maxima nominal motor int puntos_encoder; //n§ ventanas del encorder por vuelta int index; //n§ de ventana en que se encuentra el encoder (0-3) unsigned int registroPRN[3]; //variable port virtualitzat

hard_motor;

Código 3. Parte código librería Q5.h

Donde la variable count será el valor resultante del cálculo definido por las variables de programa del ciclo de trabajo y la velocidad máxima del motor, interviniendo también la base de tiempos del sistema (tic)..

La variable recarga es el valor de recarga de la variable count una vez consumida. La variable tic hará referencia al tic que seleccione el alumno durante la ejecución de su programa, siendo la base de tiempo mínima para poder realizar los correspondientes timers.

La variable direction nos indicará el sentido del motor, a izquierdas o a derechas. La variable vel_max_motor tal y como indica su nombre, es el valor de velocidad máxima según la tensión de alimentación de nuestra fuente.

La variable index nos indica en qué ventana del encoder se encuentra el sistema en un momento dado. Se ha definido el orden de las ventanas en la siguiente figura:

Proyecto final de carrera

La variable registroPRNla información que dirigíamos antes a los registros del puerto paralelo.

registroPRN + 0:

Bit 7 Bit 6

Pin 9 Pin 8

registroPRN + 1:

Bit 7 Bit 6

/Pin 11 Pin 10 Pin 12

registroPRN + 2:

Bit 7 Bit 6

- -

Habiendo sustituido los tres registros del puerto paralelo mapeados en memoria por esta variable con igual tamaño.

Memoria descriptiva

Figura 45. Orden ventanas encoder

registroPRN es un array de 3 posiciones de 8 bits donde almacenaremos que dirigíamos antes a los registros del puerto paralelo.

Bit 5 Bit 4 Bit 3 Bit 2 Bit 1

Pin 7 Pin 6 Pin 5 Pin 4 Pin 3

Bit 5 Bit 4 Bit 3 Bit 2 Bit 1

Pin 12 Pin 13 Pin 15 - -

Bit 5 Bit 4 Bit 3 Bit 2 Bit 1

- IRQ /Pin 17 Pin 16 /Pin 14

Tabla 3. Registros del puerto paralelo

Habiendo sustituido los tres registros del puerto paralelo mapeados en memoria por esta variable con igual tamaño.

Memoria descriptiva

Página 53

es un array de 3 posiciones de 8 bits donde almacenaremos

Bit 0

Pin 2

Bit 0

-

Bit 0

/Pin 1

Habiendo sustituido los tres registros del puerto paralelo mapeados en memoria por

Memoria descriptiva

Proyecto final de carrera Página 54

1.6.3 Librería k1.h

En esta librería residen todas las funciones necesarias para poder simular el comportamiento de la planta estudiada, emulando la velocidad respecto la tensión de alimentación versus el ciclo de trabajo del PWM y las señales ocasionadas al respecto por el encoder.

En la cabecera de la librería se declaran unas etiquetas que nos ayudaran a simplificar las operaciones de escritura del código.

Seguidamente tenemos la macro llamada ini_datos_sim( ), que tal y como da a entender su nombre inicializa las variables de la estructura que contiene los datos necesarios para el funcionamiento del sistema.

Como puntos más importantes a destacar de la macro es la puesta a cero de la variable donde almacenaremos los datos que iban antes a los registros del puerto paralelo y la sustitución del puntero a la función asociada a la interrupción software del puerto paralelo, pudiendo provocar de esta manera interrupciones de este a nuestra voluntad. Consiguiendo de esta manera cerrar el lazo entre la información del “encoder” y el control de la velocidad del motor.

#define ini_datos_sim() *(virtual_motor.registroPRN+0)=0x00; *(virtual_motor.registroPRN+1)=0x00; *(virtual_motor.registroPRN+2)=0x00; virtual_motor.index=0; old_handler_prn2=_dos_getvect(0x17); _dos_setvect(0x17,cuadrat); virtual_motor.vel_max_motor=25; virtual_motor.puntos_encoder=800; virtual_motor.count=0; virtual_motor.recarga=0; virtual_motor.direction=d_derecha;

Código 4. Macro ini_datos_sim. Parte código librería k1.h

La base de tiempos utilizada a través de un temporizador del chip 8253 la cual se ha denominado como tic, que utiliza el alumno para realizar otros timers, no es una base de tiempo fijada.

Cada alumno puede escoger una base de tiempos tic de forma sensata y dentro de unos rangos. Este hecho condiciona totalmente nuestra forma de operar. A causa de no tener fijada una base de tiempo concreta, nuestro sistema tiene que ser flexible al cambio ésta.

Memoria descriptiva

Proyecto final de carrera Página 55

En relación a este hecho, tenemos la macro llamada cal_time_irq7( ).

#define cal_time_irq7() float x; x=virtual_motor.vel_max_motor*inf_pwm.dc; if (x<0) x=x*(-1); virtual_motor.direction=d_izquierda; else virtual_motor.direction=d_derecha; if (x==0) x=1; x=x*virtual_motor.puntos_encoder; x=(1/x)*1000000; x=x/h_timer.tic; virtual_motor.count=x+0.5; virtual_motor.recarga=virtual_motor.count;

Código 5. Macro cal_time_irq7. Parte código librería k1.h

Esta macro calcula el tiempo que asociaremos al timer count de la estructura de datos del tipo hard_motor. Este tiempo se determina a través de la velocidad máxima del motor (según su alimentación), el ciclo de trabajo determinado por el controlador PID, la resolución del encoder y finalmente por el tic escogido por el usuario.

9~qE 1qº nQ pqEQ\\~]99pqQ 5

Ep9 38

qº nQ pqEQ\\~]99pqQ 5 Q áv Rs n9 ]~qE_Qq9nQ\ 39

El timer count nos determinará el tiempo entre interrupciones asociadas a la función de interrupción software del IRQ 7.

Dependiendo de la velocidad que tenga el motor, este tiempo será mayor o menor. Es importante tener un tic pequeño para conseguir una buena resolución, ya que si por lo contrario tenemos un tic grande, como cabe esperar el rizado de velocidad será elevado.

qº nQ pqE. 5 3980 \Q3pq 1 3pq

60 800 ]~. Qq9nQ\ 53066 p\Q8 40

9~qE 15306635 10@D 0.53 íqp3 1 9~qE 1

35 10@D 28571 p\Q8 41

Proyecto final de carrera

Como se observa en las formulas anteriores, para la máxima velocidad del motor, con un tic de 35µs obtendríamos un error muy grande en la velocidad final dede tener un tic inapropiado para tener la resolución necesaria para esa velocidad.

La base principal del emulador es la macro llamada sim_motor( ). Esta origina las señales A y B que generaría el encoder, según el número de ventana ya especificado más arriba, provocando posteriormente la inmanera el lazo de control. En la

La llamada a esta macro debe insertarse al final de la rutina de atención a la interrupción IRQ0 realizada por el alumno, un lugar sencillo y que no entorpecerá la ejecución de su código.

Si observamos el diagrama de bloques de la página anterior, la variable clave esvariable count, la cual determina en qu07. Una vez transcurrido el tiempo, la macro recalcula el tiempo por si se ha variado el ciclo de trabajo. Dependiendo de la dirección establecida y de la ventanaencoder), se generarán las señales A y B correctamente al igual como haría el encoder, y se provocará una llamada a la interrupción software asociada a IRQ

De esta forma, cerramos el lazo de control sin modificar considerablemente el crealizado por el alumno. La clave reside en cambiar el vector que apunta a la interrupción hardware del puerto paralelo por el vector que apunta a la interrupción software de este.

En modo de utilización normal con el hardware activo, el alumno coloca el puntero de la función a asociada a la interrupción el puerto paralelo en el vector 0x0F de la tabla de vectores de interrupciones. El cambio función asociada a la interrupción IRQinterrupción, que corresponde a la interrupción software del puerto paralelo.

Memoria descriptiva

Como se observa en las formulas anteriores, para la máxima velocidad del motor, con un tic de 35µs obtendríamos un error muy grande en la velocidad final de

inapropiado para tener la resolución necesaria para esa velocidad.

Figura 46. Tiempo entre interrupciones IRQ07

La base principal del emulador es la macro llamada sim_motor( ). Esta origina las que generaría el encoder, según el número de ventana ya especificado más

arriba, provocando posteriormente la interrupción del puerto paralelo,En la figura 47 mostramos el diagrama de ejecución

sta macro debe insertarse al final de la rutina de atención a la interrupción IRQ0 realizada por el alumno, un lugar sencillo y que no entorpecerá la

Si observamos el diagrama de bloques de la página anterior, la variable clave es, la cual determina en qué instante debe provocarse una interrupción en IRQ

07. Una vez transcurrido el tiempo, la macro recalcula el tiempo por si se ha variado el ciclo de trabajo. Dependiendo de la dirección establecida y de la ventana

n las señales A y B correctamente al igual como haría el encoder, y se una llamada a la interrupción software asociada a IRQ-07.

De esta forma, cerramos el lazo de control sin modificar considerablemente el crealizado por el alumno. La clave reside en cambiar el vector que apunta a la interrupción hardware del puerto paralelo por el vector que apunta a la interrupción software de este.

En modo de utilización normal con el hardware activo, el alumno coloca el puntero de la función a asociada a la interrupción el puerto paralelo en el vector 0x0F de la tabla de vectores de interrupciones. El cambio el software de simulación coloca el puntefunción asociada a la interrupción IRQ-7 en el vector 0x17 de la tabla de vectores de interrupción, que corresponde a la interrupción software del puerto paralelo.

Memoria descriptiva

Página 56

Como se observa en las formulas anteriores, para la máxima velocidad del motor, con un tic de 35µs obtendríamos un error muy grande en la velocidad final de éste, a causa

inapropiado para tener la resolución necesaria para esa velocidad.

La base principal del emulador es la macro llamada sim_motor( ). Esta origina las que generaría el encoder, según el número de ventana ya especificado más

terrupción del puerto paralelo, cerrando de esta mostramos el diagrama de ejecución.

sta macro debe insertarse al final de la rutina de atención a la interrupción IRQ0 realizada por el alumno, un lugar sencillo y que no entorpecerá la

Si observamos el diagrama de bloques de la página anterior, la variable clave es la instante debe provocarse una interrupción en IRQ-

07. Una vez transcurrido el tiempo, la macro recalcula el tiempo por si se ha variado el ciclo de trabajo. Dependiendo de la dirección establecida y de la ventana actual (señales

n las señales A y B correctamente al igual como haría el encoder, y se

De esta forma, cerramos el lazo de control sin modificar considerablemente el código realizado por el alumno. La clave reside en cambiar el vector que apunta a la interrupción hardware del puerto paralelo por el vector que apunta a la interrupción software de este.

En modo de utilización normal con el hardware activo, el alumno coloca el puntero de la función a asociada a la interrupción el puerto paralelo en el vector 0x0F de la tabla de

el software de simulación coloca el puntero de la 7 en el vector 0x17 de la tabla de vectores de

interrupción, que corresponde a la interrupción software del puerto paralelo.

Memoria descriptiva

Proyecto final de carrera Página 57

Figura 47. Diagrama ejecución IRQ 0

Llamada Rutina

Sim_motor ( )

Count=0 ?

Count --

Calcula tiempo Tiner según dc

PWM

Dirección ?

Genera señales

A y B

Provoca soft interrupt puerto

paralelo

Fin rutina atención IRQ-0

Genera señales

A y B

Provoca soft interrupt puerto

paralelo

NO

SI

DERECHA IZQUIERDA

Rutina atención IRQ0

Memoria descriptiva

Proyecto final de carrera Página 58

El código fuente de la macro es el siguiente:

#define sim_motor() if (!virtual_motor.count) cal_time_irq7(); virtual_motor.count=virtual_motor.recarga; if (virtual_motor.direction==d_derecha) switch (virtual_motor.index) case 0: *(virtual_motor.registroPRN+1)=0x20; geninterrupt(0x17); virtual_motor.index++; break ; case 1: *(virtual_motor.registroPRN+1)=0x30; geninterrupt(0x17); virtual_motor.index++; break ; case 2: *(virtual_motor.registroPRN+1)=0x10; geninterrupt(0x17); virtual_motor.index++; break ; case 3: *(virtual_motor.registroPRN+1)=0x00; geninterrupt(0x17); virtual_motor.index=0; break ; if (virtual_motor.direction==d_izquierda) switch (virtual_motor.index) case 0: *(virtual_motor.registroPRN+1)=0x10; geninterrupt(0x17); virtual_motor.index++; break ; case 1: *(virtual_motor.registroPRN+1)=0x30; geninterrupt(0x17); virtual_motor.index++; break ; case 2: *(virtual_motor.registroPRN+1)=0x20; geninterrupt(0x17); virtual_motor.index++; break ; case 3: *(virtual_motor.registroPRN+1)=0x00; geninterrupt(0x17); virtual_motor.index=0; break ; else virtual_motor.count--;

Código 6. Macro sim_motor. Parte código librería k1.h

Memoria descriptiva

Proyecto final de carrera Página 59

A partir de este punto, tenemos que cambiar las macros que trabajaban con los registros del puerto paralelo (datos de partida en las practicas de la asignatura) por macros con igual identidad, pero cambiando su interior para operar con nuestra variable llamada registroPRN de la estructura de datos virtual_motor.

Por ejemplo la macro llamada pulse_on_a( ) la cual tenía por función alimentar la parte derecha del puente de transistores. La metodología de la operación a realizar es la misma que la original, pero sobre la variable registroPRN en vez del registro del puerto paralelo.

#define pulse_on_a() *(PRN_BASE)=((*(PRN_BASE)&PULSEOFF_B)|PULSEO N_A); virtual_motor.direction=d_derecha;

Código 7. Macro pulse_on_a. Parte código librería k1.h

Por otra parte, al contrario que la operación anterior, se anula la alimentación a la parte derecha del puente de transistores. #define pulse_off_a() *(PRN_BASE)=(*(PRN_BASE))&PULSEOFF_A; virtual_motor.direction=d_stop;

Código 8. Macro pulse_off_a. Parte código librería k1.h

Es importante transformar todas las macros existentes en el archivo printer.h suministrado al principio de las practicas, porque durante el cambio de modo entre sistema real y sistema en emulador no surjan errores de compilación por no tener declaradas las macros.

El resto de macros serán comentadas en el anexo B, donde estará especificado todo el código del emulador.

Memoria descriptiva

Proyecto final de carrera Página 60

1.7 Modo de Uso

Para poder utilizar este simulador y sus librerías existen unas restricciones de uso. A causa del flujo necesario de información entre el código que realice el alumno y las librerías del simulador, es necesario definir las variables nombradas de la siguiente forma:

Figura 48. Restricciones de Uso

De no ser así, el programa de compilación retornará diferentes errores por variables no declaradas y no se generará el fichero ejecutable.

- El puntero a la estructura HARD_TIMER debe llamarse h_timer

- El puntero a la estructura SOFT_TIMER debe llamarse s_timer

- El puntero a la estructura PWM debe llamarse inf_pwm

- El puntero a la estructura PID debe llamarse inf_pid

Memoria descriptiva

Proyecto final de carrera Página 61

En el caso que el alumno haya decidido realizar la programación de las prácticas en un solo archivo con extensión *.c, donde residan todas sus funciones y macros, deberá realizar estos ajustes en su código de programa para poder utilizar el simulador.

Figura 49. Cambios en el código

Estos ajustes sólo se deberán realizar la primera vez que utilice el simulador. Las macros insertadas son inertes en caso que el simulador esté en modo de no operación.

- Insertar definición: # define simula

- Incluir librería: #include “q5.h” , NO incluir la librería “Printer.h”

- Insertar llamada a función de inicialización simulador: ini_datos_sim ( ) (Esta debe ubicarse después de las pertinentes inicializaciones de todas las variables del programa realizado por el alumno)

- Insertar llamada a función de restauración: Restaura_sistema ( ) (Debe ubicarse al final del programa)

- Insertar llamada a función para ejecutar el simulador: sim_motor ( ) (Esta debe ubicarse al final de la rutina de atención IRQ 0 realizada por el alumno)

Memoria descriptiva

Proyecto final de carrera Página 62

En el caso que el alumno haya decidido realizar la programación con la modalidad de proyecto, teniendo un archivo base *.c con la correspondiente función main() más archivos complementarios con extensión *.c donde residan funciones varias deberá seguir esta guía de ejemplo para realizar los cambios necesarios en el código para utilizar el simulador.

Ejemplo de proyecto formado por: Archivo Main.c + Archivo Timer.c + Archivo Ini_IRQ.c + Archivo PID.c + Archivo PWM.c

Cambios a realizar en archivo Main.c:

- Insertar definición: # define simula - Incluir librería: #include “q5.h” - Insertar llamada a función de inicialización simulador: ini_datos_sim ( )

(Esta debe ubicarse después de las pertinentes inicializaciones de todas las variables del programa realizado por el alumno)

- Insertar llamada a función de restauración: Restaura_sistema ( ) (Debe ubicarse al final del programa)

Cambios a realizar en archivo Timer.c:

(Este archivo contiene la rutina de atención a la interrupción IRQ 0)

- Insertar definición: # define simula - Insertar definición: # define Project - Incluir librería: #include “q5.h”

- Insertar llamada a función para ejecutar el simulador: sim_motor ( ) (Esta debe ubicarse al final de la rutina de atención IRQ 0 realizada por el alumno)

Cambios a realizar en archivo Ini_IRQ.c:

- Insertar definición: # define simula - Insertar definición: # define Project - Incluir librería: #include “q5.h”

Cambios a realizar en archivo PID.c:

- Insertar definición: # define simula - Insertar definición: # define Project - Incluir librería: #include “q5.h”

Cambios a realizar en archivo PWM.c:

- Insertar definición: # define simula - Insertar definición: # define Project - Incluir librería: #include “q5.h”

Memoria descriptiva

Proyecto final de carrera Página 63

Estos ajustes sólo se deberán realizar la primera vez que utilice el simulador. Las macros insertadas son inertes en caso que el simulador este en modo OFF.

Una vez realizados los cambios, para poder utilizar el simulador se debe operar de la siguiente manera:

Figura 51. ON/OFF simulador

- Simulador OFF -> // #define simula (Comentar definición para no ser compilada)

- Simulador ON -> #define simula

(La definición debe ser compilada)

Memoria descriptiva

Proyecto final de carrera Página 64

En el anexo C del presente proyecto adjuntamos todo el código de la práctica nº 4 de la asignatura Informática Industrial II para utilizar este simulador.

Proyecto final de carrera Página 65

2 Anexo A

Anexo B

Proyecto final de carrera Página 66

2.1 El motor de corriente continua

En el siguiente anexo describiremos brevemente el motor de corriente continua y sus principales características de manera que el alumnado pueda comprender más fácilmente los parámetros que identifican a este tipo de motores. [2]

El motor de corriente continua de imanes permanentes se compone principalmente de dos partes, una parte exterior llamada estator, la cual da soporte mecánico al aparato, y un núcleo llamado rotor, el cual es la parte móvil del motor.

El estator está formado por unos imanes permanentes de altas prestaciones de polos opuestos, enfrentado entre ellos, los cuales provocan unas líneas de fuerza entre N-S de los respectivos imanes.

En cambio el rotor está formado por un núcleo de hierro devanado con unas espiras de conductor eléctrico, generalmente cobre, que son alimentadas a través de dos escobillas.

El movimiento del rotor viene ocasionado por la acción derivada de la repulsión y atracción entre polos magnéticos. Creando campos constantes convenientemente orientados en estator y rotor, se origina un par de fuerzas que obliga a que el rotor gire buscando la posición de equilibrio.

Figura 52. Motor de corriente continua.

A la hora de interpretar una hoja de características de un motor de corriente continua es conveniente conocer el significado de cada parámetro, para ello, describiremos los más significativos.

Potencia nominal asignada:

Esta cifra representa la máxima potencia de salida cuando se opera dentro del rango de trabajo recomendado. Unidad de medida internacional expresada en watios (w) Tensión nominal:

Anexo B

Proyecto final de carrera Página 67

Es el voltaje al cual se han medido los datos nominales (velocidad en vacío, par de arranque, corriente de arranque, máx. potencia de salida, máx. rendimiento). Se ha escogido este dato para no exceder la máxima velocidad recomendada en vacío. Por supuesto, el uso del motor no está limitado a este voltaje. Para alcanzar la potencia nominal asignada se permiten voltajes de trabajo más elevados. La velocidad en vacío, par de arranque y corriente de arranque dependen directamente del voltaje aplicado. Unidad de medida internacional expresada en voltios (V) Velocidad en vacío:

Es la velocidad a la que gira el motor cuando no tiene carga y se le aplica la tensión nominal. En la práctica, esta velocidad es proporcional al voltaje aplicado (constante de velocidad). Unidad de medida internacional expresada en rpm. Par de arranque:

Es el par teórico a la tensión nominal y con el rotor bloqueado. El par de arranque aumenta proporcionalmente con el voltaje aplicado. El valor dado corresponde a una temperatura del rotor de 25°C. El par de arranque está relacionado con la corriente de arranque. Su conexión es la constante de par km Simbolizado con las siglas Mh y la unidad de medida internacional esta expresada en Nm (newton metro) Relación velocidad/par:

La relación velocidad/par da información de las prestaciones del motor y se representa por la línea (o curva) velocidad-par. Cuanto más pequeño es este valor, más potente es el motor, y consecuentemente menor es la variación de la velocidad del motor con los cambios en la carga. La constante velocidad/par depende de las prestaciones del circuito magnético (ej: imán permanente), de las dimensiones del bobinado (longitud, diámetro, número de espiras) y de la resistencia del bobinado. En la práctica, la constante velocidad/par se puede obtener dividiendo la velocidad en vacío entre el par de arranque. Simbolizado con las siglas n/M y la unidad de medida internacional esta expresada en rpm/Nm Corriente en vacío:

Anexo B

Proyecto final de carrera Página 68

Esta es la corriente que consume el motor sin carga, alimentado a su tensión nominal. Simbolizado con las siglas Io y la unidad de medida internacional esta expresada en Amperios (A) Corriente de arranque:

Es el cociente entre el voltaje nominal U y la resistencia en bornes Ra. Esta corriente es proporcional al par de arranque. Ambas magnitudes están relacionadas mediante la constante de par km. Simbolizado con las siglas IA y la unidad de medida internacional esta expresada en Amperios (A) Resistencia en bornes:

Es la resistencia en los terminales a 25°C y determina la corriente de arranque a un voltaje dado. La resistencia entre bornes es un valor compuesto por la resistencia del bobinado, la resistencia de la escobilla y la resistencia de contacto entre la escobilla y el colector. Simbolizado con las siglas Ra y la unidad de medida internacional esta expresada en Ohmios (Ω) Velocidad máxima permitida:

Esta velocidad representa el límite superior del rango recomendado de funcionamiento y no debería ser excedida durante el funcionamiento normal del motor. La velocidad está limitada principalmente por la conmutación. Si el motor gira a velocidades superiores pueden aparecer problemas de conmutación, que a su vez pueden llevar a reducir la vida útil del motor. Esto es debido a los siguientes factores: 1.- Aumento del desgaste mecánico debido a que la distancia recorrida por el colector es mayor. 2.-Aumento del desgaste por electro-erosión debido a la vibración de las escobillas y la formación de chispas. Simbolizado con las siglas nmax y la unidad de medida internacional esta expresada en rpm

Máxima corriente en servicio continuo:

Anexo B

Proyecto final de carrera Página 69

Si el motor funciona continuamente con esta corriente y a 25°C de temperatura ambiente, se calentará hasta alcanzar la máxima temperatura del bobinado. Se asume que el motor no tiene refrigeración adicional, sin otras piezas que hagan de radiador de calor y aumenten este valor sustancialmente. Un aumento de la temperatura ambiente reduce la corriente máxima en continuo. Los bobinados con baja resistencia óhmica admiten corrientes más altas que los bobinados con alta resistencia. En motores con bobinados de resistencia baja, la máxima corriente en continuo puede estar limitada por las escobillas y no por el bobinado. La máxima corriente en continuo es equivalente al máx. par permanente. Están relacionados por la constante de par km. Simbolizado con las siglas Imax y la unidad de medida internacional esta expresada en Amperios (A) Máxima par en servicio continuo:

Es el par que se puede entregar continuamente, o de media, alcanzando en el bobinado la máxima temperatura admisible, basado en una temperatura ambiente de 25°C. A temperatura ambiente más alta, este valor se reduce. El par máximo limita el rango recomendado de funcionamiento. Simbolizado con las siglas Mcont y la unidad de medida internacional esta expresada en Nm (newton metro) Máxima potencia de salida:

Es la máxima potencia teórica a 25°C de temperatura del rotor. La máxima potencia se alcanza en la mitad del par de arranque y la mitad de la velocidad en vacío. Los límites permitidos (máx. corriente en continuo y máx. velocidad permitida) frecuentemente están por debajo de este nivel. Simbolizado con las siglas Pmax y la unidad de medida internacional esta expresada en watios (w) Constante de par:

Representa la relación del par generado y la corriente aplicada. La constante de par transforma valores de par en valores de corriente y viceversa. En la práctica, km se determina por el par de arranque MH y la corriente de arranque Ia. En el cálculo teórico, han de tomarse en consideración las dimensiones del bobinado (longitud l, diámetro 2r, número de espiras w), así como la fuerza del campo magnético. La constante de par está relacionada con la constante de velocidad kn ya que ambas están determinadas por los mismos parámetros. Simbolizado con las siglas km y la unidad de medida internacional esta expresada en Nm/A (Newton metro por Amperio)

Anexo B

Proyecto final de carrera Página 70

Constante de velocidad:

Muestra la velocidad específica por voltio del voltaje aplicado sin contar las pérdidas por fricción. En la práctica, kn se determina por el voltaje nominal U y la velocidad en vacío n0. En el cálculo teórico, deben tenerse en cuenta las dimensiones del bobinado (longitud, diámetro, número de espiras, w), así como la fuerza del campo magnético B0. La constante de velocidad está relacionada con la constante de par km porque éstas se determinan por los mismos parámetros. Simbolizado con las siglas kn y la unidad de medida internacional esta expresada en rpm/V (revoluciones por minuto por Voltio) Inercia del motor:

Es el momento de inercia del rotor, basado en el eje de giro. Determina la constante de tiempo mecánica del motor. Simbolizado con las siglas JR y la unidad de medida internacional esta expresada en km² (kilos por metro cuadrado) Constante de tiempo mecánica:

Es el tiempo que tarda el rotor en acelerar desde parado hasta el 63% de la velocidad en vacío. Este valor se calcula desestimando las fricciones, carga e inercia de la carga.

Transcurridas 4 veces este valor (τ) el rotor habrá alcanzado más del 99% de la velocidad en vacío. La constante mecánica de tiempo se puede calcular con la inercia del rotor y el gradiente velocidad-par

Simbolizado con las siglas τm y la unidad de medida internacional esta expresada en milisegundos (ms) Inductancia entre bornes:

Es la inductancia del bobinado estacionario y medida con una onda senoidal de 1 kHz. Simbolizado con las siglas La y la unidad de medida internacional esta expresada en Henrios (H) Constante eléctrica:

Anexo B

Proyecto final de carrera Página 71

La inductancia entre bornes y la resistencia entre bornes determina la constante eléctrica de tiempo del motor. Este parámetro se refiere al tiempo requerido por la corriente para aumentar o disminuir. Típicamente, la constante eléctrica de tiempo es de 100 a 1.000 veces más pequeña que la constante mecánica de tiempo. Los cambios de corriente ocurren instantáneamente comparados con los cambios en velocidad. Un fenómeno a destacar cuando la corriente puede reaccionar de manera tan rápida, es el caso de los motores que son alimentados mediante PWM. En algunas ocasiones se puede producir un rizo de corriente no deseado que sobrecalienta al motor. En estos casos, puede que sea necesario aumentar la frecuencia del PWM o conectar una inductancia adicional. Simbolizado con las siglas ke

Proyecto final de carrera Página 72

3 Anexo B

Anexo B

Proyecto final de carrera Página 73

3.1 Código Librería Q5.h

#ifdef simula //Mode de funcionament simulador ON- #include "k1.h" //ON-OFF segons si es declara la #else //definicio #include "printer.h" #define ini_datos_sim() #define sim_motor() #endif typedef struct //Estructura de dades necesaries pel //funcionament del simular soft long count; //Interval de Temps abans d'executar //la funci¢ associada (micro seg) long recarga; //Valor de recarrega double tic; //Interval entre //interrupcions(microseg) int direction; //Direccio motor;Izquierda-Derecha-0 int vel_max_motor; //Velocidad maxima nominal motor int puntos_encoder; //num. Finestres del encorder per //volta int index; //nº de finestra en que es troba en //un instant el encoder (0-3) unsigned int registroPRN[3]; //Variable port paral·lel //virtualitzat hard_motor; #ifndef project //En cas de projecte declara la //variable con a interna o externa //del arxiu en questió hard_motor virtual_motor; void interrupt (*old_handler_prn2)(); //Mante el punter original #else extern hard_motor virtual_motor;

#endif

Anexo B

Proyecto final de carrera Página 74

3.2 Código Librería K1.h

#define PRN_IRQ_MASK 0x10 //Mascara interrupcions pin 10 //DB-25 #define PULSEON_A 0x01 //ON de pin 2 DB25 #define PULSEOFF_A ~PULSEON_A //Pulsos de control en pin 2 //DB-25 #define PULSEON_B 0x02 //On de pin 3 DB25 #define PULSEOFF_B ~PULSEON_B //Pulsos de control en pin 3 //DB-25 #define INI_PRN 0xFF //11111111 Inicializacio del //port_base+ 1 de prn #define VCC_ON 0xFC //Pines 2 y 3 a zero i pins //4...9 a ú DB25 #define VCC_OFF 0x00 //Pines 2...9 a zero DB25 #define MASK 0x80 //Mascara per confirmacio de //int #define CUADRAT_MASK 0x30 //Mascara bits 4 y 5 de //cuadratura (pins 12 y 13) #define d_derecha 1 //Direccio motor a dreta #define d_izquierda 2 //Direcció motor Esquerra #define d_stop 0 //Motor Parat #define PRN_BASE virtual_motor.registroPRN //Etiqueta a la direccio del //registre soft virtual PRN #define PRN_VERIFI (virtual_motor.registroPRN+1) //Etiqueta a la direccio del //registre soft virtual PRN+1 #define PRN_IRQ (virtual_motor.registroPRN+2) //Etiqueta a direcció del //registre soft virtual PRN+2 //------------------------------------------------- --------------------- // ini_datos_sim: // Inicialitza datos principals del similador //------------------------------------------------- --------------------- #define ini_datos_sim() \ *(virtual_motor.registroPRN+1)=0x00; \ virtual_motor.index=0; \ old_handler_prn2=_dos_getvect(0x17); \ _dos_setvect(0x17,cuadrat); \ virtual_motor.vel_max_motor=25; \ virtual_motor.puntos_encoder=800; \ virtual_motor.count=0; \ virtual_motor.recarga=0; \ virtual_motor.direction=d_derecha; \

Anexo B

Proyecto final de carrera Página 75

//------------------------------------------------- ---------------------- //cal_time_irq7: // Funcio que determina el temps entre l es interrupcions // irq7 realitzades pel encoder virtual en funcio del // dc del pwm, tic hardware timer i vel. ma x. del motor cc //------------------------------------------------- ---------------------- #define cal_time_irq7() \ float x; \ x=virtual_motor.vel_max_motor*inf_pwm.dc; \ if (x<0) \ \ x=x*(-1); \ virtual_motor.direction=d_izquierda; \ \ else \ virtual_motor.direction=d_derecha; \ if (x==0) x=1; \ x=x*virtual_motor.puntos_encoder; \ x=(1/x)*1000000; \ x=x/h_timer.tic; \ virtual_motor.count=x+0.5; \ virtual_motor.recarga=virtual_motor.count;\ //------------------------------------------------- ---------------------- //sim_motor: // Funcio que simula les senyales A i B del encorder en el port // PRN virtual i genera la interrupcio irq7 //------------------------------------------------- ---------------------- #define sim_motor() \ \ if (!virtual_motor.count) \ \ cal_time_irq7(); \ virtual_motor.count=virtual_motor.recarga; \ if (virtual_motor.direction==d_derecha) \ \ kk1++; \ switch (virtual_motor.index) \ \ case 0: \ *(virtual_motor.registroPRN+1)=0x20; \ geninterrupt(0x17); \ virtual_motor.index++; \ break ; \ case 1: \ *(virtual_motor.registroPRN+1)=0x30; \ geninterrupt(0x17); \ virtual_motor.index++; \ break ; \ case 2: \ *(virtual_motor.registroPRN+1)=0x10; \ geninterrupt(0x17); \ virtual_motor.index++; \ break ; \ case 3: \ *(virtual_motor.registroPRN+1)=0x00; \ geninterrupt(0x17); \ virtual_motor.index=0; \ break ; \ \

Anexo B

Proyecto final de carrera Página 76

\ if (virtual_motor.direction==d_izquierda) \ \ switch (virtual_motor.index) \ \ case 0: \ *(virtual_motor.registroPRN+1)=0x10; \ geninterrupt(0x17); \ virtual_motor.index++; \ break ; \ case 1: \ *(virtual_motor.registroPRN+1)=0x30; \ geninterrupt(0x17); \ virtual_motor.index++; \ break ; \ case 2: \ *(virtual_motor.registroPRN+1)=0x20; \ geninterrupt(0x17); \ virtual_motor.index++; \ break ; \ case 3: \ *(virtual_motor.registroPRN+1)=0x00; \ geninterrupt(0x17); \ virtual_motor.index=0; \ break ; \ \ \ \ else \ \ virtual_motor.count--; \ \ //------------------------------------------------- ------------------ //pulse_on_a() pin 2 DB-25 a '1' i pin 3 DB-25 a 'O ' //------------------------------------------------- ------------------ #define pulse_on_a() \ \ *(PRN_BASE)=((*(PRN_BASE)&PULSEOFF_B)|PULSEON_ A); \ virtual_motor.direction=d_derecha; \ /*------------------------------------------------- - pulse_off_a() pin 2 DB-25 a 'O' --------------------------------------------------- -*/ #define pulse_off_a() \ *(PRN_BASE)=(*(PRN_BASE))&PULSEOFF_A; \ virtual_motor.direction=d_stop; \ /*------------------------------------------------- -- pulse_on_b() pin 3 DB-25 a '1' i pin 2 DB-25 a 'O' --------------------------------------------------- */ #define pulse_on_b() \ *(PRN_BASE)=(((*(PRN_BASE))&PULSEOFF_A)|PULSE ON_B); \ virtual_motor.direction=d_izquierda; \

Anexo B

Proyecto final de carrera Página 77

/*------------------------------------------------- -- pulse_off_b() pin 3 DB-25 a 'O' --------------------------------------------------- -*/ #define pulse_off_b() \ *(PRN_BASE)=((*(PRN_BASE))&PULSEOFF_B); \ virtual_motor.direction=d_stop; \ /*------------------------------------------------- -- ini_prn() pins 2 i 3 a zero (PWM), pins 4 i 5 a ú ( cuadrat), pins 6 a 9 a ú (VCC=ON) --------------------------------------------------- --*/ #define ini_prn() \ *(PRN_BASE+1)=INI_PRN; \ /*------------------------------------------------- ---- verifi() pin 11 -BUSY -DB-25. Utilitzat com a comfi rmació de int --------------------------------------------------- ---*/ //#define verifi() (inportb(PRN_VERIFI)&MASK) #define verifi() /*------------------------------------------------- ---- cuadrat_leer() pin 12 Data_5 i pin 13 Data_4,info d e cuadratura --------------------------------------------------- ----*/ #define cuadrat_leer() ((((*(PRN_BASE+1))&CUADRAT_MASK)>>4 )) /*------------------------------------------------- ------- vcc_on() pins 2 i 3 a zero i pins 4...9 a ú DB 25 --------------------------------------------------- ------*/ //# #define vcc_on() \ *(PRN_BASE)=VCC_ON; \ /*------------------------------------------------- ------- vcc_off() pines 2...9 a zero DB 25 --------------------------------------------------- ------*/ #define vcc_off() \ *(PRN_BASE)=VCC_OFF; \ /*------------------------------------------------- ------- en_i_prn(): Es valida la interrupcio de prn pin 10 DB-25 --------------------------------------------------- ------*/ #define en_i_prn() \ *(PRN_IRQ)=((*(PRN_BASE))|PRN_IRQ_MASK); \ /*------------------------------------------------- ------- dis_i_prn(): Inibeix interrupcions des de prn --------------------------------------------------- ------*/ #define dis_i_prn() \ *(PRN_IRQ)=((*(PRN_BASE))&~PRN_IRQ_MASK); \

Proyecto final de carrera Página 78

4 Anexo C

Anexo C

Proyecto final de carrera Página 79

4.1 Librería 8259.h /*------------------------------------------------- -------------------- FILE: 8259.h -declaraciones y macros para el chip 8259 MACROS: mask_prn_off() - desactiva m scara IRQ7 mask_prn_on() - activa m scara IRQ7 mask_prn() - devuelve el estado de la m scara IRQ7 eoi_ns() - fin de interrupci¢n no esp ec¡fica eoi_prn() - fin de interrupci¢n espec¡ fica IRQ7 eoi_timer() - fin de interrupci¢n espec¡ ficaIRQO --------------------------------------------------- --------------------*/ #define BASE_8259 0x20 /* direcci¢n base */ #define PORT_EOI (BASE_8259+0) /* puerto para EOI */ #define PORT_MASK (BASE_8295+1) /* puerto para mascaras */ #define VECT_BASE 8 /* vector base */ #define VECT_TIMER (VECT_BASE+O) /* vector del timer 8253 */ #define VECT_PRN (VECT_BASE+7) /* vector de impresora */ #define MASK_TIMER 0x0l /* M scara para timer */ #define MASK_PRN 0x80 /* M scara para impresora */ #define EOI_TIMER 0x60 /* F¡n de interrup. para timer */ #define EOI_PRN 0x67 /* F¡n de interrup. para inpresora */ #define EOI_NS 0x20 /* F¡n deinterrup. no espec¡fica /*------------------------------------------------- ------- mask_prn_off() desactiva la m scara permitiendo las interrupciones. --------------------------------------------------- ------*/ #define mask_prn_off() (outportb(BASE_8259+1,(inportb(BASE_8259+1)&~MASK_P RN))) /*------------------------------------------------- -------- mask_prn_on() activa la m scara bloqueando las inte rrupciones. --------------------------------------------------- -------*/ #define mask_prn_on() (outportb(BASE_8259+1,(inportb(BASE_8259+1)|MASK_PR N)) /*------------------------------------------------- --------- mask_prn() devuelve 1 si m scara activa y O en caso contrario --------------------------------------------------- ----------*/ #define mask_prn() (((inportb(BASE_8259+1>>7)&0x0l) /*------------------------------------------------- ----------- eoi_ns() fin de interrupci¢n no espec¡fica --------------------------------------------------- ----------*/ #define eoi_ns() (outportb(BASE_8259,EOI_NS)) /*------------------------------------------------- ----------- eoi_prn() fin de interrupci¢n espec¡fica para port paralelo (IRQ7) --------------------------------------------------- -----------*/ #define eoi_prn() (outportb(BASE_8259,EOI_PRN)) /*------------------------------------------------- ------------ eoi_timer() fin de interrupci¢n espec¡fica el timer (IRQO) --------------------------------------------------- -------------*/ #define eoi_timer() (outportb(BASE_8259,EOI_TIMER))

Anexo C

Proyecto final de carrera Página 80

4.2 Librería Ini_IRQ.h #define CR 0x0D /* c¢digo ASCII de tecla retorno de carro */ #define PULSOS_ENCODER 200 /*pulsos por revoluci¢n*/ #define ESTADO_00 0x00 /* estados de cuadratura*/ #define ESTADO_01 0x01 #define ESTADO_10 0x02 #define ESTADO_11 0x03 #define DIRECTA 1 /* valores de los flags de direcci¢n */ #define INVERSA 0 /* declaraci¢n de tipos derivados --------------------------------*/ typedef unsigned char u_char; typedef unsigned int u_int; typedef unsigned long u_long; /* prototipos de funciones ---------------------------------*/ double get_posicion( void ); /* retorna la posici¢n */ void inc_p( void ), /* incrementa la cuenta de pulsos dec_p( void ), /* decrementa de cuenta de pulsos reset_prn( void ), /* restaura condiciones iniciales /*de prn */ ini_cuadrat( void ); /* inicilizaci¢n */ void interrupt cuadrat(_CPPARGS);

Anexo C

Proyecto final de carrera Página 81

4.3 Librería PID.h /*------------------------------------------------- ---------------------- FILE: pid.h -declaracions per al pid.c --------------------------------------------------- --------------------*/ typedef struct double kp, Ti, Td, consigna, error_1, error_2, t_sample; struct_PID; //------------------------------------------------- ---------------------- // cap‡alera //------------------------------------------------- ---------------------- double obtenir_voltes( void ); int variables_pid( void ); int control( void ); int funcio_velocitat( void );

Anexo C

Proyecto final de carrera Página 82

4.4 Librería Printer.h /*------------------------------------------------- ------- FILE: printer.h NOTAS: Se definen las macros para el acceso al por t paralelo Las macros de ataque al puente excluyen la posibilidad de que ambas ramas puedan activarse simulta neamente MACROS: pulse_on_a() activa la rama 'a' del puen te pulse_off_a() desactiva la rama 'a' del p uente pulse_on_b() activa la rama 'b' del puen te pulse_off_b() desactiva la rama 'b' del p uente ini_prn() inicializa el port prn verifi() verifica que la interrupci¢ n no es ruido cuadrat_leer() lee estado de cuadratura pa ra posicion en_i_prn() habilita las interrupciones (IRQ7) dis_i_prn() deshabilita las interrupcio nes (IRQ7) vcc_on() entrega tensi¢n al exterior a trav‚s del port vcc_off() anula tensi¢n exterior FUNCIONES: printer() devuelve la direcci¢n base asociada al port --------------------------------------------------- ------------------*/ #include <dos.h> #define PRN_BASE 0X378 #define PRN_VERIFI PRN_BASE+1 #define PRN_IRQ PRN_BASE+2 #define PRN_IRQ_MASK 0x10 /* mascara interrupciones pin 10 DB-25 */ #define PULSEON_A 0x01 /* puesta a uno de pin 2 DB25 */ #define PULSEOFF_A ~PULSEON_A /* pulsos de control en pin 2 DB-25 */ #define PULSEON_B 0x02 /* puesta a uno de pin 3 DB25 */ #define PULSEOFF_B ~PULSEON_B /* pulsos de control en pin 3 DB-25 */ #define INI_PRN 0xFF /* 11111111 inicializaci¢n del port_base+ 1 de prn */ #define VCC_ON 0xFC /* pines 2 y 3 a cero y pines 4...9 a uno DB25 */ #define VCC_OFF 0x00 /* pines 2...9 a cero DB25 */ #define MASK 0x80 /* m scara para confirmaci¢n de int */ #define CUADRAT_MASK 0x30 /* m scara para bits 4 y 5 de cuadratura (pines 12 y 13)*/ #define N_PRN 0x00410 /* direcci¢n de nø de ports de impresora */ #define D_PRN 0x00408 /* indirecci¢n para direcci¢n base de PRN */

Anexo C

Proyecto final de carrera Página 83

/*------------------------------------------------- pulse_on_a() pin 2 DB-25 a '1' y pin 3 DB-25 a 'O' -------------------------------------------------*/ #define pulse_on_a() (outportb(PRN_BASE,((inportb(PRN_BASE)&PULSEOFF_B)| PULSEON_A))) /*------------------------------------------------- - pulse_off_a() pin 2 DB-25 a 'O' --------------------------------------------------- -*/ #define pulse_off_a() (outportb(PRN_BASE,(inportb(PRN_BASE )&PULSEOFF_A))) /*------------------------------------------------- -- pulse_on_b() pin 3 DB-25 a '1' y pin 2 DB-25 a 'O' --------------------------------------------------- */ #define pulse_on_b() (outportb(PRN_BASE,((inportb(PRN_BASE)&PULSEOFF_A)| PULSEON_B))) /*------------------------------------------------- -- pulse_off_b() pin 3 DB-25 a 'O' --------------------------------------------------- -*/ #define pulse_off_b() (outportb(PRN_BASE,(inportb(PRN_BASE )&PULSEOFF_B))) /*------------------------------------------------- -- ini_prn() pines 2 y 3 a cero (PWM), pines 4 y 5 a u no (cuadrat), pines 6 a 9 a uno (VCC=ON) --------------------------------------------------- --*/ #define ini_prn() (outport(PRN_BASE+l,INI_PRN)) /*------------------------------------------------- ---- verifi() pin 11 -BUSY -DB-25. Usado como confirmaci ¢n de int NOTA: el valor le¡do es el inverso del real --------------------------------------------------- ---*/ #define verifi() (inportb(PRN_VERIFI)&MASK) /*------------------------------------------------- ---- cuadrat_leer() pin 12 Data_5 y pin 13 Data_4,info d e cuadratura --------------------------------------------------- ----*/ #define cuadrat_leer() ((inportb(PRN_BASE+1)&CUADRAT_MASK) >>4) /*------------------------------------------------- ------- vcc_on() pines 2 y 3 a cero y pines 4...9 a uno DB 25 --------------------------------------------------- ------*/ #define vcc_on() (outportb(PRN_BASE,VCC_ON)) /*------------------------------------------------- ------- vcc_off() pines 2...9 a cero DB 25 --------------------------------------------------- ------*/ #define vcc_off() (outportb(PRN_BASE,VCC_OFF)) /*------------------------------------------------- ------- en_i_prn() se valida la interrupci¢n de prn pin 10 DB-25 --------------------------------------------------- ------*/ #define en_i_prn() (outport(PRN_IRQ,(inportb(PRN_IRQ)|PRN_ IRQ_MASK))) /*------------------------------------------------- ------- dis_i_prn() inhibe interrupciones desde prn --------------------------------------------------- ------*/ #define dis_i_prn() (outportb(PRN_IRQ,(inportb(PRN_IRQ)&~P RN_IRQ_MASK))) /*------------------------------------------------- ------ printer() -devuel ve la direcci¢n base asociada al port pasado --------------------------------------------------- ----------*/ int printer( int );

Anexo C

Proyecto final de carrera Página 84

4.5 Librería PWM.h typedef struct // referida a excitacio PWM double dc; // cicle de treball long T, // periode (us) ton, // temps de on (us) toff, // temps de off (us) gir, // dreta/esquerra abans; // ve de on o de off struct_PWM; #define dreta 1 #define esquerra 0 #define ON 1 #define OFF 0 //------------------------------------------------- -------------- //Cap‡aleres de pwm.c //------------------------------------------------- -------------- int frequency( double freq); int duty_cycle( double dc); int pwm( void );

4.6 Librería Timer.h /*------------------------------------------------- -------------- FILE: TIMER.h -declaracions per al TIMER.c --------------------------------------------------- -------------*/ #ifdef _cplusplus /* consideracions sobre el tipus de compilador */ #define _CPPARGS... #else #define _CPPARGS #endif /* declaraci¢ de tipus derivats --------------------------------*/ typedef struct int port, //@ del port base timer; //un de tres double clock, //frecuencia del cristall d'exitaci¢ tic; //interval entre //interrupcions(microseg) hard_timer;

Anexo C

Proyecto final de carrera Página 85

typedef struct long count, //interval abans d'executar la funci¢ //associada (micro seg) recarga; //valor de recarrega int incremental; //incremental/decremental int (*fun)( void ); //funcio associada a count soft_timer; #define base_8253 0x40 //@ base del timer 8253 #define tmr0 0 //timer 0 del 8253 #define clock_timer 1193180 //freq encia d'oscilúlacio del //cristall #define vector_irq_timer 0x08 //posicio del vector a la taula //vectoritzada #define base_8259 0x20 #define EOI_NS 0x20 //final d'irq no especifica /*-------------------------------------- Cap‡aleres de les funcions de timer.c ----------------------------------------*/ int captura_valors( double *valors); //adquireix dades del teclat int captura_tecla_teclat( char taula[30]); int set_timer( int timer, double interval); //estableix el contingut d'un //soft_timer concret int ini_timers( double *valors); //inicia tots els soft_timers void ini_struct_hard_timer( int interval); //estableix el contingut de //l'estructura del hard_timer void canvi_vector_irq( void ); //posa el nou vector a la taula //vectoritzada int trans_interval_tic( void ); //transforma microseg a tics int ini_8253( void ); //inicialitza el timer 8253 void restaura_sistema( void ); //restaura tot el sistema double get_timer( int timer); //captura el contingut d'un //soft_timer void interrupt irq_timer( void ); //rutina d'atencio a la //interrupcio

Anexo C

Proyecto final de carrera Página 86

4.7 Librería Main.c /*------------------------------------------------- --------------- FILE: inf4.c ALGORISME DE CONTROL NOTES: FORMAT D'ENTRADA: Nom del programa + espai + base de temps del 8253 en microsegons --------------------------------------------------- --------------*/ //PFC #define simula #include "q5.h" //PFC #include "timer.h" #include "pwm.h" #include "ini_irq.h" #include "pid.h" #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <dos.h> #include <math.h> int analisi_arguments( int argc, char **argv); //Comprova els arguments //d'entrada int inicialitzacio( int tmp, double *valors); //inicialitza tot el //sistema int control_tecla( int tecla); void presentacio ( void ); //PFC extern hard_timer h_timer; extern double k1,k2,k3; extern double error_0; //PFC extern soft_timer s_timer[3]; //variable declarada a timer.c extern struct_PWM inf_pwm; long int irq_8253=0; //compta les irq's provocades pel 8253 extern int error_irq; extern long cuenta_p; extern long irq_prn; extern double velocitat; extern struct_PID inf_pid;

Anexo C

Proyecto final de carrera Página 87

//------------------------------------------------- main( int argc, char **argv) int tmp; double valors[3]; char tecla; tmp=analisi_arguments(argc,argv); //comprova els arguments d'entrada clrscr(); if (inicialitzacio(tmp,valors)) return (1); //PFC ini_datos_sim(); //PFC while (tecla!=27) if (error_irq) return (1); presentacio(); tecla=getch(); restaura_sistema(); //restaura l'antic apuntador de la t.vectoritzada, //el port paralel i para el motor return (0); // retorn sense error //------------------------------------------------- ------------ //analisi_arguments: Analitza els arguments introdu its // per teclat, realitza l'arrodon iment // //------------------------------------------------- ------------ int analisi_arguments( int argc, char **argv) float tmp; char *missatge= "\nError en la cadena d'entrada al programa. \n\nFO RMAT: Nom del programa + espai + base de temps\nen micro segons" ; tmp=0.0; if ((argc==1)|(argc>2)) //Si l'argument de crida al programa no es 2 //donarem error d'entrada dades printf( "%s\n" ,missatge); abort(); if (argc==2) tmp=atof(argv[1]); //tractem argument introduit tmp=tmp+0.5; //arodonim if ((tmp<5.0)|(tmp>200.0)) //si base temps no adecuada //abortem programa printf( "\n\nBase de temps no adecuada\n\n" ); abort(); return (tmp);

Anexo C

Proyecto final de carrera Página 88

int inicialitzacio( int tmp, double *valors) ini_struct_hard_timer(tmp); if (captura_valors(valors)) //adquireix dades del teclat printf( "\n\nError al entrar les dades" ); return (1); if (ini_timers(valors)) //inicia els soft_timers, si es //retorna 1 hi ha //error i finalitzal'execucio printf( "\n\nError en les dades dels timers" ); return (1); pulse_off_b(); pulse_off_a(); if (frequency((1/valors[1])*1e3)) printf( "Error de dades en Frequencia PWM" ); return (1); inf_pid.t_sample=valors[0]; //POSAR DINS LA FUNCIO variables_pid if (variables_pid()) return (1); inf_pid.error_1=0.0; inf_pid.error_2=0.0; ini_cuadrat(); canvi_vector_irq(); //posa el nou apuntador a la nostra //rutina de servei dins la taula //vectoritzada if (ini_8253()) //programa el 8253 per a que comenci //a comptar printf( "\n\nError en la inicialitzaci¢ del hard timer" ); return (1); return (0); void presentacio ( void ) double graus; int voltes; clrscr(); while (!kbhit()) graus=get_posicion(); //posici¢ absoluta de l'eix voltes=( int )(graus/360.0); // voltes donades gotoxy(7,2); printf( "---------------------- Control de potencia ------- ------" ); gotoxy(7,3); printf( "| |" ); gotoxy(7,4);

Anexo C

Proyecto final de carrera Página 89

printf( "-------------------------------------------------- ------" ); gotoxy(15,5); printf( "DC:%3.0lf % " ,(inf_pwm.dc)*100); gotoxy(15,6); printf( "Ton: %ld microsegons " ,inf_pwm.ton); gotoxy(15,7); printf( "Toff: %ld microsegons " ,inf_pwm.toff); gotoxy(15,8); if (inf_pwm.gir==1) printf( "Sentit de gir: DRETA " ); else printf( "Sentit de gir: ESQUERRA " ); gotoxy(15,9); printf( "Velocitat real motor: %4.2lf rpm " ,velocitat); gotoxy(15,10); printf( "Pulsos del encoder: %ld polsos " ,cuenta_p); gotoxy(15,11); printf( "errors encoder: %d " ,error); gotoxy(15,12); printf( "posici¢ absoluta de l'eix: %8.2f§C " , graus); gotoxy(15,13); printf( "posici¢ relativa de l'eix: %8.2f¦C " , graus-voltes*360.0); gotoxy(15,14); printf( "n§ de voltes:%5d " , voltes); //PFC gotoxy(7,15); printf( "------------------------- Proves ----------------- ------" ); gotoxy(7,16); printf( "| |" ); gotoxy(7,17); printf( "-------------------------------------------------- ------" ); gotoxy(7,18); printf( "k1 PID:%5f " , k1); gotoxy(7,19); printf( "k2 PID:%5f " , k2); gotoxy(7,20); printf( "N§ Tics:%5d " , virtual_motor.recarga); gotoxy(7,21); printf( "Direcci¢:%5d " , virtual_motor.direction); gotoxy(7,22); printf( "Index finestra:%5d " , virtual_motor.index); gotoxy(30,18); printf( "Consigna velocitat:%5f " ,inf_pid.consigna); gotoxy(30,19); printf( "Velocitat Real:%5f " ,velocitat); gotoxy(30,20); printf( "PWM:%5f " ,inf_pwm.dc); gotoxy(30,21); printf( "Error 0:%5f " ,error_0); gotoxy(30,22); printf( "Error 1:%5f " ,inf_pid.error_1); gotoxy(30,23); printf( "increment PWM:%4f" ,k1*error_0+k2*inf_pid.error_1); //PFC

Anexo C

Proyecto final de carrera Página 90

4.8 Librería Ini_IRQ.c

/*------------------------------------------------- ------------------ FILE: ini_irq.c -medida de posici¢n del eje de un m otor partiendo de dos se¤ales en cuadratura propo cionadas por un encoder relativo autor: Jacob Pie NOTAS: La posici¢n se determina contando el n£mero d e pulsos que se detectan en una misma direcci¢n. La direcci¢n se determina a partir de la secu encia de pulsos desfasados 90 grados que proporcion a el encoder relativo. --------------------------------------------------- -----------------*/ //PFC #define simula #define project #include "q5.h" //PFC #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <dos.h> #include "ini_irq.h" //#include "printer.h" #include "8259.h" /*------------- datos privados -------------*/ long cuenta_p; //conta el nø de interrupcions //del encoder static int direccion, //sentido de giro del motor estado_old, //estado previo de la entrada //de cuadratura flag_inver, //flag de direcci¢n inversa prn_base; //direcci¢n base del puerto //paralelo int error=0; void interrupt (*old_handler_prn)(); //mantiene el manejador //original double grados; //posici¢n absoluta del eje del //motor en grados sexagesimales int vueltas; //vueltas dadas long irq_prn=0;

Anexo C

Proyecto final de carrera Página 91

/*------------------------------------------------- ------------------- cuadrat() -Rutina de servicio a la interrupcion de cuadratura NOTA: Esta funcion es llamada a cada flanco (ascend ente y descendente) de cada una de las dos se¤ales en cuadratura. El sentido de giro es funcion de la se cuencia de unos y ceros provinientes de las do s se¤ales desfasadas 90§ dadas por el encoder. A si, la accion a tomar depender del estado act ual y del anterior. --------------------------------------------------- ------------------*/ void interrupt cuadrat(_CPPARGS) int estado_curso; //estado actual de cuadratura estado_curso=cuadrat_leer(); //lectura de info de cuadratura if (estado_old!=estado_curso) switch (estado_old) //analisis de secuencia de pulsos //del encoder case ESTADO_00: if ( estado_curso==ESTADO_01) dec_p(); /* retroceso */ else if (estado_curso==ESTADO_10) inc_p(); /* avance */ else error++; /* error */ break ; case ESTADO_01: if (estado_curso==ESTADO_11) dec_p(); else if (estado_curso==ESTADO_00) inc_p(); else error++; break ; case ESTADO_11: if (estado_curso==ESTADO_10) dec_p(); else if (estado_curso==ESTADO_01) inc_p(); else error++; break ; case ESTADO_10: if (estado_curso==ESTADO_00) dec_p(); else if (estado_curso==ESTADO_11) inc_p(); else error++; break ;

Anexo C

Proyecto final de carrera Página 92

estado_old=estado_curso; //el estado actual pasa a ser //el anterior ahora irq_prn++; eoi_ns(); //fin de interrupci¢n no //espec¡fica /*------------------------------------------------- -------------------- inc_p() -incrementar cuenta_p incrementa el nø de inten-upciones acumuladas --------------------------------------------------- -------------------*/ static void inc_p( void ) ++cuenta_p; //incrementamos la cuenta de //pulsos if (direccion==INVERSA) //si la direcci¢n anterior era //inversa==>cambio de direcci¢n direccion=DIRECTA; //direcci¢n actual flag_inver=1; //indicaci¢n de cambio en //direcci¢n /*------------------------------------------------- ------------------- dec_p -decrementar cuenta_p decrementa el nø de interrupciones acumulada s --------------------------------------------------- ------------------*/ static void dec_p( void ) --cuenta_p; //decrementamos la cuenta de //pulsos if ( direccion==DIRECTA) //si la direcci¢n anterior era //directa==>cambio de direcci¢n direccion=INVERSA; //direcci¢n actual flag_inver=1; //indicaci¢n de cambio de //direcci¢n /*------------------------------------------------- -------------------- ini_cuadrat -inicializaci¢n --------------------------------------------------- -------------------*/ void ini_cuadrat( void ) cuenta_p=0; //puesta a cero error=0; flag_inver=0; direccion=DIRECTA; //arbitrariamente elegida estado_old=cuadrat_leer(); //estado actual old_handler_prn=getvect(VECT_PRN); //guadamos vector original setvect(VECT_PRN,cuadrat); //establecemos nueva rutina de //atenci¢n

Anexo C

Proyecto final de carrera Página 93

en_i_prn(); //activamos interrup. IRQ7 (prn) mask_prn_off(); //permitimos int de prn en 8259 /*------------------------------------------------- ---------------------- reset_prn() Restaura el vector original y desactiva int errup. --------------------------------------------------- -------------------*/ void reset_prn( void ) dis_i_prn(); //inhibe interrupciones de pin //10 setvect(VECT_PRN,old_handler_prn); //restaura vector original pulse_off_a(); //pin 2 DB-25 a cero pulse_off_b(); //pin 3 DB-25 a cero /*------------------------------------------------- --------------------- cuadrat_getp() retorna de la posici¢n en grados sexagesimales --------------------------------------------------- --------------------*/ double get_posicion( void ) long cuenta; //copia de cuenta_p disable(); //comienzo regi¢n cr¡tica cuenta=cuenta_p; //info de posici¢n en pulsos enable(); //fin de regi¢n cr¡tica return (cuenta*360.0/(PULSOS_ENCODER*4.0)); //conversi¢n a grados //cent¡grados

Anexo C

Proyecto final de carrera Página 94

4.9 Librería PID.c //------------------------------------------------- ---------------------- FILE: pid.c Implementacio de les funcions relatives al control PID //------------------------------------------------- --------------------- #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <dos.h> #include <math.h> #include "timer.h" #include "pwm.h" #include "ini_irq.h" #include "pid.h" double velocitat=0.0; extern long cuenta_p; double k1,k2,k3; struct_PID inf_pid; extern struct_PWM inf_pwm; extern soft_timer s_timer[3]; //taula que conte els 3 soft timers double error_0; //------------------------------------------------- -------------------- //funcio_velocitat: //------------------------------------------------- -------------------- int funcio_velocitat( void ) double espai,temps; espai=obtenir_voltes(); //nº de voltes en un interval de t temps=get_timer(2)/1000.0; //temps esta en segons s_timer[2].count=0; velocitat=(espai/temps)*60.0; //velocitat es mesura en rpm return (0); //------------------------------------------------- -------------------- //obtenir_voltes() // retorna de les voltes //------------------------------------------------- -------------------- double obtenir_voltes( void ) long cuenta; double voltes; static long cuenta_ant=0; disable(); // comienzo regi¢n cr¡tica cuenta=cuenta_p; // info de posici¢n en pulsos enable(); // fin de regi¢n cr¡tica voltes=((cuenta-cuenta_ant)/(PULSOS_ENCODER*4.0)); cuenta_ant=cuenta;

Anexo C

Proyecto final de carrera Página 95

return (voltes); //------------------------------------------------- --------------------- //Variables_pid:demana per teclat les variables // del controlador pid //------------------------------------------------- --------------------- int variables_pid( void ) char temp[10]; printf( "Introdueix la variable Kp pel controlador PID: " ); if (captura_tecla_teclat(temp)) return(1); else inf_pid.kp=atof(temp); //valor de kp printf( "Introdueix el temps Td(ms) pel controlador PID: " ); if (captura_tecla_teclat(temp)) return(1); else inf_pid.Td=atof(temp); //valor de td printf( "Introdueix el temps Ti(ms) pel controlador PID: " ); if (captura_tecla_teclat(temp)) return(1); else inf_pid.Ti=atof(temp); //valor de ti printf( "Introdueix la consigna de velocitat pel controlado r PID: " ); if (captura_tecla_teclat(temp)) return(1); else inf_pid.consigna=atof(temp); //valor de consigna //inf_pid.consigna=+180; //consigna posicio k1=inf_pid.kp*(1+(inf_pid.t_sample/inf_pid.Ti)+(in f_pid.Td/inf_pid. t_sample)); k2=-(1+2*(inf_pid.Td/inf_pid.t_sample))*(inf_pid.k p); k3=inf_pid.kp*(inf_pid.Td/inf_pid.t_sample); return (0); //------------------------------------------------- ---------------------- //control: Funcio associada al control PID //------------------------------------------------- --------------------- int control( void ) if (funcio_velocitat()) return (1); error_0=inf_pid.consigna-velocitat; //calcul de l'error de //velocitat //error_0=inf_pid.consigna-get_posicion(); //calc ul de l'error de //posicio inf_pwm.dc+=k1*error_0+k2*inf_pid.error_1; if (inf_pwm.dc>1.0) inf_pwm.dc=1.0; //evita la saturacio integral del PID if (inf_pwm.dc<-1.0) inf_pwm.dc=-1.0; if (duty_cycle(inf_pwm.dc)) return (1); //actualitza Ton i Toff inf_pid.error_2=inf_pid.error_1; inf_pid.error_1=error_0; return (0);

Anexo C

Proyecto final de carrera Página 96

4.10 Librería PWM.c //------------------------------------------------- ----------------- // FILE pwm.c //------------------------------------------------- ----------------- //PFC #define simula #define project #include "q5.h" //PFC #include "pwm.h" //#include "printer.h" #include "timer.h" extern hard_timer h_timer; struct_PWM inf_pwm; //------------------------------------------------- ----------------- // frequency(): //------------------------------------------------- ----------------- int frequency( double freq) //TOTS ELS VALORS ESTAN EN us if (freq>0.0) inf_pwm.dc=0.0; inf_pwm.T=(1/freq)*1e6; inf_pwm.ton=inf_pwm.T*inf_pwm.dc; inf_pwm.toff=inf_pwm.T-inf_pwm.ton; inf_pwm.gir=dreta; inf_pwm.abans=OFF; return (0); return (1); //retorn amb error //------------------------------------------------- ---------------- // duty_cycle: //------------------------------------------------- ---------------- int duty_cycle( double dc) double tmp; inf_pwm.gir=inf_pwm.dc>0.0?dreta:esquerra; if ((dc>=-1.0)&&(dc<=1.0)) //comprova si tmp>0, si ho es Ton=tmp //sino Ton=-tmp tmp=inf_pwm.T*dc; inf_pwm.ton=tmp>0.0?tmp:-tmp; //actualitza valor de Ton inf_pwm.toff=inf_pwm.T-inf_pwm.ton; //actualitza valor de Toff return (0); return (1); //retorna amb error

Anexo C

Proyecto final de carrera Página 97

//------------------------------------------------- --------------- // pwm(): //------------------------------------------------- ---------------- int pwm( void ) //prove de gir a dretes //if (inf_pwm.gir==dreta) //aixi pel motor casa P FC if (inf_pwm.gir==esquerra) if (inf_pwm.abans==ON) //prove de TON if (set_timer(1,inf_pwm.toff)) return (1); pulse_off_b(); inf_pwm.abans=OFF; else //prove de TOFF if (set_timer(1,inf_pwm.ton)) return (1); pulse_on_b(); inf_pwm.abans=ON; else //prove de gir a esquerres if (inf_pwm.abans==ON) //prove de TON if (set_timer(1,inf_pwm.toff)) return (1); pulse_off_a(); inf_pwm.abans=OFF; else //prove de TOFF if (set_timer(1,inf_pwm.ton)) return (1); pulse_on_a(); inf_pwm.abans=ON; return (0);

Anexo C

Proyecto final de carrera Página 98

4.11 Librería Timer.c /*------------------------------------------------- ------------------- FILE: timer.c Implementacio de les funcions relatives als tempori tzadors --------------------------------------------------- ------------------*/ //PFC #define simula #define project #include "q5.h" //PFC #include "pid.h" #include "timer.h" #include "pwm.h" //necessari per l'assignacio del apuntador a //ini_timers #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <dos.h> #include <math.h> void interrupt (*old_handler_timer)(); //mante el manejador //original extern struct_PWM inf_pwm; soft_timer s_timer[3]; //taula que conte els 3 soft timers hard_timer h_timer; extern long int irq_8253; long int PID=0; int error_irq=0; //dtecta si alguna de les funcions associades h //a generat error //------------------------------------------------- ------------------- //captura_valors: comprova els valors de temps intr oduits // des de teclat //------------------------------------------------- ------------------- int captura_valors( double *valors) char temps[10]; printf( "\n\nEls valors de TEMPS han d'estar en ms\n\n" ); printf( "Periode de mostreig PID: " ); if (captura_tecla_teclat(temps)) return (1); else valors[0]=atof(temps); printf( "Periode de PWM: " ); if (captura_tecla_teclat(temps)) return (1); else valors[1]=atof(temps); return (0);

Anexo C

Proyecto final de carrera Página 99

//------------------------------------------------- ---------------------- // captura_tecla_teclat: captura una cadena de num eros i realitza control // d'error. // retorna una cadena de caracters //------------------------------------------------- ---------------------- int captura_tecla_teclat( char taula[30]) char caracter; int ind=0; caracter=getchar(); while (caracter!= '\n' ) if ((caracter>= '0' )&&(caracter<= '9' )||(caracter== '.' )) taula[ind]=caracter; ind++; caracter=getchar(); if (caracter== '\n' ) taula[ind]= '\0' ; return (0); return (1); //retorn amb error //------------------------------------------------- ---------------------- //set_timer: Inicialitza els camps de la estructura // s_timer d'un soft timer concret //------------------------------------------------- ---------------------- int set_timer( int timer, double interval) //interval esta en us switch (timer) case 0: //timer soft decremental s_timer[0].count=(interval/h_timer.tic)+0.5; //trunca interval s_timer[0].recarga=(interval/h_timer.tic)+0.5; break ; case 1: //timer soft decremental s_timer[1].count=(interval/h_timer.tic)+0.5; //trunca interval s_timer[1].recarga=(interval/h_timer.tic)+0.5; break ; case 2: //timer soft incremental s_timer[2].count=0; s_timer[2].recarga=0; break ; default : //sino es cap dels 3 retorna return (1); //un error

Anexo C

Proyecto final de carrera Página 100

return (0); //retorn sense error //------------------------------------------------- ------------------ //ini_timers: Inicialitza tots els soft timers. // Demana a l'usuari els valors de temps per als // diferents timers // //NOTA: Els valors introduits per l'usuari se ran en ms //------------------------------------------------- ------------------ int ini_timers( double *valors) //valors es una taula on hi ha el temps de cada tim er s_timer[0].incremental=0; //timer decremental s_timer[0].fun=control; //funcio associada al timer 0 if (set_timer(0,valors[0]*1000)) return (1); //inicialitza soft_timer 0 //valor en us s_timer[1].incremental=0; //timer decremental s_timer[1].fun=pwm; //funcio associada al timer 1 if (set_timer(1,valors[1]*1000)) return (1); //inicialitza soft_timer 1 s_timer[2].incremental=1; //timer incremental s_timer[2].fun=funcio_velocitat; //funcio associada al timer 2 if (set_timer(2,valors[2]*1000)) return (1); //inicialitza soft_timer 2 return (0); //retorn sense error //------------------------------------------------- ------------------ //ini_struct_hard_timer: Inicialitza la estructura h_timer // colúlocant informaci¢ del timer hard // que usem per realitzar la practica //------------------------------------------------- ------------------ void ini_struct_hard_timer( int interval) h_timer.port=base_8253; //adre‡a base del 8253 h_timer.timer=tmr0; //selecciona el comptador 0 del 8253 h_timer.clock=clock_timer; //freq encia a la que oscilúla el //timer h_timer.tic=interval; //interval entre interrupcions //------------------------------------------------- -------------------- // canvi_vector_irq: guarda l'antic apuntador de la posicio 8 de la // taula vectoritzada i hi colúlo ca el nou // //------------------------------------------------- -------------------- void canvi_vector_irq( void ) old_handler_timer=getvect(vector_irq_timer); setvect(vector_irq_timer,irq_timer);

Anexo C

Proyecto final de carrera Página 101

//------------------------------------------------- ----------------- // trans_interval_tic: Transforma els microseg al valor // per carregar el 8253, arrodoneix i trunca // el valor a carregar //------------------------------------------------- ----------------- int trans_interval_tic( void ) return (((h_timer.tic)*(h_timer.clock)*1e-6)+0.5); //------------------------------------------------- ----------------- //ini_8253: Inicialitza el timer 0 de la placa ba se del Pc // en mode rate generator. Introdu‹m el valor de // la base de temps al registre count #0 //------------------------------------------------- ----------------- int ini_8253( void ) int valor=0; valor=trans_interval_tic(); //transforma microseg. a tics if ((valor<2)||(valor>0xFFFF)) return (1); outportb(base_8253+3,0x3C); //timer0, mode rate generator outportb(base_8253,( unsigned char )(valor&0x00FF)); //carrega byte_L del 8253 outportb(base_8253,( unsigned char )(valor>>8)); //carrega byte_H del 8253 return (0); //------------------------------------------------- --------------------- // restaura_ sistema: restaura l'antic vector de la taula vectoritzada // i restaura el valor origina d el timer 8253 //------------------------------------------------- --------------------- void restaura_sistema( void ) disable(); setvect(vector_irq_timer,old_handler_timer); //restaura vector outportb(base_8253+3,0x3C); //timer0, mode rate generator outportb(base_8253,( unsigned char )(0xFF)); //recarrega 8253 amb valor original outportb(base_8253,( unsigned char )(0xFF)); enable(); pulse_off_a(); //para el motor pulse_off_b(); reset_prn(); //restaura port paralel printf( "\n\nSortida del Programa" ); //------------------------------------------------- --------------- // irq_timer: Rutina de servei al timer 8253 //------------------------------------------------- --------------- void interrupt irq_timer( void ) int ind; for (ind=0;ind<3;ind++) //Comprova els 3 soft_timers if (!(s_timer[ind].incremental)) //timer decremental

Anexo C

Proyecto final de carrera Página 102

if (s_timer[ind].count) //si no es 0 es decrementa s_timer[ind].count--; //comprova per nivell si s_timer es //0, si es 0 continua cridant la funcio if (!s_timer[ind].count) //temps exhaurit //es crida la funcio associada error_irq=(*s_timer[ind].fun)(); s_timer[ind].count=s_timer[ind].recarga; // recarrega el s_timer else //timer incremental if ((s_timer[ind].count)<2e31) s_timer[ind].count++; else //error error_irq=1; sim_motor(); irq_8253++; outportb(base_8259,EOI_NS); // envia final irq no especific //------------------------------------------------- ------------------------ // funcio get_timer: retorna el valor actual d'un s oft_timer especific //------------------------------------------------- ------------------------ double get_timer( int timer) //transforma el valor a ms return (((s_timer[timer].count)*h_timer.tic)/1000);

Proyecto final de carrera Página 103

5 Anexo D: Referencias

[1] Libro: Esteban del Castillo, Control de Procesos, Publicacions URV, Año 2008.

[2] Libro: Felipe Espinosa Zapata, Análisis Diseño y Realización de Sistemas Electrónicos de Control Contínuo, Universidad de Alcalá de Henares, Año 2006.

[3] Libro: Manuel Mazo Quintas, Control de Motores Paso-Paso, dc con escobillas y brushless, Universidad de Alcalá de Henares, Año 1997