Go Down

Topic: Sketch to operate door with reed switches (Read 1 time) previous topic - next topic

clausgudum

I have tried to make an automatic door for at 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.
Im using a DC motor to pull a string that opens and closes the hatch, the motor is controlled with DRV8835MotorShield.

Its not working, noting happens. I dont event get a reading on the serial monitor.
So im going carzy. I would really appreciate som help on this sketch...

Code: [Select]


#include <DRV8835MotorShield.h>

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 = 6;   // 10 minutes

//**************************************** setup *****************************************

void setup (void) {

  Serial.begin(9600);

  // 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


}

// ************************************** 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();

}

AWOL

#1
Jun 09, 2015, 03:12 pm Last Edit: Jun 09, 2015, 03:14 pm by AWOL
Quote
I dont event get a reading on the serial monitor.
Probably because you never send anything to the serial monitor.

Code: [Select]
void doCoopDoor() {


  if (photocellReadingLevel  == '1') {     

Ask yourself how "photocellReadingLevel" could have the value '1', when all you do is set it to zero.

clausgudum

but I thought that this:

Code: [Select]
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(photocellReading);
    Serial.println(" - Light");
  }
}


Asks to send "photocellReading" to the serial monitor? and then this readings should be transformed into a "photocellereadingLevel" - dark, twillight and light...

Im sorry if Im not to bright - I dont have much coding experince

AWOL


JimboZA

Looks to me that there are 2 functions which are to do with reading the photocell, to wit readPhotoCell() and doReadPhotoCell(). Far as I can see, only the latter gets called in loop() and it doesn't do a serial print.

We should also see the circuit, to see how the cell is hooked up: presumably in a divider with another resistor?
Johannesburg hams call me: ZS6JMB on Highveld rep 145.7875 (-600 & 88.5 tone)
Dr Perry Cox: "Help me to help you, help me to help you...."
Your answer may already be here: https://forum.arduino.cc/index.php?topic=384198.0

clausgudum

#5
Jun 09, 2015, 04:15 pm Last Edit: Jun 09, 2015, 04:18 pm by clausgudum
Yay!!! I changed the last bit so now something happens, you were right!

Code: [Select]

#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 = 600;   // 10 minutes

//**************************************** setup *****************************************

void setup (void) {

  Serial.begin(9600);

  // 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


}

// ************************************** 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
      }
    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
        // 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();
  readPhotoCell();
  doCoopDoor();
}


I also deletet the delays in the "openCoopDoorMotorB" and "closeCoopDoorMotorB"

But the motor is diffenetly not doing what i want it to do...hmmm

AWOL

#6
Jun 09, 2015, 04:24 pm Last Edit: Jun 09, 2015, 04:29 pm by AWOL
Quote
But the motor is diffenetly not doing what i want it to do
Well, you're the one with the hardware and a view of the debug output.

Code: [Select]
  if (photocellReadingLevel  == '3') {             // if it's light
    if (photocellReadingLevel != '2') {             // if it's not twilight
      if (photocellReadingLevel != '1') {

If a variable is known to have the value '3', you can say with 100% certainty that it doesn't have the value '2' - there's no need to test it.

clausgudum


clausgudum

Well it pretty much works  :)  :)  :)
But for some reason the in the void "doReadPhotoCell ()" does not delay the light readings! the point was that the light should be mesured every 10 minutes, and then if it gets dark it should run the "doCoopDoor()" until the door was closed. Now it run the loop continuously, and the motor goes tick tick tick evry time the loop is run (dont really now why), and it would be better if it only "tick" every 10 min...

Code: [Select]
// photocell reading delay
unsigned long lastPhotocellReadingTime = 0;
unsigned long photocellReadingDelay = 6000000;   // 10 minutes


Code: [Select]
void doReadPhotoCell() { // function to be called repeatedly - per coopPhotoCellTimer set in setup

  photocellReading = analogRead(photocellPin);

  if ((unsigned long)(millis() - lastPhotocellReadingTime) >= photocellReadingDelay) {
    lastPhotocellReadingTime = millis();
  }
}


can you see if there is a problem with it?

AWOL

Quote
But for some reason the in the void "doReadPhotoCell ()" does not delay the light readings!
It delays them by the execution time of all the functions called from "loop()".
Other than that, it reads the LDR every time you call it.

If that's not what you want, you need to move the analogRead inside the conditional statement following the "if"

clausgudum

eeehhh, ok. Im not sure I understand, sorry.

What I would like the program to do:
every 10. minut the light is being meassured. Then if the light has changed it should close/open the door, and the door brakes when the reedswitch closes.

As the program is now,  the light is measured continuously, the door open and closes correct (but has a continuously ticken). problem with the continous light measure is that the door would open and close a few times when the light is close to the light threshold.

If i replace the "doReadPhotoCell()" with a delay (10 minutes) instead. The problem here is that when the motor is runing, and pulling the hatch, the reed switces are only active every 10 minutes and by then the door has passed the reedswitch...

you help is much appreciated


AWOL

Code: [Select]
void doReadPhotoCell() { // function to be called repeatedly - per coopPhotoCellTimer set in setup

  photocellReading = analogRead(photocellPin);

  if ((unsigned long)(millis() - lastPhotocellReadingTime) >= photocellReadingDelay) {
    lastPhotocellReadingTime = millis();
  }
}

Every time you call "doReadPhotoCell" (which is every time through "loop()" ) you take an LDR reading.

Code: [Select]
void doReadPhotoCell() { // function to be called repeatedly - per coopPhotoCellTimer set in setup
  if ((unsigned long)(millis() - lastPhotocellReadingTime) >= photocellReadingDelay) {
    lastPhotocellReadingTime = millis();
    photocellReading = analogRead(photocellPin);
  }
}

Only takes a reading every " photocellReadingDelay" milliseconds.

clausgudum

I get it. That is exactly what i want. But its not working. it reads the light contiously  >:(


What's the differens between doing this, and a delay (10min) in the loop - seems like its the same thing?

Code: [Select]
#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 = 6000000;   // 10 minutes

//**************************************** setup *****************************************

void setup (void) {

  Serial.begin(9600);

  // 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


}

// ************************************** 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 <= 300) {
    photocellReadingLevel = '1';
    Serial.print(" Photocel Reading Level:");
    Serial.println(" - Dark");
  }  else if (photocellReading  >= 301 && photocellReading <= 400) {
    photocellReadingLevel = '2';
    Serial.print(" Photocel Reading Level:");
    Serial.println(" - Twilight");
  }  else if (photocellReading  >= 401 ) {
    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
      motors.setM1Speed(400);                    // enable motor, full speed 0 --> -400
    if (bottomSwitchPinVal == 1) {                         // if bottom reed switch circuit is closed
              motors.setM1Speed(0);                         //brake motor down from Negative speed -400 --> 0
    }
    Serial.print(" Coop Door Closed - no danger");
  }



// open the coop door (motor dir open = postive speed)
void openCoopDoorMotorB() {
      motors.setM1Speed(400);         // enable motor, full speed
    if (topSwitchPinVal == 1) {                       // if top reed switch circuit is closed
              motors.setM1Speed(0);                        //brakes motor down from positive speed 400 --> 0
        // Serial.print(" Coop Door open - danger!");
      }
    }
 

void doCoopDoor() {


  if (photocellReadingLevel  == '1') {              // if it's dark
    debounceTopReedSwitch();                    // read and debounce the switches
    debounceBottomReedSwitch();
    closeCoopDoorMotorB();                      // close the door
  }

if (photocellReadingLevel  == '3') {             // if it's light
  debounceTopReedSwitch();                    // read and debounce the switches
  debounceBottomReedSwitch();
  openCoopDoorMotorB();                       // Open the door
}
}



// ************************************** the loop **************************************

void loop() {
  doReadPhotoCell();
  readPhotoCell();
  doCoopDoor();
}

AWOL

#13
Jun 09, 2015, 09:04 pm Last Edit: Jun 09, 2015, 09:06 pm by AWOL
 Your doReadPhotoCell is exactly as it was before.

readPhotoCell also gets called for a reading every time through loop() too.

Stop a while, and think

gpop1

photocellReading is being updated in 2 places. Highlight it in the code "photocellReading" and use edit, find and it will show you all the places its used. I don't think you want to do it twice especially as you only want to do it once every 10 mins


Code: [Select]
  if ((unsigned long)(millis() - lastPhotocellReadingTime) >= photocellReadingDelay) {
   
    //im going to do something ever 10 mins here......i wonder what?

    lastPhotocellReadingTime = millis();
  }







Go Up