RobotyPic son proyectos básicos de electrónica con microcontroladores PIC, de aplicación en el mundo de la robótica didáctica, con archivos fuente creados mediante el compilador CCS PIC C COMPILER en lenguajeC.
Este proyecto es una versión más elaborada del artículo Comunicación PC-PIC por USB, al que remito para más detalle en la configuración de fuses, descripción de funciones USB, etc. En este caso se emplea una aplicación desarrollada bajo visual basic para poder interactuar con el PIC desde el PC. Esta aplicación permite la lectura del canal analógico del Puerto A de un PIC 18F4550, además de la lectura o escritura de los puertos B y D. Todo controlado desde el PC a través de una conexión USB.
La aplicación VB indica la orden al PIC mediante un código de 4 caracteres. El primero de esos caracteres le indica al PIC la actuación que debe realizar, ya sea la lectura de la entrada analógica, lectura del puerto D o puerto B, escrituras en los puertos,etc.
if (usb_cdc_kbhit()){ //Si hay recepción de datos los lee
recepcion_datos();
switch(opcion[0]){ //Gestión según información recibida
case '0': escritura_puertoD();
break;
case '1': canal_analogico();
break;
case '2': lectura_puertoD();
break;
case '3': lectura_puertoB();
break;
case '4': escritura_puertoB();
break;
default:
break;
}
}
recepcion_datos() {
char c; //Caracteres individuales de la cadena
i=0; //Reinicio del puntero para 1º caracter
for (i=0;i<4;i++){ //Recepción máxima de 4 caracteres
//Hasta que buffer se quede vacío
if (usb_cdc_kbhit()) c=usb_cdc_getc();
opcion[i]=c; //Guarda el caracter recibido
}
}
El resto de caracteres del código será la información a mostrar en el puerto del PIC en el caso de la escritura en los puertos.
i=3; //ultimo caracter recibido...
decodificacion(i); //lo transforma en los 4 bits bajos Puerto B
PuertoB_bajo = numero; //guarda valor
i=2; //penultimo caracter recibido...
decodificacion(i); //lo transforma en los 4 bits altos Puerto B
PuertoB_alto = numero; //guarda el valor
//Salida de los dos caracteres leidos como un byte
PORTB=(PuertoB_alto<<4)|(PuertoB_bajo);
Por su lado, el PIC envía la información solicitada al PC mediante cadenas de caracteres acotadas por un primer carácter que indica de que información se trata y un carácter final (#) para separarla de las posteriores cadenas. La aplicación Visual Basic se encarga de identificarlos. Los caracteres contenidos entre ambos será la información "útil".
//////////////////////////////////////////////////////////////////////////////// // // // COMUNICACIÓN PC - PIC POR USB // // Clase de dispositivo CDC USB emulando dispositivo RS232 // // Interfase con aplicación Visual basic // // // // RobotyPic (c) // // // //////////////////////////////////////////////////////////////////////////////// #include <18F4550.h> //PIC a emplear #device adc=10; //Conversor A/D de 10 bits #fuses HSPLL,NOWDT,NOLVP,USBDIV,PLL5,CPUDIV1,VREGEN #use delay(clock=20000000) //Frecuencia del cristal oscilador externo #define USB_CON_SENSE_PIN PIN_B0 //Pin de detección conexión-desconexión dispositivo USB #include <usb_cdc.h> //Librería de control USB #byte TRISD = 0xf95 #byte PORTD = 0xf83 #byte TRISB = 0xf93 #byte PORTB = 0xf81 /******************************************************************************/ int16 valor_digital; //Valor digital obtenido del conversor A/D float valor_analogico; //Valor analógico medido en el conversor A/D int PuertoB; //Valor del puerto B int PuertoD; //Valor del Puerto D char opcion[4]=""; //Recepción información del PC int i; //Puntero int PuertoD_bajo; //4 bits bajos del Puerto D int PuertoD_alto; //4 bits altos del Puerto D int PuertoB_bajo; //4 bits bajos del Puerto B int PuertoB_alto; //4 bits altos del Puerto B int numero; //Valor numérico de los puertos /******************************************************************************/ /******************** LECTURA Y ENVIO CANAL ANALOGICO *************************/ canal_analogico() { valor_digital=read_adc(); //Lectura conversor AD valor_analogico=5.0*valor_digital/1024.0; //Transformación a valor analógico printf(usb_cdc_putc, "\fA%01.2fV#", valor_analogico); //Envío por USB } /******************************************************************************/ /************************** RECEPCION CADENA ***********************************/ recepcion_datos() { char c; //Caracteres individuales de la cadena i=0; //Reinicio del puntero para 1º caracter for (i=0;i<4;i++){ //Recepción máxima de 4 caracteres if (usb_cdc_kbhit()) c=usb_cdc_getc();//Hasta que buffer se quede vacío opcion[i]=c; //Guarda el ultimo caracter recibido } } /******************************************************************************/ /************************** DECODIFICACIÓN ************************************/ decodificacion(i) { if (opcion[i]=='0') numero=0; else if (opcion[i]=='1') numero=1; else if (opcion[i]=='2') numero=2; else if (opcion[i]=='3') numero=3; else if (opcion[i]=='4') numero=4; else if (opcion[i]=='5') numero=5; else if (opcion[i]=='6') numero=6; else if (opcion[i]=='7') numero=7; else if (opcion[i]=='8') numero=8; else if (opcion[i]=='9') numero=9; else if (opcion[i]=='A') numero=10; else if (opcion[i]=='B') numero=11; else if (opcion[i]=='C') numero=12; else if (opcion[i]=='D') numero=13; else if (opcion[i]=='E') numero=14; else if (opcion[i]=='F') numero=15; } /******************************************************************************/ /************************* ESCRITURA PUERTO B *********************************/ escritura_puertoB() { TRISB=0b00000100; //Puerto B como salida excepto Bit 2 i=3; //ultimo caracter recibido... decodificacion(i); //lo transforma en los 4 bits bajos Puerto B PuertoB_bajo = numero; //guarda valor i=2; //penultimo caracter recibido... decodificacion(i); //lo transforma en los 4 bits altos Puerto B PuertoB_alto = numero; //guarda el valor //Salida de los dos caracteres leidos como un byte PORTB=(PuertoB_alto<<4)|(PuertoB_bajo); } /******************************************************************************/ /************************* ESCRITURA PUERTO D *********************************/ escritura_puertoD() { TRISD=0x00; //Puerto D como salida i=3; //ultimo caracter recibido... decodificacion(i); //lo transforma en los 4 bits bajos Puerto D PuertoD_bajo = numero; //guarda valor i=2; //penultimo caracter recibido... decodificacion(i); //lo transforma en los 4 bits altos Puerto D PuertoD_alto = numero; //guarda el valor //Salida de los dos caracteres leidos como un byte PORTD=(PuertoD_alto<<4)|(PuertoD_bajo); } /******************************************************************************/ /*************************** LECTURA PUERTO B *********************************/
lectura_puertoB() { TRISB=0xff; //Puerto B como entrada PuertoB= PORTB; PuertoB= PuertoB & 0b11111110; //Ignora Bit RB0 printf(usb_cdc_putc,"\fB%x#", PuertoB); //Envío a aplicación visual basic } /******************************************************************************/ /*************************** LECTURA PUERTO D *********************************/ lectura_puertoD() { TRISD=0xff; //Puerto D como entrada PuertoD= PORTD; printf(usb_cdc_putc, "\fD%x#", PuertoD); //Envío a aplicación visual basic } /******************************************************************************/ /************************* FUNCIÓN PRINCIPAL ********************************/ void main() { TRISD=0xff; //Puerto D como entrada setup_adc_ports(AN0); //Definición pin a utilizar como entrada analógica setup_adc(ADC_CLOCK_INTERNAL);//Definición de la fuente de reloj para el A/D set_adc_channel(0); //Selección del canal analógico usb_cdc_init(); //Inicialización del modo CDC usb_init(); //Inicialización del control del USB do { usb_task(); //Detección de la conexión de dispositivo USB if (usb_enumerated()) { //Devuelve TRUE si dispositivo ha sido enumerado por el PC if (usb_cdc_kbhit()){ //Si hay recepción de datos los lee recepcion_datos(); switch(opcion[0]){ //Gestión según la información recibida case '0': escritura_puertoD(); break; case '1': canal_analogico(); break; case '2': lectura_puertoD(); break; case '3': lectura_puertoB(); break; case '4': escritura_puertoB(); break; default: break; } } } delay_ms(10); } while (TRUE); }
Bajo proteus se ha desarrollado un esquema para poder comprobar los puertos como entradas y salidas mediante interruptores y leds.
Aquí podemos ver el resultado:
En el archivo de descarga se incluye el archivo "usb_desc_cdc.h" ya modificado junto al resto de librerías C USB utilizadas.
El proyecto contenido en el artículo ha sido diseñado y probado con éxito utilizando las siguientes versiones de software: - Windows xp y windows 7 - Proteus V7.7 SP2 - CCS PIC C COMPILER v4.084
Saludos estimados amigos, antes que nada felicitarte por el genial programa que realizaste esta muy completo y con una infinidad de aplicaciones que se pueden realizar, he tratado de implementarlo pero se me es algo complejo adecuarlo a lo que ya realizaste, llevo dándome de topes en la cabeza por eso te pido tu ayuda, me podrías mandar la programación en visual basic que realizaste. mi correo es o_sam1@msn.com te lo estaría inmensamente agradecido.
hola mucho gusto me parecio muy bueno el aporte quisiera saber si igual podrias enviarnme la programacion en visual basic mi correo vector9269@hotmail.com
Gracias por mostrarnos tu trabajo. Pero, serias tan amable de enviar el codigo vb 6.0 o colgarlo. Muchas gracias de antemano. Mi correo es: luchadorinsaciable@gmail.com
Que tal amigo, felicitándote por el desarrollo de proyecto al igual que el resto me gustaría que me facilitaras el código en VB si no es mucha molestia. Mi correo es pabloluce2021@gmail.com Gracias amigo
Buen trabajo, espero que sigas publicando otras aplicaciones con relacionadas con este tema.Por favor si podrías enviarme la programación en VB 6.0 mi correo es pumitaandy1969@hotmail.com
Gracias por presentarnos tu trabajo, excelente. Cargue el programa al pic pero la PC nunca ve al PIC, ¿que crees que este haciendo mal? Muchas gracias. rvaldez@cablevision.net.mx
Hola Ruben. Si estas usando el mismo programa del ejemplo entonces el problema lo tendras al reconocer el PC al PIC. Debes asegurarte que tienes cargado el driver USB y si lo tienes correctamente instalado prueba a cambiar de puerto USB.
Hola, buenas tardes. Primeto de todo quería felicitarte por el fantástico programa que has desarrollado. En segundo lugar, quería pedirte que si por favor me puede mandar el código en VB6 ya que me sería de gran utilidad. Mi correo electrónico es juanllopisbernat@hotmail.com
Hola, excelente trabajo, también me gustaría los código de Vb6, lo intenté, pero no consigo recibir desde e micro, te lo agradecería que me mandase a jesussorroche@hotmail.com, Un cordial saludo
Buenas..Excelente tu programa..me ha sido de gran ayuda..realizo una aplicacion para captar unas señales análogas en vb6 . no se si me podrías hacer el favor de instruirme en cuanto al codigo de visual ya q el del pic uno lo entiende pero no se como captar esas variables allí y asignarlas...de antemano muchas gracias.. (chis_juan@hotmail.com)
Chiras. Debes diseñar la comunicación como si se tratase de un puerto serie COM dado que esta comunicación USB emula un puerto serie. Los valores numéricos leidos debes transformarlos a caracteres y enviarlos como una cadena de texto a la aplicación vb.
Hola Robotypic Es genial este conocimiento que compartes con los que sabemos menos y te agradezco por eso, te cuento que yo también tengo la misma duda con respecto a la recepción en VB6 de las señales analógicas sobretodo cuando son varias por ejemplo adc-0,1,2,3 como separarlas no me queda claro,según entiendo en tu comentario anterior se devén asignar letras a los valores numéricos y luego en VB6 transformarlos de nuevo en números?
Seria de muchísima ayuda para mi si me pudieras mandar el código de este ejemplo a mi correo merlinguzman.mg@gmail.com estoy un poco atorado con la recepción ADC supongo que se debe usar una instrucción "Case" para saber adonde corresponde cada paquete.
Merlin. El valor numérico lo debes pasar a una cadena de caracteres y luego enviarlos caractera a caracter. Revisa esta entrada donde se muestra algo similar: http://robotypic.blogspot.com.es/2012/08/transmision-variable-tipo-float-por.html
17 comentarios:
Saludos estimados amigos, antes que nada felicitarte por el genial programa que realizaste esta muy completo y con una infinidad de aplicaciones que se pueden realizar, he tratado de implementarlo pero se me es algo complejo adecuarlo a lo que ya realizaste, llevo dándome de topes en la cabeza por eso te pido tu ayuda, me podrías mandar la programación en visual basic que realizaste. mi correo es o_sam1@msn.com te lo estaría inmensamente agradecido.
yo también quisiera que me pasara la programación en visual basic e buscado mucho y no e encontrado nada. mi correo es sanyonatan33@gamail.com
hola mucho gusto me parecio muy bueno el aporte quisiera saber si igual podrias enviarnme la programacion en visual basic mi correo vector9269@hotmail.com
Gracias por mostrarnos tu trabajo. Pero, serias tan amable de enviar el codigo vb 6.0 o colgarlo. Muchas gracias de antemano. Mi correo es: luchadorinsaciable@gmail.com
Que tal amigo, felicitándote por el desarrollo de proyecto al igual que el resto me gustaría que me facilitaras el código en VB si no es mucha molestia. Mi correo es pabloluce2021@gmail.com
Gracias amigo
Buen trabajo, espero que sigas publicando otras aplicaciones con relacionadas con este tema.Por favor si podrías enviarme la programación en VB 6.0 mi correo es pumitaandy1969@hotmail.com
Excelente aporte, pedirte xfavor si me puedes mandar la programación en VB6 gracias por la colaboración mi correo es tugui.flores@gmail.com
Gracias por presentarnos tu trabajo, excelente.
Cargue el programa al pic pero la PC
nunca ve al PIC, ¿que crees que este haciendo mal?
Muchas gracias.
rvaldez@cablevision.net.mx
Hola Ruben.
Si estas usando el mismo programa del ejemplo entonces el problema lo tendras al reconocer el PC al PIC. Debes asegurarte que tienes cargado el driver USB y si lo tienes correctamente instalado prueba a cambiar de puerto USB.
Hola, buenas tardes. Primeto de todo quería felicitarte por el fantástico programa que has desarrollado. En segundo lugar, quería pedirte que si por favor me puede mandar el código en VB6 ya que me sería de gran utilidad. Mi correo electrónico es juanllopisbernat@hotmail.com
Muchas gracias de antemano, Juan.
Facil en vb6, el los mismo tienes que programa como puerto serial
1. añade el MsComm control
2. Pega este codigo en vb6 y listo
Private Sub Form_Load()
MSComm1.CommPort = 6 ' Poner el puerto que da el administrador de dispositivos de windows
MSComm1.PortOpen = True
MSComm1.Output = "0x80"
MSComm1.Output = "0x40"
MSComm1.Output = "0x20"
MSComm1.Output = "0x10"
End Sub
los codigo de los leds te da el programa ejecutable, que esta en este foro (USB PC-PIC.exe).
para simularo utilice el archivo de proteus (Comunicación PIC-PC por USB y vb.DSN).
muy facil verdad ggggggg.
Hola, excelente trabajo, también me gustaría los código de Vb6, lo intenté, pero no consigo recibir desde e micro, te lo agradecería que me mandase a jesussorroche@hotmail.com, Un cordial saludo
Buenas..Excelente tu programa..me ha sido de gran ayuda..realizo una aplicacion para captar unas señales análogas en vb6 . no se si me podrías hacer el favor de instruirme en cuanto al codigo de visual ya q el del pic uno lo entiende pero no se como captar esas variables allí y asignarlas...de antemano muchas gracias.. (chis_juan@hotmail.com)
Chiras.
Debes diseñar la comunicación como si se tratase de un puerto serie COM dado que esta comunicación USB emula un puerto serie. Los valores numéricos leidos debes transformarlos a caracteres y enviarlos como una cadena de texto a la aplicación vb.
Hola Robotypic
Es genial este conocimiento que compartes con los que sabemos menos y te agradezco por eso, te cuento que yo también tengo la misma duda con respecto a la recepción en VB6 de las señales analógicas sobretodo cuando son varias por ejemplo adc-0,1,2,3 como separarlas no me queda claro,según entiendo en tu comentario anterior se devén asignar letras a los valores numéricos y luego en VB6 transformarlos de nuevo en números?
Seria de muchísima ayuda para mi si me pudieras mandar el código de este ejemplo a mi correo merlinguzman.mg@gmail.com estoy un poco atorado con la recepción ADC supongo que se debe usar una instrucción "Case" para saber adonde corresponde cada paquete.
Merlin.
El valor numérico lo debes pasar a una cadena de caracteres y luego enviarlos caractera a caracter.
Revisa esta entrada donde se muestra algo similar:
http://robotypic.blogspot.com.es/2012/08/transmision-variable-tipo-float-por.html
Publicar un comentario