#include <ezBuzzer.h>
#include <AccelStepper.h>
// #define MOTOR_DIST 0x2540BE400
#define MOTOR_DIST 100000
// INTERRUPTS: 0, 1, 2, 3, 7
// attachInterrupt(digitalPinToInterrupt(pin), <callback>, CHANGE|RISING|FALLING|LOW)
struct BtnState {
int lastFlickerableState = 0;
int lastSteadyState = 1;
int currentState = 0;
unsigned long last_debounce = 0;
};
const int PIN_PAUSE = 2;
const int PIN_REVERSE = 3;
const int PIN_POT = A0;
const int PIN_MOTOR_DIR = 4;
const int PIN_MOTOR_STEP = 5;
const int PIN_BUZZER = 6;
const int DEBOUNCE_PERIOD = 50;
const int ACCELERATION = 200;
int BTNS[2] = {PIN_PAUSE, PIN_REVERSE};
const float SPEED_MIN = 0.0;
const float SPEED_MAX = 400.0;
float motorSpeed(0.0);
long motorMove(MOTOR_DIST);
bool pause_state, reverse_state;
BtnState btn_states[2];
AccelStepper myStepper(AccelStepper::DRIVER, PIN_MOTOR_STEP, PIN_MOTOR_DIR);
ezBuzzer buzzer(PIN_BUZZER);
const int melody1[] = {NOTE_E5, NOTE_G5, NOTE_E5, NOTE_E5};
const int dur1[] = {4, 4, 8, 8};
const int melody2[] = {NOTE_D5, NOTE_C5, NOTE_C5, NOTE_D5};
const int dur2[] = {8, 16, 16, 8};
bool clicked[2];
int cnt(0);
void setup() {
// Serial.begin(9600);
pinMode(PIN_PAUSE, INPUT_PULLUP);
pinMode(PIN_REVERSE, INPUT_PULLUP);
pinMode(PIN_BUZZER, OUTPUT);
myStepper.setMaxSpeed(SPEED_MAX);
myStepper.setAcceleration(ACCELERATION);
myStepper.setSpeed(0);
pause_state = true;
reverse_state = false;
}
void beep1() {
buzzer.playMelody(melody1, dur1, 4);
}
void beep2() {
buzzer.playMelody(melody2, dur2, 4);
}
float mapFloat(float x, float in_min, float in_max, float out_min, float out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
void getClicked(unsigned int size, BtnState* states, int* pins, bool* clicked) {
for (unsigned int i=0; i<size; i++) {
clicked[i] = false;
unsigned long ctime = millis();
states[i].currentState = digitalRead(pins[i]);
if (states[i].currentState != states[i].lastFlickerableState) {
states[i].last_debounce = ctime;
states[i].lastFlickerableState = states[i].currentState;
}
if ((ctime - states[i].last_debounce) > DEBOUNCE_PERIOD) {
if (states[i].lastSteadyState == LOW && states[i].currentState == HIGH)
clicked[i] = true;
states[i].lastSteadyState = states[i].currentState;
}
}
}
void loop() {
buzzer.loop();
motorSpeed = pause_state? SPEED_MIN : mapFloat(analogRead(PIN_POT), 0.0, 1023.0, SPEED_MIN, SPEED_MAX);
getClicked(2, btn_states, BTNS, clicked);
if (clicked[0]) { // pause
pause_state = !pause_state;
beep1();
// Serial.print("PAUSE = "); Serial.println(pause_state);
if (pause_state) {
myStepper.stop();
motorSpeed = SPEED_MIN;
}
}
if (clicked[1]) { // reverse
reverse_state = !reverse_state;
beep2();
// Serial.print("REV = "); Serial.println(reverse_state);
myStepper.stop();
motorMove *= -1;
delay(1000);
}
if (motorSpeed != SPEED_MIN) {
myStepper.setSpeed(motorSpeed);
myStepper.move(motorMove);
myStepper.runSpeedToPosition();
}
else
myStepper.stop();
}