Autor Tema: Combinacion de Pasos Motor PAP  (Leído 6008 veces)

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

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Combinacion de Pasos Motor PAP
« en: 02 de Marzo de 2018, 10:08:16 »
Amigos del foro. Tengo desarrollado este pequeño codigo en el que con la ayuda de dos pulsadores logre mover dos motores PAP, es decir, presiono un boton y muevo un motor, presiono otro pulsador y muevo el otro motor.

Sencillo para ustedes jeje (a mi me costo), ahora lo que no e podido hacer es una rutina en la que al presionar un tercer pulsador pueda mover los dos motores pero.... y aqui mi problema, que al presionar ese tercer pulsador los pasos de los motores se combinen. Si, si presiono ese pulsador y de un paso el motor uno y luego un paso el motor dos, un paso el motor uno y luego un paso el motor dos y asi sucesivamente.. Alguna idea por Favor.

Código: C#
  1. #include <18F4550.h>                                                    
  2.          #use delay(clock=4000000,crystal=4000000)
  3.          #fuses XT,NOWDT,NOPROTECT,NOLVP,NODEBUG,PUT        
  4.          #byte porta=0xF80 #byte portb=0xF81 #byte portc=0xf82 #byte portd=0xf83 #byte porte=0xf84    
  5.          #define motor_off    output_e(0);
  6.          #define motor_uno    output_e(1);
  7.          #define motor_dos    output_e(2);
  8.  
  9.          byte const pap_1[4]={1,2,4,8};
  10.          byte const pap_2[4]={16,32,64,128};
  11.          int i,inicio=0,seleccion=0;
  12.          
  13.          #int_ccp1
  14.          void trata_ccp_1()
  15.          {inicio++; if (inicio>1) {inicio=0;}}
  16.          
  17.          #int_ccp2
  18.          void trata_ccp_2()
  19.          {seleccion++; if (seleccion>2) {seleccion=1;}}
  20.          
  21.          void main(void)
  22.          {        
  23.          set_tris_d(0x00);                              
  24.          PORTd = 0x00;  
  25.          setup_ccp1(CCP_CAPTURE_RE);
  26.          enable_interrupts (int_ccp1);
  27.          setup_ccp2(CCP_CAPTURE_RE);
  28.          enable_interrupts (int_ccp2);
  29.          enable_interrupts (global);
  30.          
  31.          while(TRUE)
  32.          {                                                      
  33.          if(inicio==0) {output_low(pin_c0); motor_off}  else output_high(pin_c0); output_d(0x00);
  34.          
  35.          if (inicio==1)
  36.          {
  37.                switch(seleccion)
  38.                {
  39.                case 1:  motor_uno for(i=0;i<4;i++) { output_d(pap_1[i]); delay_ms(150); }
  40.                         break;
  41.                case 2:  motor_dos for(i=0;i<4;i++) { output_d(pap_2[i]); delay_ms(150); }
  42.                         break;
  43.                         default:
  44.                }  
  45.          }                
  46.          }
  47.          }
« Última modificación: 02 de Marzo de 2018, 10:16:16 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Combinacion de Pasos Motor PAP
« Respuesta #1 en: 02 de Marzo de 2018, 10:36:23 »
No se porque todos los CCP pero... en realidad ahi estas dando 4 pasos por pulso.. Porque no mejor algo asi:

Código: C
  1. while(1)
  2. {
  3.         // Botones
  4.  
  5.         if (boton3presionado)
  6.         {
  7.                 i++;
  8.                 j++;
  9.         }
  10.         else if (boton2presionado)
  11.         {
  12.                 j++;
  13.         }
  14.         else if (boton1presionado)
  15.         {
  16.                 i++;
  17.         }
  18.  
  19.         // Proteccion de indice, si es mayor a 3, lo pone a 0
  20.  
  21.         if(j >= sizeof pap_2) j=0;
  22.         if(i >= sizeof pap_1) i=0;
  23.  
  24.         //Salida
  25.  
  26.         output_d(pap_1[i] | pap_2[j]);
  27.  
  28.         // delay entre pasos
  29.  
  30.         delay_ms(150);
  31. }

Ahora si quisiera actuar que sea un paso para un motor y un paso para el otro solo debo actuar sobre los indices, creo otro variable para indicarme cual debo aumentar.

Y lo cambio por esto:

Código: C
  1. if (boton3presionado)
  2.         {
  3.                 if(turnoPAP1)
  4.                 {
  5.                         i++;
  6.                         turnoPAP1 = 0;
  7.                 }
  8.                 else
  9.                 {
  10.                         j++;
  11.                         turnoPAP1 = 1;
  12.                 }

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Combinacion de Pasos Motor PAP
« Respuesta #2 en: 02 de Marzo de 2018, 10:58:35 »
Gracias por su pronta ayuda. En verdad es bueno saber como alguien mas le da solución a las cosas.

Una duda con el OR | ,ahora en la salida para avanzar los dos motores al mismo tiempo.

        if (boton3presionado)
        {
                i++;
                j++;
        }
if(j >= sizeof pap_2) j=0;
        if(i >= sizeof pap_1) i=0;

Aqui la duda: output_d(pap_1 | pap_2[j]); o seria en vez de | el & para que avancen los dos al mismo tiempo?.
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Combinacion de Pasos Motor PAP
« Respuesta #3 en: 02 de Marzo de 2018, 11:33:43 »
es una OR

pensa tus arrays  en binario

pap_1
0: 0b0000 0001
1: 0b0000 0010
2: 0b0000 0100
3: 0b0000 1000

pap_2
0: 0b0001 0000
1: 0b0010 0000
2: 0b0100 0000
3: 0b1000 0000


El problema que habia antes es que si hacias output de un solo array, el otro bobinado su salidas pasaban a 0 todas. y la idea es que se mantenga energizada la bobina sobre ese paso.

Entonces suponete esto:

i = 2
j = 3

pap_1[2] = 0b0000 0100
pap_2[3] = 0b1000 0000 

si hago una OR la salida queda:

0b1000 0100

Si aumento j, por ejemplo, pasaria a 0. y la OR me quedaria

0b0001 0100

Observaras que el otro motor sigue como estaba, nunca se modifico. Si hago una AND &, el resultado va a ser 0 siempre ya que una AND entre un 0 y un 1 es 0

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Combinacion de Pasos Motor PAP
« Respuesta #4 en: 02 de Marzo de 2018, 11:38:51 »
Genial... Gracias  KILLERJC ahora lo entiendo mejor. Un saludo.
El señor es mi pastor,  nada me faltará.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Combinacion de Pasos Motor PAP
« Respuesta #5 en: 16 de Marzo de 2018, 08:37:24 »
Ahora me surge otra duda, como puedo hacer para mover estos motores pap pero con interrupcion del timer0 ya que si al momento de estar el motor en movimiento  ejecuto otra instrucción. Alguna idea...
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Combinacion de Pasos Motor PAP
« Respuesta #6 en: 16 de Marzo de 2018, 12:01:07 »
Depende de que queres hacer con tu motor.

Queres que el motor funcione solo, y avance solo? y que con los botones, detener o no el avance?
Queres que modificar la velocidad de avance con los botones?

Explica bien como queres que funcione.


Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Combinacion de Pasos Motor PAP
« Respuesta #7 en: 17 de Marzo de 2018, 01:55:37 »
Hola killer_jc.  Dos motores con velocidad constante cada uno con su pulsador que gire mientras presiono un pulsador. 
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Combinacion de Pasos Motor PAP
« Respuesta #8 en: 17 de Marzo de 2018, 08:29:27 »
Entonces todo (sin el delay) el codigo que te pase antes lo podes usar en la interrupcion, si son 2 botones nomas, entonces:

Código: C
  1. void interrupcionTMR(void)
  2. {
  3.         //Limpieza de flag y recarga de TMR
  4.  
  5.         // Aumentamos si esta presionado
  6.  
  7.         if (boton2presionado) j++;
  8.         if (boton1presionado) i++;
  9.  
  10.         // Proteccion de indice, si es mayor a 3, lo pone a 0
  11.  
  12.         if(j >= sizeof pap_2) j=0;
  13.         if(i >= sizeof pap_1) i=0;
  14.  
  15.         //Salida
  16.  
  17.         output_d(pap_1[i] | pap_2[j]);
  18.  
  19. }

La velocidad lo va a dar el tiempo de interrupcion del Timer.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Combinacion de Pasos Motor PAP
« Respuesta #9 en: 18 de Marzo de 2018, 21:35:41 »
KILLER JC o amigos del foro, después de un rato de estarle dando teclazos a la pc llegue aquí. Sugerencias...por favor.

Código: C++
  1. #include <18f4550.h>
  2.          #fuses PLL1,CPUDIV1,USBDIV,XTPLL,NOFCMEN,NOIESO,PUT,NOBROWNOUT,VREGEN,NOWDT,NOPBADEN,MCLR,NOSTVREN,NOLVP,NODEBUG,NOPROTECT,NOSTVREN,NOCPB,NOWRT,NOWRTC
  3.          #use delay(clock=48000000,crystal=4000000)
  4.          
  5.          int i=0;     // Llevara un conteo de interrupciones    
  6.          byte const pap_1[4]={1,2,4,8};   // secuencia sentido horario
  7.          byte const pap_0[4]={0,0,0,0};   // limpia la secuencia
  8.          
  9.          #INT_TIMER0                          
  10.          void isr_timer0()
  11.          {        
  12.          i++; if(i>3){i=0;}
  13.          if(!input(pin_c1)){ output_d(pap_1[i]); }else output_d(pap_0[i]);
  14.          set_timer0(56161);                     // recargamos el timer0 para 200ms aprox.
  15.          }
  16.                  
  17.          void main()
  18.          {        
  19.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
  20.          set_timer0(56161);                     // recargamos el timer0 para 200ms aprox.
  21.          enable_interrupts(INT_TIMER0);
  22.          enable_interrupts(GLOBAL);                
  23.            
  24.          while(true)
  25.          {
  26.          output_high(pin_b0); delay_ms(1000);
  27.          output_low(pin_b0); delay_ms(1000);
  28.          }                          
  29.          }

De lo que no estoy seguro es que si esos 200 ms es entre pulso y pulso o bien es cada que termina los cuatro pulsos y vuelve a cero.

Acepto correcciones, ayudas y regaños.. jejejeje.
« Última modificación: 18 de Marzo de 2018, 22:04:36 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Combinacion de Pasos Motor PAP
« Respuesta #10 en: 18 de Marzo de 2018, 22:20:37 »
Respecto a si los 200ms son entre pulsos o entre cada 4 pulsos, esos 200ms es cada pulso que se le da al motor y no cada 4. Si deseas que sea cada 4, entonces reduci el tiempo de la interrupcion a 50ms, de esa forma ya cuando pasen los 4 seran 200ms.

Algunas correcciones:
¿Por que crear un array con 4 ceros?, simplemente usar un 0.
Y la asignacion del Timer al comienzo de la interrupcion, un poco menos de error.

Código: C
  1. #INT_TIMER0                          
  2.          void isr_timer0()
  3.          {        
  4.                 set_timer0(56161);                     // recargamos el timer0 para 200ms aprox.
  5.                 i++;
  6.                 if(i>3){i=0;}
  7.                 if(!input(pin_c1))
  8.                 {
  9.                         output_d(pap_1[i]);
  10.                 }
  11.                 else output_d(0);
  12.          }

y en el while del main, es mas rapido si usas output_toggle

Código: C
  1. while(true)
  2.          {
  3.          output_toggle(pin_b0); delay_ms(1000);
  4.          }

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Combinacion de Pasos Motor PAP
« Respuesta #11 en: 20 de Marzo de 2018, 09:25:10 »
Desde el inicio de este tema había tenido varias dudas que gracias a su ayuda están aclaradas por completo. Esto es lo que llevo hasta ahora (no por mi, si no por su ayuda KILLER JC).

Estoy moviendo 2 Motores a pasos con 4 pulsadores. El primer motor en el eje x+, x-; el segundo motor y+,y-. Pues hasta ahora todo bien con la interrupción que los mueve (aunque ahora todo simulado en proteus). El siguiente paso que me falta es detectar cuando llegue al limite del eje izquierdo o derecho con un fin de carrera, en esta parte:

Código: C++
  1. #define motor1_Xp   !input(PIN_C0)
  2.          #define motor1_Xn   !input(PIN_C1)
  3.          #define motor2_Yp   !input(PIN_C2)
  4.          #define motor2_Yn   !input(PIN_C4)
  5.  
  6.          int i=0;                       // Llevara un conteo de interrupciones    
  7.          const unsigned int pap_1p[4]={1,2,4,8};
  8.          const unsigned int pap_1n[4]={8,4,2,1};
  9.          const unsigned int pap_2p[4]={16,32,64,128};
  10.          const unsigned int pap_2n[4]={128,64,32,16};
  11.          
  12.         #INT_TIMER0                          
  13.          void isr_timer0(void)
  14.          {
  15.          set_timer0(56161);                                          // recargamos el timer0 para 200ms aprox.
  16.          i++; if(i>3){i=0;}
  17.               if(motor1_Xp){ output_d(pap_1p[i]); }         // motor1 eje positivo con giro horario
  18.          else if(motor1_Xn){ output_d(pap_1n[i]); }       // motor1 eje negativo con giro anti-horario
  19.          else if(motor2_Yp){ output_d(pap_2p[i]); }
  20.          else if(motor2_Yn){ output_d(pap_2n[i]); }
  21.          else output_d(0);        
  22.          }

El fin de carrera sera un micro switch al limite del eje que al ser presionado, el motor tendrá que detenerse y así sabrá que no puede avanzar mas en ese sentido (esa fue mi idea, no se de que otra manera detectar el fin de recorrido del motor).

Y también no se como hacer esa condición; si con un while para decirle que se mueva mientras no llegue a presionar el micro switch o con un if....

Gracias por su ayuda...

« Última modificación: 20 de Marzo de 2018, 09:31:43 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Combinacion de Pasos Motor PAP
« Respuesta #12 en: 20 de Marzo de 2018, 13:43:34 »
Perdon, eso fue por usar el codigo tuyo al implementar el mio. Ese codigo trae un problema al usarlo en muchas salidas. Como vistes antes yo procedi a usar 2 indices, uno para cada motor, La idea es que tengas solo 2 arrays con los valores de salida de lso bobinados y te manejes con el indice nomas... Me explico:

Código: C
  1. int indiceX = 0;                       // Indice para el motor X
  2.          int indiceY = 0;                       // Indice para el motor Y
  3.  
  4.          const unsigned int pap_m1[4]={1,2,4,8};
  5.          const unsigned int pap_m2[4]={16,32,64,128};
  6.  
  7.         #INT_TIMER0                          
  8.          void isr_timer0(void)
  9.          {
  10.  
  11.             set_timer0(56161);                              // recargamos el timer0 para 200ms aprox.
  12.  
  13.             // Revisamos si debemos avanzar o no
  14.             // Motor en X, primero revisamos que no estemos al final sea cual sea las 2 puntas
  15.             if(motorX_Fp && motor1_Xp) { indiceX++; }              // motor1 eje X con giro horario
  16.             else if(motorX_Fn && motor1_Xn) { indiceX--; }         // motor1 eje X con giro antihorario
  17.  
  18.             // Motor Y
  19.             if(motorY_Fp && motor1_Yp){ indiceY++; }            // motor2 eje Y con giro horario
  20.             else if(motorY_Fn && motor2_Yp){ indiceY--; }       // motor2 eje Y con giro anti-horario
  21.          
  22.             // Ahora procedemos a corregir los indices en caso de que superen los valores permitidos.
  23.             // Si es igual al tamaño del array ( 4 ) entonces se paso ( era 3 y se incremetno en 1) y hay que hacerlo 0.
  24.             // Si es mayor a eso, quiere decir que era 0 y se resto 1, por lo tanto su indice ahora debe ser 3.
  25.  
  26.             // Indice X
  27.             if(indiceX == sizeof pap_m1) { indiceX = 0; }
  28.             else if (indiceX > sizeof pap_m1) {indiceX = 3;}
  29.  
  30.             // Indice Y
  31.             if(indiceY == sizeof pap_m1) { indiceY = 0; }
  32.             else if (indiceY > sizeof pap_m1) {indiceY = 3;}            
  33.  
  34.  
  35.             // Actualizamos las salidas:
  36.             output_d(pap_m1[indiceX] | pap_m2[indiceY]);
  37.            
  38.          }

motorY_Fp , motorY_Fn, motorX_Fp, motorX_Fn son 4 finales de carrera. Cada uno en su sentido.
Usualmente lo que se hace en estos casos es usar solo 2 finales de carrera (aunque los 4 estarian buenos como para proteccion). Asi al comienzo te vas a X=0 Y=0, que seria el punto donde ambos finales de carrera se activan. Y de alli te moves en X o en Y, esto seria relativo a la posicion 0,0. Esto no se tuvo en cuenta en el codigo. Pero al ser manejado con botones no creo que te preocupe.

El codigo que pase, hace que primero se revise el final de carrera y luego el boton. Hay que tener consideracion de cuando se presionan ambos botones al mismo tiempo, seria bueno tener una condicion extra que se asegure que solo 1 boton se encuentra presionado.
Otra de las cosas es que siempre estan activas las bobinas del PaP. En tu codigo veo que eso no es asi.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Combinacion de Pasos Motor PAP
« Respuesta #13 en: 22 de Marzo de 2018, 09:56:47 »
Un saludo KILLER JC, e implementado el código que me pasaste y veo que los dos motores siempre están funcionando presione o no los pulsadores. Pero si quito los fines de carrera motorY_Fp , motorY_Fn, motorX_Fp, motorX_Fn, entonces el código funciona pero no sabe cuando llego al limite para detener el motor. Algo mas, e cambiado al puerto(b) las entradas de los pulsadores.

Código: C++
  1. #define motor1_Xp   !input(PIN_B0)
  2.          #define motor1_Xn   !input(PIN_B1)
  3.          #define motor2_Yp   !input(PIN_B2)
  4.          #define motor2_Yn   !input(PIN_B3)
  5.          #define motorX_Fp   !input(PIN_B4)
  6.          #define motorX_Fn   !input(PIN_B5)
  7.          #define motorY_Fp   !input(PIN_B6)
  8.          #define motorY_Fn   !input(PIN_B7)
  9.          
  10.          int indiceX = 0;                       // Indice para el motor X
  11.          int indiceY = 0;                       // Indice para el motor Y
  12.          
  13.          const unsigned int pap_m1[4]={1,2,4,8};
  14.          const unsigned int pap_m2[4]={16,32,64,128};
  15.          
  16.          #INT_TIMER0                          
  17.          void isr_timer0(void)
  18.          {
  19.          set_timer0(56161);                              // recargamos el timer0 para 200ms aprox.
  20.          // Revisamos si debemos avanzar o no
  21.          // Motor en X, primero revisamos que no estemos al final sea cual sea las 2 puntas
  22.          if(motorX_Fp && motor1_Xp) { indiceX++; }         // motor1 eje X con giro horario
  23.          else if(motorX_Fn && motor1_Xn) { indiceX--; }       // motor1 eje X con giro antihorario
  24.          
  25.          // Motor Y
  26.          if(motorY_Fp && motor2_Yp){ indiceY++; }            // motor2 eje Y con giro horario
  27.          else if(motorY_Fn && motor2_Yn){ indiceY--; }       // motor2 eje Y con giro anti-horario
  28.          
  29.          // Ahora procedemos a corregir los indices en caso de que superen los valores permitidos.
  30.          // Si es igual al tamaño del array ( 4 ) entonces se paso ( era 3 y se incremetno en 1) y hay que hacerlo 0.
  31.          // Si es mayor a eso, quiere decir que era 0 y se resto 1, por lo tanto su indice ahora debe ser 3.
  32.  
  33.          if(indiceX == sizeof pap_m1) { indiceX = 0; }                     // Indice X
  34.          else if (indiceX > sizeof pap_m1) {indiceX = 3;}
  35.  
  36.          if(indiceY == sizeof pap_m2) { indiceY = 0; }                     // Indice Y
  37.          else if (indiceY > sizeof pap_m2) {indiceY = 3;}            
  38.          
  39.          output_d(pap_m1[indiceX] | pap_m2[indiceY]);                      // Actualizamos las salidas:
  40.          }
  41.                            
  42.          void main()
  43.          {      
  44.          porta=0x00; portb=0x00; portc=0x00; portd=0x00; porte=0x00;  
  45.          set_tris_a(0b11111111);                                                    
  46.          set_tris_b(0b00000000);
  47.          set_tris_c(0b11111111);
  48.          set_tris_d(0b00000000);
  49.          set_tris_e(0b11111111);
  50.          setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
  51.          set_timer0(56161);                                                         // recargamos el timer0 para 200ms aprox.
  52.          enable_interrupts(INT_TIMER0);
  53.          enable_interrupts(GLOBAL);                
  54.            
  55.          while(true)
  56.          {
  57.          output_toggle(pin_c0); delay_ms(200);        
  58.          }                          
  59.          }

Asi funciona perosin saber donde llego al limite
Código: C++
  1. if(motor1_Xp) { indiceX++; }         // motor1 eje X con giro horario
  2.          else if(motor1_Xn) { indiceX--; }       // motor1 eje X con giro antihorario

Y en realidad los motores si iniciaran (-X,-Y), es decir cuando dos fines de carrera estén pulsados.

Tardo en responder por que trato de entender la lógica del programa,gracias por tu inmensa ayuda.
« Última modificación: 22 de Marzo de 2018, 12:29:54 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.

Desconectado Abner_emanuel

  • PIC16
  • ***
  • Mensajes: 160
Re:Combinacion de Pasos Motor PAP
« Respuesta #14 en: 23 de Marzo de 2018, 09:27:57 »
Una disculpa KILLER JC el programa realmente funciona!!!. Yo estaba adaptando un par de cosas mal. 1) al emigrar al Puerto_b los pulsadores y fines de carrera los tenia como salida y no como entrada. Estaba duplicando nombres en el proteus lo cual daba una simulación errónea (nunca se detenían los motores).

Con esos cambios al código anterior quedan funcionando los fines de carrera, es decir al estar funcionado el motor y presionar su fin de carrera, el motor de detiene.

La siguiente tarea que tendrá que hacer el pic es la siguente:

No importando el lugar en donde se encuentren los motores, al presionar un nuevo pulsador, entonces los motores deberán de
regresar al origen (-X,Y) del plano cartesiano. Eseorigen podria ser los finales de carrera #define motorX_Fn   !input(PIN_B5) y #define motorY_Fp   !input(PIN_B6) que corresponden a (-X,Y). Un saludo y gracias por su ayuda en este trabajo que me trae entusiasmado.

Alguna idea para esto?

« Última modificación: 23 de Marzo de 2018, 09:58:40 por Abner_emanuel »
El señor es mi pastor,  nada me faltará.


 

anything