Auto Chicken Door

it might burn out the motor trying to close a jammed door.

Then, you need to add current sensors, to detect a stalled motor. And warning lights and sirens that the door is going to open and close. And e-mail and text messages that the door has been opened or closed. And, don't forget to twit that, too. Oh, and COSM probably needs to be able to show the light level and current consumption.

@PaulS
You must be really bored rite now to be trolling?

PaulS:

it might burn out the motor trying to close a jammed door.

Then, you need to add current sensors, to detect a stalled motor. And warning lights and sirens that the door is going to open and close. And e-mail and text messages that the door has been opened or closed. And, don't forget to twit that, too. Oh, and COSM probably needs to be able to show the light level and current consumption.

Only if you're billing the government on the job. Then add a small well paid private-sector staff to deal with all those messages and make telephone book thick reports, plus armed guards.

But for a farmer who doesn't have a barrel of pork to pay it all with, it'd be cheaper in chickens, motors and possibly damage to his own arm to set up an IR led and sensor or two.

But for a farmer who doesn't have a barrel of pork to pay it all with, it'd be cheaper in chickens, motors and possibly damage to his own arm to set up an IR led and sensor or two.

Oh, geez. Can't anybody have any fun here?

I dunno. I just did. ]:smiley:

I dunno. I just did.

ROTFLMAO

@Arrch

I tried to input the code you gave me, and couldn't get it to work. I'm sure it's something I'm doing. I did get it to work with this code, switching directions with light and dark.

int photocellPin = A5; // select the input pin for the photocell
int sensorValue = 0; // variable to store the value coming from the photocell
int motorPin = 12; //
int limitSwitch = A4; //stop motor when reached

void setup() {
Serial.begin(9600); //set baud rate to 9600 on the Arduino
pinMode(photocellPin,INPUT);
//Setup Channel A
pinMode(motorPin, OUTPUT); //Initiates Motor Channel A pin
pinMode(9, OUTPUT); //Initiates Brake Channel A pin

}

void loop(){
sensorValue = analogRead(photocellPin);
Serial.println(sensorValue); //print the value to serial monitor

if (sensorValue < 300) //if there is darkness then turn the motor on
if (limitSwitch > 512) //
{
//forward @ full speed
digitalWrite(motorPin, HIGH); //Establishes forward direction of Channel A
digitalWrite(9, LOW); //Disengage the Brake for Channel A
analogWrite(3, 255); //Spins the motor on Channel A at full speed

digitalWrite(9, HIGH); //Eengage the Brake for Channel A
}
{
if (sensorValue >300) //if there is light then turn the motor on
digitalWrite(motorPin, LOW); //Establishes Reverse direction for channel A
digitalWrite(9, LOW); //Disengage the brake for channel A
analogWrite(3,255); //Spins the motor on channel A at full speed

delay (1000);

digitalWrite(9, HIGH);

}
}

Now my problem is I can't get the motor to stop...at all. I only want it to run for 10 seconds. Also want 30 minutes of light or dark before the motor turns on. But that seems like a long ways away from where I am now. Any help would be appreciated. Thanks!!

GoForSmoke:
Be practical, it might burn out the motor trying to close a jammed door.

Current sensor. Or chicken sensor. :stuck_out_tongue:

Where do you read the limit switch?

If it's a digital read then it will only ever be 0 or 1, 512 is a bit high and I have yet to see an analog limit switch.

Once you understand the Blink Without Delay sketch in you IDE-included examples (under 2. Digital) you should be able to make things happen over time in your sketch.

berndtc426:
I tried to input the code you gave me, and couldn't get it to work. I'm sure it's something I'm doing. I did get it to work with this code, switching directions with light and dark.

Please edit your post, select the code, and put it between [code] ... [/code] tags.

You can do that by hitting the # button above the posting area.

I can't make much sense of your intentions here. How about a bit of indenting (after putting in the code tags)?

For example:

  if (sensorValue < 300) //if there is darkness then turn the motor on
  if (limitSwitch > 512) //
  {
  //forward @ full speed

How much code is intended to be affected by " if (sensorValue < 300) "?

[/codeint photocellPin = A5; // select the input pin for the photocell
int sensorValue = 0; // variable to store the value coming from the photocell
int motorPin = 12;  //


void setup() {
  Serial.begin(9600); //set baud rate to 9600 on the Arduino
  pinMode(photocellPin,INPUT);
  //Setup Channel A
  pinMode(motorPin, OUTPUT); //Initiates Motor Channel A pin
  pinMode(9, OUTPUT); //Initiates Brake Channel A pin
  
}

void loop(){
  sensorValue = analogRead(photocellPin);
  Serial.println(sensorValue);  //print the value to serial monitor
  
  if (sensorValue < 300) //if there is darkness then turn the motor on
  
  {
  //forward @ full speed
  digitalWrite(motorPin, HIGH); //Establishes forward direction of Channel A
  digitalWrite(9, LOW);   //Disengage the Brake for Channel A
  analogWrite(3, 255);   //Spins the motor on Channel A at full speed
  
  
  digitalWrite(9, HIGH); //Eengage the Brake for Channel A
}
{
  if (sensorValue >300) //if there is light then turn the motor on
  digitalWrite(motorPin, LOW); //Establishes Reverse direction for channel A
  digitalWrite(9, LOW);  //Disengage the brake for channel A
  analogWrite(3,255);  //Spins the motor on channel A at full speed

delay (1000);

digitalWrite(9, HIGH);

}
}

disengage the brake
start the motor
engage the brake

All within microseconds.

So many things to tell that have already been told.
Learn This Well:

Part of the not-secret: every time loop() goes around at least a little bit of time has gone by. Loop() may execute millions of times between start the motor and the door moving just inches.

If you just flip back with some half-baked changes then I hope someone helps you but it won't be me. These things take actual effort. Just how much depends on how much you need to unlearn maybe more than how much you need to learn and what attitude you feel when you're about it.

It's not the effort I'm having issues with, it's the understanding. Thanks though.

Each time loop() ends the Arduino runs loop(). That is like a wheel that turns, moving forward along your real-time tasks.
Arduino operates faster than thought. Even analog reads, a very slow operation compared to almost all the rest is still done at about 9000 times per second. Digital reads take less than a micosecond.

Your door moves much slower than that so you code to start the movement and at least wait for the door to close before you end the move. Loop() could run many millions of times between start and end even if it takes less than 1/2 second for the door to close. So start is one operation you do at one time and stop is another to do at a later time. But both fit inside of loop(), or you call functions to do those inside loop().
You might even add some kind of switches or sensors to tell you when the door has reached the desired positions and have the controller watch for the door to finish the move commanded and perhaps keep track of how long that is taking in case the door jams unexpectedly. You would if you moved the door by hand wouldn't you?

But hey, it's your motor, your door and your chickens.

You should understand that time is involved in the task you want done every bit of the way and code for it. Whether it's 3 hours or 3 milliseconds, handle the start and end of the interval as separate events because to Arduino those are like 3 months or 3 minutes where from one line of code to the next is less than 1 second.
The controller will do as instructed. It is up to you to to say what to do and when. Using millis() makes it easier to handle the when(s) and using a state machine and/or sensor checks (if ready then do, if done then stop, if timeout then stop and tell someone, etc) makes it easier to set up sub-tasks inside loop() that do not have to fit inside the logic/braces of each other.

pseudocode -- just to show an idea of how it's done:

loop()
{
  if time to open the door -- command to start open the door -- end if

  if command to start open the door -- start the motor to open, command to watch the door open -- end if

  if command to watch the door open -- if the door is open the stop the door, command nothing to happen -- end if

// etc for time to close and what else you might want done

None of those subtasks is inside the logic of another. That means less logic tangles to puzzle out and debug. Every task requires a certain amount of complexity, this helps reduce the excess.

The subtasks run on either time or what command was given previously, or both. The 'command nothing' is just to clear the last command.

New tasks can be added that depend on the state of sensor(s) or serial.available or what you want without having to fit those inside the others. Keep those simple and short, don't try to do everything in 1 pass through loop() and your code will ultra-responsive without extra complication in how the pieces fit.

We sometimes call the command the 'state of operations' or some other phrase with the word 'state' in it. The code is referred to as a state machine. But it's really as simple as keeping track of what is being done to do what is needed each time through loop().

You can have more than one state/command to be able to do more than 1 thing at a time.

State/command is just a value you keep in a global or static variable so that each time through loop() your code "knows what it was doing then to know what to do now".

I hope this helps you understand.

GoForSmoke:
...
pseudocode -- just to show an idea of how it's done:

loop()

{
  if time to open the door -- command to start open the door -- end if

if command to start open the door -- start the motor to open, command to watch the door open -- end if

if command to watch the door open -- if the door is open the stop the door, command nothing to happen -- end if

// etc for time to close and what else you might want done




None of those subtasks is inside the logic of another. That means less logic tangles to puzzle out and debug. Every task requires a certain amount of complexity, this helps reduce the excess.
...

berndtc426 , this is all very good advice from GoForSmoke... No need to give up, it's not as hard as you think right now :slight_smile:

In fact the above doesn't even have to be pseudocode, it might/could (IMHO should) be real code:

void loop()
{
	if (sunriseDetected()) startMotorOpening();
	if (sunsetDetected())  startMotorClosing();
	if (openedLimitDetected()) stopMotor();
	if (closedLimitDetected()) stopMotor();
	if (manualButtonPushDetected()) startMotorWhichEverWayMakesSense();
}

Another interesting thing about it is that those lines (in both mine and GoForSmokes) can be placed in any order! Think about it...

Cheers,
John

You miss the point entirely John. I'm not calling functions when using control/state. I'm changing the value of a variable that controls what section of the loop() code runs next.

I tried to explain that before and after the pseudocode example and I even explained why.

Why do people have to take simple things and complicate them? Is it because they believe it must be so and can't believe otherwise? Or because they learn one way to code and warp everything to fit that?

  1. Each if those lines in the pseudocode stands by itself.
  2. Each represents a small separate section of code.
  3. Each may run or not run (mostly not run) each time loop() executes.
  4. Which parts run depends on time or the value of a control/state variable.
  5. Any part can change the control/state variable.

Some people use switch(state)-case to only run 1 section per time through loop() but that's not required. It can save on checking a load of if()'s which is often a good thing if you have a load of if()'s and use of that doesn't keep some section or sections from running at all. The latter is when "cleanup the code logic" becomes a bad thing.
Ascetics is only good when it's practical, otherwise it becomes baroque. Making inline code into functions just to make it pleasing to the eye is not always as "simplifying" as claims would have it (just the opposite), it runs slower and generally uses more stack which on a small-RAM chip isn't the brightest idea in the world.

Hey man, sorry if you took my post as an attack, negation, or rebuttal-- quite the contrary is what I intended. I admire the advice you gave to berndtc426 in both content and clarity with which you conveyed it.

I think there are a different things that can be effective for various people --and even the same people (including me) in various contexts and various times---both in practice and pedagogy. This includes "what is an appropriate level of abstraction".

One has lots of choices as to how he will reify his abstractions, i.e. what line is to be written after the comment // e.g. Start the Pump?

// Start the Pump
1101 1011 0101 1010        machine language binary?
DB5A                       machine language hex? *
outp 0x5a, 0x09            ; assembly
outp THEPORT, PUMPSTATE   ; assembly with symbolic?
digitalWrite( 11, 255);   // c?
digitalWrite( THEPORT, PUMPSTATE );  c with symbolics?
setPump( ON);             // domain language
or even get rid of the comment and write:
startThePump();           // domain language
or higher:
beginWateringChickens();

That you seem to assert the abstractions I have presented here are [missing point|overly complicated|warped|inefficient] is ok with me, YMMV :slight_smile: "But hey, [his] your motor, [his] door and [his] chickens." And his abstractions.

Back to work;Best regards,
John

*P.S.: for some reason comes to mind that saying:
real programmers use echo '\xDB\x5A' >> myprog.o ;...; chmod 660 myprog.o; myprog.o

johncc:
Hey man, sorry if you took my post as an attack, negation, or rebuttal--

None of those.

You missed the point completely. You turned it into something different. I tried to correct that, but now it's about you? Sorry but no. Try reading what I wrote, not what you think of what I wrote.

OP;

The loop() goes around. When loop() ends, it runs loop() again. The command/state is a value to use to control what parts of the loop() code to execute each time. It's just code that remembers what it was doing last time to run the right parts(s) each time. Nothing else. What the parts are, I only gave examples.

@ GoForSmoke, thank you for taking the time and helping me understand. Now I need to go back and take a good look at what I have with new understanding.