This sketch goal is to operate a gate/door in a chicken coop. A photo resistor senses the shift in light condition.
when the light falls under the threshold it will close the door, and the opposite in the morning.
The door is connected to a DC-motor. The open/close distance of the door is controlled by two reed switches.
This sketch uses DRV8835MotorShield library to drive the motor (M1) Pololu DRV8835 Dual Motor Driver Shield for Arduino forward and backward, to open and close the chicken door.
Its not really working. The motor keeps running when the door is down, why is it not braking? Would some one please comment on my code, I apologise in advance :-/
#include <DRV8835MotorShield.h>
/*
* This sketch goal is to operate a gate/door in a chicken coop. A photo resistor senses the shift in light condition.
* when the light falls under the threshold it will close the door, and the opposite in the morning.
* The door is connected to a DC-motor. The open/close distance of the door is controlled by two reed switches.
*
* This sketch uses DRV8835MotorShield library to drive the motor (M1) Pololu DRV8835 Dual Motor Driver Shield for Arduino forward and backward, to open and close the chicken door
*
*/
DRV8835MotorShield motors;
const int photoValue =A3;
const int magneticSwitchUP = 2;
const int magneticSwitchDOWN = 3;
int photocellReading = 0;
int doorswitchUP = 0;
int doorswitchDOWN = 0;
//____________________________SETUP_______________________________________
void setup()
{
//magnetiske kontakter
pinMode (magneticSwitchUP, INPUT);
digitalWrite(magneticSwitchUP, HIGH);
pinMode (magneticSwitchDOWN, INPUT);
digitalWrite(magneticSwitchDOWN,HIGH);
Serial.begin(9600);
// uncomment the following line if your motor directions need to be flipped
//motors.flipM1(true);
}
//____________________________LOOP________________________________________
void loop()
{
photocellReading = analogRead (A3);
delay(5);
doorswitchUP = digitalRead (2);
delay(5);
doorswitchDOWN = digitalRead (3);
Serial.print("photocellReading: ");
Serial.println(photocellReading);
Serial.print("Upper switch ");
Serial.println(doorswitchUP);
Serial.print("Lower switch ");
Serial.println(doorswitchDOWN);
//_________Morning - sunrise________________________
if (photocellReading > 500)
{while (digitalRead (magneticSwitchDOWN)== HIGH) //if hacth is down the door shold move up
{
motors.setM1Speed(300); //run motor forward at speed 300
}
if (digitalRead (magneticSwitchUP) == HIGH) //When the door reaches the uppe switch the motor brakes down
{
for (int speed = 300; speed >= 0; speed--)
{
motors.setM1Speed(speed);
}
}
}
//______________Night - sunset___________________________
if (photocellReading < 500) //lightvalue drops under threshold
{while (digitalRead (magneticSwitchUP)== HIGH) //If the door is up, the door start closing
{
motors.setM1Speed(-300); //run motor bagward at speed -300
if (digitalRead (magneticSwitchDOWN) == HIGH) //when the door reaches the lower contact the motor brakes
{
for (int speed = -300; speed <= 0; speed--)
{
motors.setM1Speed(speed);
}
}
}
}
//_____________________________________
delay (1000);
}
You have no hysteresis in your light detection - fix this first, you need 4 states to represent the
two static and two dynamic states of the system - closed, opening, open, closing. The
states should be arranged to cycle in that order according to light level and whether the
motor is still moving.
The light level to transition closed->opening must be significantly higher than that
which triggers open->closing, or the system will oscillate as clouds pass over the sky.
You could also add a time-window to prevent successive opening / closing, perhaps an hour
When the motor is going in one direction you only have to test for a single switch changing,
the one it is heading towards.
Why are you using a stepping motor? That's so power-hungry.
You need some sort of code to limit the rate of ramping the motor drive up and down,
otherwise it'll happen in a few microseconds.
So I think I understood what I had to do, but lack of experience made me search around and i found very usefull code from cduryee (found here: Chicken Coop Controller - Programming Questions - Arduino Forum) I changed some of it, since my setup is litle different. But for some reason the code is not working at all. Not even the serial monitor has any input. please comment. again...i apologise in advance
by the way, im not using a stepper but a DC motor, I run it using af DRV8835MotorShield and a library along with it.
#include <DRV8835MotorShield.h>
/*
* This sketch goal is to operate a gate/door in a chicken coop. A photo resistor senses the shift in light condition.
* when the light falls under the threshold it will close the door, and the opposite in the morning.
* The door is connected to a DC-motor. The open/close distance of the door is controlled by two reed switches.
*
* This sketch uses DRV8835MotorShield library to drive the motor (M1) Pololu DRV8835 Dual Motor Driver Shield for Arduino forward and backward, to open and close the chicken door
*
*/
DRV8835MotorShield motors;
// pins assignments
const int photocellPin=A3;
const int topSwitchPin = 2; //reedswitch at the top
const int bottomSwitchPin = 3; //reedswitch at the bottom
// variables
int photocellReading = 0;
int photocellReadingLevel = 0;
int bottomSwitchPinVal = 0;
int bottomSwitchPinVal2 = 0;
int bottomSwitchState = 0;
int topSwitchPinVal = 0;
int topSwitchPinVal2 = 0;
int topSwitchState = 0;
// photocell reading delay
unsigned long lastPhotocellReadingTime = 0;
unsigned long photocellReadingDelay = 6000; // 10 minutes
//**************************************** setup *****************************************
void setup() {
// bottom switch
pinMode(bottomSwitchPin, INPUT); // set bottom switch pin as input
digitalWrite(bottomSwitchPin, HIGH); // activate bottom switch resistor
// top switch
pinMode(topSwitchPin, INPUT); // set top switch pin as input
digitalWrite(topSwitchPin, HIGH); // activate top switch resistor
Serial.begin(9600);
}
// ************************************** functions **************************************
void doReadPhotoCell() { // function to be called repeatedly - per coopPhotoCellTimer set in setup
photocellReading = analogRead(photocellPin);
if ((unsigned long)(millis() - lastPhotocellReadingTime) >= photocellReadingDelay) {
lastPhotocellReadingTime = millis();
}
}
// photocel to read levels of exterior light
void readPhotoCell() // function to be called repeatedly - per cooptimer set in setup
{
photocellReading = analogRead(photocellPin);
Serial.print(" Photocel Analog Reading = ");
Serial.println(photocellReading);
// set photocel threshholds
if (photocellReading >= 0 && photocellReading <= 3) {
photocellReadingLevel = '1';
Serial.print(" Photocel Reading Level:");
Serial.println(" - Dark");
} else if (photocellReading >= 4 && photocellReading <= 120){
photocellReadingLevel = '2';
Serial.print(" Photocel Reading Level:");
Serial.println(" - Twilight");
} else if (photocellReading >= 125 ) {
photocellReadingLevel = '3';
Serial.print(" Photocel Reading Level:");
Serial.println(" - Light");
}
}
//debounce bottom reed switch
void debounceBottomReedSwitch() {
//debounce bottom reed switch
bottomSwitchPinVal = digitalRead(bottomSwitchPin); // read input value and store it in val
delay(10);
bottomSwitchPinVal2 = digitalRead(bottomSwitchPin); // read input value again to check or bounce
if (bottomSwitchPinVal == bottomSwitchPinVal2) { // make sure we got 2 consistant readings!
if (bottomSwitchPinVal != bottomSwitchState) { // the switch state has changed!
bottomSwitchState = bottomSwitchPinVal;
}
Serial.print (" Bottom Switch Value: "); // display "Bottom Switch Value:"
Serial.println(digitalRead(bottomSwitchPin)); // display current value of bottom switch;
}
}
// debounce top reed switch
void debounceTopReedSwitch() {
topSwitchPinVal = digitalRead(topSwitchPin); // read input value and store it in val
delay(10);
topSwitchPinVal2 = digitalRead(topSwitchPin); // read input value again to check or bounce
if (topSwitchPinVal == topSwitchPinVal2) { // make sure we got 2 consistant readings!
if (topSwitchPinVal != topSwitchState) { // the button state has changed!
topSwitchState = topSwitchPinVal;
}
Serial.print (" Top Switch Value: "); // display "Bottom Switch Value:"
Serial.println(digitalRead(topSwitchPin)); // display current value of bottom switch;
}
}
// close the coop door motor (motor dir close = negative speed)
void closeCoopDoorMotorB() {
delay(900); // New delay to keep motor running for locks
for (int speed = 0; speed >= -400; speed--) //speed value 0 --> -400
{
motors.setM1Speed(speed); // enable motor, full speed 0 --> -400
}
if (bottomSwitchPinVal == 0) { // if bottom reed switch circuit is closed
for (int speed = -400; speed <= 0; speed++) //speedvalues from 400 to 0
{
motors.setM1Speed(speed); //brake motor down from Negative speed -400 --> 0
delay(2);
}
Serial.print(" Coop Door Closed - no danger");
}
}
// open the coop door (motor dir open = postive speed)
void openCoopDoorMotorB() {
for (int speed = 0; speed <= 400; speed++)
{
motors.setM1Speed(speed); // enable motor, full speed
if (topSwitchPinVal == 0) { // if top reed switch circuit is closed
for (int speed = 400; speed >= 0; speed--) //speedvalues from 400 to 0
{
motors.setM1Speed(speed); //brakes motor down from positive speed 400 --> 0
delay(2);
Serial.print(" Coop Door open - danger!");
}
}
}
}
void doCoopDoor(){
if (photocellReadingLevel == '1') { // if it's dark
if (photocellReadingLevel != '2') { // if it's not twilight
if (photocellReadingLevel != '3') { // if it's not light
debounceTopReedSwitch(); // read and debounce the switches
debounceBottomReedSwitch();
closeCoopDoorMotorB(); // close the door
}
}
}
if (photocellReadingLevel == '3') { // if it's light
if (photocellReadingLevel != '2') { // if it's not twilight
if (photocellReadingLevel != '1') { // if it's not dark
debounceTopReedSwitch(); // read and debounce the switches
debounceBottomReedSwitch();
openCoopDoorMotorB(); // Open the door
}
}
}
}
// ************************************** the loop **************************************
void loop() {
doReadPhotoCell();
doCoopDoor();
}