Ronroneos y vibraciones en nema 17 con RemoteXY

Hola a tod@s desde de mi ultima consulta ha pasado un tiempo, he logrado, no sin ayuda conformar un programa totalmente funcional controlado por bluetooth con la aplicación RemoteXY.

El funcionamiento se basa en pequeñas rotaciones del motor que avanza linealmente una camara montada en un husillo, despues de cada parada la camara efectua un disparo. La finalidad es hacer microfotos.

Con el fin de ganar mas precision he sustituido el motor de 1,8º por uno de 0,9º, y aqui llega el problema que con el anterior motor ya existia y con este ha empeorado, se trata de ronroneos y vibraciones bien conocidos por los creadores de RemoteXY, esta aplicacion consume demasiado tiempo del controlador y es necesario controlarlo con interrupciones de temporizador, no es facil y quería saber si alguien mas se ha encontrado con esta problematica.

Buscando por la red he encontrado este tutorial muy util, pero antiguo y ya no encuentro la biblioteca que el autor compartió en su dia.

Aqui dejo el programa, puede ser util tambien.
Saludos.

// RemoteXY select connection mode and include library 
#define REMOTEXY_MODE__SOFTSERIAL
#include <SoftwareSerial.h>

#include <RemoteXY.h>

// RemoteXY connection settings 
#define REMOTEXY_SERIAL_RX 3
#define REMOTEXY_SERIAL_TX 2
#define REMOTEXY_SERIAL_SPEED 38400


// RemoteXY configurate  
#pragma pack(push, 1)
uint8_t RemoteXY_CONF[] =
    { 255,15,0,11,0,87,1,16,31,1,1,1,2,3,14,22,6,31,69,110,
  100,101,118,97,110,116,0,1,1,2,27,14,21,22,24,77,101,109,32,105,
  110,105,99,105,0,1,1,18,27,14,21,22,24,77,101,109,32,102,105,110,
  97,108,0,1,1,18,3,14,22,6,31,69,110,114,101,114,97,0,1,1,
  2,50,14,21,2,31,115,116,97,114,116,0,1,1,18,50,14,21,2,31,
  72,111,109,101,0,4,0,37,5,8,63,6,24,7,53,2,75,30,5,2,
  26,1,7,53,2,84,30,5,2,26,1,129,0,8,72,18,2,24,84,101,
  109,112,115,32,101,110,116,114,101,32,102,111,116,111,115,0,129,0,13,81,
  8,2,24,78,46,32,102,111,116,111,115,0,67,5,2,94,30,5,2,26,
  11,129,0,4,91,26,2,24,68,105,115,116,97,110,99,105,97,32,99,97,
  109,112,32,102,111,116,111,103,114,97,102,105,97,116,0,4,0,49,5,8,
  63,12,26,129,0,37,4,8,2,24,86,101,108,111,99,105,116,97,116,0,
  129,0,38,6,6,2,24,109,111,116,111,114,0,129,0,49,4,9,2,24,
  73,110,116,101,110,115,105,116,97,116,0,129,0,52,6,3,2,24,108,101,
  100,0,2,1,37,88,22,7,2,26,31,31,65,85,84,79,0,77,65,78,
  0,129,0,43,84,9,2,8,77,97,110,47,65,117,116,111,0,7,53,35,
  75,25,5,65,26,1,129,0,39,72,16,2,8,84,101,109,112,115,32,101,
  120,112,111,115,105,99,105,195,179,0 };
// this structure defines all the variables and events of your control interface 
struct {

    // input variables
  uint8_t B_endevant; // =1 if button pressed, else =0 
  uint8_t B_mem_inici; // =1 if button pressed, else =0 
  uint8_t B_mem_final; // =1 if button pressed, else =0 
  uint8_t B_enrera; // =1 if button pressed, else =0 
  uint8_t B_start; // =1 if button pressed, else =0 
  uint8_t B_home; // =1 if button pressed, else =0 
  int8_t slider_velman; // =0..100 slider position 
  int16_t edit_temps_1;  // 32767.. +32767 
  int16_t edit_num_2;  // 32767.. +32767 
  int8_t slider_1; // =0..100 slider position 
  uint8_t man_auto; // =1 if switch ON and =0 if OFF 
  int16_t edit_exposicio_1;  // 32767.. +32767

     // output variables
  char distancia_1[11];  // string UTF8 end zero 

 
    // other variable
  uint8_t connect_flag;  // =1 if wire connected, else =0 

} RemoteXY;
#pragma pack(pop)

/////////////////////////////////////////////
//           END RemoteXY include          //
/////////////////////////////////////////////
int intensitat_led;
int pot_led;
int vel;
int pot_vel;
boolean start;
int retard_motor;
int retard_motor2;
boolean dir;
boolean ok_home;
boolean ok_pos;
int seq_home;
boolean fc_home;
int posicio_motor;
int posicio_anar;
int max_pos_motor;
int posicio_inicial;
int posicio_final;
int index_foto;
int seq_auto;
boolean fet_fotos;
int num_fotos;
int local_remot;
boolean ent_home;
boolean ent_endavant;
boolean ent_enrera;
boolean ent_start;
boolean ent_mem_punt_inicial;
boolean ent_mem_punt_final;
boolean man_auto;
float distancia;
float distancia_1;
float distancia_total;
long aux_calcul;
long aux_calcul2;
long diff;
long aux_div;

//input/ouputs
int motor_pulsos=6;
int motor_dir=5;
int motor_enable=4;
int foto_trigger=10;
int led=9;
int tensio=11;

void setup() 
{
  RemoteXY_Init (); 
  
  
  // TODO you setup code
  vel=500;
  pinMode(led, OUTPUT);
  pinMode(motor_pulsos,OUTPUT);  
  pinMode(motor_enable,OUTPUT); 
  pinMode(motor_dir,OUTPUT); 
  pinMode(7,INPUT_PULLUP); 
  pinMode(8,INPUT);  
  pinMode(9,OUTPUT);  
  pinMode(foto_trigger,OUTPUT);  
  pinMode(11,OUTPUT); 
  pinMode(12,INPUT); 
  start=LOW;
  pinMode(13,INPUT);
  pinMode(A1,INPUT);
  pinMode(A2,INPUT);
  pinMode(A3,INPUT);
  pinMode(A4,INPUT);
  pinMode(A5,INPUT);
  digitalWrite(motor_enable, LOW); 
  retard_motor=0;
  retard_motor2=0;
  seq_home=0;
  fc_home=HIGH;
  posicio_motor=-32000;
  ok_home=LOW;
  ok_pos=LOW;
  max_pos_motor=32000;
  index_foto=0;
  seq_auto=0;
  fet_fotos=HIGH;
  local_remot=1;
  ent_home=LOW;
  ent_endavant=LOW;
  ent_enrera=LOW;
  ent_start=LOW;
  ent_mem_punt_inicial=LOW;
  ent_mem_punt_final=LOW;
  digitalWrite(tensio,HIGH);

  Serial.begin(9600);
  
}

void loop() 
{ 
  RemoteXY_Handler ();
  
  


  if (RemoteXY.connect_flag) {
    control_remot();
  }
  else  {
    control_local();
  }

  if (ent_home==HIGH) {
    ok_home=LOW;
  }

  if (ok_home==LOW) {
    homer();
  }


  if ((man_auto==LOW) && (ok_home)){  
    //pot_vel=analogRead(A1);
    //vel=map(pot_vel,0,1023,100,10);
    if (vel>50){  
      start=HIGH;
    }
    if ((ent_endavant==HIGH) & (posicio_motor<max_pos_motor) & (start)) { 
      motor(vel,HIGH);
    }
    if ((ent_enrera==HIGH) & (posicio_motor>0) & (start)) { 
      motor(vel,LOW);
    }

    if (ent_mem_punt_inicial==HIGH)  {  
      posicio_inicial=posicio_motor;
      Serial.print("pos_inicial= ");
      Serial.println(posicio_inicial);
    }
    if (ent_mem_punt_final==HIGH)  { 
      posicio_final=posicio_motor;
      Serial.print(" pos_final= ");
      Serial.println(posicio_final);
      distancia=0.00125;                              
      distancia_1=posicio_final-posicio_inicial;
      distancia_total=distancia_1*distancia;
      dtostrf(distancia_total, 0, 3,RemoteXY.distancia_1);
      
      
    }
    
  }

  // Automatic

  if ((man_auto==HIGH) && (ok_home)){ 
    num_fotos=RemoteXY.edit_num_2;        
    if (ent_start==HIGH) {  
      fet_fotos=LOW;
      index_foto=0;
      seq_auto=0;
    }
    if ( (ent_start==LOW) && (fet_fotos==LOW)) {  
      automatic (100,200,5);  
    }

  }


}

//--------------------------------------------------------------------------
void motor ( int velocitat, boolean direccio)
{
  retard_motor++;
  digitalWrite(motor_dir,direccio);
  digitalWrite(motor_enable,LOW);  
  if ((retard_motor>=velocitat) & (retard_motor<(velocitat*2))){
    digitalWrite(motor_pulsos, HIGH);
  }
  if (retard_motor>=(velocitat*2)){
    digitalWrite(motor_pulsos, LOW);
    retard_motor=0;
    if (digitalRead(5)==HIGH) {
      posicio_motor++;
    }
    else {
      posicio_motor--;
    }
  }
}
//--------------------------------------------------------------------------
void motor_pos ( int velocitat2,int posicio_anar2)
{
  retard_motor2++;
  digitalWrite(motor_enable,LOW);  
  if (posicio_motor<posicio_anar2) {
    digitalWrite(motor_dir,HIGH);
  }
  else {
    digitalWrite(motor_dir,LOW);
    //digitalWrite(5,HIGH);
  }

  if ((retard_motor2>=velocitat2) & (retard_motor2<(velocitat2*2))){
    digitalWrite(motor_pulsos, HIGH);
  }
  if (retard_motor2>=(velocitat2*2)){
    digitalWrite(motor_pulsos, LOW);
    retard_motor2=0;
    if (digitalRead(motor_dir)==HIGH) {
      posicio_motor++;
    }
    if (digitalRead(motor_dir)==LOW){
      posicio_motor--;
    }
  }

  if (posicio_motor==posicio_anar2) {
    ok_pos = HIGH;
  }
  if (posicio_motor!=posicio_anar2) {
    ok_pos = LOW;
  }
}

void homer()
{
  fc_home=!digitalRead(7);
  switch (seq_home) {
    case 0:
      digitalWrite(motor_enable,HIGH); 
      if (fc_home){
        seq_home=2;
      }
      else{
        seq_home=1;
        digitalWrite(motor_pulsos, LOW);
        retard_motor=0;
      }
      break;
    case 1:  //busquem fc del home
      digitalWrite(motor_enable,LOW);  
      motor(10,LOW);  
      if (fc_home){
        seq_home=2;
        digitalWrite(motor_enable,HIGH); 
        posicio_motor=0;
        digitalWrite(motor_pulsos, LOW);
        retard_motor=0;
      }
      break;
    case 2:  //anem a pos 0 virtual
      digitalWrite(motor_enable,LOW);  
      motor_pos(100,10); 
      if (ok_pos){
        seq_home=0;
        digitalWrite(motor_enable,HIGH);r
        posicio_motor=0;
        digitalWrite(motor_pulsos, LOW);
        retard_motor=0;
        ok_home=HIGH;
      }
      break;
  } 
}


void automatic(int velocitat_inici,int velocitat_fotos, int velocitat_fi)
{
  switch (seq_auto) {
    case 0:
      digitalWrite(motor_enable,LOW); 
      posicio_anar=posicio_inicial;
      motor_pos(velocitat_inici,posicio_anar);  
      if (ok_pos){
        ok_pos=LOW;
        seq_auto=2;
      }
      break;
    case 1:  
      digitalWrite(motor_enable,LOW); 
      motor_pos(velocitat_fotos,posicio_anar);  
      if (ok_pos){
        seq_auto=2;
      }
      break;
    case 2:   //retard foto
      digitalWrite(motor_enable,LOW); 
      delay(1000);
      seq_auto=3;
      Serial.print("pos_inicial= ");
      Serial.print(posicio_inicial);
      Serial.print(" pos_final= ");
      Serial.print(posicio_final);
      Serial.print(" pos_anar= ");
      Serial.println(posicio_anar);
      break;
    case 3:  
      digitalWrite(motor_enable,LOW); 
      delay (RemoteXY.edit_temps_1);
      digitalWrite(foto_trigger,HIGH); //foto On
      delay(50);
      digitalWrite(foto_trigger,LOW); //foto Off
      delay (RemoteXY.edit_exposicio_1);
      index_foto++;
      seq_auto=4;
      break;
    case 4:   //seguent foto o parem
      digitalWrite(motor_enable,LOW); //enable motor
      if (index_foto<num_fotos) {
        posicio_anar=posicio_inicial + calcul_pasos(posicio_inicial,posicio_final,num_fotos,index_foto);
        seq_auto=1;
        ok_pos=LOW;
      }
      else {
        seq_auto=10;  
      }
      break;
    case 10:
      digitalWrite(motor_enable,LOW); 
      motor_pos(velocitat_fi,0); 
      index_foto=0;
      distancia_total=0;
      if (ok_pos){
        digitalWrite(motor_enable,LOW); 
        ok_pos=LOW;
        fet_fotos=HIGH;
        seq_auto=0;
      }
      break;
  }
}

//---------------------------------------------------------------------------
void control_local (){
  //ent_endavant=digitalRead(A4);
  //ent_enrera=digitalRead(A5);
  //ent_mem_punt_inicial=digitalRead(A2);
  //ent_mem_punt_final=digitalRead(A3);
  //ent_start=digitalRead(12);
  //ent_home=digitalRead(13);
  
  pot_vel=analogRead(A1);
  vel=map(pot_vel,0,100,100,10);
}//---------------------------------------------------------------------------
void control_remot (){
  ent_endavant=RemoteXY.B_endevant;           
  ent_enrera=RemoteXY.B_enrera;             
  ent_mem_punt_inicial=RemoteXY.B_mem_inici; 
  ent_mem_punt_final=RemoteXY.B_mem_final;    
  ent_start=RemoteXY.B_start;                     
  ent_home=RemoteXY.B_home;                       
  man_auto=RemoteXY.man_auto;

  
 
  pot_led=RemoteXY.slider_1;
  intensitat_led=map(pot_led,0,100,100,10);
  analogWrite(led, RemoteXY.slider_1);
  
  pot_vel=RemoteXY.slider_velman;
  vel=map(pot_vel,0,100,100,10);
}

int calcul_pasos (int inici_pos, int final_pos, int fotos, int index) {
  
 
  aux_div=fotos-1;
  diff=final_pos-inici_pos;
  aux_calcul=diff*index;
  aux_calcul2=aux_calcul/aux_div;  
 
  Serial.print(aux_div);
  Serial.print("   ");
  Serial.print(diff);
  Serial.print("   ");
  Serial.print(aux_calcul);
  Serial.print("   "); 
  Serial.print(aux_calcul2);
  Serial.println("   ");
  return aux_calcul2;
}

Esto es lo que no encuentras, pues pones en google: Arduino RemoteXY.h y aparece lo siguiente

Hola Surbyte, esta libreria ya esta incluida en en IDE, si te fijas ya la tengo incluida en el programa, contiene los elementos que hacen posible el funcionamiento normal de RemoteXY, yo me refiero a una librería para interrupciones... tema complicado, y mas para mi.

Gracias de todas maneras por prestar atención!

Veo bastantes librerias para muchas opciones pero ninguna para interrupciones...

https://github.com/Proyectos-Tote/Test_ESP32_Motor_ISR_OOP_VSC
¿esa?
Saludos

Te refieres a este link que esta caído?
ToteESP32MotorTimer
pues es cierto, lo esta y no tiene referencias.
Pero el autor esta disponible para que lo consultes. Habla español de modo que no deberías tener problema.

EDITO: no caí que @DanX3 ya lo habia preguntado.

Si es este surbyte este es el que me interesa, le envie un correo hace varios dias, pero no ha respuesto todavía.

Hay un fork de las librerías teensy que creo que van con interrupciones.
Míralo por si te sirviera
https://github.com/rcp1/ESP32Step
Saludos.

Necesitas entender y manejar los timers del ESP32.
Para que las tareas se hagan sin demoras "digamos" como que no tienes que atenderlas.
Esta librería es mas adecuada

y este ejemplo tal vez sea uno que se adapte, al menos yo empezaría por acá

Pues muchas gracias! Veo que tendre que cambiar el microcontrolador, creo que arduino se queda corto.
Respecto a las interrupciones tengo que ver como lo implanto a mi programa, he aprendido mucho pero veo mucho mas por aprender...
Por cierto veo que RemoteXY es compatible con ESP32, pero no se ven proyectos con motores nema y esta app, que creo que es increíblemente útil.
Gracias otra vez

Tal vez te malentienda pero un ESP32 no es un Arduino (si usa como opción programación estilo Arduino) y si este microcontrolador se queda corto que queda para los demás!!

No se que has querido decir, pero el ESP32 es el procesador mas potente precio/perfomance del momento, tal vez haya alguno que rivalice pero no tan popular.

Puede que no me haya explicado bien, actualmente tengo un arduino nano, y lo que quiero es sustituirlo por un XTVTX ESP32 ESP-WROOM-32, con bluetooth integrado. Creo que es este tambien compatible con RemoteXY.

Surbyte, creeme que me leo siempre las normas de un foro y aplico las normas siempre con respeto, aquí y en todas partes. Daba por hecho que había comentado el tema de arduino, pero viendo los mensajes veo que no, así que mil disculpas.
En el transcurso de estos dias tambien he ido comentando mi problemática, con otras personas y he llegado a la conclusión que siempre es mejor un ESP32 y mas en estos casos. Creía en un principio que con arduino sería posible solucionarlo pero es justo, y es muy facil en mi caso sustituirlo por un ESP32.
Probare este microcontrolador sin interrupciones de tiempo, de momento, mientras miro como puedo implantar interrupciones de tiempo.
De nuevo gracias.

Yo creo que puedes usar los timers del ESP32. Estúdialos con detenimiento. Como todo lo resuelves dedicándole un tiempo.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.