I'm trying to use a DC motor with pinion engaged to a rack gear, and have that motor move a distance, save the distance, delay, reverse, and travel back the same distance from where it started, delay, do it again. I want to start/stop the initial save with a button push, then from those saves, loop the motor movement.

I have considered using a Hall effect sensor or reed switch to count, but it seems a software interrupt or timing is easier using millis(). I researched and found that millis() cannot be reset, so I'm wondering if this is possible.

I haven't started a sketch, but I got this idea from the BlinkWithoutDelay example sketch included with the Arduino IDE. Like, have the motor positioned at "home" position, button push, start the timer, motor travels to end of work piece, stop the timer, save that forward distance traveled into a variable, reverse the motor, (at this point the timer would be at 0 again for the reverse travel) travel back to "home" save that reversed distance traveled into another variable with a button push, and then use these start/stop values in a loop. So I would save the values with a button pushes, then just loop that.

Or I'm thinking about putting an if or while button push outside the loop with a nested counter++, eyeballing the motor travel, once it gets to where I want it, save those counts in variables, then using them in the loop to analogWrite() to the motor.

  • Comments are not for extended discussion; this conversation has been moved to chat.
    – Nick Gammon
    Jan 25, 2018 at 4:58
  • Comments under a question are for clarifying the question, and for the OP to respond to such requests for clarification. For example "what type of Arduino do you have?". They are not for extended debugging of the issue. This is not a forum. If you (Jim) want to clarify your question please edit the question to do so.
    – Nick Gammon
    Jan 25, 2018 at 5:00

1 Answer 1


You can't reset the millis() function, but you can count the amount of milliseconds and stop when necessary: beware though, the positioning might not be as precise as you wish and you have to consider the error will accumulate on the long run.

Nonetheless here is the code:

uint16_t duration;
bool direction = true;
void loop() {
  if (duration != 0 and !buttonPressed()) {
    // running back and forth if setup and no "finish" button detect
    uint16_t start = millis(); // reset the timer
    while (millis() - start < duration && !buttonPressed()) {
      ; // keep going
    direction = !direction; // reverse direction
  } else if (duration == 0) {
    // your motor positioning setup
    while (!buttonPressed()) {
      ; // wait for button to start positioning
    uint16_t start = millis(); // ask for time
    startMotor(true); // run the motor cw
    while (!buttonPressed()) {
      ; wait for button to end positioning
    duration = millis() - start; // store duration
    direction = false; // reverse motor direction
    // next time loop() is executed the motor will go back to home
bool buttonPressed() {} // define this to determine if the button has been pressed, safer if you use an interrupt
void startMotor(bool cw) {} // define this to run your motor clockwise or counterclockwise
  • 1
    Comments are not for extended discussion; this conversation has been moved to chat.
    – Majenko
    Jan 23, 2018 at 13:32
  • This is a great answer; I don't see the fault and it should be accepted. The first thing the answer does is point out the misunderstanding about millis() not being reset-able, and the second benefit is an example of using millis() properly. Jun 19, 2018 at 4:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.