Stepper motor - Problems with the SW to control it

Hi everybody!
It’s the first time I write here, and i have read some of the rules from the forum but sorry if i’m doing something in a wrong way.
I’m working on a project that includes the control of a stepper motor. I’m using a driver TB6600-4A (Datasheet: https://www.mcielectronics.cl/website_MCI/static/documents/TB6600_data_sheet.pdf) and Arduino Mega 2560.

The stepper is the next one: https://es.rs-online.com/web/p/motores-paso-a-paso/8293500/?sra=pstk

I managed to make it work without the typical libraries such us accelstepper (i had so many problems when i used it). I use the typical “for…” that sends pulses with the frequency that corresponds to the velocity i want to achieve.It’s better for me to control velocity and acceleration using it. The typical for is the next one:

for (int x=0; x < 1*steps; x++) {
  digitalWrite(stepPin, HIGH);
  delayMicroseconds(i);
  digitalWrite(stepPin, LOW);
  delayMicroseconds(i);
 }

I have implemented a State machine on my Arduino program. In the state that corresponds to the motor move, i have the next code:

for(double i=i_act; i>= i_vmax; i-=t002){ //Acceleration
  i_act=i;
  if(estado!=1) break;      //necesary to come out from here when i touch Stop button
  Serial.println(String("Acel. TiempoDelay: ")+i);
  for (int x=0; x < 1*steps; x++) {
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(i);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(i);
  }
}

    //Vcte --> WHERE THE PROBLEM STARTS, the motor stops here always.

    Serial.println(String("TiempoDelay Cte: ")+i_vmax);
    for(int u=0; u<=200; u++){ 
      if(estado!=1) break;
      for (int x=0; x < 1*steps; x++) {                
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(i_vmax);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(i_vmax);
      }
    }

I suspect the problem is that the instructions that are in between the “fors” of the motion (print, if…) are too long, and the stepper goes a short time without receiving pulses, and then cannot start at high speeds. Could be this possible?
How could i change my code so that the stepper works well?

If there’s something here that you don’t understand please do not hesitate to tell me and i will try to explain it well!

Thank you all!!

When posting code please use the code tags ( </> ) as the forum software can munge code without them.

And please post the complete program.

Unless you only want the motor to move a specific number of steps a blocking FOR loop is unlikely to be useful. Better to use IF and allow loop() to do the repetition.

...R
Stepper Motor Basics
Simple Stepper Code

Sorry, i’ve already fixed de code parts from my previous post.
Here I attach the .ino with the code. I don’t know if maybe I should upload it in some other format.

My objective would be to control the motor by clicking on “p” from the keyboard as “play”; and a button for “stop” in case you want to stop before finishing the commanded movements.

I’m going to explain a little more my code… in general, the state machine works like this:
-St.0: the program is waiting untill you press the “p” on the keyboard.
-St.1:You have pressed “Play”. The method “ensayo” is where you command the movements you want to make with the stepper here (until now it has always been acceleration, constant speed, deceleration).
-St.2: An interruption happens when you press the Stop button, and brings you here. If you are above a certain speed, the motor will decelerate until braking.

I found it an easy and comfortable state machine to get what I wanted, and i though that I could control the motor correctly with the basic “for” structure that I talk about in the other post.

By the way, thanks for recommending me to use loop () - if (), I’ll try it tomorrow. Today I tried to use while () instead of for, with similar results …

ensayo_Velocidad_v1_botonStop_tecladoPlay.ino (7.68 KB)

It’s much easier for people to help you when you include the code in a Post so they don’t have to download it

/*DESCRIPCION: Control del motor mediante entrada de "p" (play) y "s" (stop) por teclado.
 *Ensayo: Aceleración de 300 a 1000 rpm, quedarse en 1000 un rato y decelerar hasta parar.
 *
 *Versión: 5 Abril 2020
 */

/* INTRODUCIR POR USUARIO AL INICIO: */
/* Velocidades mínima y máxima */
double tiempoDelay=10.0;   //i=10 es 850rpm
double tiempoDelayMax=9.375; //i=9.375 es 1000rpm
double i_limite= 133;  //Valor a partir del cual es necesario acelerar/decelerar para arrancar/parar. i=133 es 70rpm
/* Conexiones a pines */
const int dirPin = 8;
const int stepPin = 9;
const int steps = 3200;
const int pinBotonStop=2;

/* VARIABLES GLOBALES */
boolean interrupcion=false;
int estado=0;

double t002=0.02;                             // Tasa de aceleración/deceleración (inicial t=0.02)
double t=5;
double t5=5;
double t3=3;
double t1=1;                                  //He probado varias tasas...
double t05=0.5;

double i_act;
int n_1, n_2;
boolean entradaPlay=false;
boolean entradaStop=false;


/*MÉTODOS
 * -setup()
 * -leerPlay()
 * -leerStop()
 * -aceleracion(double velMin, double velMax)
 * -motorVcte(double i_consigna)
 * -deceleracion(double velMax, double velMin)
 * -ensayo(double i_vmin, double i_vmax)
 * -ensayo2(double i_vmin, double i_vmax)
 * -loop()  //State Machine
 */

void setup() {
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  Serial.begin(9600);
  Serial.setTimeout(1); //Finaliza el tiempo de espera del monitor serial en 1ms (Fin de String)
  pinMode(pinBotonStop, INPUT);
  attachInterrupt(digitalPinToInterrupt(pinBotonStop), Stop, LOW); 
}

int leerPlay(){
  Serial.println( "Pulse la tecla P cuando quiera comenzar.");
  n_1=0; //ascii
  if(Serial.available()>0){
    n_1=Serial.read(); //n1 es el codigo ascii de lo que lee por teclado
    if (n_1==80 || n_1==112){ //Se ha pulsado "P" ó "p"
      entradaPlay=true;
    }
    return n_1;
  }
  delay(10);
}

void Stop(){
  while(pinBotonStop==LOW){
    delay(10);
  }
  entradaStop=true;
  estado=2;
  Serial.println("Interrupcion de Stop. Se debería cambiar a estado 2.");
}

/* //I tried to do an interruption with Serial.Event() but it doesn't work >.<
boolean leerStop(){
  if(Serial.available()>0){
    n_2=Serial.read(); //n2 es el codigo ascii de lo que lee por teclado
    if (n_2==83 || n_2==115){ //Se ha pulsado "S" ó "s"
      entradaStop=true;
      estado=2;
    }
  }
  return entradaStop;
}
*/

void aceleracion(double velMin, double velMax){
  Serial.println(String("Comienzo Aceleración Constante, t = ")+t);
  for(double i=velMin; i>= velMax; i-=t){
    i_act=i;
    if(estado!=1) break;
    Serial.println(String("Acel. TiempoDelay: ")+i);
    for (int x=0; x < 1*steps; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i);
    }    
  }
}

void motorVcte(double i_consigna){                 // Se le podría pasar como parámetro el nº de vueltas
  i_act=i_consigna;
  Serial.println(String("TiempoDelay Cte: ")+i_act);
  for(int u=0; u<=200; u++){ //meto el número de vueltas que quiero dar en un for externo, el for de dentro sólo da una vuelta 
    if(estado!=1) break;
    for (int x=0; x < 1*steps; x++) {                // 6 vueltas
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i_act);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i_act);
    }
  }
}

void deceleracion(double velMax, double velMin){ 
  for(double i=velMax; i<= velMin; i+=t){
    i_act=i;
    if(estado!=1) break;
    Serial.println(String("Decelerando. TiempoDelay= ")+i);
    for (int x=0; x < 1*steps; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i);
    }
  }
}

void frenar(double velMax, double velMin){
  Serial.println(String("Frenando, tasa de deceleración t = ")+t);  
  for(double i=velMax; i<= velMin; i+=t){
    i_act=i;
    Serial.println(String("TiempoDelay: ")+i);
    for (int x=0; x < 1*steps; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i);
    }
  }
}


void ensayo(double i_vmin, double i_vmax){
  boolean b_fin=false;
  do{                                       
    aceleracion(i_vmin, i_vmax);
    motorVcte(i_vmax);                      
    deceleracion(i_vmax, i_vmin);
    b_fin=true;
    if(b_fin==true){
      break;
    }
  }while(estado==1);
}

void ensayo2(double i_vmin, double i_vmax){
  boolean b_fin=false;
  do{     
    //Acel                                  
    for(double i=i_vmin; i>=i_vmax*4; i-=t5){
      i_act=i;
      if(estado!=1) break;
      Serial.println(String("Acel. TiempoDelay: ")+i);
      for (int x=0; x < 1*steps; x++) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(i);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(i);
      }
    }
    for(double i=i_act; i>= i_vmax*2; i-=t3){
      i_act=i;
      if(estado!=1) break;
      Serial.println(String("Acel. TiempoDelay: ")+i);
      for (int x=0; x < 1*steps; x++) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(i);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(i);
      }
    }
    for(double i=i_act; i>= i_vmax; i-=t002){
      i_act=i;
      if(estado!=1) break;
      Serial.println(String("Acel. TiempoDelay: ")+i);
      for (int x=0; x < 1*steps; x++) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(i);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(i);
      }
    }
    //Vcte
    //i_act=i_vmax;
    Serial.println(String("TiempoDelay Cte: ")+i_vmax);
    for(int u=0; u<=200; u++){ //meto el número de vueltas que quiero dar en un for externo, el for de dentro sólo da una vuelta 
      if(estado!=1) break;
      for (int x=0; x < 1*steps; x++) {                
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(i_vmax);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(i_vmax);
      }
    }
    //Decel
    for(double i=i_vmax; i<= i_vmin; i+=t1){
      i_act=i;
      if(estado!=1) break;
      Serial.println(String("Decelerando. TiempoDelay= ")+i);
      for (int x=0; x < 1*steps; x++) {
        digitalWrite(stepPin, HIGH);
        delayMicroseconds(i);
        digitalWrite(stepPin, LOW);
        delayMicroseconds(i);
      }
    }
    b_fin=true;
    if(b_fin==true) break;
  }while(estado==1);
}

void loop(){
/*Maquina de estados:
  Estado=0 - Espera a pulsar Play
  Estado=1 - Se ha pulsado Play, se inicia el ensayo
  Estado=2 - Ha habido una interrupcion (se ha pulsado Stop), decelera y vuelve a estado 0 
*/
  delay(100);
  switch (estado){
    
    case 0: //Espera a play
      Serial.println("Estado 0. INICIO.");
      leerPlay();
      if(entradaPlay){
        estado=1;
        Serial.println("Has pulsado Play.");
        entradaPlay=false;
      }
      break;
      
    case 1:  //Se ha pulsado play, acelera
      Serial.println("Se ha pasado a Estado 1, aquí el motor tiene que moverse.");
      //i_act=tiempoDelay;
      ensayo2(134, 7.81);   //i_vmin, i_vmax      De 50 a 900 rpm    
      if(entradaStop=true){
        entradaStop=false;
        estado=2;
      }else{
        estado=0;
      }
      break;
      
    case 2: //Ha habido interrupcion
      Serial.println("Estado 2: Se ha pulsado Stop y el bicho va a decelerar hasta parar.");
      if(i_act<=i_limite){ //Si la velocidad es mayor a v_limite
        frenar(i_act, 312.5); //(REVISAR ESTE VALOR)i=312.5 son 30 rpm 
      }
      estado=0;
      break;
  }
}

…R

If you want a responsive program get rid of all the delay()s. The functions delay() and delayMicroseconds() block the Arduino until they complete. FOR and WHILE are also blocking statements and should be avoided unless they complete very quickly - for example in a couple of millisecs or less.

Have a look at how millis() is used to manage timing without blocking in Several Things at a Time.

See Using millis() for timing. A beginners guide if you need more explanation.

The second (non-blocking) example in this Simple Stepper Code and this simple acceleration code may also be useful.

...R

AccelStepper is easy to use - what were the problems?

Hi everybody again.

I have tried to use a basic structure to move the motor at a constant speed, similar to what Robin2 recommends (https://forum.arduino.cc/index.php?topic=223286.0). Thank you very much Robin2, i am learning a lot about different and more efficient programming statements to do the same!

This code would replace the basic motor motion structure:

/*
 * First try without using for() or while() statements.
 * I will try to use loop(), if() and millis() to command Vcte to the motor, infinitely
 * If this works, this one will be the basic structure to move the motor with my program (before, it was  for() structure)
 */

 /* Conexiones a pines */
const int dirPin = 8;
const int stepPin = 9;
const int pinBotonStop=2;


/*Variables globales */
byte pulseState=LOW;
const long pulseWidth = 5; // number of millisecs in state high or in state low, before it was called i(ms)

unsigned long currentMillis = 0;    // stores the value of millis() in each iteration of loop()
unsigned long previousPulseMillis = 0;   // will store last time the pulse was updated

void setup() {
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  currentMillis = millis();
  generaPulso();
  escribePulso();
}

void generaPulso(){
 if (pulseState == LOW) {
  if (currentMillis - previousPulseMillis >= pulseWidth) {
     pulseState = HIGH;
     previousPulseMillis += pulseWidth;
   }
 }
 else {  // if pulseState is HIGH
  if (currentMillis - previousPulseMillis >= pulseWidth) {
     pulseState = LOW;
     previousPulseMillis += pulseWidth;
   }
 }
}
void escribePulso(){
 //Serial.print("El valor del pulso es: ");
 //Serial.println(pulseState);                //By printing "pulseState" I can check that "pulseWidth" is correct (showing the timestamp on the serial monitor)
 digitalWrite(stepPin, pulseState);
}

The problem is that this code doesn't work. I can generate a pulse with the frequency I want, but the problem is that the motor moves badly: it makes a sound and doesn't moves smoothly.

Maybe i made a mistake. I thought that maybe using such a small pulse width (5ms) is a problem. About the configuration of the driver, now I am using microStep=1, configuration of complete step, trying to make the pulse width a higher value. (In my first code I was using microSeconds, but with this one I must use milliseconds.)

Markt, some time ago I tried to use accelStepper librarie but i had a lot of problems trying to move the motor exactly how I wanted. I would like a complete control about acceleration, time in constant velocity... or well, that's what I was trying :cold_sweat: . If i can't solve this actual problems, I will have to resume accelstepper. But, at the moment, I prefer to waste a little more time trying to solve this problem, since I am also learning about programming with Arduino.

Anyway, the first code I shared with you works. The problem appears if I want a speed of more than about 650 rpm, when going from acceleration to Vcte the motor loses steps, and above 800rpm the motor can't follow and stops. As I say, I will try to make the code more efficient to solve it. I know that the problem is there because I have tried to accelerate from 50rpm to 1200rpm and there was no problem.

Thank you all, I will keep you informed.

If you want precise timing it may be better to use micros() rather than millis()

Also, you should make a distinction between the pulse width (which probably only needs to be 10 µsecs or less) and the interval between pulses which governs the speed. Making that distinction gives you more time because the interval can be longer for the same motor speed.

Try writing your pulse function like this

void generaPulso(){
  if (currentMillis - previousPulseMillis >= intervalBetweenPulses) {
     digitalWrite(stepPin, HIGH);
     digitalWrite(stepPin, LOW);
     previousPulseMillis += intervalBetweenPulses;
   }
}

digitalWrite() is a slow function so two successive calls probably give a pulse that is long enough.

If you need an interval shorter than about 30 msecs and or more precise than +/- 1 millisec then I would use micros()

Of course you must also ensure that the function is called often enough.

...R

Hello again!

In the end I managed to solve, even a little, the problem I was talking about: when going fromaaceleration to constant speed. Y tried to use some of the ideas you gave me, but nothing worked well. It finally worked while I was testing different acceleration rates. I wasn’t expecting it, but it makes sense: at the last acceleration rate, the motor takes one full turn for each speed step. This makes it have more inertia to go at a constant speed. (in the last version, the motor takes only one step per speed step).

I send here the last version of this program, in case it serves to someone:

/*DESCRIPCION: Control del motor mediante entrada de "p" (play) y "s" (stop) por teclado.
 *Ensayo: Aceleración de 300 a 1000 rpm, quedarse en 1000 un rato y decelerar hasta parar.
 *
 *Versión: 12 Abril 2020
 */

/* INTRODUCIR POR USUARIO AL INICIO: */
/* Velocidades mínima y máxima */
const double w_min = 110.00;      //Introducir la velocidad a la que comenzará (en rpm) --> máximo 120rpm
const double w_max = 2500;      //Introducir la velocidad que se quiere alcanzar en Vcte (en rpm)
const int n_vueltas = 800;        //Numero de vueltas a velocidad constante
const double w_limite = 100;      //Valor a partir del cual es obligatorio decelerar para parar, en microSegundos (mirar Excel). i=93.75 es 100rpm

/* Conexiones a pines */
const int dirPin = 8;
const int stepPin = 9;
const int steps = 3200;
const int pinBotonStop = 2;

/*PARAMETROS COMFIGURACION del MOTOR*/
const int microStep=16;
const double step_original=1.8;
double step_final, steps_rev, tiempo_rev_s, tiempo_rev_us;
//double w_min, w_max;

/* VARIABLES GLOBALES */
boolean interrupcion=false;
int estado=0;
                         
double t5=5;                      // Tasa de aceleración/deceleración (inicial t=0.02)
double t3=3;
double t1=1;                      // Se utilizan distintas tasas...
double t05=0.5;
double t002=0.02;    

double i_act;
int n_1;
boolean entradaPlay=false;
boolean entradaStop=false;


/* MÉTODOS:
 * -setup()
 * -leerPlay()
 * -leerStop()
 * -double velocidad_a_i(double w)
 * -double i_a_velocidad(double i)
 * -aceleracion(double w_min, double w_max)
 * -motorVcte(double w_consigna, int n_vueltas)
 * -deceleracion(double w_max, double w_min)
 * -frenar(double i_velMax, double i_velMin)
 * -ensayo(double w_min, double w_max, int n_vueltas)
 * -loop()  //State Machine
 */

void setup() {
  pinMode(dirPin, OUTPUT);
  pinMode(stepPin, OUTPUT);
  Serial.begin(9600);
  Serial.setTimeout(1);           //Finaliza el tiempo de espera del monitor serial en 1ms (Fin de String)
  pinMode(pinBotonStop, INPUT);
  attachInterrupt(digitalPinToInterrupt(pinBotonStop), Stop, LOW); 
  step_final=step_original/microStep;
  steps_rev=360.0/step_final;
}

int leerPlay(){
  Serial.println( "Pulse la tecla P (mayúscula ó minúscula) cuando quiera comenzar.");
  n_1=0; //ascii
  if(Serial.available()>0){
    n_1=Serial.read();            //n1 es el codigo ascii de lo que lee por teclado
    if (n_1==80 || n_1==112){     //Se ha pulsado "P" ó "p"
      entradaPlay=true;
    }
    return n_1;
  }
  delay(10);
}

void Stop(){
  while(pinBotonStop==LOW){
    delay(10);
  }
  entradaStop=true;
  estado=2;
  Serial.println("Se ha producido una Interrupcion de Stop. Se va a pasar al Estado 2.");
}

double velocidad_a_i(double w){   // Dada una velocidad w, devuelve la i necesaria
  tiempo_rev_s=60.0/w;
  tiempo_rev_us=tiempo_rev_s/0.000001;
  double i=tiempo_rev_us/(2*steps_rev);
  return i;
}

double i_a_velocidad(double i){    // Dada una i, devuelve la w en rpm
  tiempo_rev_us=i*2.0*steps_rev;
  tiempo_rev_s=tiempo_rev_us*0.000001;
  double w=60.0/tiempo_rev_s;
  return w;
}

void aceleracion(double i_vmin, double i_vmax){ // Tres tramos de aceleración
  double tramo = (i_vmax-i_vmin)/4;
  double tramo1=i_vmax-tramo;      // Tasa alta hasta que alcanza un cuarto de la vmax
  double tramo2=i_vmax-3*tramo;    // Tasa media hasta la mitad
      
  //Tramo1                          
  for(double i=i_vmin; i>=tramo1; i-=t5){
    if(estado!=1) break;
    i_act=i;
    Serial.println(String("Acel. TiempoDelay: ")+i);
    for (int x=0; x < steps/4; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i);
    }
  }
  //Tramo2
  for(double i=i_act; i>= tramo2; i-=t3){
    if(estado!=1) break;
    i_act=i;
    Serial.println(String("Acel. TiempoDelay: ")+i);
    for (int x=0; x < steps/4; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i);
    }
  }
  //Tramo3
  for(double i=i_act; i>= i_vmax; i-=t05){
    if(estado!=1) break;
    i_act=i;
    Serial.println(String("Acel. TiempoDelay: ")+i);
    for (int x=0; x < steps; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i);
    }
  }
}

void motorVcte(double i_vmax, int n_vueltas){
  if(estado==1) i_act=i_vmax;
  for(int u=n_vueltas; u>=0; u--){
    if(estado!=1) break;
    Serial.println(String("Velocidad Cte: ")+i_act);
    for (int x=0; x < steps; x++) {                
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i_act);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i_act);
    }
  }
}

void deceleracion(double i_vmax, double i_vmin){
  for(double i=i_vmax; i<= i_vmin; i+=t1){
    if(estado!=1) break;
    i_act=i;
    Serial.println(String("Decelerando. TiempoDelay= ")+i);
    for (int x=0; x < steps; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i);
    }
  }
}

void frenar(double velMax, double velMin){ //Se utiliza sólo en el Estado2, si al pulsar Stop la velocidad actual supera un valor estipulado (i_vlimite).
  for(double i=velMax; i<= velMin; i+=t5){
    i_act=i;
    Serial.println(String("Frenando. TiempoDelay: ")+i);
    for (int x=0; x < 1*steps; x++) {
      digitalWrite(stepPin, HIGH);
      delayMicroseconds(i);
      digitalWrite(stepPin, LOW);
      delayMicroseconds(i);
    }
  }
}

void ensayo(double w_min, double w_max, int n_vueltas){        
  double i_vmin=velocidad_a_i(w_min);
  double i_vmax=velocidad_a_i(w_max);                      
  aceleracion(i_vmin, i_vmax);
  motorVcte(i_vmax, n_vueltas);                      
  deceleracion(i_vmax, i_vmin);
}


void loop(){
  double i_limite= velocidad_a_i(w_limite);
/*Maquina de estados:
  Estado=0 - Espera a pulsar Play
  Estado=1 - Se ha pulsado Play, se inicia el ensayo
  Estado=2 - Ha habido una interrupcion (se ha pulsado Stop), decelera y vuelve a estado 0 
*/
  delay(100);
  switch (estado){
    
    case 0: //Espera a play
      Serial.println("Estado 0. INICIO.");
      leerPlay();
      if(entradaPlay){
        estado=1;
        Serial.println("Has pulsado Play.");
        entradaPlay=false;
      }
      break;
      
    case 1:  //Se ha pulsado play, acelera
      Serial.println("Estado 1. Se va a realizar el ensayo.");
      ensayo(w_min, w_max, n_vueltas);    //rpm_vmin, rpm_vmax, numero_vueltas 
      if(entradaStop==false)estado=0;
      break;
      
    case 2: //Ha habido interrupcion
      Serial.println("Estado 2. Se ha pulsado Stop. Si la velocidad es mayor a i_limite, se va a frenar de forma controlada hasta parar.");
      entradaStop=false;
      if(i_act<=i_limite){                //Si la velocidad es mayor a v_limite
        frenar(i_act,80);                 //Se frenará desde la i_act hasta i=80 (hasta w=117.18rpm, para evitar el tramo de resonancia)
      }
      i_act=0;
      estado=0;
      break;
  }
}

Playing with the oscilloscope I have discovered another problem: despite the fact that I send a pulse frequency as a setpoint, the pulses that really come out of the arduino are somewhat slower. This error increases the higher the pulse frequency. I think it’s because of the statements i use in Arduino, and the “efficiendy” of my code.
I have thought about using the arduino timers to make the pulse (instead of the “for statement”), or directly doing everything with LabView and sending the pulses to the driver with RS-232 communication. “But that is another story and shall be told another time.”

Thank you all for your time.

G.

Try using the digitalWriteFast library. It is very significantly faster than the standard digitalWrite() and digitalRead() but the pin numbers must be known at compile time.

...R