/* */ #include #include "SevSeg.h" #include #include // PIN USAGE #define SEVSEG_DIGIT_1 16 #define SEVSEG_DIGIT_2 17 #define SEVSEG_DIGIT_3 3 #define SEVSEG_DIGIT_4 4 #define SEVSEG_COLON 2 #define SEVSEG_SEGMENT_A 8 #define SEVSEG_SEGMENT_B 14 #define SEVSEG_SEGMENT_C 6 #define SEVSEG_SEGMENT_D A1 #define SEVSEG_SEGMENT_E 23 #define SEVSEG_SEGMENT_F 7 #define SEVSEG_SEGMENT_G 5 #define SEVSEG_SEGMENT_H 22 #define ROT_BUTT 11 #define ROT_ENC_1 12 #define ROT_ENC_2 13 #define STEPPER_STEP 10 #define STEPPER_DIRECTION 0 #define STEPPER_ENABLE A5 //SETTINGS #define SEVSEG_REFRESH 250 // Refresh rate in ms #define SEVSEG_BRIGHTNESS 100 // 100%, full brightness #define STEPPER_MAX_SPEED 5000 #define STEPPER_MIN_SPEED 0 #define STEPPER_ACCELERATION 30.0 #define STEP_MOTOR_STEPS_PER_TURN 200 #define STEPPER_MICROSTEP 8 SevSeg sevseg; //Instantiate a seven segment controller object // Setup a RoraryEncoder for pins 12 and 13: RotaryEncoder encoder(ROT_ENC_1, ROT_ENC_2); AccelStepper stepper(1, STEPPER_STEP, STEPPER_DIRECTION); EveryTimer timer; //Global variables byte numDigits = 4; byte digitPins[] = {SEVSEG_DIGIT_1, SEVSEG_DIGIT_2, SEVSEG_DIGIT_3, SEVSEG_DIGIT_4}; byte segmentPins[] = {SEVSEG_SEGMENT_A, SEVSEG_SEGMENT_B, SEVSEG_SEGMENT_C, SEVSEG_SEGMENT_D, SEVSEG_SEGMENT_E, SEVSEG_SEGMENT_F, SEVSEG_SEGMENT_G, SEVSEG_SEGMENT_H}; bool resistorsOnSegments = false; // 'false' means resistors are on digit pins byte hardwareConfig = COMMON_ANODE; // See README.md for options bool updateWithDelays = false; // Default. Recommended bool leadingZeros = false; // Use 'true' if you'd like to keep the leading zeros long refresh_timer = 0; long countdown = 0; byte hours = 0; byte minutes = 0; byte seconds = 0; int current_rpm = 0; int new_rpm = 0; static bool currBut = true; byte mode = 0; void countdown_callback() { if (current_rpm != 0) { countdown--; if (countdown < 0) { countdown = 0; } hours = countdown / 3600; minutes = (countdown / 60) % 60; seconds = countdown % 60; // Update data to be displayed if (mode == 0) { // mode 0 = display speed digitalWrite(SEVSEG_COLON, false); sevseg.setNumber(current_rpm); } else if (mode == 1) { // mode 1 = display countdown //Blink colon each seconds if (seconds % 2) { digitalWrite(SEVSEG_COLON, true); } else { digitalWrite(SEVSEG_COLON, false); } //Display HH:MM or MM:SS if there is less than 1h left if (hours) { sevseg.setNumber(100*hours+minutes); } else { sevseg.setNumber(100*minutes+seconds); } } Serial.println(countdown); } else { Serial.println("Pause"); } } void update_encoder() { static long currVal = 0; int multiplier = 10; encoder.tick(); long newVal = encoder.getPosition(); if (currVal != newVal) { currVal = newVal; if (mode == 0) { if (current_rpm >= 500) { multiplier = 100; } new_rpm += multiplier * encoder.getDirection(); if (new_rpm < STEPPER_MIN_SPEED) { new_rpm = STEPPER_MIN_SPEED; } if (new_rpm > STEPPER_MAX_SPEED) { new_rpm = STEPPER_MAX_SPEED; } } if (mode == 1) { multiplier = 60; if (countdown >= 3600) { multiplier = 600; } countdown += multiplier * encoder.getDirection(); if (countdown < 0) { countdown = 0; } if (countdown >= 86400) { countdown = 86399; } } Serial.print("RPM: "); Serial.print(current_rpm); Serial.print(" | Countdown: "); Serial.println(countdown); } //Check button for mode change bool newBut = digitalRead(ROT_BUTT); if (newBut != currBut) { currBut = newBut; if (currBut) { mode++; } if (mode == 2) { mode = 0; } else if (mode == 0) { encoder.setPosition(current_rpm); } else if (mode == 1) { encoder.setPosition(countdown); } Serial.print("Mode :"); Serial.println(mode); } } void update_stepper() { if (new_rpm != current_rpm) { new_rpm = current_rpm; stepper.setSpeed(current_rpm); // Enable/Disable motor if (current_rpm == 0) { stepper.disableOutputs(); Serial.println("Stepper : Off"); } else { stepper.enableOutputs(); Serial.println("Stepper : On"); } //if Countdown = 0 => pause (no move but keep speed setting) if (countdown != 0 and current_rpm != 0) { stepper.runSpeed(); } } } void setup() { Serial.begin(115200); pinMode(ROT_BUTT, INPUT_PULLUP); pinMode(SEVSEG_COLON, OUTPUT); sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins, resistorsOnSegments, updateWithDelays, leadingZeros); sevseg.setBrightness(SEVSEG_BRIGHTNESS); stepper.setEnablePin(STEPPER_ENABLE); stepper.disableOutputs(); stepper.setMaxSpeed(STEPPER_MAX_SPEED); stepper.setAcceleration(STEPPER_ACCELERATION); stepper.setSpeed(0); timer.Every(1000, countdown_callback); } void loop() { update_encoder(); //Update countdown timer.Update(); //Make the motor move update_stepper(); //refresh the 7-segment display sevseg.refreshDisplay(); }