Hola necesito ayuda con un proyecto que inicie hace un tiempo y estoy casi terminando, se trata de un dispositivo de entrada/salida que emula el piloto automático de un avión pequeño. Por lo cual no se trata de un simple joystick sino que además este dispositivo recibe algunos datos provenientes del PC (del simulador de vuelo) como ser la altitud, el rumbo, la velocidad vertical, etc. y las muestra en un LCD de 16x2.
Para dicho proyecto utilice un 18F4550 por sus prestaciones y su cantidad de patas, cabe aclarar que este dispositivo cuenta con la entrada de 7 botones encargados de la activación-desactivación de los comandos del AP, así como 4 botones mas encargados de subir o bajar el numero y de cambiar el selector.
Paso a enseñarles el diagrama del dispositivo para que aclaren un poco las cosas:
En tamaño real:
http://img830.imageshack.us/img830/4663/fsap10.jpg
Bueno el dispositivo funciona perfectamente, todas sus funciones estas activas y el LCD muestra lo correcto enviado desde el PC pero el problema es el siguiente:
TODO MARCHA BIEN HASTA LUEGO DE PRESIONAR 8 VECES LOS BOTONES, ES DECIR FUNCIONA PERFECTO PERO A LA OCTAVA VEZ QUE SE A PRESIONADO CUALQUIER BOTON SE REINICIA EL PIC.
Presione cualquier botón, a cualquier velocidad, da igual si lo mantengo presionado como si se presiona una hora después, luego de 8 veces se reinicia el pic y al segundo reinicio se vuelve inestable e inoperable.
Bueno les envio el código del PIC realizado en PROTON y con la ayuda del EasyHID, no les doy el código fuente del software ya que este no es el del problema (el PIC se reinicia este conectado o no al software).
Ojala puedan ayudarme, prometo compartir el proyecto una vez funcione, tanto diagramas pcb códigos etc. Un saludo grande a toda la comunidad, Gaston.
Para dicho proyecto utilice un 18F4550 por sus prestaciones y su cantidad de patas, cabe aclarar que este dispositivo cuenta con la entrada de 7 botones encargados de la activación-desactivación de los comandos del AP, así como 4 botones mas encargados de subir o bajar el numero y de cambiar el selector.
Paso a enseñarles el diagrama del dispositivo para que aclaren un poco las cosas:
En tamaño real:
http://img830.imageshack.us/img830/4663/fsap10.jpg
Bueno el dispositivo funciona perfectamente, todas sus funciones estas activas y el LCD muestra lo correcto enviado desde el PC pero el problema es el siguiente:
TODO MARCHA BIEN HASTA LUEGO DE PRESIONAR 8 VECES LOS BOTONES, ES DECIR FUNCIONA PERFECTO PERO A LA OCTAVA VEZ QUE SE A PRESIONADO CUALQUIER BOTON SE REINICIA EL PIC.
Presione cualquier botón, a cualquier velocidad, da igual si lo mantengo presionado como si se presiona una hora después, luego de 8 veces se reinicia el pic y al segundo reinicio se vuelve inestable e inoperable.
Bueno les envio el código del PIC realizado en PROTON y con la ayuda del EasyHID, no les doy el código fuente del software ya que este no es el del problema (el PIC se reinicia este conectado o no al software).
Ojala puedan ayudarme, prometo compartir el proyecto una vez funcione, tanto diagramas pcb códigos etc. Un saludo grande a toda la comunidad, Gaston.
PHP:
' select MCU and clock speed
Device = 18F4550
XTAL = 48
' descriptor file, located in \inc\usb_18 - a copy
' is located in the same folder as this file
USB_DESCRIPTOR = "FSXAP2010DESC.inc"
' USB Buffer...
Symbol USBBufferSizeMax = 32
Symbol USBBufferSizeTX = 32
Symbol USBBufferSizeRX = 32
Dim USBBuffer[USBBufferSizeMax] As Byte
'REMINDERS = 1 ' Mostrar todos los avisos al compilar.
'********************************
'* CONFIGURACION DE FUSES *
'********************************
@CONFIG_REQ
@PLL_REQ
@__config config1l, PLLDIV_1_1 & CPUDIV_1_1 & USBDIV_2_1
@__config config1h, FOSC_XTPLL_XT_1
@WATCHDOG_REQ
@__config config2h, WDT_OFF_2 & WDTPS_128_2
@DEBUG_REQ
@__config config4l, LVP_OFF_4 & ICPRT_OFF_4 & XINST_OFF_4 & DEBUG_OFF_4
@__config config3h, PBADEN_OFF_3
ALL_DIGITAL = true
'********************************
'* CONFIGURACION DE PUERTOS *
'********************************
TRISA = 0 ' El puerto A como salida
TRISB = 0 ' El puerto B como salida (Panel LCD)
TRISC.0 = 1 ' El puerto C como entrada (Selector y subir bajar numero)
TRISC.1 = 1
TRISC.2 = 1
TRISC.6 = 1
TRISC.7 = 1
TRISD = 255 ' El puerto D como entrada (Botones AP)
TRISE.0 = 1 ' El puerto E como entrada (Auxiliares)
TRISE.1 = 1
'SETEO EL LCD 16X2 PARA 4 CABLES
LCD_DTPIN = PORTB.4
LCD_RSPIN = PORTB.3
LCD_ENPIN = PORTB.2
LCD_INTERFACE = 4
LCD_LINES = 2
LCD_TYPE = 0
'VARIABLES
Dim SELECTOR_UP As Bit ' "SELECTOR_UP" se utiliza para establecer un incremento en el numero
Dim SELECTOR_DOWN As Bit ' "SELECTOR_DOWN" se utiliza para establecer un decremento en el numero
Dim ARRAY[2] As Byte ' Array para el pasaje de los estados
Dim NUMERO As Word ' Variable para el numero recibido del buffer
Dim DIVISOR As Word ' Variable para el multiplicador del numero recibido del buffer
Dim RESTO As Word ' Variable para el resto recibido del buffer
Dim NUMERO_VS As Word ' Variable para el numero del la Vs recibido del buffer
Dim DIVISOR_VS As Word ' Variable para el multiplicador del numero_Vs recibido del buffer
Dim NUMERO_STR As String * 6 ' String para imprimir el numero
Dim NUMERO2_STR As String * 5 ' String para imprimir el numero de la Vs
Dim NUMERO_HDG As String * 3 ' String para imprimir el numero de rumbo HDG
'VARIABLES DE LOS ESTADOS DE LOS PUERTOS
Dim ESTADO_SELECTOR As Byte ' Variable del estado del selector
Dim ESTADO_GRAL_STR As String * 3 ' String para el pasaje de los estados
Dim ESTADO_GRAL As Byte ' Variable para enviar los estados al buffer
Dim ESTADO_BOTONES As Byte ' Variable del estado de los botones
Dim ESTADO_ATP As Byte ' Variable del estado ATP para los LEDs
Dim SELECTOR_ANT As Byte ' Variable para guardar el estado del selector antes de presionar el boton
Dim ESTADO_NUMERO As Byte ' Variable del estado de los botones de subir/bajar
Dim A As Word ' Variable multifuncion
'REGISTROS Y BANDERAS
Dim PP0 As Byte SYSTEM ' Registro dentro del PIC USBPOLL STATUS
Symbol CARRY_FLAG = STATUS.0 ' En estado alto si el PIC no tiene el control sobre el buffer
Symbol ATTACHED_STATE = 6 ' Si el USB está conectado
Cls ' Borrar el LCD al iniciar
Clear ' Limpiar la memoria al iniciar
A= 0 ' Inicializo las variables
ESTADO_SELECTOR = 1
SELECTOR_ANT = 1
ESTADO_NUMERO = 0
ESTADO_BOTONES = PORTD
Print At 1,1,"Conectando "
Print At 2,1,"al USB. "
DelayMS 500
Cls
Print At 1,1,"Conectando "
Print At 2,1,"al USB... "
GoSub AttachToUSB ' Comprueba si esta conectado a USB
DelayMS 500
Print Cls,At 1,1," Conectado! " ' Escribe que la conexion funciona
DelayMS 500
' *****************************************************************
' * LAZO PRINCIPAL DEL PROGRAMA MIENTRAS SE ESTÁ CONECTADO A USB *
' *****************************************************************
INICIO:
Print Cls, At 1,1, "Esperando al "
Print At 2,1, "Software... "
PRINCIPAL:
If A = 0 Then GoSub ESPERAR_DATO
DelayMS 200 ' Demora para establecer los botones
SELECTOR_ANT = ESTADO_SELECTOR ' El selector anterior sera ahora el selector actual
'RUTINA DEl ENVIO DE DATOS AL USB
ENVIAR:
USBBuffer[0] = 0 ' El primer byte es de reporte de conexion
USBBuffer[1] = SELECTOR_ANT ' El segundo sera el estado del selector
USBBuffer[3] = ESTADO_BOTONES ' El tercer sera el estado del PORTD (botones del AP)
USBBuffer[4] = ESTADO_NUMERO ' El estado del numero (subir/bajar) 0 no hace nada 1 sube 2 baja
GoSub DoUSBOut ' Transmite lo almacenado en el buffer
DelayMS 50 ' Se da un tiempo de demora
ESTADO_NUMERO = 0
'RUTINA DE LA RECEPCION DE DATOS DEL USB
GoSub ESPERAR_DATO ' Lee el buffer de entrada
RECIBIDO:
A = 1
ESTADO_ATP = USBBuffer[5] ' recibe el estado de los botones del AP
NUMERO = USBBuffer[6] ' recibe el numero sin multiplicar (para no ecceder los 256 del byte)
DIVISOR = USBBuffer[7] ' recibe el numero para multiplicar al anterior
RESTO = USBBuffer[8] ' recibe el resto de la cuenta, para lograr el numero exacto
NUMERO_VS = USBBuffer[9] ' reciben los numeros para formar el
DIVISOR_VS = USBBuffer[10] ' Numero de la Velocidad vertical (Vs) que utilizaremos para mostrar en caso de que el
' Selector se encuentre en "Alt"
ESTADO_SELECTOR = USBBuffer[11] ' El ultimo Byte recibe el estado actual del selector
'RUTINA PARA ESTABLECER LOS DATOS RECIBIDOS
Select ESTADO_SELECTOR ' Comprueba el estado del selector actual y lo muestra
' En el LCD, se coloca en la rutina de recibo de datos
Case 1: ' Porque si desde el juego se cambia el estado del selector
Print Cls, At 1,2, "Alt " ' Y se cambia el numero, el hardware debe mostrar el dato
Print At 2,1, " Vs " ' En el LCD que ha cambiado.
Case 2:
Print Cls, At 1,2, "Vs "
Case 4:
Print Cls, At 1,2, "HDG "
Case 8:
Print Cls, At 1,2, "IAS "
End Select
DelayMS 10
SELECTOR_ANT = ESTADO_SELECTOR
NUMERO = NUMERO * DIVISOR + RESTO ' En las siguientes lineas se establecen los numeros
NUMERO_VS = NUMERO_VS * DIVISOR_VS ' Recibidos, se multiplica con sus respectivos "divisores" y se
NUMERO_STR = Str$ (DEC5 NUMERO) ' Les suma el resto, luego se los pasa a las variables de tipo
NUMERO2_STR = Str$ (DEC4 NUMERO_VS) ' String para poder imprimir como cadena de texto (esto se puede evitar) pero
NUMERO_HDG = Str$ (DEC3 NUMERO) ' El autor prefiere utilizar este metodo.
If SELECTOR_ANT = 1 Then ' Si el selector es "Alt" entonces imprime tambien el numero de la velocidad vertical
Print At 2,12, NUMERO2_STR
End If
If SELECTOR_ANT = 4 Then ' Si el selector es "HDG" (rumbo) entonces imprime solo los tres numeros del rumbo si los
Print At 1,12, NUMERO_HDG ' Ceros de la izquierda
Else ' Si no es asi imprime de forma normal
Print At 1,11, NUMERO_STR
End If
GoSub ESPERAR_CAMBIO ' Se cierra la rutina llamando a la subrutina DoUSBIn para recibir datos del USB, o en caso
' se presionarse un boton, volver a la rutina principal
' ************************************************************
' * RUTINA DE RECEPCIÓN DE DATOS Y CAMBIO DE ESTADO *
' ************************************************************
ESPERAR_CAMBIO:
If PORTC.6 = 0 Then ' Si se presiona el boton de SUBIR el selector, sale de la
DelayMS 50 ' Rutina actual y va a ANALISIS para establecer el nuevo
SELECTOR_UP = 1 ' Estado
GoTo ANALISIS
End If
If PORTC.7 = 0 Then ' Si se presiona el boton de BAJAR el selector, sale de la
DelayMS 50 ' Rutina actual y va a ANALISIS para establecer el nuevo
SELECTOR_DOWN = 1 ' Estado
GoTo ANALISIS
End If
If PORTC.1 = 0 Then ' Si se presiona el boton de SUBIR numero, sale de la
DelayMS 50 ' Rutina actual y va a principal para ENVIAR el nuevo
ESTADO_NUMERO = 1 ' Numero
GoTo PRINCIPAL
End If
If PORTC.2 = 0 Then ' Si se presiona el boton de BAJAR el numero, sale de la
DelayMS 50 ' Rutina actual y va a principal para ENVIAR el nuevo
ESTADO_NUMERO = 2 ' Numero
GoTo PRINCIPAL
End If
ESTADO_BOTONES = PORTD ' El estado del PORTB lo asigna a "ESTADO_BOTONES" para almacenar el estado
' y que no se pierda luego de soltar el boton
If ESTADO_BOTONES > 0 Then GoTo PRINCIPAL ' Si se presiono alguno de los botones el estado sera distinto de cero, por los cual sale
ESPERAR_DATO: ' Inmediatamente de esta rutina y va a PRINCIPAL a enviar los nuevos datos.
USBIn 1, USBBuffer, USBBufferSizeRX, ESPERAR_CAMBIO ' Si no recibe nada del USB vuelve a empezar la rutina, en caso contrario
GoSub RECIBIDO ' Sale y va a la rutina "RECIBIDO"
' ************************************************************
' * RUTINA DE TRANSMISIÓN DE DATOS *
' ************************************************************
DoUSBOut:
USBOut 1, USBBuffer, USBBufferSizeTX, DoUSBOut
Return
' ************************************************************
' * ESPERA HASTA QUE EL USB SE CONECTE *
' ************************************************************
AttachToUSB:
Repeat
USBPoll
Until PP0 = ATTACHED_STATE
Return
' ************************************************************
' * ANALIZA EL ESTADO DEL SELECTOR *
' ************************************************************
ANALISIS:
DelayMS 50 ' Da una pequeña demora
If SELECTOR_UP = 1 Then GoSub SUBIR_SELECTOR ' Si se presiono el boton de SUBIR va a la rutina "SUBIR_SELECTOR"
DelayMS 50
If SELECTOR_DOWN = 1 Then GoSub BAJAR_SELECTOR ' Si se presiono el boton de BAJAR va a la rutina "SUBIR_SELECTOR"
DelayMS 50
GoSub PRINCIPAL
SUBIR_SELECTOR: ' Si se presiono el boton de SUBIR, el programa establece
SELECTOR_UP = 0 ' El nuevo estado del selector dependiendo del estado anterior
ESTADO_SELECTOR = ESTADO_SELECTOR * 2 ' Si el numero del estado supera el 8 es porque no puede subir mas
If ESTADO_SELECTOR > 8 Then
ESTADO_SELECTOR = 8
GoSub ESPERAR_CAMBIO
End If
Return
BAJAR_SELECTOR: ' Si se presiono el boton de BAJAR, el programa establece
SELECTOR_DOWN = 0 ' El nuevo estado del selector dependiendo del estado anterior
If ESTADO_SELECTOR = 1 Then GoSub ESPERAR_CAMBIO ' Si el NUMERO del estado es 1 es porque no puede bajar mas
ESTADO_SELECTOR = ESTADO_SELECTOR / 2 ' Y no cambia nada
Return