Here is the Arduino Program that will listen to the Serial Port. Based on the command received on the Serial Port it will either Set the Direction of the Motor or Set the PWM Duty Cycle of the Motor Driver, thereby controlling the speed of the motor. The Program uses the Frequency Count Library to measure the speed of the Motor by a optical disk encoder and a slotted optical sensor.

To make the Motor rotate in Clockwise direction send the command "cw#" over Serial terminal.

To make it rotate in anti clock wise direction send "ccw#".

To set motor speed send in the following format e.g. "s128#" i.e. to set PWM at 50% and so on. The numeric values in the string "s!!!#", where !!! can be 0 to 255, i.e 8 bit Integer.

Arduino Code:
  1. // Declare Freq Count Pin
  2. // Unusable Pins by using FreqCount Library 3, 9, 10, 11
  3. #include <FreqCount.h>
  4.  
  5. // Declare RPM(Pulses)-in Pin / Encoder Pin
  6. #define MotorRPM 5;
  7.  
  8.  
  9. // Declare Motor Driver Pins
  10. #define MotorPlus 2
  11. #define MotorMinus 4
  12. #define MotorPWM 6
  13.  
  14.  
  15.  
  16. // Declare global speed variable;
  17. int rpm; // Measured Spped
  18. int pwmDuty; // Desired Speed as Duty of PWM
  19.  
  20.  
  21. // Declare variable to store command
  22. String command;
  23. // e.g. s120# will set pwm to 120
  24. // e.g. dcw# will set direction to cw
  25. // e.g. dccw# will set ccw direction of motor
  26. // e.g. m# will report current speed
  27.  
  28. void setup() {
  29. // start serial port at 9600 bps:
  30. //Serial.begin(115200);
  31. Serial.begin(500000);
  32. FreqCount.begin(500);
  33. // Begin frequency counting. GateInterval is the time in milliseconds
  34. // for each measurement. Using 1000 provides direct frequency output without mulitplying or dividing by a scale factor.
  35.  
  36. }
  37.  
  38. void loop() {
  39. // Send Motor Speed
  40.  
  41. // Receive PWM Duty
  42. handleSerial();
  43. }
  44.  
  45. int measureRPM()
  46. {
  47. //Measure RPM of Motor by calculating no of pulses in a fixed time interval
  48. if (FreqCount.available()) {
  49. unsigned long count = FreqCount.read(); // Pulses in 500 milliSecond
  50. rpm = (count/8) * 60 * 2;
  51. // RPM = (No of counted Pulses / No of Cuts in the Encoder) * Time Interval Scaling factor
  52. // Determine the time interval scaling factor from FreqCount.begin();
  53. }
  54. return rpm;
  55. }
  56.  
  57. void setMotorSpeed()
  58. {
  59. // Set the Motor Speed by AnalogWrite
  60. analogWrite(MotorPWM, pwmDuty);
  61. }
  62.  
  63. void setMotorDirectionCW()
  64. {
  65. // Set Motor Direction ClockWise
  66. digitalWrite(MotorPlus, HIGH);
  67. digitalWrite(MotorMinus, LOW);
  68. }
  69.  
  70. void setMotorDirectionCCW()
  71. {
  72. // Set Motor Direction Counter-ClockWise
  73. digitalWrite(MotorPlus, LOW);
  74. digitalWrite(MotorMinus, HIGH);
  75. }
  76.  
  77. void handleSerial() {
  78. while (Serial.available() > 0) {
  79. command = Serial.readStringUntil('#');
  80. char commandType = command.charAt(0);
  81. if (commandType == 's') {
  82. // Set Motor Speed (write pwm duty)
  83. String pwmDuty_ = command.substring(1);
  84. pwmDuty = pwmDuty_.toInt();
  85. setMotorSpeed();
  86. //Serial.print("The Motor PWM Duty Cycle is set to ");
  87. Serial.println(pwmDuty);
  88. }
  89. else if (commandType == 'c') {
  90. String motorDirection = command;
  91. if (motorDirection == "cw") {
  92. setMotorDirectionCW();
  93. Serial.print("Motor Direction is set to Clock-Wise \n");
  94. }
  95. else if (motorDirection == "ccw") {
  96. setMotorDirectionCCW();
  97. Serial.print("Motor Direction is set to Counter-Clock-Wise \n");
  98. }
  99. }
  100. else if (commandType == 'm') {
  101. // Measure motor speed and report
  102. int currentSpeed = measureRPM();
  103. //Serial.print("Current Speed of the motor is ");
  104. Serial.println(currentSpeed);
  105. }
  106. else {
  107. Serial.print("Unknown Command Received ");
  108. Serial.println(command);
  109. }
  110. }
  111. }