How to increase PWM at specific time interval from 0 to 255 and back to 0?

Hello,

I'm trying to solve the following problem: increase PWM to control DC motor, at specific time interval, every 200 ms, while counting the total encoder ticks during that interval and increase the PWM in steps from 0 to 255 and decrease in steps back to 0.

Here is my attempt using Timer2 library. The timer ISR works and the PWM value increases from 0 to 255 at a defined time interval. But i can't figure out how to make the PWM go back to 0 at the same time interval and also display the total encoder ticks during each interval.

#include <MsTimer2.h>

const int motor_AIN1 = 8;    //set the motor driver pins 
const int motor_AIN2 = 12;
const int motor_PWMA = 10;
const int motor_EncoderA = 2;   //set the encoder pin.

volatile long encoder_count = 0;
int PWMvalue = 0; //initialise PWM value
int copy_encoder_count = 0; //copy encoder count

#define INTERVAL 200  //time interval in milliseconds to run timer interrupt function

volatile bool state = false;

void setup() //execute only once
{
  Serial.begin(9600);

  //set the control pins of motor to OUTPUT
  pinMode(motor_AIN1,OUTPUT);
  pinMode(motor_AIN2,OUTPUT);
  pinMode(motor_PWMA,OUTPUT);

  //speed encoder input
  pinMode(motor_EncoderA, INPUT_PULLUP);

  //wait 1 second before starting the motor
  delay (1000);
  
  attachInterrupt(digitalPinToInterrupt(motor_EncoderA), encoderISR, CHANGE); //RISING or FALLING or LOW or CHANGE
    
  MsTimer2::set(INTERVAL, timerFunction);    //configures the interrupt function to run every time interval in ms.
  MsTimer2::start();              //start interrupt
}

void loop() 
{
  if (state == true)
  {
    printValues();
    
    if(PWMvalue < 255)   //the PWM value should never exceed 255.
      PWMvalue++;
    
    digitalWrite(motor_AIN1, HIGH);
    digitalWrite(motor_AIN2, LOW);
    analogWrite(motor_PWMA, PWMvalue);
    
    state = !state;
  }
}

void encoderISR() //increments the value of the encoder count every pulse
{
  encoder_count++;
}

void printValues()
{
  Serial.print("Time interval: "); //PWM value and the corresponding total encoder pulses every time interval in ms.
  Serial.print(INTERVAL);
  Serial.print(" ms. ");
  Serial.print("PWM value: ");
  Serial.print(PWMvalue);
  Serial.print(". ");
  Serial.print("Total encoder pulses: ");
  Serial.println(copy_encoder_count);
}

void timerFunction()  //timer interrupt function
{
  //interrupts are disabled by default when the timer ISR is running
  copy_encoder_count = encoder_count;     //assign the value counted by encoder to copy_encoder_count
  encoder_count = 0;     //Reset the count value
  
  state = !state; //toggle state
}

Here is an initial part of the output on the Arduino IDE Serial Monitor:

Time interval: 200 ms. PWM value: 0. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 1. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 2. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 3. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 4. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 5. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 6. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 7. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 8. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 9. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 10. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 11. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 12. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 13. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 14. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 15. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 16. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 17. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 18. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 19. Total encoder pulses: 1
Time interval: 200 ms. PWM value: 20. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 21. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 22. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 23. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 24. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 25. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 26. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 27. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 28. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 29. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 30. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 31. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 32. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 33. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 34. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 35. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 36. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 37. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 38. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 39. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 40. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 41. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 42. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 43. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 44. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 45. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 46. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 47. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 48. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 49. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 50. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 51. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 52. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 53. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 54. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 55. Total encoder pulses: 0
Time interval: 200 ms. PWM value: 56. Total encoder pulses: 9
Time interval: 200 ms. PWM value: 57. Total encoder pulses: 33
Time interval: 200 ms. PWM value: 58. Total encoder pulses: 40
Time interval: 200 ms. PWM value: 59. Total encoder pulses: 42
Time interval: 200 ms. PWM value: 60. Total encoder pulses: 43
Time interval: 200 ms. PWM value: 61. Total encoder pulses: 44
Time interval: 200 ms. PWM value: 62. Total encoder pulses: 45
Time interval: 200 ms. PWM value: 63. Total encoder pulses: 47
Time interval: 200 ms. PWM value: 64. Total encoder pulses: 47
Time interval: 200 ms. PWM value: 65. Total encoder pulses: 48
Time interval: 200 ms. PWM value: 66. Total encoder pulses: 50
Time interval: 200 ms. PWM value: 67. Total encoder pulses: 50
Time interval: 200 ms. PWM value: 68. Total encoder pulses: 51
Time interval: 200 ms. PWM value: 69. Total encoder pulses: 53

The PWM goes up to 255 and then it stays there indefinitely.

But i can't figure out how to make the PWM go back to 0.
Should it ramp down to 0 or go to 0 in one step ?

UKHeliBob:
Should it ramp down to 0 or go to 0 in one step ?

It should ramp down from 255 to 0, at the same time interval of 200 ms, while doing the same thing as when the PWM was ramping up, meaning, count the total encoder ticks during that time interval.

Or something like:

byte PWMvalue = 0;
int Direction = 1;

...

  if(PWMvalue == 255)
    Direction = -1;

  if (PWMvalue == 0)
    Direction = 1;

  PWMValue += Direction;
1 Like