Problema con código para controlar 3 motores DC con PIC

Me gustaría saber qué me está pasando con este nuevo código el cual me está activando un eje ( eje x)
Cuando inicio el PIC con la alimentación este hace movimientos erróneos en ambos sentidos.
Espero que analicen mi código para ver cuál es el problema.
C:
#include <16f877a.h>

#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT,PUT, NOCPD

#use delay(clock=20M, crystal)

#USE RS232 (baud=57600,bits=8,parity=N,xmit=PIN_C6,rcv=PIN_C7)

#include "button.c"

/*

INFORMACION

[URL unfurl="true"]https://sites.google.com/site/proyectosroboticos/encoder/encoder-por-software/encoder-simple-con-16f628a[/URL]

*/

#byte porta = 0x05

#byte portb = 0x06

#byte portc = 0x07

#byte portd = 0x08

#byte porte = 0x09


#define RELAY1 PIN_D0       

#define RELAY2 PIN_D1       

#define RELAY3 PIN_D2       

#define RELAY4 PIN_D3


#define motorX1 PIN_B5

#define motorX2 PIN_B6

#define motorPWM_X PIN_B7


#define motorY1 PIN_B4

#define motorY2 PIN_B3

#define motorPWM_Y PIN_B2


#define motorZ1 PIN_D7

#define motorZ2 PIN_D6

#define motorPWM_Z PIN_B1


#define motorA1 PIN_D5

#define motorA2 PIN_D4

#define motorPWM_A PIN_B0


#define Enable PIN_C5


#define END_SWITCH_X PIN_E0

#define END_SWITCH_Y PIN_E1

#define END_SWITCH_Z PIN_E2

 

 int8   Enc_X;  // Se almacenará el valor actual de RA0 y RA1, hasta la siguiente comparación.   

 int8   Aux_X;  // Se almacenará el valor anterior de RA0 y RA1, hasta la siguiente comparación.

 

 int8   Enc_Y;  // Se almacenará el valor actual de RA2 y RA3, hasta la siguiente comparación.

 int8   Aux_Y;   // Se almacenará el valor anterior de RA2 y RA3, hasta la siguiente comparación.

 

 int8   Enc_Z;  // Se almacenará el valor actual de RA4 y RA5, hasta la siguiente comparación.

 int8   Aux_Z;   // Se almacenará el valor anterior de RA4 y RA5, hasta la siguiente comparación.

 

 int8 B0=0,B1=0,B2=0;

 

 signed long long  SetPoint_X = 0;

 signed long long  ActualPoint_X = 0;

 signed long long  SetPoint_Y = 0;

 signed long long  ActualPoint_Y = 0;

 signed long long  SetPoint_Z = 0;

 signed long long  ActualPoint_Z = 0;

 

unsigned int intcount_X =217;

unsigned int intcount_Y =217;

unsigned int intcount_Z =217;

//unsigned int intcount_A =217;


unsigned int dutycycle_X=1;

unsigned int dutycycle_Y=1;

unsigned int dutycycle_Z=1;

//unsigned int dutycycle_A=1;

 

 #int_timer0


void timer0_isr()

{

        set_timer0(217);

        if (intcount_X--==0)

        {

        intcount_X=128;

        output_high (motorPWM_X);


       // output_b(0b00100110);//cambiar de puerto si desea; por ejemplo output_c(0b11111111)

        }

      

        if (intcount_Y--==0)

        {

        intcount_Y=128;

       //output_b(0b00100110); //cambiar de puerto si desea; por ejemplo output_c(0b11111111)

        output_high (motorPWM_Y);

        }

      

        if (intcount_Z--==0)

        {

        intcount_Z=128;

       // output_b(0b00100110); //cambiar de puerto si desea; por ejemplo output_c(0b11111111)

        output_high (motorPWM_Z);

        }

      

        if (intcount_X==dutycycle_X)

        {

                output_low(motorPWM_X); //cambiar de puerto si desea; por ejemplo output_low(pin_c0)

        }

        if (intcount_Y==dutycycle_Y)

        {

                output_low(motorPWM_Y); //cambiar de puerto si desea; por ejemplo output_low(pin_c1)

        }

        if (intcount_Z==dutycycle_Z)

        {

                output_low(motorPWM_Z); //cambiar de puerto si desea; por ejemplo output_low(pin_c2)

        }

     /*   if (intcount_A==dutycycle_A)

        {

                output_low(motorPWM_A); //cambiar de puerto si desea; por ejemplo output_low(pin_c2)

        }*/

}

  

 void write_duty(CH,value)

{

        switch(CH)

        {

        case 0: dutycycle_X=value;

                        if (dutycycle_X>=129)dutycycle_X=128;

                        break;

        case 1: dutycycle_Y=value;

                        if (dutycycle_Y>=129)dutycycle_Y=128;

                        break;

        case 2: dutycycle_Z=value;

                        if (dutycycle_Z>=129)dutycycle_Z=128;

                        break;

     /*   case 3: dutycycle_A=value;

                        if (dutycycle_A>=129)dutycycle_A=128;

                        break;    */         

        }

}     

 

 #int_rda

 

void rda_isr() {

char keypress=' ';

 keypress=' ';

 

if(kbhit()){


      Keypress=getc();

      switch (keypress){

 

case 'a':

        SetPoint_X++;

         output_high(Enable);

         break;

case 'b':

        SetPoint_X--;

         output_high(Enable);

          break;

case 'c':

        SetPoint_Y++;

         output_high(Enable);

         break;

case 'd':

        SetPoint_Y--;

         output_high(Enable);             

          break;

case 'e':

        SetPoint_X++;

        SetPoint_Y++;

         output_high(Enable);

         break;

case 'f':

        SetPoint_Y--;

         SetPoint_X--;

          output_high(Enable);

          break;

case 'g':

      

         SetPoint_X++;

         SetPoint_Y--;

      

          output_high(Enable);break;

case 'h':

        SetPoint_X--;

        SetPoint_Y++;

         output_high(Enable);

          break;

case 'U':

  output_high(Enable);

        SetPoint_Z++;

    

         break;

case 'u':

 output_high(Enable);

        SetPoint_Z--;

 

          break;


case 's':

         output_low(Enable);

         write_duty(0,0);

         write_duty(1,0);

         write_duty(2,0);

         output_low(motorX1);

         output_low(motorX2);

         output_low(motorY1);

         output_low(motorY2);

         output_low(motorZ1);

         output_low(motorZ1);

         output_low(RELAY1);

         output_low(RELAY2);

         output_low(RELAY3);

         output_low(RELAY4);

          break;   

case 'r':

        output_low(RELAY1);

       break;

case 'R':

         output_high(RELAY1);

       break;       

case 'p':

output_low(RELAY2);

 

       break;

case 'P':

output_high(RELAY2);

      

       break;

case 'i':

output_low(RELAY3);

    

       break;

case 'I':


output_high(RELAY3);     

       break;

case 'j':

output_low(RELAY4);


       break;

       case 'J':

output_high(RELAY4);


       break;

    }

      }

      }

 

    

void main()

{


   set_tris_a(0b111111);   

   set_tris_b(0b00000000);

   set_tris_c(0b10000000);

   set_tris_d(0b00000000);

   set_tris_e(0b111);

    

      setup_timer_0(RTCC_INTERNAL|RTCC_8_BIT);

      enable_interrupts(INT_TIMER0);

 

        enable_interrupts(Global);         

        enable_interrupts(INT_RDA);

 

        setup_adc(ADC_CLOCK_INTERNAL);

    

        Write_Duty(0,0);

         Write_Duty(1,0);

         Write_Duty(2,0);

        // Write_Duty(3,0);

      

        output_b(0b00000000);

        output_d(0b00000000);

        output_c(0b10000000);

        output_high(Enable);

      

 

        ActualPoint_X = 0;

        SetPoint_X = 0;

        Enc_X = 0;   

      

        Enc_Y = 0;

        SetPoint_Y = 0;

        ActualPoint_Y = 0;

      

        output_low(PIN_C0);

        output_low(PIN_C1);

        output_low(PIN_C2);

        output_low(PIN_C3);

        output_low(PIN_C4);

    while (true)

   {

 

   //************************************* Eje X ********************************************

      Aux_X = Enc_X;        // Igualamos 'Aux_X' y 'Enc_X' para luego comparar cuando cambie 'ENC'.

      Enc_X = porta & 3;  // Aislamos RA0 y RA1 como un número de 2 bits y se carga en la  variable 'Enc_X'. 12

                              

          if ((Aux_X == 3)&&(Enc_X == 1)) { ActualPoint_X++;  }  // 000011 and 000001

          if ((Aux_X == 1)&&(Enc_X == 0)) { ActualPoint_X++;  }  // 000001 and  000000   

          if ((Aux_X == 0)&&(Enc_X == 2)) {ActualPoint_X ++;  }  // 000000 and  000010           

          if ((Aux_X == 2)&&(Enc_X == 3)) { ActualPoint_X++;  }  // 000010  and 000011

        

          if ((Aux_X == 1)&&(Enc_X == 3)) { ActualPoint_X--;  }

          if ((Aux_X == 0)&&(Enc_X == 1)) { ActualPoint_X--;  }

          if ((Aux_X == 2)&&(Enc_X == 0)) { ActualPoint_X--;  }

          if ((Aux_X == 3)&&(Enc_X == 2)) { ActualPoint_X--;  }

        

   if(ActualPoint_X == SetPoint_X ){

        

               output_low(motorX1);

               output_low(motorX2);

          

               Write_Duty(0,0);

       }

 

    if(ActualPoint_X < SetPoint_X){

               output_high(motorX1);

               output_low(motorX2);

             }

     if(ActualPoint_X > SetPoint_X){

               output_low(motorX1);

               output_high(motorX2);

        }

      // set_pwm1_duty(200);

       Write_Duty(0,2);

 //*********************************** Eje Y   *******************************************

 

    Aux_Y = Enc_Y;        // Igualamos 'Aux_Y' y 'Enc_Y' para luego comparar cuando cambie 'Enc_Y'.

      Enc_Y = porta & 12;  // Aislamos RA2 y RA3 como un número de 2 bits y se carga en la  variable 'Enc_Y'. 12Aux_Y

                              

          if ((Aux_Y == 12)&&(Enc_Y == 4)) { ActualPoint_Y++;  }  // 001100 and 000100

          if ((Aux_Y == 4)&&(Enc_Y == 0)) { ActualPoint_Y++;  }   // 00100 and  000000

          if ((Aux_Y == 0)&&(Enc_Y == 8)) {ActualPoint_Y ++;  }   // 000000 and  001000       

          if ((Aux_Y == 8)&&(Enc_Y == 12)) { ActualPoint_Y++;  }  // 001000  and 001100

        

          if ((Aux_Y == 4)&&(Enc_Y == 12)) { ActualPoint_Y--;  }

          if ((Aux_Y == 0)&&(Enc_Y == 4)) { ActualPoint_Y--;  }

          if ((Aux_Y == 8)&&(Enc_Y == 0)) { ActualPoint_Y--;  }

          if ((Aux_Y == 12)&&(Enc_Y == 8)) { ActualPoint_Y--;  }

    

   if(ActualPoint_Y == SetPoint_Y ){

        

               output_low(motorY1);

               output_low(motorY2);

            

               Write_Duty(1,0);

       }

 

    if(ActualPoint_Y < SetPoint_Y){

               output_high(motorY1);

               output_low(motorY2);

             }

     if(ActualPoint_Y > SetPoint_Y){

               output_low(motorY1);

               output_high(motorY2);

        }

    

   Write_Duty(1,2);

   //*********************************** Eje Z   *******************************************

 

    Aux_Z = Enc_Z;        // Igualamos 'Aux_Z' y 'Enc_Z' para luego comparar cuando cambie 'ENC'.

      Enc_Z = porta & 48;  // Aislamos RA4 y RA5 como un número de 2 bits y se carga en la  variable 'Enc_Z'. Aux_Z

                              

          if ((Aux_Z == 48)&&(Enc_Z == 16)) { ActualPoint_Z++;  }  // 110000 and 010000

          if ((Aux_Z == 16)&&(Enc_Z == 0)) { ActualPoint_Z++;  }   // 010000 and  000000

          if ((Aux_Z == 0)&&(Enc_Z == 32)) {ActualPoint_Z ++;  }   // 000000 and  100000 

          if ((Aux_Z == 32)&&(Enc_Z == 48)) { ActualPoint_Z++;  }  // 100000  and 110000

        

          if ((Aux_Z == 16)&&(Enc_Z == 48)) { ActualPoint_Z--;  }

          if ((Aux_Z == 0)&&(Enc_Z == 16)) { ActualPoint_Z--;  }

          if ((Aux_Z == 32)&&(Enc_Z == 0)) { ActualPoint_Z--;  }

          if ((Aux_Z == 48)&&(Enc_Z == 32)) { ActualPoint_Z--;  }

      

   if(ActualPoint_Z == SetPoint_Z ){

               output_low(motorZ1);

               output_low(motorZ2);

               Write_Duty(2,0);

       }

 

    if(ActualPoint_Z < SetPoint_Z){

               output_high(motorZ1);

               output_low(motorZ2);

             }

     if(ActualPoint_Z > SetPoint_Z){

               output_low(motorZ1);

               output_high(motorZ2);

        }

 

   Write_Duty(2,2);

 

 //*********************************** Limites X Y Z   *******************************************

 

 if (button(PIN_E0,0,255,10,B0,1))

      {

         printf("X");

      }

    

      if (button(PIN_E1,0,255,10,B1,1))

      {

          printf("Y");

      }

 if (button(PIN_E2,0,255,10,B2,1))

      {

          printf("Z");

      }

    }

 

 }
Diagrama.jpg
 
Última edición por un moderador:
No entiendo que es esto:
1648834775003.png
Pero si es el motor con encoder incorporado o algo así, te faltan unas cuantas cosas por conectar, el común y muy probablemente resistencias de pullup o de pushdown


No estoy muy puesto en C pero la declaración como long long me chirría.
 
No entiendo que es esto:
Ver el archivo adjunto 280061
Pero si es el motor con encoder incorporado o algo así, te faltan unas cuantas cosas por conectar, el común y muy probablemente resistencias de pullup o de pushdown
Si señor! es un motor de CC con encoder.
Los 3 pines de la izquierda son las señales A,B en cuadratura y el del medio el índice. Son señales de 0-5V y no necesitan pullup.

No estoy muy puesto en C pero la declaración como long long me chirría
No es para menos, son consecuencias del terror de los informáticos al hardware, donde una variable int y una long tienen diferente tamaño según el entorno. Todo por ese intento pelo***o de abstraerse del hardware.

En CCS int es 8 bits, long int es 16 y long long es 32. Pero en otros entornos int es de 32bits, long también 32 y long long 64. Pero a su vez depende si se compila para 16 , 32 o 64 bits.

Vienen a ser los Watts PMPO de la informática ;)
 
Última edición:
¿Que precisión tiene el encoder?
Los encoders que conozco tienen 400 pulsos por revolución o así, no más. Con 16 bits debería de bastar.
Si el encoder ya da 0-5V entonces tendrá alimentación aparte.
 
Gracias Mr Scooter y Mr Eduardo Por Sus comentarios Dejenme decirle Que el codigo Funciona Bien ,Fue um error Mio
en la nueva Targeta Que Implemente para este Proyecto,resulta que deje sin alimentacion Los tres Encoder,Por lo tanto
los motores giran sin parar.
Mr Scooter Mis Encoder son de 32 pulsos por Vuelta , ver Videos Publicados en YOUTUBE.
Me gustaria Saber si estan bien definidos los puerto o si necesito definirlo mejor , ya que no soy un buen Programador.
pero me la busco con lo que ustedes publican Gracias Por todo.
 
¿Que precisión tiene el encoder?
Los encoders que conozco tienen 400 pulsos por revolución o así, no más. Con 16 bits debería de bastar.
Si el encoder ya da 0-5V entonces tendrá alimentación aparte.
Al encoder del Proteus le ponés la cantidad de pulsos por vuelta que quieras.

Los encoders de máquinas herramienta generalmente son de 1000ppv para husillo y 2500ppv para ejes. Cuando tiene eje C (o B) pueden llegar a 360000ppv (resolución de 1 milésima de grado) , pero no los vas a ver mucho porque valen fortunas. En el taller el de mayor resolución que tenemos es para rotación de mesa y tiene 18000ppv.
 
...acaba de decir que 32 pero si, puede ser un sinfín de 1m que a 32 por revolución salen un montón .

No caí que hay que medir el husillo entero no vale resetear a cada vuelta.
 
Arriba