Autor Tema: :: PWM :: CCS :: PIC18F2550 :: SERVOS::  (Leído 25731 veces)

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

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #45 en: 15 de Agosto de 2012, 19:19:52 »

cuando entra en el timer 0  que haces primero:
 activar el timer1 y  empezar a contar tiempo en alto
o activar de nuevo el timer 0


  Lo primero es activar la salida correspondiente.
  Luego activar el timer1
  Precargar nuevamente el valor del timer0
  Incrementar el contador de salida.


¿es posible saber cuanto timepo dura cada intrucción?
y en base a eso recarcular los timer para corregir ese error?


  Dentro de proteus puedes colocar un BreakPoint luego de activar la salida -en la interrupción del timer0-, y ejecutas el código. con el botón de "play". A la derecha vas a encontrar entre paréntesis cuando tiempo llevó la ejecución del código entre que le diste play y que paró por el breakpoint. En mi caso me da 2.0008mS.

  Teniendo en cuenta dicho valor, será cuestión de ir variando el valor que le precargas al timer0 para que llegue a la interrupción en mayor o menor tiempo.


el perido entre flancos de subida de cada señal me sale 20.60ms
des el cursor vertical al primer pulso de la señal le cuesta 6.70ms.
entre pulso y pulso es decir la ventana me va 1.10ms

y me da un error creo que tiene que ver con el encendido y apagado del timer..
no se es asi..

error: OSCTUNE register not fully modelled - the TUNx bits are not modelled

este es un bucle..de este error.


  Entre flanco de subida y flanco de subida de una misma señal -supongamos el canal A del osciloscopio- tiene que dar el período de trama. En tu caso debería ser de 20mS porque cuentas 20 interrupciones de timer0. Si en la práctica obtienes 20.6mS es porque tienes que ajustar un poco el valor que precargas en el timer0.
No es para marearte, ten en cuenta que antes de que estés activando tu salida hay código que se ejecuta y está escapando a tu cálculo de tiempo y por lo tanto hay que ajustar la precarga.

  Si la ventana te da 1.1mS, se soluciona ajustando la precarga del timer0.

  También deberías medir cuanto dura cada pulso en alto, para saber si debes ajustar la precarga del timer1.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #46 en: 15 de Agosto de 2012, 22:14:34 »
hola
coloque los puntos de ruptura en las lineas:

6 - 8 - 9 - 10 - 12 - 13

Código: C++
  1. ..
  2. #int_TIMER0
  3. void  TIMER0_isr(void)
  4. {  
  5.  
  6.   output_high (servos[cnt_t0]);             //activo servo
  7.   //ventana de 1 ms cambio de svmotor
  8.   set_timer0(ventana);                      //desborda cada 1ms
  9.   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);   //activo timer1
  10.   set_timer1(g_90);                         //tiempo en alto
  11.  
  12.   if(cnt_t0==20){ //cambio de ventana
  13.      cnt_t0=0;
  14.      //printf("\n\r -->T0 1ms 20 ventanas  1 perido");
  15.   }
  16.  
  17.   //printf("\n\r cnt_t0: %d "cnt_t0);
  18.   //cnt_t0=cnt_t0+1; //incremta ventana => motor
  19. }
  20.  
  21. #int_TIMER1
  22. void  TIMER1_isr(void)
  23. {
  24. output_low (servos[cnt_t0]);     //apago motor
  25. //printf("\n\r OFF servo: %d "cnt_t0-1);
  26. cnt_t0=cnt_t0+1;                 // incremta ventana => motor
  27. setup_timer_1(0);                // desactivo timer 1
  28.  
  29. }
  30. ..

una vez colocados los puntos de ruptura de ejecucion
le doy al stop, vuelvo adarle al play y se para
en el primer punto:(linea 6)

le doy una segunda vez (linea 8 )

me marca dos tiempo : entiendo que un es el total
y el otro entre punto y tunto de ruptura.

linea 6: 18.772ms (18.772ms)

si entra en la interrupcion del timer0 es que ha pasado el tiempo que precargue
cuyo valor es el de la ventana 20ms, pero por el contrario faltan casi 2ms

pero me parece muy raro porque si tambien cuenta el tiempo de carga desde que di al play
hasta el punto de rupctura , ese tiempo sera el de ejucion de las lineas más el del timer0
si las intrucuiones se ejecutan en us .

en linea 8 me dice: 18.801ms ( 28.800us)

hay algo que no me cuadra.
analizamos el proceso ..

arrana el programa y cuando llega a la linea de carga del timer0 le carga el valor de la ventana 10ms
sigue ejecutando el programa y de forma trasparente contara lo cargado en el timer 0
quien llegara primero?

- la ejecucion hasta fin de programa o
- la interupcion del timer 0.

llegara antes al final de programa, al while..! y la interupcion se producira despues.

tengo que controlar el tiempo desde que se produce la primera interrupcion
hasta la siguiente es decir 1ms.

parece sencillo pero no lo es, ...


hice calculos y la diferencia es 1.041, 1.032 ,1.039, 1.032, 1.03 ms no es el milisegundo perfecto

los calculos los hice entre  ventana y ventana

como se puede ajustar un tiempo que varia tanto, es imposible...

lo peor es cuando tenga que ajustar el tiempo en alto que tambien varia
para mas dar mal..



« Última modificación: 16 de Agosto de 2012, 09:06:40 por pajaro »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #47 en: 15 de Agosto de 2012, 23:48:09 »
  Yo dejaría el breakpoint sólo en la línea 8, el resto de las líneas dentro de la interrupción las puedes ir ejecutando con F11 si quieres.

  Por el momento dejaría sólo ese breakpoint y tomaría el tiempo que tarda entre la parada y una nueva parada. Que sería justamente el tiempo que cuenta el timer0.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #48 en: 16 de Agosto de 2012, 09:28:55 »
Hola
ya coloque el punto de ruptura en la linea 8:
y los tiempos que obtuve fueron:

Código: C++
  1. ...
  2. INT_1.....   18.801ms(18.801ms)  cnt_t0=0 (cuando entra en la INT vale)
  3. INT_2.....   19.840ms(1.0392ms)  cnt_t0=1
  4. INT_3.....   20.872ms(1.0312ms)
  5. INT_4.....   21.904ms(1.0328ms)
  6. INT_5.....   22.934ms(1.0296ms)
  7. INT_6.....   23.964ms(1.0296ms)
  8. INT_7.....   24.993ms(1.0296ms)
  9. INT_8.....   26.023ms(1.0296ms)
  10. INT_9.....   27.052ms(1.0296ms)
  11. INT_10....   28.082ms(1.0296ms)
  12. INT_11....   29.115ms(1.0328ms)
  13. INT_12....   30.144ms(1.0296ms)
  14. INT_13....   31.174ms(1.0296ms)
  15. INT_14....   32.208ms(1.0344ms)
  16. INT_15....   33.238ms(1.0296ms)
  17. INT_16....   34.268ms(1.0296ms)
  18. INT_17....   35.297ms(1.0296ms)
  19. INT_18....   36.327ms(1.0296ms)
  20. INT_19....   37.356ms(1.0296ms) cnt_t0=18
  21. INT_20....   38.389ms(1.0328ms) cnt_t0=19
  22. INT_21.....  39.430ms(1.0408ms) cnt_t0=20
  23.  
  24. INT_1.....   40.469ms(1.0392ms) cnt_t0=0 (cuando entra en la INT vale)
  25. INT_2.....   41.500ms(1.0312ms)
  26. INT_3.....   42.533ms(1.0328ms)
  27. INT_4.....   43.563ms(1.0296ms)
  28. ..
debo de evaluar que el cambio debe de ser en 19 ya que cuanto emepieza desde 0

la pregunta la corrrepción seria de 1.03 redondeando?
¿Porque no es constante el incremento?





Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #49 en: 16 de Agosto de 2012, 09:47:15 »
  Todo dependerá del código generado por CCS.

  Yo ahora lo estoy probando con el compilador SDCC, el primer ingreso tarda 13mS y algo -debido a todo el código anterior-. El segundo ingreso se da a los 2.5mS (en mi caso el salto debería ser cada 2mS). Luego de ello probé 70 saltos sucesivos y todos dieron a 2.0008mS.

  Vale aclarar que no tengo implementado nada todavía con I2C.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #50 en: 16 de Agosto de 2012, 18:18:32 »
Hola AngelGris

otra cosa rara si cambio entre 20 o 19 en la comparacion de la ventana
me tira abajo el primer servo.

deberia de rectificar ya que de 0 a 20 hay 21 INT ya que evalua despues.
no ha manera..lo qu eno entiendo es que si el servo primero esta en la posicion 0
del vector que narces le afecta, ... no deberia de afectarle por lo menos la primera vez..


Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #51 en: 16 de Agosto de 2012, 22:18:57 »
  No sé que código generará CCS, posiblemente haya algún problema en como maneja la configuración de los timers y por ello las diferencias de tiempo.

  Estuve modificando un poco mis códigos y logré lo siguiente...

  Al código que mostré anteriormente en SDCC, le agregué el manejo de I2C slave por interrupción de baja prioridad. Se reciben 3 bytes que indican el servo al cual va dirigido el dato, el byte alto del dato y el byte bajo del dato. Luego de recibido los tres, los dos que forman el dato indican el tiempo en alto del servo.

  Hice un código con I2C master que justamente transmite los datos hacia el slave. El master lee el valor de un pote por el ADC, calcula el valor adecuado para el tiempo en alto y lo envía por I2C.

  Por el momento sólo tengo el pote correspondiente al servo0, pero es suficiente para corroborar que funciona perfectamente y que el ancho de pulso del slave varía conforme  a la posición del pote.

  En mi caso, el ancho de pulso varía entre 1mS y 2mS
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #52 en: 17 de Agosto de 2012, 10:32:44 »
Hola AngelGris

el SDCC con que IDE lo manejas?


Encontre este hilo por el foro:

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

pero mo me cuadra el tiempo que le pone:

--------------------------------------------------------------------

float const uSxTick = 0.2;                  // Microsegundos por Tick de TMR1 a 20 Mhz

#define VAL_TIMER1 53000   // 65536-53000=12536 * 0,0002 = 2,5 milisegundos

----------------------------------

supongo que el timer1 lo tine a 2^16=65536
si cada tick es 0.2us  un int son 13107.2 us

si quiere conseguir 2.5ms serian 2500us
si

 1 tick -------------    0.2 us
 x tick -------------  2500 us

me salen: 12500tick la pregunta porque a el le salen 36 mas

esos 36 tick de mas son 36 tick X 0.2 us = 7.2 us de mas
---------------------------

Estoy pensando en armarme yo tambine un potenciomentro y un lcd
para mover el servo y ver cuantos tick, us y gados se mueve el servo

tenia por ahi montado un lcd por i2c solo seria buscar el potenciometro adecuado.

« Última modificación: 17 de Agosto de 2012, 11:42:04 por pajaro »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #53 en: 17 de Agosto de 2012, 13:48:04 »
  SDCC lo uso con PikLab, siempre estoy "trabajando" desde linux.

  Acá te dejo un link a la simulación
feature=youtu.be

  El dato que tiene que variar es el canal rojo (tercero de arriba hacia abajo) pero en algunos momentos varia un poquito también el canal azul. Quizá haya que retocar el código...
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #54 en: 17 de Agosto de 2012, 17:37:13 »
Hola

otra sorpresa, con el proteus veo que la señal le llega  cada 20.20ms
y la ventana la he ajustado para 4ms y de tal forma. las señales llegan al osciloscopio
pero al probar con los servos estos no se mueven,

ni siquiera con los estandeares de 0.5ms, 1.5ms, 2.5ms
probe con los tiempo que yo tenia de ejemplos anteriores con el set_duty y los delay.
y no hay manera y se oye el tick, tick, tick

no se que esta pasando

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #55 en: 17 de Agosto de 2012, 21:55:24 »
Hola

otra sorpresa, con el proteus veo que la señal le llega  cada 20.20ms
y la ventana la he ajustado para 4ms y de tal forma. las señales llegan al osciloscopio
pero al probar con los servos estos no se mueven,


  ¿Qué señal le llega cada 20.20mS? ¿A qué le llega esa señal?

ni siquiera con los estandeares de 0.5ms, 1.5ms, 2.5ms
probe con los tiempo que yo tenia de ejemplos anteriores con el set_duty y los delay.
y no hay manera y se oye el tick, tick, tick

no se que esta pasando
 
  Hasta donde tengo entendido "set_duty" es para trabajar con el módulo CCP en su función de PWM. Pero eso es por hardware, y si vos te estás guiando con los timers en realidad lo estás implementando por software.

  Has una cosa, sube una captura de pantalla del osciloscopio de proteus. También te conviene medir el tiempo entre flanco de subida y flanco de subida de una misma señal (que tendría que ser 20mS o aproximado). Y también mide el tiempo en alto de dicha señal. El osciloscopio de proteus tiene cursores para dichos menesteres. Para medir el tiempo en alto te conviene ajustar la base de tiempo para ver el pulso lo mas largo posible y poder medir con mayor precisión.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #56 en: 18 de Agosto de 2012, 09:30:18 »
Hola AngelGris
Pongo la foto del osciloscopio de proteus
los canales se corresponden con las patillas:

A: RB7
B: RB6
C: RC2
D: RC1

se puede apreciar que hay una diferencia

el periodo es de 20ms, la ventana es de 1ms
hice zoom  y hay diferencia entre ello es unas decimas.

creo que hay limite de cursores..pongo dos

pongo el codigo.
code main
Código: C++
  1. //variables i2c
  2. int8 state, comando;
  3. //int8 iic_dato, Direc_master;
  4. int8 direc_Mas_esc, recivo=0;
  5. int8 dato[4];
  6. //int8 dato_1[4];
  7. int8 cnt=0;
  8. int8 angulo;
  9. int8 inclina;
  10. int8 motor_on;
  11.  
  12. //servos pwm soft
  13. int8 servos[]={sv_0,sv_1,sv_2,sv_3,sv_4,0,0,0,0,0};
  14.  
  15.  
  16. //variables timer
  17. int8 cnt_t0=0;
  18. int8 cnt_t1=0;
  19. int1 t0=0;
  20. int1 t1=0;
  21.  
  22. //debug tick
  23. int16 valor;
  24.  
  25. #priority  ssp, timer0, timer1    
  26. /*
  27. #int_RTCC
  28. void  RTCC_isr(void)
  29. {
  30.  
  31. }
  32. */
  33. #int_TIMER0
  34. void  TIMER0_isr(void)
  35. {  
  36.    
  37.    output_high (servos[cnt_t0-1]);             //activo servo
  38.    //ventana de 1 ms cambio de svmotor
  39.      
  40.    setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);   //activo timer1
  41.    //valor = t_on(500); //convierte us en tick --<> no va bien
  42.    
  43.    //printf("\n\r tick: %ld "valor);
  44.    set_timer1(g_90);  //tiempo en alto
  45.    
  46.    set_timer0(ventana);             //ventana desborda cada Xms
  47.    //printf("\n\r cnt_t0: %d"cnt_t0);
  48.    if(cnt_t0==5){ //cambio de ventana
  49.       cnt_t0=0;
  50.       //printf("\n\r -->T0 1ms 20 ventanas  1 perido");
  51.    }
  52.  
  53.    //printf("\n\r cnt_t0: %d "cnt_t0);
  54.    //cnt_t0=cnt_t0+1; //incremta ventana => motor
  55. }
  56.  
  57. #int_TIMER1
  58. void  TIMER1_isr(void)
  59. {
  60. output_low (servos[cnt_t0-1]);     //apago motor
  61. //printf("\n\r OFF servo: %d "cnt_t0-1);
  62. cnt_t0=cnt_t0+1;                 // incremta ventana => motor
  63. setup_timer_1(0);                // desactivo timer 1
  64.  
  65. }
  66.  
  67.  
  68. #int_SSP
  69. void  SSP_isr(void){
  70. //disable_interrupts(INT_SSP);
  71. //disable_interrupts(INT_TIMER0);
  72. //disable_interrupts(INT_TIMER1);
  73. //int8 comando;
  74. //master escribe de esclavo  menor de <80
  75. //master lee de esclavo      mayor de >80
  76.  
  77. state = i2c_isr_state();
  78.    if(state==0)
  79.    {
  80.       direc_Mas_esc=i2c_read();
  81.       if(direc_Mas_esc==S1){
  82.       ////////////////////////////////
  83.       printf("\n\r --> Direccion: %X "direc_Mas_esc); //--- debug mas rapido
  84.       ////////////////////////////////
  85.          recivo=1;
  86.          output_high(PIN_B2);  //---debug rapido
  87.       }
  88.      
  89.       //printf("\n\r Direccion : %X "direc_Mas_esc); //para solo imprime s1
  90.       //if(SSPADD==S1){
  91.       //printf("\n\r state==0 soy S1: %X "SSPADD);
  92.       //}
  93.      
  94.    }
  95.    
  96.    if(state < 0x80)
  97.    {
  98.      
  99.       //iic_dato=i2c_read();
  100.       //comando=iic_dato;
  101.       if(recivo==1){
  102.          dato[cnt]=i2c_read();
  103.          
  104.          // coreccion para lo de error en dato=1
  105.          if(dato[cnt]==10){
  106.            dato[cnt]=1;
  107.          }
  108.          
  109.          if(dato[0]==1){ // control de motor
  110.             output_high(PIN_B6);
  111.             motor_on=1;
  112.          }
  113.          
  114.          if(dato[cnt]!=0){ //control de angulo
  115.             angulo=dato[1];
  116.             inclina=dato[2];
  117.          }
  118.          ///////////////////////
  119.          
  120.          /////////////////////////////
  121.          printf("\n\r dato[%u]:%u"cnt,dato[cnt]);  //-- debug +rapido
  122.          /////////////////////////////
  123.          recivo=0;
  124.          output_low(PIN_B2);  //--- debug rapido
  125.          
  126.          // para resetear almacen dato
  127.          if(dato[cnt]==99){  //cnt resetea en 3 si es 99
  128.            cnt=0;
  129.          }
  130.          else{
  131.            cnt=cnt+1;
  132.          }
  133.          
  134.       }
  135.      
  136.      
  137.      
  138.  
  139.      
  140.  
  141.      
  142.       //Aqui colocas lo que necesites hacer con el dato enviado por el maestro
  143.       //printf("\n\r comando recibo <80: %u"comando);
  144.      
  145.    }
  146.    if(state == 0x80)
  147.    {
  148.     /*
  149.     switch(comando)
  150.       {
  151.          Case Pide_Dato1:
  152.             i2c_write(Dato1);
  153.             output_high(PIN_B7);
  154.             delay_ms(300);
  155.             output_low(PIN_B7);
  156.            
  157.             printf("\n\r Llego dato.");
  158.             break;
  159.          Case Pide_Dato2:
  160.             i2c_write(Dato2);
  161.             output_high(PIN_B2);
  162.             break;
  163.       }
  164.       */
  165.    }
  166. enable_interrupts(INT_SSP);  //para imprimir completo priff del main
  167. //enable_interrupts(INT_TIMER0);
  168. //enable_interrupts(INT_TIMER1);
  169. }
  170.  
  171.  
  172. #int_BUSCOL
  173. void  BUSCOL_isr(void)
  174. {
  175.  
  176. }
  177.  
  178.  
  179.  
  180. void main()
  181. {
  182.  
  183.    setup_adc_ports(NO_ANALOGS|VSS_VDD);
  184.    setup_adc(ADC_CLOCK_DIV_2);
  185.    setup_wdt(WDT_OFF);
  186.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
  187.    setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
  188.    setup_timer_2(T2_DISABLED,0,1);
  189.    setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
  190.    setup_comparator(NC_NC_NC_NC);
  191.    setup_vref(FALSE);
  192.    enable_interrupts(INT_RTCC);
  193.    enable_interrupts(INT_TIMER0);
  194.    enable_interrupts(INT_TIMER1);
  195.    enable_interrupts(INT_SSP);
  196.    enable_interrupts(INT_BUSCOL);
  197.    enable_interrupts(GLOBAL);
  198. //Setup_Oscillator parameter not selected from Intr Oscillator Config tab
  199.  
  200.    // TODO: USER CODE!!
  201. set_timer0(ventana);
  202. setup_timer_1(T1_DISABLED);  // timer 1 no activo
  203. //set_timer1(0);
  204.  
  205. printf("\n\r Prueba de timer: ");
  206.  
  207.    while(true){
  208.       if(t0==2){
  209.          printf("\n\r -->T0 20ms");
  210.       }
  211.       if(t1==4){
  212.          printf("\n\r -->T1 40ms");
  213.       }
  214.       enable_interrupts(INT_SSP);
  215.       enable_interrupts(INT_TIMER0);
  216.       enable_interrupts(INT_TIMER1);  
  217.    }
  218. }

code cabecera:

Código: C++
  1. #include <18F2550.h>
  2. #device adc=8
  3.  
  4. #FUSES NOWDT                    //No Watch Dog Timer
  5. #FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
  6. #FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
  7. #FUSES NOPROTECT                //Code not protected from reading
  8. #FUSES NOBROWNOUT               //No brownout reset
  9. #FUSES BORV20                   //Brownout reset at 2.0V
  10. #FUSES NOPUT                    //No Power Up Timer
  11. #FUSES NOCPD                    //No EE protection
  12. #FUSES STVREN                   //Stack full/underflow will cause reset
  13. #FUSES NODEBUG                  //No Debug mode for ICD
  14. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  15. #FUSES NOWRT                    //Program memory not write protected
  16. #FUSES NOWRTD                   //Data EEPROM not write protected
  17. #FUSES IESO                     //Internal External Switch Over mode enabled
  18. #FUSES FCMEN                    //Fail-safe clock monitor enabled
  19. #FUSES NOPBADEN                 //PORTB pins are configured as digital I/O on RESET
  20. #FUSES NOWRTC                   //configuration not registers write protected
  21. #FUSES NOWRTB                   //Boot block not write protected
  22. #FUSES NOEBTR                   //Memory not protected from table reads
  23. #FUSES NOEBTRB                  //Boot block not protected from table reads
  24. #FUSES NOCPB                    //No Boot Block code protection
  25. #FUSES MCLR                     //Master Clear pin enabled
  26. #FUSES LPT1OSC                  //Timer1 configured for low-power operation
  27. #FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
  28. #FUSES PLL12                    //Divide By 12(48MHz oscillator input)
  29. #FUSES CPUDIV4                  //System Clock by 4
  30. #FUSES USBDIV                   //USB clock source comes from PLL divide by 2
  31. #FUSES VREGEN                   //USB voltage regulator enabled
  32.  
  33. //timer 0
  34. /*
  35. #DEFINE T0CON 0xFD5     // timer0
  36. #DEFINE T1CON 0xFCD     // timert1
  37.  
  38. #BIT TMR0ON = T0CON.7   // valor enable del timer0 1=on, 0=Off
  39. #BIT RD16 = T1CON.7     // valor enable del timer0 1=on, 0=Off
  40.  
  41. #define TIMER1_ON RD16
  42. */
  43.  
  44. // --- esclavos  --------------------------------
  45. #define S1 0xB0
  46. #define S2 0xB2
  47. #define S4 0xB4
  48. #define S6 0xB6
  49. #define S8 0xB8
  50.  
  51. // ----- define los servos ----------------------
  52. #define sv_0 PIN_B7
  53. #define sv_1 PIN_B6
  54. #define sv_2 PIN_C1
  55. #define sv_3 PIN_C2
  56. #define sv_4 PIN_C0
  57. /*
  58. #define sv_5 PIN_B7
  59. #define sv_6 PIN_B6
  60. #define sv_7 PIN_B5
  61. #define sv_8 PIN_B4
  62. #define sv_9 PIN_B3
  63. */
  64.  
  65. // TIMER 2 exp 16 bit : 65536 tick 0.2us -->13107.2us 1 INT
  66.  
  67. // ---- perido de 20 ms 20000us -------------------------------
  68. //      1 tick ........ 0.2us
  69. //      5 tick ........ 1  us
  70.  
  71. // ----- ventana o cambio motor -------------------------------
  72. //                                      Tick para us en on
  73. //const int16 ventana = 60536;  // 65536 -  5000 = 1ms 1000us
  74. //const int16 ventana = 55536;  // 65536 - 10000 = 2ms 2000us
  75. //const int16 ventana = 50536;  // 65536 - 15000 = 3ms 3000us
  76. const int16 ventana = 45536;  // 65536 - 20000 = 4ms 4000us
  77. //const int16 ventana = 40536;  // 65536 - 25000 = 5ms 5000us
  78. //const int16 ventana = 15536;  // 65536 - 50000 = 10ms 10000us
  79.  
  80.  
  81. //1 tick -------- 0.2us
  82. //x tick -------- y  us
  83.  
  84. // ----- tick para tiempo en ON -------------------------------
  85.  
  86. // --- generico ---------------------
  87. const int16 g_0    = 63036;    //65536 -  2500  0.5ms  500us
  88. const int16 g_90   = 58036;    //65536 -  7500  1.5ms 1500us
  89. const int16 g_180  = 53036;    //65536 - 12500  2.5ms 2500us
  90. //-------------------------------------------------------------
  91.  
  92. // --- mis tick ---------------------
  93.  
  94. //conts inr16 g_1    = .....;    //65536 - .....  .....ms  ...us
  95. //const int16 g_0    = 63036;    //65536 -   600  0.120ms  120us
  96. //const int16 g_90   = 58036;    //65536 -  1875  0.375ms  375us
  97. //const int16 g_180  = 53036;    //65536 -  3150  0.630ms  630us
  98.  
  99. /* en calculos y pruebas..
  100. const int16 g_0    = 63036;    //65536 -   600  0.120ms  120us
  101. const int16 g_15   = 63661;    //65536 - 1875  375us
  102. const int16 g_30   = 63661;    //65536 -   625  0.125ms 375us / 3 = 125us
  103.  
  104. const int16 g_45   = 63661;    //65536 -  ....  0.185ms 370us / 2 = 185us
  105. const int16 g_60   = 63661;    //65536 -  1875  0.185ms 630us / 3 = 210us
  106. const int16 g_75   = 63661;    //65536 -  1875  375us
  107.  
  108. const int16 g_105  = 63661;    //65536 - 1875  375us
  109. const int16 g_120  = 63661;    //65536 - 1875  375us
  110. const int16 g_135  = 63661;    //65536 - 1875  375us
  111.  
  112. const int16 g_150   = 63661;    //65536 - 1875  375us
  113. const int16 g_165   = 63661;    //65536 - 1875  375us
  114. const int16 g_180  = 53036;    //65536 -  3150  0.630ms  630us
  115. */
  116.  
  117. // --- vector inicializacion y angulos servos ----------------------
  118. static int16 valor_PWM[]={g_90, g_0,g_180,0,0,0,0};
  119. static int16 ini_PWM[]={g_90, g_90, g_90, g_90,0,0,0,0}; //8 servos
  120.  
  121. #define Pide_Dato1 2
  122. #define Pide_Dato2 3
  123. #define dato1 4
  124. #define dato2 5
  125.  
  126. #use delay(clock=20000000)
  127. //#define I2C_SCL   PIN_B7
  128. //#define I2C_SDA   PIN_C4
  129. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
  130. #use i2c(Slave,Slow,sda=PIN_B0,scl=PIN_B1,address=0xB0)
  131. //#include "milib.c"
  132.  
  133.  
  134. //--------- milib.c-------------
  135.  
  136. //convierte us en tick de reloj
  137. // 1us ---> 5tick
  138. // xus ---> y tick
  139. int16 t_on(int16 us_on){
  140.    int16 tick_on;
  141.  
  142.       tick_on= 65536 - (us_on * 5);
  143. return tick_on;
  144.  
  145. }
  146.  
  147. bueno no se que pasa..
  148.  
  149. como obtergo los numeros de tick para 1 grado de forma precisa y estable?
« Última modificación: 18 de Agosto de 2012, 09:39:33 por pajaro »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #57 en: 18 de Agosto de 2012, 10:18:09 »
  Según esas capturas, estaría muy bien. El tiempo obtenido de 1.54mS debería llevar el servo aproximadamente a la mitad de su recorrido.

 Si la falla está en el circuito real, habría que ver con un osciloscopio real como son las señales obtenidas. Si las señales están bien habría que ver si no hay algún problema de conexionado entre el servo y el pic.

  Si no tienes osciloscopio se puede utilizar la placa de sonido... como la señal es de baja frecuencia no tendrás inconvenientes, podrías colocar un divisor resistivo a la salida del pic para bajar la señal a 1Vpp y luego inyectar la señal en la placa. Hay programas para utilizarla como osciloscopio, pero también puedes recurrir a grabarlas con algún editor de audio y medir el tiempo manualmente.
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas

Desconectado pajaro

  • PIC24H
  • ******
  • Mensajes: 1121
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #58 en: 18 de Agosto de 2012, 13:18:06 »
Hola AngelGris

Despues de repasar el circuito, los servos y conexiones
he descubierto el error,  :mrgreen: estaba nuevamente en la variable
de definicion como hice un copiar y pegar y el entorno se colgo, ya no guarde
al arrancar me dejo recuperar pero, no me guardo los cambios y estaba con los angulos
malos  :?, ahora modifique los angulos de extremos centro y funcionan.
despues modicare el pos anterior.

---->> post anterior modificado

Voy a calcular los intermedios...
« Última modificación: 19 de Agosto de 2012, 10:14:35 por pajaro »

Desconectado AngelGris

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2480
Re: :: PWM :: CCS :: PIC18F2550 :: SERVOS::
« Respuesta #59 en: 18 de Agosto de 2012, 13:56:35 »
  Bueno, al menos un problema resuelto... ¿Cómo piensas hacer el movimiento, con un potenciómetro conectado al ADC?
De vez en cuando la vida
nos besa en la boca
y a colores se despliega
como un atlas