simple pin timer

what i want to do is have the arduino count time between when a switch is pressed, or rather a sequence like this:
motor turns on and timer starts counting, switch is high
person presses switch, it goes low, motor stops, timer stops
then the person releases the switch and the motor starts up, the timer starts back up
this happens until the timer reaches a total time of .5 seconds.
after that the motor switches directions and starts the process over.
basically this is for a user-controlled oscillating easel for a painting. .5 seconds is about the time it takes to rotate 45 degrees with the motor i have it set up with. i want this to oscillate back and forth but have the user able to stop it anywhere in that interval for any length of time.

i know the millis() function counts time since the arduino has been on, but i don't want that. is there a function example i can use that works like millis() but tells me how long a PIN has been on/high? i don't want to use a delay function because i want the user to be able to input how long this thing stops for. i'm trying the pulseIN() function but getting weird results.

any ideas? i have a switch controlled oscillation working (routed through an h-bridge so every time the user hits the switch the motor changes directions) and an automatic program that just oscillates back and forth about every half a second, but i'm trying to combine these as explained.

Hey,

I think I have a solution for you. It utilizes the millis() function, but keeps track of current time and elapsed time only while a switch is ON. Also, when the elapsed time reaches a predetermined amount (500 milliseconds) it changes direction.

It stays in the 'while' loop and keeps spinning the motor back/forth until the switch is turned off, then it exits WHILE loop and finishes IF scope keeping track of the current elapsed motor time.

Next time the switch is flipped on, it will keep track of current elapsed time PLUS previous elapsed time, until it totals 500 milleseconds, then it will toggle direction and reset the previous elapsed time to zero - so it doesn't keep adding the lastTime into the current elapsedTime.

Anyway, I hope it makes sense. Fairly simple though. It could be refined more I'm sure. I just wrote this up because it seemed you had a valid question that I was curious about as well. Fun stuff.

int toggleSwitch = 10;     // switch on digital pin 10
int motorRight = 11;  // output to motor to spin clockwise - pin 11
int motorLeft = 12;    // output to motor to spin counter-clockwise - pin 12
                                  
unsigned long currentTime;
unsigned long startTime;
unsigned long lastTime = 0;
unsigned long elapsedTime;
unsigned long timeToChange = 500;   // .5 seconds -- doesn't need to be unsigned long, but this will let you make it really large
int motorDirection = 0;             // 0 for clockwise (right) 1 for counterclockwise (left)  this is the starting motor direction


void motorSpin()
{
  if (motorDirection == 0)
  {
    motorLeft = LOW;            
    motorRight = HIGH;
  }
  if (motorDirection == 1)
  {
    motorRight = LOW;
    motorLeft = HIGH;
  } 
}

void motorKill()
{
  motorLeft = LOW;
  motorRight = LOW;
}

void directionToggle()
{
  if (motorDirection == 0)
    motorDirection = 1;
  if (motorDirection == 1)
    motorDirection = 0;
}

void setup()
{
  pinMode(motorRight, OUTPUT);
  pinMode(motorLeft, OUTPUT);
  pinMode(toggleSwitch, INPUT);
}

void loop()
{
  if (toggleSwitch == HIGH)
  {
    startTime = millis();              // sets the start of the countdown - only for the first
                                       // time the switch is flipped.  After that, it only resets
                                       // the counter when it reaches 500 milliseconds
    motorSpin();                       
    while (toggleSwitch == HIGH)       
    {
      currentTime = millis();
      elapsedTime = (currentTime - startTime + lastTime);
      if (elapsedTime > timeToChange)
      {
        directionToggle();
        startTime = millis();
        lastTime = 0;              // resets 'lastTime' to zero so it won't keep adding it into current elapsed time
      }
    }
    motorKill();                      // stops motors
    lastTime = elapsedTime;           // records current elapsed time
  }
}

hope this works for you

Tip: Use boolean logic to make the above code far more efficient.

E.g.

void motorSpin()
{
  motorLeft = motorDirection;
  motorRight = !motorDirection;
}

void directionToggle()
{
  motorDirection = !motorDirection;
}

Note: Completely untested and assuming a few things. (I dont have a Arduino yet)
Tricks like this however are very efficent. :slight_smile: