PLS HELP: Controlling DC motor using buttons and measure speed using IR encoder speed measurement sensor


Hi, I'm currently doing a project of :Rotation Speed Control for Ceramic Clay Spinning Wheel.In this project, I need to measure and set the appropriate spinning speed.

Currently, I used two buttons which is increase speed in clockwise and anticlockwise. The speed will increase 234rpm each for set device when I pushed the button clockwise once and keep increasing.

However, I use a IR enconder speed motion sensor to measure the speed of dc motor. Display the set speed and measure speed on LCD screen.The value of set speed should same with the measure speed, but it does not. How can I make the set speed same with the measure speed and display in lcd and serial monitor in Arduino.

#include <LiquidCrystal.h>

const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

const int dir1Pin = 10;
const int dir2Pin = 9;

const int butPin1 = 7;
const int butPin2 = 8;
const int sensorPin = 6; // IR sensor connected to pin 6

int countA = 0;
int countB = 0;

bool aFlag = false;
bool bFlag = false;

int mapVal = 0;
const int fromLow = 0;
const int fromHigh = 255;
const int toLow = 0;
const int toHigh = 16530;

volatile unsigned long pulseCount = 0;
unsigned long lastTime = 0;
float rpm = 0;

void setup() {
  pinMode(dir1Pin, OUTPUT);
  pinMode(dir2Pin, OUTPUT);
  pinMode(butPin1, INPUT_PULLUP);
  pinMode(butPin2, INPUT_PULLUP);
  pinMode(sensorPin, INPUT_PULLUP);

  lcd.begin(16, 2);
  lcd.print("DC Motor RPM +/-");

  Serial.begin(9600);
  attachInterrupt(digitalPinToInterrupt(sensorPin), countPulse, RISING);
}

void loop() {
  if (countA == 0 && countB == 0) {
    aFlag = false;
    bFlag = false;
  }

  // Check for user inputs to set speed
  while (aFlag == false && bFlag == false) {
    digitalWrite(dir1Pin, LOW);
    digitalWrite(dir2Pin, LOW);
    if (digitalRead(butPin1) == 0) {
      aFlag = true;
      countA += 5;
      analogWrite(dir1Pin, countA);
      mapVal = map(countA, fromLow, fromHigh, toLow, toHigh);
      lcd.setCursor(0, 0); // First row, first column
      lcd.print("Set Speed: ");
      lcd.print(mapVal);
      lcd.print("   "); // Clear trailing characters
      while (digitalRead(butPin1) == 0) {} // Debounce
    }
    if (digitalRead(butPin2) == 0) {
      bFlag = true;
      countB += 5;
      if (countB > 255) countB = 255; // Limit max speed
      analogWrite(dir2Pin, countB);
      mapVal = map(countB, fromLow, fromHigh, toLow, toHigh);
      lcd.setCursor(0, 0); // First row, first column
      lcd.print("Set Speed: ");
      lcd.print(-mapVal); // Negative for reverse
      lcd.print("   "); // Clear trailing characters
      while (digitalRead(butPin2) == 0) {} // Debounce
    }
  }

  // Adjust speed in forward (dir1) mode
  if (aFlag == true) {
    while (digitalRead(butPin1) == 1 && digitalRead(butPin2) == 1) {}
    if (digitalRead(butPin1) == 0) {
      countA += 5;
      if (countA > 255) { countA = 255; }
      analogWrite(dir1Pin, countA);
      mapVal = map(countA, fromLow, fromHigh, toLow, toHigh);
      lcd.setCursor(0, 0); // First row, first column
      lcd.print("Set Speed: ");
      lcd.print(mapVal);
      lcd.print("   "); // Clear trailing characters
      while (digitalRead(butPin1) == 0) {}
    }
    if (digitalRead(butPin2) == 0) {
      countA -= 5;
      analogWrite(dir1Pin, countA);
      mapVal = map(countA, fromLow, fromHigh, toLow, toHigh);
      lcd.setCursor(0, 0); // First row, first column
      lcd.print("Set Speed: ");
      lcd.print(mapVal);
      lcd.print("   "); // Clear trailing characters
      while (digitalRead(butPin2) == 0) {}
      if (countA == 0) aFlag = false;
    }
  }

  // Adjust speed in reverse (dir2) mode
  if (bFlag == true) {
    while (digitalRead(butPin1) == 1 && digitalRead(butPin2) == 1) {}
    if (digitalRead(butPin2) == 0) {
      countB += 5;
      if (countB > 255) { countB = 255; }
      analogWrite(dir2Pin, countB);
      mapVal = map(countB, fromLow, fromHigh, toLow, toHigh);
      lcd.setCursor(0, 0); // First row, first column
      lcd.print("Set Speed: ");
      lcd.print(-mapVal); // Negative for reverse
      lcd.print("   "); // Clear trailing characters
      while (digitalRead(butPin2) == 0) {}
    }
    if (digitalRead(butPin1) == 0) {
      countB -= 5;
      analogWrite(dir2Pin, countB);
      mapVal = map(countB, fromLow, fromHigh, toLow, toHigh);
      lcd.setCursor(0, 0); // First row, first column
      lcd.print("Set Speed: ");
      lcd.print(-mapVal);
      lcd.print("   "); // Clear trailing characters
      while (digitalRead(butPin1) == 0) {}
      if (countB == 0) bFlag = false;
    }
  }

  // Calculate and display measured speed (RPM)
  unsigned long currentTime = millis();
  if (currentTime - lastTime >= 1000) { // Update every second
    rpm = (pulseCount / 20.0) * 60.0; // Assuming 20 pulses per revolution
    pulseCount = 0;
    lastTime = currentTime;
    lcd.setCursor(0, 1); // Second row, first column
    lcd.print("Meas Speed: ");
    lcd.print(rpm);
    lcd.print("   "); // Clear trailing characters
    Serial.print("RPM: ");
    Serial.println(rpm);
  }
}

void countPulse() {
  pulseCount++;
}

Lose the. 9v battery, add the driver and motor to your drawing.

Split the program up…
Solve your motor control first, and only then look into speed measurement.

Hm, but it does what?

Is the motor already turning in the intended direction?

From my point of view the regulation is completly missing. Something at minimum PI, better PID should be implented for the described application.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.