/* Steuerung fr motorisierte Hhnerklappe ber Lichtsensor
* Material:
* Arduino Uno mit Protyping Board
* Lichtsensor
* IR Receiver
* Fernbedienung
* 2 Relais
* 16x2 LCD
* 2 Endlagenschalter
* Real Time Clock
* Scheibewischermotor mit montierter Rolle
* Zustzliches 12V Netzteil
*/
/***************************
*
* ANLEITUNG FR DIE HHNERKLAPPE
*
* Im AUTO Modus ffnet die Klappe sich morgens um 9.00 und fhrt Abends bei Dunkelheit herunter.
* Im manuellen Modus kann die Klappe mit den Tasten <<< und >>> schrittweise bewegt werden, und bleibt in der Position.
*
* >| - Schaltet um zwischen AUTO Modus und manuellem Modus
* <<< - Fhrt im manuellen Modus die Klappe einen Schritt herunter
* >>> - Fhrt im manuellen Modus die Klappe einen Schritt hoch
* + - Schaltet die Hintergrundbeleuchtung ein
* - - Schaltet die Hintergrundbeleuchtung aus
*
* Achtung: Beim Umschalten von manuellem in AUTO-Modus muss die Klappe zuvor wieder in die richtige Position gebracht werden (tagsber auf, nachts unten).
*
*/
// Klappe & Motor
int statusKlappe = 2; // 1= down, 2 = up, d.h. der Initialstatus der Klappe ist oben,
// wenn das Gert einschaltet. Klappe sollte oben sein, oder
// manuell da hin gefahren werden
#define CW 8 // CW auf LOW fhrt die Klappe runter
#define CCW 9 // CCW auf LOW fhrt die Klappe hoch
#define lift 4000 // Manuelle Hebezeit in millisekunden (War mal auf kleine 500er
// Schritte eingestellt, aber mit den Endlagenschaltern ist das nicht mehr ntig
#define liftUp 4000 // Automatische Hebezeit
#define liftDown 3000 // Automatische Senkzeit
#define endDownPin 6
#define endUpPin 7
unsigned long motorCounter = millis();
// COM an 5V, NC an PIN & GND via 10KOhm = HIGH wenn Taster nicht gedrckt, LOW wenn gedrckt
// Zum Simulieren des nicht gedrckten Tasters drhte Kurzschlieen
// Buttons & Modes
int modeAuto = 1; // 0=Auto, 1= Manual
int button = 0; // Status der IR RC Knpfe
#define threshold 35 // Schwellenwert fr den Auto-Mode wird festgelegt.
#define unlockTime 8 // Die Automatik ffnet die Klappe nur, wenn Uhrzeit erreich ist
// Light Sensor
int sensorPin = A0;
int sensorValue = 0;
int sensorAvg1;
int sensorAvg2;
int sensorAvg3;
int sensorAvg;
unsigned long counterStart = millis();
int pass = 1;
// Remote
#include <IRremote.h>
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
// Display
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <LCD.h>
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);
// Clock
#include "RTClib.h"
RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char buffer[30];
/*---------------------------------------------------------------------------------------------------------*/
void setup() {
// Only for Testing: Remove for Production
// Serial.begin(9600);
// Display initial beschreiben
lcd.begin(16,2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print("L: ");
lcd.setCursor(0,1);
lcd.print("M:");
lcd.setCursor(2,1);
lcd.print("Mn");
lcd.setCursor(6,1);
lcd.print("D:");
lcd.setCursor(8,1);
lcd.print ("Mn");
// Remote einschalten
irrecv.enableIRIn();
// Motor und Endlagen PINs zuweisen
pinMode(CW, OUTPUT); //Set CW as an output//
pinMode(CCW, OUTPUT); //Set CCW as an output//
digitalWrite(CW, HIGH); //Motor stops//
digitalWrite(CCW, HIGH); //Motor stops//
pinMode(endDownPin, INPUT); // Endlagenschalter fr unten
pinMode(endUpPin, INPUT); // Endlagenschalterfr oben
// Initiate RTC
if (! rtc.begin()) {
lcd.setCursor(0,1);
lcd.print("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
lcd.setCursor(0,1);
lcd.print("RTC lost power!");
// following line sets the RTC to the date & time this sketch was compiled
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
// This line sets the RTC with an explicit date & time, for example to set
// rtc.adjust(DateTime(2020, 8, 1, 14, 30, 0));
}
// Uhr stellen
// rtc.adjust(DateTime(2020, 4, 20, 17, 18, 0));
// Uhr beim kompilieren stellen
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
DateTime now = rtc.now();
}
/* --------------------------------------------------------------------------------------*/
void loop() {
// Lesen des Lichtsensors und schreiben des Ergebnisses
sensorValue = analogRead(sensorPin);
lcd.setCursor(2,0);
sprintf(buffer,"%04d", sensorValue);
lcd.print(buffer);
// Display Clock
DateTime now = rtc.now();
lcd.setCursor(11,12);
sprintf(buffer,"%02d",now.hour());
lcd.print(buffer);
lcd.print(":");
sprintf(buffer,"%02d",now.minute());
lcd.print(buffer);
// Lesen und bersetzen der IR Fernbedienung
if (irrecv.decode(&results)) //Wenn ein IR-Signal erkannt wurde,
{
if (results.value == 16720605) { // Wenn der Schalter <<< gedrckt wurde
button = 1;
if (modeAuto == 1) { // uns der Modus "manuell" ist
motorCounter = millis(); // Motorzhler auf jetzt.
while ((millis()-motorCounter < lift) && (digitalRead(endDownPin) == HIGH)){ // Solange die Zeit "lift" nicht erreicht
digitalWrite(CW,LOW); // und der Endlagenschalter nicht gedrckt ist.
} // fhrt die Klappe runter
digitalWrite(CW, HIGH); // und schaltet wieder ab.
}
}
else if (results.value == 16712445) { // Wenn der Schalter >>> gedrckt wurde
button = 2;
// statusKlappe=0;
if (modeAuto == 1) { // uns der Modus "manuell" ist
motorCounter = millis();
while ((millis()-motorCounter < lift) && (digitalRead(endUpPin) == HIGH )){
digitalWrite(CCW,LOW);
}
digitalWrite(CCW, HIGH);
}
}
else if (results.value == 16761405) { // Wenn der "Modus" Knopf >|| gedrckt wurde schalte den Modus um
button = 3;
// statusKlappe=0;
if (modeAuto == 0) {
modeAuto= 1;
lcd.setCursor(2,1);
lcd.print("Mn ");
}
else if (modeAuto == 1) {
modeAuto=0;
lcd.setCursor(2,1);
lcd.print("Au ");
if (now.hour() < unlockTime) { // Wenn die unlockTime nicht erreicht ist, wird ein Sternchen angezeigt
lcd.setCursor(4,1);
lcd.print ("*");
}
if (statusKlappe == 1) {
lcd.setCursor(8,1);
lcd.print ("Dn");
}
else if (statusKlappe == 2) {
lcd.setCursor(8,1);
lcd.print ("Up ");
}
}
}
else if (results.value == 16769055) { // Knopf - schaltet Backlight ab
button = 4;
lcd.noBacklight();
}
else if (results.value == 16754775) { // Knopf + schaltet Backlight an
button = 5;
lcd.backlight();
}
else {
button =0;
}
irrecv.resume();
}
else
{
button =0;
}
// Drei Messdurchgnge werden durchgefhrt
if (millis() - counterStart >= 3000) {
counterStart = millis();
lcd.setCursor(12,0);
lcd.print("P:");
lcd.print (pass);
// sensorAvg[pass] = sensorValue; // Sensorwert wird in Array geschrieben
if (pass == 1) {
sensorAvg1 = sensorValue;
}
else if (pass == 2) {
sensorAvg2 = sensorValue;
}
else if (pass == 3) {
sensorAvg3 = sensorValue;
}
// Hochzhlen bis 3
if (pass < 3) {
pass++;
}
// Beim dritten Durchgang wird der Klappenstatus gesetzt.
else {
sensorAvg = (sensorAvg1 + sensorAvg2 + sensorAvg3)/3;
lcd.setCursor(7,0);
sprintf(buffer,"%04d", sensorAvg);
lcd.print(buffer);
// Wenn es dunkel ist und die Klappe oben, dann fhrt sie runter
if ((modeAuto == 0) && (sensorAvg < threshold) && (statusKlappe == 2)) {
statusKlappe=1;
motorCounter = millis(); // Motorzhler auf jetzt.
while ((millis()- motorCounter < liftDown) && (digitalRead(endDownPin) == HIGH )){ // Solange die Zeit "lift" nicht erreicht
digitalWrite(CW,LOW);
}
digitalWrite(CW, HIGH); // und schaltet wieder ab
}
// Wenn es vor Unlocktime ist und die Klappe oben, dann fhrt sie runter
else if ((modeAuto == 0) && (now.hour() < unlockTime) && (statusKlappe == 2) ) {
statusKlappe=1;
motorCounter = millis(); // Motorzhler auf jetzt.
while ((millis()-motorCounter < liftDown) && (digitalRead(endDownPin) == HIGH )){ // Solange die Zeit "lift" nicht erreicht
digitalWrite(CW,LOW);
}
digitalWrite(CW, HIGH);
}
// Wenn es hell ist und die Klappen unten und die Unlcktime erreicht, fhrt sie hoch
else if ((modeAuto == 0) && (sensorAvg >= threshold) && (statusKlappe == 1) && (now.hour() >= unlockTime)) {
statusKlappe=2;
motorCounter = millis(); // Motorzhler auf jetzt.
while ((millis()-motorCounter < liftUp) && (digitalRead(endUpPin) == HIGH )){ // Solange die Zeit "lift" nicht erreicht
digitalWrite(CCW,LOW); // Relais schaltet
}
digitalWrite(CCW, HIGH); // und schaltet wieder ab
}
pass =1;
}
}
// Status korrekt schreiben
if (modeAuto == 1) {
lcd.setCursor(8,1);
lcd.print ("Mn");
}
else if (statusKlappe == 1) {
lcd.setCursor(8,1);
lcd.print ("Dn");
}
else if (statusKlappe == 2) {
lcd.setCursor(8,1);
lcd.print ("Up");
}
}
Comments