Fair warning: the code below may not compile.
Your application has three states...
Motor On
Motor Off
Motor Stalled
There are three transitions...
Motor Off --> Motor On
Motor On --> Motor Off
Motor On --> Motor Stalled
I would define an enum for the states...
typedef enum ( MotorInit, MotorOff, MotorOn, MotorStalled ) tMotorState;
tMotorState CurrentMotorState;
Then in loop do something roughly like this...
void loop( void )
{
switch ( CurrentMotorState )
{
case MotorInit:
// This stuff could also be done in setup
// Ensure the pin for the motor is off
digitalWrite( MotorPin, 0 );
// Ensure the motor shaft is not rotating (save the state of the encoder, delay, check the state of the encoder)
// Say hello to the human or display a fault message
// If everything looks good, transition to MotorOff
CurrentMotorState = MotorOff;
break;
case MotorOff:
// When the conditions are right, turn the motor on
if ( WhateverIsTrue )
{
digitalWrite( MotorPin, 1 );
CurrentMotorState = MotorOn;
}
break;
case MotorOn:
// When the conditions are right, turn the motor off
if ( WhateverElseIsTrue )
{
digitalWrite( MotorPin, 0 );
CurrentMotorState = MotorOff;
}
// Otherwise, check for a stall
else
{
ThisMillis = millis();
// If the encoder changed, the motor is not stalled
if ( EncoderChanged )
{
LastEncoderMillis = ThisMillis;
}
// If the encoder hasn't changed in 50ms, something is wrong
if ( ThisMillis - LastEncoderMillis >= 50 )
{
digitalWrite( MotorPin, 0 );
CurrentMotorState = MotorStalled;
// Inform the human
}
}
break;
case MotorStalled:
// We need the human's assitance to get out of this state
break;
}
}
I hope that makes sense.