Project in progress

Touchless Door Opener © CC BY-NC-SA

Touchless door handle mechanism that can be used in every door just replacing the standard handle. Very useful for people with disabilities.

  • 3,090 views
  • 5 comments
  • 27 respects

Components and supplies

door handle
3d printed
×2
Stepper motor obl 600  73570.1448057593.500.659
Digilent Stepper Motor
One for each side
×2
Sharp microelectronics gp2y0a41sk0f image
Proximity Sensor
One for each side
×2
gears
3d printed
×2
door plate
3d printed
×2
Ard nano
Arduino Nano R3
or Arduino MKR wifi for smart functions
×1
09590 01
LED (generic)
Shows the status of the door, one for each side of the door
×2
batterie 18650
×4
wireless charger
×1
wheel
can be 3d printed
×1
housing cyber door truck
3d printed
×1
DC motor (generic)
×1
09670 01
SparkFun Dual H-Bridge motor drivers L298
×1
Boostxl uln2003 boostxl angle2
Texas Instruments BOOSTXL-ULN2003 ULN2003A Dual Stepper Motor BoosterPack
×2

Necessary tools and machines

prusa mk3

Apps and online services

About this project

Coronavirus spreads through surfaces that are frequently touched like door handles - we need a solution especially for hospitals and public buildings, an automatic door opener can help to decrease the risk to be infected and is also useful for people with special needs and disabilities.

There will be two versions of the door handle, an automatic and manual one

Video with the project explanation



At first we thought it would be easier:

video with the first idea

First prototypes:

First Test with the kinematic usinga 12v motor just to improve the movement.

First tests with Arduino

The stepper 28BYJ-48 seems to be too weak for this application, I am considering to use two steppers or maybe one with more torque. First I will improve the mechanism to lower the required torque and if this still not works I will change the concept to a double stepper solution driving the handle trough the opposite side of the door too.

After some tests I have changed the ratio of the bevel gears to 3:1 and used spiral teeth but the mechanism requires too much torque for this little motor. So I have included a new stepper on the opposite side and this option works quite good!

An important target is achieved because using the two 28BYJ-48 steppers, this automatic door handle can be very affordable.

Improving the door handle

The movement of the steppers are the same just in opposite direction, it means that I can use the same pins on Arduino for the both motors. This is very important because we can save 4 pins on the board for further applications.

FIRST PROTOTYPE:

The first prototype uses PIR sensors to detect the movement and trigger the handle.

I‘ve added brackets to hold the arduino board and the motor drivers. The handle is integrated on the pinion, reducing the number of parts.

SECOND PROTOTYPE:

I am replacing the PIR sensors with ultrasonic ones because then is possible to detect not only the objects but their related distance too. If we have the distance we can avoid false openings just setting the right distance to start the movement of the handles.

The following changes have been done:

1- Substitution of PIR sensors for ultrasonic sensors:

to trigger the movement with a signal in function of the object distance

2-Arduino board transferred to the Cyber Door Mover:

To save space and complexity on the Handles

3- Stepper driver transferred to the middle of the door plate.

This reduces the length of the cable wires and allows the door plate to be

symmetric.

4- Door plate is now the same for the pull and the push door side:

We can use the same design of the plate for both sides, this reduce

the complexity of the whole system.

5. Cable management:

The cables (or at least most of them) are moved to the back side of the door

plate.

THIRD PROTOTYPE:

new concept simplified and with a tiny handle for manual opening

All the cables sensors, steppers and drivers are inside of the black cover. There’s a tiny release to open the door manually in case of failure.

So far so good but the door is still closed!

This system works properly but this is only a mechanism which activates the handle, but how to open the door automatically?

This could be solved with the Cyber Door Mover concept ;-)

The Cyber door mover open and close the door automatically and supplies electricity for the whole system. It has a wireless charger that can be placed next to the wall.

I have planned to use the well known 18650 batteries that can be recycled from old notebooks.

Door mover.

The first prototype will run with a 9V power supply. With the screw on the left it is possible to adjust the grip of the wheel to prevent it from slipping.

My first test shows that the motor is too weak and too fast for this application, now I know that the motor is doing around 5 revolutions to open the door completely, as the nominal speed of this affordable motor is dated to 240rpm, and I want to open the door in around 3 seconds, I can try to add some gears with a ratio of around 2.5:1 to increase the torque and reduce the speed to approximately 100rpm, hoping to have enough torque.

The fixing concept on the door works really good because I can adjust the hight of the mover with the included guides and fixed the position with just two screws. This will be helpful to adjust the grip of the wheel, considering the different types of floors including slippery tiles.

That’s all about my first prototype!

SECOND PROTOTYPE:

In order to add a gear reduction some other parts are needed like the bracket for the motor and a new wheel axis. The motor pivots around its fixing point and with one screw it is possible to adjust the grip of the wheel.

Now it's time to print!

I have set the gears to around 1:4 ratio and now the system is working.

I have still some problems because the wheel slips slightly but I’m very confident using the right rubber tyre (the one that I’m using is made of hard plastic) the mover will work properly.

THIRD PROTOTYPE:

Our intention was to use a little 5V motor but this was not powerful enough to move the door on different surfaces and in a reliable way. We have changed the motor to a 12V one with integrated gears. The drive unit has a suspension to adapt to the different conditions of the floor and to keep the grip as constant as possible.

Changes done:

-Integration of Arduino Nano

-New 12V Motor added (can work with 9V)

-3D Printed wheel and tyre in TPU

-New suspension for the drive unit.

Views of the current stand

IoT and further smart functions

Finally using an Arduino MKR instead of Arduino Nano we can introduce smart functions like remote control for hospitals or nursing homes.

Or just to name an example: by using the adequate sensor we can detect body temperatures locking the door for people with fever.

Note:

It was not possible to use the sponsored MKR due to malfunctions with IOS, or maybe the received MKR was damaged.

Things to do...

after 3 prototypes of each component we have a functional automatic door handle but there’s still a “few” things to do:

-Integration of an end switch to stop the door in closed position

-Integration of batteries and wireless charger

-new silent Motor

-Code updates

-IoT

-Alternative system to the Carrier

Code explanation

To manage the interactions of the touchless door, we used an state dependant program. That means that the programs acts different depending on the current state of the door. It features five states:

  • Closed(default)
  • Opening from the pull side
  • Opening from the push side
  • Fully opened
  • Closing

Then, to manage the inputs and outputs of the program we use the following functions:

For the ultrasonic sensors, we read their value at the start of the loop() function

distance1 = getDistance(TRIG1, ECO1);
distance2 = getDistance(TRIG2, ECO2);

The getDistance function is our standard ultrasonic sensor handler.

int getDistance(int TRIG, int ECO){
digitalWrite(TRIG, LOW);
delayMicroseconds(2);
digitalWrite(TRIG, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG, LOW);
int duration = pulseIn(ECO, HIGH);
return duration / 58.2;
}

Then we handle the DC motor(the one that moves the door) with the doorMotor() function. This is just a method to use the motor in both directions and stop it, using the l298n driver.

#define MOTOR_CLOSING -1
#define MOTOR_STOPPED 0
#define MOTOR_OPENING 1

int IN1 = 8;
int IN2 = 9;
int ENA = 10;

void doorMotor(int rotDirection){
if(rotDirection == MOTOR_CLOSING){
Serial.println ("Door motor closing...");
digitalWrite(ENA, HIGH);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
}else{
if(rotDirection == MOTOR_STOPPED){
Serial.println ("Door motor stopping...");
digitalWrite(ENA, LOW);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}else{
if(rotDirection == MOTOR_OPENING){
Serial.println ("Door motor opening...");
digitalWrite(ENA, HIGH);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
}
}
}
}

And last but not least we move the handle with an stepper motor. We control it with a lookup table. It controls the coils of the stepper which are activated in a certain order.

const int STEP1 = 4;
const int STEP2 = 5;
const int STEP3 = 6;
const int STEP4 = 7;

const int numSteps = 4;
const int stepsLookup[4] = {B1000, B0100, B0010, B0001};

As you can see by default we use the stepper with one-phase behaviour as we got the best results this way but it can be changed.

Then to advance the motor we use the opening() and closing() functions which are very similar.

void opening(){
stepCounter++;
if(stepCounter >= numSteps) stepCounter = 0;
setOutput(stepCounter);
}
void closing(){
stepCounter--;
if(stepCounter < 0) stepCounter = numSteps - 1;
setOutput(stepCounter);
}

We also included a demagnetize() function to turn off all coils.

void demagnetize(){
digitalWrite(STEP1, LOW);
digitalWrite(STEP2, LOW);
digitalWrite(STEP3, LOW);
digitalWrite(STEP4, LOW);
}

And finally the setOutput function translates these look-up table values to the coils that should be activated in the stepper.

void setOutput(int step){
digitalWrite(STEP1, bitRead(stepsLookup[step], 0));
digitalWrite(STEP2, bitRead(stepsLookup[step], 1));
digitalWrite(STEP3, bitRead(stepsLookup[step], 2));
digitalWrite(STEP4, bitRead(stepsLookup[step], 3));
}

Now that we know how to read the sensors and activate the motors we can start explaining the behaviour of the program.

To behave differently in each state, we use a switch clause in out loop() function, governed by an integer that represents the state of the program.

#define DOOR_CLOSED 0
#define DOOR_OPENING 1
#define DOOR_OPENING_OUTSIDE 4
#define DOOR_OPENED 2
#define DOOR_CLOSING 3

int doorState = DOOR_CLOSED;
void loop(){
switch(doorState){
case DOOR_CLOSED:
...
break;

...

case DOOR_OPENED:
...
break;
}
}

Now we will examine the behaviour of the program in each state.

Closed

When the door is closed we want the program to wait until the user places his hand on the ultrasonic sensor, so we compare the value read by the sensor with a constant that defines how close should the user place his hand

const int handDistance = 5;

We make sure that the distance is positive as the sensor can sometimes give erratic values. We will expand on this problem later. This is the code for detecting the user's hand in the sensor that is on the pull side.

case DOOR_CLOSED:
if(distance1 <= handDistance && distance1 > 0){

When we detect that the user has placed his hand on the sensor, we start turning the stepper motor, controlling the door's handle.

for(int i = 0; i < steps; i++){
opening();
delayMicroseconds(motorSpeed);
}

We can tweak the angle of rotation by modifying the variable steps.

When the handle is opened, we stop sending current to the stepper coils so the rest of the components can draw more power(this is specially important for the motor that opens the door)

demagnetize();

Then we can start the DC motor that opens the door and change the program's state to opening

doorState = DOOR_OPENING;
doorMotor(MOTOR_OPENING);
handInSensor = true;

We also set the variable handInSensor to True, for the reasons we will see in the next chapter.

Opening

When the door is opening, we don't have to do anything until it fully opens, when we should stop the DC motor. So we compare the value of the inside sensor with a constant that determines how close to the wall do we want the door to stop.

const int wallDistance = 20;
case DOOR_OPENING:
if(distance1 <= wallDistance && distance1 > 0 && !handInSensor){

As you can see we use the variable handInSensor in here. The reasoning is simple, if we didn't use it as soon as the door started opening it would detect the hand of the user still on the sensor as if it were the wall, and the motor would stop. So we first have to detect when the user takes away his hand to avoid this problem.

if(distance1 > wallDistance){
handInSensor = false;
}

So when the hand is taken away and the sensor detects proximity to an object, we stop the DC motor and set the state to fully opened.

doorMotor(MOTOR_STOPPED);
doorState = DOOR_OPENED;

Opening from the outside

You may have noticed that we have only explained how to open the door from the pull side. To open it from the push side we do basically the same, with the exception that we don't have to use that handInSensor variable, as the sensor that detected the hand and the sensor that will detect the wall are different.

case DOOR_CLOSED:
if(distance2 <= handDistance && distance2 > 0){
for(int i = 0; i < steps; i++){
opening();
delayMicroseconds(motorSpeed);
}
demagnetize();

doorState = DOOR_OPENING_OUTSIDE;
doorMotor(MOTOR_OPENING);
}
break;

Then, when it is opening;

case DOOR_OPENING_OUTSIDE:
if(distance1 <= wallDistance && distance1 > 0){
Serial.println("Wall");

doorMotor(MOTOR_STOPPED);
doorState = DOOR_OPENED;
}
break;

Opened

When the door has opened we need to wait some time to let the user pass through the door and then start to close it, so we use a delay with another constant, that represents the waiting time in milliseconds.

const int doorWaitTime = 2000;
case DOOR_OPENED:
delay(doorWaitTime);

doorMotor(MOTOR_CLOSING);
doorState = DOOR_CLOSING;
break;

Closing

So here comes the difficult part. In order to not introduce more components to the project, we decided to detect when the door is closed by reading the push side sensor value and detecting when it stays constant(indicating the door has stopped moving)

To do this, we tried to take samples of the readings of the sensor and calculating its variance. We do this at the start of the loop function, having declared the size of the sample and the variables we will use.

const int sampleSize = 3;
const float varThreshold = 1.5;

int sampleIndex = 0;
int sample[sampleSize];
float sampleVariance = 0;

So in each iteration of the loop() function we save the sensor's detected value in our sample.

sample[sampleIndex] = distance2;
sampleIndex++;

Then, when we have collected a full sample, we detect its variance

if(sampleIndex % sampleSize == 0){
sampleIndex = 0;

int mean = 0;
for(int i = 0; i < sampleSize; i++){
mean += sample[i];
}
mean /= sampleSize;

sampleVariance = 0;
for(int i = 0; i < sampleSize; i++){
sampleVariance += pow(sample[i] - mean, 2);
}
sampleVariance /= sampleSize;
}

So finally we determine the door has stopped if the variance of the last sample is less than the constant varThreshold we defined earlier. In out switch statement,

case DOOR_CLOSING:   
if(sampleVariance < varThreshold){
doorState = DOOR_CLOSED;
doorMotor(MOTOR_STOPPED);

for(int i = 0; i < steps; i++){
closing();
delayMicroseconds(motorSpeed);
}
demagnetize();
}
break;

As you can see we first make sure the door is closed and then we return the handle to the original position. This is because our DC motor doesn't have enought torque to close the door with the handle closed. If you are using a more powerful motor, you can close the handle when the door is on the opened position.

If the sensor gave accurate values we would have finished, but this is not the case. When the sensor is a long distance from an object it gives erratic values. We noticed they tend to be the correct value but sometimes drop a large amount. This in turn creates a large variance even when the door is stationary, making this code useless.

To solve this problem, we take a sub-sample of the sensor values and take the biggest value of the sample as the real sensor reading. We do this in a similar way to the previous sampling. First we define our variables:

const int subSampleSize = 5;

int subSampleIndex = 0;
float subSampleMax = 0;

And then at the start of the loop() function we compute this sub-sample maximum,

if(distance2 > subSampleMax){
subSampleMax = distance2;
}
subSampleIndex++;

When the sub-sample is finished, we feed its value to the original sample, as it if were the sensor reading, and reset the variables to take a new sub-sample.

if(subSampleIndex % subSampleSize == 0){
sample[sampleIndex] = subSampleMax;
sampleIndex++;

subSampleMax = 0;
subSampleIndex = 0;
}

Then we change a bit the big sample code so it only computes the variance one time.

if(sampleIndex % sampleSize == 0 && subSampleIndex % subSampleSize == 0){
...
}

Here we can see the effect of the sub-sample, how it filters out these spikes and the general noise. Blue is the raw sensor data, red is the subSampleMax value.

And below the green value is the variance. You can see in the graph that the value is pretty high when the door is closing as the sensor values move a lot but when it is closed it drops to almost zero as the sensor values are mostly constant.

By adjusting the sample and sub-sample sizes we tried to find a compromise between having small samples which means more noise and in turn less precision(stopping before closing completely for example) and big samples which means slower detection, so the DC motor keeps running a bit with the door is already closed.

Code

New Code Arduino
Happy to welcome my nephew Óscar to this project. He studies Mathematics at the university of Madrid, and will support me on this and hopefully also on future projects.
#define DOOR_CLOSED 0
#define DOOR_OPENING 1
#define DOOR_OPENING_OUTSIDE 4
#define DOOR_OPENED 2
#define DOOR_CLOSING 3

#define MOTOR_CLOSING -1
#define MOTOR_STOPPED 0
#define MOTOR_OPENING 1

String stateNames[] = {"Closed", "Opening", "Opened", "Closing"};

//Stepper pins
const int STEP1 = 4;
const int STEP2 = 5;
const int STEP3 = 6;
const int STEP4 = 7;

//Stepper parameters
int motorSpeed = 5000;
int stepCounter = 0;

const int numSteps = 4;
//We use one phase rotation for the stepper
const int stepsLookup[4] = {B1000, B0100, B0010, B0001};

//Time that the stepper takes to open the door(in ms)
const int doorOpeningTime = 3000;
//Time that the door waits before closing
const int doorWaitTime = 2000;

//Number of steps of motor1
const int steps = 700;

//Maximum hand distance to open door
const int handDistance = 5;
//Distance to the wall at which the door motor stops
const int wallDistance = 20;
//Distance at which the closing door stops to avoid hitting user
const int blockDistance = 20;

//Door's inside ultrasonic sensor
int TRIG1 = 3;
int ECO1 = 2 ;
float distance1;

//Door's outside ultrasonic sensor
int TRIG2 = 11;
int ECO2 = 12;
float distance2;

//Door opener motor
int IN1 = 8;      // IN1 de L298N to pin digital 8
int IN2 = 9;      // IN2 de L298N to pin digital 9
int ENA = 10;      // ENA de L298N to pin digital 10

int refreshRate = 100;

//Parameters for sampling the outside sensor
const int subSampleSize = 5;
const int sampleSize = 3;
const float varThreshold = 1.5;

int subSampleIndex = 0;
int sampleIndex = 0;

int sample[sampleSize];

float sampleVariance = 0;
float subSampleMax = 0;

//int that represents the current state of the door
int doorState = DOOR_CLOSED;

//Detect when the user retires his hand from the sensor
bool handInSensor;

void setup() {
  //We initialize all pins
  pinMode(TRIG1, OUTPUT);
  pinMode(ECO1, INPUT);

  pinMode(STEP1, OUTPUT);
  pinMode(STEP2, OUTPUT);
  pinMode(STEP3, OUTPUT);
  pinMode(STEP4, OUTPUT);
  
  pinMode(IN1, OUTPUT);   // pin 8 output
  pinMode(IN2, OUTPUT);   // pin 9 output 
  pinMode(ENA, OUTPUT);   // pin 10 output
  Serial.begin(9600);
}
void demagnetize(){
  //Stop the stepper from drawing current
  digitalWrite(STEP1, LOW);
  digitalWrite(STEP2, LOW);
  digitalWrite(STEP3, LOW);
  digitalWrite(STEP4, LOW);
}
//Stepper
void opening(){
  stepCounter++;
  if(stepCounter >= numSteps) stepCounter = 0;
  setOutput(stepCounter);
}
void closing(){
  stepCounter--;
  if(stepCounter < 0) stepCounter = numSteps - 1;
  setOutput(stepCounter);
}

void setOutput(int step){
  digitalWrite(STEP1, bitRead(stepsLookup[step], 0));
  digitalWrite(STEP2, bitRead(stepsLookup[step], 1));
  digitalWrite(STEP3, bitRead(stepsLookup[step], 2));
  digitalWrite(STEP4, bitRead(stepsLookup[step], 3));
}

int getDistance(int TRIG, int ECO){
  digitalWrite(TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH);    // Ultrasonic sensor routine
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  int duration = pulseIn(ECO, HIGH);
  return duration / 58.2;
}

//Control the motor
void doorMotor(int rotDirection){
  if(rotDirection == MOTOR_CLOSING){
    Serial.println ("Door motor closing...");  
    digitalWrite(ENA, HIGH);
    digitalWrite(IN1, HIGH);  // IN1 a 1
    digitalWrite(IN2, LOW); // IN2 a 0
  }else{
    if(rotDirection == MOTOR_STOPPED){
      Serial.println ("Door motor stopping...");  
      digitalWrite(ENA, LOW); // ENA en 0 DC Motor off
      digitalWrite(IN1, LOW); // IN1 a 0
      digitalWrite(IN2, LOW); 
    }else{
      if(rotDirection == MOTOR_OPENING){
        Serial.println ("Door motor opening...");  
        digitalWrite(ENA, HIGH);
        digitalWrite(IN1, LOW); // IN1 a 0
        digitalWrite(IN2, HIGH);  // IN2 a 1
      }
    }
  } 
}

void loop() {
  //Read the distance of both sensors
  distance1 = getDistance(TRIG1, ECO1);
  distance2 = getDistance(TRIG2, ECO2);

  //We compute the max value of the subSample
  if(distance2 > subSampleMax){
    subSampleMax = distance2;
  }
  subSampleIndex++;

  if(subSampleIndex % subSampleSize == 0){
    sample[sampleIndex] = subSampleMax;
    sampleIndex++;

    Serial.println(subSampleMax);

    subSampleMax = 0;
    subSampleIndex = 0;
  }

  if(sampleIndex % sampleSize == 0 && subSampleIndex % subSampleSize == 0){
    sampleIndex = 0;

    int mean = 0;
    for(int i = 0; i < sampleSize; i++){
      mean += sample[i];
    }
    mean /= sampleSize;

    sampleVariance = 0;
    for(int i = 0; i < sampleSize; i++){
      sampleVariance += pow(sample[i] - mean, 2);
    }
    sampleVariance /= sampleSize;

    Serial.print("variance: ");
    Serial.println(sampleVariance);
  }
  
  //Print the door state
  Serial.print ("Door state: ");
  Serial.println (stateNames[doorState]);

  //Refresh rate of sensors
  delay(refreshRate);

  //Manage changes of door state
  switch(doorState){
    case DOOR_CLOSED:
      //The door is closed and awaits input
      if(distance1 <= handDistance && distance1 > 0){
        //We detected a hand in the inside sensor, so the door starts to open and we register that it was opened from the inside
        for(int i = 0; i < steps; i++){
          opening();
          delayMicroseconds(motorSpeed);
        }
        demagnetize();

        //And start the door's motor
        doorState = DOOR_OPENING;
        doorMotor(MOTOR_OPENING);
        //The user's hand starts in the sensor
        handInSensor = true;

        Serial.println("Pomo abierto");
      }else{
        if(distance2 <= handDistance && distance2 > 0){
          //We detected a hand in the inside sensor, so the door starts to open and we register that it was opened from the inside
          for(int i = 0; i < steps; i++){
            opening();
            delayMicroseconds(motorSpeed);
          }
          demagnetize();
  
          //And start the door's motor
          doorState = DOOR_OPENING_OUTSIDE;
          doorMotor(MOTOR_OPENING);
  
          Serial.println("Pomo abierto");
        }
      }
      break;
    case DOOR_OPENING:
      if(distance1 > wallDistance){
        //We detect when the user takes his hand away(so the inside sensor doesnt mix up the hand with the wall)
        handInSensor = false;
      }
      if(distance1 <= wallDistance && distance1 > 0 && !handInSensor){
        Serial.println("Wall");
        
        //If the inside sensor detects that the door has reached the wall it stops the motor
        doorMotor(MOTOR_STOPPED);
        doorState = DOOR_OPENED;
      }
      break;
    case DOOR_OPENING_OUTSIDE:
      if(distance1 <= wallDistance && distance1 > 0){
        Serial.println("Wall");
        
        //If the inside sensor detects that the door has reached the wall it stops the motor
        doorMotor(MOTOR_STOPPED);
        doorState = DOOR_OPENED;
      }
      break;
    case DOOR_OPENED:
      //For now we just wait some time with the door closed, later on we can use the outside sensor to detect when the user crosses the door
      delay(doorWaitTime);

      doorMotor(MOTOR_CLOSING);
      doorState = DOOR_CLOSING;
      break;
    case DOOR_CLOSING:   
      if(sampleVariance < varThreshold){
        doorState = DOOR_CLOSED;
        doorMotor(MOTOR_STOPPED);

        for(int i = 0; i < steps; i++){
          closing();
          delayMicroseconds(motorSpeed);
        }
        demagnetize();
      }
      break;
    default:  
      break;
    }
 }
old codeArduino
#include <Stepper.h>

Stepper motor1(2048, 4, 6, 5, 7);

int TRIG = 10;
int ECO = 9 ;
int DURATION;
int DISTANCE;
int IN1 = 2;      // IN1 de L298N to pin digital 2
int IN2 = 3;      // IN2 de L298N to pin digital 3
int ENA = 11;      // ENA de L298N to pin digital 11

void setup() {
 
  pinMode(TRIG, OUTPUT);
  pinMode(ECO, INPUT);
  pinMode(IN1, OUTPUT);   // pin 2 output
  pinMode(IN2, OUTPUT);   // pin 3 output 
  pinMode(ENA, OUTPUT);   // pin 11 output
  Serial.begin(9600);
  motor1.setSpeed(3);   // Stepper for door handle
  
}
  

void loop() {
  if (Serial.available()){     // system waits after you introduce a value of steps for the handle steppers
    
  digitalWrite(TRIG, HIGH);    // Ultrasonic sensor routine
  delay(1);
  digitalWrite(TRIG, LOW);
  DURATION = pulseIn(ECO, HIGH);
  DISTANCE = DURATION / 58.2;
  Serial.println (DISTANCE);      // end of Ultrasonic Sensor routine (shows the detected distance)
  delay(200);
  
  if (DISTANCE <= 100 && DISTANCE >=0){   //IF Distance ist between 0 and 100cm then is true and handle starts      
  int steps = Serial.parseInt();
  Serial.println(steps);            // handle stepper moves to the number of steps introduced
  motor1.step(steps);
  
  delay(5000);               //wait for 5 seconds
  
  digitalWrite(ENA, HIGH);  // DC door motor  (turns cw)
  digitalWrite(IN1, LOW); // IN1 a 0
  digitalWrite(IN2, HIGH);  // IN2 a 1
  delay(3000);      // wait for 3 seg.

  digitalWrite(ENA, LOW); // ENA en 0 DC Motor off
  delay(2000);      // wait for 2 seg.

  digitalWrite(ENA, HIGH);  // DC door motor  (turns ccw)
  digitalWrite(IN1, HIGH);  // IN1 a 1
  digitalWrite(IN2, LOW); // IN2 a 0
  delay(3000);      // wait for 3 seg

  digitalWrite(ENA, LOW); //  DC Motor off
  delay(2000);      // wait for 2 seg.
  }
 }
 }

Schematics

Option with two steppers works!
an important target is achieved because using the two 28BYJ-48 steppers, this automatic door handle can be very affordable
20200612_224232_Rj5au73s29.mp4
new schema with Arduino Nano
Captura de pantalla 2020 08 26 a les 18 47 32 hlkofpgwiy
alternative with switch
in this schema shows the alternative using a switch to detect the closed door.
Switch lmtl3nrhsg
Video with last stand
automatic_door_handle_yarAO2OCFS.mp4

Comments

Similar projects you might like

Touchless faucet with door control system for COVID-19

Project tutorial by Rucksikaa Raajkumar

  • 3,848 views
  • 6 comments
  • 19 respects

IoT arduino ESP Garage Door opener (UD)

Project in progress by David Smerkous

  • 15,681 views
  • 8 comments
  • 21 respects

Secret Door Opener

Project tutorial by Alex Wulff

  • 8,897 views
  • 2 comments
  • 35 respects

Garage Door Opener with Siemens TC35i Modem and Pro Mini

Project showcase by Grubits Gábor

  • 5,136 views
  • 2 comments
  • 9 respects

Garage door opener via mobile phone and RFID

Project tutorial by dtbaker

  • 12,055 views
  • 2 comments
  • 17 respects
Add projectSign up / Login