Trying to create an automatic swing door opener using UDS and a servo motor

Hi all! this is my first project and it's for school. Our project is to create an automatic swing door opener using an ultrasonic distance sensor and a servo motor. It's a life-sized prototype so the door we built is really lightweight.

how we want it to work is that once the UDS detects an object within 50cm or so, it will trigger the servo to rotate. It will wait 5 seconds then check if the object is still there. If it is, it will stay open. If it isn't it will return the servo to initial position then repeat the whole thing again.

The challenge with this project is to be able to make the device portable, meaning it can be transferred from one swing door to another while still being fully functional.

it works similarly to this video Servo motor to open trap door - YouTube but with the use of a distance sensor

Our problem right now is coding... no matter what we do, the servo will not stop rotating continuously. We think we may have bought a continuous servo without knowing, but it may just be from the code.

We're on a tight budget and schedule so any sort of input to this would be very much appreciated thank you!

#include <Servo.h>

// define pins for ultrasonic sensor
const int trigPin = 10;
const int echoPin = 11;

// define pin for servo
const int servoPin = 9;

// define variables for distance measurement
long duration;
int distance;

// create a servo object
Servo myServo;

void setup() {
  // initialize serial communication
  Serial.begin(9600);

  // define the pin modes
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(servoPin, OUTPUT);

  // attach the servo to the corresponding pin
  myServo.attach(servoPin);
}

void loop() {
  // generate a pulse to trigger the ultrasonic sensor
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // measure the duration of the pulse from the ultrasonic sensor
  duration = pulseIn(echoPin, HIGH);

  // calculate the distance in centimeters
  distance = duration * 0.034 / 2;

  // print the distance to the serial monitor
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // check if an object is detected within 50 centimeters
  if (distance < 50) {
    // rotate the servo to 90 degrees
    myServo.write(180);
    Serial.println("OPEN");

    // wait for 5 seconds
    delay(5000);

    // measure the distance again
    duration = pulseIn(echoPin, HIGH);
    distance = duration * 0.034 / 2;

    // check if the object is still there
    if (distance < 50) {
      // keep the servo at 180 degrees
      myServo.write(180);
      Serial.println("OPEN");
    } else {
      // return the servo to the initial position
      myServo.write(0);
      Serial.println("CLOSED");
    }
  } else {
    // return the servo to the initial position
    myServo.write(0);
    Serial.println("CLOSED");
  }

  // wait for some time before measuring the distance again
  delay(500);
}

myServo.write(0);

We've tried that also but nothing seemed to change..

If it rotates continuously (360 degrees) then it is indeed a continuously rotating servo and won't work in your application.

So you need to buy a regular servo

Yea we thought so as well but tried to keep a positive mind.. Is there a specific model name? and would the code be able to work in that case? thanks!

WOKWI simulator to the rescue

1 Like

Well, now it's a matter of mechanics rather that electronics or program code.
How much torque do you need to open a life-sized door with the lever system shown in the video?
Once you figure that out then look for a servo that can deliver at least that much torque.
That's all the advice I can give.

I modified the code and ran it through WOKWI simulator (thank you!) and it works how we want it to! Our only problem now is the servo we bought :frowning: The door that we have is pretty lightweight that it can be opened by wind. Is there any normal servo that could do the trick?

No one would complain if you were to use the Share button in wokwi and post a link to your simulation here.

That's a hint. :wink:

Please post next on this thread the new code also. That will give the best chance of further scrutiny and assistance.

a7

I modified this post with the new code :slight_smile: as for the link for wokwi, i'm not quite sure how as it was my first time using it :sweat_smile:

First, please don't go back and modify code that eveyone's been talking about. It makes trash of the conversation and takes our remarks out a context where they make sense.

New code, new contribution to this thread in the next post you make here on this thread.

So like do not start a new thread, just post the new code.

I said but should have been clear: in the wokwi, look around a bit, there is a giant "share" button, which would allow you to copy the URL and paste it here.

Which, BTW, you might have just done by grabbing the URL your browser no doubt shows when you are on the wokwi page simulating your heart away.

HTH and I am looking forward to playing with your door device.

a7

1 Like

Apologies, I am new to this forum. I figured it would be alright to edit the original post since the code wasn't discussed anyway. Here is the new code!

#include <Servo.h>

// define pins for ultrasonic sensor
const int trigPin = 10;
const int echoPin = 11;

// define pin for servo
const int servoPin = 9;

// define variables for distance measurement
long duration;
int distance;

// create a servo object
Servo myServo;

void setup() {
  // initialize serial communication
  Serial.begin(9600);

  // define the pin modes
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(servoPin, OUTPUT);

  // attach the servo to the corresponding pin
  myServo.attach(servoPin);
}

void loop() {
  // generate a pulse to trigger the ultrasonic sensor
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // measure the duration of the pulse from the ultrasonic sensor
  duration = pulseIn(echoPin, HIGH);

  // calculate the distance in centimeters
  distance = duration * 0.034 / 2;

  // print the distance to the serial monitor
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");

  // check if an object is detected within 50 centimeters
  if (distance < 50) {
    // rotate the servo to 90 degrees
    myServo.write(180);
    Serial.println("OPEN");

    // wait for 5 seconds
    delay(5000);

    // measure the distance again
    duration = pulseIn(echoPin, HIGH);
    distance = duration * 0.034 / 2;

    // check if the object is still there
    if (distance < 50) {
      // keep the servo at 180 degrees
      myServo.write(180);
      Serial.println("OPEN");
    } else {
      // return the servo to the initial position
      myServo.write(0);
      Serial.println("CLOSED");
    }
  } else {
    // return the servo to the initial position
    myServo.write(0);
    Serial.println("CLOSED");
  }

  // wait for some time before measuring the distance again
  delay(500);
}

Here is the link to wokwi as well :slight_smile: Automatic Swing Door Opener UDS & Servo Motor Copy - Wokwi Arduino and ESP32 Simulator

Hello [parliamo

Wrt to the IPO model check this pseudo code:

INPUT: 
If (timer==fired) {restartTimer(); distance=readUDS();}

PROCESSING: 
distance>=triggerDistance?angle=Open:angle=Close;

OUTPUT:
servoWrite(angle);

Each function can be coded and tested separately before integration.

Have a nice day and enjoy coding in C++.

1 Like

Even though you have a continuously rotating servo is it strong enough to open and close the door?

Thank you for this, Paul! It's much appreciated, and yes this is how the device should function. We opted to only include the 5 second interval when the door is open so that it stays in that position to allow people to enter with enough time. We didn't include it when the door is closed because then people would have to wait 5 seconds before it would open.

We aren't at all proficient at coding at the moment, so apologies if the code ever seems messy haha

Yes, it's more than enough actually. The servo that we have at the moment is a DF15RSMG 360 Degree Motor 20kg Servo. I read something just earlier that "360 degree" is often a codename for continuous servos. We should have read more on servos before purchasing...

My group mate stated that the door that we have is for sure not heavier than 8kg

Well, you have two choices as to what to do next.

You can buy a normal 180 degree 20kg servo OR use the continuous servo with limit switches.
You would need to put the limit switches somewhere that would operate when the door is open and closed. The code will read the limit switches and stop the servo when the door is fully open or closed.

It's going to make you mechanical set-up more complicated but if you don't want to buy another servo it your only option. The code will also be different.

1 Like

Yes. It would also allow doing the opening and closing at a specified speed… in the current code, when the servo is told to go to a new angle, it will do that as fast as it can.

@parliamo See

for how a "180 degree" servo must be handled to slow it down.

Which you may want to consider doing in your sketch.

If you do use the "360 degree" servo (file that under you learn something every day!), the speed becomes very simple to adjust, as the speed is set by the servo signal and corresponds to how far off from 90 (stopped) you tell it, 100 (slow CCW), 10 (fast CW).

But you have to add physical switches and arrange them mechanically and code for limit switch logic.

So tradeoffs. The life blood of engineering.

a7

We plan to keep the device as simple as possible, so I think buying a standard servo is our best option right now with the time that we have remaining for this project, especially with our lack of coding and wiring knowledge about limit switches.

I had just checked the shops in our area that sell servos, and I found something called Servo DF Metal Geared 15Kg Standard 270° (DSS-M15S). Any chance this is a standard servo and not a continuous one?

Check the datasheet.