Here's an example that uses a Finite State Machine to do the ramping. It ramps up over 6 seconds, holds at full speed until count 25, and then ramps down over 6 seconds. You kick off a sequence by setting RampStartTime to millis(). When RampStartTime is zero the sequence is done.
#define DEBUG_RAMP
#define MAX_PWM 255
int PWM_val = 0;
unsigned long RampStartTime = 0;
unsigned long currentTime = 0;
const unsigned long RampInterval = 6000; // Ramp timing cycle at 6 seconds
int EncoderCount = 0;
const int StartDecelerationCount = 25;
void setup()
{
// put your setup code here, to run once:
Serial.begin(115200);
delay(1000); //0 - 999 blocking count
RampStartTime = millis(); // initiate ramp-up
}
void loop()
{
// put your main code here, to run repeatedly:
delay(500); //0 - 499 blocking count
// top of loop statements
EncoderCount += 1; // simulate encoder count
Ramp_PWM();
}
enum RampStates {Idle, RampingUp, FullSpeed, RampingDown} RampState = Idle;
int Ramp_PWM()
{
unsigned long currentTime = millis();
unsigned long elapsedRampTime = currentTime - RampStartTime;
switch (RampState)
{
case Idle:
if (RampStartTime != 0)
{
EncoderCount = 0;
PWM_val = 0;
#ifdef DEBUG_RAMP
Serial.println(F("Starting Ramp Up"));
#endif
RampState = RampingUp;
}
break;
case RampingUp:
if (elapsedRampTime <= RampInterval)
{
PWM_val = MAX_PWM *
(float(elapsedRampTime) / float(RampInterval));
}
else
{
#ifdef DEBUG_RAMP
Serial.println(F("Reached Full Speed"));
#endif
RampState = FullSpeed;
}
break;
case FullSpeed:
PWM_val = MAX_PWM;
if (EncoderCount >= StartDecelerationCount)
{
RampStartTime = currentTime;
#ifdef DEBUG_RAMP
Serial.println(F("Start Ramping Down"));
#endif
RampState = RampingDown;
}
break;
case RampingDown:
if (elapsedRampTime <= RampInterval)
{
PWM_val = MAX_PWM - MAX_PWM *
(float(elapsedRampTime) / float(RampInterval));
}
else
{
PWM_val = 0;
RampStartTime = 0;
#ifdef DEBUG_RAMP
Serial.println(F("End Ramping Down"));
#endif
RampState = Idle;
}
}
#ifdef DEBUG_RAMP
if (RampStartTime != 0)
{
Serial.print(F("Elapsed time: "));
Serial.print(elapsedRampTime);
Serial.print(F(", Encoder Count: "));
Serial.print(EncoderCount);
Serial.print(F(", PWM value: "));
Serial.println(PWM_val);
}
#endif
return 0;
}