Hola Carlos, ..bueeenooo... jeje, te diré que esa idea ya la hice en un enfocador que tengo.
Puedes ver aquí para que veas más o menos el equipo:
http://tinyurl.com/e26w7allí verás una interfaz más o menos como la que tu dices. El problema: El encoder barato no me dá la suficiente resolución como para llegar al foco ideal. El encoder que necesitaría (4000 steps o más), no lo consigo en mi país y me sale muy caro traerlo. Ese circuito maneja un enfocador externo que es accesorio y usa un motor DC. Tiene básicamente un 16F84A, un Hbridge y un encoder.
¿Es muy dificil contar los pasos del stepper?.
En realidad el único problema que veo es que como no hay feedback entre el motor y el pic y como uso el pulso que da el micro-p para contar los pasos, entonces si el motor desliza o por cualquier motivo no ejecuta el paso, el micro lo va a contar como si se hubiera efectuado. Por lo tanto es susceptible al error.
De todas formas voy a pensar en algo como lo que comentas para la calibración.
Hola poi5on,Lo que comentas es lo que estoy haciendo ahora, solo que estoy manejando los datos separados y no en una trama. En 2 posiciones prefijadas de la EEPROM guardo el número total de pasos que ejecuta una rutina que llamo desde el puerto serial, y en otras 2 almaceno la posición actual. Dependiendo de si doy medio paso para adelante o para atrás, sumo o resto 1 en 16 bits respectivamente y guardo constantemente en cada variación.
Desde el serial puedo pedir: Posición actual, Pulsos totales, Resetear la EEPROM, Mover hacia adentro y Mover hacia afuera.
No se que está pasando con el PIC. pero cuando mando a grabar en la EEPROM, el PIC queda colgado. A pesar de estar casi 100% seguro de que la rutina de escritura está bien, no logro saber que pasa. No uso TMR0 ni ninguna interrupcion (están todas prohibidas) y si se trata de un autoreset del PIC desconozco que lo está causando.
Anexo el .ASM al final del mensaje, a ver si alguien me puede ayudar con esto. A lo mejor ustedes ven algo que yo no. (Usé la suma y resta de 16 Bits de la librería de assembler del foro). No se por qué pero el foro no me deja subir anexos a pesar de que éste es de 13K solamente.
Bueno amigos, muchas gracias por toda su ayuda y buenas sugerencias.
Marcelo Gabriel.
;*********************************************************************************************************
;++++++++++++ RUTINA DE MOVIMIENTO DE FOCUSER Sábado 7 de Enero 2006
;+++++++++++++ ALIMENTACION PARA CONTROL DEL MOTOR
;+++++++++++++ RUTINA DE COMUNICACIONES CON EL PC
;+++++++++++++ MOTOR PASO A PASO
List p=16C84 ;Tipo de procesador
include "P16C84.INC" ;Definiciones de registros internos
;
;Declaración de Variables.
;
Variables equ 0x20
CBLOCK Variables
RECIBIDO ;Caracter recibio por el serial
TEMP1 ;Registros de propósito general.
TEMP2
CUENTAPP ;Contador de la secuencias de pasos
DIRECCION ;Ultima dirección de giro
Dato_A_L ;Low Byte del primer numero (16 Bits)
Dato_B_L ;Low Byte del segundo numero (16 Bits)
Dato_A_H ;High Byte del primer numero (16 Bits)
Dato_B_H ;High Byte del segundo numero (16 Bits)
Resultado_L ;Low Byte del resultado (16 Bts)
Resultado_H ;High Byte del resultado (16 Bts)
DIRE ;Variable para pasar la dirección de la EEPROM
ESCR ;Variable para pasar el dato a escribir enla EEPROM
endc
Rs232_var equ 0x0C ;Inicio de las variables para rutinas RS232low.inc
;
;Parámetros de la rutina de comunicación
;
CLKIN equ .4000000;Frecuencia
BAUDIOS equ .9600 ;Velocidad de comunicación
T_MODO equ 1 ;Transmite primero bit LSB
R_MODO equ 1 ;Recibir primero bit LSB
T_Nbit equ 8 ;Transmite caracteres de 8 bits
R_Nbit equ 8 ;Recibe caracteres de 8 bits
Sbit equ 1 ;Transmite 1 bits de stop
;
;******************************Rutina de Inicio
org 0
goto INICIO
org 5 ;Salvar el vector de interrupción
include "RS232LOW.INC" ;Incluir rutinas de comunicación
;**********************************************************************************************
INICIO: bsf STATUS, RP0
movlw b"11110000" ;Se configura RA0-RA3 como entrada y el resto de la
movwf TRISA ;PORTA como salida - Los 4 bornes del Stepper.
movlw b"10110011" ;Se configura RB6 CON TX HACIA EL PC
movwf TRISB ;y RB5 CON RX DESDE EL PC en el PORTB
bcf STATUS, RP0 ;RB2 y RB3 son LEDs testigos del movimiento del motor (RB3)
;y de la Lectura/Escritura de la EEPROM (RB2)
clrf INTCON ;Se anulan las interrupciones.
bsf INTCON,EEIE
movlw 0x04
movwf CUENTAPP ;Coloca 4 en el contador de secuencias de pasos
clrf PORTA
clrf PORTB
;****************************************Inicialización de datos
movlw b"00001000"
movwf PORTB
movlw 0x01 ;Coloca el número "1" en el sustraendo
movwf Dato_B_L
movlw 0x00
movwf Dato_B_H
movlw 0x04 ;Lee POSICION ACTUAL desde la EEPROM y lo guarda en Dato_A
movwf DIRE
call LEE_EEPROM
movwf Dato_A_H ;Salvamos el High Byte que viene en W
movlw 0x05 ;Lee POSICION ACTUAL desde la EEPROM y lo guarda en Dato_A
movwf DIRE
call LEE_EEPROM
movwf Dato_A_L ;Salvamos el Low Byte que viene en W
;****************************************Inicio del bucle de lectura
BUCLE
clrf PORTA
clrf PORTB
call RxD ;Llama la rutina de recepción
movf Rxdreg,W ;Coloca el caracter recibido en W
movwf RECIBIDO ;Coloca W en RECIBIDO
;****************************************RECEPCIÓN DE UNA "F" - HACIA ADELANTE
movlw 0x46 ;Prueba si se recibió una F
subwf RECIBIDO,0 ;Resta W del caracter recibido y almacena resultado en W
btfss STATUS,Z ;Está a 1 el bit ZERO de STATUS?
goto NEXT1 ;No es una "F", Va a ver si es una "B"
movlw 0x07 ;Se recibió una "F". Chequea si el paso es el cuarto.
subwf CUENTAPP,0
btfss STATUS,Z ;Si no es lo es, incrementa CUENTAPP
goto SALTO1 ;y sigue
clrf CUENTAPP ;Si es el cuarto paso, coloca a 0 CUENTAPP
call RESTA_PASO
call DERECHA ;y continua.
movf RECIBIDO,0
movwf Txdreg ;Manda el ECO
call TxD
goto BUCLE
SALTO1 incf CUENTAPP,1
call RESTA_PASO
call DERECHA ;Entonces FORWARD - Derecha
movf RECIBIDO,0
movwf Txdreg ;Manda el ECO
call TxD
goto BUCLE
;****************************************RECEPCIÓN DE UNA "B" - HACIA ATRÁS
NEXT1 movlw 0x42 ;Prueba si se recibió una F
subwf RECIBIDO,0 ;Resta W del caracter recibido y almacena resultado en W
btfss STATUS,Z ;Está a 1 el bit ZERO de STATUS?
goto NEXT2 ;No es una "B", Va a ver si es una "S"
movlw 0x00 ;Se recibió una "B". Chequea si el paso es el primero
subwf CUENTAPP,0
btfss STATUS,Z ;Si no lo es, decrementa y sigue
goto SALTO2
movlw 0x08 ;Si si lo es, coloca 4 en CUENTAPP para que
movwf CUENTAPP ;cuando se decremente quede en 3
SALTO2 decf CUENTAPP,1
call SUMA_PASO
call IZQUIERDA ;Entonces BACKWARD - Izquierda
movf RECIBIDO,0
movwf Txdreg ;Manda el ECO
call TxD
goto BUCLE
;****************************************RECEPCIÓN DE UNA "S" - SOLICITUD DE "TOTAL STEPS"
NEXT2 movlw 0x53 ;Prueba si se recibió una s
subwf RECIBIDO,0 ;Resta W del caracter recibido y almacena resultado en W
btfss STATUS,Z ;Está a 1 el bit ZERO de STATUS?
goto NEXT3 ;No es una "S", Va a ver si es una "P"
movlw 0x07 ;Se recibió una "S". Lee High Byte PASOS TOTALES desde la EEPROM
movwf DIRE
call LEE_EEPROM
movwf Txdreg ;y transmite el High Byte
call TxD
movlw 0x08 ;Lee Low Byte PASOS TOTALES desde la EEPROM
movwf DIRE
call LEE_EEPROM
movwf Txdreg ;y transmite el Low Byte
call TxD
goto BUCLE ;Regresa a esperar otro caracter
;****************************************RECEPCIÓN DE UNA "P" - SOLICITUD DE LA POSICIÓN ACTUAL
NEXT3 movlw 0x50 ;Prueba si se recibió una P
subwf RECIBIDO,0 ;Resta W del caracter recibido y almacena resultado en W
btfss STATUS,Z ;Está a 1 el bit ZERO de STATUS?
goto NEXT4 ;No es una "B", va a ver si es una "R"
movlw b"00000100" ;Se recibió una "B"
movwf PORTB
movf Dato_A_H,0 ;Copiamos el High Byte en W
movwf Txdreg ;y transmite el High Byte
call TxD
movf Dato_A_L,0 ;Copiamos el Low Byte en W
movwf Txdreg ;y transmite el Low Byte
call TxD
goto BUCLE
;****************************************RECEPCIÓN DE UNA "R" - SOLICITUD DE RESET DE LA EEPROM
NEXT4 movlw 0x52 ;Prueba si se recibió una P
subwf RECIBIDO,0 ;Resta W del caracter recibido y almacena resultado en W
btfss STATUS,Z ;Está a 1 el bit ZERO de STATUS?
goto BUCLE ;No es una "R", regresa al bucle
movlw 0 ;Se recibió una "R". Carga W con 0
movwf ESCR ;Dato a escribir
movlw 0x04 ;En la dirección de memoria
movwf DIRE
call ESCRIBE_EEPROM ;Borra EEPROM 0x04
movlw 0x05 ;En la dirección de memoria
movwf DIRE
call ESCRIBE_EEPROM ;Borra EEPROM 0x05
movlw 0x07 ;En la dirección de memoria
movwf DIRE
call ESCRIBE_EEPROM ;Borra EEPROM 0x07
movlw 0x08 ;En la dirección de memoria
movwf DIRE
call ESCRIBE_EEPROM ;Borra EEPROM 0x08
movf RECIBIDO,0
movwf Txdreg ;Manda el ECO
call TxD
goto BUCLE
;**********************************************************************************************
;IZQUIERDA Y DERECHA: Son las encargadas de dar al motor los pasos correspondientes
;para que gire en un sentido en otro. HALF STEPS
IZQUIERDA:
movlw b"00001000"
movwf PORTB
movf CUENTAPP,0
addlw 0x30
movwf Txdreg ;Manda el ECO
call TxD
movlw 0x00
subwf CUENTAPP,0
btfss STATUS,Z
goto BACKWARD1
movlw b"00000001"
goto ENVIO
BACKWARD1 movlw 0x01
subwf CUENTAPP,0
btfss STATUS,Z
goto BACKWARD2
movlw b"00000101"
goto ENVIO
BACKWARD2 movlw 0x02
subwf CUENTAPP,0
btfss STATUS,Z
goto BACKWARD3
movlw b"00000100"
goto ENVIO
BACKWARD3 movlw 0x03
subwf CUENTAPP,0
btfss STATUS,Z
goto BACKWARD4
movlw b"00000110"
goto ENVIO
BACKWARD4 movlw 0x04
subwf CUENTAPP,0
btfss STATUS,Z
goto BACKWARD5
movlw b"00000010"
goto ENVIO
BACKWARD5 movlw 0x05
subwf CUENTAPP,0
btfss STATUS,Z
goto BACKWARD6
movlw b"00001010"
goto ENVIO
BACKWARD6 movlw 0x06
subwf CUENTAPP,0
btfss STATUS,Z
goto BACKWARD7
movlw b"00001000"
goto ENVIO
BACKWARD7 movlw b"00001001"
goto ENVIO
DERECHA:
movlw b"00001000"
movwf PORTB
movf CUENTAPP,0
addlw 0x30
movwf Txdreg ;Manda el ECO
call TxD
movlw 0x07
subwf CUENTAPP,0
btfss STATUS,Z
goto FORWARD1
movlw b"00001001"
goto ENVIO
FORWARD1 movlw 0x06
subwf CUENTAPP,0
btfss STATUS,Z
goto FORWARD2
movlw b"00001000"
goto ENVIO
FORWARD2 movlw 0x05
subwf CUENTAPP,0
btfss STATUS,Z
goto FORWARD3
movlw b"00001010"
goto ENVIO
FORWARD3 movlw 0x04
subwf CUENTAPP,0
btfss STATUS,Z
goto FORWARD4
movlw b"00000010"
goto ENVIO
FORWARD4 movlw 0x03
subwf CUENTAPP,0
btfss STATUS,Z
goto FORWARD5
movlw b"00000110"
goto ENVIO
FORWARD5 movlw 0x02
subwf CUENTAPP,0
btfss STATUS,Z
goto FORWARD6
movlw b"00000100"
goto ENVIO
FORWARD6 movlw 0x01
subwf CUENTAPP,0
btfss STATUS,Z
goto FORWARD7
movlw b"00000101"
goto ENVIO
FORWARD7 movlw b"00010001"
ENVIO movwf PORTA
call TEMPO
return ;Se vuelve a BUCLE para esperar otra acción.
;********************************************************************************************************
SUBRUTINAS
;********************************************************************************************************
SUMA_16_BITS
movf Dato_A_L,W ;Carga menos peso del dato A
addwf Dato_B_L,W ;Suma menos peso del dato B
movwf Resultado_L ;Almacena el resultado
movf Dato_A_H,W ;Carga más peso del dato A
btfsc STATUS,C ;Hubo acarreo anterior ??
addlw 1 ;Si, suma 1 al acumulador
addwf Dato_B_H,W ;Suma más peso del dato B
movwf Resultado_H ;Guarda el resultado
return
RESTA_16_BITS
movf Dato_B_L,W ;Carga menos peso del dato B (sustraendo)
subwf Dato_A_L,W ;Resta menos peso del dato A (minuendo)
movwf Resultado_L ;Almacena el resultado
movf Dato_B_H,W ;Carga más peso del dato B (sustraendo)
btfss STATUS,C ;Hubo acarreo (CARRY = 0) anterior ??
addlw 1 ;Si, añade 1 al acumulador (sustraendo)
subwf Dato_A_H,W ;Resta más peso del dato A (minuendo)
movwf Resultado_H ;Guarda el resultado
return
ESCRIBE_EEPROM
movlw b"00000100"
movwf PORTB
return
bcf STATUS,RP0 ;Seleccionamos Banco 0
movlw DIRE ;Ponemos en W la dirección que vamos a escribir
movwf EEADR ;y la guardamos en EEADR
movlw ESCR ;Ponemos ahora el dato a escribir en W
movwf EEDATA ;y lo guardamos en EEDATA
bsf STATUS,RP0 ;Seleccionamos Banco 1
bsf EECON1,WREN ;Colocamos el permiso de escritura (WREN) en EECON1 a 1
;Aquí da inicio la secuencia de escritura
movlw 0x55 ;Inicio de las intrucciones para EECON2
movwf EECON2
movlw 0xAA
movwf EECON2 ;Fin de las intrucciones para EECON2
bsf EECON1,WR ;Comienza la escritura propiamente dicha.
WAITING btfss EECON1,EEIF
goto WAITING ;Espera a que se termine el grabado
bcf EECON1,EEIF
return
LEE_EEPROM
movlw b"00000100"
movwf PORTB
bcf STATUS,RP0 ;Seleccionamos el Banco 0
movlw DIRE ;Ponemos en W la dirección que vamos a leer
movwf EEADR ;y pasamos W al registro EEADR, definiendo la dirección a leer
bsf STATUS,RP0 ; Seleccionamos el Banco 1
bsf EECON1,RD ;Hacemos la lectura colocando RD a 1
bcf STATUS,RP0 ;y regresamos al Banco 0
movf EEDATA,W ;para finalmente rescatar el dato desde EEDATA hacia W
return
SUMA_PASO
;Suma 1 a la posición actual y la almacena en la EEPROM
call SUMA_16_BITS ;Llama a la rutina de resta (En Dato_A está la posición actual)
movf Resultado_H,0 ;Salva el High Byte de la posición actual en la EEPROM 0x01
movwf Dato_A_H ;Aquí se coloca la nueva posición en la variable
movwf ESCR ;Dato a escribir
movlw 0x04 ;En la dirección de memoria
movwf DIRE
call ESCRIBE_EEPROM ;Escribir
movf Resultado_L,0 ;Salva el Low Byte de la posición actual en la EEPROM 0x02
movwf Dato_A_L ;Aquí se coloca la nueva posición en la variable
movwf ESCR
movlw 0x05
movwf DIRE
call ESCRIBE_EEPROM
return
RESTA_PASO
;Resta 1 a la posición actual y la almacena en la EEPROM
call RESTA_16_BITS ;Llama a la rutina de resta (En Dato_A está la posición actual)
movf Resultado_H,0 ;Salva el High Byte de la posición actual en la EEPROM 0x04
movwf Dato_A_H ;Aquí se coloca la nueva posición en la variable
movwf ESCR ;Dato a escribir
movlw 0x04 ;En la dirección de memoria
movwf DIRE
call ESCRIBE_EEPROM ;Escribe
movf Resultado_L,0 ;Salva el Low Byte de la posición actual en la EEPROM 0x04
movwf Dato_A_L ;Aquí se coloca la nueva posición en la variable
movwf ESCR
movlw 0x05
movwf DIRE
call ESCRIBE_EEPROM
;*********************************************************************************************************
;TEMPO Subrutina de temporización.
TEMPO movlw 0x0F ;carga 0F en TEMP1
movwf TEMP1
clrf TEMP2;Carga 0 en TEMP2
TEMPO_1 decfsz TEMP2, F ;Decrementa TEMP2 y si es 0 salta
goto TEMPO_1 ;volver a TEMPO_1
decfsz TEMP1, F ;Decrementa TEMP1 y si es 0 salta
goto TEMPO_1 ;volver a TEMPO_1
RETURN
END