Problema de giro continuo con nema 17 al intentar integrarlo con control de hotend

Buenas tardes!. Como describe el titulo tengo problemas de codificacion al hacer que un motor nema 17 gire continuamente en un extenso código donde intento integrar un control de temperatura de un hotend y a la vez un control de la velocidad, ON/OFF y sentido de giro del motor con driver a4988.Estos parámetros se los visualizan en un oled 128x64 y se accede al ajuste de cada uno mediante un cursor que se desplaza con un encoder rotativo. El codigo funciona bien en cuanto a los ajustes pero no he logrado que cuando enciendo el motor éste gire normalmente ya que hace un pequeño giro y se detiene y luego vuelve a girar y vuelve a detenerse. Creo que es un problema debido a que el loop se reinicia con retrasos al encender el motor y por esta razon el giro es intermitente, espero haber sido claro y si alguien tiene alguna idea o puede colaborar con algun tip estare agradecido. Adjunto el codigo:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SH1106.h>

// DEFINICIÓN DE PINES
const int heater = 9; // Pin PWM para el cartucho calefactor
const int encoderCLK = 2; // Pin CLK del encoder
const int encoderDT = 3; // Pin DT del encoder
const int encoderSW = 4; // Pin SW del encoder
#define STEP 7      // Pin STEP del A4988
#define DIR 6       // Pin DIR del A4988
#define ENABLE 8    // Pin ENABLE del A4988

// VARIABLES
int Vo;
float R1 = 98000; // Resistencia fija del divisor de tensión 
float logR2, R2, temperaturaActual;
float c1 = -2.010608807e-03, c2 = 5.659157240e-04, c3 = -7.396338278e-07;
volatile int setTemp = 0; // Valor inicial del setpoint de temperatura
volatile int setSpeed = 2000; // Valor inicial del setpoint de velocidad
int pwmValue = 0; // Variable para almacenar el valor PWM
int delayTime = 1000; // Valor inicial de delay
int newDelayTime = 1000; // Valor de delay ajustado con el encoder
int lastClk = HIGH; // Estado anterior del pin CLK
int lastButtonState = HIGH; // Estado anterior del botón
unsigned long lastDebounceTime = 0; // Tiempo del último cambio de estado
unsigned long debounceDelay = 50; // Tiempo de debounce
const unsigned long debounceDelayEncoder = 10; // Retardo de debounce para el encoder
unsigned long lastEncoderTime = 0; // Última vez que se leyó el encoder
unsigned long lastTempReadTime = 0; // Última vez que se leyó la temperatura
unsigned long tempReadInterval = 1000; // Intervalo de lectura de temperatura (en milisegundos)
bool encoderMoved = false; // Variable para controlar si el encoder se ha movido

// Nuevas variables para el cursor y el modo de ajuste
int cursorPosition = 0; // Posición del cursor (0 para SetTemp, 1 para Speed, 2 para Motor ON/OFF, 3 para Dirección)
bool adjusting = false; // Modo de ajuste
bool motorEnabled = false; // Estado del motor (habilitado o deshabilitado)
bool motorDirectionCW = true; // Dirección del motor: true para CW, false para CCW

// Definición de la pantalla OLED
#define OLED_RESET -1
Adafruit_SH1106 display(OLED_RESET);

void setup() {
  Serial.begin(9600); // Inicializa comunicación serie a 9600 bps
  setupDisplay();
  
  pinMode(heater, OUTPUT);
  pinMode(encoderCLK, INPUT);
  pinMode(encoderDT, INPUT);
  pinMode(encoderSW, INPUT_PULLUP);
  pinMode(STEP, OUTPUT);
  pinMode(DIR, OUTPUT);
  pinMode(ENABLE, OUTPUT);
  
  attachInterrupt(digitalPinToInterrupt(encoderCLK), updateEncoder, CHANGE);
}

void loop() {
  digitalWrite(ENABLE, motorEnabled ? LOW : HIGH); // Controlar el estado del motor según la variable
  handleEncoder(); // Manejar el encoder por separado
  
  int buttonState = digitalRead(encoderSW);
  
  // Verificar si el botón ha sido presionado
  if (buttonState == LOW && lastButtonState == HIGH && (millis() - lastDebounceTime) > debounceDelay) {
    if (cursorPosition == 2) {  // Si el cursor está en la posición para el motor
      motorEnabled = !motorEnabled;  // Cambia el estado del motor
    } else if (cursorPosition == 3) { // Nueva posición para dirección del motor
      motorDirectionCW = !motorDirectionCW; // Cambia la dirección del motor
    } else {
      adjusting = !adjusting;  // Cambia el modo de ajuste
    }
    lastDebounceTime = millis(); // Actualiza el tiempo de debounce
    delay(200); // Espera para evitar rebotes
  }
  lastButtonState = buttonState;

  if (encoderMoved) {
    encoderMoved = false;
    if (adjusting) {
      if (cursorPosition == 0) {
        setTemp = constrain(setTemp, 0, 270);
      } else if (cursorPosition == 1) {
        newDelayTime = constrain(newDelayTime, 100, 1000);
        delayTime = newDelayTime;
      }
    }
    displayStatus(); // Actualiza la pantalla cuando el encoder se mueve
  }
  
  if (millis() - lastTempReadTime >= tempReadInterval) {
    lastTempReadTime = millis();
    LecturaTemp(); // Llama a la función LecturaTemp
    controlHeat(); // Llama a la función controlHeat
    displayStatus(); // Actualiza la pantalla con la temperatura actual
  }
  
  moverMotor(); // Mueve el motor con el valor de delay ajustado

}

void setupDisplay() {
  display.begin(SH1106_SWITCHCAPVCC, 0x3C);
  display.display();
  delay(2000);
  display.clearDisplay();
}

void handleEncoder() {
  unsigned long currentTime = millis();
  if (currentTime - lastEncoderTime > debounceDelayEncoder) {
    int currentClk = digitalRead(encoderCLK);
    if (currentClk != lastClk) {
      if (digitalRead(encoderDT) != currentClk) {
        if (adjusting) {
          if (cursorPosition == 0) {
            setTemp = constrain(setTemp + 5, 0, 270);
          } else if (cursorPosition == 1) {
            newDelayTime = constrain(newDelayTime + 50, 100, 1000);
            delayTime = newDelayTime;
          }
        } else {
          cursorPosition = min(cursorPosition + 1, 3); // Cambia la posición del cursor, pero no más allá de 3
        }
      } else {
        if (adjusting) {
          if (cursorPosition == 0) {
            setTemp = constrain(setTemp - 5, 0, 270);
          } else if (cursorPosition == 1) {
            newDelayTime = constrain(newDelayTime - 50, 100, 1000);
            delayTime = newDelayTime;
          }
        } else {
          cursorPosition = max(cursorPosition - 1, 0); // Cambia la posición del cursor, pero no menos de 0
        }
      }
      encoderMoved = true;
    }
    lastClk = currentClk;
    lastEncoderTime = currentTime;
  }

  // Verificar el estado del botón para entrar/salir del modo de ajuste
  int buttonState = digitalRead(encoderSW);
  if (buttonState == LOW && lastButtonState == HIGH && (millis() - lastDebounceTime) > debounceDelay) {
    if (cursorPosition == 2) {  // Si el cursor está en la posición para el motor
      motorEnabled = !motorEnabled;  // Cambia el estado del motor
    } else if (cursorPosition == 3) { // Nueva posición para dirección del motor
      motorDirectionCW = !motorDirectionCW; // Cambia la dirección del motor
    } else {
      adjusting = !adjusting;  // Cambia el modo de ajuste
    }
    lastDebounceTime = millis(); // Actualiza el tiempo de debounce
    delay(200); // Espera para evitar rebotes
  }
  lastButtonState = buttonState;
}

void updateEncoder() {
  unsigned long currentTime = millis();
  if (currentTime - lastEncoderTime > debounceDelayEncoder) {
    int currentClk = digitalRead(encoderCLK);
    if (currentClk != lastClk) {
      if (digitalRead(encoderDT) != currentClk) {
        if (adjusting) {
          if (cursorPosition == 0) {
            setTemp += 5;
          } else if (cursorPosition == 1) {
            newDelayTime += 50;
          }
        } else {
          cursorPosition = min(cursorPosition + 1, 3); // Cambia la posición del cursor, pero no más allá de 3
        }
      } else {
        if (adjusting) {
          if (cursorPosition == 0) {
            setTemp -= 5;
          } else if (cursorPosition == 1) {
            newDelayTime -= 50;
          }
        } else {
          cursorPosition = max(cursorPosition - 1, 0); // Cambia la posición del cursor, pero no menos de 0
        }
      }
      encoderMoved = true;
    }
    lastClk = currentClk;
    lastEncoderTime = currentTime;
  }

  // Verificar el estado del botón para entrar/salir del modo de ajuste
  int buttonState = digitalRead(encoderSW);
  if (buttonState == LOW && lastButtonState == HIGH && (millis() - lastDebounceTime) > debounceDelay) {
    adjusting = !adjusting; // Cambia el modo de ajuste
    lastDebounceTime = millis(); // Actualiza el tiempo de debounce
  }
  lastButtonState = buttonState;
}

float LecturaPromediada(int pin, int numLecturas) {
  float suma = 0;
  for (int i = 0; i < numLecturas; i++) {
    suma += analogRead(pin);
    delay(10); // Pequeña demora entre lecturas
  }
  return suma / numLecturas;
}

void LecturaTemp() {
  Vo = LecturaPromediada(A1, 10); // Promedia 10 lecturas
  R2 = R1 * (1023.0 / (float)Vo - 1.0); // Conversión de tensión a resistencia
  logR2 = log(R2); // Logaritmo de R2 necesario para ecuación
  temperaturaActual = (1.0 / (c1 + c2 * logR2 + c3 * logR2 * logR2 * logR2)); // Ecuación S-H
  temperaturaActual -= 273.15; // Conversión de Kelvin a Celsius
}

void controlHeat() {
  int error = setTemp - temperaturaActual; // Error de temperatura
  pwmValue = constrain(map(error, -10, 10, 0, 255), 0, 255); // Mapea el error a valor PWM
  analogWrite(heater, pwmValue); // Ajusta el calefactor
}

void moverMotor() {
  if (motorEnabled) {
    digitalWrite(DIR, motorDirectionCW ? HIGH : LOW); // Define la dirección del motor
    digitalWrite(STEP, HIGH);
    delayMicroseconds(delayTime);
    digitalWrite(STEP, LOW);
    delayMicroseconds(delayTime);
  }
}


void displayStatus() {
  display.clearDisplay();
  display.setTextSize(1);
  display.setTextColor(WHITE);

  // Mostrar temperatura actual
  display.setCursor(0, 0);
  display.print("Temp: "); 
  display.print(temperaturaActual, 1);
  display.print(" C");

  // Mostrar setpoint de temperatura
  display.setCursor(10, 10);
  display.print("SetTemp: ");
  display.print(setTemp);

  // Mostrar valor PWM
  display.setCursor(80, 0);
  display.print("PWM: ");
  display.print(pwmValue);

  // Mostrar setpoint de velocidad
  display.setCursor(10, 30);
  display.print("Speed: ");
  display.print(delayTime);

  // Mostrar estado del motor
  display.setCursor(10, 40);
  display.print("Motor: ");
  display.print(motorEnabled ? "ON" : "OFF");

  // Mostrar dirección del motor
  display.setCursor(10, 50);
  display.print("Dir: ");
  display.print(motorDirectionCW ? "CW" : "CCW");

  // Mostrar cursor
  if (!adjusting) {
    int cursorY = 0;
    switch (cursorPosition) {
      case 0:
        cursorY = 10;
        break;
      case 1:
        cursorY = 30;
        break;
      case 2:
        cursorY = 40;
        break;
      case 3:
        cursorY = 50;
        break;
    }
    display.fillRect(0, cursorY, 5, 5, WHITE); // Dibuja un pequeño cuadrado como cursor
  }

  display.display();
}

Que micro estas usando?

Arduino pro mini, he intentado también con un arduino uno y tengo los mismos resultados

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