Hi guys, please bear with me 'coz I'm so in newbie in this kind of world. So, I have implemented forward and reverse functionalities in my motor control system, where the direction of rotation is controlled by the PWM duty cycle. However, I am experiencing a peculiar problem where the RPM values seem to be behaving in an unexpected manner.
Specifically, when I adjust the PWM duty cycle to a higher value, I notice that the RPM drops to a lower value, and conversely, when I adjust it to a lower value, the RPM increases. This behavior is contrary to what I would expect, as higher PWM duty cycles should typically result in higher motor speeds and consequently higher RPM readings.
I am unsure whether this issue stems from a problem in the accurate simulation on proteus, or the code logic or if there might be an issue with the pins or connections in my setup. Please help me
example pics when simulating forward direction
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
#define potentiometer A0 // 10k Variable Resistor
#define buttonForward A1 // Forward Button
#define buttonStop A2 // Stop Button
#define buttonReverse A3 // Reverse Button
#define greenLEDPin A4 // Green LED pin
#define redLEDPin A5 // Red LED pin
#define blueLEDPin 0 // Blue LED pin
#define M1_Ena 11 // Enable1 L298 for PWM
#define M1_in1 10 // In1 L298 for Clockwise
#define M1_in2 9 // In2 L298 for Anticlockwise
const int motorSpeedPin = 4; // PWM pin for motor speed control (L293D Enable)
int motorSpeed = 0; // Variable to store motor speed
int read_ADC = 0;
int duty_cycle;
int duty_cycle_lcd;
int set = 0; // Variable to store motor direction (0: Stop, 1: Forward, 2: Reverse)
const int maxRPM = 400; // Maximum RPM of the motor
const int pulsesPerRevolution = 24; // Number of pulses per revolution of the motor encoder
unsigned long lastMillis = 0;
volatile unsigned long pulseCount = 0;
float rpm = 0;
const int TimeInterval = 1000; // Time interval in milliseconds for RPM calculation
void setup() {
Serial.begin(9600);
pinMode(potentiometer, INPUT);
pinMode(buttonForward, INPUT_PULLUP);
pinMode(buttonStop, INPUT_PULLUP);
pinMode(buttonReverse, INPUT_PULLUP);
// Motor control pins as outputs
pinMode(M1_Ena, OUTPUT);
pinMode(M1_in1, OUTPUT);
pinMode(M1_in2, OUTPUT);
lcd.begin(20, 4);
lcd.print("Motor Speed:"); // Display text on LCD
pinMode(motorSpeedPin, OUTPUT); // Set PWM pin as output
attachInterrupt(digitalPinToInterrupt(3), countPulses, RISING);
}
void loop() {
// Read potentiometer value and map it to motor speed (0-255)
read_ADC = analogRead(potentiometer);
duty_cycle = map(read_ADC, 0, 1023, 0, 255);
duty_cycle_lcd = map(read_ADC, 0, 1023, 0, 100);
motorSpeed = map(read_ADC, 0, 1023, 0, 255);
// Control motor speed using PWM
analogWrite(M1_Ena, duty_cycle);
analogWrite(motorSpeedPin, motorSpeed); // Control motor speed using PWM
// Update LCD with duty cycle
lcd.setCursor(0, 0);
lcd.print("Duty Cycle: ");
lcd.print(duty_cycle_lcd);
lcd.print("% ");
// Check button inputs for motor direction control
if (digitalRead(buttonForward) == LOW) {
setDirection(1); // Forward
} else if (digitalRead(buttonStop) == LOW) {
setDirection(0); // Stop
} else if (digitalRead(buttonReverse) == LOW) {
setDirection(2); // Reverse
}
// Display motor direction and speed on LCD
displayDirection();
lcd.setCursor(0, 2);
lcd.print("Speed:");
lcd.print(motorSpeed);
// Calculate RPM every specified time interval
calculateRPM();
delay(50); // Delay for stability
}
void setDirection(int direction) {
set = direction;
switch (set) {
case 0: // Stop
analogWrite(M1_Ena, 0); // Turn off motor
break;
case 1: // Forward
digitalWrite(M1_in1, HIGH); // Set motor direction to clockwise
digitalWrite(M1_in2, LOW);
break;
case 2: // Reverse
digitalWrite(M1_in1, LOW); // Set motor direction to anticlockwise
digitalWrite(M1_in2, HIGH);
break;
}
}
void displayDirection() {
lcd.setCursor(0, 1);
lcd.print("Direction:");
switch (set) {
case 0:
lcd.print("Stop ");
digitalWrite(greenLEDPin, LOW); // Turn off green LED
digitalWrite(redLEDPin, HIGH); // Turn on red LED
digitalWrite(blueLEDPin, LOW); // Turn off blue LED
break;
case 1:
lcd.print("Forward ");
digitalWrite(greenLEDPin, HIGH); // Turn on green LED
digitalWrite(redLEDPin, LOW); // Turn off red LED
digitalWrite(blueLEDPin, LOW); // Turn off blue LED
break;
case 2:
lcd.print("Reverse ");
digitalWrite(greenLEDPin, LOW); // Turn off green LED
digitalWrite(redLEDPin, LOW); // Turn off red LED
digitalWrite(blueLEDPin, HIGH); // Turn on blue LED
break;
}
}
void calculateRPM() {
unsigned long currentMillis = millis();
if (currentMillis - lastMillis >= TimeInterval) {
rpm = (pulseCount * 60.0 * 1000.0) / (pulsesPerRevolution * TimeInterval); // Calculate RPM
pulseCount = 0;
lastMillis = currentMillis;
lcd.setCursor(0, 3);
lcd.print("RPM: ");
lcd.print(rpm);
}
}
void countPulses() {
pulseCount++; // Increment pulse count for RPM calculation
}