Project in progress

Chicken Coop Automation © GPL3+

Automating a chicken coop with sensors and actors, using an Arduino MKR1000 and the Blynk internet dashboard.

  • 6,522 views
  • 10 comments
  • 19 respects

Components and supplies

Abx00004 iso both
Arduino MKR1000
×1
CHIHAI DC Motor - 12V 200rpm Encoder with Mounting Bracket
×1
Geekcreit L298N Dual H Bridge Stepper Motor Driver Board For Arduino
×1
Adafruit industries ada161 image 75px
Photo resistor
×1
10167 01
DHT22 Temperature Sensor
×1

Apps and online services

About this project

Introduction

To protect our new chickens from the different predators, an automatic door is needed. We had a look on the available solutions on the market, but none could meet our requirements:

  • Remote monitoring and control by using an app
  • Possibility to add additional sensors and actors to measure temperature or buzzer alert
  • Not too expensive

It would be way more fun to build it myself, so this is the start of my first microcontroller project.

Concept

A simple aluminium plate with guide rails will serve as the door. It is attached to a DC motor by using nylon wire. The DC motor includes a gearbox, resulting in 200 rpm on 12V DC. The used motor has a hall sensor encoder built in. To keep the door in the "up" position, it is not needed to engage the motor. Resulting power consumption will therefore be very low.

The control module I used is the Arduino MKR1000. It has WiFi built in and plenty of I/O. I have installed a WiFi Access Point in my garden shed, so WiFi reception is perfect within my chicken coop.

After booting or restarting the Arduino, the first step will be to "calibrate" the encoder values for its up and down positions. The app will ask to give the Up command or to confirm the door is already in the Up position. Once done, the encoder value is set to zero.

For the next step, the app will ask to give the Close command and Close confirmation. The encoder value at that moment will be stored in a variable. From now on, we can control the door between a zero encoder value and closed encoder value.

To control the door automatically, I've used a cheap photoresistor. Threshold value for daylight and sunset are preset within the Blynk dashboard as well as the operating mode: manual or automatic.

The DHT22 temperature & humidity sensor is only used to monitor both values.

Issues

1. The solution is not working very reliably. After some days, the door movement or sensor reading stops working. Browsing on the internet showed more people are having the same problem with the MKR1000 in combination with a web service - it is to be analysed if this can be solved.

*UPDATE V1*

New code includes a connection validation to Blynk. Only when the connection is in place, blynk.run will be executed. If the connection is down, it will try to reconnect first.

Data exchange to Blynk has been reduced to a 1 minute interval for slow changing values like Temperature, lux, humidity, etc. The encoder (= fast changing) will send it's value every second in case it has changed (=door is moving). If the door is standing still, it'll also send each minute to make sure the Supergraph in Blynk correctly displays historical values. Setup data is configured in PULL mode and will only be refreshed every 10s when the app is open on your smartphone.

==>> With those corrections, the setup is running for 3 weeks without a single interruption in functionality. I measured 4 reconnects with Blynk, with no impact on it's reliability.

Future improvements

1. Install magnetic reed switches to serve as a reliable positioning measurement and to generate position alarms in case the door will not reach the requested position in time.

2. IR camera to be able to monitor if all chicken have entered in the coop before the door closes. Maybe also to keep an eye on the egg nest or to monitor the outside at night.

3. Motion sensor including buzzer or strobo light to scare away predators who are too close to the chicken coop.

Code

Chicken Coop CodeArduino
/* Code developed by BMic on 19 March 2018
 * Used to connect with Blynk IOT service and to control a chicken coop: 
 * - Door control based on encoder value
 * - Environmental monitoring: Temperature, Humidity and light
*/

#include "DHT.h"
#include <SPI.h>
#include <WiFi101.h>
#include <BlynkSimpleMKR1000.h>


//========================================================== //
//============== IO & Variables definition ================= //
//========================================================== //

#define encoderPinA 0
#define encoderPinB 1
#define O_MotorDriverOut1 7
#define O_MotorDriverOut2 8

#define I_LightSensor A0

#define DHTPIN 9
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

float hum;  //Stores humidity value
float temp; //Stores temperature value

int LightValue = 0;
int deltaLight = 0;
int deltaDark = 0;

volatile int encoderPos = 0;
int encoderClosePos = 0;

//--- Used for sequential programming steps during initialize procedure ---
int step = 0;

//--- The different states of the system ---
enum states {INITIALIZE, DOOR_ERROR, DOOR_IS_OPEN, CLOSING_DOOR, DOOR_IS_CLOSED, OPENING_DOOR};
String OldState;

states state;

//========================================================== //
//=========== Blynk connection with Read/Write ============== //
//========================================================== //
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxxxxxx";

// Your WiFi credentials.
// Set password to "" for open networks.
char ssid[] = "WiFi-SSID";
char pass[] = "password";

//========================================================== //
//============== Initial setup at Startup ================= //
//========================================================== //

BlynkTimer timer;

void setup() 
{
  
//--- initialize digital pin LED_BUILTIN as an output ---
  pinMode(O_MotorDriverOut1, OUTPUT);
  pinMode(O_MotorDriverOut2, OUTPUT);
  pinMode(encoderPinA, INPUT_PULLUP);
  pinMode(encoderPinB, INPUT_PULLUP);
  
 state = INITIALIZE;

  attachInterrupt(0, doEncoder, CHANGE);

  dht.begin();
  timer.setInterval(5000L, dhtTimerEvent);

  Blynk.begin(auth, ssid, pass);
  timer.setInterval(1000L, BlynkTimerEvent);
}

int ThresHoldGettingDark = 25;
  BLYNK_WRITE(V21)
{
  ThresHoldGettingDark = param.asInt();
}

int ThresHoldGettingLight = 650;
  BLYNK_WRITE(V22)
{
  ThresHoldGettingLight = param.asInt();
}

void BlynkTimerEvent()
{
  Blynk.virtualWrite(V2, encoderPos);
}

void dhtTimerEvent()
{
  hum = dht.readHumidity();
  temp= dht.readTemperature();
  Blynk.virtualWrite(V3, temp); 
  Blynk.virtualWrite(V4, hum);

  LightValue = analogRead(I_LightSensor);
  deltaLight = ThresHoldGettingLight - LightValue;
  deltaDark = ThresHoldGettingDark - LightValue;
  Blynk.virtualWrite(V1, LightValue);
  Blynk.virtualWrite(V11, deltaLight);
  Blynk.virtualWrite(V12, deltaDark);
}

int buttonOpenValue;
  BLYNK_WRITE(V7)
{
  buttonOpenValue = param.asInt();
}

int buttonCloseValue;
  BLYNK_WRITE(V8)
{
  buttonCloseValue = param.asInt();
}

int switchOpenValue;
  BLYNK_WRITE(V9)
{
  switchOpenValue = param.asInt();
}

int switchCloseValue;
  BLYNK_WRITE(V10)
{
  switchCloseValue = param.asInt();
}

int operatingModeValue = 0;
  BLYNK_WRITE(V20)
{
  operatingModeValue = param.asInt();
}

//========================================================== //
//============== Finite State Machine Loop ================= //
//========================================================== //
void loop() 
{ 

  Blynk.run(); 
  timer.run(); 
 
  switch (state)
  {
    case INITIALIZE:
      Initializing();
      break;

    case DOOR_IS_OPEN: 
      StopDoorMotor();
      CheckDownButton(); 
      CheckGettingDark();
      ChangeState("Door is OPEN");
    break;

    case CLOSING_DOOR:
      ClosingDoor(); 
      CheckCloseSwitch();
      CheckEncoderCloseValue();
      ChangeState("Closing door");
    break;   

    case DOOR_IS_CLOSED:
      StopDoorMotor();
      CheckUpButton(); 
      CheckGettingLight();
      ChangeState("Door is CLOSED");
    break; 

    case OPENING_DOOR:
      OpeningDoor();
      CheckOpenSwitch();
      CheckEncoderOpenValue();
      ChangeState("Opening door");
    break; 

    case DOOR_ERROR:
      ChangeState("Door Error");
    break;
  }


}

//========================================================== //
//============== Finite State - Functions ================= //
//========================================================== //

// --------------- Initializing Function ---------------
void Initializing() //Calibrate Encoder values for Open & Closed position

{
  switch(step)
  {   
    case 0:
      Blynk.virtualWrite(V6, "Give Open Command");
      if(buttonOpenValue == HIGH)
      {
        OpeningDoor();
        step = 1;
      }
      else if(switchOpenValue == HIGH)
      {
        StopDoorMotor();
        encoderPos = 0;
        step = 2;  
      }
      break;

    case 1:
      Blynk.virtualWrite(V6, "Opening - Stop when Open");
      if(switchOpenValue == HIGH)
      {
        StopDoorMotor();
        encoderPos = 0;
        step = 2;         
      }
      break;

    case 2:
      Blynk.virtualWrite(V6, "Give Close Command");
      if(buttonCloseValue == HIGH)
      {
        ClosingDoor();
        step = 3;
      }
      break;

    case 3:
      Blynk.virtualWrite(V6, "Closing - Stop when Closed");
      if(switchCloseValue == HIGH)
        {
          StopDoorMotor();
          encoderClosePos = encoderPos;
          state = DOOR_IS_CLOSED;         
        }
        break;
    }
    
}

// --------------- MOTOR Functions ---------------
void StopDoorMotor()
{
  digitalWrite(O_MotorDriverOut1, LOW);
  digitalWrite(O_MotorDriverOut2, LOW);
}

void ClosingDoor()
{
 digitalWrite(O_MotorDriverOut1, HIGH);
 digitalWrite(O_MotorDriverOut2, LOW);
}

void OpeningDoor()
{
 digitalWrite(O_MotorDriverOut1, LOW);
 digitalWrite(O_MotorDriverOut2, HIGH);
}

// --------------- Input Buttons ---------------
void CheckDownButton()
{
  if(buttonCloseValue == HIGH) // Virtual value from Blynk
  {
    state = CLOSING_DOOR;
  }  
}

void CheckUpButton()
{
  if(buttonOpenValue == HIGH) // Virtual value from Blynk
  {
    state = OPENING_DOOR;
  }
}

// --------------- Input Switches ---------------
void CheckCloseSwitch()
{
  if(switchCloseValue == HIGH) // Virtual value from Blynk
    {
      state = DOOR_IS_CLOSED;
    }
}

void CheckOpenSwitch()
{
  if(switchOpenValue == HIGH) // Virtual value from Blynk
  {
    state = DOOR_IS_OPEN;
  }
}

void CheckEncoderCloseValue()
{
  if(encoderPos >= encoderClosePos)
  {
    StopDoorMotor();
    state = DOOR_IS_CLOSED;    
  }
}

void CheckEncoderOpenValue()
{
  if(encoderPos <= 0)
  {
    StopDoorMotor();
    state = DOOR_IS_OPEN;    
  }
}

// --------------- Light Sensor ---------------
void CheckGettingDark()
{
  if(operatingModeValue && LightValue < ThresHoldGettingDark)
  {
    state = CLOSING_DOOR;
  }
}

void CheckGettingLight()
{
  if(operatingModeValue && LightValue > ThresHoldGettingLight)
  {
    state = OPENING_DOOR;
  }
}

// --------------- Status String ---------------
void ChangeState(String Status)
{
  if(OldState != Status)
  {
    Blynk.virtualWrite(V6, Status);
    OldState = Status;
  }
}

//========================================================== //
//=========== Interrupts - Detect fast changes ============== //
//========================================================== //
void doEncoder()
{
  if(digitalRead(encoderPinA) == digitalRead(encoderPinB))
  {
    encoderPos++;
  }
  else 
  {
    encoderPos--;
  }
}
Chicken Coop Code - V1Arduino
- Including Blynk reconnect logic
- Reduced data exchange interval
/* Code developed by BMic on 21 May 2018
 * Used to connect with Blynk IOT service and to control a chicken coop: 
 * - Door control based on encoder value
 * - Environmental monitoring: Temperature, Humidity and light
 * 
 * Change V1:
 * - Decrease amount of values sent to Blynk only upon Change or every minute for historical values
 * - Split data exchanges in Pull and Push mode
 * - Include input button for Open/Close commands and Reed position switches 
 * - Reconnection logic to Blynk in case it's down
 * 
*/
#define BLYNK_PRINT Serial
//#define BLYNK_DEBUG        // Optional, this enables more detailed prints

#include "DHT.h"
#include <SPI.h>
#include <WiFi101.h>
#include <BlynkSimpleMKR1000.h>

//========================================================== //
//============== IO & Variables definition ================= //
//========================================================== //

//--- Digital inputs ---//
#define encoderPinA 0            // Encoder input Channel A
#define encoderPinB 1            // Encoder input Channel A
#define I_CloseDoorSwitch 2      // Reed switch for Closed position
#define I_OpenDoorSwitch 3       // Reed switch for Open position
#define I_CloseDoorButton 4      // Button to send Close command
#define I_OpenDoorButton 5       // Button to send Open command
#define O_MotorDriverOut1 7      // Motor Output to Close the Door
#define O_MotorDriverOut2 8      // Motor Output to Open the Door

//--- Analog inputs ---//
#define I_LightSensor A0         // Analog input to measure Photo resistor 0 - 1023

//--- DHT Sensor input ---//
#define DHTPIN 9
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

float hum;              //Stores humidity value
float temp;             //Stores temperature value

//--- Light sensor ---//
int LightValue = 0;                   // Actual analog input measurement
int deltaLight = 0;                   // Difference between Light threshold and actual value 
int deltaLightOld = 0;                // Previous value to trigger a value change
int deltaDark = 0;                    // Difference between Dark threshold and actual value
int deltaDarkOld = 0;                 // Previous value to trigger a value change
int ThresHoldGettingDark = 25;        // Treshold value to indicate it's getting Dark and door should close
int ThresHoldGettingLight = 650;      // Treshold value to indicate it's getting Light and door should open

//--- Encoder input ---//
volatile int encoderPos = 0;          // Volatile int should be used for interrupt values
int encoderClosePos = 0;              // Variable to store the encoder value for Closed position
int encoderPosOld = 0;                // Previous value to trigger a value change

//--- Blynk command variables ---/
int buttonOpenValue;                  // Virtual Button to send Open command from Blynk
int buttonCloseValue;                 // Virtual Button to send Close command from Blynk
int switchOpenValue;                  // Virtual Button to send Open position from Blynk in case no reed switch is used
int switchCloseValue;                 // Virtual Button to send Close position from Blynk in case no reed switch is used
int operatingModeValue;               // Set mode to work in automatic mode using Photo resistor or manual operation

//--- Used for sequential programming steps during initialize calibration procedure ---
int step = 0;           // Squencer in void Initializing()

//--- The different states of the system ---
enum states {INITIALIZE, DOOR_ERROR, DOOR_IS_OPEN, CLOSING_DOOR, DOOR_IS_CLOSED, OPENING_DOOR};
String OldState;

//--- Holds the initial state of the system ---
states state;

//========================================================== //
//=========== Blynk connection with Read/Write ============== //
//========================================================== //
// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "xxxxxxxxxxxxxxxxx";

// Your WiFi credentials.
// Set password to "" for open networks.
int StatusWifi = WL_IDLE_STATUS; // the Wifi radio's status
char ssid[] = "WiFi-SSID";
char pass[] = "Password";

int DisconnectCount = 0;    // Count number of disconnects
int ReCnctFlag;             // Reconnection Flag
int ReCnctCount = 0;        // Reconnection counter

//========================================================== //
//============== Initial setup at Startup ================= //
//========================================================== //

BlynkTimer timer;           // Start Timer based on SimpleTimer supporting to schedule 16 timers

void EncoderTimerEvent()    // Fast timer of 1 second to Push values to Blynk
{ 
  //--- Encoder ---//
  if(encoderPosOld != encoderPos){ // Check if encoder value has changed. If yes, send to Blynk.
  Blynk.virtualWrite(V2, encoderPos);
  encoderPosOld = encoderPos;
  Serial.print("Previous encoder position was: ");
  Serial.println(encoderPosOld);
  Serial.print("Actual encoder position is: ");
  Serial.println(encoderPos);
  }
}
  
void BlynkTimerEvent()    // Slow timer of 1 minute to Push values to Blynk
{
  //--- DHT22 ---//
  hum = dht.readHumidity();
  temp= dht.readTemperature();
  Blynk.virtualWrite(V3, temp); 
  Blynk.virtualWrite(V4, hum);

  //--- LUX ---//
  LightValue = analogRead(I_LightSensor);
  Blynk.virtualWrite(V1, LightValue);

  //--- Encoder ---//
  Blynk.virtualWrite(V2, encoderPos); // Only upon change (EncoderTimerEvent) messes up the graph in Blynk

  //--- Reconnect counter ---//
  Blynk.virtualWrite(V0, ReCnctCount);
}

// Pull requests from Blynk --> Only Pull when app is open since we don't need those as historical values!!
// Light Treshold -> Frequency is set in Blynk app and will only work when app is active in foreground!!

  BLYNK_READ(V11){                      // When Blynk requests a new value, calculate value and write back
    deltaLight = ThresHoldGettingLight - LightValue;
    Blynk.virtualWrite(V11, deltaLight);
  }

  BLYNK_READ(V12){                      // When Blynk requests a new value, calculate value and write back
  deltaDark = ThresHoldGettingDark - LightValue;
  Blynk.virtualWrite(V12, deltaDark);
  }
  
//--- Command's from Blynk to MKR1000 ---//
//--- These functions will be called every time a blynk Widget value is changed ---//

  BLYNK_WRITE(V21)
{
  ThresHoldGettingDark = param.asInt();
}

  BLYNK_WRITE(V22)
{
  ThresHoldGettingLight = param.asInt();
}

  BLYNK_WRITE(V7)
{
  buttonOpenValue = param.asInt();
}

  BLYNK_WRITE(V8)
{
  buttonCloseValue = param.asInt();
}

  BLYNK_WRITE(V9)
{
  switchOpenValue = param.asInt();
}

  BLYNK_WRITE(V10)
{
  switchCloseValue = param.asInt();
}

  BLYNK_WRITE(V20)
{
  operatingModeValue = param.asInt();
}

//========================================================== //
//================== Initial Setup LOOP ==================== //
//========================================================== //

void setup() 
{
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  Serial.println();

    //Check for the presence of the shield:
  /**************************************************************************************/
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    /*Don't continue:*/
    while (true);
  }
  /**************************************************************************************/
  
//--- initialize digital pin LED_BUILTIN as an output ---
  pinMode(I_CloseDoorSwitch, INPUT_PULLUP);
  pinMode(I_OpenDoorSwitch, INPUT_PULLUP);
  pinMode(I_CloseDoorButton, INPUT_PULLUP);
  pinMode(I_OpenDoorButton, INPUT_PULLUP); 
  pinMode(O_MotorDriverOut1, OUTPUT);
  pinMode(O_MotorDriverOut2, OUTPUT);
  pinMode(encoderPinA, INPUT_PULLUP);
  pinMode(encoderPinB, INPUT_PULLUP);
  
 state = INITIALIZE;

  attachInterrupt(0, doEncoder, CHANGE);    // Use Interrupt to count reliable every encoder input

  Blynk.begin(auth, ssid, pass);
  dht.begin();
  
  timer.setInterval(1000L, EncoderTimerEvent);    // One second update timer for Blynk
  timer.setInterval(60000L, BlynkTimerEvent);     // One minute update timer for Blynk

}

  BLYNK_CONNECTED() {
    Serial.println("Connected");
    ReCnctCount = 0;
}


//========================================================== //
//========== Finite State Machine - Main LOOP ============== //
//========================================================== //
void loop() 
{ 

  timer.run();                                    // Starts Blynk Timer

// Reconnect routine tried from: https://community.blynk.cc/t/mega-esp-will-freeze-if-there-is-a-connection-problem/25124/2
// Not sure if this is actually needed or even working
if (Blynk.connected()) {
  Blynk.run();                                    // Starts Blynk connection
}
else if (ReCnctFlag == 0) {
  ReCnctFlag = 1;                                 // Set reconnection Flag
  Serial.println("Starting reconnection timer in 30 seconds...");
  timer.setTimeout(30000L, []() {                 // Lambda Reconnection Timer Function
      ReCnctFlag = 0;                             // Reset reconnection Flag
      ReCnctCount++;                              // Increment reconnection Counter
      Serial.print("Attempting reconnection #");
      Serial.println(ReCnctCount);
      Blynk.connect();                            // Try to reconnect to the server
    });
}

// --- Sequencer logic to track the State of the door and specific monitor events ---//
  switch (state)
  {
    case INITIALIZE:
      Initializing();
      break;

    case DOOR_IS_OPEN: 
      StopDoorMotor();
      CheckDownButton(); 
      CheckGettingDark();
      ChangeState("Door is OPEN");
    break;

    case CLOSING_DOOR:
      ClosingDoor(); 
      CheckCloseSwitch();
      CheckEncoderCloseValue();
      ChangeState("Closing door");
    break;   

    case DOOR_IS_CLOSED:
      StopDoorMotor();
      CheckUpButton(); 
      CheckGettingLight();
      ChangeState("Door is CLOSED");
    break; 

    case OPENING_DOOR:
      OpeningDoor();
      CheckOpenSwitch();
      CheckEncoderOpenValue();
      ChangeState("Opening door");
    break; 

    case DOOR_ERROR:
      ChangeState("Door Error");
    break;
  }
}

//--- Not sure if the previous routine within the Main LOOP is needed or not, so I use both for now ---//
BLYNK_DISCONNECTED()
{
  Serial.println("Blynk is disconnected!");

  if(Blynk.connected()!=true)
  {
    DisconnectCount++;
    Serial.println("Blynk not conected counter = ");
    Serial.println(DisconnectCount);
    Blynk.connect();
  }
}

//========================================================== //
//============== Finite State - Functions ================= //
//========================================================== //

// --------------- Initializing Function ---------------
void Initializing()

/* Still to Do:
 *  1. Record Time to Close
 *  2. Save the time in a variable and use it during Opening/Closing
 *  3. If time > preset value and encoder value is not reached -> ERROR
 *  4. When error, retry to open/close 2..3..?? times and then return critical error 
*/
/* Initializing Function:
 *  - After rebooting or resetting Arduino, first step will be to calibrate open/close position based on encoder value
 *  case 0: Sequencer will wait for your Open command to open the door or skip the step if the door is already in the Open position
 *  case 1: Door will open until Open switch is triggered or Virtual Open position is confirmed and EncoderPos value is set to 0
 *  case 2: Sequencer will wait for your Close command to close the door
 *  case 3: Door will close until Close switch is triggered or Virtual Open position is confirmed and encoderClosePos value is set
 */

{
  switch(step)
  {   
    case 0:
      ChangeState("Give Open Command");
      if(buttonOpenValue == HIGH or digitalRead(I_OpenDoorButton) == LOW)
      {
        OpeningDoor();
        step = 1;
      }
      else if(switchOpenValue == HIGH or digitalRead(I_OpenDoorSwitch) == LOW)
      {
        StopDoorMotor();
        encoderPos = 0;
        step = 2;  
      }
      break;

    case 1:
      ChangeState("Opening - Stop when Open");
      if(switchOpenValue == HIGH or digitalRead(I_OpenDoorSwitch) == LOW)
      {
        StopDoorMotor();
        encoderPos = 0;
        step = 2;         
      }
      break;

    case 2:
      ChangeState("Give Close Command");
      if(buttonCloseValue == HIGH or digitalRead(I_CloseDoorButton) == LOW)
      {
        ClosingDoor();
        step = 3;
      }
      break;

    case 3:
      ChangeState("Closing - Stop when Closed");
      if(switchCloseValue == HIGH or digitalRead(I_CloseDoorSwitch) == LOW)
        {
          StopDoorMotor();
          encoderClosePos = encoderPos;
          state = DOOR_IS_CLOSED;         
        }
        break;
    }
    
}

// --------------- MOTOR Functions --------------- //
void StopDoorMotor()
{
  digitalWrite(O_MotorDriverOut1, LOW);
  digitalWrite(O_MotorDriverOut2, LOW);
}

void ClosingDoor()
{
 digitalWrite(O_MotorDriverOut1, HIGH);
 digitalWrite(O_MotorDriverOut2, LOW);
}

void OpeningDoor()
{
 digitalWrite(O_MotorDriverOut1, LOW);
 digitalWrite(O_MotorDriverOut2, HIGH);
}

// --------------- Open/Close command Buttons --------------- //
void CheckDownButton()
{
  if(buttonCloseValue == HIGH or digitalRead(I_CloseDoorButton) == LOW) // Virtual value from Blynk or input button
  {
    state = CLOSING_DOOR;
  }  
}

void CheckUpButton()
{
  if(buttonOpenValue == HIGH or digitalRead(I_OpenDoorButton) == LOW) // Virtual value from Blynk or input button
  {
    state = OPENING_DOOR;
  }
}

// --------------- Open/Close Input Switches --------------- //
void CheckCloseSwitch()
{
  if(switchCloseValue == HIGH or digitalRead(I_CloseDoorSwitch) == LOW) // Virtual value from Blynk or input switch
    {
      state = DOOR_IS_CLOSED;
    }
}

void CheckOpenSwitch()
{
  if(switchOpenValue == HIGH or digitalRead(I_OpenDoorSwitch) == LOW) // Virtual value from Blynk or input switch
  {
    state = DOOR_IS_OPEN;
  }
}

// --- Stop Closing Door if encoder value >= Closed value registered during Initializing loop --- //
void CheckEncoderCloseValue()
{
  if(encoderPos >= encoderClosePos)
  {
    StopDoorMotor();
    state = DOOR_IS_CLOSED;    
  }
}

// --- Stop Opening Door if encoder value <= 0 which is calibrated during Initializing loop --- //
void CheckEncoderOpenValue()
{
  if(encoderPos <= 0)
  {
    StopDoorMotor();
    state = DOOR_IS_OPEN;    
  }
}

// --------------- Light Sensor --------------- //
void CheckGettingDark()
{
  if(operatingModeValue && LightValue < ThresHoldGettingDark)
  {
    state = CLOSING_DOOR;
  }
}

void CheckGettingLight()
{
  if(operatingModeValue && LightValue > ThresHoldGettingLight)
  {
    state = OPENING_DOOR;
  }
}

// --------------- Status String --------------- //
void ChangeState(String Status)
{
  if(OldState != Status)
  {
    Blynk.virtualWrite(V6, Status);     // Only push to Blynk if value is changed 
    OldState = Status;
  }
}

//========================================================== //
//=========== Interrupts - Detect fast changes ============== //
//========================================================== //
void doEncoder()
{
  if(digitalRead(encoderPinA) == digitalRead(encoderPinB))
  {
    encoderPos++;
  }
  else 
  {
    encoderPos--;
  }
}

Schematics

kippendeur_Ndx0y55bgl.fzz
kippendeur_Ndx0y55bgl.fzz
2018-04-29_14_40_35-kippendeur_OpOH7Fj2Gg.png
2018 04 29 14 40 35 kippendeur opoh7fj2gg

Comments

Similar projects you might like

Arduino Atari Adaptor

Project tutorial by Dante Roumega

  • 7,546 views
  • 6 comments
  • 23 respects

Arduino Pendulum Physics Lab

Project tutorial by Paul Kassebaum

  • 1,147 views
  • 0 comments
  • 3 respects

Generating Audio with an Arduino and a Resistor Ladder DAC

Project showcase by 3 developers

  • 2,724 views
  • 5 comments
  • 7 respects

Automated Plant Watering System

Project in progress by Ammar Shahid

  • 439 views
  • 0 comments
  • 2 respects

Humidity Measuring Molecule

Project showcase by KatjaNiggl

  • 1,460 views
  • 4 comments
  • 15 respects
Add projectSign up / Login