TODOPIC

Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: fco1306 en 12 de Octubre de 2010, 16:53:09

Título: Control servos con pic simulador
Publicado por: fco1306 en 12 de Octubre de 2010, 16:53:09
Tengo este programa que mueve servos y recuerda su posición cuando se enciende la alimentación.
Un botón sirve para posicionarlo en el centro y otro para moverlo a derecha e izquierda.Además controla un par de leds y un relé.

La cuestión es que cuando enciendo y apago la alimentación el servo se mueve, aunque no se hayan pulsado los botones.
Cuando pulso el boton para moverlo al centro, tengo que pulsarlo varias veces para que se posicione en el centro,cuando en teoría con una pulsación debería ir.
Cuando lo simulo con proteus no tengo problemas.No sé donde puede estar el problema.¿Cómo debo configurar los bits en el iceprog para programar el pic?
Muchas gracias
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 12 de Octubre de 2010, 19:42:46
Declaraste los fuses en el código de tu programa, así que, tu programador no debe, no puede modificarlos. Debería de configurarse de forma automática con la misma configuración de los fuses de tu código.
No sé porque el servo hace cosas raras en el arranque, lo que puedes hacer es configurar la salida del servo a controlar lo antes posible al estado bajo, o arranca la rutina de control del servo lo antes posible.
Con respecto a por que los servos no van a su posición, pues lo más probable sea porque no le das tiempo a que llegue. El servo tarda un tiempo en realizar el desplazamiento mínimo, la suma de estos tiempos mínimos ayudado por la velocidad, será el tiempo que tarde en llegar el servo a su lugar. Por lo tanto deberías mantener la señal de control hasta que llegue al destino.

    While hasta llegar a posicion
       ServoOut servo, 160
    Wend

Repetir ServoOut servo, 160 hasta llegar a la posicion.

Puedes ver los ejemplos del indice de este hilo:

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

Y como puedes ver en este ejemplo no se puede dejar de refrescar la posicion del servo

http://www.todopic.com.ar/foros/index.php?topic=14917.msg113728#msg113728
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 14 de Octubre de 2010, 16:20:34
He modificado un poco el código ,le he puesto una pausa de 200ms después de mover el servo y ha mejorado.
Lo que no consigo es hacerme con el control del servo al inicio.Cuando conecto la alimentación se mueve hacia cualquier sitio.
Le tengo puesto que vaya a la posición 160 pero no hace caso.
Sólo cuando pulso el botón el servo va a su sitio.Después conserva la posición y se mueve a dch o izq según voy pulsando el botón.
No sé que puede pasar

AllDigital  'todos los pines digitales
Symbol rele = GPIO.0  'define los pines entradas/salidas
Symbol rojo = GPIO.1
Symbol verde = GPIO.2
Symbol progr = GPIO.3
Symbol boton = GPIO.4
Symbol servo = GPIO.5

TRISIO = %011000

'define variables
Dim velocidad As Byte
Dim n As Byte
Dim posicion As Byte
Dim angulo As Byte
Dim angulo1 As Byte
'posiciona el servo en su sitio cuando se conecta la alimentación
'conecta los leds según la posición y el relè



rojo = 0
verde = 0
rele = 0
servo = 0
For n = 1 To 200 Step 1
ServoOut servo, 160
Next n
WaitMs 500


Read 01, posicion
If posicion = 0xff Then
Write 01, 01
For n = 1 To 200 Step 1
ServoOut servo, 160
Next n
WaitMs 200
rojo = 1
verde = 1
rele = 0
Endif

If posicion = 01 Then
Write 01, 01
For n = 1 To 200 Step 1
ServoOut servo, 160
WaitMs 200
Next n
rojo = 1
verde = 1
rele = 0
Endif


If posicion = 02 Then

For n = 1 To 200 Step 1
ServoOut servo, 190
Next n
WaitMs 200
rojo = 1
verde = 0
rele = 0
Endif

If posicion = 03 Then
For n = 1 To 200 Step 1
ServoOut servo, 130
Next n
WaitMs 200
rojo = 0
verde = 1
rele = 1
Endif

'inicio programa
inicio:
Read 01, posicion

If progr = 1 Then
WaitMs 200
Gosub pulso
Endif

If boton = 1 Then
WaitMs 200
Gosub mover_servo
Endif

Goto inicio

End                                               




pulso:
For n = 1 To 200 Step 1
ServoOut servo, 160
Next n
WaitMs 200
rojo = 1
verde = 1
Write 01, 01
Return                                           

'mueve el servo
mover_servo:
Read 01, posicion

If posicion = 01 Then
'el servo està en centro y tiene que pasar a dch

For n = 160 To 190 Step 1
ServoOut servo, n
WaitMs 100
Next n
WaitMs 200
rojo = 0
verde = 0
WaitMs 200
rojo = 1
verde = 0
rele = 1
Write 01, 02
Endif



If posicion = 02 Then
'el servo està en dch y tiene que pasar a izq
For n = 190 To 130 Step -1
ServoOut servo, n
WaitMs 100
Next n
WaitMs 200
rojo = 0
verde = 0
WaitMs 200
rojo = 0
verde = 1
rele = 0
Write 01, 03
Endif

If posicion = 03 Then
'el servo está en izq y tiene que pasar a dch
For n = 130 To 190 Step 1
ServoOut servo, n
WaitMs 100
Next n
WaitMs 200
rojo = 0
verde = 0
WaitMs 200

rojo = 1
verde = 0
rele = 1
Write 01, 02
Endif

Return                             
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 14 de Octubre de 2010, 20:47:55
Una vez que funciona puedes bajar el valor de "periodo" hasta el minimo que siga funcionando el servo.

Código: vb.net
  1. 'Trabajando con servos, PIC12F675
  2. Define CONF_WORD = 0x3184
  3. Define CLOCK_FREQUENCY = 4
  4. AllDigital  'todos los pines digitales
  5. Symbol rele = GPIO.0  'define los pines entradas/salidas
  6. Symbol rojo = GPIO.1
  7. Symbol verde = GPIO.2
  8. Symbol progr = GPIO.3
  9. Symbol boton = GPIO.4
  10. Symbol servo = GPIO.5
  11. TRISIO = %011000
  12. 'define variables
  13. Dim velocidad As Byte
  14. Dim n As Byte
  15. Dim posicion As Byte
  16. Dim angulo As Byte
  17. Dim angulo1 As Byte
  18. Dim outon As Byte  'Tiempo de la señal de control del servo a On (duty cycle)
  19. Dim outoff As Word  'Tiempo de la señal de control del servo a Off
  20. Dim periodo As Word  'Periodo de la frecuencia de trabajo de la señal de control del servo
  21.  
  22. 'posiciona el servo en su sitio cuando se conecta la alimentación
  23. 'conecta los leds según la posición y el relè
  24. rojo = 0
  25. verde = 0
  26. rele = 0
  27. servo = 0
  28. periodo = 2000  '20mSeg., para servos de 50Hz, señal a On mas señal a Off = 20mSeg.
  29.  
  30. outon = 160  '1.6mSeg.
  31. outoff = (periodo - outon) * 10  'Calculo tiempo de la señal a Off en uSeg.
  32. For n = 0 To 74  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
  33.     ServoOut servo, outon  '1.6mSeg. (señal a On)
  34.     WaitUs outoff  'Tiempo de la señal a Off
  35. Next n
  36. WaitMs 500
  37.  
  38. Read 01, posicion
  39. If posicion = 0xff Then
  40.     Write 01, 01
  41.     For n = 1 To 200 Step 1
  42.         ServoOut servo, 160
  43.     Next n
  44.     WaitMs 200
  45.     rojo = 1
  46.     verde = 1
  47.     rele = 0
  48. Endif
  49.  
  50. If posicion = 01 Then
  51.     Write 01, 01
  52.     For n = 1 To 200 Step 1
  53.         ServoOut servo, 160
  54.         WaitMs 200
  55.     Next n
  56.     rojo = 1
  57.     verde = 1
  58.     rele = 0
  59. Endif
  60.  
  61. If posicion = 02 Then
  62.     For n = 1 To 200 Step 1
  63.         ServoOut servo, 190
  64.     Next n
  65.     WaitMs 200
  66.     rojo = 1
  67.     verde = 0
  68.     rele = 0
  69. Endif
  70.  
  71. If posicion = 03 Then
  72.     For n = 1 To 200 Step 1
  73.         ServoOut servo, 130
  74.     Next n
  75.     WaitMs 200
  76.     rojo = 0
  77.     verde = 1
  78.     rele = 1
  79. Endif
  80.  
  81. 'inicio programa
  82. main:
  83.     Read 01, posicion
  84.     If progr = 1 Then
  85.         WaitMs 200
  86.         Gosub pulso
  87.     Endif
  88.  
  89.     If boton = 1 Then
  90.         WaitMs 200
  91.         Gosub mover_servo
  92.     Endif
  93.  
  94. Goto main
  95. End                                              
  96.  
  97. pulso:
  98.     For n = 1 To 200 Step 1
  99.         ServoOut servo, 160
  100.     Next n
  101.     WaitMs 200
  102.     rojo = 1
  103.     verde = 1
  104.     Write 01, 01
  105. Return                                            
  106.  
  107. 'mueve el servo
  108. mover_servo:
  109.     Read 01, posicion
  110.     If posicion = 01 Then
  111.     'el servo està en centro y tiene que pasar a dch
  112.         For n = 160 To 190 Step 1
  113.             ServoOut servo, n
  114.             WaitMs 100
  115.         Next n
  116.         WaitMs 200
  117.         rojo = 0
  118.         verde = 0
  119.         WaitMs 200
  120.         rojo = 1
  121.         verde = 0
  122.         rele = 1
  123.         Write 01, 02
  124.     Endif
  125.  
  126.     If posicion = 02 Then
  127.     'el servo està en dch y tiene que pasar a izq
  128.         For n = 190 To 130 Step -1
  129.             ServoOut servo, n
  130.             WaitMs 100
  131.         Next n
  132.         WaitMs 200
  133.         rojo = 0
  134.         verde = 0
  135.         WaitMs 200
  136.         rojo = 0
  137.         verde = 1
  138.         rele = 0
  139.         Write 01, 03
  140.     Endif
  141.  
  142.     If posicion = 03 Then
  143.     'el servo está en izq y tiene que pasar a dch
  144.         For n = 130 To 190 Step 1
  145.             ServoOut servo, n
  146.             WaitMs 100
  147.         Next n
  148.         WaitMs 200
  149.         rojo = 0
  150.         verde = 0
  151.         WaitMs 200
  152.         rojo = 1
  153.         verde = 0
  154.         rele = 1
  155.         Write 01, 02
  156.     Endif
  157. Return
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 15 de Octubre de 2010, 16:17:43
 :) :)Muchas,muchas gracias, funciona perfectamente.El servo se va al centro y se mantiene hasta que se pulsa el botón.Además el movimiento es muy suave.
He modificado un poco el código para que se posicione en la dch o izq según quedó anteriormente.
Una última cosa.Para que se mueva por ejemplo de 160 a 190  y a poca velocidad ¿se puede mejorar el código que tengo?


For n = 160 To 190 Step 1
ServoOut servo, n
WaitMs 100
Next n





Código: [Seleccionar]
'
Trabajando con servos, PIC12F629
Define CONF_WORD = 0x3184
Define CLOCK_FREQUENCY = 4
AllDigital  'todos los pines digitales
Symbol rele = GPIO.0  'define los pines entradas/salidas
Symbol rojo = GPIO.1
Symbol verde = GPIO.2
Symbol progr = GPIO.3
Symbol boton = GPIO.4
Symbol servo = GPIO.5
TRISIO = %011000
'define variables
Dim velocidad As Byte
Dim n As Byte
Dim posicion As Byte
Dim angulo As Byte
Dim angulo1 As Byte
Dim outon As Byte  'Tiempo de la señal de control del servo a On (duty cycle)
Dim outoff As Word  'Tiempo de la señal de control del servo a Off
Dim periodo As Word  'Periodo de la frecuencia de trabajo de la señal de control del servo
'posiciona el servo en su sitio cuando se conecta la alimentación
'conecta los leds según la posición y el relè
rojo = 0
verde = 0
rele = 0
servo = 0
periodo = 2000  '20mSeg., para servos de 50Hz, señal a On mas señal a Off = 20mSeg.
'outon = 160  '1.6mSeg.
'outoff = (periodo - outon) * 10  'Calculo tiempo de la señal a Off en uSeg.
'For n = 0 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
'ServoOut servo, outon  '1.6mSeg. (señal a On)
'WaitUs outoff  'Tiempo de la señal a Off
'Next n

Read 01, posicion
If posicion = 0xff Or posicion = 01 Then
Write 01, 01
outon = 160  '1.6mSeg.
outoff = (periodo - outon) * 10  'Calculo tiempo de la señal a Off en uSeg.
For n = 0 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
ServoOut servo, outon  '1.6mSeg. (señal a On)
WaitUs outoff  'Tiempo de la señal a Off
Next n
WaitMs 200
rojo = 1
verde = 1
rele = 0
Endif


If posicion = 02 Then
outon = 190  '1.9mSeg.
outoff = (periodo - outon) * 10  'Calculo tiempo de la señal a Off en uSeg.
For n = 0 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
ServoOut servo, outon  '1.9mSeg. (señal a On)
WaitUs outoff  'Tiempo de la señal a Off
Next n
WaitMs 200
rojo = 1
verde = 0
rele = 0
Endif

If posicion = 03 Then
outon = 130  '1.3mSeg.
outoff = (periodo - outon) * 10  'Calculo tiempo de la señal a Off en uSeg.
For n = 0 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
ServoOut servo, outon  '1.3mSeg. (señal a On)
WaitUs outoff  'Tiempo de la señal a Off
Next n
WaitMs 200
rojo = 0
verde = 1
rele = 1
Endif

'inicio programa
main:
Read 01, posicion
If progr = 1 Then
WaitMs 200
Gosub pulso
Endif

If boton = 1 Then
WaitMs 200
Gosub mover_servo
Endif

Goto main
End                                               

pulso:
outon = 160  '1.6mSeg.
outoff = (periodo - outon) * 10  'Calculo tiempo de la señal a Off en uSeg.
For n = 0 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
ServoOut servo, outon  '1.6mSeg. (señal a On)
WaitUs outoff  'Tiempo de la señal a Off
Next n
WaitMs 200
rojo = 1
verde = 1
Write 01, 01
Return                                           

'mueve el servo
mover_servo:
Read 01, posicion
If posicion = 01 Then
'el servo està en centro y tiene que pasar a dch
For n = 160 To 190 Step 1
ServoOut servo, n
WaitMs 100
Next n
WaitMs 200
rojo = 0
verde = 0
WaitMs 200

rojo = 1
verde = 0
rele = 1
Write 01, 02
Endif

If posicion = 02 Then
'el servo està en dch y tiene que pasar a izq
For n = 190 To 130 Step -1
ServoOut servo, n
WaitMs 100
Next n
WaitMs 200
rojo = 0
verde = 0
WaitMs 200
rojo = 0
verde = 1
rele = 0
Write 01, 03
Endif

If posicion = 03 Then
'el servo está en izq y tiene que pasar a dch
For n = 130 To 190 Step 1
ServoOut servo, n
WaitMs 100
Next n
WaitMs 200
rojo = 0
verde = 0
WaitMs 200
rojo = 1
verde = 0
rele = 1
Write 01, 02
Endif
Return                                           

Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 16 de Octubre de 2010, 01:38:35
Control de velocidad:

Código: vb.net
  1. velocidad = 50  'Velocidad a la que se mueve el servo
  2. For outon = 160 To 190  'De un punto a otro
  3.     outoff = (periodo - outon) * 10  'Calculo tiempo de la senal a Off en uSeg.
  4.     For n = 0 To velocidad 'Control velocidad
  5.         ServoOut servo, outon  'Senal a on
  6.         WaitUs outoff  'Tiempo de la senal a Off
  7.     Next n
  8. Next outon
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 16 de Octubre de 2010, 12:14:32
No tienes por qué trabajar con la función del sistema, puedes crearte la tuya propia:

Código: vb.net
  1. Define CONF_WORD = 0x31c4
  2. Define CLOCK_FREQUENCY = 4
  3. '********************************************************************************
  4. 'NOMBRE: 12F675 Mini-EBasic Trabajando con Servos 1
  5. 'MICRO: PIC12F675, 4Mhz Interno
  6. 'DESCRIPCION: Circuito para hacer practicas con PWM, ADC, RS232 y ICSP
  7. 'FECHA/AUTOR: By COS, 09/07, 16/10
  8. 'Version 1.0
  9. 'Puerto RS232 optoacoplado para depuracion y muestra de datos
  10. 'Programacion del microcontrolador en placa (ICSP)
  11. '********************************************************************************
  12. 'Define SEROUT_DELAYUS = 0
  13. '************* Configuracion modulos generales (E/S) *********
  14. CMCON = 0x07  'comparator off
  15. VRCON = 0x00  'vref off, comparador
  16. ANSEL = %00010100  'fosc/8 (4Mhz=2uSeg.), an2 en mode analogico, resto de pin digitales
  17. ADCON0 = %00001001  'adc a 8bit, vdd reference, adc On
  18. OSCCAL = 68  'calibracion del oscilador interno
  19. TRISIO = 0xff  'tri-state pins, entradas
  20. TRISIO.4 = 0  'GP4 pin, como salida, Tx puerto serie
  21. TRISIO.5 = 0  'GP5 pin, como salida, Control del servomotor
  22. GPIO.5 = 0  'valor inicial a cero
  23. '*********************Configuracion del Timer1*****************************
  24. T1CON.TMR1CS = 0  'bit de seleccion de reloj para el timer1, interno Fosc/4
  25. T1CON.T1CKPS0 = 0  'bit de seleccion del prescaler para el reloj del timer1
  26. T1CON.T1CKPS1 = 0  'bit de seleccion del prescaler para el reloj del timer1
  27. TMR1H = 0xff  'carga el byte alto del registro del tiemr1 (1mSeg)
  28. TMR1L = 0x9c  'carga el byte bajo del registro del timer1 (1mSeg)
  29. 'INTCON.T1IE = 1  'bit de habilitacion de interrupcion de TMR1 por rebose
  30. T1CON.TMR1ON = 1  'bit de habilitacion del temporizador timer1
  31. 'PIE1.TMR1IE = 1  'activa la interrupcion del timer1
  32. '*********************Habilitacion****************************************
  33. 'INTCON.PEIE = 1  'habilitacion de interrupciones de perifericos
  34. 'Enable  'intcon.GIE = 1, habilita las interrupciones generales
  35. '************* Rutina del programa ***************************************
  36. '----Definiciones
  37. '--- Variables
  38. Dim outon As Word
  39. Dim n As Word
  40. main:
  41.     For n = 0 To 75  'Posicion inicial
  42.         Call servo(400, 5)
  43.     Next n
  44.     For outon = 400 To 2250 Step 5  'De un extremo al otro
  45.             Call servo(outon, 5)
  46.     Next outon
  47.     For outon = 2250 To 400 Step -10  'De un extremo al otro
  48.             Call servo(outon, 5)
  49.     Next outon
  50.     For outon = 400 To 2250 Step 50  'De un extremo al otro
  51.             Call servo(outon, 5)
  52.     Next outon
  53.     While n = n  'Servo parado manteniendo la ultima posicion
  54.         Call servo(outon, 5)
  55.     Wend
  56. Goto main
  57. End                                              
  58. 'Mi función para controlar Servos Futaba S3003
  59. 'x = Posición del servo
  60. 'pin = pin de la senal de control del servo
  61. 'Máximo izquierda 2250, minimo derecha 400
  62. '20000uSeg. para servos de 50Hz
  63. Proc servo(x As Word, pin As Byte)
  64.     Const periodo = 20000  'Periodo en uSeg. para servos de 50Hz
  65.     Dim outoff As Word  'Variable local
  66.     outoff = periodo - x  'Calculo de la senal a Off
  67.     If x < 400 Then x = 400  'Máximo derecha
  68.     If x > 2250 Then x = 2250  'Máximo izquierda
  69.     If pin = 0 Then GPIO.0 = 1  '*/ Seleccina pin de control
  70.     If pin = 1 Then GPIO.1 = 1
  71.     If pin = 2 Then GPIO.2 = 1
  72.     If pin = 4 Then GPIO.4 = 1
  73.     If pin = 5 Then GPIO.5 = 1  '*/
  74.     WaitUs x  'Senal de control a On
  75.     If pin = 0 Then GPIO.0 = 0  '*/ Selecciona pin de control
  76.     If pin = 1 Then GPIO.1 = 0
  77.     If pin = 2 Then GPIO.2 = 0
  78.     If pin = 4 Then GPIO.4 = 0
  79.     If pin = 5 Then GPIO.5 = 0  '*/
  80.     WaitUs outoff  'Senal de control a Off
  81. End Proc

Un video con el ejemplo anterior:

Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 17 de Octubre de 2010, 15:44:30
He probado con el código
Código: [Seleccionar]
velocidad = 50  'Velocidad a la que se mueve el servo
For outon = 160 To 190  'De un punto a otro   
outoff = (periodo - outon) * 10  'Calculo tiempo de la senal a Off en uSeg.   
For n = 0 To velocidad 'Control velocidad     
  ServoOut servo, outon  'Senal a on     
  WaitUs outoff  'Tiempo de la senal a Off   
 Next n
Next outon
y los servos se comportan de manera extraña.
Se mueven muy despacio,llega un momento en que dejan de moverse y comienzan a temblar.Parece como si quisieran moverse pero no pueden ,al mismo tiempo los leds y relés comienzan a conectarse y desconectarse.
Estoy usando servos minis.No son de la misma calidad que el futaba que aparece en el vídeo.
Con el código
Código: [Seleccionar]
For n = 160 To 190 Step 1
ServoOut servo, n
WaitMs 100
Next n
Se mueven sin problemas , con un movimiento lento, pero a saltitos.
Si aumento la pausa,se mueven más despacio,pero a saltos más bruscos.
La calidad de los servos que uso no es muy buena,pienso que puede ser por ello.
Un saludo y muchas gracias,me has sido de gran ayuda.
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 17 de Octubre de 2010, 17:42:01
OK, lo he probado con un servo pequeño sin marca, y ajustando los márgenes y bajando el periodo a 15mSeg, funciona bien.

En tu caso:
For n = 160 To 190 Step 1
ServoOut servo, n
WaitMs 100
Next n

100 + n = Periodo muy elevado, fuera de rango, el servo se mueve a saltos y genera ruidos y pierde fuerza.

El mío sin marca y sin datasheet y teniendo en cuenta que está bastante cascado funciona con estos parámetros:
'izq. 2450uSeg. (X), der. 500uSeg. (X), periodo 15mSeg+XmSeg.

Y desconozco con que hardware estas trabajando, si quieres, por pura curiosidad puedes ver el esquema de la Mini-EBasic, que tiene las protecciones
mínimas como para funcionar en casa, en otro tipo de ambiente es posible que se tenga que añadir alguna más.
http://www.todopic.com.ar/foros/index.php?topic=24123.0
http://www.todopic.com.ar/foros/index.php?topic=24123.msg195614#msg195614
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 18 de Octubre de 2010, 06:44:21
Los servos que uso son del siguiente tipo

http://cgi.ebay.com.au/ws/eBayISAPI.dll?ViewItem&item=220592754522

Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 18 de Octubre de 2010, 08:28:44
No se donde puede estar el problema el servo se ve bueno.
http://www.rctoys.com/pdf/hitec-servos/HIT-HS55.pdf
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 18 de Octubre de 2010, 11:56:30
Pues no sé.
He mirado la electrónica un montón de veces. No encuentro donde puede estar el fallo. Una duda que tengo es que uso un 7805 para 4 leds,4 relés 4 pic y 4 servos. Que la fuente no sea suficiente para alimentar al circuito.
Lo que no acabo de entender es el control de la velocidad. Por la web aparecen páginas que explican el posicionamiento del servo ,pero no he encontrado nada que me sirva para la velocidad.
Si no he entendido mal , la separación entre pulsos 20mseg. Es decir el tiempo a on+el tiempo a off=20mseg.
que es lo que hace el código:

For n = 0 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
 ServoOut servo, outon  '1.6mSeg. (señal a On)
 WaitUs outoff  'Tiempo de la señal a Off
Next n

repitiéndose varias veces para dar tiempo al servo a posicionarse.
Pero, el  control de velocidad no lo veo. ¿alguna página en donde aparezca explicado?
Muchas gracias
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 18 de Octubre de 2010, 16:34:08
Pues casi seguro que tengo un problema con la fuente de alimentación.En un momento hice una con un 7805 y un par de condensadores y funciona sin ningún problema.Los servos se han movido con bastante suavidad aplicando tu código. Voy a hacer otra.
Ya entiendo como se controla la velocidad.
Muchas gracias por tu ayuda.
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 18 de Octubre de 2010, 19:10:21
Parece que ya dominas la técnica, pero de todas formas:

For n = 0 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
 ServoOut servo, outon  '1.6mSeg. (señal a On)
 WaitUs outoff  'Tiempo de la señal a Off
Next n

Esto está basado en que cuando envías una posición al servo el no la memoriza, y tienes que ir repitiéndola hasta que llegue a ella. Este tiene que hacer un recorrido que le llevara un tiempo, por esto se repite la misma orden hasta que llega a la posición deseada.
Según el bucle anterior:
En el caso del ejemplo 1.6mSeg + 18.4mSeg. = 20mSg. * 75 veces se repite el bucle = 1500mSeg., en realidad esta equivocado es * 76 ya que el cero se cuenta 1520mSeg. De esto deducimos que durante 1520mSeg. estaremos enviando la misma orden al servo, para que le dé tiempo a llegar a su posición, realmente no deberíamos parar de enviar la posición ya que si paramos, el servo se desconecta y queda flojo, solo con la fuerza que oponen sus mecanismos internos al giro, en el caso de querer obtener toda su potencia hay que mantener la trama de control de forma permanente, de esta manera si ejercemos fuerza exterior para moverlo, el servo, se opondrá a ser movido absorbiendo corriente, proporcionalmente a la fuerza que ejerza el mecanismo exterior que controla.

PD: Es cierto, no he visto ninguna rutina de control de velocidad en la red.

Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 01 de Enero de 2011, 19:16:06
Sigo intentando mejorar el programa.He añadido otro pulsador más. Uno aumenta el recorrido del servo ,el otro lo disminuye. además el recorrido a dch e izq se puede ajustar independientemente. Al probarlo en proteus va bien, cuando lo paso a la placa que tengo hace cosas raras. Sí aumento y disminuyo el ángulo del servo pero después no se mueve bien.
Os dejo los ficheros por si podéis hacer algo.
Un saludo
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 02 de Enero de 2011, 10:28:54
Es un programa demasiado extenso como para que lo pueda verificar sin correrlo sobre el hard. De todas formas en las rutinas tipo “ETIQUETA/RETURN”  no se puede salir de ellas usando “GOTO” hay que salir utilizando “RETURN”, de otra manera saturamos el stack del micro y hace cosas raras, a esto se le llama fallo por “HARDWARE STACK OVERFLOW”. De todas formas los “GOTOS” en los lenguajes de alto nivel no es recomendable su uso. Solo se utiliza una sola vez para mantener el bucle infinito en la rutina principal de programa.

Otro tema es que repetiste nombres en el código y no podía compilar.

De todas formas te recomiendo que primero lo simules en el Pic Simulator IDE, con la opción saltar los Wait en el programa y luego configuras el PSI con Ultímate y deshabilitas el Track del editor, esto acelera mucho la simulación. El PSI suele mostrar fácilmente los fallos de este tipo.

Código: vb.net
  1. 'Trabajando con servos, PIC12F629
  2. Define CONF_WORD = 0x3184
  3. Define CLOCK_FREQUENCY = 4
  4. Define SIMULATION_WAITMS_VALUE = 1  'suprime los tiempos de espera Waitms, solo activar esta linea en simulacion
  5. AllDigital
  6. Symbol mass = GPIO.0
  7. Symbol rojo = GPIO.1
  8. Symbol verde = GPIO.2
  9. Symbol menoss = GPIO.3
  10. Symbol boton = GPIO.4
  11. Symbol servos = GPIO.5
  12. TRISIO = %011001
  13. 'define variables
  14. Dim velocidad As Byte
  15. velocidad = 3
  16. Dim n As Byte
  17. Dim posicion As Byte  '1 centro 2-dch 3-izq posicion servo
  18. Dim pulso_dch As Byte  'angulo dch servo
  19. Dim pulso_izq As Byte  'angulo izq servo
  20. Dim pulso_dch1 As Byte
  21. Dim pulso_izq1 As Byte
  22. Dim outon As Byte  'Tiempo de la señal de control del servo a On (duty cycle)
  23. Dim outon1 As Byte
  24. 'Dim outoff As Word
  25. 'Dim periodo As Word
  26. Gosub leer
  27. rojo = 0
  28. verde = 0
  29. servos = 0
  30. '###################################################################################################
  31. 'posiciona los servos como habían quedado
  32. If posicion = 0xff Or posicion = 01 Then  'el servo está en el centro o se conecta la primera vez
  33.         'mueve el servo al centro e inicializa variables
  34.         posicion = 01
  35.         Write 01, posicion
  36.         pulso_dch = 155
  37.         Write 03, pulso_dch
  38.         pulso_izq = 155
  39.         Write 04, pulso_izq
  40.         Call servo_inicio(pulso_dch)
  41.         rojo = 1
  42.         verde = 1
  43. Endif
  44. If posicion = 02 Then
  45.         Call servo_inicio(pulso_dch)
  46.         rojo = 1
  47.         verde = 0
  48. Endif
  49. If posicion = 03 Then
  50.         Call servo_inicio(pulso_izq)
  51.         rojo = 0
  52.         verde = 1
  53. Endif
  54. '####################################################################################################
  55. 'inicio programa
  56. main:
  57.         Gosub leer
  58.         If mass = 1 Then
  59.                 WaitMs 200
  60.                 Gosub mas
  61.         Endif
  62.  
  63.         If menoss = 1 Then
  64.                 WaitMs 200
  65.                 Gosub menos
  66.         Endif
  67.  
  68.         If boton = 1 Then
  69.                 WaitMs 400
  70.                 Gosub mover_servo
  71.         Endif
  72. Goto main
  73. End                                              
  74. '###################################################################################################
  75. mas:
  76.         Gosub leer
  77.         Select Case posicion
  78.                 Case 01
  79.                         pulso_dch1 = pulso_dch + 1
  80.                         If pulso_dch1 > 210 Then
  81.                                 pulso_dch = 155
  82.                                 pulso_dch1 = pulso_dch + 1
  83.                                 WaitMs 1000
  84.                                 verde = 1
  85.                                 rojo = 1
  86.                         Endif
  87.                         Call servo3(pulso_dch, pulso_dch1)
  88.                         pulso_dch = pulso_dch1
  89.                         Write 03, pulso_dch
  90.                 Case 02
  91.                         pulso_dch1 = pulso_dch + 1
  92.                         If pulso_dch1 > 210 Then
  93.                                 pulso_dch = 155
  94.                                 pulso_dch1 = pulso_dch + 1
  95.                                 WaitMs 1000
  96.                                 verde = 1
  97.                                 rojo = 1
  98.                         Endif
  99.                         Call servo3(pulso_dch, pulso_dch1)
  100.                         pulso_dch = pulso_dch1
  101.                         Write 03, pulso_dch
  102.                 Case 03
  103.                         pulso_izq1 = pulso_izq - 1
  104.                         If pulso_izq1 < 100 Then
  105.                                 pulso_izq = 155
  106.                                 pulso_izq1 = pulso_izq - 1
  107.                                 WaitMs 1000
  108.                                 verde = 1
  109.                                 rojo = 1
  110.                         Endif
  111.                         Call servo4(pulso_izq, pulso_izq1)
  112.                         pulso_izq = pulso_izq1
  113.                         Write 04, pulso_izq
  114.         EndSelect
  115. Return                                            
  116. menos:
  117.         Gosub leer
  118.         Select Case posicion
  119.                 Case 01
  120.                         pulso_dch1 = pulso_dch - 1
  121.                         If pulso_dch1 < 155 Then
  122.                                 pulso_dch = 155
  123.                                 pulso_dch1 = pulso_dch + 1
  124.                                 WaitMs 1000
  125.                                 verde = 1
  126.                                 rojo = 1
  127.                         Endif
  128.                         Call servo4(pulso_dch, pulso_dch1)
  129.                         pulso_dch = pulso_dch1
  130.                         Write 03, pulso_dch
  131.                 Case 02
  132.                         pulso_dch1 = pulso_dch - 1
  133.                         If pulso_dch1 < 155 Then
  134.                                 pulso_dch = 155
  135.                                 pulso_dch1 = pulso_dch + 1
  136.                                 WaitMs 1000
  137.                                 verde = 1
  138.                                 rojo = 1
  139.                         Endif
  140.                         Call servo4(pulso_dch, pulso_dch1)
  141.                         pulso_dch = pulso_dch1
  142.                         Write 03, pulso_dch
  143.                 Case 03
  144.                         pulso_izq1 = pulso_izq + 1
  145.                         If pulso_izq1 > 155 Then
  146.                                 pulso_izq = 155
  147.                                 pulso_izq1 = pulso_izq - 1
  148.                                 WaitMs 1000
  149.                                 verde = 1
  150.                                 rojo = 1
  151.                         Endif
  152.                         Call servo3(pulso_izq, pulso_izq1)
  153.                         pulso_izq = pulso_izq1
  154.                         Write 04, pulso_izq
  155.         EndSelect
  156. Return                                            
  157. '####################################################################
  158. 'mueve el servo
  159. mover_servo:
  160.         Gosub leer
  161.         If posicion = 01 Then
  162.         'el servo està en centro y tiene que pasar a dch
  163.                 Call servo(155, pulso_dch, velocidad)
  164.                 servos = 0
  165.                 rojo = 0
  166.                 verde = 0
  167.                 WaitMs 200
  168.                 rojo = 1
  169.                 verde = 0
  170.                 boton = 0
  171.                 posicion = 02
  172.                 Write 01, posicion
  173.                 Goto main  'NO SE PUEDE SALIR DE UN ETIQUETA/RETURN CON GOTO HAY QUE SALIR CON RETURN
  174.         Endif
  175.         If posicion = 02 Then
  176.         'el servo està en dch y tiene que pasar a izq
  177.                 Call servo1(pulso_dch, pulso_izq, velocidad)
  178.                 servos = 0
  179.                 rojo = 0
  180.                 verde = 0
  181.                 WaitMs 200
  182.                 rojo = 0
  183.                 verde = 1
  184.                 boton = 0
  185.                 posicion = 03
  186.                 Write 01, posicion
  187.                 Goto main  'NO SE PUEDE SALIR DE UN ETIQUETA/RETURN CON GOTO HAY QUE SALIR CON RETURN
  188.         Endif
  189.         If posicion = 03 Then
  190.         'el servo está en izq y tiene que pasar a dch
  191.                 Call servo(pulso_izq, pulso_dch, velocidad)
  192.                 servos = 0
  193.                 rojo = 0
  194.                 verde = 0
  195.                 WaitMs 200
  196.                 rojo = 1
  197.                 verde = 0
  198.                 boton = 0
  199.                 Write 01, 02
  200.                 Goto main  'NO SE PUEDE SALIR DE UN ETIQUETA/RETURN CON GOTO HAY QUE SALIR CON RETURN
  201.         Endif
  202. Return                                            
  203. leer:
  204.         Read 01, posicion
  205.         Read 03, pulso_dch
  206.         Read 04, pulso_izq
  207. Return                                            
  208. '################################################################
  209. 'procedimiento para mover servo con control velocidad
  210. Proc servo(x1 As Byte, y1 As Byte, velocidad As Byte)
  211.         Const periodo = 20000  'Periodo en uSeg. para servos de 50Hz
  212.         Dim outoff As Word  'Variable local
  213.         For outon = x1 To y1
  214.                 outoff = (periodo - x1) * 10  'Calculo tiempo de la señal a Off en uSeg.
  215.                 For n = 0 To velocidad  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
  216.                         ServoOut servos, outon  '1.6mSeg. (señal a On)
  217.                         WaitUs outoff  'Tiempo de la señal a Off
  218.                 Next n
  219.         Next outon
  220. End Proc                                          
  221. '#################################################################
  222. 'procedimiento para mover servo con boton mas
  223. Proc servo3(x2 As Byte, y2 As Byte)
  224.         For n = x2 To y2
  225.                 ServoOut servos, n
  226.                 WaitMs 4
  227.         Next n
  228. End Proc                                          
  229. '##################################################################
  230. 'procedimiento para mover servo con boton menos
  231. Proc servo4(x3 As Byte, y3 As Byte)
  232.         For n = x3 To y3 Step -1
  233.                 ServoOut servos, n
  234.                 WaitMs 4
  235.         Next n
  236. End Proc                                          
  237. '################################################################
  238. 'procedimiento para mover servo con control velocidad en sentido negativo
  239. Proc servo1(x4 As Byte, y4 As Byte, velocidad As Byte)
  240.         Const periodo1 = 20000  'Periodo en uSeg. para servos de 50Hz
  241.         Dim outoff1 As Word  'Variable local
  242.         For outon = x4 To y4 Step -1
  243.                 outoff1 = (periodo1 - x4) * 10  'Calculo tiempo de la señal a Off en uSeg.
  244.                 For n = 0 To velocidad  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
  245.                         ServoOut servos, outon  '1.6mSeg. (señal a On)
  246.                         WaitUs outoff1  'Tiempo de la señal a Off
  247.                 Next n
  248.         Next outon
  249. End Proc                                          
  250. Proc servo_inicio(x5 As Byte)
  251.         Const periodo2 = 20000
  252.         Dim outoff2 As Word
  253.         outon = x5
  254.         outoff2 = (periodo2 - outon) * 10  'Calculo tiempo de la señal a Off en uSeg.
  255.         For n = 1 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
  256.                 ServoOut servos, outon  '1.6mSeg. (señal a On)
  257.                 WaitUs outoff2  'Tiempo de la señal a Off
  258.         Next n
  259. End Proc
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 02 de Enero de 2011, 15:20:12
Los goto main es para que el programa vuelva a la rutina principal.No sé por qué no vuelve y el servo se mueve primero para un lado, después para el otro y a continuación se mantiene fijo ,con sólo apretar una vez el boton.En teoría debería moverse para un lado al pulsar,mantenerse ,pulsar , moverse para el otro y mantenerse. En teoría la rutina mover_servo termina con un return y debería pasar a main.Pero parece que vuelve a entrar en ella otra vez
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 02 de Enero de 2011, 15:52:38
Primero corregir el error y luego seguir buscando fallos:

Código: vb.net
  1. 'Trabajando con servos, PIC12F629
  2. Define CONF_WORD = 0x3184
  3. Define CLOCK_FREQUENCY = 4
  4. 'Define SIMULATION_WAITMS_VALUE = 1  'suprime los tiempos de espera Waitms, solo activar esta linea en simulacion
  5. AllDigital
  6. Symbol mass = GPIO.0
  7. Symbol rojo = GPIO.1
  8. Symbol verde = GPIO.2
  9. Symbol menoss = GPIO.3
  10. Symbol boton = GPIO.4
  11. Symbol servos = GPIO.5
  12. TRISIO = %011001
  13. 'define variables
  14. Dim velocidad As Byte
  15. velocidad = 3
  16. Dim n As Byte
  17. Dim posicion As Byte  '1 centro 2-dch 3-izq posicion servo
  18. Dim pulso_dch As Byte  'angulo dch servo
  19. Dim pulso_izq As Byte  'angulo izq servo
  20. Dim pulso_dch1 As Byte
  21. Dim pulso_izq1 As Byte
  22. Dim outon As Byte  'Tiempo de la señal de control del servo a On (duty cycle)
  23. Dim outon1 As Byte
  24. 'Dim outoff As Word
  25. 'Dim periodo As Word
  26. Gosub leer
  27. rojo = 0
  28. verde = 0
  29. servos = 0
  30. '###################################################################################################
  31. 'posiciona los servos como habían quedado
  32. If posicion = 0xff Or posicion = 01 Then  'el servo está en el centro o se conecta la primera vez
  33.         'mueve el servo al centro e inicializa variables
  34.         posicion = 01
  35.         Write 01, posicion
  36.         pulso_dch = 155
  37.         Write 03, pulso_dch
  38.         pulso_izq = 155
  39.         Write 04, pulso_izq
  40.         Call servo_inicio(pulso_dch)
  41.         rojo = 1
  42.         verde = 1
  43. Endif
  44. If posicion = 02 Then
  45.         Call servo_inicio(pulso_dch)
  46.         rojo = 1
  47.         verde = 0
  48. Endif
  49. If posicion = 03 Then
  50.         Call servo_inicio(pulso_izq)
  51.         rojo = 0
  52.         verde = 1
  53. Endif
  54. '####################################################################################################
  55. 'inicio programa
  56. main:
  57.         Gosub leer
  58.         If mass = 1 Then
  59.                 WaitMs 200
  60.                 Gosub mas
  61.         Endif
  62.  
  63.         If menoss = 1 Then
  64.                 WaitMs 200
  65.                 Gosub menos
  66.         Endif
  67.  
  68.         If boton = 1 Then
  69.                 WaitMs 400
  70.                 Gosub mover_servo
  71.         Endif
  72. Goto main
  73. End                                              
  74. '###################################################################################################
  75. mas:
  76.         Gosub leer
  77.         Select Case posicion
  78.                 Case 01
  79.                         pulso_dch1 = pulso_dch + 1
  80.                         If pulso_dch1 > 210 Then
  81.                                 pulso_dch = 155
  82.                                 pulso_dch1 = pulso_dch + 1
  83.                                 WaitMs 1000
  84.                                 verde = 1
  85.                                 rojo = 1
  86.                         Endif
  87.                         Call servo3(pulso_dch, pulso_dch1)
  88.                         pulso_dch = pulso_dch1
  89.                         Write 03, pulso_dch
  90.                 Case 02
  91.                         pulso_dch1 = pulso_dch + 1
  92.                         If pulso_dch1 > 210 Then
  93.                                 pulso_dch = 155
  94.                                 pulso_dch1 = pulso_dch + 1
  95.                                 WaitMs 1000
  96.                                 verde = 1
  97.                                 rojo = 1
  98.                         Endif
  99.                         Call servo3(pulso_dch, pulso_dch1)
  100.                         pulso_dch = pulso_dch1
  101.                         Write 03, pulso_dch
  102.                 Case 03
  103.                         pulso_izq1 = pulso_izq - 1
  104.                         If pulso_izq1 < 100 Then
  105.                                 pulso_izq = 155
  106.                                 pulso_izq1 = pulso_izq - 1
  107.                                 WaitMs 1000
  108.                                 verde = 1
  109.                                 rojo = 1
  110.                         Endif
  111.                         Call servo4(pulso_izq, pulso_izq1)
  112.                         pulso_izq = pulso_izq1
  113.                         Write 04, pulso_izq
  114.         EndSelect
  115. Return                                            
  116. menos:
  117.         Gosub leer
  118.         Select Case posicion
  119.                 Case 01
  120.                         pulso_dch1 = pulso_dch - 1
  121.                         If pulso_dch1 < 155 Then
  122.                                 pulso_dch = 155
  123.                                 pulso_dch1 = pulso_dch + 1
  124.                                 WaitMs 1000
  125.                                 verde = 1
  126.                                 rojo = 1
  127.                         Endif
  128.                         Call servo4(pulso_dch, pulso_dch1)
  129.                         pulso_dch = pulso_dch1
  130.                         Write 03, pulso_dch
  131.                 Case 02
  132.                         pulso_dch1 = pulso_dch - 1
  133.                         If pulso_dch1 < 155 Then
  134.                                 pulso_dch = 155
  135.                                 pulso_dch1 = pulso_dch + 1
  136.                                 WaitMs 1000
  137.                                 verde = 1
  138.                                 rojo = 1
  139.                         Endif
  140.                         Call servo4(pulso_dch, pulso_dch1)
  141.                         pulso_dch = pulso_dch1
  142.                         Write 03, pulso_dch
  143.                 Case 03
  144.                         pulso_izq1 = pulso_izq + 1
  145.                         If pulso_izq1 > 155 Then
  146.                                 pulso_izq = 155
  147.                                 pulso_izq1 = pulso_izq - 1
  148.                                 WaitMs 1000
  149.                                 verde = 1
  150.                                 rojo = 1
  151.                         Endif
  152.                         Call servo3(pulso_izq, pulso_izq1)
  153.                         pulso_izq = pulso_izq1
  154.                         Write 04, pulso_izq
  155.         EndSelect
  156. Return                                            
  157. '####################################################################
  158. 'mueve el servo
  159. mover_servo:
  160.         Gosub leer
  161.         If posicion = 01 Then
  162.         'el servo està en centro y tiene que pasar a dch
  163.                 Call servo(155, pulso_dch, velocidad)
  164.                 servos = 0
  165.                 rojo = 0
  166.                 verde = 0
  167.                 WaitMs 200
  168.                 rojo = 1
  169.                 verde = 0
  170.                 boton = 0
  171.                 posicion = 02
  172.                 Write 01, posicion
  173.                 Return  'goto main  'NO SE PUEDE SALIR DE UN ETIQUETA/RETURN CON GOTO HAY QUE SALIR CON RETURN
  174.         Endif
  175.         If posicion = 02 Then
  176.         'el servo està en dch y tiene que pasar a izq
  177.                 Call servo1(pulso_dch, pulso_izq, velocidad)
  178.                 servos = 0
  179.                 rojo = 0
  180.                 verde = 0
  181.                 WaitMs 200
  182.                 rojo = 0
  183.                 verde = 1
  184.                 boton = 0
  185.                 posicion = 03
  186.                 Write 01, posicion
  187.                 Return  'goto main  'NO SE PUEDE SALIR DE UN ETIQUETA/RETURN CON GOTO HAY QUE SALIR CON RETURN
  188.         Endif
  189.         If posicion = 03 Then
  190.         'el servo está en izq y tiene que pasar a dch
  191.                 Call servo(pulso_izq, pulso_dch, velocidad)
  192.                 servos = 0
  193.                 rojo = 0
  194.                 verde = 0
  195.                 WaitMs 200
  196.                 rojo = 1
  197.                 verde = 0
  198.                 boton = 0
  199.                 Write 01, 02
  200.                 Return  'goto main  'NO SE PUEDE SALIR DE UN ETIQUETA/RETURN CON GOTO HAY QUE SALIR CON RETURN
  201.         Endif
  202. Return                                            
  203. leer:
  204.         Read 01, posicion
  205.         Read 03, pulso_dch
  206.         Read 04, pulso_izq
  207. Return                                            
  208. '################################################################
  209. 'procedimiento para mover servo con control velocidad
  210. Proc servo(x1 As Byte, y1 As Byte, velocidad As Byte)
  211.         Const periodo = 20000  'Periodo en uSeg. para servos de 50Hz
  212.         Dim outoff As Word  'Variable local
  213.         For outon = x1 To y1
  214.                 outoff = (periodo - x1) * 10  'Calculo tiempo de la señal a Off en uSeg.
  215.                 For n = 0 To velocidad  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
  216.                         ServoOut servos, outon  '1.6mSeg. (señal a On)
  217.                         WaitUs outoff  'Tiempo de la señal a Off
  218.                 Next n
  219.         Next outon
  220. End Proc                                          
  221. '#################################################################
  222. 'procedimiento para mover servo con boton mas
  223. Proc servo3(x2 As Byte, y2 As Byte)
  224.         For n = x2 To y2
  225.                 ServoOut servos, n
  226.                 WaitMs 4
  227.         Next n
  228. End Proc                                          
  229. '##################################################################
  230. 'procedimiento para mover servo con boton menos
  231. Proc servo4(x3 As Byte, y3 As Byte)
  232.         For n = x3 To y3 Step -1
  233.                 ServoOut servos, n
  234.                 WaitMs 4
  235.         Next n
  236. End Proc                                          
  237. '################################################################
  238. 'procedimiento para mover servo con control velocidad en sentido negativo
  239. Proc servo1(x4 As Byte, y4 As Byte, velocidad As Byte)
  240.         Const periodo1 = 20000  'Periodo en uSeg. para servos de 50Hz
  241.         Dim outoff1 As Word  'Variable local
  242.         For outon = x4 To y4 Step -1
  243.                 outoff1 = (periodo1 - x4) * 10  'Calculo tiempo de la señal a Off en uSeg.
  244.                 For n = 0 To velocidad  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
  245.                         ServoOut servos, outon  '1.6mSeg. (señal a On)
  246.                         WaitUs outoff1  'Tiempo de la señal a Off
  247.                 Next n
  248.         Next outon
  249. End Proc                                          
  250. Proc servo_inicio(x5 As Byte)
  251.         Const periodo2 = 20000
  252.         Dim outoff2 As Word
  253.         outon = x5
  254.         outoff2 = (periodo2 - outon) * 10  'Calculo tiempo de la señal a Off en uSeg.
  255.         For n = 1 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
  256.                 ServoOut servos, outon  '1.6mSeg. (señal a On)
  257.                 WaitUs outoff2  'Tiempo de la señal a Off
  258.         Next n
  259. End Proc                                          
  260. 'End
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 02 de Enero de 2011, 18:48:34
He modificado el código corrigiendo errores. No lo he simulado. Lo he pasado a la electrónica y parece que funciona.Si lo quieres simular y observas alguna cosa lo vuelvo a corregir.
Muchas gracias por tu ayuda y paciencia.

Código: [Seleccionar]
'Trabajando con servos, PIC12F629
Define CONF_WORD = 0x3184
Define CLOCK_FREQUENCY = 4
AllDigital
Symbol menos = GPIO.0
Symbol rojo = GPIO.1
Symbol verde = GPIO.2
Symbol mas = GPIO.3
Symbol boton = GPIO.4
Symbol servo = GPIO.5
TRISIO = %011001
'#########################################################################
'define variables
Dim velocidad As Byte
Dim n As Byte
Dim p1 As Byte
Dim p2 As Byte
Dim p3 As Byte
Dim p4 As Byte
Dim posicion As Byte  '1 centro 2-dch 3-izq posicion servo
Dim pulso_dch As Byte  'angulo dch servo
Dim pulso_izq As Byte  'angulo izq servo
Dim pulso_dch1 As Byte
Dim pulso_dch_1 As Byte
Dim pulso_izq1 As Byte
Dim outon As Byte  'Tiempo de la señal de control del servo a On (duty cycle)
Dim outon1 As Byte
Dim outoff As Word
Dim periodo As Word
Dim off1 As Word
Dim off2 As Word
Dim off3 As Word
Dim off4 As Word
'##########################################################################
Gosub leer
rojo = 0
verde = 0
servo = 0
periodo = 2000
If posicion = 0xff Or posicion = 01 Then  'el servo está en el centro o se conecta la primera vez
'mueve el servo al centro e inicializa variables
posicion = 01
Write 01, posicion
pulso_dch = 155
Write 03, pulso_dch
pulso_izq = 155
Write 04, pulso_izq
Call servo_inicio(pulso_dch)
servo = 0
rojo = 1
verde = 1
Endif


If posicion = 02 Then
Call servo_inicio(pulso_dch)
servo = 0
rojo = 1
verde = 0
Endif

If posicion = 03 Then
Call servo_inicio(pulso_izq)
servo = 0
rojo = 0
verde = 1
Endif
'######################################################
'inicio programa
main:
Read 01, posicion
Read 03, pulso_dch
Read 04, pulso_izq
'#####################################################
'si se pulsa el boton aumentar ángulo
If mas = 1 Then
WaitMs 250
Gosub leer

If posicion = 01 Or posicion = 02 Then
p1 = pulso_dch + 1
If p1 > 210 Then
pulso_dch = 155
p1 = pulso_dch + 1
WaitMs 1000
verde = 1
rojo = 1
Endif
For n = pulso_dch To p1
off1 = (2000 - n) * 10
ServoOut servo, n
WaitUs off1
Next n
pulso_dch = p1
Write 03, pulso_dch
Endif

If posicion = 03 Then
p2 = pulso_izq - 1
If p2 < 100 Then
pulso_izq = 155
p2 = pulso_izq - 1
WaitMs 1000
verde = 1
rojo = 1
Endif
For n = pulso_izq To p2 Step -1
off2 = (2000 - n) * 10
ServoOut servo, n
WaitUs off2
Next n
pulso_izq = p2
Write 04, pulso_izq
Endif

Endif
'############################################################
'si se pulsa el boton disminuir ángulo
If menos = 1 Then
WaitMs 250

If posicion = 01 Or posicion = 02 Then
p3 = pulso_dch - 1
If p3 < 155 Then
pulso_dch = 155
p3 = 155
WaitMs 1000
verde = 1
rojo = 1
Endif
For n = pulso_dch To p3 Step -1
off3 = (2000 - n) * 10
ServoOut servo, n
WaitUs off3
Next n
pulso_dch = p3
Write 03, pulso_dch
Endif

If posicion = 3 Then
p4 = pulso_izq + 1
If p4 > 155 Then
pulso_izq = 155
p4 = 155
WaitMs 1000
verde = 1
rojo = 1
Endif
For n = pulso_izq To p4
off4 = (2000 - n) * 10
ServoOut servo, n
WaitUs off3
Next n
pulso_izq = p4
Write 04, pulso_izq
Endif
Endif

'#######################################################
'si se pulsa el boón mover servo
If boton = 1 Then
WaitMs 400
Gosub mover_servo
Endif

Goto main
End                                               

'###################################################
'mueve el servo
mover_servo:
Gosub leer
If posicion = 01 Then
Call servo_directo(155, pulso_dch)
servo = 0
rojo = 0
verde = 0
WaitMs 200
rojo = 1
verde = 0
boton = 0
posicion = 02
Write 01, posicion
Return                                           
Endif

If posicion = 02 Then
'el servo està en dch y tiene que pasar a izq
Call servo_inverso(pulso_dch, pulso_izq)
servo = 0
rojo = 0
verde = 0
WaitMs 200
rojo = 0
verde = 1
boton = 0
posicion = 03
Write 01, posicion
Return                                           
Endif

If posicion = 03 Then
Call servo_directo(pulso_izq, pulso_dch)
'el servo está en izq y tiene que pasar a dch
servo = 0
rojo = 0
verde = 0
WaitMs 200
rojo = 1
verde = 0
boton = 0
Write 01, 02
Return                                           
Endif
Return                                           


leer:
Read 01, posicion
Read 03, pulso_dch
Read 04, pulso_izq
Return                                           


Proc servo_inicio(x As Byte)
Const periodo1 = 2000
Dim outoff1 As Word
outoff1 = (periodo1 - x) * 10  'Calculo tiempo de la señal a Off en uSeg.
For n = 1 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
ServoOut servo, x  '1.6mSeg. (señal a On)
WaitUs outoff1  'Tiempo de la señal a Off
Next n
End Proc                                         


Proc servo_directo(x1 As Byte, y1 As Byte)
Const velocidad2 = 3  'Velocidad a la que se mueve el servo
Const periodo2 = 2000
Dim outoff2 As Word
Dim outon_2 As Byte
For outon_2 = x1 To y1  'De un punto a otro
outoff2 = (periodo2 - outon_2) * 10  'Calculo tiempo de la senal a Off en uSeg.
For n = 0 To velocidad2  'Control velocidad
ServoOut servo, outon_2  'Senal a on
WaitUs outoff2  'Tiempo de la senal a Off
Next n
Next outon_2
End Proc                                         


Proc servo_inverso(x2 As Byte, y2 As Byte)
Const velocidad3 = 3  'Velocidad a la que se mueve el servo
Const periodo3 = 2000
Dim outoff3 As Word
Dim outon_3 As Byte
For outon_3 = x2 To y2 Step -1  'De un punto a otro
outoff3 = (periodo3 - outon_3) * 10  'Calculo tiempo de la senal a Off en uSeg.
For n = 0 To velocidad3  'Control velocidad
ServoOut servo, outon_3  'Senal a on
WaitUs outoff3  'Tiempo de la senal a Off
Next n
Next outon_3
End Proc                                         



Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 04 de Enero de 2011, 09:21:25
Estoy intentando probar el programa en un 16f628.Es la primera vez que uso un micro de 18 patitas en el programador JDM que tengo. Cuando leo el pic me aparece todo 3FFF. ¿no debería de aparecer en alguna posición el valor de oscal (como sucede con un 12f628)  para usar el oscilador interno?
Pienso que igual tengo mal el programador
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 04 de Enero de 2011, 09:29:51
Es posible que este micro no tenga ese valor, en la mayoría de los PIC no se necesita hacer la corrección porque el oscilador es muy estable, sobre el 2% o menor. Pero en todos se permite hacer la corrección.
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 04 de Enero de 2011, 10:15:40
Vaya ,pues me parece que estoy liado con la configuración  del micro en el pic simulador y en el icprog.
En pic simulador tengo RA5/digital -----Oscilator intrc ¿es correcto?
En ic-prog cuando cargo el fichero me aparece el mensaje de "el fichero no contiene un valor de id para el dispositivo" el mismo que cuando cargo programas para los 12f,por eso pensaba que se necesitaba un valor y que si no se ponía se estropeaba el micro.O sea ¿puedo grabar aunque aparezca este mensaje?
Un saludo
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 04 de Enero de 2011, 13:00:41
Lo del oscilador es correcto y el mensaje que te da el IC-PROG, pues ni idea, porque no lo he utilizado en la vida.
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 04 de Enero de 2011, 14:35:10
Pues en algunos programadores la patita 10 del 16f628 la hay que dejar sin conectar.
Al hacerlo así y arrancar winpic me ha detectado inmediatamente el pic.
De momento el programa no funciona, pero eso es otro tema.
Un saludo
Título: Re: Control servos con pic simulador
Publicado por: dogflu66 en 04 de Enero de 2011, 21:04:57
Pues te dejo el enlace para que puedas ver como programo mis micros, utilizo la forma clasica con cinco pin: Vdd, Vss, Data, Clock y Vpp.

http://www.pickey.es/programador_pic.html
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 11 de Enero de 2011, 13:02:19
Excelente programador. En cuanto denga tiempo hago la entrenadora.
Ya sé solucioné el problema con el 16f628. La fuente de alimentación daba poca potencia. He probado con otra y funciona perfectamente. Lo único quitar la patita 10 al programar.
un saludo
Título: Re: Control servos con pic simulador
Publicado por: fco1306 en 21 de Febrero de 2011, 18:22:26
Intento mejorar el programa.Un par de cuestiones
Para leer la posición de un servo ¿se utiliza servoin?
¿Es posible hacer que un servo gire y cuando la fuerza que tenga que hacer pase de un valor se pare?