Skip to content

Commit

Permalink
change to different TMC driver and implement
Browse files Browse the repository at this point in the history
  • Loading branch information
mwood77 committed Nov 5, 2024
1 parent d42f859 commit cd794ce
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 34 deletions.
3 changes: 2 additions & 1 deletion platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,5 @@ lib_deps =
adafruit/Adafruit SSD1306@^2.5.9
electromagus/ESPMX1508@^1.0.5
dawidchyrzynski/home-assistant-integration@^2.1.0
janelia-arduino/TMC2209@^9.4.2
teemuatlut/TMCStepper@^0.7.3
plerup/EspSoftwareSerial@^8.2.0
11 changes: 11 additions & 0 deletions src/platformio/osww-server/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,17 @@ unsigned long calculateWindingTime()
*/
void beginWindingRoutine()
{


if (userDefinedSettings.direction == "CW" )
{
motor.setMotorDirection(1);
}
else if (userDefinedSettings.direction == "CCW")
{
motor.setMotorDirection(0);
}

startTimeEpoch = rtc.getEpoch();
previousEpoch = startTimeEpoch;
routineRunning = true;
Expand Down
153 changes: 120 additions & 33 deletions src/platformio/osww-server/src/utils/MotorControl.cpp
Original file line number Diff line number Diff line change
@@ -1,46 +1,54 @@
#include "MotorControl.h"

// Define the static instance variable
MotorControl* MotorControl::instance = nullptr;

#if PWM_MOTOR_CONTROL
#include <ESP32MX1508.h>
#define CH1 1
#define CH2 2
int motorSpeed = 145;
#endif

#if STEPPER_MOTOR_CONTROL
#include <TMC2209.h>

HardwareSerial & serial_stream = Serial2;
#ifdef STEPPER_MOTOR_CONTROL
#include <TMCStepper.h>
#include <SoftwareSerial.h>

const uint16_t EN_PIN = 4; // Enable
const uint16_t DIR_PIN = 16; // Direction
const uint16_t STEP_PIN = 17; // Step

const signed long RUN_VELOCITY = 20000;
const signed long STOP_VELOCITY = 0;

#define SW_RX 3 // TMC2208/TMC2224 SoftwareSerial receive pin
#define SW_TX 1 // TMC2208/TMC2224 SoftwareSerial transmit pin
#define SERIAL_PORT Serial1 // TMC2208/TMC2224 HardwareSerial port
#define DRIVER_ADDRESS 0b00 // TMC2209 Driver address according to MS1 and MS2

const uint16_t R_SENSE = 0.11f; // TMC2209 - SilentStepStick series use 0.11

const uint8_t STEP_PIN = 17;
const uint8_t DIRECTION_PIN = 16;

const int32_t RUN_VELOCITY = 20000;
const int32_t STOP_VELOCITY = 0;
const uint16_t HALF_STEP_DURATION_MICROSECONDS = 10;
SoftwareSerial softwareSerial(SW_RX, SW_TX); // Create SoftwareSerial object
TMC2208Stepper driver = TMC2208Stepper(&softwareSerial, R_SENSE); // Use SoftwareSerial object

// current values may need to be reduced to prevent overheating depending on
// specific motor and power supply voltage
const uint8_t RUN_CURRENT_PERCENT = 100;
// For non-blocking stepper movement
hw_timer_t *timer = NULL;
volatile bool stepPinState = LOW;
static bool timerConfigured = false;

// Instantiate TMC2209
TMC2209 stepper_driver;
// For stepper timing control (RPM)
uint16_t microSteps = 8;
uint16_t rmsCurrent = 800;
uint64_t timerMicroSecondInterval = 400; // 937 microseconds for 40 RPM / 400 microseconds for 100 RPM

#endif

MotorControl::MotorControl(int pinA, int pinB, bool pwmMotorControl)
{
#if STEPPER_MOTOR_CONTROL
#ifdef STEPPER_MOTOR_CONTROL
instance = this;
stepperSetup();

stepper_driver.setup(serial_stream);

pinMode(STEP_PIN, OUTPUT);
pinMode(DIRECTION_PIN, OUTPUT);

stepper_driver.setRunCurrent(RUN_CURRENT_PERCENT);
stepper_driver.enableCoolStep();
stepper_driver.enable();

_motorDirection = 0;
#else
_pinA = pinA;
Expand All @@ -50,14 +58,76 @@ MotorControl::MotorControl(int pinA, int pinB, bool pwmMotorControl)
#endif
}

void MotorControl::stepperSetup() {

softwareSerial.begin(9600);

pinMode(EN_PIN, OUTPUT);
pinMode(STEP_PIN, OUTPUT);
pinMode(DIR_PIN, OUTPUT);
digitalWrite(EN_PIN, LOW);

driver.begin();
driver.toff(5); // Enables driver in software
driver.rms_current(rmsCurrent); // Set motor RMS current in mA
driver.microsteps(microSteps); // Set microsteps to 1/8th because reasons
driver.stealth(); // Enable stealthChop
}

// This private function is used to toggle the step pin by the timer
void IRAM_ATTR MotorControl::onTimer()
{
digitalWrite(STEP_PIN, stepPinState);
stepPinState = !stepPinState;
}

void IRAM_ATTR MotorControl::onTimerStatic()
{
instance->onTimer();
}

void killTimer()
{
Serial.println("[INFO] - Killing timer");

timerAlarmDisable(timer); // Disable the timer to stop
timerDetachInterrupt(timer); // Detach the interrupt
timerEnd(timer); // End the timer

stepPinState = LOW;
digitalWrite(STEP_PIN, stepPinState);

timer = NULL;
timerConfigured = false;
}

void MotorControl::configureHardwareTimer()
{
if (!timerConfigured)
{
timer = timerBegin(0, 80, true); // Timer 0, prescaler 80 (1 MHz clock)
timerAttachInterrupt(timer, &onTimerStatic, true); // Attach onTimer function to timer
timerAlarmWrite(timer, timerMicroSecondInterval, true); // Set timer interval 937 microseconds for 40 RPM
timerAlarmEnable(timer); // Enable the timer
timerConfigured = true;
}

}

void MotorControl::clockwise()
{
#if PWM_MOTOR_CONTROL
MX1508 pwmControl(_pinA, _pinB, CH1, CH2);
pwmControl.motorGo(motorSpeed);
#elif STEPPER_MOTOR_CONTROL
// stepper_driver.moveAtVelocity(RUN_VELOCITY);
stepper_driver.moveUsingStepDirInterface();
// Set the direction pin
if (timerConfigured) timerAlarmDisable(timer);

digitalWrite(DIR_PIN, LOW);
delay(10);

if (timerConfigured) timerAlarmEnable(timer);
// Non-blocking step handling is now through the timer function; "configureHardwareTimer()"
#else
digitalWrite(_pinA, HIGH);
digitalWrite(_pinB, LOW);
Expand All @@ -71,8 +141,14 @@ void MotorControl::countClockwise()
MX1508 pwmControl(_pinA, _pinB, CH1, CH2);
pwmControl.motorRev(motorSpeed);
#elif STEPPER_MOTOR_CONTROL
// stepper_driver.moveAtVelocity(RUN_VELOCITY);
stepper_driver.moveUsingStepDirInterface();
// Set the direction pin
if (timerConfigured) timerAlarmDisable(timer);

digitalWrite(DIR_PIN, HIGH);
delay(10);

if (timerConfigured) timerAlarmEnable(timer);
// Non-blocking step handling is now through the timer function; "configureHardwareTimer()"
#else
digitalWrite(_pinA, LOW);
digitalWrite(_pinB, HIGH);
Expand All @@ -86,8 +162,10 @@ void MotorControl::stop()
MX1508 pwmControl(_pinA, _pinB, CH1, CH2);
pwmControl.motorBrake();
#elif STEPPER_MOTOR_CONTROL
stepper_driver.moveAtVelocity(STOP_VELOCITY);
stepper_driver.moveUsingStepDirInterface();
if (timerConfigured)
{
killTimer();
}
#else
digitalWrite(_pinA, LOW);
digitalWrite(_pinB, LOW);
Expand All @@ -100,15 +178,21 @@ void MotorControl::determineMotorDirectionAndBegin()
if (_motorDirection)
{
#if STEPPER_MOTOR_CONTROL
stepper_driver.disableInverseMotorDirection();
clockwise(); // We call this for logging purposes
if (!timerConfigured) {
configureHardwareTimer();
}
#else
clockwise();
#endif
}
else
{
#if STEPPER_MOTOR_CONTROL
stepper_driver.enableInverseMotorDirection();
countClockwise(); // We call this for logging purposes
if (!timerConfigured) {
configureHardwareTimer();
}
#else
countClockwise();
#endif
Expand All @@ -123,4 +207,7 @@ int MotorControl::getMotorDirection()
void MotorControl::setMotorDirection(int direction)
{
_motorDirection = direction;

Serial.print("[INFO] - MOTOR CONTROLLER - Setting direction to: ");
Serial.println(_motorDirection ? "CW" : "CCW");
}
10 changes: 10 additions & 0 deletions src/platformio/osww-server/src/utils/MotorControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ class MotorControl
int _motorDirection;
bool _pwmMotorControl;

void stepperSetup();

static void IRAM_ATTR onTimerStatic(); // Add this line

void onTimer();

void configureHardwareTimer();

static MotorControl* instance; // Add this line

public:
MotorControl(int _pinA, int _pinB, bool pwmMotorControl = false);

Expand Down

0 comments on commit cd794ce

Please sign in to comment.