Autor Tema: Construccion maquina de posicionamiento 2D -3D impresora, cnc, ...  (Leído 14521 veces)

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

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Construccion maquina de posicionamiento 2D -3D impresora, cnc, ...
« Respuesta #30 en: 23 de Octubre de 2015, 02:07:24 »
Como que el programa en si no tiene demasiado secreto. El secreto esta en como calcula eso.. Es decir la primer linea.

Dependiendo de la velocidad que ingrese a la funcion ( la velocidad ES un numero flotante de doble precision de 64bits ) calcula la cantidad de microsegundos que debe esperar para dar medio paso. Por eso el "half", como no posee ningun maldito parentesis... la funcion por el orden de precedencia. seria algo asi:

(((1 / stepInFullRound) / speedRPS) / 2) * 1E6 , o que es igual que hacer:

\frac{1}{2*stepInFullRound*speedRPS} * 1e6

Esto lo probe en C++ en mi computadora, por que el orden de precedencia me confundia. Mas que nada los cast no estaba seguro de como los tomaba. Para valores de velocidad de 100 RPS te da valores muy chicos, tenes que hablar de valores como 0.00002 RPS como para obtener un numero que ya use mas de 16bits

Finalmente eso se va a guardar en un long, un numero entero y sin comas. Si el valor supera los 65535 , que es lo maximo para 16bits y que debe ser el maximo delay que soporta la funcion "delayMicroseconds" entonces calcula por cuanto veces se excedio de ese valor y lo guarda en overflowCount. Supongamos que tenes 100000 (0x186A0) en holdTime_us, entonces overflowCount va a ser 1,  si tenes 280000 (0x445C0) overflowCount va a ser 4. Esto es mas simple de ver en hexadecimal si observas el valor fuera de los 16bits es tu overflowCount...

Finalmente debemos cumplir con ese "resto"  y por eso castea el holdtime_us a 16 bits. Es decir elimina los demas bits y se queda con solo lso 16 bits de menos peso, o por ponerlo de otra forma, lo que no lo hizo con el overflowCount, debe hacerlo aca asi alcanzar el valor del delay
« Última modificación: 23 de Octubre de 2015, 02:11:38 por KILLERJC »

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Construccion maquina de posicionamiento 2D -3D impresora, cnc, ...
« Respuesta #31 en: 23 de Octubre de 2015, 12:03:56 »
muy bien,  analizando la respuesta de KILLERJC

Código: C++
  1. void holdHalfCycle(double speedRPS) {
  2.   long holdTime_us = (long)( 1.0 / ( (double) stepsInFullRound / speedRPS / 2.0 ) * 1E6);
  3.   int overflowCount = holdTime_us / 65535;
  4.   for (int i = 0; i < overflowCount; i++) {
  5.     delayMicroseconds(65535);
  6.   }
  7.   delayMicroseconds((unsigned int) holdTime_us);
  8. }

segun zator
http://www.zator.com/Cpp/E2_2_4.htm

1: un double tiene 8 bytes 64 bits y el dominio de operacion es 2.23e-308 <= |X| <= 1.79e308,   Precisión científica (15-dígitos),

2: un long tiene 4 bytes 32 bits y el dominio de operacion es -2,147,483,648 <= X <= 2,147,483,647   

segun lo anterior el parametro speedRPS los valores logicos irian entre [0 y 1.79e308], no tiene sentido ingresar valores negativos, ademas C++ no permite restringir  positivamente un double como UNSIGNED LONG

segun entiendo el motor NEMA17 en giro completo requiere 200 pasos, ya que el paso es de 1.8 grados * 200 = 360 grados es decir 1 vuelta, en el codigo original, la variable  stepsInFullRound se define con valor 400 por que el micropaso se definio como HALF

Código: C++
  1. const int stepsInFullRound = 400; // half stepping
  2.   digitalWrite(DRIVER8825_MODE0_PIN, HIGH); // 1
  3.   digitalWrite(DRIVER8825_MODE1_PIN, LOW);  // 0
  4.   digitalWrite(DRIVER8825_MODE2_PIN, LOW);  // 0

Con los valores anteriores y speedRPS=6, expresando la sentencia long holdTime_us = (long)(1.0 / (double) stepsInFullRound / speedRPS / 2.0 * 1E6); como funcion matematica

f(speedRPS,stepsInFullRound)=integerPart(1E6/(speedRPS*stepsInFullRound))

f(6,400)=integerPart(1E6/(speedRPS*stepsInFullRound)) => 208.333333333 => 208

ahora

int overflowCount = holdTime_us / 65535;

208/(2^16-1) => 0.00317 => 0

el ciclo for no se efectúa

  for (int i = 0; i < overflowCount; i++) {
    delayMicroseconds(65535);
  }

solo la siguiente sentencia

delayMicroseconds((unsigned int) holdTime_us);

delayMicroseconds(208) // 208us = 0.000208s

es correcto este calculo?

ahora si speedRPS = 0.019

f(0.019,400) = 65789.4736842 => 65789

65789/(2^16-1) => 1.00387579156 => 1

el ciclo for se efectua una sola vez y hace un retardo de delayMicroseconds(65535); 65535us
mas
delayMicroseconds(65789) // 65789us

en total 131324us verdad? esto es 0.131324s
« Última modificación: 23 de Octubre de 2015, 13:02:18 por CompSystems »
Desde Colombia

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Construccion maquina de posicionamiento 2D -3D impresora, cnc, ...
« Respuesta #32 en: 23 de Octubre de 2015, 13:12:05 »
una nota de https://www.arduino.cc/en/Reference/DelayMicroseconds


Hace una pausa en el programa para la cantidad de tiempo (en microsegundos) especificado como parámetro. Hay mil microsegundos en un milisegundo, y un millón de microsegundos en un segundo.


Actualmente, el valor más grande que va a producir un retraso exacto es 16383. Esto podría cambiar en el futuro . Para retrasos de más de unos pocos miles de microsegundos, debe usar delay() en su lugar.
Desde Colombia

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Construccion maquina de posicionamiento 2D -3D impresora, cnc, ...
« Respuesta #33 en: 23 de Octubre de 2015, 13:24:11 »
Citar
int overflowCount = holdTime_us / 65535;

208/(2^16-1) => 0.00317 => 0

el ciclo for no se efectúa

  for (int i = 0; i < overflowCount; i++) {
    delayMicroseconds(65535);
  }

solo la siguiente sentencia

delayMicroseconds((unsigned int) holdTime_us);

delayMicroseconds(208) // 208us = 0.000208s

es correcto este calculo?

ahora si speedRPS = 0.019

f(0.019,400) = 65789.4736842 => 65789

65789/(2^16-1) => 1.00387579156 => 1

el ciclo for se efectua una sola vez y hace un retardo de delayMicroseconds(65535); 65535us
mas
delayMicroseconds(65789) // 65789us

en total 131324us verdad? esto es 0.131324s

El primer calculo si. el segundo NO, el segundo con tus pasos (copio y pego y le cambio los valores ) quedaria:
(En negrita lo corregido)

ahora si speedRPS = 0.019

f(0.019,400) = 65789.4736842 => 65789

65789/(2^16-1) => 1.00387579156 => 1

el ciclo for se efectua una sola vez y hace un retardo de delayMicroseconds(65535); 65535us
mas 65789 - 65536(esto es 2^16) = 253
delayMicroseconds(253) // 253us


La suma total de ambas es 65788, un delay de 65535 y otro de 253 ( se pìerde 1 us por cada for, ya que no llega a 65536

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Construccion maquina de posicionamiento 2D -3D impresora, cnc, ...
« Respuesta #34 en: 23 de Octubre de 2015, 13:50:32 »
ok, ósea que la siguiente sentencia
delayMicroseconds((unsigned int) holdTime_us);

seria equivalente matemáticamente como

delayMicroseconds(holdTime_us - 2^16);
Desde Colombia

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Construccion maquina de posicionamiento 2D -3D impresora, cnc, ...
« Respuesta #35 en: 23 de Octubre de 2015, 13:54:57 »
no, seria el equivalente a :

delayMicroseconds((unsigned int) holdTime_us);  ==
delayMicroseconds( holdTime_us & 0xFFFF );

Por eso mismo te decia que es mas facil verlo en hexadecimal, 65789 = 0x100FD , o separado en 16 bits 0x1 00FD , 0x1 es el for y 0x00FD (253) es tu "resto" de los 65535 (menos 1 obviamente)

Ojo esto es un aproximado ya que se divide por 65535 y no por 65536, pero es mas simple de verlo asi. Si queres que sea exacto deberia haber realizado:

delayMicroseconds( holdTime_us % 65535 );

Peeeero, es mas rapido lo primero. Es mas, es totalmente malo dividir asi (como lo hizo esa persona)...en terminos de eficiencia.
« Última modificación: 23 de Octubre de 2015, 14:13:16 por KILLERJC »

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Construccion maquina de posicionamiento 2D -3D impresora, cnc, ...
« Respuesta #36 en: 25 de Octubre de 2015, 16:24:43 »
ok, gracias KILLERJC

Un amigo de Chile muestra en su video como Enderezar varillas roscadas de un eje Z RepRap Prusa

El dice: Tener varillas roscadas perfectamente rectas podría ser una parte crucial de su impresora 3D. En este vídeo os muestro un método para hacer eso. Los resultados son bastante buenos.

Desde Colombia

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
Re:Construccion maquina de posicionamiento 2D -3D impresora, cnc, ...
« Respuesta #37 en: 10 de Noviembre de 2015, 10:44:28 »
Continuando con el proyecto, aun sobre una protoboard y con partes recicladas de una impresora

En las pruebas que estoy actualmente realizando, tengo 2 motores, a veces solo funciona uno a la vez y el otro motor cuando no trabaja genera un ruido (me parece que también una leve vibración), entonces decidí deshabilitarlo por software (pin ENABLE del DRIVER8824-5 ). Mientras este PIN esta en HIGH deshabilita el funcionamiento del DRIVER por ende (libera el eje del motor), cuando pasa a LOW (habilita el funcionamiento del DRIVER ).

Se anexa código simplificado al anterior (adaptado de un tuto en francés), usa el pin ENABLE, lo que no logro es poner en practica los pines RESET y SLEEP, ¿Cual es la función de estos pines cuando se llevan a LOW? no observo ningún efecto sobre el motor

 digitalWrite( pinSleep  , LOW);  //
 digitalWrite( pinReset  , LOW);  //
 

Código: C++
  1. // Un tutoriel http://wiki.mchobby.be/index.php?title=DRV8825
  2. // Ou Acheter un StepStick DRV8825
  3. // http://shop.mchobby.be/product.php?id_product=454
  4. //
  5. // Microcontroller: Arduino MEGA
  6. // DRV8825
  7. #define pinEnable  52 // Activation du driver/pilote
  8. #define pinMode0   50 //
  9. #define pinMode1   48 //
  10. #define pinMode2   46 //
  11. #define pinReset   44 //
  12. #define pinSleep   42 //    
  13. #define pinStep    40 // Signal de PAS (avancement)
  14. #define pinDir     38 // Direction
  15. #define pinFAULT   36  
  16.  
  17. #define ENABLE_ HIGH
  18. #define ENABLE_INVL !HIGH // inverse logic
  19.  
  20. #define DISABLE_ LOW
  21. #define DISABLE_INVL !LOW // inverse logic
  22.  
  23. void setup(){
  24.   Serial.begin(9600);
  25.   Serial.println("Test DRIVER8825");
  26.  
  27.   pinMode( pinEnable, OUTPUT );
  28.   pinMode( pinMode0,  OUTPUT );
  29.   pinMode( pinMode1,  OUTPUT );
  30.   pinMode( pinMode2,  OUTPUT );
  31.   pinMode( pinReset , OUTPUT );
  32.   pinMode( pinSleep , OUTPUT );
  33.   pinMode( pinDir   , OUTPUT );
  34.   pinMode( pinStep  , OUTPUT );
  35.  
  36.   digitalWrite( pinMode0, LOW );
  37.   digitalWrite( pinMode1, LOW );
  38.   digitalWrite( pinMode2, LOW );
  39.   //digitalWrite( pinFAULT, LOW );
  40. }
  41.  
  42. void loop(){
  43.   int i = 0;
  44.   // Al inicio y fin el motor debe estar libre
  45.   Serial.println("eje del motor libre (no activo)");
  46.   digitalWrite( pinEnable, DISABLE_INVL ); // HIGH: logique inversée
  47.   delay( 5000 );
  48.   Serial.println("eje del motor bloqueado (funcionamiento)");
  49.   digitalWrite( pinEnable, ENABLE_INVL ); // LOW: logique inversée
  50.  
  51.   digitalWrite( pinDir   , HIGH); // Direction avant
  52.   digitalWrite( pinStep  , LOW);  // Initialisation de la broche step
  53.  
  54.  
  55.  digitalWrite( pinReset  , HIGH);  //
  56.  digitalWrite( pinSleep  , HIGH);  //
  57.  
  58.   // Avance de 200 pas
  59.   for( i=0; i<200; i++){
  60.     digitalWrite( pinStep, HIGH );
  61.     delayMicroseconds( 2000 );
  62.     digitalWrite( pinStep, LOW );
  63.     delayMicroseconds( 2000 );
  64.   }
  65.  
  66.   // deshabilitar temporalmente
  67.   Serial.println("eje del motor libre (no activo)");
  68.   digitalWrite( pinEnable, DISABLE_INVL ); // HIGH: logique inversée
  69.   delay( 3000 );
  70.   Serial.println("eje del motor bloqueado (funcionamiento)");
  71.   digitalWrite( pinEnable, ENABLE_INVL ); // LOW: logique inversée
  72.  
  73.   digitalWrite( pinDir, LOW); // Direction avant
  74.   // Refaire 200 pas dans l'autre sens
  75.   for( i=0; i<200; i++){
  76.     digitalWrite( pinStep, HIGH );
  77.     delayMicroseconds( 2000 );
  78.     digitalWrite( pinStep, LOW );
  79.     delayMicroseconds( 2000 );
  80.   }
  81.  
  82.  
  83.   Serial.println("eje del motor libre (no activo)");
  84.   digitalWrite( pinEnable, DISABLE_INVL ); // HIGH: logique inversée
  85.  
  86.   Serial.println("Fin de programme");
  87.     // Fin et blocage du programme
  88.   // Presser [reset] pour recommander
  89.   while( true );
  90. }
  91. }

He notado que si, desconecto la fuente de alimentación y muevo el carro del motor, se iluminan los LEDs pilotos del proyecto, el motor funciona como un dinamo, puede ser peligroso y dañar el sistema de control
« Última modificación: 10 de Noviembre de 2015, 11:13:47 por CompSystems »
Desde Colombia

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
« Última modificación: 02 de Julio de 2016, 22:50:50 por CompSystems »
Desde Colombia