MacGyver
New Coder
I have this code for an automatic dog door. I am having an issue that I would like your input on. When I put the program on my NODEMCU board, the dog door is as quiet as can be. When I hit the user switch (to open the door) the door comes up, stops, pauses for the 3 sec duration and then brakes when it falls back to close. The 12% keeps the door from slamming and keeps the slack out of the cable from the motor to the door. When the door is closed, the motor should be off (disconnected). However, I hear the motor hum, so I pull on the cable and there was tension on the cable. I used my o-scope and can see that there is still a 4k oscillation with about a 4% duty cycle. So the board isn't truly going to 0% so it seems. I tried using a Wemos D1 mini, and an Arduino UNO (had to change the PWM there) and they all gave me the same results where the motor can't be at rest. What am I missing here? I am not a professional programmer, I just tinker so I am at a loss here. I know it's like a states machine which I am very familiar with from teaching Engineering in high school but it was using stepper motors which react differently and not a good choice for this application.
One last thing. I used an Opto Isolator from the D1 output to the opto then from there to the motor driver. I put the input to the opto on D6 and the other side to ground. I tried to toggle this to cut it completely off but I couldn't get the stupid thing to send a digitalWrite(OPTO, LOW); It only stayed high no matter how I tried to get it to change.
Thanks for all your help!!!! I do appreciate it....
One last thing. I used an Opto Isolator from the D1 output to the opto then from there to the motor driver. I put the input to the opto on D6 and the other side to ground. I tried to toggle this to cut it completely off but I couldn't get the stupid thing to send a digitalWrite(OPTO, LOW); It only stayed high no matter how I tried to get it to change.
Thanks for all your help!!!! I do appreciate it....
Code:
// Pin Definitions
const int MOTOR_PIN = D1; // PWM output to motor driver
const int USER_SWITCH = D2; // Momentary switch input
const int SWITCH_START = D3; // Door starting position switch
const int SWITCH_MID = D4; // Door halfway position switch
const int SWITCH_END = D5; // Door fully open position switch
const int LED_PIN = LED_BUILTIN; // Status LED
// Constants
const int PWM_FREQ = 4000; // PWM frequency in Hz
const float HOLD_DUTY = 18.0; // Holding duty cycle
const float BRAKE_DUTY = 12.0; // Braking duty cycle
const float SLOW_DUTY = 40.0; // Slower duty cycle for top approach
const float START_DUTY = 85.0; // Initial opening duty cycle
const int HOLD_TIME = 3000; // Hold time in milliseconds
// Door states
enum DoorState {
CLOSED,
OPENING,
OPEN_HOLD,
CLOSING
};
// Global variables
DoorState currentState = CLOSED;
unsigned long lastStateChange = 0;
float currentDuty = 0;
void setup() {
// Configure pins
pinMode(MOTOR_PIN, OUTPUT);
pinMode(USER_SWITCH, INPUT_PULLUP);
pinMode(SWITCH_START, INPUT_PULLUP);
pinMode(SWITCH_MID, INPUT_PULLUP);
pinMode(SWITCH_END, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
// Set PWM frequency
analogWriteFreq(PWM_FREQ);
// Initialize motor off
digitalWrite(MOTOR_PIN, LOW);
// Initialize serial for debugging
Serial.begin(115200);
Serial.println("\nDoor Control System");
Serial.println("==================");
}
void setMotorDuty(float dutyPercent) {
int pwmValue = (dutyPercent / 100.0) * 1023;
pwmValue = constrain(pwmValue, 0, 1023);
if (dutyPercent == 0) {
digitalWrite(MOTOR_PIN, LOW); // Complete shutoff
} else {
analogWrite(MOTOR_PIN, pwmValue);
}
currentDuty = dutyPercent;
Serial.print("Duty Cycle: ");
Serial.print(dutyPercent, 1);
Serial.println("%");
}
void updateDoorState() {
bool userButton = !digitalRead(USER_SWITCH); // D2
bool atStart = !digitalRead(SWITCH_START); // D3
bool atMid = !digitalRead(SWITCH_MID); // D4
bool atEnd = !digitalRead(SWITCH_END); // D5
unsigned long currentTime = millis();
switch (currentState) {
case CLOSED:
if (userButton) {
currentState = OPENING;
lastStateChange = currentTime;
setMotorDuty(START_DUTY); // Start at 85%
Serial.println("State: OPENING");
}
break;
case OPENING:
if (atMid && currentDuty > SLOW_DUTY) {
setMotorDuty(SLOW_DUTY);
Serial.println("Slowing for approach");
}
if (atEnd) {
currentState = OPEN_HOLD;
lastStateChange = currentTime;
setMotorDuty(HOLD_DUTY);
Serial.println("State: HOLDING");
}
break;
case OPEN_HOLD:
if (!userButton && (currentTime - lastStateChange >= HOLD_TIME)) {
currentState = CLOSING;
setMotorDuty(BRAKE_DUTY);
Serial.println("State: CLOSING");
}
break;
case CLOSING:
if (userButton) {
currentState = OPENING;
lastStateChange = currentTime;
setMotorDuty(START_DUTY);
Serial.println("State: REOPENING");
}
else if (atStart) {
currentState = CLOSED;
setMotorDuty(0);
Serial.println("State: CLOSED");
}
break;
}
digitalWrite(LED_PIN, currentState != CLOSED);
}
void loop() {
updateDoorState();
delay(10);
}