#define buttonPin 12
#define revolutionPin A0
#define dirPin 2
#define stepPin 3
#define MIN_RAW 0
#define MAX_RAW 1023
#define MIN_REVOLUTION 1
#define MAX_REVOLUTION 1000
#define STEPS_PER_REVOLUTION 200
#define DEFAULT_REVOLUTION 60
#define INTERVAL_LCD_PRINT 250
#define ONE_SECOND 1010000UL
enum {
CCW,
CW
};
#define DEBOUNCE_PERIOD 10UL // Debounce Delay 10 milliseconds
typedef struct {
private:
bool input;
unsigned long startTime;
public:
bool state;
bool debounce(bool bounce) {
unsigned long currentTime = millis();
bool prevState = state;
if (bounce) {
state = true;
} else {
if (state) {
if (input) {
startTime = currentTime;
}
unsigned long elapsedTime = currentTime - startTime;
if (elapsedTime >= DEBOUNCE_PERIOD) {
state = false;
}
}
}
input = bounce;
return state != prevState & state == true;
}
} debounce_t;
debounce_t buttonDebounce;
bool start;
bool direction;
uint32_t timeDelay;
uint32_t startTime;
void ButtonCondition();
uint32_t rpm(long rpm, long steps);
void StepperMotor(bool enable, bool direction, uint32_t timeDelay = 10L);
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
pinMode(dirPin, OUTPUT);
pinMode(stepPin, OUTPUT);
pinMode(LED_BUILTIN, OUTPUT);
direction = CW;
digitalWrite(dirPin, direction);
digitalWrite(stepPin, LOW);
}
void loop() {
Revolution();
ButtonCondition();
StepperMotor(start, direction, timeDelay);
}
void ButtonCondition() {
bool pressed = buttonDebounce.debounce(!digitalRead(buttonPin));
uint32_t currTime = micros();
if (pressed) {
start = !start;
startTime = currTime;
}
if (start) {
uint32_t elapsedTime = currTime - startTime;
if ( elapsedTime >= ONE_SECOND) {
start = false;
}
}
}
void Revolution() {
long revo = analogRead(revolutionPin);
revo = map(revo, 0, 1023, 60, 1000);
timeDelay = rpm(revo, STEPS_PER_REVOLUTION);
}
void StepperMotor(bool en, bool dir, uint32_t timeDelay) {
static bool enable;
static uint32_t startTime;
uint32_t currTime = micros();
if (en & !enable) {
startTime = currTime;
}
enable = en;
if (enable) {
uint32_t elapsedTime = currTime - startTime;
if (elapsedTime >= timeDelay) {
digitalWrite(dirPin, dir);
digitalWrite(stepPin, HIGH);
digitalWrite(stepPin, LOW);
startTime = currTime;
}
}
}
// Revolution per minute
uint32_t rpm(long rpm, long steps) {
unsigned long div = (unsigned long)rpm * (unsigned long)steps;
return 60000000UL / div;
}