Hello everybody,
I facing a issue on my projet for chickencoop automation
I want to make a chicken coop automation door like (https://www.hackster.io/BMic/chicken-coop-automation-c2d034)
Here you will find the picture of the projet. I can’t reach the good value for my DHT22 and I can’t find my Lightsensor value.
Thanks a lot,
• MKR1000 with DHT22
• Android version
• Blynk server or local server
• Blynk Library version
#define BLYNK_PRINT Serial
#define BLYNK_DEBUG
#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 2
#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[] = "fc64d94d462740dea99be9e65521efc5";
// Your WiFi credentials.
// Set password to "" for open networks.
int StatusWifi = WL_IDLE_STATUS; // the Wifi radio's status
char ssid[] = "xxx";
char pass[] = "xxx";
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--;
}
}