Project Description: I am working on an Arduino project to control a motorized door using limit switches and a remote control (433 MHz RF). The motor should open and close the door, stopping when the respective limit switch is triggered.
Problem: When opening the door, the motor sometimes stops immediately without reaching the limit switch. This issue does not occur when closing the door; the motor stops correctly at the limit switch.
Current Setup:
- Arduino Uno
- Motor driver connected to pins 8, 9, and 10
- Limit switches connected to pins 2 and 3
- RF receiver connected to pin 7
- Remote control with RF codes
#include <RCSwitch.h>
// Pin definitions
const int motorIn1 = 8;
const int motorIn2 = 9;
const int motorPWM = 10;
const int openLimitSwitch = 2;
const int closeLimitSwitch = 3;
const int toggleButton = 4; // Pin for open/close button
const int rfReceiverPin = 7; // Pin for RF receiver
// Variables
int motorSpeed = 0; // Motor speed (0-255)
const int maxSpeed = 255; // Maximum motor speed
const int slowSpeed = 100; // Slow start and stop speed
const int accelerationDelay = 100; // Delay between speed increments (milliseconds)
bool doorOpening = false;
bool doorClosing = false;
bool doorOpen = false; // Track if the door is open
bool doorClosed = true; // Track if the door is closed
unsigned long debounceDelay = 50; // Debounce delay in milliseconds
unsigned long lastDebounceTimeButton = 0; // Last debounce time for toggle button
int lastButtonState = HIGH; // Last stable state of toggle button
RCSwitch mySwitch = RCSwitch();
// Remote control codes
const unsigned long openCloseCodeA = 2046641; // Actual remote control code for button A
const unsigned long openCloseCodeB = 2046642; // Actual remote control code for button B
void setup() {
// Set pin modes
pinMode(motorIn1, OUTPUT);
pinMode(motorIn2, OUTPUT);
pinMode(motorPWM, OUTPUT);
pinMode(openLimitSwitch, INPUT_PULLUP);
pinMode(closeLimitSwitch, INPUT_PULLUP);
pinMode(toggleButton, INPUT_PULLUP); // Use internal pull-up resistor
// Initialize RF receiver
mySwitch.enableReceive(digitalPinToInterrupt(rfReceiverPin)); // Receiver on interrupt 0 => that is pin #2
// Initialize serial communication for debugging
Serial.begin(9600);
Serial.println("Setup complete. Waiting for commands...");
}
void loop() {
int currentButtonState = digitalRead(toggleButton);
// Debounce toggle button
if (currentButtonState != lastButtonState) {
lastDebounceTimeButton = millis();
}
if ((millis() - lastDebounceTimeButton) > debounceDelay) {
if (currentButtonState == LOW) {
handleToggleButton();
}
}
lastButtonState = currentButtonState;
// Check for RF remote signals
if (mySwitch.available()) {
unsigned long rfValue = mySwitch.getReceivedValue();
Serial.print("Received RF Code: ");
Serial.println(rfValue);
handleRFRemote(rfValue);
mySwitch.resetAvailable();
}
// Check limit switches only when motor is moving
if (doorOpening && digitalRead(openLimitSwitch) == LOW) {
stopMotor();
doorOpen = true;
doorClosed = false;
doorOpening = false;
Serial.println("Door is fully open");
}
if (doorClosing && digitalRead(closeLimitSwitch) == LOW) {
stopMotor();
doorClosed = true;
doorOpen = false;
doorClosing = false;
Serial.println("Door is fully closed");
}
}
void handleToggleButton() {
if (doorClosed && !doorOpening) {
// If the door is closed and not already opening, open the door
doorOpening = true;
doorClosing = false;
openDoor();
} else if (doorOpen && !doorClosing) {
// If the door is open and not already closing, close the door
doorClosing = true;
doorOpening = false;
closeDoor();
}
}
void handleRFRemote(unsigned long rfValue) {
// Check if the received RF code matches the open/close codes
if (rfValue == openCloseCodeA || rfValue == openCloseCodeB) {
Serial.println("RF Code matches open/close command");
handleToggleButton();
} else {
Serial.println("RF Code does not match");
}
}
void openDoor() {
Serial.println("Opening door");
doorOpening = true;
doorClosing = false;
// Slow start
for (motorSpeed = 0; motorSpeed <= slowSpeed; motorSpeed += 5) {
analogWrite(motorPWM, motorSpeed);
digitalWrite(motorIn1, HIGH);
digitalWrite(motorIn2, LOW);
delay(accelerationDelay); // Adjust this delay to control acceleration speed
}
// Max speed
analogWrite(motorPWM, maxSpeed);
while (doorOpening) {
// Keep running the motor until the limit switch is triggered
analogWrite(motorPWM, maxSpeed);
digitalWrite(motorIn1, HIGH);
digitalWrite(motorIn2, LOW);
if (digitalRead(openLimitSwitch) == LOW) {
stopMotor();
doorOpening = false;
doorOpen = true;
doorClosed = false;
Serial.println("Door is fully open");
break; // Exit the loop
}
delay(10); // Check limit switch periodically to avoid endless loop
}
}
void closeDoor() {
Serial.println("Closing door");
doorClosing = true;
doorOpening = false;
// Slow start
for (motorSpeed = 0; motorSpeed <= slowSpeed; motorSpeed += 5) {
analogWrite(motorPWM, motorSpeed);
digitalWrite(motorIn1, LOW);
digitalWrite(motorIn2, HIGH);
delay(accelerationDelay); // Adjust this delay to control acceleration speed
}
// Max speed
analogWrite(motorPWM, maxSpeed);
while (doorClosing) {
// Keep running the motor until the limit switch is triggered
analogWrite(motorPWM, maxSpeed);
digitalWrite(motorIn1, LOW);
digitalWrite(motorIn2, HIGH);
if (digitalRead(closeLimitSwitch) == LOW) {
stopMotor();
doorClosing = false;
doorClosed = true;
doorOpen = false;
Serial.println("Door is fully closed");
break; // Exit the loop
}
delay(10); // Check limit switch periodically to avoid endless loop
}
}
void stopMotor() {
analogWrite(motorPWM, 0);
digitalWrite(motorIn1, LOW);
digitalWrite(motorIn2, LOW);
doorClosing = false;
doorOpening = false;
Serial.println("Motor stopped");
}
Debug Output:
- When opening the door, the motor sometimes stops immediately without reaching the limit switch.
Questions:
- What could be causing the motor to stop prematurely when opening the door?
- Is there an issue with the debouncing logic or the motor control logic?
- Are there any suggestions for improving the motor control logic or ensuring the limit switches work correctly?
Thank you for your help!