safety of automatic gate?

Hi,

This is my first arduino project. I’m making an automatic gate for my hallway which will allow people to walk through the gate automatically. The gate is used so the dog cannot get down to the lounge room carpet. The problems we had was no one remembered to shut the gate, so by making it automatic, that should eliminate the problem.

I plan on having two PID sensors, one either side. When triggered, the 10kg servo will move the gate in the opposite direction of the triggered sensor, wait ten seconds open, then shut the gate. Then it cannot be activated again for ten seconds.

This all works fine in testing. This is my code (note I only have one PID sensor with me at the moment, but I have more at home) I’m using the varspeedservo.h library from here to control servo position and speed: GitHub - netlabtoolkit/VarSpeedServo: Arduino library for servos that extends the standard servo.h library with the ability to set speed, and wait for position to complete

This is a vid of a prototype of the electronics working using a clone arduino ( I have a real one to use in the final version). Also it only stays open for 3 seconds rather than 10 because I was testing.

https://vid.me/yhfM

/*
* AUTOMATIC GATE
*/
#include <VarSpeedServo.h> 

int ledPin = 13;                // choose the pin for the LED
int inputPin = 2;               // choose the input pin (for PIR sensor)
int pirState = LOW;             // we start, assuming no motion detected
int val = 0;                    // variable for reading the pin status
VarSpeedServo myservo;          //includes varspeed servo library

void setup() {
myservo.attach(9);            //declare servo as output
pinMode(ledPin, OUTPUT);      // declare LED as output
pinMode(inputPin, INPUT);     // declare sensor as input

Serial.begin(9600);

}

void loop(){
myservo.write(90, 20, true); //sets servo back to home GATE CLOSED
val = digitalRead(inputPin);  // read input value
if (val == HIGH) {            // check if the input is HIGH
  digitalWrite(ledPin, HIGH);  // turn LED ON
  myservo.write(0, 20, true); // turn servo 90 degrees OPEN GATE
  delay(3000);  //delays servo open for ten seconds
  if (pirState == LOW) { //detect if sensor is clear
          myservo.write(90, 20, true); //sets servo back to home
          delay(10000); //stops sensor being triggered for ten seconds
       }
} else {
  digitalWrite(13, HIGH);
  delay(60);
  digitalWrite(13, LOW);
  delay(2000);
    
}
}

My only concern is safety of kids. Most of the time there are no kids at the house, but if my niece or nephew visits, I’m just worried, what if the gate tries to close or open while they are in the way? I’m not sure if the 10kg swinging the gate would be powerful enough to cause severe injuries?

Can anyone think of any ideas how I can safeguard against this? Is there a way to sense feedback in servos? Or if the servo can’t reach it’s position in the time specified, then stop?

Many thanks.

5A Range Current Sensor Module ACS712 for Arduino (Ebay)

Connect into servo power supply line and monitor the servo current.
Would need trial and error to see what is considered “normal” current draw and then set “alarm” or whatever a percentage above this.

bluejets: 5A Range Current Sensor Module ACS712 for Arduino (Ebay)

Connect into servo power supply line and monitor the servo current. Would need trial and error to see what is considered "normal" current draw and then set "alarm" or whatever a percentage above this.

This is brilliant thanks mate! Hopefully it doesn't pull more than 5 amps.. I only got a 2amp power supply anyway. So this device outputs a signal of some kind? and I set that as an input on the arduino? Is there example code of people using this in this type of fashion?

First point, you should never post your code inline like this. It must be placed between code tags. In the “Post” and “Reply” windows, </> marks the code tag button. It’s not too late to edit your post and fix this.

Second point, you declare and initialise this:-

int pirState = LOW;             // we start, assuming no motion detected

Then you use it in a conditional to check if the PIR has gone low:-

if (pirState == LOW){ //detect if sensor is clear
    myservo.write(90, 20, true); //sets servo back to home
    delay(10000); //stops sensor being triggered for ten seconds
}

But you never alter it when the PIR output is read, so it will always be low.

Finally, you don’t have to worry about someone being injured. The servo might have 10kg of pressure at it’s horn, but it will have very little strength at the swinging end of the gate. If it’s 10kg/cm, then at 10cm it will be 1kg, at 30cm 330grams, 60cm 165grams etc. I doubt if it’s powerful enough to do the job of swinging a gate properly.
The biggest concern is that if someone gets in the way, the servo gears will strip, killing it.
And I think the dog will be able to force it open, unless it’s a pretty weak chihuahua.
I’m not sure that a hobby RC servo will like running full-time, either. I assume that this has to run 24 hours per day? It won’t last long.

OldSteve:
First point, you should never post your code inline like this. It must be placed between code tags. In the “Post” and “Reply” windows, </> marks the code tag button. It’s not too late to edit your post and fix this.

Second point, you declare and initialise this:-

int pirState = LOW;             // we start, assuming no motion detected

Then you use it in a conditional to check if the PIR has gone low:-

if (pirState == LOW){ //detect if sensor is clear

myservo.write(90, 20, true); //sets servo back to home
    delay(10000); //stops sensor being triggered for ten seconds
}



But you never alter it when the PIR output is read, so it will *always* be low.

Finally, you don't have to worry about someone being injured. The servo might have 10kg of pressure at it's horn, but it will have very little strength at the swinging end of the gate. If it's 10kg/cm, then at 10cm it will be 1kg, at 30cm 330grams, 60cm 165grams etc. I doubt if it's powerful enough to do the job of swinging a gate properly.
The biggest concern is that if someone gets in the way, the servo gears will strip, killing it.
And I think the dog will be able to force it open, unless it's a pretty weak chihuahua.
I'm not sure that a hobby RC servo will like running full-time, either. I assume that this has to run 24 hours per day? It won't last long.

I’m not really sure what the issue is that you try and explain. It’s probably just the description I used to describe the code is wrong. Because functionally it works fine, exactly as I intended.

The gate is only small, about 80cm wide and quote short. My dog is quite small, but I bought one of those locks that uses electromagnet to open, so I will use this is my dog can push it open.

Hopefully the servo has enough torque! I originally bought a stepper motor but I didn’t want to have to rely on using end switches and setting a home location, but maybe it’s what I should have done anyway… oh well I’ll see how the servo goes first.

hinghacks: I'm not really sure what the issue is that you try and explain. It's probably just the description I used to describe the code is wrong. Because functionally it works fine, exactly as I intended.

No, it's not your description, it's a fault in your code. You should look more closely.

This does nothing will always close the gate, because you never set pirState to high, so it will always be low, as I said:-

if (pirState == LOW){ //detect if sensor is clear
    myservo.write(90, 20, true); //sets servo back to home
    delay(10000); //stops sensor being triggered for ten seconds
}

Even if someone is moving right in front of the PIR sensor, the gate will close. (You set pirState 'LOW' when you declare it, but that value is never changed in the code.) Now do you understand?

Yeah I knew it would close even if someone was standing in front of it. Like I said it's the description that's wrong..

Could I change it so that if the sensor is high it won't move on?

hinghacks: Yeah I knew it would close even if someone was standing in front of it. Like I said it's the description that's wrong..

No, for the third time, the code is wrong. Your comment in the code says "//detect if sensor is clear", and that is quite obviously what you actually intended, so don't keep saying it's just your description that's wrong. You'll never learn a damn thing that way. That code does not "detect if sensor is clear". It just always closes the gate regardless.

Could I change it so that if the sensor is high it won't move on?

Yes, you could change it. First you need to change the way you write the program to use millis()-based timing. Then, when you open the gate, you record the time (in millis) that it was opened. Next, when the time period expires, if the PIR sensor signal has gone low, you close the gate.

To learn a little about millis()-based timing, take a look at the "BlinkWithoutDelay" example that came with the IDE, and also this thread:- Demonstration code for several things at the same time It's poor programming practice to use 'delay()' for timing, because it 'blocks' execution and allows nothing else to happen until the delay times out.

There are also other issues with your code that need to be addressed. As it stands, your code will open the gate if the PIR is triggered, then close it after 3 seconds, as you want. If the PIR is not triggered, the program will flash a LED on for 60mS then wait for 2 full seconds before checking if the PIR detector has been triggered. So a person will have to be in front of the PIR sensor for up to 2 seconds before the gate opens. Is that the behaviour you wanted?

A rewrite using the methods for millis()-based timing would be the best way to tackle this program. One 'if' statement would handle opening the gate, and another 'if' statemant would handle closing the gate, and the "gate-closing" 'if' statement wouldn't be nested inside the "gate-opening" 'if' statement.

All in all, you need a bit more practice, to learn the basics. The best approach would be to play with "BlinkWithoutDelay" and the examples in Robin2's thread, which I linked to, then start again. It will get a lot harder when you have to handle two PIR sensors, too.

I believe the unit I mentioned would have an analog output so it will have to go to an analog input.

Should be info somewhere in here about using them as I have not done so as yet.

If you are concerned about servo life then maybe metal gears would ramp it up a bit. Can get some on Ebay for around $7.00 (last for yonks in my experience)

OldSteve:
No, for the third time, the code is wrong.
Your comment in the code says “//detect if sensor is clear”, and that is quite obviously what you actually intended, so don’t keep saying it’s just your description that’s wrong. You’ll never learn a damn thing that way.
That code does not “detect if sensor is clear”. It just always closes the gate regardless.
Yes, you could change it. First you need to change the way you write the program to use millis()-based timing.
Then, when you open the gate, you record the time (in millis) that it was opened.
Next, when the time period expires, if the PIR sensor signal has gone low, you close the gate.

To learn a little about millis()-based timing, take a look at the “BlinkWithoutDelay” example that came with the IDE, and also this thread:- Demonstration code for several things at the same time
It’s poor programming practice to use ‘delay()’ for timing, because it ‘blocks’ execution and allows nothing else to happen until the delay times out.

There are also other issues with your code that need to be addressed.
As it stands, your code will open the gate if the PIR is triggered, then close it after 3 seconds, as you want.
If the PIR is not triggered, the program will flash a LED on for 60mS then wait for 2 full seconds before checking if the PIR detector has been triggered. So a person will have to be in front of the PIR sensor for up to 2 seconds before the gate opens. Is that the behaviour you wanted?

A rewrite using the methods for millis()-based timing would be the best way to tackle this program.
One ‘if’ statement would handle opening the gate, and another ‘if’ statemant would handle closing the gate, and the “gate-closing” ‘if’ statement wouldn’t be nested inside the “gate-opening” ‘if’ statement.

All in all, you need a bit more practice, to learn the basics. The best approach would be to play with “BlinkWithoutDelay” and the examples in Robin2’s thread, which I linked to, then start again. It will get a lot harder when you have to handle two PIR sensors, too.

Thanks for the advice. This is my first program so no doubt it’s bad. I didn’t think about the LED flashing delay would delay the pid sensor, but it totally makes sense since I’m experiencing that behavior, I think anyway…honestly it still works fine. I just had the LED flashing so you could tell it was waiting to sense and the gate was on.

I’ll try to improve the code but I’m honestly just happy it works as it is :slight_smile:

hinghacks: I'll try to improve the code but I'm honestly just happy it works as it is :)

Well, it sort of works, just not quite as you expected or wanted.

If you really want to learn to use an Arduino and write useful programs, I strongly recommend thouroughly reading the examples I mentioned, then doing some playing around to get the feel of 'millis()'-based timing. It's the only way you'll ever be able to get an Arduino to do multiple things at once, which is an important aspect of programming.

You could at least start by using 'millis()' to do the timing for the LED flashes, then go from there.

Good luck, anyway, I'm sure you'll get the hang of it. :)