instituto politcnico nacional - Instituto Politécnico Nacional

Anuncio
INSTITUTO POLITÉCNICO NACIONAL
CENTRO DE INVESTIGACIÓN Y DESARROLLO
DE TECNOLOGÍA DIGITAL
“MEDICIÓN DE LAS VARIABLES DEL MOVIMIENTO DE
CARRERA LIMITADA”
TESINA
QUE PARA OBTENER LA
ESPECIALIDAD EN SISTEMAS INMERSOS
PRESENTA:
ING. RENÉ DE JESÚS GÓMEZ LÓPEZ
BAJO LA DIRECCIÓN DE:
M. en C. JOSÉ MARÍA MONTOYA FLORES
DICIEMBRE 2009
TIJUANA, BAJA CALIFORNIA, MÉXICO
2
3
Resumen.
Este trabajo es parte integral de un proyecto cuyo objetivo es
diseñar un equipo que emule una carga mecánica para estudiar
variables de comportamiento de dicha carga. Se presenta la
implementación de la adquisición de datos que forma parte del sistema
en conjunto con la carga mecánica simulada, el sistema de generación
de señales y el driver. La generación de señales lo conforman un
conjunto de memorias en donde se almacena valores
correspondientes a las diferentes variables a las que se quiere
someter el sistema simulado tales como fricción, inercia o alguna otra
fuerza particular que se desee emplear en la simulación. Estos valores
son el comportamiento deseado que se ha programado previamente.
Las salidas de estas señales van conectadas directamente a los
actuadores con su respectivo amplificador. La adquisición de datos se
realiza empleando el miniModul-515c con el que se implementa un
muestreo cada milisegundo de la posición del mecanismo a través de
un encoder, así como la conversión a digital de la señal de los
sensores de torque. Estas lecturas se almacenan en los 32 kBytes de
memoria externa incluida en la tarjeta de desarrollo antes mencionada.
Finalmente el microcontrolador envía esta información a través del
puerto serie cuando se le solicita mediante una aplicación realizada en
Visual Basic .NET 2008 haciendo uso de la biblioteca de clases del
puerto serie incluida en la .NET framework que permite implementar
un puerto serie virtual a través del puerto USB de la computadora. El
driver es el encargado de aportar el voltaje requerido para que el
motor funcione de acuerdo a algún algoritmo de control que se
implemente, dicho driver y algoritmo de control puede variar, esto es el
fin de este trabajo, que cada estudiante pueda llegar con su driver y
algoritmo de control y lo pruebe con el sistema integrado.
4
Abstract
This work is an integral part of a project whose objective is to
design a mechanism and hardware for emulate a mechanical charge.
In this paper is explained the implementation of the data acquisition
that is part of the system in conjunction with the emulated mechanical
load, the system of signal generation and the driver. The generation of
signals is made up by a set of memories where is stored the values for
different variables kind of friction inertia and any other particular force
that would be wanted to be consider in the simulation. These values
are the desired behavior of the system that anyone has programmed
previously. The outputs of these signals are directly connected to the
actuators with their respective power amplifier. The data acquisition is
obtained by implementing the miniModul-515c. In this development
board is implemented a sampling each millisecond of the position of
the mechanism through an encoder, as well as the conversion to digital
of the signal from torque sensors. These readouts are stored in the 32
Kbytes of the external memory included on the development board
mentioned above. Finally the microcontroller sends this information
through the serial port when it was requested by a application made in
Visual Basic .NET 2008 making use of the library of classes of serial
port included in the .NET framework that allows us to implement a
virtual serial port via the USB port of the computer. The driver is
responsible for providing the voltage needed for the motor to work in
agreement to some control algorithm is implemented, the driver and
the control algorithm can be different, that’s the purpose of this work, in
which each student can develop its own driver and control algorithm
and be able to prove those in the integrated system.
5
Contenido:
CAPITULO 1. – INTRODUCCIÓN ......................................................10
1.1 ANTECEDENTE Y ALCANCES. ........................................................10
1.2 PLANTEAMIENTO DEL PROBLEMA .....................................................11
1.3 Objetivo General ......................................................................11
1.4 Objetivos Específicos...............................................................11
CAPITULO 2. – SISTEMA DE EMULACIÓN DE CARGA..................13
2.1 DIAGRAMA GENERAL. .....................................................................13
2.2 PROGRAMACIÓN (TARJETA DE CIRCUITO DE EMULADOR). ..................13
2.3 MEDICIÓN (SISTEMA INMERSO). ......................................................14
2.4 INTERFAZ DE USUARIO (COMPUTADORA PERSONAL)..........................14
2.5 PARTE MECÁNICA (MECÁNICA DE EMULACIÓN Y CAPTURA).................14
2.6 MOTOR Y SU ALIMENTADOR (SISTEMA DE MOVIMIENTO).....................15
CAPITULO 3. – DESARROLLO DEL TRABAJO...............................16
3.1 ESPECIFICACIONES. .......................................................................16
3.2 ELEMENTOS A UTILIZAR. .................................................................17
3.3 PROGRAMA DEL MICROCONTROLADOR.............................................19
3.3.1 Ciclo principal........................................................................19
3.3.2 Envío de lecturas. .................................................................21
3.3.3 Captura inicial. ......................................................................23
3.3.4 Interrupción del Timer 2. .......................................................26
3.3.5 Interrupción del Puerto Serie. ...............................................28
3.4 PROGRAMA DE LA PC ....................................................................28
3.4.1 Interfaz de usuario ................................................................28
CAPITULO 4. – CONCLUSIONES Y TRABAJO FUTURO................39
6
ANEXO 1. PROBLEMA DE SINCRONIA. ..........................................40
ANEXO 2. PLATAFORMA .NET Y CONTROL DEL PUERTO SERIE.
.............................................................................................................43
.Net SerialPort Class......................................................................45
ANEXO 3. CÓDIGO DE PROGRAMA DEL MICROCONTROLADOR.
.............................................................................................................50
ANEXO 4. CÓDIGO DE APLICACIÓN DE LA PC. ............................54
BIBLIOGRAFÍA...................................................................................60
7
Lista de figuras:
FIGURA 1. SISTEMA DE EMULACIÓN DE CARGA. .........................................13
FIGURA 2 PARTE MECÁNICA....................................................................15
FIGURA 3. COMPONENTE A DESARROLLAR ................................................16
FIGURA 4. CONEXIONES DEL MICROCONTROLADOR. ..................................17
FIGURA 5. ORGANIZACIÓN DE MEMORIA EXTERNA......................................18
FIGURA 6 CICLO PRINCIPAL DEL PROGRAMA ..............................................20
FIGURA 7. ENVÍO DE LECTURAS ...............................................................22
FIGURA 8. COMPARACIÓN ENTRE LECTURAS DE 10 Y 8 BITS DEL ADC........23
FIGURA 9. CAPTURA INICIAL. ...................................................................25
FIGURA 10. INTERRUPCIÓN DEL TMR2 ....................................................27
FIGURA 11. FORMULARIO PRINCIPAL. .......................................................29
FIGURA 12. OPCIONES DEL MENÚ. ...........................................................30
FIGURA 13. VENTANA DE GUARDAR POSICIÓN ..........................................30
FIGURA 14. AVISO DE QUE NO ENCONTRÓ PUERTO SERIE...........................31
FIGURA 15. AVISO DE COM ELEGIDO ERRÓNEAMENTE. .............................32
FIGURA 16. AYUDAS PARA EL USUARIO.....................................................33
FIGURA 17. MUESTRA GRAFICA DE LOS PASOS A SEGUIR. ..........................33
FIGURA 18. PASO 2. ...............................................................................34
FIGURA 19. PASO 3. ...............................................................................35
FIGURA 20. PASO 3 EN DECIMAL. ............................................................36
FIGURA 21. PASO 3 EN HEXADECIMAL......................................................36
FIGURA 22. ERROR POR MICRO OCUPADO. ...............................................37
FIGURA 23. ERROR DE CONEXIÓN............................................................38
FIGURA 24. ERROR DE I/O. .....................................................................38
FIGURA 25. DIAGRAMA DE POSICIÓN. .......................................................40
FIGURA 26. TIEMPO DE CONFIGURACIÓN Y DE MANTENIMIENTO. .................40
FIGURA 27. PROBLEMA DE SINCRONISMO. ................................................41
FIGURA 28. SINCRONIZACIÓN CON UN CIRCUITO MONOESTABLE.................42
FIGURA 29. FRAMEWORK .NET. ..............................................................44
8
Lista de Tablas:
TABLA 1. CONSTRUCTOR DE LA CLASE SERIALPORT..................................46
TABLA 2. PROPIEDADES ÚTILES DE LA CLASE SERIALPORT.........................47
TABLA 3. MÉTODOS ÚTILES DE LA CLASE SERIALPORT...............................48
TABLA 4. EVENTOS DE LA CLASE SERIALPORT. .........................................49
TABLA 5. DELEGADOS DE LA CLASE SERIALPORT. .....................................49
9
CAPITULO 1. – INTRODUCCIÓN
1.1
Antecedente y alcances.
La emulación de una carga mecánica surge de la necesidad
existente de validar algoritmos de control, con la que se busca
construir un mecanismo, en donde se puedan implementar diferentes
algoritmos de control sin tener la necesidad de contar con un sistema
real. Con este trabajo se pretende tener una planta que se pueda
programar para diferentes escenarios y diferentes comportamientos
que puedan emular una carga real. Esta flexibilidad es útil por que el
usuario solamente tendría que preocuparse por perfeccionar su
algoritmo de control contando con la facilidad de adquirir los datos
arrojados por el sistema en cualquier momento. La recuperación de los
datos muestreados por el sistema se podrá obtener en un archivo de
texto para su posterior procesamiento en cualquier computadora que
tenga WINXP, VISTA o WIN7 con el driver del cable USB-SERIE y por
supuesto un puerto USB disponible.
Para la factibilidad del presente trabajo se cuenta con dos
aspectos primordiales a considerar, tal es el caso de la construcción
de la carga mecánica y la tarjeta de desarrollo a emplear.
Afortunadamente el mecanismo está construido casi en su totalidad y
el kit de desarrollo miniModul-515c con el que ya se cuenta, encaja
perfectamente para esta aplicación ya que permite implementar una
prueba con duración de poco más de 8 segundos con un tiempo de
muestreo de 1 milisegundo dada la cantidad de memoria externa con
la que se cuenta, situación que es más que suficiente para una prueba
de este tipo.
Otro aspecto que se considera pertinente aclarar es que los
datos arrojados como resultado de una prueba serán presentados sin
procesamiento alguno.
10
1.2 Planteamiento del problema
El trabajo realizado trata básicamente de la adquisición de
datos. Los datos que se requieren son la posición y el torque de la
carga, ya que con estas mediciones se pueden obtener otras variables
útiles, tales como velocidad, aceleración, fuerza, trabajo etc., por
medio de un procesamiento posterior mediante software.
La opción más indicada para tomar lecturas de la posición es por
medio de un encoder acoplado a la flecha del motor; en lo que
respecta al torque podemos optar por la opción de medir la corriente
que consume el motor o medir la tensión de la banda que acopla un
motor con su carga. Para la primera opción la exactitud es pobre y
depende mucho de conocer las características del motor, la segunda
es mejor opción. Más adelante se presentará una explicación detallada
de ello. Por último se tiene la necesidad de almacenar y comunicar los
resultados obtenidos, es decir, las lecturas obtenidas durante la
simulación de las variables a observar.
1.3 Objetivo General
El desarrollo del presente trabajo tiene como objetivo crear una
herramienta que se pueda utilizar para fines didácticos, donde el
estudiante pueda probar algoritmos de control de una manera simple
conociendo únicamente las entradas que requiere el sistema y las
salidas que obtendrá del mismo.
1.4 Objetivos Específicos
Para la construcción física de esta herramienta se ha planeado
emplear un sistema inmerso para establecer la comunicación
requerida entre el usuario y el mecanismo mismo que emulará la carga
mecánica.
También se busca que el comportamiento de la carga mecánica
pueda ser totalmente programable, es decir, contar con la flexibilidad
11
de limitar sus movimientos, que permita establecer si será de carrera
limitada o no, si la fricción será constante o variable.
El sistema inmerso podrá ser conectado a cualquier
computadora con puerto USB, que cuente con la aplicación y driver
necesarios para establecer comunicación con la tarjeta del
microcontrolador.
Y para quien elabora este documento el objetivo primordial es
fortalecer, enriquecer y desafiar los conocimientos adquiridos durante
el paso por esta institución en la especialidad de sistemas inmersos.
12
CAPITULO 2. – SISTEMA DE EMULACIÓN DE CARGA.
2.1 Diagrama general.
Para el desarrollo del presente trabajo se optó por organizar las
diferentes etapas como se muestra en el siguiente diagrama a
bloques.
Figura 1. Sistema de emulación de carga.
2.2 Programación (Tarjeta de circuito de emulador).
En esta tarjeta se aloja un conjunto de memorias donde se
cargarán los datos (Inercia, fricción, efectos de gravedad y límite de
carrera) que permitirán manipular ciertos actuadores con el objetivo de
programar un comportamiento deseado en la planta. Las salidas de
estas memorias van conectadas a un DAC, un amplificador y
posteriormente a un actuador para producir el efecto esperado en el
mecanismo, en otras palabras, las memorias contendrán la
información referente a lo que se quiere someter al sistema. La
localidad de memoria estará conectada al actuador en un tiempo dado,
13
y determinada por un contador, dicho contador recibe pulsos del
encoder acoplado al motor, del cual también se medirá su torque.
2.3 Medición (Sistema inmerso).
Se toma lectura de las variables esenciales que permitirán
caracterizar el comportamiento completo de la parte mecánica del
sistema: posición y torque. A partir de estos datos se puede obtener
velocidad, aceleración, potencia, etc., es decir se puede caracterizar el
comportamiento del sistema como resultado del algoritmo de control
utilizado. Una vez teniendo la información de la posición y el torque del
mecanismo, podemos inferir todo lo que se requiere para conocer el
comportamiento del mecanismo, por lo tanto son las variables que se
muestrearán cada milisegundo para ser enviadas a la PC para su
posterior análisis.
2.4 Interfaz de usuario (Computadora personal).
La interfaz del usuario, como su nombre lo indica, es el medio
con el cual el usuario podrá interactuar con los componentes del
sistema de emulación. Esta interacción es a través de la PC por medio
del puerto serie, La PC se comunica al microcontrolador que a su vez
ejecuta las tareas seleccionadas por el usuario y tiene las conexiones
de los sensores y bus de control del sistema completo.
2.5 Parte mecánica (Mecánica de emulación y captura).
Es la parte física donde se montará el motor, discos de freno,
sensores, peso, etc.
14
Figura 2 Parte Mecánica.
2.6 Motor y su alimentador (Sistema de movimiento).
Este componente lo integra el usuario del sistema. La persona
que desee evaluar un algoritmo de control en particular, debe
proporcionar el motor que va utilizar y la tarjeta que albergará el
algoritmo a ser sujeto de análisis. La única restricción es emitir un
pulso al iniciar, como medio de sincronización.
15
CAPITULO 3. – DESARROLLO DEL TRABAJO.
3.1 Especificaciones.
La medición de variables del movimiento de carrera limitada
involucra al componente de medición y parte del componente de la
interfaz de usuario relacionada con dicha medición, como se
menciona en el capítulo 2. Si se visualiza el presente trabajo como una
caja negra se puede tener una idea clara de los requerimientos que
debe satisfacer este componente para ser compatible con las otras
etapas del sistema de emulación.
Figura 3. Componente a desarrollar
Como se observa en la figura anterior, se debe satisfacer la
necesidad de obtener datos muestreados con una base de tiempo a
1ms de dos señales analógicas que provienen de dos sensores de
fuerza, cuya frecuencia oscila entre 0 y 200 Hz, y dos señales digitales
de 8 bits, con una frecuencia de 0 a 80KHz. Ambas señales se unen
para formar una lectura de posición de 16 bits. También se requiere
proporcionar una señal de “listo”, para indicar que está listo para tomar
lecturas, al igual que debe aceptar una señal de “empieza”, para que
en ese momento comience la toma de muestras de las variables de
interés.
16
3.2 Elementos a utilizar.
Para satisfacer los requerimientos solicitados, se utiliza el
miniModul-515C, que es la tarjeta que contiene el microcontrolador
que se utiliza para organizar las lecturas; marcar la pauta entre
muestreo y muestreo; hacer la conversión analógica digital; y
comunicar información solicitada por medio de la PC a través de un
adaptador USB a serial (DB9) como se puede observar en la siguiente
figura.
Figura 4. Conexiones del microcontrolador.
La memoria externa, que es parte del miniModul-515C, se utiliza
para almacenar las lecturas de las variables de interés, la cual consta
de 32K localidades que serán llenadas de la siguiente manera.
17
Figura 5. Organización de memoria externa.
De la figura anterior, se puede observar, que primero se realizan
dos conversiones analógicas a digital de las señales de fuerza,
posteriormente se toman dos lecturas de posición y se almacenan en
localidades de memoria de 8 bits, que son direccionadas por el
apuntador DPTR de 16 bits. Por lo tanto, son 4 bytes los que se
almacenan cada milisegundo, si se saturan los 32kBytes con esas
muestras, equivale a almacenar datos por más de 8 segundos, lo que
es suficiente para la aplicación deseada para el sistema de emulación.
El dato de posición se congela en dos latches de 8 bits, dichos
bits son actualizados continuamente. Al momento de ser leídos se
impide que sean actualizados por medio de un circuito monoestable,
para evitar problemas de sincronismo como se muestra en el anexo 1.
El Timer 2 del microcontrolador es el encargado de interrumpir al
microcontrolador cada milisegundo para hacer el muestreo una vez
que se ha solicitado el arranque de las lecturas.
18
3.3 Programa del microcontrolador.
3.3.1 Ciclo principal.
El programa del microcontrolador está organizado por modos de
operación, que están relacionados con la opción elegida por el usuario
que se envía desde la PC mediante el puerto serie. Inicialmente
después de un hardware-RESET el programa inicia con la
configuración, tanto del puerto serie como del timer 2, interrupciones,
ADC, entre otras salidas de control como se muestra enseguida.
19
Figura 6 Ciclo principal del programa
Como se puede observar en la figura anterior el programa del
microcontrolador está en un lazo infinito evaluando R0, que es el
registro donde se almacena el comando que el usuario envía por
medio del puerto serie. Dicho comando se almacena al presentarse la
interrupción del puerto serie. Por lo tanto, el programa se encuentra a
la espera de instrucciones del usuario que son evaluadas en el lazo
anterior para posteriormente ejecutar las instrucciones adecuadas.
Existen tres estados que el usuario puede seleccionar y que se
ejecutan independientemente uno de los otros, estos son: “r” que es
cuando el usuario desea leer la memoria externa del microcontrolador,
“c” cuando el usuario desea poner al micro a hacer el muestreo y “p”
20
que es lo que se ejecutará cuando el usuario desee programar las
variables de fricción, inercia, etc. Existen otros dos estados
secundarios que permiten conocer qué es lo que está haciendo el
microcontrolador, cuando el micro tiene el estado “e”, en este proceso
el microcontrolador le indica a la PC, en qué estado se encuentra
actualmente y cuando el estado es “s”, le indica a la PC el progreso de
las muestras enviando un aviso ya que se han capturado 256 datos.
3.3.2 Envío de lecturas.
El proceso de envío de las lecturas empieza inicializando los
valores de R0 y R1. R0 almacena la opción del usuario y R1 almacena
el estado actual del microcontrolador, de tal suerte que una vez dentro
del proceso, R0 debe ser desactivada para evitar que se ejecute este
proceso repetidamente y R1 toma el valor correspondiente a la
captura. Una vez teniendo esto se deshabilitan interrupciones para
que el proceso se ejecute de principio a fin, sin interrupciones. Esto es
necesario ya que la variable DPTR, que es el apuntador de 16 bits, se
utiliza en otros procesos y en cada uno se inicializa desde 0 hasta
cubrir los 32KBytes de la memoria externa que se están utilizando. El
envío se realiza cargando el acumulador con el valor de la localidad de
memoria actual y éste a su vez se carga al registro SBUF, de esta
manera se envía byte por byte a la PC. Esto se realiza mientras la
parte alta del apuntador DPTR que se almacena en el registro DPH no
alcanza el valor 80H, una vez que DPH toma este valor significa que
ha llegado al final de las lecturas y es cuando termina el proceso
habilitando de nuevo las interrupciones, tal como se muestra en el
siguiente diagrama:
21
Figura 7. Envío de Lecturas
El código en ensamblador, de esta y las siguientes rutinas, se
presentan en el ANEXO 3.
22
3.3.3 Captura inicial.
El proceso de captura inicial se ejecuta cuando el registro R0
tiene el valor “c”. En la captura inicial se realiza lo necesario para
poner al micro en alerta y listo para iniciar la toma de lecturas, esto es,
para que el micro inicie el proceso de captura se necesita cargar
previamente al contador externo de 16 bits con su valor de inicio, que
es el que permite llevar un seguimiento de la posición, también se
inicializa el DPTR y se envía la señal de “listo”. Una vez ahí, se espera
la instrucción del alimentador del motor quien será el encargado de
indicar el inicio del muestreo. Una vez recibida dicha instrucción, lo
primero que hará el microcontrolador es enviar un cero lógico para que
los latches que almacenan la posición se congelen en el valor actual
mientras se realiza la lectura. En lo que el circuito monoestable realiza
su labor se realizan las conversiones de las dos señales analógicas,
que se conectan a los canales 0 y 1 del ADC del microcontrolador.
Figura 8. Comparación entre lecturas de 10 y 8 bits del ADC.
Se sabe que el ADC del micro arroja lecturas de 10 bits, como se
muestra en la figura anterior, si se trabaja con localidades de memoria
de 8 bits, únicamente sería necesario considerar la parte alta de los
23
registros del ADC para que se almacene la lectura de los sensores de
fuerza con una resolución de 8 bits. Una vez que ya se han
almacenado los dos valores analógicos se procede a activar la salida
del lacth con los bits mas significativos y después se coloca en alta
impedancia para que el latch con los bits menos significativos se
pueda activar, una vez realizada dichas lecturas se procede a cargar
al registro del TMR2 para que el lapso entre la muestra inicial y las
siguientes sea de exactamente 1ms, de esta manera si se agregan o
quitan instrucciones de este procedimiento se puede hacer una
compensación de tiempo agregando o quitando unidades a TH2 y TL2
respectivamente según corresponda. Ya solo resta poner a contar al
TMR2 y activar las interrupciones deshabilitadas anteriormente y
esperar a que se presente una interrupción del TMR2 y proceder de
forma similar a la captura inicial con la diferencia en que ya no se
cargará el valor del contador externo de 16 bits; no se inicializará el
DPTR; ni se modifican los registros del TMR2.
24
Figura 9. Captura Inicial.
25
3.3.4 Interrupción del Timer 2.
A diferencia de la captura inicial, en esta rutina se monitorea el
valor del apuntador DPTR, tanto para saber si se ha llenado la
memoria como para saber cuántos datos han sido muestreados y así
avisar a la PC para que muestre al usuario el progreso de la captura.
Por tal motivo se verifica si DPL ha regresado a cero y cada vez que
regresa a cero se envía un aviso a la PC para que se incremente el
porcentaje de progreso de la captura. Para saber si se llenó la
memoria se verifica si DPH es igual a 80 en hexadecimal y es cuando
se debe suspender el almacenamiento de los datos. Una vez que se
ha llenado la memoria solo resta detener el TMR2 para que ya no
cuente; limpiar la bandera de interrupción; y mandar la señal a la PC
que ha finalizado la prueba.
26
Figura 10. Interrupción del TMR2
27
3.3.5 Interrupción del Puerto Serie.
En la rutina de interrupción del puerto serie se verifica si la
interrupción es causada por una recepción. Si es causada por una
transmisión es ignorada. En el caso de la recepción, se carga el valor
recibido al registro R0 y posteriormente se limpia la bandera de
interrupción del puerto serie.
3.4 Programa de la PC
Para comunicar los datos obtenidos al usuario se desarrolló una
aplicación para la PC, bajo Windows, con el entorno de desarrollo
Visual Basic .NET 2008 en su versión express, bajado gratuitamente
de la red. Se optó por utilizar el framework de Microsoft .NET ya que al
ser proporcionado por el mismo desarrollador del sistema operativo,
permite reutilizar las librerías ya cargadas en el sistema operativo sin
tener que realizar programación de más bajo nivel. De este modo para
poder acceder al puerto serie virtual que se conecta desde un puerto
USB no se requiere hacer ninguna programación extra. Más
información de esta plataforma y del control del puerto serie se
presenta en el ANEXO 2.
3.4.1 Interfaz de usuario
La interfaz del usuario representa el medio que permitirá
interactuar con el sistema. Esta interfaz tiene el esqueleto completo
que utilizará el sistema de emulación, por lo que posteriormente se le
agregara al menos otro módulo. Al cargarse la aplicación se presenta
el formulario principal que se muestra a continuación y cuyo código,
realizado en Visual Basic, se incluye en el ANEXO 4.
28
Figura 11. Formulario principal.
Se puede observar que se cuenta con una barra de menú que
contiene las siguientes opciones.
29
Figura 12. Opciones del menú.
Para guardar, se agregó dos opciones, la primera permite grabar
en un archivo de texto las lecturas referentes a la posición y la
segunda para el torque.
Figura 13. Ventana de Guardar Posición
La figura anterior muestra la ventana que se abre al elegir
guardar posición. Se puede observar que el directorio por defecto para
almacenar el archivo es la carpeta Desktop; la extensión por defecto
30
es .txt; el nombre por defecto es posicion.txt; si se elige Guardar
Torque ocurre lo mismo, únicamente cambia el nombre por defecto a
torque.txt.
Es importante hacer notar que al iniciar la aplicación,
inmediatamente intenta abrir el COM4, que es el nombre que tiene
asignado el puerto serie virtual por defecto, sin embargo no está atado
a utilizar únicamente el COM4, si no lo encuentra avisa al usuario y le
presenta una lista de los puertos series disponibles en la PC. Si en ese
momento no se ha conectado el cable USB-COM se puede conectar
pero será presentado en la lista cuando se vuelva a desplegar dicha
ventana, que se muestra enseguida y cuyo código se incluye en el
ANEXO 4.
Figura 14. Aviso de que no encontró puerto serie.
El usuario tiene la opción de elegir un puerto serie de la lista o
cerrar la aplicación. Si el usuario no sabe cual es el COM al que
conectó el microcontrolador puede ir seleccionando cada COM de la
lista. Si el COM elegido es erróneo, se le mostrará un aviso de la
siguiente manera.
31
Figura 15. Aviso de COM elegido erróneamente.
El código en Visual Basic de esta y los demás mensajes de error
se incluyen en el ANEXO 4.
Este mensaje también podría ser enviado en caso de que el
cable no haya sido conectado bien o el micro está en un estado
desconocido. La acción a tomar en ese caso seria darle un reset al
micro o desconectar y conectar el USB para que sea dado de alta
correctamente y al momento de presionar el OK mostrará la lista de los
puertos COM encontrados y podrá seguir probando con otros.
Para que la aplicación pueda comunicarse exitosamente el
microcontrolador debe estar conectado a su fuente de voltaje, ya que
al abrir la aplicación se envía un comando para que el micro le
responda, si el micro no responde dentro de 500ms significa que el
puerto serie elegido no es donde está conectado el micro. Si se está
seguro que el COM elegido es el correcto y el micro no responde es
posible que se encuentre trabado, cosa que se va solucionar con un
reset.
Debajo de la barra de menú de la aplicación se incluyó una
etiqueta de ayuda la cual presenta indicaciones para el usuario, como
se muestra a continuación
32
Figura 16. Ayudas para el usuario.
Los pasos a seguir para obtener los resultados deseados del
sistema se muestran en las siguientes etiquetas.
Figura 17. Muestra grafica de los pasos a seguir.
El paso uno será motivo de estudio de otra tesina. El paso dos
corresponde a poner el microcontrolador en su modo de captura y
presenta la ventana que se muestra a continuación.
33
Figura 18. Paso 2.
El usuario únicamente debe presionar START cuando desee
colocar el microcontrolador listo para arrancar el muestreo,
inmediatamente se despliega el mensaje de “ESPERANDO” debajo
del aviso de STATUS. Lo que ocurre en ese momento es que el
microcontrolador espera la señal de la tarjeta que proveerá de
corriente al motor. Dicha señal puede ser un pulso, que al ser
detectado por el microcontrolador inmediatamente empieza con el
muestreo de datos, en ese momento se presenta la hora de inicio y la
etiqueta de STATUS se coloca en “CORRIENDO”, mientras se
actualiza la barra de progreso cada 256 datos muestreados. Una vez
finalizada la etapa de muestreo, la etiqueta de status se actualiza a
“FINALIZÓ”, se despliega la hora final y se muestra la cantidad de
bytes almacenados en la memoria externa del microcontrolador.
Transcurriendo 5 segundos se coloca la etiqueta de status en
34
“INACTIVO”; el siguiente paso es solicitar los bytes almacenados para
que se puedan observar en la aplicación.
El paso tres del TAB presenta los siguientes campos.
Figura 19. Paso 3.
En este paso de la aplicación el usuario debe presionar el botón
“Leer Datos” y al instante se envía la instrucción al microcontrolador
para que envíe las lecturas. El usuario tiene la libertad de seleccionar,
lecturas en números decimales o hexadecimales, dando la siguiente
salida.
35
Figura 20. Paso 3 en Decimal.
Figura 21. Paso 3 en Hexadecimal.
36
La lectura en hexadecimal corresponde al valor binario arrojado
por el convertidor analógico-digital y la lectura en decimal muestra su
equivalente en voltaje, tomando como referencia un voltaje de 5V.
Cuando se presentan los datos en forma hexadecimal, los valores
negativos se muestran en complemento a dos; dado que la variable
que almacena cada lectura es de 2 Bytes es de esperar que los
valores negativos se muestren con 4 letras o números, como se
observa en la figura anterior.
Algunos de los mensajes de error que presenta la aplicación se
describen a continuación: enviar un comando dos veces.
Figura 22. Error por micro ocupado.
Cuando se desconecta el cable USB
37
Figura 23. Error de conexión.
Y por fallas inherentes a la aplicación.
Figura 24. Error de I/O.
38
CONCLUSIONES Y TRABAJO FUTURO.
El empleo de la plataforma .NET permite aprovechar las ventajas
de la programación orientada a objetos con la reutilización de código;
en este caso se utilizó la clase SerialPort que, sin duda alguna,
aceleró el tiempo de desarrollo de la aplicación. En la que queda
pendiente agregar el código para el PASO 1 de la aplicación, dado que
será desarrollado como parte de otro trabajo de tesina.
El hecho de Interfazar aplicaciones por medio del puerto USB,
amplía el panorama y la utilización de equipos actuales ya que por lo
regular se utilizan puertos que ya no están disponibles y por ende se
tiende a depender de esa tecnología y se desaprovechan las
bondades y mejoras de los puertos disponibles en la actualidad.
39
ANEXO 1. PROBLEMA DE SINCRONiA.
Para obtener la lectura de la posición se requiere lo siguiente.
Figura 25. Diagrama de posición.
Se obtiene a partir de la interfaz de un encoder que genera
pulsos que son utilizados como señal de reloj de un contador de 16
bits. El valor del contador representa la posición y debe ser capturada
por el microcontrolador cada milisegundo. Los 16 bits de la posición se
envían en paralelo a la tarjeta de memorias de emulación y por medio
de un bus de 8 bits al microcontrolador.
Se requiere emplear dos latches triestado para enviar los 16 bits
por el bus de 8. Alguna de las especificaciones del latch utilizado son:
el tiempo de configuración ( t ) y de mantenimiento ( t ) que se muestra
S
h
en la siguiente gráfica.
Figura 26. Tiempo de configuración y de mantenimiento.
40
Esta información representa el tiempo que deben permanecer los
datos a almacenar en los latches en los pines de entrada antes y
después de que se coloque la terminal latch enable en cero; de lo
contrario no se garantiza su confiabilidad.
Debido a los requerimientos del latch se presenta un problema
de sincronización. Puesto que el contador se incrementa o decrementa
en sincronía con los pulsos generados por la interfaz del encoder y el
lacth se controla en sincronía con el tiempo de muestreo marcado por
el microcontrolador, se corre el riesgo de que tanto el contador y los
latches se activen al mismo tiempo y genere una lectura errónea.
Dado que no se puede predecir este comportamiento es necesario
buscar una manera de evitar que se generen lecturas erróneas.
Contador
En sincronía con
el movimiento del
motor
Latch
En sincronía con
tiempo
de
muestreo
Figura 27. Problema de sincronismo.
La opción más sencilla y confiable para evitar este problema es
utilizando un circuito monoestable. Dicho circuito genera un pulso de
salida, cuyo ancho de pulso es controlado por un circuito RC, cada
que en la entrada detecta un flanco de bajada. La salida de este
circuito se conecta al pin “latch enable” para que al momento en que
dicha señal regresa a cero el dato sea almacenado. La señal de
41
entrada para este circuito proviene de una compuerta NAND, la que
generará el flanco de bajada, solo cuando el pulso de la interfaz del
encoder y la salida del microcontrolador estén en nivel alto; y dado que
el circuito es no re-disparable, no importa si una señal llega antes que
la otra, ya que una vez que se genera el pulso y se coloca la salida del
micro en cero, ya no hay manera que se altere la información
almacenada en los latches mientras son leídos, tal como se muestra a
continuación.
Figura 28. Sincronización con un circuito Monoestable.
42
ANEXO 2. PLATAFORMA .NET Y CONTROL DEL PUERTO
SERIE.
Microsoft .NET es un conjunto de productos y tecnologías de la
empresa Microsoft dentro de los cuales la mayoría dependen del
Framework .NET, el cual es un componente del sistema Windows y
que se puede considerar como un equivalente a una máquina virtual.
El Framework .NET puede ser descargado de la página de
Microsoft aunque también viene integrada en varias tecnologías de
Microsoft. La versión 3.0 del Framework está integrada al Sistema
Operativo Windows Vista y a la mayoría de las versiones del Windows
Server 2008. La última versión del Framework es la 3.5.
Varios lenguajes de programación se utilizan, como C# (el cual
es una mezcla entre C++ y Java), C++, J# (cercano a Java más no
compatible con él) y Visual Basic .NET. Además de estos lenguajes,
más adelante el lenguaje Python será compatible gracias al proyecto
IronPython. PHP ya es compatible gracias al proyecto Phalanger.
43
Figura 29. Framework .NET.
El Framework se compone de dos bloques principales: el CLR
(Common-Language Runtime) y la biblioteca de clases .NET. El CLR
es para .NET lo que la Máquina virtual de Java (JVM) es para Java,
esto es, una máquina virtual sin la cual la ejecución de código .NET
sería imposible. El Framework .Net nació para permitir la
interoperabilidad entre diferentes lenguajes de programación.
No importa cual lenguaje de programación se utilice para
programar en .NET, pues todo el código se transforma en MSIL
(Microsoft Intermediate Language).
Este código intermedio no lleva ninguna instrucción relativa al
Hardware o al Sistema Operativo. Entonces no se puede ejecutar
directamente. A pesar de esto, se puede escribir una aplicación
directamente en IL, un lenguaje que se parece a Assembler, sin
necesidad de pasar por un lenguaje de última generación como C#.
El CLR es necesario para ejecutar el código intermedio. Aporta
varias funcionalidades como el Garbage Collector (optimiza la
memoria utilizada por una aplicación durante su ejecución), la BCL
44
(Base Class Library) y el sistema de seguridad. Una vez que el código
está presente en la CLR, pasa a ser compilado por el JIT Compiler
(Just In Time) en lenguaje nativo de la máquina.
Accesando al puerto serie
Los drivers del sistema operativo son los encargados de manejar
ciertos detalles específicos del hardware, tal como el detectar puertos,
asignarles nombres y manejar la comunicación entre las aplicaciones.
Varios drivers son proporcionados con el sistema operativo, cada
uno maneja diferentes aspectos de la comunicación del puerto serie: el
driver serial.sys controla la comunicación con los dispositivos seriales,
el driver serenum.sys se trata de un filtro de más alto nivel que se
encarga de enumerar y de recuperar la información de identificación
para los dispositivos seriales con la funcionalidad de Plug-and-Play.
Un dispositivo con conexión USB que es accesado mediante un
puerto serial requiere de un driver adicional. El usbser.sys es un driver
del bus que administra la comunicación entre el driver del puerto serie
y el driver USB. Los puertos series virtuales requieren el driver
proporcionado por el fabricante en lugar de los proporcionados por
Windows.
Para identificar los puertos series virtuales, Windows utiliza el
driver del USB proporcionado por el fabricante y el proporcionado por
el sistema operativo. Los archivos .INF son descriptores que contienen
información necesaria para identificar los drivers de un dispositivo en
particular.
.Net SerialPort Class
Los programadores que utilizan el .NET Framework de Microsoft
pueden disponer de la clase SerialPort para poder acceder a los
dispositivos que contengan puerto serie. Las aplicaciones pueden
45
crear objetos de esta clase y tienen la libertad de manipular sus
propiedades, utilizar sus métodos o agregar nuevos al igual que a sus
eventos, sin la necesidad de recurrir a programación de bajo nivel o a
las Windows API que se utilizaban en Visual Basic 6, que por su
vulnerabilidad se dejaron de usar en la plataforma .NET. La clase
SerialPort fue añadida en la versión 2.0 de dicha plataforma. Y para
utilizar esta clase en nuestra aplicación es necesario incluir el
namespace System y el System.IO.Ports. La palabra namespace es
equivalente a los paquetes y librerías de java.
Tabla 1. Constructor de la clase SerialPort.
La clase SerialPort tiene un constructor que se puede utilizar con
o sin parámetros, dichos parámetros se emplean para inicializar
algunas de las propiedades que se muestran en la siguiente tabla.
Estas propiedades se deben personalizar de acuerdo a las
características del puerto serie que se requiere utilizar, para el caso
particular en el que se desea interfazar la PC con el miniMODUL-515C
utiliza un Baud rate de 9600, ya que cualquier computadora con puerto
serie soporta esta velocidad de transmisión. La propiedad de paridad
no se utiliza para esta aplicación por lo que se le asigna el valor
Parity.None. La propiedad DataBits le asignamos el valor de 8 bits ya
que el microcontrolador permite utilizar entre 8 y 9 bits, sin embargo
con 8 bits que se utilicen son suficientes. Para el caso de la propiedad
StopBits que almacena el número de bits de paro se le asignó el valor
StopBits.One para utilizar un solo bit y en total estará enviando un bit
de inicio, 8 bits de datos y un bit de paro. Además de las propiedades
mencionadas en la aplicación se utiliza la propiedad BytesToRead
para saber cuántos bytes hay en el buffer disponibles para ser leídos,
IsOpen se utiliza al abrir el puerto para evitar una excepción.
PortName que es donde se carga el nombre del puerto serie que
deseamos utilizar de los disponibles.
46
Tabla 2. Propiedades útiles de la clase SerialPort.
ReceivedBytesThreshold almacena el número de bits que se
requieren en el buffer para que se pueda generar un evento de dato
recibido. ReadTimeout se le asigna un valor en milisegundos que la
aplicación debe esperar para recibir un dato, es decir, los métodos de
lectura que se verán a continuación en todos con excepción de uno
bloquean el proceso donde se ejecuta la lectura hasta que se recibe el
47
dato a leer, por lo tanto, si no inicializamos esta propiedad corremos el
riesgo que la aplicación se congele esperando datos.
Tabla 3. Métodos útiles de la clase SerialPort.
“Close” se denomina el método para liberar el puerto utilizado al
cerrar la aplicación (caso en que se haya abierto el puerto); “Open”,
método para abrir y reservar el puerto para la actual aplicación en
tiempo de ejecución; “GetPortNames” es el método que regresa un
arreglo con los puertos COM presentes en la PC. De los métodos de
lectura que se muestran en la tabla anterior únicamente ReadExisting
es el único que no bloquea al proceso al ser empleado.
48
Tabla 4. Eventos de la clase SerialPort.
De los eventos generados por la clase SerialPort solamente se
utiliza el evento DataReceived que como su nombre lo indica, se
genera un evento al recibir el número de bytes que se determinaron
con la propiedad ReceivedBytesThreshold. Ahora bien, cuando se
presenta este evento se requiere especificar el componente que será
avisado en ese caso, para hacerlo se requiere de declarar un
delegado que es un concepto que se maneja en la plataforma .NET
Tabla 5. Delegados de la clase SerialPort.
El único delegado que se utiliza para esta aplicación es el
SerialDataReceivedEventHandler. Un delegado es una estructura de
programación que permite invocar a uno o varios métodos a la vez.
Estos métodos pueden encontrarse en la misma clase desde la que se
invocan o en otras clases asociadas. Hablando "a bajo nivel", un
delegado es un puntero fijo a una función (pero sin la complejidad de
la administración propia de dicho puntero). El principal uso de los
delegados es notificar a uno o varios componentes el acontecimiento
de un determinado evento con el fin de que dichos componentes
tomen alguna acción al respecto.
49
ANEXO 3. CÓDIGO DE PROGRAMA DEL
MICROCONTROLADOR.
$NOMOD51
$INCLUDE(REG515c.INC)
CSEG
AT
USING
0
SJMP
INICIO
0
;----------------------------------------------------------------------------RUTINA DE INTERRUPCIÓN DEL PUERTO SERIE
ORG
0023H
LJMP
SERISR
;----------------------------------------------------------------------------RUTINA DE INTERRUPCIÓN DE TIMER 2
ORG
002BH
LJMP
TIMER2ISR
;----------------------------------------------------------------------------CONFIGURACIÓN
INICIO:
MOV
MOV
MOV
IEN0,#10110000B
PCON,#10000000B
SCON,#01010000B
MOV
ADCON1,#10000000B
MOV
ADCON0,#10000000B
MOV
MOV
SRELH,#03H
SRELL,#0B2H
;SE HABILITAN INTERRUPCIONES DEL TIMER2 PUERTO SERIE
;EL BIT SMOD=1 DEL REGISTRO PCON.
;SE ELIGE MODO 1 DE PUERTO SERIE
;Y SE HABILITA LA RECEPCIÓN DEL PUERTO SERIE
;SE PONE EN ALTO ADCL PARA LOGRAR UNA FRECUENCIA
;DE CONVERSIÓN MENOR A 2MHZ RECOMENDADA POR EL FABRICANTE
;SE PONE A BD, PARA ELEGIR AL BAUD GENERATOR COMO GENERADOR DEL BAUD RATE
;DISPARO PARA CONVERSIÓN INTERNA
;MODO DE CONVERSIÓN EN SINGLE
;SE ELIGE EL CANAL 0
;PARA 9600 BAUD
;----------------------------------------------------------------------------CONFIGURANDO TIMER 2 PARA INTERRUPCIONES DE MUESTREO
MOV
CRCH,#0FCH
;VALOR DE RECARGA PARA CONTADOR
MOV
CRCL,#17H
MOV
T2CON,#00010000B
;SE CONFIGURA T2 CON RECARGA Y SE DEJA DETENIDO
;----------------------------------------------------------------------------INICIALIZANDO CONTADOR DE 16 BITS
SETB
P4.6
;PONE EN ALTA IMPEDANCIA BUFFER LOWER
SETB
P4.5
;PONE EN ALTA IMPEDANCIA BUFFER HIGH
SETB
P4.7
;EL LATCH ES CONTROLADO POR SEÑAL DE CLOCK
MOV
R0,#00H
;OPCIÓN DE MENÚ, VALOR INICIAL
MOV
R1,#00H
;PARA ALMACENAR EL ESTATUS DEL MICRO. 0 EN INACTIVO
CLR
P4.0
;PARA HACERLO ENTRADA
;---------------------------------------------------------------------------MAIN PRINCIPAL
MAINLOOP:
CJNE
R0,#'r',OPCAPTURA
CALL
MEMEXTR
OPCAPTURA:
CJNE
R0,#'c',OPPROG
CALL
CAPTURAINI
OPPROG:
CJNE
R0,#'p',OPSTAT
CALL
PROGMEM
OPSTAT:
CJNE
R0,#"s",OPEXTRA
CALL
STATUS
OPEXTRA:
CJNE
R0,#'e',MAINLOOP
CALL
OPCIONESTADO
JMP
MAINLOOP
;----------------------------------------------------------------------------ENVIAR ESTADO DEL MICRO
OPCIONESTADO:
MOV
A,R1
MOV
SBUF,A
;ENVÍA EL ÚLTIMO DATO DE ESTADO
ENVEDO:
JNB
TI,ENVEDO
CLR
TI
MOV
R0,#00H
;ELIMINA LA OPCIÓN DE MENÚ LEÍDA
RET
;---------------------------------------------------------------------------ENVÍA STATUS DE CAPTURA
STATUS:
MOV
A,DPH;#80H
50
MOV
SBUF,A
;ENVÍA EL ÚLTIMO DATO DEL STATUS
JNB
CLR
MOV
RET
TI,ENVSTA
TI
R0,#00H
;ELIMINA LA OPCIÓN DE MENÚ LEÍDA
ENVSTA:
;----------------------------------------------------------------------------ENVÍO DE LECTURAS
MEMEXTR:
MOV
R0,#00H
;ELIMINA LA OPCIÓN DE MENÚ LEÍDA
MOV
R1,#03H
;SE ENCUENTRA EN ESTADO DE ENVÍO DE LECTURAS
MOV
IEN0,#10100000B
;SE HABILITA LA INTERRUPCIÓN DEL TMR2 Y DESHABILITA LA DEL PUERTO SERIE
MOV
DPTR,#0000H
MASR0:
MOVX
MOV
A,@DPTR
SBUF,A
JNB
CLR
INC
MOVX
MOV
TI,MASR01
TI
DPTR
A,@DPTR
SBUF,A
JNB
CLR
INC
TI,MASR11
TI
DPTR
MOVX
MOV
A,@DPTR
SBUF,A
JNB
CLR
INC
TI,MASR21
TI
DPTR
MOVX
MOV
A,@DPTR
SBUF,A
JNB
CLR
INC
MOV
CJNE
MOV
MOV
RET
TI,MASR31
TI
DPTR
A,DPH
A,#80H,MASR0
IEN0,#10110000B
R1,#00H
;ENVÍA LA PRIMERA LECTURA
MASR01:
;ENVÍA LA SEGUNDA LECTURA
MASR11:
;ENVÍA LA TERCERA LECTURA
MASR21:
;ENVÍA LA CUARTA LECTURA
MASR31:
;SE HABILITAN LAS INTERRUPCIONES DEL TIMER2 Y PUERTO SERIE
;HA TERMINADO EL ENVÍO Y REGRESA A INACTIVO
;----------------------------------------------------------------------------CAPTURA INICIAL
CAPTURAINI:
MOV
R0,#00H
;ELIMINA LA OPCIÓN DE MENÚ ELEGIDA, ENVIADA POR PUERTO SERIE
MOV
R1,#02H
;SE ENCUENTRA EN ESTADO DE CAPTURA DE MUESTRAS
MOV
IEN0,#10100000B
;SE HABILITAN INTERRUPCIONES DEL TMR2 Y SE DESHABILITA LA DEL PUERTO SERIE
SETB
P4.3
;PONE EN ALTO LOAD (ESTA EN ALTO POR DEFAULT)
;PARA CARGAR EL CONTADOR DE 16 BITS CON UN VALOR DE INICIO
CLR
P4.3
;NECESARIO PARA PRODUCIR UN FLANCO DE SUBIDA
MOV
DPTR,#0000H
;SE INICIALIZA EL APUNTADOR DE 16BITS
SETB
P4.3
;YA ESTÁN LOS VALORES DE INICIO EN EL CONTADOR
CLR
P4.2
;ENCIENDE LÁMPARA PARA INDICAR QUE ESTA EN ESPERA PARA INICIAR CAPTURA
CAPTWAIT:
JNB
P4.0,CAPTWAIT
;EN ESPERA QUE SE SOLICITE CAPTURA
CLR
P4.7
;ENVIADO AL MONOESTABLE PARA QUE YA NO SE CAPTUREN MAS VALORES EN LATCH
MOV
MOV
ADCON0,#10000000B
ADDATL,#0FFH
;LECTURA DEL ADC CANAL 0
;SE ELIGE CANAL CERO Y SE DEJA IGUAL EL ADCL
;SE REALIZA LA CONVERSIÓN
JB
MOV
MOVX
INC
BSY,XMASW21
A,ADDATH
@DPTR,A
DPTR
MOV
MOV
ADCON0,#10000001B
ADDATL,#0FFH
JB
MOV
MOVX
INC
BSY,XMASW31
A,ADDATH
@DPTR,A
DPTR
XMASW21:
;ESPERAR MIENTRAS TERMINA LA CONVERSIÓN
;LECTURA DEL ADC CANAL 1
;SE ELIGE CANAL UNO Y SE DEJA IGUAL EL ADCL
;SE CORRE LA CONVERSIÓN
XMASW31:
;ESPERAR MIENTRAS TERMINA LA CONVERSIÓN
51
CLR
MOV
MOVX
INC
SETB
P4.5
A,P5
@DPTR,A
DPTR
P4.5
;HABILITA SALIDA DE LATCH HIGH
CLR
MOV
MOVX
INC
SETB
P4.6
A,P5
@DPTR,A
DPTR
P4.6
MOV
MOV
SETB
TH2,#0F8H
TL2,#7FH
T2I0
;VALOR INICIAL PARA CONTADOR
SETB
P4.7
;SE HABILITA LACTH PARA QUE PUEDAN SER ACTUALIZADOS
;PRIMERA LECTURA DE POSICIÓN
;DESHABILITA SALIDA DE LATCH HIGH
;HABILITA SALIDA LATCH LOW
;SEGUNDA LECTURA DE POSICIÓN
;DESHABILITA SALIDA DE LATCH LOW
;SE PONE A CONTAR AL TMR2
RET
;----------------------------------------------------------------------------TIMER 2 ISR. CAPTURA DE MUESTRAS
TIMER2ISR:
NOP
CLR
P4.7
;LATCH ENABLE
;LECTURA DEL ADC CANAL 0
;SE ELIGE CANAL CERO Y SE DEJA IGUAL EL ADCL
;SE CORRE LA CONVERSIÓN
MOV
MOV
ADCON0,#10000000B
ADDATL,#0FFH
JB
MOV
MOVX
INC
BSY,MASW21
A,ADDATH
@DPTR,A
DPTR
MOV
MOV
ADCON0,#10000001B
ADDATL,#0FFH
JB
MOV
MOVX
INC
BSY,MASW31
A,ADDATH
@DPTR,A
DPTR
CLR
MOV
MOVX
INC
SETB
P4.5
A,P5
@DPTR,A
DPTR
P4.5
;HABILITA SALIDA DE HIGH
CLR
MOV
MOVX
INC
SETB
P4.6
A,P5
@DPTR,A
DPTR
P4.6
;HABILITA SALIDA LATCH LOW
;DESHABILITA SALIDA DE LATCH LOW
SETB
P4.7
;LATCH ENABLE
MOV
CJNE
MOV
A,DPL
A,#00H,MASW0B
R0,#'s'
;INDICA QUE DEBE ENVIAR EL STATUS (S)
MOV
CJNE
A,DPH
A,#80H,MASW0
SETB
CLR
P4.2
T2I0
;INDICA QUE NO ESTA LISTO SE APAGA LA LÁMPARA
;PARA DE CONTAR EL T2
MOV
MOV
A,#00H
SBUF,A
;ENVÍA EL ÚLTIMO DATO DEL STATUS
JNB
CLR
TI,MASW0C
TI
MOV
MOV
MOV
R0,#00H
R1,#00H
IEN0,#10010000B
MASW21:
;ESPERA MIENTRAS TERMINA LA CONVERSIÓN
;LECTURA DEL ADC CANAL 1
;SE ELIGE CANAL UNO Y SE DEJA IGUAL EL ADCL
;SE CORRE LA CONVERSIÓN
MASW31:
;ESPERAR MIENTRAS TERMINA LA CONVERSIÓN
;PRIMERA LECTURA DE POSICIÓN
;DESHABILITA SALIDA DE LATCH HIGH
;SEGUNDA LECTURA DE POSICIÓN
MASW0B:
MASW0C:
52
;ELIMINA LA OPCIÓN DE MENÚ LEÍDA
;HA TERMINADO EL MUESTREO Y REGRESA A ESTADO INACTIVO
;SE HABILITA INTERRUPCIÓN DEL PUERTO SERIE Y SE DESHABILITA LA DEL TMR2
MASW0:
CLR
RETI
TF2
;---------------------------------------PROGRAMACIÓN DE MEMORIAS
PROGMEM:
MOV
R0,#00H
;ELIMINA LA OPCIÓN DE MENÚ LEÍDA
MOV
R1,#01H
;SE ENCUENTRA EN ESTADO DE PROGRAMACIÓN
MOV
R1,#00H
;HA TERMINADO DE PROGRAMAR Y REGRESA A ESTADO INACTIVO
RET
;---------------------------------------SERIAL PORT ISR
SERISR:
JB
TI,TRANSF
MOV
A,SBUF
MOV
R0,A
MOV
P1,A
CLR
RI
RETI
TRANSF:
RETI
END
53
ANEXO 4. CÓDIGO DE APLICACIÓN DE LA PC.
Código del formulario principal:
Imports
Imports
Imports
Imports
Imports
Imports
Imports
Imports
System
System.IO
System.IO.Ports
System.Runtime.Remoting.Messaging
System.Collections.Generic
System.Text
System.Windows.Forms
System.Drawing
Public Class Form1
Friend horaActual As Date
Friend estado As Integer = -1
Friend paraEnviar As String
Friend myValidarPuerto As New validarPuerto
Friend myMicroOcupado As New MicroOcupado
Friend myPuertoEquivocado As New puertoEquivocado
Friend myPuertoDesconectado As New puertoDesconectado
Friend myPuertoNoFunciona As New puertoNoFunciona
Public nombrePuerto As String = "COM4"
Friend puertoSerieBuffer(32767) As Byte
Friend lectorBinario As BinaryReader
Friend opcionDecimal As Boolean = True
Friend pasoElegido As Integer = 0
Friend contadorStatus As Integer = 0
Friend dato As Byte
Public Shared contador As Integer = 0
Friend auxPos As StringBuilder
Friend auxTorque As StringBuilder
Friend auxTime As StringBuilder
Friend resultadoDecimal As StringBuilder
Friend resultadoHexadecimal As StringBuilder
Friend Delegate Sub SerialDataReceivedEventHandlerDelegate(ByVal sender As Object, ByVal e As
SerialDataReceivedEventArgs)
Private SerialDataReceivedEventHandler1 As New SerialDataReceivedEventHandler(AddressOf DataReceived)
Friend myPuertoSerie As SerialPort
Friend MyMainForm As Form1
Private Delegate Sub AccessFormMarshalDelegate()
Private Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click
Label8.Text = "Pueder ejecutar los pasos en orden o como mejor te convenga."
End Sub
Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles
Me.FormClosing
If (Not (myPuertoSerie Is Nothing)) Then
If myPuertoSerie.IsOpen Then
Do While (myPuertoSerie.BytesToRead > 0)
myPuertoSerie.ReadExisting()
Loop
myPuertoSerie.Dispose()
End If
End If
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
AddHandler validarPuerto.configuracionPuerto, AddressOf setportparameter
Dim namearray() As String
Dim index As Integer = -1
Dim good As Boolean = False
Do Until (good)
index = -1
namearray = SerialPort.GetPortNames
Do
index += 1
Loop Until ((namearray(index) = nombrePuerto) Or (index = namearray.GetUpperBound(0)))
If (namearray(index) = nombrePuerto) Then
myPuertoSerie = New SerialPort(nombrePuerto, 9600, Parity.None, 8, StopBits.One)
myPuertoSerie.ReadBufferSize = 65536
54
myPuertoSerie.ReadTimeout = 500
myPuertoSerie.ReceivedBytesThreshold = 1
If (Not myPuertoSerie.IsOpen) Then
Try
myPuertoSerie.Open()
Try
pasoElegido = 0
paraEnviar = "e"
myPuertoSerie.Write(paraEnviar)
estado = myPuertoSerie.ReadByte
If estado = 0 Then
good = True
estado = -1
Else
myPuertoEquivocado.ShowDialog()
myPuertoSerie.ReadExisting()
myPuertoSerie.Dispose()
If (myValidarPuerto.ShowDialog() = Windows.Forms.DialogResult.Cancel) Then
End
End If
End If
Catch ex As TimeoutException
myPuertoEquivocado.ShowDialog()
myPuertoSerie.ReadExisting()
myPuertoSerie.Dispose()
If (myValidarPuerto.ShowDialog() = Windows.Forms.DialogResult.Cancel) Then
End
End If
Catch ex As System.IO.IOException
myPuertoNoFunciona.ShowDialog()
End
End Try
Catch ex As UnauthorizedAccessException
If (myValidarPuerto.ShowDialog() = Windows.Forms.DialogResult.Cancel) Then
End
End If
good = False
Catch ex As System.Exception
If (myValidarPuerto.ShowDialog() = Windows.Forms.DialogResult.Cancel) Then
End
End If
good = False
End Try
End If
Else
If (myValidarPuerto.ShowDialog() = Windows.Forms.DialogResult.Cancel) Then
End
End If
good = False
End If
Loop
Timer1.Stop()
AddHandler myPuertoSerie.DataReceived, SerialDataReceivedEventHandler1
End Sub
Private Sub setportparameter(ByVal puertoSeleccionado As String)
nombrePuerto = puertoSeleccionado
End Sub
Private Sub AccessFormMarshal()
Dim args() As Object = {}
Dim AccessFormMarshalDelegate1 As New AccessFormMarshalDelegate(AddressOf AccessForm)
MyBase.Invoke(AccessFormMarshalDelegate1, args)
End Sub
Private Sub AccessForm()
Select Case pasoElegido
Case 0
Case 1
Case 2
If (Not estado = 0) Then
estado = dato
Else
If contadorStatus = 0 Then
horaActual = Now
TextBox5.Text = horaActual
End If
Label7.Text = "CORRIENDO"
contadorStatus = contadorStatus + 256
55
ProgressBar1.Value = contadorStatus * (100 / 32768)
If ProgressBar1.Value = 100 Then
ProgressBar1.Value = 0
Label7.Text = "FINALIZO"
estado = -1
Timer1.Start()
End If
TextBox3.Text = contadorStatus
If contadorStatus = 32768 Then
horaActual = Now
TextBox6.Text = horaActual
End If
End If
Case 3
TextBox2.Text = contador
If contador >= 32768 Then
estado = -1
Dim fin As Integer = puertoSerieBuffer.Count / 4 - 1
Dim posicion(fin) As Double
Dim torque(fin) As Double
Dim a As Integer
Dim b As Integer
Dim i As Integer = 0
auxPos = New StringBuilder
auxTorque = New StringBuilder
auxTime = New StringBuilder
resultadoDecimal = New StringBuilder
resultadoHexadecimal = New StringBuilder
'***************************datos decimales
For index As Integer = 0 To puertoSerieBuffer.Count - 4 Step 4
posicion(i) = puertoSerieBuffer(index + 2) * 256 + puertoSerieBuffer(index + 3)
a = puertoSerieBuffer(index)
b = puertoSerieBuffer(index + 1)
torque(i) = (a - b) * (5 / 255)
i += 1
Next
For index As Integer = 0 To fin
auxTime.AppendLine(index)
auxPos.AppendLine(posicion(index))
auxTorque.AppendLine(torque(index))
resultadoDecimal.AppendLine(Chr(9) & index & Chr(9) & Chr(9) & posicion(index) & Chr(9) & Chr(9) &
Format(torque(index), "0.000"))
Next
Dim torqueH(fin) As Short
Dim posicionH(fin) As Integer
i = 0
For index As Integer = 0 To puertoSerieBuffer.Count - 4 Step 4
posicionH(i) = puertoSerieBuffer(index + 2) * 256 + puertoSerieBuffer(index + 3)
a = puertoSerieBuffer(index)
b = puertoSerieBuffer(index + 1)
torqueH(i) = a - b
i += 1
Next
'*******************************datos hexadeciamles
For index As Integer = 0 To fin
auxTime.AppendLine(index)
auxPos.AppendLine(Convert.ToString(posicionH(index), 16).PadLeft(2, "0"c))
auxTorque.AppendLine(Convert.ToString(torqueH(index), 16).PadLeft(2, "0"c))
resultadoHexadecimal.AppendLine(Chr(9) & index & Chr(9) & Chr(9) &
Convert.ToString(posicionH(index), 16).PadLeft(2, "0"c).ToUpper _
& Chr(9) & Chr(9) & Convert.ToString(torqueH(index), 16).PadLeft(2, "0"c).ToUpper)
Next
If opcionDecimal Then
TextBox1.Text = resultadoDecimal.ToString
Else
TextBox1.Text = resultadoHexadecimal.ToString
End If
End If
Case Else
End Select
End Sub
Private Sub DataReceived(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)
Dim numberOfBytesToRead As Integer
56
Select Case pasoElegido
Case 0
Case 1
Case 2
If Not (String.Equals(paraEnviar, "e")) Then
dato = myPuertoSerie.ReadByte
End If
Case 3
numberOfBytesToRead = myPuertoSerie.BytesToRead
contador = numberOfBytesToRead
If numberOfBytesToRead >= 32768 Then
Dim mySerialPortStream As Stream
mySerialPortStream = myPuertoSerie.BaseStream
lectorBinario = New BinaryReader(mySerialPortStream)
lectorBinario.Read(puertoSerieBuffer, 0, 32768)
End If
Case Else
End Select
If Not (String.Equals(paraEnviar, "e")) Then
Me.AccessFormMarshal()
End If
End Sub
Private Sub btnWriteSingle_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
btnWriteSingle.Click
If estado = -1 And myPuertoSerie.IsOpen Then
Try
pasoElegido = 0
paraEnviar = "e"
myPuertoSerie.Write(paraEnviar)
estado = myPuertoSerie.ReadByte
pasoElegido = 3
TextBox1.Text = ""
paraEnviar = "r"
myPuertoSerie.Write(paraEnviar)
Debug.WriteLine(paraEnviar)
Catch ex As TimeoutException
Catch ex As System.IO.IOException
myPuertoNoFunciona.ShowDialog()
End
End Try
Else
If Not myPuertoSerie.IsOpen Then
myPuertoDesconectado.ShowDialog()
End
Else
myMicroOcupado.ShowDialog()
End If
End If
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Timer1.Stop()
Label7.Text = "INACTIVO"
End Sub
Private Sub SalirToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
SalirToolStripMenuItem.Click
End
End Sub
Private Sub GuardarComoToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
GuardarComoToolStripMenuItem.Click
If SaveFileDialog1.ShowDialog() = DialogResult.OK Then
Dim myStreamWriter As New StreamWriter(SaveFileDialog1.FileName)
If Not (myStreamWriter Is Nothing) Then
myStreamWriter.Write(auxPos.ToString)
myStreamWriter.Close()
End If
End If
End Sub
Private Sub GuardarTorqueToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
GuardarTorqueToolStripMenuItem.Click
If SaveFileDialog2.ShowDialog() = DialogResult.OK Then
Dim myStreamWriter As New StreamWriter(SaveFileDialog2.FileName)
If Not (myStreamWriter Is Nothing) Then
myStreamWriter.Write(auxTorque.ToString)
myStreamWriter.Close()
57
End If
End If
End Sub
Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
RadioButton1.CheckedChanged
opcionDecimal = True
If Not TextBox1.Text = "" Then
TextBox1.Text = resultadoDecimal.ToString
End If
End Sub
Private Sub RadioButton2_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles
RadioButton2.CheckedChanged
opcionDecimal = False
If Not TextBox1.Text = "" Then
TextBox1.Text = resultadoHexadecimal.ToString
End If
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
If estado = -1 And myPuertoSerie.IsOpen Then
contadorStatus = 0
Label7.Text = "ESPERANDO"
TextBox3.Text = ""
TextBox5.Text = ""
TextBox6.Text = ""
pasoElegido = 0
Try
paraEnviar = "e"
myPuertoSerie.Write(paraEnviar)
estado = myPuertoSerie.ReadByte
pasoElegido = 2
If estado = 0 Then
paraEnviar = "c"
myPuertoSerie.Write(paraEnviar)
Debug.WriteLine(paraEnviar)
End If
Catch ex As TimeoutException
Debug.WriteLine("ocurrio timeout")
Catch ex As System.IO.IOException
myPuertoNoFunciona.ShowDialog()
End
End Try
Else
If Not (myPuertoSerie.IsOpen) Then
myPuertoDesconectado.ShowDialog()
End
Else
myMicroOcupado.ShowDialog()
End If
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
pasoElegido = 1
End Sub
Private Sub TabControl1_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles
TabControl1.MouseClick
Dim value As TabPage
value = TabControl1.SelectedTab
If value.Equals(TabPage2) Then
Label8.Text = "Presiona START para poner el micro en modo de captura."
ElseIf value.Equals(TabPage1) Then
Label8.Text = "Se implementara proximamente."
Else
Label8.Text = "Pueder ejecutar los pasos en orden o como mejor te convenga."
End If
End Sub
End Class
Código del formulario del error “microcontrolador ocupado”:
Public Class MicroOcupado
58
Private Sub Label1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label1.Click
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.DialogResult = Windows.Forms.DialogResult.OK
End Sub
Private Sub PictureBox1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click
End Sub
Private Sub Label2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label2.Click
End Sub
End Class
Código del formulario del error “puerto desconectado”:
Public Class puertoDesconectado
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.DialogResult = Windows.Forms.DialogResult.OK
End Sub
End Class
Código del formulario del error “puerto equivocado”:
Public Class puertoEquivocado
Private Sub puertoEquivocado_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.DialogResult = Windows.Forms.DialogResult.OK
End Sub
End Class
Código del formulario del error “puerto no funciona”:
Public Class puertoNoFunciona
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Me.DialogResult = Windows.Forms.DialogResult.OK
End Sub
End Class
Código del formulario del aviso “no encontró puerto serie
elegido”:
Imports System
Imports System.Configuration
Imports System.IO
Imports System.IO.Ports
Public Class validarPuerto
Friend Shared Event configuracionPuerto(ByVal puertoSeleccionado As String)
Private Sub validarPuerto_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
ComboBox1.DataSource = SerialPort.GetPortNames
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
RaiseEvent configuracionPuerto(ComboBox1.SelectedItem.ToString)
Me.DialogResult = Windows.Forms.DialogResult.OK
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Me.DialogResult = Windows.Forms.DialogResult.Cancel
End Sub
End Class
59
BIBLIOGRAFÍA
[1]
Jeffrey Richter, "WINDOWS VIA C/C++”, Microsoft Press, 2008.
[2] Mark E. Russinovich, “WINDOWS INTERNALS”, Microsoft Press,
2005
[3] Bill Vejen, Billy Hollis, “PROFESSIONAL VISUAL BASIC 2008”,
Wiley, 2008
[4]
http://www.phytec.com/pdf/manuals/L-230e.pdf
[5]
http://www.phytec.com/pdf/datasheets/C515C_UM.pdf
60
Descargar