TODOPIC
Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: MarceloGabriel2 en 08 de Enero de 2006, 13:47:00
-
Saludos a la comunidad y Feliz Año Nuevo a todos ! (este es mi primer post del año)
Tengo el siguiente problema:
Hice un circuito basado en PIC 16F84A, el cual mueve un motor paso a paso en "half steps".
Este motor mueve un engranaje de un telescopio que tiene tope en ambos sentidos es decir, gira hacia la derecha hasta un tope y lo mismo hacia la izquierda.
En total, el engranaje da alrededor de 35 vueltas en todo su viaje.
Lo que me falta del firmware es lo siguiente:
Luego de llevar el engranaje a mano hasta un tope (full adentro o afuera), mediante el uso de un software en PC mando a mover el motor en sentido contrario hasta llegar al tope opuesto. En ese tiempo, el PIC debe contar los pasos que dió el motor durante ese proceso y almacenarlo en la EEPROM. Esto se hace cuando se quiere calibrar el conteo.
De allí en adelante, el PIC debe almacenar la posición en la que se encuentra el motor es decir, a cuantos pasos se encuentra del cero. Cada vez que da un paso en cualquier sentido, se debe almacenar su nueva posición en la EEPROM.
El número total de pasos según calculé es menor a 10.000 (alrededor de 8000).
Alguien tiene algún .INC o rutina en assembler que pueda hacer esto?
Mujchas gracias.
Marcelo Gabriel.
-
Hola amigo y feliz año

No entiendo muy bien porque tienes un software de pc para mover el motor y poder calibrar el circuito.
Pienso que lo mas simple seria dos motones en la propio placa para mover el motor en un sentido u otro. Un interruptor para calibrar o usar y listo.
Si tu PIC maneja directamente el motor pasa a paso, tienes que contar los pasos a la fuerza. Entonces, simplemente mirar si estamos en modo calibración y empezar a contar pasos.
No se si te ha sido de ayuda, un saludo
-
Hola pK_kraken; gracias por contestar.
Bueno, trataré de explicarte por qué el circuito es de esta forma.
Lo que mueve el motor PP es el foco del telescopio. La parte circuital ya está terminada y funciona, por lo que no tengo problemas con ella. El programa de PC que tengo es un test, y lo uso para mover en forma remota el motor en un sentido y en el otro, tal como si lo hiciera diréctamente en el telescopio con la mano.
La comunicación del circuito y el PC es serial y el firmware del PIC debe seguir unos estándares de comunicación de una plataforma de desarrollo que se llama ASCOM.
Esa plataforma se usa para desarrollar los drivers (DLL) del circuito para que los programas comerciales de astronomía se puedan comunicar en forma estandarizada con ellos (Enfocadores, Seguimiento, Ajustes de foco por variación de temperatura, etc.)
En mi caso, el software comercial enfocará automáticamente una cámara CCD para astrofotografía mediante unos algoritmos especiales. Para esto, el circuito debe enviar algunos parámetros y entre ellos están:
1) Número de pasos totales del recorrido del foco (De aquí lo de la calibración. Como el circuito se puede usar en cualquier telescopio, no todos ellos tienen el mismo recorrido de foco, por lo que debe existir una forma de contarlos. Aquí me falta el conteo uno a uno en 16 bits (creo que encontré algo en la librería de assembler de este foro).
2) La posición en la que quedó el foco cuando se apaga el telescopio. Esto permite retomar las acciones sin necesidad de volver a calibrar el recorrido, siempre y cuando el foco no se haya movido manualmente.
Estos dos parámetros los debo almacenar en la eeprom para que estén disponibles la próxima vez que lo utilice.
Aquí tienes un link con un aparato similar para que veas de lo que estoy hablando.
http://www.homedome.com/robofoc1.htm
Saludos y Gracias,
Marcelo Gabriel.
-
Hola MarceloGabriel2, con el permiso tuyo te daré una sugerencia:
*En ves de poner 2 topes, por que no reemplazas estos por pulsadores (final de carrera) y por medio de estos tomas el inicio y fin de la carrera.
*Teniendo los pulsadores tu haces que el motor gire en un sentido asta presionar uno de los pulsadores, en esta posición pones el contador en cero y mueves el motor hasta tocar el otro pulsador mientras vas contando los pasos.
*De esta forma ya tienes la cuenta de los pasos para el telescopio en cuestión
*Con el método que elijas (PC o PIC) mueves el telescopio asta el pulsador tomado como arranque pones en cero la cuenta después posicionas el telescopio en el lugar que desees mientras cuentas los pasos y memorizas los pasos
*Entonces cuando arranque lo único que tienes que haces es que el pic genere pasos hasta que el pulsador que tomas de referencia para el arranque este presionado, luego desde esa posición (previa lectura de la eeprom) cuentas los pasos que darás hacia el otro sentido y el motor quedara exactamente en la posición que tenia al momento que apagaste el equipo.
Bueno espero que te sirva de ayuda, si tienes mas dudas haz las preguntas que en la medida de los conocimientos te serán respondidas.
Suerte con el proyecto.
Atte. CARLOS
-
Gracias Carlos por responderme y por la sugerencia.
Lo que me comentas pudiera funcionar en el caso de que tuviera algo que se moviera fuera del telescopio cuando varío el foco.
En mi caso, lo que se mueve está dentro del tubo óptico y no es accesible a no ser que desarmes el aparato.
En caso de los refractores; que son los telescopios que uno comunmente está acostumbrado a ver; si se podría implementar algo así ya que el tubo por donde se mira entra y sale al enfocar.
En los schmit cassegrain (que es el que yo tengo) lo que se mueve es el espejo primario por medio de un tornillo interno y por fuera existe como "interfaz al usuario", una perilla que pareciera que gira "loca" pero que en realidad está moviendo ese espejo. De esa forma se logra el foco.
Lo que tu comentas es ideal porque tendría un feedback que daría algo más de "inteligencia" al circuito, pero desafortunadamente no lo puedo hacer por lo que te expliqué. Otra cosa que quisiera poder hacer es que cuando mueva el foco en forma manual, existiera alguna especie de encoder o algo que pudiera contar los pasos del motor pero al revés es decir, como si el motor estuviera generando los pulsos con el movimiento y funcionara como un encoder. De esta manera pudiera mantener en que posición está el foco tanto si lo muevo por software como manualmente. Esta última idea la encuentro tan complicada que creo que ya la deseché.
Gracias Carlos,
Marcelo Gabriel.
-
Hola MarceloGabriel2, ahora comprendo tu complicación

Pensaste en reemplazar el motor de pasos por uno normal y ponerle un encoder, de esta forma ya podrías utilizarlo de las 2 formas que tu comentas, y no se te complicaría con el tema del motor por pasos.
Aplicas el mismo sistema que te comente ya anteriormente pero en ves de pulsadores trabajas con los topes y el encoder, pero deberás colocar un embrague (del tipo pasa casette) entre el motor común y el eje para que a determinado torque no le siga imponiendo fuerza al eje y no dañe a este.
El embrague si conoces los de las casetteras sabrás que es muy sencillo de realizar, y sobre este mismo podrás aplicar el encoder y luego mandar la fuerza por el par de engranajes que tu comentas.
Espero tu respuesta, a ver si podemos encontrarte un a solución.
Atte. CARLOS
-
Hola amigo,
Supongo que lo que quieres es guardar la posicion en que quedo el foco al apagar verdad? y al prender el aparato que vuelva a la posicion en que estaba? bueno el problema que yo veo es que puedas contar los pasos a partir de un tope por ejemplo 500 pasos desde el tope inferior y si dices que son como 8000 entonces quedaria de 7500 desde el tope superior. eso es lo que entiendo. Entonces te recomiendo que construyas una trama o una "palabra" de 16bits para que la guardes en la eeprom seria asi:
|t2|t1|t0|x|x|x|x|x|x|x|x|x|x|x|x|x|
donde t0 - t2 te indiquen a partir de que tope se cuenta por ejemplo:
001 = tope inferior
010 = tope superior
y las demas x son los pasos que tiene que dar para la posición original, eso te ocupa dos posiciones en la eeprom, tambien lo podias construir con las vueltas y como son 35 caben en un reg de 8 bits. Espero que de algo te sirva.
Saludos
-
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/e26w7
allí 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
-
Hola MarceloGabriel2, no se como pensabas vos poner el encoder pero este tiene que ir montado sobre el eje del paso a paso y justo después del embrague, la secuencia seria así:
Motor > embrague > encoder > piñón > corona que mueve lo deseado
De esta forma vos estaría controlando las vueltas del motor y no de la corona, me entiendes?
Con este sistema tienes las dos opciones que pretendes y con un encoder de los económicos (256 pasos) contaras un gran numero de pasos.
Espero tu respuesta, y que puedas llegar a una solución.
Atte. CARLOS
-
Hola amigo
Chequeando tu codigo vi al menos dos errores el las rutinas "leer eeprom" y "escribir eeprom" cuando vas a leer la direccion para grabar o leer en la eeprom, tienes:
movlw direc
y debería ser
movf direc,w
asi siempre estas leyendo y escribiendo en la misma dirección EEPROM que es el numero que tiene direc en la RAM a lo mejor eso te produzca el error que tu dices.
Saludos
-
Hola MarceloGabriel2, estuve mirando un poco tu programa y realmente no encontré la función del return en la siguiente parte:
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
Si bien no revisé todo el programa en esta parte creo que no debería estar el primer return, ya que llegado a ese punto el programa retornaría a donde se produce la llamada call, sin haber grabado en la memoria.
Espero que te haya solucionado el problema.
Atte. CARLOS
-
Hola Carlos y poi5on,
Carlos: Ahora entiendo lo que dices. Un par de preguntas:
¿Tendrías el serial del encoder?
Según lo que me explicas, creo que el encoder debería tener el mismo paso que el stepper (7,5 º en mi caso) o un múltiplo de él. Me parece que debería estar sincronizado de alguna forma con el motor de manera tal que con cada paso genere un número igual de pulsos. ¿Como haría esto?
Yo usé un stepper precisamente para evitar usar el encoder, pero al parecer hay que usarlo igualmente.
Con respecto al código, el return que me dices se me olvidó sacarlo de allí. Lo puse para chequear si esa rutina es la que me estaba provocando el error es decir, que el programa la llama y cuando va para allá se regresa sin hacer nada, solo prende el led de indicación. Así el programa funciona pero cuando lo dejo entrar en la rutina eliminando ese return, se cuelga el PIC. No se si será cuastión de autoreset pero estoy evitando el uso de timers que lo generen así es que en realidad no se que pasa.
poi5on:
Tienes razón en el error. Inicialmente tenía un literal en la instrucción y posteriormente decidí pasar la variable a la subrutina. Cambié el literal por la variable pero se me olvidó cambiar la instrucción. Muchas gracias. Cambié el código pero se me sigue colgando. El led testigo se queda prendido lo que me indica que se queda en la rutina de escritura de la eeprom y no regresa al programa principal.
Voy a seguir chequeando a ver...
Saludos,
Marcelo.
-
Hola MarceloGabriel2, me alegra de que nos hayamos entendido, lo que te puedo decir con respecto a los encoder es que el mas chico que yo conozco es de 256 pasos y tu motor es de 48 por lo que estarían lejos de poder ir sincronizados, pero de todas formas esto a vos no te influiría ya que tu tendrías que contar los pasos del encoder y no del motor, hasta podrías ponerle un motor de los comunes que el sistema andaría bien.
Por otro lado acá te paso la rutina de grabación en la eeprom para el 16F84 que seria igual que del 16C84:
GRABAR_EEPROM
movlw H"01" ;DIRECCION DE LA EEPROM
movwf EEADR
movf DATO,W ;DATO A GRABAR
movwf EEDATA
bsf STATUS,RP0
bcf EECON1,WRERR
bsf EECON1,WREN
movlw H"55"
movwf EECON2
movlw H"AA"
movwf EECON2
bsf EECON1,WR
ESPERE
nop
btfss EECON1,EEIF
goto ESPERE
nop
btfsc EECON1,WRERR
goto GRABAR_EEPROM
nop
bcf EECON1,EEIF
bcf EECON1,WREN
bcf STATUS,RP0
return
Te comento que esta rutina yo la tengo andando y va de 10 con un cuarzo de 4MHz, a diferencia de la tuya esta tiene una comprobación de sí el dato fue escrito correctamente, de lo contrario se vuelve a reiniciar el proceso de escritura, este paso se repetiría asta que el dato se guarde correctamente. Es muy similar a la tuya pero tiene un par de diferencias.
Espero que te sea de utilidad, cualquier duda consúltala.
Suerte, estamos en contacto
Atte. CARLOS
-
Gracias Carlos,
Ya copié la rutina y la adapté a mis variables. Funciona bien.
Cualquier cosa vuelvo a preguntar, pero parece que ya empezó a ir la cosa.
Gracias a todos por la ayuda.
Marcelo Gabriel.