# necesito programar 2 motores DC para funcionar con PWM, en Pic 16f877A



## bngbel (Jul 5, 2014)

la idea es que funcionen con unos sensores de proximidad, que he buscado la manera para que el voltaje me lo entrege en distancia.. ya que cuando se encuentre a menos de 10 cm tiene que doblar, derecha izquieda o 180 grados.. estoy es lo que he hecho.. 


```
#include <16F877A.h>
#device adc=8
#fuses XT, NOWDT, PUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT,
#use delay(clock=4000000)
#include <math.h>
float volta,volti,voltd,disa,disi,disd;
int  adelante,izq,der;

void main(){
    	set_tris_A(0x1F);
    	set_tris_C(0x00);
        setup_adc(ADC_CLOCK_DIV_4);
        setup_adc_ports(3);
    
	
	while(1){
		setup_timer_2(T2_DIV_BY_16,255,1); //Modo, periodo y postscaler, para que funciones a 1 Hz
	    setup_ccp1(CCP_PWM);
    	setup_ccp2(CCP_PWM);
		set_pwm1_duty(207);
     	set_pwm2_duty(80);;
        set_adc_channel(0);
		delay_ms(15);
		adelante = read_adc();
		volta = adelante*5.0/256.0;
        set_adc_channel(1);
	    delay_ms(15);
		izq = read_adc();
        volti = izq* 5.0/256.0;
        set_adc_channel(2);
		delay_ms(15);
		der = read_adc();
		voltd = der* 5.0/256.0;
        if ((Volta >0.5) && (volta<2.7)){
                disa=(((16.75*pow(volta,4.0))-119.26*pow(volta,3.0))+(311.7*pow(volta,2.0))-(365.71*volta)+184.03);
                        if (disa<10.0){
                                        
                                if ((volti >0.5) && (volti<2.7)){
                                            disi=(((16.75*pow(volti,4.0))-119.26*pow(volti,3.0))+(311.7*pow(volti,2.0))-(365.71*volti)+184.03);
                                            if (disi<10.0){ 
                                                           if ((voltd >0.5) && (voltd<2.7)){
                                                                 disd=(((16.75*pow(voltd,4.0))-119.26*pow(voltd,3.0))+(311.7*pow(voltd,2.0))-(365.71*voltd)+184.03);
                                                              }if (disd<10.0){ 
                                                                     	 set_pwm1_duty(207);
                                                                         set_pwm2_duty(80);
	                                                                     delay_ms(500);
                                                                         
                                                              }else{
                                                                     
                                                                     set_pwm1_duty(207);
	                                                                 set_pwm2_duty(80);
	                                                                 delay_ms(250);  
                                                             }

                                           }else{
                                                
                                                set_pwm1_duty(80);
                                                set_pwm2_duty(207);
	                                            delay_ms(250);  
                                           }
				                }else{
                                            set_pwm1_duty(80);
                                            set_pwm2_duty(207);
	                                        delay_ms(250);

                                } 
                        }else{ break;}
        }                
           
                
       else{ 
           if ((volti >0.5) && (volti<2.7)){
                disi=(((16.75*pow(volti,4.0))-119.26*pow(volti,3.0))+(311.7*pow(volti,2.0))-(365.71*volti)+184.03);
                if (disi<10.0){
                       set_pwm1_duty(207);
	                   set_pwm2_duty(80);
	                   delay_ms(250); 
                       
                }
              
							
          } else{
                    if ((voltd >0.5) && (voltd<2.7)){
                          disd=(((16.75*pow(voltd,4.0))-119.26*pow(voltd,3.0))+(311.7*pow(voltd,2.0))-(365.71*voltd)+184.03);
                                if (disd<10.0){ 
                                         set_pwm1_duty(80);
                                         set_pwm2_duty(207);
	                                     delay_ms(250); 
                                         
                               }else{ break;}
                    }else{ break;}
            }      
        
      }  


  }
}
```

pero lo he provado con proteus.. y no me anda, como que nunca me entra a las condiciones que tengo, y ya no se que hacer :/, no se mucho de pic ni me manejo mucho con el PWM he visto muchas informaciones.. y con eso he ido formando el programa.. pero ya no se que hacer .. ( son 2 motores y cree un puente H con L293D),  bueno muchas gracias de ante mano... ...


----------



## LittleBastard (Jul 5, 2014)

Divide tu problema en problemas mas pequeños y fáciles de resolver.
Haz una función para cada uno de ellos, digamos una función que controle los dos motores para que avancen hacia adelante, otra para que retroceden, giro hacia la izquierda, hacia la derecha y otra para que haga el giro de 180 grados.
Después haz una para los sensores, donde convierta el valor entregado por el sensor en un valor que puedas interpretar como la distancia en metros o centímetros. Esto depende del sensor que utilices y como tengas tu circuito.
Para el PWM igual haces otra función donde controles la velocidad, aceleración, frenado o lo que quieras controlar de los motores.
Al final que tengas todas estas partes funcionando sólo debes unirlas y tendrás tu gran problema resuelto.
No olvides utilizar el buscador, en el foro encontraras mucha información útil.


----------



## fen2006 (Jul 5, 2014)

te recomiendo lo mismo que LittleBastard. tienes que hacerlo por parte y avanzando cuando hayas probado una parte. y es bueno que uses el simulador y te recomiendo que lo montes en una placa de prototipo antes de hacerle la placa definitiva.


----------



## bngbel (Jul 5, 2014)

#include <16F877A.h>
#device adc=8
#fuses XT, NOWDT, PUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT,
#use delay(clock=4000000)
#include <math.h>
float volta,disa;
int  adelante;

void main(){
    	set_tris_A(9);
    	set_tris_C(0x00);
        setup_adc(ADC_CLOCK_DIV_4);
        setup_adc_ports(3);

	while(1){

        setup_timer_2(T2_DIV_BY_16,255,1); 
	setup_ccp1(CCP_PWM);
    	setup_ccp2(CCP_PWM);
        set_adc_channel(0);
		delay_ms(15);
		adelante = read_adc();
		volta = adelante*5.0/256.0;

                 disa=(((16.75*pow(volta,4.0))-119.26*pow(volta,3.0))+(311.7*pow(volta,2.0))-(365.71*volta)+184.03);
                        if (disa<10.0){
                                                set_pwm1_duty(80);
                                                set_pwm2_duty(207);

                        }else{

	                                 set_pwm1_duty(80);
                                    	set_pwm2_duty(80);

																								}

}
}

este seria una parte del programa, pero aun así no anda y cuando le entrego un voltaje entre 2.5 y 0.8 volt a la entrada analógica (AN0), no la ingresa ya que me aparece apagada la señal en el proteus, y aun no ingresa a la condición, lo que me dicen de hacer las funciones.. tampoco me ha resultado tengo un programa mas grande aun que el que he mostrado con funciones.. pero lo he hecho mas simple para poder saber donde esta el error, con el dutty de 207 el motor anda hacia atras y con el de 80 hacia adelante, pero aun no me corre, adjunto simulación y proyecto en MPLAB, la verdad que estoy super atrasado con el proyecto, y les agradezco mucho la ayuda


----------

