TODOPIC

Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: navegante74 en 16 de Julio de 2015, 23:29:51

Título: Posicionar un servo de forma aleatoria utilizando interrupcion por timer0
Publicado por: navegante74 en 16 de Julio de 2015, 23:29:51
   Hola que tal a todo el foro!

Necesito alguna idea,consejo o ejemplo de como puedo posicionar un servo de forma aleatoria sin usar nada es decir sin pulsadores,ni pots,ni adc,etc unicamente el valor a cargar en la variable pos y que segun ese valor se coloque en posicion x,otro valor y se coloque en la posicion y, otro valor y se coloque en la posicion z,no necesariamente tenga que ser consecutivo osea en pocas palabras jugar con el servo,moverlo en cualquier posicion de forma aleatoria claro con su respectivo pause todo esto utilizando la interrupcion por timer0.
Hice un recorrido por el foro y los temas sobre servos son los citados arriba utilizando pulsadores,pots,adc,la instruccion pulsout,pwm,...todo esto ya lo he utilizado con resultados satisfactorios...Ahora lo que deseo es mover el servo automaticamente con int/tmr0 (que se posicione en un angulo cierto tiempo,luego se mueva a otro angulo espere cierto tiempo y asi sucesivamente...),intente cargar valores a la variable pos con su respectiva pause pero no hace lo que yo deseo osea cargo pos=23,se mueve digamos a la posicion max(angulo +90) enseguida cargo pos=15 (centro) y no regresa...entonces desde aqui hay algo mal no se si falte poner limites a alguna variable dentro del main o crear otra variable en fin...si alguien tiene un poco de tiempo,dejo datos y parte del codigo...Gracias por algun aporte.



Datos:

Desbordamiento del timer0: cada 100us
Oscilador: 20MHz
Pic: pic16f628a
Compilador:Pic Basic Pro
Simulador:Proteus

Extracto del codigo:

     PORTB.0=0
   On Interrupt GoTo Interrupciones_ISR
   
   main:
   
   pos=x  ;x grados
 
   pos=y  ;y grados
 
   pos=z  ;z grados
   
   
   goto main
   
   Disable         
   Interrupciones_ISR:
   
             
   if INTCON.2=1 THEN
   
      contador=contador+1   
      if contador > 200 then contador=0
      iF contador < pos then PORTB.0=1
      if contador = pos then PORTB.0=0
             
   ENDIF       
    TMR0=166       ;carga TMR0                                                                                                                                                     
    INTCON.2 = 0
     
    Resume   
    Enable
    end
Título: Re: Posicionar un servo de forma aleatoria utilizando interrupcion por timer0
Publicado por: dogflu66 en 19 de Julio de 2015, 13:10:11
No se puede generar un numero aleatorio solamente con la utilización de un timer, para generar un numero aleatorio de forma simple con un timer se necesita ayudarle con la pulsación de una tecla a mano.
Hay gente en el foro que parece que ha logrado buenos resultados generando los números aleatorios leyendo una entrada analógica del adc, dejando esta al aire o sin conexión.

Ejemplo de posicionamiento de un servomotor de forma aleatoria cada vez que se pulsa una tecla:

'Posiciona de forma aleatoria un servo analógico al pulsar una tecla usando el TMR0
'Pic12F1840
Define CONFIG1 = 0x0f84  'PLL4 enable
Define CONFIG2 = 0x1dff
Include "_FuncionesPic12F1840.bas"
Include "_FuncionesRS232_IO.bas"
'Include "_FuncionesCadenas.bas"
Define CLOCK_FREQUENCY = 32
Define STRING_MAX_LENGTH = 25
'Constantes(codigos de control ascii del hyperterminal)
Const ff = 0x0c  'ff, avance de pagina
Const bell = 0x07  'bell, señal sonora
Const sp = 0x20  'sp, espacio
Const bksp = 0x08  'bksp, retroceso
Const cr = 0x0d  'cr, retorno de carro
Const _lf = 0x0a  'Lf, salto de linea
Const ctrlz = 0x1a  'ctrl - Z
Const esc = 0x1b  'escape
main:
   Call _setup_oscillator_mode(_oscillator_by_fosc)
   Call _setup_oscillator(_osc_8mhz_hf)
   Call _setup_rs232(4800, 32000000)
   Call _setup_timer0(_tmr0_div2)
   AllDigital
   TRISA = 0xff
   TRISA.3 = 0
   TRISA.2 = 0
   TRISA.4 = 0
   Symbol pin_servo = RA2  'Pin control servomotor
   Symbol sw1 = RA5  'Pin tecla
   Dim x As Byte
   x = 0
   Dim rand As Long
   Dim pos_max As Word
   Dim pos_min As Word
   Dim pos_servo As Word
   Dim pos_off As Word
   pos_max = 2000  'Posición maxima
   pos_min = 1000  'Posición minima
   
   pos_servo = 1500  'Posición inicial
   Call putchar(ff)  'Pagina en blanco al hyperterminal

   While x = 0
      pos_off = 19000 - pos_servo
      pin_servo = 1
      WaitUs pos_servo
      pin_servo = 0
      WaitUs pos_off
      'Calcula posición aleatoria mediante TMR0 y pulsación de la tecla, formula de max y minimos
      If sw1 = 0 Then
         While sw1 = 0
         Wend
         rand = ((((TMR0 * 100) / 255) * (pos_max - pos_min)) / 100) + pos_min
         pos_servo = rand  'Asigna la posición y cambia de tipo de dato.
         Call putchdec(pos_servo)  'Envia posición al puerto serie
         Call putchar(" ")  'Envia un espacio en blanco al puerto serie
      Endif
   Wend
End
Título: Re: Posicionar un servo de forma aleatoria utilizando interrupcion por timer0
Publicado por: navegante74 en 19 de Julio de 2015, 23:20:06
Gracias Dogflu66 yo quiero hacer algo mas sencillo claro utilizando la interrupcion por Timer0,por decir centro servo lo mantengo un cierto tiempo,lo muevo de min a max lo mantengo un tiempo,lo muevo de max a min lo mantengo un tiempo,etc... sin utilizar pulsadores,ni pots,ni adc,etc.
Observa dogflu66 en este pedacillo de codigo utilizo el comando PULSOUT para mover el servo sin nada de hardware algo similar es lo que busco hacer con el Timer0...to be continued.


  m var byte
  n var byte
  x var byte
  PORTB.0=0                    ;IMPORTANTE iniciar en CERO ya que PULSOUT invierte la señal
  pulsout PORTB.0,150       ;centro servo futaba
  pause 1000                     ;lo mantengo centrado 1000ms
 
  inicio:                             ;bucle principal
   for m=50 to 250  step 1  ;desplazo servo de min(-90grados) a max(+90grados) con paso de 1
     pulsout portb.0,m
     pause 30
   next m
   
   pause 1000                    ;lo mantengo en esa posicion durante 1000ms
   
   for m=250 to 50  step -1 ;desplazo servo de max(+90grados) a min(-90grados) con paso de -11
     pulsout portb.0,m
     pause 30
   next m
   
   pause 1000                   ;lo mantengo en esa posicion durante 1000ms
   
  goto inicio
 
Título: Re: Posicionar un servo de forma aleatoria utilizando interrupcion por timer0
Publicado por: dogflu66 en 20 de Julio de 2015, 06:10:58
Lo siento pero no te entiendo, con solo el uso de un timer no se puede generar aleatoriedad.
Y si lo que quieres es que realice una secuencia prefijada para que quires el timer0?, no te comprendo.

     pos_off = 19000 - pos_servo
      pin_servo = 1
      WaitUs pos_servo
      pin_servo = 0
      WaitUs pos_off

Ese pequeño codigo es lo mismo que pulsout, la diferencia es que con el codigo se puede elegir la resolución del servo, mientras que con pulsout no se puede.