.
REPORTE
UNIDAD
5 ALUMNO
LUIS ALBERTO SALINAS DIEGO DOCENTE
M. EN M. JOSÉ MIGUEL HERNÁNDEZ PAREDES
1 RESUMEN
En este documento se reporta el desarrollo para la solución del examen correspondiente a la unidad 4 de la materia Programación Avanzada, el cual consistía en crear una interfaz de usuario para un controlador PID utilizando la comunicación USB realizada en la unidad anterior para la comunicación entre la interfaz y el controlador y compartir los datos. INTRODUCCION
El Bus Universal en Serie o USB, es un bus de comunicaciones que sigue un estándar que define los cables, conectores y protocolos usados para conectar, comunicar y proveer de alimentación eléctrica entre computadoras, periféricos y dispositivos electrónicos. Su desarrollo partió de un grupo de empresas del sector que buscaban unificar la forma de conectar periféricos a sus equipos. Hoy en día este estándar es muy utilizado para la conexión de periféricos como: teclados, ratones, memorias USB, joysticks, escáneres, cámaras digitales, teléfonos móviles, reproductores multimedia, impresoras, dispositivos multifuncionales, sistemas de adquisición de datos, entre muchos otros más. Tal ha sido su éxito, que ha ido desplazando con el tiempo a otros estándares como lo es el puerto serie, o el paralelo siendo así que los nuevos dispositivos ya no los implementen en su hardware. OBJETIVO
Crear una interfaz de usuario y establecer comunicación entre el PIC y la Computadora utilizando el estándar USB Bulk para un Controlador PID. PLANTEAMIENTO DEL PROBLEMA
Se podrá crear una UI para un controlador PID para establecer la comunicación USB entre un PIC y una Computadora utilizando PIC C Compiler y Visual Studio QT .
“
”
MATERIALES Y METODOS Microcontrolador PIC 18F4550 de Microchip®. Computadora con Visual Studio con QT Add on y PIC C Compiler. Tarjeta de Desarrollo para el PIC Programador PickIt3
MARCO TEORICO
Bus Universal en Serie (USB) Es un protocolo de comunicación que permite enlazar diversos periféricos a un dispositivo electrónico (frecuentemente, un ordenador) para el intercambio de datos, el desarrollo de operaciones y, en algunos casos, la carga de la batería del dispositivo o dispositivos conectados. Es, por tanto, básicamente, un puerto que funciona de toma de conexión entre diferentes aparatos. Los equipos que se pueden conectar a una computadora gracias al USB son múltiples. Cámaras de fotos, teléfonos móviles, ratones y teclados, pendrives, reproductores MP4, webcams, tarjetas de vídeo, mini altavoces, impresoras, grabadoras de DVD, discos duros externos o PDA son sólo a lgunos ejemplos. Este protocolo fue creado en la década de los años 90 por un conjunto de siete grandes empresas de la tecnología (Intel, IBM, Northern Telecom, Compaq, Microsoft, NEC) con la única finalidad de alcanzar un estándar para la conexión de los periféricos a una computadora.
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA
2
Clase USB - Dispositivo de Interfaz Humana (HID) El HID o dispositivo de interfaz humana, hace referencia a un tipo de interfaces de usuario para computadores que interactúan directamente, tomando entradas provenientes de humanos, y pueden entregar una salida a los humanos.
Clase USB – Clase de Dispositivo de Comunicaciones (CDC) Es un compuesto de Universal Serial Bus clase de dispositivo. La clase puede incluir más de una interfaz, como una interfaz de control personalizado, interfaz de datos, audio o almacenamiento masivo interfaces relacionadas. La clase de dispositivo de comunicaciones se utiliza para dispositivos de red como una tarjeta de red, módems, ISDN, fax y aplicaciones de telefonía para realizar llamadas de voz regulares. Esta clase puede utilizarse para equipos industriales como maquinaria CNC para permitir la actualización de antiguos controladores seriales RS-232 y la robótica, ya que pueden mantener compatibilidad de software. El dispositivo se conecta a una línea de comunicación R S-232 y el sistema operativo en el lado USB hace que el dispositivo USB aparece como un puerto RS-232 tradicional. Fabricantes de chip como tecnología prolific, FTDI, Microchip, Atmel ofrecen instalaciones para el desarrollo de dispositivos USB RS-232. Dispositivos de esta clase también se ejecutan en sistemas embebidos como los teléfonos móviles para que un teléfono puede ser utilizado como un puerto de módem, el fax o la red. Se utilizan generalmente las interfaces de datos para realizar transferencia de datos a granel.
Modo USB Bulk Modo de transferencia de datos USB el cual transmite los datos con mayor velocidad entre el periférico y la computadora comparado con la clase CDC los cuales estén configurados al mismo PI D y VID.
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA
3 DESARROLLO
La problemática a resolver era crear una aplicación e n Visual Studio la cual tuviera una interfaz con la cual se pudiese controlar las constantes de un controlador PID en un PIC para el control de velocidad de un motor DC, para establecer la comunicación se utilizó la comunicación USB clase bulk utilizada en la unidad anterior, el proceso de comunicación debía de ser bidireccional para enviar y recibir datos al controlador PID. Primero una vez teniendo armado completamente el circuito de la tarjeta de desarrollo para pa ra el PIC, se procedió a realizar la programación para este, en el cual se creó un nuevo proyecto y en el asistente se configuro para el con un cristal de y un reloj de , además de configurar el USB en modo , en donde definimos algunos parámetros como el y el y agregar los .
Después se creó y compilo el programa y en la tarjeta de desarrollo se conectó el programador pickit3, con el que una vez compilado se cargó el archivo hexadecimal en la placa con la ayuda de la herramienta de software propia del programador. Allí se cargó y se habilito el voltaje de .
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA
4 Después se creó un proyecto en para crear una en donde se creó el , la y se agregaron las y para poder establecer la comunicación . En las librerías de comunicación se modificaron para p oder y solamente, ya que lo demás ya estaba hecho, (detectar todos los dispositivos conectados, verificar que estuviese conectado, etc.), bastaba con llamar las funciones en el programa principal, guardar y mostrar las variables por consola. Una vez terminado el programa se y se el programa en Visual Studio en donde una vez hecho esto en la tarjeta debía de aparecer que se había enumerado correctamente el dispositivo USB, además de mostrar en la PC una ventana en donde confirmara la conexión correcta del dispositivo (esto de acuerdo a la programación que se realizó), después de confirmar la conexión la computadora debió de haber mandado los hacia la tarjeta, en donde se debieron mostrar en la correctamente los bytes que se habían mandado, y rápidamente el PIC debía de responder mandando otros 1 , por lo que la PC debía de mostrarlos de igual manera en la .
PROGRAMA PIC EN CCS (HEADER) //PIC #include <18F4550.h> #device ADC=10 //FUSIBLES #fuses HSPLL //High Speed Crystal/Resonator with PLL PLL enabled enabled #fuses NOWDT //No Watch Dog Timer #fuses NOPROTECT //Code not protected from reading #fuses NOLVP //No low voltage programming #fuses NODEBUG NODEBUG //No Debug mode for ICD #fuses USBDIV //USB clock source comes from PLL divide by 2 #fuses PLL5 //Divide By 5(20MHz oscillator input) #fuses CPUDIV1 CPUDIV1 //No System System Clock Postscaler #fuses VREGEN //USB voltage regulator regulator enabled //RELOJ Y OSCILADOR OSCILADOR #use delay(clock=48MHz, crystal=20MHz, USB_FULL) USB_FULL) //Configurado para un cristal de 20MHz y un reloj de 48MHz //USB #define USB_TX_DATA 0x0C #define USB_RX_DATA 0x14
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA
5 #define USB_CONFIG_VID 0x04D8 //ID del Fabricante del dispositivo USB #define USB_CONFIG_PID 0x0011 //ID del Producto del dispositivo USB #define USB_CONFIG_BUS_POWER USB_CONFIG_BUS_POWER 100 //100mA (Rango 0-500mA) //#define USB_CONFIG_VERSION USB_CONFIG_VERSION 0x0100 0x0100 //01.00 //range is 00.00 to 99.99 //#define USB_HID_DEVICE USB_HID_DEVICE FALSE //Deshabilita el uso de las directivas HID //#define USB_EP1_TX_ENABLE USB_EP1_TX_ENABLE USB_ENABLE_BULK USB_ENABLE_BULK //Enciende //Enciende EP1 (EndPoint1) para transferencias IN Bulk/Interrupt //#define USB_EP1_RX_ENABLE USB_EP1_RX_ENABLE USB_ENABLE_BULK USB_ENABLE_BULK //Enciende //Enciende EP1 (EndPoint1) para transferencias OUT Bulk/Interrupt Bulk/Interrupt #define USB_EP1_TX_SIZE USB_TX_DATA USB_TX_DATA //Bytes a Enviar (Tama?o a asignar para el buffer del Endpoint 1 de TX) #define USB_EP1_RX_SIZE USB_RX_DATA USB_RX_DATA //Bytes a Recibir (Tama?o a asignar para el buffer del Endpoint 1 de RX) //LCD #define LCD_ENABLE_PIN LCD_ENABLE_PIN PIN_D0 #define LCD_RS_PIN PIN_D1 #define LCD_RW_PIN PIN_D2 #define LCD_DATA4 PIN_D4 #define LCD_DATA5 PIN_D5 #define LCD_DATA6 PIN_D6 #define LCD_DATA7 PIN_D7 //OTROS #define LED_CICLO LED_CICLO PIN_D3 //Led Ciclo Tarjeta Desarrollo //LIBRERIAS #include
//Capa de hardware hardware Microchip PIC18FXX5X PIC18FXX5X para el controlador PIC USB de CCS CCS #include //Enumerador //Enumerador y Descriptor USB para comunicacion USB Modo Bulk(Masivo) #include //Maneja los tokens de configuraci?n USB y obtiene informes del descriptor #include //Controla la pantalla LCD 16x2 #include //Libreria Float
PROGRAMA PIC EN CCS (PRINCIPAL) #include //VARIABLES //VARIABLES GLOBALES int8 inData[USB_RX_DATA] inData[USB_RX_DATA] = {0,0,0,0,0,0,0,0,0,0,0,0 {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0}; ,0,0,0}; int8 outData[USB_TX_DATA] outData[USB_TX_DATA] = {0,0,0,0,0,0,0,0,0,0,0,0}; {0,0,0,0,0,0,0,0,0,0,0,0}; //PROTOTIPOS void PIC_LCD_Init(); void PIC_LED_Blink(); void PIC_USB_Init(); void PIC_USB_Transfer_Data(); PIC_USB_Transfer_Data(); float BytesToFloat(char *d); char *FloatToBytes(float n); //PROGRAMA PRINCIPAL PRINCIPAL void main() { PIC_LCD_Init(); PIC_LED_Blink(); //PIC_USB_Init(); usb_init(); do{ usb_task(); PIC_USB_Transfer_Data(); }while(TRUE); /*while(TRUE) { PIC_USB_Transfer_Data(); }*/ } //FUNCIONES void PIC_LCD_Init() { lcd_init(); printf(lcd_putc,"\f PROGRAMACION"); lcd_gotoxy(1, 2);
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA
6 printf(lcd_putc," AVANZADA"); delay_ms(1250); printf(lcd_putc,"\fCONTROL printf(lcd_putc,"\fCONTROL PID"); lcd_gotoxy(1,2); printf(lcd_putc," VELOCIDAD"); } void PIC_LED_Blink() { for(int i = 0; i < 6; i++) { output_toggle(LED_CICLO); delay_ms(75); } } void PIC_USB_Init() { usb_init(); //Inicia la libreria de Comunicacion USB printf(lcd_putc,"\f->CONEXION printf(lcd_putc,"\f->CONEXION USB"); usb_task(); //Monitorea el Estado de Conexion USB lcd_gotoxy(1, 2); printf(lcd_putc,"ESPERANDO printf(lcd_putc,"ESPERANDO ENUM."); usb_wait_for_enumeration(); //Espera //Espera hasta que se enumere el PIC en la PC printf(lcd_putc,"\fENUMERACION"); lcd_gotoxy(1, 2); printf(lcd_putc, "ASIGNADA"); "ASIGNADA"); } void PIC_USB_Transfer_Data() { if(usb_enumerated()) { //Si el dispositivo ha sido sido enumerado if (usb_kbhit(1)) { //Si recibe algun dato usb_get_packet(1, inData, USB_RX_DATA); //Recibe 2 Bytes y los Almacena en inData union{ unsigned int32 f; unsigned char c[4]; }UN; UN.c[0] = inData[0]; // LSB UN.c[1] = inData[1]; UN.c[2] = inData[2]; UN.c[3] = inData[3]; // MSB union{ unsigned int32 f2; unsigned char c2[4]; }UN2; UN2.c2[0] = inData[4]; // LSB UN2.c2[1] = inData[5]; UN2.c2[2] = inData[6]; UN2.c2[3] = inData[7]; // MSB union{ unsigned int32 f3; unsigned char c3[4]; }UN3; UN3.c3[0] = inData[8]; // LSB UN3.c3[1] = inData[9]; UN3.c3[2] = inData[10]; UN3.c3[3] = inData[11]; // MSB union{ unsigned int32 f4; unsigned char c4[4]; }UN4; UN4.c4[0] = inData[12]; // LSB UN4.c4[1] = inData[13];
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA
7 UN4.c4[2] = inData[14]; UN4.c4[3] = inData[15]; // MSB union{ unsigned int32 f5; unsigned char c5[4]; }UN5; UN5.c5[0] = inData[16]; // LSB UN5.c5[1] = inData[17]; UN5.c5[2] = inData[18]; UN5.c5[3] = inData[19]; // MSB float Res = (float)f_IEEEtoPIC(UN.f); (float)f_IEEEtoPIC(UN.f); float Res2 = (float)f_IEEEtoPIC(UN2.f (float)f_IEEEtoPIC(UN2.f2); 2); float Res3 = (float)f_IEEEtoPIC(UN3.f3); (float)f_IEEEtoPIC(UN3.f3); float Res4 = (float)f_IEEEtoPIC(UN4.f4); (float)f_IEEEtoPIC(UN4.f4); float Res5 = (float)f_IEEEtoPIC(UN5.f5); printf(lcd_putc, "\f%f %f %f", Res, Res2, Res3); lcd_gotoxy(1, 2); printf(lcd_putc, "%f %.3f", Res4, Res5); char *dat1 = FloatToBytes(3.1416); char *dat2 = FloatToBytes(3.1416); char *dat3 = FloatToBytes(3.1416); outData[0] = dat1[0]; outData[1] = dat1[1]; outData[2] = dat1[2]; outData[3] = dat1[3]; outData[4] = dat2[0]; outData[5] = dat2[1]; outData[6] = dat2[2]; outData[7] = dat2[3]; outData[8] = dat3[0]; outData[9] = dat3[1]; outData[10] = dat3[2]; outData[11] = dat3[3]; usb_put_packet(1, outData, USB_TX_DATA, USB_DTS_TOGGLE); USB_DTS_TOGGLE); //Envia 2 Bytes de la variable outData delay_ms(300); } } } float BytesToFloat(char *d) { union u_tag{ char b[4]; unsigned int32 i; }u; for(int i = 0; i < 4; i++) { u.b[i] = d[i]; } return (float) f_IEEEtoPIC(u.i); } char *FloatToBytes(float n) { char n_bytes[4]; int32 n_ieee = f_PICtoIEEE(n); n_bytes[0] = make8(n_ieee, 0); n_bytes[1] = make8(n_ieee, 1); n_bytes[2] = make8(n_ieee, 2);
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA
8 n_bytes[3] = make8(n_ieee, 3); return n_bytes; }
PROGRAMA EN VISUAL STUDIO (PRINCIPAL) #include "PA_CONTROL_PID_VS.h" "PA_CONTROL_PID_VS.h" //CONSTRUCTOR //CONSTRUCTOR PA_CONTROL_PID_VS::PA_CONTROL PA_CONTROL_PID_VS::PA_CONTROL_PID_VS(QWidget _PID_VS(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); //DECLARACION //DECLARACION DE MEMORIAS DINAMICAS DINAMICAS send = new char[2]; read = new char[2]; send[0] = 2; send[1] = 12; if (!COM_USB.usbInit()) { QMessageBox::critical(this, "Error Critico", "No se ha establecido la Comunicacion USB. Dispositivo No Conectado", "Aceptar"); } else { QMessageBox::information(this, QMessageBox::informati on(this, "Informacion", "Dispositivo Conectado. Se ha establecido la Comunicacion USB correctamente.", "Aceptar"); COM_USB.usbWr(send); COM_USB.usbRd(read); } } //FUNCIONES QVectorPA_CONTROL_PID_VS::By QVectorPA_CONTR OL_PID_VS::BytesToFloat(float tesToFloat(float inFloat) { QVector b; b.reserve(4); byte *d = new byte[4]; d = (byte*)&inFloat; for (int i = 0; i < 4; i++) { b.append(d[i]); } return b; } float PA_CONTROL_PID_VS::BytesToFloat(QVector PA_CONTROL_PID_VS::BytesToFloat(QVector d) { union u_tag { byte b[4]; float fval; }u; for (int i = 0; i < 4; i++) { u.b[i] = d[i]; } return u.fval; }
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA
9 RESULTADOS Y ANALISIS
Los Resultados fueron los siguientes:
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA
10 CONCLUSION
Con el desarrollo de la aplicación de comunicación pudimos reforzar nuestros conocimientos obtenidos en las tres unidades anteriores, las comunicaciones de dispositivos electrónicos son muy importantes ya que con esta podemos enviar y recibir información rápidamente, segura y a largas distancias, con lo cual nos amplía el panorama de saber qué tipo de comunicación escoger ante determinadas situaciones, además de que nos va a ser útil a futuro cuando se decida crear una aplicación para transmitir información de algún microcontrolador a una PC o viceversa, los cuales estén conectados a sensores, actuadores, interfaces u otros o tros dispositivos periféricos. REFERENCIAS
PROGRAMACIÓN AVANZADA INGENIERÍA MECATRÓNICA