My concern with such a change is that by definition, the door is in an indeterminate position and we have no idea if anything is in the portal's threshold. By blinding lowering the door it may pose a risk for any critter in the way. Granted, the door isn't direct drive but its still contrary to my preference for leaning toward a builtin safety. So its not that its wrong, I personally don't feel its as safe. Ultimately, that's not my call to make.
Good point, however, your code will open the door, then lower it should the light level be below the threshold, all I have done is eliminate the need for the door to open before checking where it should be, hopefully saving a little battery life in the process.
Yes, the opening and closing is by intent and design. It only kicks in when the door is in a transient position which should never occur unless an error or power loss had previously occurred. Basically during testing and tweaking phase, its likely to be seen a lot. Beyond that, unless the power goes out or the door chronically jams, I wouldn't expect it to ever be triggered.
As for animal safety, the door is simply being lowered by the spool winding down, the only force pulling the door down is gravity, there is no force pushing the door downwards, I doubt anything but a small rodent would be injured by the force of a fairly light door being lowered relatively slowly.
I have no idea how large or small the size of his animal. Part of engineering is to plan for reasonable worst case. He may have a tea cup Chihuahua for all I know; whereas a large rodent would be more hardy. I didn't attempt to do the math to see how quickly the door comes down. Therefore, I have no idea what the potential energy looks like. Even if the door closure itself can't physically do harm, a wedged head and extraction isn't likely to endear the animal to the door. Seriously, what does erring on the side of caution really cost us? An extra complete lift following power failure every dozen years; whereby the door was already partially open? Do we really care, especially since its already coded?
Plus, for what I want to use this circuit for (chicken coop door opener) that safety measure becomes pretty much redundant, chickens tend to stay away from the door when it's time for bed.
Different animals have different behaviors. Dogs don't have a problem lying across a threshold. That doesn't mean his specific animal will. The flip side of that is, if you want to keep predators out, you'll likely want a fairly heavy door. Maybe even a locking mechanism via a solenoid. Unless your goal isn't to keep predators out so much as to simply keep them in. In this neck of the woods, snakes, coyotes, and even feral hogs, can all lift such a door. Depending on his animal, he may find a heavier door is also required. But that's more on the physical construction details rather than the programming side of things. Accordingly, this feature should be fairly robust regardless of the actual construction details (heavy door, large spindle diameter, high rpm motor, etc).
Nice work on the safety measures there, seems like this would be useful in the testing phase of installation. How would I go about implementing a test mode option (delay becomes next to nothing before opening/closing based on LDR value), then a manual close and a manual open button?
Just a simple interrupt at the top for each pin?, something like this:
if (manualclose == high){
lower_door()
}
and the inverse for manual open?
Excuse the syntax, I code not good.
IMOHO, you'll likely want the push button to generate an interrupt. You'll need to declare an Interrupt Service Routine (ISR). The ISR should access a volatile global variable (or other shared mechanism), changing its state to reflect the activation of the button, Then, you need to create your own delay function, which also accepts a unsigned long as its argument. Then, loop testing against both the expiration of the requested delay or the change in global variable set by your ISR.
Pseudo code would look something like the following. It can be written better but this should give you an idea.
// We return the number of milliseconds spent inside
unsigned long delayButtonCheck( unsigned long delay ) {
unsigned long start = millis() ;
while( (millis() - start < delay) && (0 == ISRButtonPressed) ) {
}
return millis() - start ;
}
And then in your calling code you can do something like:
#define WAIT_DELAY 1000
if( delayButtonCheck( WAIT_DELAY ) < WAIT_DELAY ) {
// Means we exited prematurely - potentially rare race condition but worst case
// it should be caught on our next iteration through.
handleButtonPress() ;
}