monitoring state change over time period SOLVED

Good Day

I am wanting to run a stepper motor while an optical switch is repeatedly changing state from low to high. when it stops changing state i want to stop the stepper motor. i will use this to "HOME" the position of the "comb" pictured below..

I have modified the "button state " code to monitor and count the state changes from low to high.

Any direction will be appreciated.

[code]
const int dir = 4;
const int Step = 5;
const int slp = 6;
const int  optoPin = 7;    // the pin that the opto is attached to


// Variables will change:
int optoCounter = 0;   // counter for the number of opto presses
int optoState = 0;         // current state of the opto
int lastoptoState = 0;     // previous state of the opto

void setup() {
  // initialize the opto pin as a input:
  pinMode(optoPin, INPUT_PULLUP);
  // initialize the LED as an output:

  pinMode (dir, OUTPUT);
  pinMode(Step, OUTPUT);
  digitalWrite(slp, HIGH);

  // initialize serial communication:
  Serial.begin(115200);
}


void loop() {
  // read the opto input pin:
  optoState = digitalRead(optoPin);

  // compare the optoState to its previous state
  if (optoState != lastoptoState) {
    // if the state has changed, increment the counter
    if (optoState == HIGH) {
      // if the current state is HIGH then the opto went from off to on:
      optoCounter++;

      Serial.print("number of comb counts: ");
      Serial.println(optoCounter);
    } else { }

  }
  // save the current state as the last state, for next time through the loop
  lastoptoState = optoState;

}

void IndexMotor() 
{
         digitalWrite(Step, HIGH);
      delay(dt);
      digitalWrite(Step, LOW);
}

[/code]

capture a time stamp whenever there is a state change

separately monitor the time since the last state change and take some action when the time exceeds some threshold

+1 what gcjr said. The following might help you understand how to monitor the time.

BlinkWithoutDelay

Arduino Multiple Things

Several Things at a Time

Thank you both for some direction

I would, instead of looking for a time between input state changes, count the number of stepper steps between input state changes. If you find that typically 15 or 16 steps happen between state changes, you can stop when you get to the 17th step and the input state has not changed.

thank you.
so to get the order right i think i would like to:
push a button to start the cycle
check and record the opto state
start motor moving (this will begin the change in state transitions)
count 10 steps and check opto state (every 10 steps of the motor a transition change should occur)
if opto state == last opto state stop motor else
keep motor turning

Does this sound right?

how can i get the IndexMotor function to stop at the else. Is there a STOP or END command?

   //-----------------------------------------------------------------------------------------
  if (cycleButtonState == LOW) //push button to start the cycle
  {
    optoState = digitalRead(optoPin);//read slotted optical sensor
    stepCount = 0;//set stepcount
    indexMotor();//start motor increase stepcount++

    if (stepCount == 10) {
      newoptoState = digitalRead(optoPin);
      if (optoState != newoptoState) {
        stepCount=0;
      }
      else{??????????}//how do I stop the IndexMotor()??
    }
  }
}

void IndexMotor()
{

  digitalWrite(Step, HIGH);
  delay(dt);
  digitalWrite(Step, LOW);
  stepCount++;
}

ultratec:
thank you.
so to get the order right i think i would like to:
push a button to start the cycle
check and record the opto state
start motor moving (this will begin the change in state transitions)
count 10 steps and check opto state (every 10 steps of the motor a transition change should occur)
if opto state == last opto state stop motor else
keep motor turning

Does this sound right?

I was thinking more like:
if the input state just changed, set the step count to zero
if the step count has reached 11, end the loop.
take a step and increment the step count.

ultratec:
how can i get the IndexMotor function to stop at the else. Is there a STOP or END command?

Stop calling indexMotor(). If you are doing this in a loop, exit the loop. If you can't exit the loop, set a flag to indicate you are done and check that flag before doing the next step.

ultratec? As in Ultratec stepper?

-jim lee

If, when homing, the period between pulses is, say 5ms. If the period between pulses exceeds 8ms, you are home.

thanks for the direction and suggestions, here is what i finally came up with. I know that every 10 steps i should get a change in state of the opto, if I don't then i know to stop the motor.

i don't have the motor or the opto hooked up, but instead wrote the steps to the serial monitor and manually changed state ever 10 steps with a pushbutton to test the condition. all seemed to work.

[code]

//make the comb "home" using the optical sensor and the stepper motor. If the optical sensor hasn't changed state in 10 (FULLSTEP) steps of the stepper motor
//then stop the motor will reverse to find edge of the comb.



const int dir = 4;
const int Step = 5;
const int slp = 6;
const int  optoPin = A4;    // the pin that the opto is attached to changed from Pin 7 for testing purposes.
const int led = 13;
int cycleButtonState;
const int cycleButt = A3;
const int dt = 100;
unsigned int stepCount;
int laststepcount;
const int stepinterval = 10;
int motorState = 1;

unsigned long previousMillis = 0;        // will store last time OPTOSTATE was updated

// constants won't change:
const long interval = 1000;           // interval at which to check OPTOSTATE (milliseconds)



// Variables will change:
int optoCounter = 0;   // counter for the number of opto presses
int optoState ;         // current state of the opto
int newoptoState ;     // previous state of the opto

void setup() {
  // initialize the opto pin as a input:
  pinMode(optoPin, INPUT_PULLUP);
  // initialize the LED as an output:

  pinMode (dir, OUTPUT);
  pinMode(Step, OUTPUT);
  pinMode(slp, OUTPUT);
  pinMode(led, OUTPUT);
  pinMode(cycleButt, INPUT_PULLUP);
  digitalWrite(slp, HIGH);
  digitalWrite(led, LOW);

  // initialize serial communication:
  Serial.begin(115200);

  optoState = digitalRead(optoPin);
  cycleButtonState = digitalRead(cycleButt);
  Serial.print ("Cycle Button State: ");
  Serial.println (cycleButtonState);
  Serial.print ("Optical State: ");
  Serial.println (optoState);
  Serial.print ("NEW Optical State: ");
  Serial.println (newoptoState);

}


void loop() {  // read the opto input pin:
  optoState = digitalRead(optoPin);
  cycleButtonState = digitalRead(cycleButt);



  //-----------------------------------------------------------------------------------------Comb Homing
  if (cycleButtonState == LOW) //push button to start the cycle
  { optoState = digitalRead(optoPin);//read slotted optical sensor
    while (motorState == 1) {




      IndexMotor();//start motor increase stepcount++
      Serial.print ("Step Count: ");
      Serial.println (stepCount);

      while (stepCount == 10) {
        newoptoState = digitalRead(optoPin);
        if (optoState != newoptoState) {
          stepCount = 0;
          optoState = newoptoState;
        } else {
          Serial.println ("HOME");
          motorState = 0;
          break;
        }
      }
    }
  }

  
}//VOID


void IndexMotor()
{

  digitalWrite(Step, HIGH);
  delay(dt);
  digitalWrite(Step, LOW);
  stepCount++;

}

[/code]