firmware-base/vendor/qitech/Winder/experiments/Calibrate/CalibrateSpreadCycle.cpp
2026-01-28 16:42:43 +01:00

216 lines
7.9 KiB
C++

/**
* Author Teemu Mäntykallio
* Initializes the library and runs the stepper motor.
*/
#include <Arduino.h>
#include <TMCStepper.h>
#define EN_PIN 12 // Enable
#define DIR_PIN 16 // Direction
#define STEP_PIN 26 // Step
#define CS_PIN 5 // Chip select
#define R_SENSE \
0.11f // Match to your driver \
// SilentStepStick series use 0.11 \
// UltiMachine Einsy and Archim2 boards use 0.2 \
// Panucatt BSD2660 uses 0.1 \
// Watterott TMC5160 uses 0.075
hw_timer_t* timer1 = NULL;
// Select your stepper driver type
TMC2130Stepper driver = TMC2130Stepper(CS_PIN, R_SENSE); // Hardware SPI
// TMC2130Stepper driver = TMC2130Stepper(CS_PIN, R_SENSE, SW_MOSI, SW_MISO, SW_SCK); // Software SPI
// TMC2660Stepper driver = TMC2660Stepper(CS_PIN, R_SENSE); // Hardware SPI
// TMC2660Stepper driver = TMC2660Stepper(CS_PIN, R_SENSE, SW_MOSI, SW_MISO, SW_SCK);
// TMC5160Stepper driver = TMC5160Stepper(CS_PIN, R_SENSE);
// TMC5160Stepper driver = TMC5160Stepper(CS_PIN, R_SENSE, SW_MOSI, SW_MISO, SW_SCK);
// You can define starting values here:
struct {
uint8_t blank_time = 24; // [16, 24, 36, 54]
uint8_t off_time = 3; // [1..15]
uint8_t hysteresis_start = 1; // [1..8]
int8_t hysteresis_end = 12; // [-3..12]
} config;
void initPins();
void IRAM_ATTR onTimer() { digitalWrite(STEP_PIN, !digitalRead(STEP_PIN)); }
void reportCurrentSettings() {
Serial.print("Off time = ");
Serial.print(config.off_time);
Serial.print(" Hysteresis end = ");
Serial.print(config.hysteresis_end);
Serial.print(" Hysteresis start = ");
Serial.println(config.hysteresis_start);
}
void setup() {
timer1 =
timerBegin(3, 8, true); // Se configura el timer, en este caso uso el timer 4 de los 4 disponibles en el ESP(0,1,2,3)
// el prescaler es 8, y true es una bandera que indica si la interrupcion se realiza en borde o en nivel
timerAttachInterrupt(timer1, &onTimer, true); // Se vincula el timer con la funcion AttachInterrup
// la cual se ejecuta cuando se genera la interrupcion
timerAlarmWrite(timer1, 80, true); // En esta funcion se define el valor del contador en el cual se genera la interrupción del timer
timerAlarmEnable(timer1); // Función para habilitar el temporizador.
initPins();
Serial.begin(115200);
Serial.println(F("Starting calibration of TMC spreadCycle parameters."));
Serial.println(F("This example by default uses X axis driver on a RAMPS1.4."));
Serial.println(F("First make sure your serial terminal sends newline ending only!"));
for (uint8_t i = 0; i < 60; i++) {
Serial.print('.');
delay(100);
}
Serial.println(F("\nThen make sure the belt is disconnected"));
Serial.println(F("as we will not respect endstops or physical limits"));
while (1) {
Serial.println(F("Is the belt disconnected? Send 'yes' to confirm."));
while (!Serial.available())
;
String yn = Serial.readStringUntil('\n');
Serial.println(yn);
if (yn == "yes") {
break;
} else {
Serial.println(F("Belt still connected."));
Serial.println(F("Please disconnect belt."));
};
}
Serial.println(F("\nNow make sure the driver has 12V (or greater) power turned on."));
while (1) {
Serial.println(F("Is VMOT power on? Send 'yes' to confirm"));
while (!Serial.available())
;
String yn = Serial.readStringUntil('\n');
Serial.println(yn);
if (yn == "yes") {
break;
} else {
Serial.println(F("Please turn on power to the driver."));
};
}
Serial.print(F("\nTesting connection..."));
uint8_t result = driver.test_connection();
if (result) {
Serial.println(F("failed!"));
Serial.print(F("Likely cause: "));
switch (result) {
case 1:
Serial.println(F("loose connection"));
break;
case 2:
Serial.println(F("Likely cause: no power"));
break;
}
Serial.println(F("Fix the problem and reset board."));
abort();
}
Serial.println(F("OK"));
driver.push();
driver.microsteps(256);
driver.irun(10);
driver.ihold(10);
Serial.print(F("Setting driver blank time to "));
Serial.print(config.blank_time);
Serial.println(F(" cycles."));
driver.blank_time(config.blank_time);
Serial.print(F("Setting driver off time to "));
Serial.println(config.off_time);
driver.toff(config.off_time);
Serial.print(F("Setting hysteresis end value to "));
Serial.println(config.hysteresis_end);
driver.hysteresis_end(config.hysteresis_end);
Serial.print(F("Setting hysteresis start value to "));
Serial.println(config.hysteresis_start);
driver.hysteresis_start(config.hysteresis_start);
Serial.print(F("Effective hysteresis = "));
Serial.print(config.hysteresis_end);
Serial.print(F(" + "));
Serial.print(config.hysteresis_start);
Serial.print(F(" = "));
Serial.println(config.hysteresis_end + config.hysteresis_start);
Serial.println(F("\nNow we start decreasing the hysteresis end setting."));
Serial.println(F("You should first hear your motor making clearly audible noise."));
Serial.println(F("As we tune the timings the noise will get higher pitched."));
Serial.println(F("When the noise is no longer audible we have reached a good setting."));
Serial.println(F("You can tune the setting by sending - (minus) character"));
Serial.println(F("or you can go back to previous parameter by sending + (plus) character."));
Serial.println(F("Sending = (equal) character move to the next phase."));
digitalWrite(EN_PIN, LOW);
while (driver.cur_a() < 240) { // Use cur_b if measuring from B coil
digitalWrite(STEP_PIN, HIGH);
digitalWrite(STEP_PIN, LOW);
delay(3);
}
while (1) {
if (Serial.available() > 0) {
uint8_t c = Serial.read();
if (c == '+') {
if (config.hysteresis_end == 12)
Serial.println(F("Reached MAX setting already!"));
else {
config.hysteresis_end++;
reportCurrentSettings();
driver.hysteresis_end(config.hysteresis_end);
}
} else if (c == '-') {
if (config.hysteresis_end == -3)
Serial.println(F("Reached MIN setting already!"));
else {
config.hysteresis_end--;
reportCurrentSettings();
driver.hysteresis_end(config.hysteresis_end);
}
} else if (c == '=')
break;
}
}
Serial.print(F("Final effective hysteresis = "));
Serial.print(config.hysteresis_end);
Serial.print(F(" + "));
Serial.print(config.hysteresis_start);
Serial.print(F(" = "));
Serial.println(config.hysteresis_end + config.hysteresis_start);
Serial.println(F("Your configuration parameters in Marlin are:"));
Serial.print(F("#define CHOPPER_TIMING { "));
Serial.print(config.off_time);
Serial.print(F(", "));
Serial.print(config.hysteresis_end);
Serial.print(F(", "));
Serial.print(config.hysteresis_start);
Serial.println(F(" }"));
}
void initPins() {
pinMode(EN_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(CS_PIN, OUTPUT);
digitalWrite(EN_PIN, HIGH); // deactivate driver (LOW active)
digitalWrite(DIR_PIN, LOW); // LOW or HIGH
digitalWrite(STEP_PIN, LOW);
digitalWrite(CS_PIN, HIGH);
SPI.begin();
pinMode(MISO, INPUT_PULLUP);
}
void loop() {}