viernes, 11 de octubre de 2013

Coche barato, radio cara. Adaptador PWM servo a motor 2/2

Hola.

Lo prometido es deuda, asi que aqui tenemos la segunda parte de este proyecto.

En este vídeo podeis ver cómo es el control de la aceleración del coche, que antes era encendido/apagado y ahora acelera más cuanto más movemos la palanca:


El programa está hecho en CCS y es muy simple. Se divide en dos partes: 1) la lectura del pulso del servo a través del puerto B y 2) la generación de PWM proporcinal a la velocidad, a través del puerto A y B. 1) Lectura del pulso del servo. Esta parte es la más crítica ya que hemos de leer con precisión los pulsos que irían a un servo y convertirlo en una numeración. Para eso usaremos el timer0 del pic. Préviamente hemos calculado los "ticks" que contará este timer y cómo ajustamos el preescaler. Por ejemplo, para el cristal de 4Mhz, sabiendo que un servo en reposo o 50% da un pulso de 1,5ms. xtal=4 incremento:Xtal/4=1us x 8(preescaler) =8us Entonces el contador contará para: 1ms: 1,5ms/8us = 125 1,5ms: 1,5ms/8us = 187 2ms: 1,5ms/8us = 250 Hemos escogido el preescaler de 8 para abarcar esta horquilla entre 0 y 255.
  1. #include <16F84.H>
  2. #FUSES NOWDT      //No Watch Dog Timer
  3. #FUSES HS      //para cristal de 6MHz
  4. #FUSES PUT     //power up timer habilitado
  5. #FUSES NOPROTECT//lectura habilitada del codigo del pic
  6. //#use delay(clock=4000000) // 4 MHz OSC
  7. //#use delay(clock=3579000) // 4 MHz OSC
  8. #use delay(clock=6000000) // 6 MHz OSC
  9. #USE FAST_IO (A)
  10. #USE FAST_IO (B)
  11. #define PIN_SERVOi1     PIN_B4
  12. #define PIN_SERVOi2     PIN_B5
  13. #define PIN_SERVOi3     PIN_B6
  14. #define PIN_SERVOi4     PIN_B7
  15. #define PIN_MOTOR1R     PIN_A0
  16. #define PIN_MOTOR1L     PIN_A1
  17. #define PIN_MOTOR2R     PIN_A2
  18. #define PIN_MOTOR2L     PIN_A3
  19. #define PIN_MOTOR3R     PIN_B0
  20. #define PIN_MOTOR3L     PIN_B1
  21. #define PIN_MOTOR4R     PIN_B2
  22. #define PIN_MOTOR4L     PIN_B3
  23. #define PIN_LED       PIN_A4
  24. /*
  25. xtal=3,57   incremento= 1.117 x 8 = 8,94 us
  26. 1.5ms= 167
  27. ULIMIT= 167 +10
  28. LLIMIT= 167 -10
  29. xtal=558k   inc= 7.168 x 1
  30. =195
  31. xtal=6 inc= 0,666  x 16 =10.66666
  32. =140
  33. */
  34. #define ULLIMIT 140
  35. #define ULIMIT 150
  36. #define LLIMIT 130
  37. int8 tempo,ledco;
  38. int8 timerco1,motor1L,motor1R;
  39. int8 timerco2,motor2L,motor2R;
  40. int8 timerco3,motor3L,motor3R;
  41. int8 timerco4,motor4L,motor4R;
  42. int8 scounter;
  43. int8 semaforo;
  44. boolean ledb;
  45. //**********************************************************************************
  46. //**********************************************************************************
  47. #INT_RB
  48. void interrupcionRB() {
  49. SWITCH(input_b()&0xF0){
  50.     case 0b00010000:set_timer0(0); semaforo=1;break;
  51.     case 0b00100000:set_timer0(0); semaforo=2;break;
  52.     case 0b01000000:set_timer0(0); semaforo=3;break;
  53.     case 0b10000000:set_timer0(0); semaforo=4;break;
  54.    
  55.     case 0:
  56.         switch (semaforo){
  57.        
  58.             case 1:timerco1=get_timer0();semaforo=0;ledco++;break;
  59.             case 2:timerco2=get_timer0();semaforo=0;ledco++;break;
  60.             case 3:timerco3=get_timer0();semaforo=0;ledco++;break;
  61.             case 4:timerco4=get_timer0();semaforo=0;ledco++;break;
  62.    
  63.         }
  64.     default:
  65.         semaforo=0;
  66.    
  67. }
  68. //**********************************************************************************
  69. //******************************  M A I N  *****************************************
  70. //**********************************************************************************
  71. void main(){
  72.    
  73.    set_tris_a(0);  // todo salida
  74.    set_tris_b(0b11110000);  // todo salida rb4,6,7 entrada
  75.    output_a(0);
  76.    output_b(0);
  77.    output_high(PIN_LED);
  78.    
  79.      
  80.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);   //activamos timer0 como interno
  81.    set_timer0(0);
  82.     motor1L,motor1R=0;
  83.     motor2L,motor2R=0;
  84.     motor3L,motor3R=0;
  85.     motor4L,motor4R=0;
  86.    
  87.     timerco1,timerco2,timerco3,timerco4=ULLIMIT;
  88.    enable_interrupts(INT_RB);
  89.    enable_interrupts(GLOBAL);
  90.    
  91.    
  92.    
  93.    
  94.    for(ledco=0;ledco<5;ledco++) {output_bit(PIN_LED,ledb);
  95.     ledb=!ledb;
  96.     delay_ms(500);
  97.    
  98.    }
  99.  
  100. while(1){  //bucle infinito  
  101.     for(tempo=0;tempo<=100;tempo++){
  102.     // PWM DEL MOTOR
  103.    
  104.     //evaluamos aqui para no perder tiempo
  105.    
  106.     if(tempo==95 ){
  107.         if(ledco++ >254){
  108.             output_bit(PIN_LED,ledb);
  109.             ledb=!ledb;
  110.             ledco=0;
  111.         }      
  112.     }else if(tempo==96 ){
  113.        
  114.         if(timerco1 > ULIMIT ){ motor1R=(--timerco1-ULIMIT)*3;motor1L=0;}
  115.         else if(timerco1 < LLIMIT) {motor1L=(LLIMIT-timerco1++)*3;motor1R=0;}
  116.         else{motor1R=0;motor1L=0;}
  117.     }else if(tempo==97 ){
  118.    
  119.         if(timerco2 > ULIMIT ){ motor2R=(--timerco2-ULIMIT)*3;motor2L=0;}
  120.         else if(timerco2 < LLIMIT) {motor2L=(LLIMIT-timerco2++)*3;motor2R=0;}
  121.         else{motor2R=0;motor2L=0;}
  122.        
  123.     }else if(tempo==98 ){
  124.    
  125.         if(timerco3 > ULIMIT ){ motor3R=(--timerco3-ULIMIT)*3;motor3L=0;}
  126.         else if(timerco3 < LLIMIT) {motor3L=(LLIMIT-timerco3++)*3;motor3R=0;}
  127.         else{motor3R=0;motor3L=0;}
  128.        
  129.     }else if(tempo==99 ){
  130.    
  131.         if(timerco4 > ULIMIT ){ motor4R=(--timerco4-ULIMIT)*3;motor4L=0;}
  132.         else if(timerco4 < LLIMIT) {motor4L=(LLIMIT-timerco4++)*3;motor4R=0;}
  133.         else{motor4R=0;motor4L=0;}     
  134.        
  135.     }
  136.    
  137.    
  138.         output_bit(PIN_MOTOR1R,(motor1R >tempo));
  139.         output_bit(PIN_MOTOR1L,(motor1L >tempo));
  140.        
  141.         output_bit(PIN_MOTOR2R,(motor2R >tempo));
  142.         output_bit(PIN_MOTOR2L,(motor2L >tempo));
  143.        
  144.         output_bit(PIN_MOTOR3R,(motor3R >tempo));
  145.         output_bit(PIN_MOTOR3L,(motor3L >tempo));
  146.        
  147.         output_bit(PIN_MOTOR4R,(motor4R >tempo));
  148.         output_bit(PIN_MOTOR4L,(motor4L >tempo));
  149.                
  150.        
  151.         delay_us(100);
  152.        
  153.    
  154.     } //bucle tempo
  155.    
  156.    
  157. } //end while  
  158. }

No hay comentarios:

Publicar un comentario