Autor Tema: Problema con Interrupcion en TMR0  (Leído 6664 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #30 en: 22 de Septiembre de 2012, 13:08:35 »
Hola tapi8, de nuevo gracias por la ayuda ofrecida desinteresadamente, tomare en cuenta lo de guardar los registros antes de entrar en la interrupcion para restaurarlos a la salida de la misma.
Referente a si sera un solo servo o varios, la idea es hasta 18 para poder controlar un hexapodo, pero todo se andara, ya que primero me interesa poder guardar las diferentes posiciones del servo para luego reproducirlas.

PD: Por curiosidad cual es tu nombre  :oops: no porque no me guste tapi8, pero me suena raro llamarte tapi8  ;-)

Miquel_S
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Problema con Interrupcion en TMR0
« Respuesta #31 en: 23 de Septiembre de 2012, 07:00:47 »
Citar
PD: Por curiosidad cual es tu nombre  no porque no me guste tapi8, pero me suena raro llamarte tapi8 

Pues Tapi, me quedo desde pequeño  :lol: el 8 lo tuve que poner porque no me dejaba Tapi solamente.

Citar
Referente a si sera un solo servo o varios, la idea es hasta 18 para poder controlar un hexapodo, pero todo se andara, ya que primero me interesa poder guardar las diferentes posiciones del servo para luego reproducirlas.

Pues para hacer eso lo tienes bastante facil, ya que si partes de 90º en todas las patitas y un paso adelante supongamos 30º, haces 3 movimientos de 10 en 10º (asi es un movimiento mas natural, si das 30º de golpe es un movimiento mas robotico) aumentas de 112 a 113 y tendras 100º (un poquito mas) ya que 10º son 111us y con TIMER en preescaler 128, solo puedes aumentar y reducir en 128us, a continuacion 114 y estara a algo mas de 110º, 115 y 120º, despues haces al reves empiezas a ir para atras otra vez 114,113,112 volvera a estar en 90º y supongo que ira hacia atras la pata, entonces restas uno 111=80º, 110=70º y 109=60º, bueno esto despues cuando ande ya se vera si asi esta bien o hay que hacer modificaciones.

Yo suprimiria la interrupcion, creo que no te aporta nada, solo te complica un poco mas. Una vez que pones a 0 el servo solo tienes que esperar a que se desborde el TIMER, chequeas el flag "INTCON,T0IF" y te evitas la interrupcion, si lo haces con interrupcion, creo que vas atener que hacer los chequeos de los grados (112,111, etc) dentro de la interrupcion.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #32 en: 23 de Septiembre de 2012, 17:56:43 »
Hola otra vez, intentare enfocarlo de la manera expuesta por ti haber si consigo reproducir los movimientos mas suaves, aparte de intentar controlar los servos en paralelo.

http://linuxdroids.wordpress.com/2010/05/07/control-de-servos-en-paralelo-con-pic/

Miquel_S
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Problema con Interrupcion en TMR0
« Respuesta #33 en: 24 de Septiembre de 2012, 13:33:22 »
Como te lo explica en ese enlace, la segunda menera, va bien encaminado, aunque no te da el resultado final, pero es sencillo.

Supongamos que quieres 3 servos a 60º otros 3 a 90º y otros 3 a 120º, por poner los extremos y el punto medio, al principio pones el TIMER a contar, pones todos los servos a 1 y chequeas cuando llega a 109 (empezo a contar en 100) y pones a 0 los que van a estar en 60º, sigues chequeando hasta que llega a 112 y pones a 0 los de 90º y cuequeas cuando llega a 115 y bajas los que estan a 120º, esperas a que el TIMER se desborde y ya esta, con un contador haces que esto se repita las veces que quieras, ya que cada 20ms seria muy rapido, creo yo, por ejemplo 6 veces que serian 120ms, a continuacion supongamos que quieres que los de 60º se pongan a 70º y los de 90 a 100º, en vez de 109 miras cuando llega a 110 y pones a 0 los que antes estaban a 60º y estaran a 70º, despues miras cuando llegan a 113 y pones los tres que antes estaban a 90 a 0 y ya estan en 100º y en 115º bajas los de 120º que siguen igual.

Todos estos grados no son exactos porque TIMER0 en vez de 111us que son 10º te cuenta 128us minimo, tendras un poco de desviacion pero bueno aqui creo que da igual. Puedes usar preescaler mas bajo y tendras mas precision pero tendras que hacer varios desbordes y te complicara un poco mas. Otra opcion es usar TIMER1, pero creo que tendras otro problema y es que como cambia cada millonesima si se te escapa, cosa que pasara, se te predera el programa. Esta la solucion de los bucles de tiempo, como ya te dije en un post anterior, asi le das los pasos y grados que quieras, de una manera muy sencilla, y con precision a la millonesima. Esta ultima es la mejor, la mas sencilla y yo diria que hasta la mas elegante  :lol: ademas si con movimiento de 10 en 10º no te gusta cambias la temporizacion de 111us  a la mitad 55us y los mueves de 5 en 5º el doble de rapido, en vez de 6 repeticiones haces 3 y quedara mas bonito, beno esto lo creo yo.

No se si has visto este hilo, es por un problema de interferencias en servos y Suki y Nocturno (foreros muy fiables) ponen un par de soluciones, a ti seguramente tambie te meteran interferencias al ser muchos servos:

http://www.todopic.com.ar/foros/index.php?topic=39282.0

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #34 en: 24 de Septiembre de 2012, 17:39:04 »
Me gusta, a medida que aumentan los posts la cosa se complica  :) o sea que voy a ver como enfoco todo esto y veremos al final que es lo que sale, al tener algo en claro creare un tema nuevo con un enlace en este post para no mezclar las cosas.

Excelente explicacion compañero, GRACIAS tapi.

Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado tapi8

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1506
Re: Problema con Interrupcion en TMR0
« Respuesta #35 en: 27 de Septiembre de 2012, 13:18:33 »
No pude resistir la tentacion de hacer un programa (en realidad solo es la idea) para los 16 servos, hice lo que serian 3 secuencias una
todos a 90º (la que podria ser la posicion de partida) otra moviendolos de 4 en 4 en distintos angulos y otra moviendolos de 2 en 2.

Un par de aclaraciones sobre el programa, en POSICION_1, para moverlos de 4 en 4 lo hago con mascara, haciendo una "and" con un literal sobre el puerto en el que quiero escribir, de este modo los que estan a 0 en el literal quedaran en 0 y los que esten en 1 quedaran con
el valor que tengan, no variaran:

   movlw   0XF0      ;para aplicar mascara, pone servos 0,1,2,3 a 0
   andwf   PORTB      ;resto de PORTB queda como estaba

Hago una temporizacion de 1166us que corresponde a 60º, 666 de 60º mas 500us de 0º, esto lo hago porque doy por hecho que nunca va a haber ningun servo que tenga menos de 60º (en cada programa habra que ver cual es este minimo) asi me ahorro de hacer 6 llamadas a demora al principio de cada ciclo.

Cada secuencia se repite 10 veces por 20ms=200ms, despues si en la realidad va lento se disminuye esta numero y si va rapido se aumenta, tambien se podria tener en unas secuencias mas tiempo y en otras menos, si por ejemplo quieres hacerla bailar. :lol: :lol: Tambien se puede hacer una temporizacion mas pequeña de 10º y asi se conseguirian movimientos mas reales, esto habra que ver en la practica como se comporta.

Esta hecho para un 16f887 pero se puede cambiar facil para otro 16f, lo depure en el MPLAB para que lo puedas simular y ver como funciona:

Código: [Seleccionar]
;Cuando son muchas salidas o muchas entradas, es mejor definirlos, asi cuando cambiemos algun pin
;no tendremos que modificar el programa, solo cambiar en el #DEFINE cual es su nueva ubicacion, ademas
;hace el programa mas comprensible tanto para el programador, como para algun colaborador que lo revise.



#DEFINE SERVO_0  PORTB,0
#DEFINE SERVO_1  PORTB,1
#DEFINE SERVO_2  PORTB,2
#DEFINE SERVO_3  PORTB,3
#DEFINE SERVO_4  PORTB,4
#DEFINE SERVO_5  PORTB,5
#DEFINE SERVO_6  PORTB,6
#DEFINE SERVO_7  PORTB,7
#DEFINE SERVO_8  PORTC,0
#DEFINE SERVO_9  PORTC,1
#DEFINE SERVO_10 PORTC,2
#DEFINE SERVO_11 PORTC,3
#DEFINE SERVO_12 PORTC,4
#DEFINE SERVO_13 PORTC,5
#DEFINE SERVO_14 PORTC,6
#DEFINE SERVO_15 PORTC,7



list p=16F887
#include P16F887.inc
;__CONFIG   _33C4  _3FFF ; creo que asi esta bien para inter_osc 4Mz

ERRORLEVEL -305
ERRORLEVEL -302

CBLOCK 0X20
CONTADOR
PDel0
PDel1
ENDC









CONFIGURACION
banksel ANSEL ;seleccionamos banco 4
clrf ANSEL ;ponemos PORTA digital
clrf ANSELH ;ponemos PORTB digital
bcf STATUS,RP1
bsf STATUS,RP0 ;banco 1 para configurar puertos
clrf TRISB    ;todas salidas
clrf TRISC    ;todas salidas
movlw 0X06      ;0000 0110
movwf OPTION_REG ;TIMER0, PREESCALER 128
movlw 0X20 ;0010 0000
movwf INTCON ;activar TIMER0 sin interrupcion
bcf STATUS,RP0
clrf CONTADOR
;*************En POSICION_0 TODOS A 90º, para no hacer mas bucles de retardo*************
;*************llamaremos 1 vez bucle de 60º y 3 veces el de 10º**************************

POSICION_0

movlw 0XFF  ;para poner a 1 todos los servos
movwf PORTB ;ya estan a 1 los del PORTB
movlw 0XFF  ;para poner a 1 todos los servos
movwf PORTC ;ya estan a 1 los del PORTC
movlw .100 ;cargamos TIMER0 para 20ms
movwf TMR0
call DEMORA_60º ;llamamos DEMORA inicial, para servos con DUTTY 60º (minimo posible)
call DEMORA_10º ;llamamos bucle de 10º 3 veces para completar 90º
call DEMORA_10º
call DEMORA_10º
clrf PORTB
clrf PORTC ;ponemos todos lo duttys a 0, todos 90º
;aqui tienes mucho tiempo, minimo 17.5ms, ya que los tiempos en alto de los duttys son
;como maximo 2.5ms y el TIMER desborda a los 20ms, podrias ejecutar 17500 instrucciones


btfss INTCON,T0IF ;aqui esperamos desborde del TIMER0
goto $-1 ;no desbordo, espera
bcf INTCON,T0IF
incf CONTADOR,1 ;desbordo, contaremos los desbordes
movlw .10 ;contando 10 cada movimiento tardara 200ms
subwf CONTADOR,0 ;cuanto menor sea el numero mas rapido ira la araña
btfss STATUS,Z
goto POSICION_0 ;todavia no van 20 veces sigue en esta posicion
clrf CONTADOR ;cuando vayan 20 pasara a siguiente posicion


;*********Aqui vamos a poner servos 0,1,2,3 a 60º, servos 4,5,6,7 a 80º, servos 8,9,10,11 a 100º****
;**********servos 12,13,14,15 a 120º, son posiciones a modo de ejemplo****************************


POSICION_1

movlw 0XFF  ;para poner a 1 todos los servos
movwf PORTB ;ya estan a 1 los del PORTB
movlw 0XFF  ;para poner a 1 todos los servos
movwf PORTC ;ya estan a 1 los del PORTC
movlw .100 ;cargamos TIMER0 para 20ms
movwf TMR0
call DEMORA_60º ;llamamos DEMORA inicial, para servos con menor DUTTY
movlw 0XF0 ;para aplicar mascara, pone servos 0,1,2,3 a 0, 60º
andwf PORTB ;resto de PORTB queda como estaba
call DEMORA_10º ;llamamos DEMORA_10º equivalente a 10º
call DEMORA_10º ;2 veces para completar 80º, 60+10+10
movlw 0X0F ;mascara igual que antes pero para servos 4,5,6,7
andwf PORTB ;es lo mismo que hacer "bcf SERVO_4-bcf SERVO_5-bcf SERVO_6-bcf SERVO_7"
call DEMORA_10º
call DEMORA_10º ;2 demoras mas para 100º
movlw 0XF0 ;mascara igual que antes pero para servos 8,9,10,11
andwf PORTC ;es lo mismo que hacer "bcf SERVO_8-bcf SERVO_9-bcf SERVO_10-bcf SERVO_11"
call DEMORA_10º
call DEMORA_10º ;2 demoras mas para 120º
movlw 0X0F ;mascara igual que antes pero para servos 12,13,14,15
andwf PORTC ;es lo mismo que hacer "bcf SERVO_12-bcf SERVO_13-bcf SERVO_14-bcf SERVO_15"

;aqui tienes mucho tiempo, minimo 17.5ms, ya que los tiempos en alto de los duttys son
;como maximo 2.5ms y el TIMER desborda a los 20ms, podrias ejecutar 17500 instrucciones

btfss INTCON,T0IF ;aqui esperamos desborde del TIMER0
goto $-1 ;no desbordo, espera
bcf INTCON,T0IF
incf CONTADOR,1 ;desbordo, contaremos los desbordes
movlw .10 ;contando 10 cada movimiento tardara 200ms
subwf CONTADOR,0 ;cuanto menor sea el numero mas rapido ira la araña
btfss STATUS,Z
goto POSICION_1 ;todavia no van 20 veces sigue en esta posicion
clrf CONTADOR ;cuando vayan 20 pasara a siguiente posicion

;***********En esta posicion los pondremos de 2 en 2 en distisntos angulos, servo 0 y 1 en 60º**************
;***********2 y 3 en 70º y asi sucesivamente, al ir de 2 en 2 no lo haremos con mascara sino directamente****

POSICION_2

movlw 0XFF  ;para poner a 1 todos los servos
movwf PORTB ;ya estan a 1 los del PORTB
movlw 0XFF  ;para poner a 1 todos los servos
movwf PORTC ;ya estan a 1 los del PORTC
movlw .100 ;cargamos TIMER0 para 20ms
movwf TMR0
call DEMORA_60º ;llamamos DEMORA inicial, para servos con menor DUTTY
bcf SERVO_0 ;ponemos a 0 duttys de 60º
bcf SERVO_1 ;ponemos a 0 duttys de 60º
call DEMORA_10º ;llamamos DEMORA_10º equivalente a 10º
bcf SERVO_2 ;ponemos a 0 duttys de 70º
bcf SERVO_3 ;ponemos a 0 duttys de 70º
call DEMORA_10º ;llamamos DEMORA_10º equivalente a 10º
bcf SERVO_4 ;ponemos a 0 duttys de 80º
bcf SERVO_5 ;ponemos a 0 duttys de 80º
call DEMORA_10º ;llamamos DEMORA_10º equivalente a 10º
bcf SERVO_6 ;ponemos a 0 duttys de 90º
bcf SERVO_7 ;ponemos a 0 duttys de 90º
call DEMORA_10º ;llamamos DEMORA_10º equivalente a 10º
bcf SERVO_8 ;ponemos a 0 duttys de 100º
bcf SERVO_9 ;ponemos a 0 duttys de 100º
call DEMORA_10º ;llamamos DEMORA_10º equivalente a 10º
bcf SERVO_10 ;ponemos a 0 duttys de 110º
bcf SERVO_11 ;ponemos a 0 duttys de 110º
call DEMORA_10º ;llamamos DEMORA_10º equivalente a 10º
bcf SERVO_12 ;ponemos a 0 duttys de 120º
bcf SERVO_13 ;ponemos a 0 duttys de 120º
call DEMORA_10º ;llamamos DEMORA_10º equivalente a 10º
bcf SERVO_14 ;ponemos a 0 duttys de 130º
bcf SERVO_15 ;ponemos a 0 duttys de 130º


;aqui tienes mucho tiempo, minimo 17.5ms, ya que los tiempos en alto de los duttys son
;como maximo 2.5ms y el TIMER desborda a los 20ms, podrias ejecutar 17500 instrucciones

btfss INTCON,T0IF ;aqui esperamos desborde del TIMER0
goto $-1 ;no desbordo, espera
bcf INTCON,T0IF
incf CONTADOR,1 ;desbordo, contaremos los desbordes
movlw .10 ;contando 10 cada movimiento tardara 200ms
subwf CONTADOR,0 ;cuanto menor sea el numero mas rapido ira la araña
btfss STATUS,Z
goto POSICION_2 ;todavia no van 20 veces sigue en esta posicion
clrf CONTADOR

DEMORA_60º                    ; retardo inicial de 1166us, 666us proporcional ya que 2000us son 180º
    ; mas 500us que son 0º, 666+500=1166us 
movlw     .232      ; 1 set numero de repeticion
        movwf     PDel0     ; 1 |
PLoop0  clrwdt              ; 1 clear watchdog
        clrwdt              ; 1 ciclo delay
        decfsz    PDel0, 1  ; 1 + (1) es el tiempo 0  ?
        goto      PLoop0    ; 2 no, loop
        clrwdt              ; 1 ciclo delay
        return              ; 2+2 Fin.


DEMORA_10º      ; retardo de 111us, equivalente a 10º
        movlw     .26       ; 1 set numero de repeticion
        movwf     PDel0     ; 1 |
PLoop1  clrwdt              ; 1 clear watchdog
        decfsz    PDel0, 1  ; 1 + (1) es el tiempo 0  ?
        goto      PLoop1    ; 2 no, loop
PDelL1  goto PDelL2         ; 2 ciclos delay
PDelL2 
        return              ; 2+2 Fin.

END


Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #36 en: 27 de Septiembre de 2012, 15:23:57 »
 ((:-)) ((:-))
Que malo que eres  :5]  :D
Gracias por el programa, me lo estudiare bien a fondo, ya que estoy seguro que es mejor que lo que tengo empezado, aunque hay cosas parecidas.
 
Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Problema con Interrupcion en TMR0
« Respuesta #37 en: 09 de Octubre de 2012, 16:59:12 »
Bueno, despues de varios dias con el programa de tapi voy a intentar darle otro enfoque, usando parte del codigo de tapi y parte mia voy a ver si consigo lo que quiero, y es que los servos se posicionen sin error y sin temblores en su sitio.
Cogiendo la idea de RedPic: http://www.todopic.com.ar/foros/index.php?topic=24801.0 voy a intentar hacer todas las temporizaciones con el timer, ya que usando demoras como comenta tapi en su programa, al no correr por igual las demoras y el timer0 es cuando tengo los problemas de temblores.
Os tendre informados  :shock:

Saludos!
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.