mirror of
https://github.com/joshr120/PD-Stepper.git
synced 2025-09-26 22:49:12 +08:00
205 lines
5.3 KiB
C++
205 lines
5.3 KiB
C++
|
|
|
|
/* Code to run a stpper motor with buttons using the USB PD Stepper Driver and Controller
|
|
*
|
|
* by Things by Josh 2024
|
|
*/
|
|
|
|
|
|
|
|
/////////////////////////
|
|
// Pin Defines //
|
|
/////////////////////////
|
|
|
|
//TMC2209 Stepper Driver
|
|
#define TMC_EN 21 //Low to enable motor, high to disable)
|
|
#define STEP 5
|
|
#define DIR 6
|
|
#define MS1 1
|
|
#define MS2 2
|
|
#define SPREAD 7
|
|
#define TMC_TX 17
|
|
#define TMC_RX 18
|
|
#define DIAG 20
|
|
#define INDEX 11
|
|
|
|
//PD Trigger (CH224K)
|
|
#define PG 15 //power good singnal (dont enable stepper untill this is good)
|
|
#define CFG1 38
|
|
#define CFG2 48
|
|
#define CFG3 47
|
|
|
|
//Other
|
|
#define VBUS 4
|
|
#define NTC 7
|
|
#define LED1 10
|
|
#define LED2 12
|
|
#define SW1 35
|
|
#define SW2 36
|
|
#define SW3 37
|
|
#define AUX1 14
|
|
#define AUX2 13
|
|
|
|
|
|
////////////////////////////
|
|
// Global Variable Defines //
|
|
////////////////////////////
|
|
//TMC2209 Stepper Driver
|
|
unsigned long lastStep = 0; //time of last step
|
|
int motorDir = 0; //Stepper motor direction
|
|
bool lastState = 0;
|
|
|
|
//USB PD Trigger
|
|
bool PGState = 0; //power good singal from trigger IC
|
|
|
|
//buttons and motor control
|
|
int counter = 0;
|
|
bool incButtonState = HIGH;
|
|
bool decButtonState = HIGH;
|
|
bool resetButtonState = HIGH;
|
|
unsigned long lastDebounceTime = 0;
|
|
unsigned long debounceDelay = 50;
|
|
|
|
int delays[] = {0, 2000, 1000, 700, 400, 200, 100, 75, 50, 40, 30}; //list of speeds (higher = slower, 0 = stop)
|
|
int numSpeeds = 10;
|
|
|
|
long lastFlash = 0;
|
|
int flashInt = 100;
|
|
bool flashState = 0;
|
|
|
|
|
|
|
|
|
|
void setup() {
|
|
// put your setup code here, to run once:
|
|
|
|
pinMode(SW1, INPUT);
|
|
pinMode(SW2, INPUT);
|
|
pinMode(SW3, INPUT);
|
|
pinMode(LED1, OUTPUT);
|
|
pinMode(LED2, OUTPUT);
|
|
|
|
//PD Trigger Setup
|
|
pinMode(PG, INPUT);
|
|
pinMode(CFG1, OUTPUT);
|
|
pinMode(CFG2, OUTPUT);
|
|
pinMode(CFG3, OUTPUT);
|
|
// 5V 9V 12V 15V 20V (Can also be changed on the fly)
|
|
digitalWrite(CFG1, LOW); // 1 0 0 0 0
|
|
digitalWrite(CFG2, LOW); // - 0 0 1 1
|
|
digitalWrite(CFG3, HIGH); // - 0 1 1 0
|
|
|
|
//Stepper simple setup (no serial comms)
|
|
pinMode(TMC_EN, OUTPUT);
|
|
pinMode(STEP, OUTPUT);
|
|
pinMode(DIR, OUTPUT);
|
|
pinMode(MS1, OUTPUT);
|
|
pinMode(MS1, OUTPUT);
|
|
|
|
digitalWrite(TMC_EN, HIGH); //High to disable on startup
|
|
digitalWrite(MS1, HIGH); //Microstep resolution configuration (internal pull-down resistors: MS2, MS1: 00: 1/8, 01: 1/32, 10: 1/64 11: 1/16
|
|
digitalWrite(MS2, LOW);
|
|
|
|
digitalWrite(LED1, LOW);
|
|
digitalWrite(LED2, LOW);
|
|
|
|
|
|
///////////////////////////////////////
|
|
// Can't auto enter bootloader if
|
|
// serial.begin has been called
|
|
// so hold down SW2 on boot to enable serial
|
|
// (wont auto enter bootloader mode)
|
|
///////////////////////////////////////
|
|
//(Can also manually enter bootloader mode by holding BOOT, press RST, release BOOT)
|
|
|
|
if (digitalRead(SW2) == LOW){ //push = LOW
|
|
Serial.begin(115200);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
void loop() {
|
|
//flash LED to show code is running
|
|
if (millis() - lastFlash > flashInt){
|
|
lastFlash = millis();
|
|
digitalWrite(LED1, flashState);
|
|
if (flashState == 0){
|
|
flashState = 1;
|
|
} else {
|
|
flashState = 0;
|
|
}
|
|
}
|
|
|
|
// Read and doubounce inputs and incriment counter
|
|
if ((millis() - lastDebounceTime) > debounceDelay) {
|
|
lastDebounceTime = millis();
|
|
bool currentIncButtonState = digitalRead(SW3);
|
|
bool currentDecButtonState = digitalRead(SW1);
|
|
bool currentResetButtonState = digitalRead(SW2);
|
|
|
|
if (currentIncButtonState != incButtonState) {
|
|
incButtonState = currentIncButtonState;
|
|
if (incButtonState == LOW) {
|
|
counter++;
|
|
if (counter > numSpeeds){
|
|
counter = numSpeeds;
|
|
}
|
|
Serial.print("Counter increased to: ");
|
|
Serial.println(counter);
|
|
}
|
|
}
|
|
|
|
if (currentDecButtonState != decButtonState) {
|
|
decButtonState = currentDecButtonState;
|
|
if (decButtonState == LOW) {
|
|
counter--;
|
|
if (counter < (numSpeeds*-1)){
|
|
counter = (numSpeeds*-1);
|
|
}
|
|
Serial.print("Counter decreased to: ");
|
|
Serial.println(counter);
|
|
}
|
|
}
|
|
|
|
if (currentResetButtonState != resetButtonState) {
|
|
resetButtonState = currentResetButtonState;
|
|
if (resetButtonState == LOW) {
|
|
counter = 0;
|
|
Serial.println("Counter reset");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
//read PG to check if motor shoulf be enabled (this should be scheduled to not run as often)
|
|
PGState = digitalRead(PG);
|
|
if (counter != 0 and PGState == 0){ //only enable motor if correct voltage seen (to stop motor running off laptop 5V when programming)
|
|
digitalWrite(TMC_EN, LOW); //low to enable (should really only do this on state change)
|
|
|
|
int abs_counter = 0;
|
|
if (counter > 0){ //set direction (should only do this on Dir change really)
|
|
digitalWrite(DIR, HIGH);
|
|
abs_counter = counter;
|
|
} else {
|
|
digitalWrite(DIR, LOW);
|
|
abs_counter = counter*-1;
|
|
}
|
|
|
|
if (micros() - lastStep > delays[abs_counter]){
|
|
lastStep = micros();
|
|
digitalWrite(STEP, lastState);
|
|
if (lastState == 0){
|
|
lastState = 1;
|
|
} else {
|
|
lastState = 0;
|
|
}
|
|
}
|
|
} else{
|
|
digitalWrite(TMC_EN, HIGH); //disable stepper as voltage not as expected (should really only do this on state change)
|
|
}
|
|
}
|