Stránka 1 z 7

Automatické zatváranie kurníku pre sliepky

Napsal: 10 úno 2019, 22:22
od lukas700602
Zdravím potreboval by som pomoc s programom pre automatické zatváranie a otváranie dverí pomocou motoru podla toho či je deň alebo noc a zároveň od vplyvu času , aby sa dvere neotvárali príliš skoro alebo naopak , príliš neskoro. Som stále začiatočník , takže za každú pomoc ďakujem.
Môj kód:

Kód: Vybrat vše

#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
// Convert normal decimal numbers to binary coded decimal
#define LIGHT 2 // define pin 2 for sensor
#define CW 7
#define CCW 8
byte decToBcd(byte val){
    return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val){
    return( (val/16*10) + (val%16) );
}
void setup(){
    Wire.begin();
    Serial.begin(9600);
    // set the initial time here:
    // DS3231 seconds, minutes, hours, day, date, month, year
    // setDS3231time(30,42,21,4,26,11,14);
    pinMode(LIGHT, INPUT_PULLUP);// define pin as Input  sensor
    pinMode(CW, OUTPUT);
    pinMode(CCW, OUTPUT);
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year){
    // sets time and date data to DS3231
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set next input to start at the seconds register
    Wire.write(decToBcd(second)); // set seconds
    Wire.write(decToBcd(minute)); // set minutes
    Wire.write(decToBcd(hour)); // set hours
    Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
    Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
    Wire.write(decToBcd(month)); // set month
    Wire.write(decToBcd(year)); // set year (0 to 99)
    Wire.endTransmission();
}
void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year){
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set DS3231 register pointer to 00h
    Wire.endTransmission();
    Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
    // request seven bytes of data from DS3231 starting from register 00h
    *second = bcdToDec(Wire.read() & 0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read() & 0x3f);
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());
}
void displayTime(){
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    // retrieve data from DS3231
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    // send it to the serial monitor
    Serial.print(hour, DEC);
    // convert the byte variable to a decimal number when displayed
    Serial.print(":");
    if (minute<10){
        Serial.print("0");
    }
    Serial.print(minute, DEC);
    Serial.print(":");
    if (second<10){
        Serial.print("0");
    }
    Serial.print(second, DEC);
    Serial.print(" ");
    Serial.print(dayOfMonth, DEC);
    Serial.print("/");
    Serial.print(month, DEC);
    Serial.print("/");
    Serial.print(year, DEC);
    Serial.print(" Day of week: ");
    switch(dayOfWeek){
        case 1:
            Serial.println("Sunday");
            break;
        case 2:
            Serial.println("Monday");
            break;
        case 3:
            Serial.println("Tuesday");
            break;
        case 4:
            Serial.println("Wednesday");
            break;
        case 5:
            Serial.println("Thursday");
            break;
        case 6:
            Serial.println("Friday");
            break;
        case 7:
            Serial.println("Saturday");
            break;
    }
}
void loop(){
    int L =digitalRead(LIGHT);// read the sensor
    int timestamp = hour * 60 + minute;
    
    displayTime(); // display the real-time clock data on the Serial Monitor,
    delay(1000); // every second

    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    readDS3232time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    
    if(timestamp >= 390 && timestamp < = 540)&&(L == 1){
      Serial.println(" DEN , Otvaram");
    digitalWrite(CW,HIGH);
    delay(5000);
    digitalWrite(CW,LOW);
    delay(5000); 
    }
    else if(timestamp >= 1200 && timestamp < = 1290)&&(L < 1){
      Serial.println("  === NOC , Zatvaram");
    digitalWrite(CCW,HIGH);
    delay(5000);
    digitalWrite(CCW,LOW);
    delay(5000);
    }
    delay(100);
}

Re: Automatické zatváranie kurníku pre sliepky

Napsal: 11 úno 2019, 07:11
od pavel1tu
S čím potřebuješ pomoc ?
NEChtělo by to napsat CO nefunguje ... ?

A kod se vkládá do

Kód: Vybrat vše

tohoto
je to pak přehlednější a jde nám lépe zkopírovat ...

Re: Automatické zatváranie kurníku pre sliepky

Napsal: 11 úno 2019, 07:36
od lukas700602
Mám problém so zápisom koncového kódu na načítanie hodín a minút do premennej a jej následné použitie pri ovládaní relé

Re: Automatické zatváranie kurníku pre sliepky

Napsal: 11 úno 2019, 15:29
od pavel1tu
Já to řeším po svém,
vyčtení času a rozhození na hodin, minuty atd. - využívám jen hodiny, minuty

Kód: Vybrat vše

Teď jsem si všimnul, máš jinou knihovnu na čas - tak si uptav to vyčítání dle tvé knihovny ...
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
pak využít ty proměnné hour a minute ?


toto je příklad z mého RTC - tvoji knihovnu nemám jak vyzkoušet

    DateTime datumCas = DS1307.now(); //zobrazení času
    hodin = datumCas.hour();          // vycti aktualni hodinu
    minut = datumCas.minute();          // vycti aktualni minutu
    rok = datumCas.year();
    mesic = datumCas.month();
    den = datumCas.day();
pak bych si někde deklaroval otevří, zavřít, aby se to při změnách nemuselo hledat v kodu
já sčítám 100*hodiny + minuty

Kód: Vybrat vše

word otevridvere = 1000;     // HH*100 + MIN toto je 10:00h
word zavridvere = 1800;     // HH*100 + MIN toto je 18:00h
pak by podminka byla

Kód: Vybrat vše

// otevreni - den
if(hodin*100 + minut >= otevridvere && hodin*100 + minut <= zavridvere)&&(L == 1)
// zavreni - noc
if(hodin*100 + minut <= otevridvere && hodin*100 + minut >= zavridvere)&&(L < 1)
jednodušeji to vysvětlit neumím

kdyžtak se ptej

PS: nejsem dobrý programátor, proto vše píši tak nějak "polopatě" abych tomu i za rok porozuměl ...

Re: Automatické zatváranie kurníku pre sliepky

Napsal: 11 úno 2019, 16:03
od lukas700602
Väčšinu som pochopil . Ale predsa by som sa rád spýtal na deklaráciu otvorenia a zatvorenia . Akým spôsobom deklarujem otvorenie a zatvorenie ?

Re: Automatické zatváranie kurníku pre sliepky

Napsal: 11 úno 2019, 16:18
od lukas700602
Takže skúsil som sa s tým popasovať nejako a tento kód som dostal :

Kód: Vybrat vše

void loop(){
    DateTime now = RTC.now();  //zobrazenie aktualneho casu
    hodin = now.hour();         //nacitanie aktualnej hodiny
    minut = now.minute();       //nacitanie aktualnej minuty
    rok = now.year();
    mesiac = now.month();
    den = now.day();
int otvorenie(){                        //deklaracia otvorenia 
    Serial.println(" DEN , Otvaram");
    digitalWrite(CW,HIGH);
    delay(5000);
    digitalWrite(CW,LOW);
    delay(5000); 
}
int zatvorenie(){                       //deklaracia zatvorenia
    Serial.println("  === NOC , Zatvaram");
    digitalWrite(CCW,HIGH);
    delay(5000);
    digitalWrite(CCW,LOW);
    delay(5000);
}

word otvorenie = 800;
word zatvorenie = 2200;


// otevreni - den
if(hodin*100 + minut >= otvorenie && hodin*100 + minut <= zatvorenie)&&(L == 1)
// zavreni - noc
if(hodin*100 + minut <= otvorenie && hodin*100 + minut >= zatvorenie)&&(L < 1)
    delay(100);
}
Snáď tam nie je žiadna chybička tentokrát. Ak áno , tak by si mi vedel poradiť ako ju odstrániť ? Ďakujem.

Re: Automatické zatváranie kurníku pre sliepky

Napsal: 11 úno 2019, 16:48
od pavel1tu
Pokusím se,
jen nemám na tu knihovnu RTC co používáš modul,nemám to jak vyzkoušet.

koukni na tento příklad,
dá se využít skoro celý,
jen na konci kdy vyčteš hodiny a minuty přidáš ty podmínky na otevření/zavření

dotaz - tvůj kod jsi někde našel, nebo vytvořil ?

Re: Automatické zatváranie kurníku pre sliepky

Napsal: 11 úno 2019, 17:11
od lukas700602
Tak zdravím znova , nakoniec som celý kód prekopal snáď k lepšiemu.
tu je:

Kód: Vybrat vše

#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
#define LIGHT 2 // define pin 2 for sensor
#define CW 7
#define CCW 8
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val){
    return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val){
    return( (val/16*10) + (val%16) );
}
void setup(){
    pinMode(LIGHT, INPUT_PULLUP);// define pin as Input  sensor
    pinMode(CW, OUTPUT);
    pinMode(CCW, OUTPUT);
    int L =digitalRead(LIGHT);
    Wire.begin();
    Serial.begin(9600);
    // set the initial time here:
    // DS3231 seconds, minutes, hours, day, date, month, year
    // setDS3231time(30,42,21,4,26,11,14);
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year){
    // sets time and date data to DS3231
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set next input to start at the seconds register
    Wire.write(decToBcd(second)); // set seconds
    Wire.write(decToBcd(minute)); // set minutes
    Wire.write(decToBcd(hour)); // set hours
    Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
    Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
    Wire.write(decToBcd(month)); // set month
    Wire.write(decToBcd(year)); // set year (0 to 99)
    Wire.endTransmission();
}
void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year){
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0); // set DS3231 register pointer to 00h
    Wire.endTransmission();
    Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
    // request seven bytes of data from DS3231 starting from register 00h
    *second = bcdToDec(Wire.read() & 0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read() & 0x3f);
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());
}
void displayTime(){
    byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
    // retrieve data from DS3231
    readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
    // send it to the serial monitor
    Serial.print(hour, DEC);
    // convert the byte variable to a decimal number when displayed
    Serial.print(":");
    if (minute<10){
        Serial.print("0");
    }
    Serial.print(minute, DEC);
    Serial.print(":");
    if (second<10){
        Serial.print("0");
    }
    Serial.print(second, DEC);
    Serial.print(" ");
    Serial.print(dayOfMonth, DEC);
    Serial.print("/");
    Serial.print(month, DEC);
    Serial.print("/");
    Serial.print(year, DEC);
    Serial.print(" Day of week: ");
    switch(dayOfWeek){
        case 1:
            Serial.println("Sunday");
            break;
        case 2:
            Serial.println("Monday");
            break;
        case 3:
            Serial.println("Tuesday");
            break;
        case 4:
            Serial.println("Wednesday");
            break;
        case 5:
            Serial.println("Thursday");
            break;
        case 6:
            Serial.println("Friday");
            break;
        case 7:
            Serial.println("Saturday");
            break;
    }
}

void loop()
{
int L =digitalRead(LIGHT);
displayTime(); // display the real-time clock data on the Serial Monitor,
delay(1000); // every second
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
char readDS3232time = (&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);

    
    
   
int otvorenie();
{                        //deklaracia otvorenia 
    Serial.println(" DEN , Otvaram");
    digitalWrite(CW,HIGH);
    delay(5000);
    digitalWrite(CW,LOW);
    delay(5000); 
    word otvorenie = 800;
    
}
int zatvorenie();
{                       //deklaracia zatvorenia
    Serial.println("  === NOC , Zatvaram");
    digitalWrite(CCW,HIGH);
    delay(5000);
    digitalWrite(CCW,LOW);
    delay(5000);
    word zatvorenie = 2200;
}
if((hour*100 + minute >= otvorenie && hour*100 + minute <= zatvorenie)&&(L == 1))
    delay(100);
if((hour*100 + minute <= otvorenie && hour*100 + minute >= zatvorenie)&&(L < 1))
    delay(100);
}
kód pre RTC som našiel , zvyšok vytvoril.

Re: Automatické zatváranie kurníku pre sliepky

Napsal: 11 úno 2019, 17:27
od pavel1tu
Pracovali jsme současně :-)

Využil jsem příkladu na internetu - prý funkčního

- doplnil jsme promenou stavu dveri aby se dokola neotvíraly a nezavíraly,
- doplnil jsem az dolu podprogram na podminku otevren-zavreni casy 10:00-18:00 jsou tam
- chybi ten senzor, dopln si ho

slo to zkompilovat, tak snad to bude OK
ale zda to bude fungovat ?

Vyzkoušej tvuj i muj a uvidíš, ten kod co jsem použil já je perfektně popsaný co kde dělá - tak jsem ho použil - a je z internetu

Kód: Vybrat vše


//------------------------------------------------------------------
// inicializace zakladnich knihoven
#include <Wire.h> // inport knihovny I2C
#define LIGHT 2 // define pin 2 for sensor
#define CW 7
#define CCW 8
//------------------------------------------------------------------
// promenne pro vyhledani adres hodinoveho modulu
byte error; // prommena pro zobrazeni chyby
int nDevices = 0; // promenna pro vyhledavani poctu zarizeni
//------------------------------------------------------------------
// promenne pro zobrazeni casu
#define DS3231_I2C_ADDRESS 0x68
byte second;
byte minute;
byte hour;
byte dayOfWeek;
byte dayOfMonth;
byte month;
byte year;
//------------------------------------------------------------------
// povoleni nahrani aktualniho casu
boolean adjustment_time = false;

//------------------------------------------------------------------
// pomocne promenne
 byte StavDveri;
//------------------------------------------------------------------
// Seznam podprogramu
void OtevritDvere();
//------------------------------------------------------------------
// spusteni programu
void setup() {
  Wire.begin(); // inicializace knihovny I2C
  Serial.begin(9600); // nastaveni rychlosti seriove komunikace
  //------------------------------------------------------------------
  // vyhledani adresy hodinoveho modulu
  Serial.println("Skenuji...");
  for (byte address = 0; address < 127; address++ ) { // prochazeni povolenych adres
    Wire.beginTransmission(address); // volani adresy
    error = Wire.endTransmission(); // ukonceni volani
    if (error == 0) { // kdyz je vracena hodnota false, zobrazi nalezenou adresu
      Serial.print("I2C zarizeni nalezeno na adrese 0x");
      if (address < 16) Serial.print("0");
      Serial.print(address, HEX);
      Serial.println("  !");
      nDevices++;
    }
    else if (error == 4) { // kdyz je vracena hodnota true, zobrazi chybu hledani
      Serial.print("Neznama chyba na adrese 0x");
      if (address < 16) Serial.print("0");
      Serial.println(address, HEX);
    }
  }
  // zobrazeni poctu nalezenych zarizeni
  if (nDevices == 0) Serial.println("Zadne zarizeni nenalezeno");
  else {
    Serial.print("Nalezeno ");
    Serial.print(nDevices);
    Serial.println(" I2C zarizeni.");
  }
  //------------------------------------------------------------------
  // nastaveni casu pri prvnim spusteni
  // DS3231 seconds, minutes, hours, day, date, month, year
  if (adjustment_time) setDS3231time(30, 42, 21, 4, 26, 11, 14);
}
//------------------------------------------------------------------
// hlavni smycka
void loop() {
  readDS3231time(); // precti cas a uloz promenne
  displayTime(); // zobraz aktualni cas,
  OtevritDvere(); //podprogram pro otevreni-zavreni dveri
  delay(5000); // pockej 5 vterin
}
//------------------------------------------------------------------
// ulozeni casu
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte dayOfMonth, byte month, byte year) { // uloz data do DS3231
  Wire.beginTransmission(DS3231_I2C_ADDRESS); // otevri komunikaci
  Wire.write(0); // nastav prvni hodnotu registru pred zapisem
  Wire.write(decToBcd(second)); // uloz vteriny
  Wire.write(decToBcd(minute)); // uloz minuty
  Wire.write(decToBcd(hour)); // uloz hodiny
  Wire.write(decToBcd(dayOfWeek)); // uloz den tydne (1=Nedele, 7=Sobota)
  Wire.write(decToBcd(dayOfMonth)); // uloz den mesice (1-31)
  Wire.write(decToBcd(month)); // uloz mesic
  Wire.write(decToBcd(year)); // uloz rok (0 to 99)
  Wire.endTransmission(); // ukonci komunikaci
}
//------------------------------------------------------------------
// cteni casu
void readDS3231time() {
  Wire.beginTransmission(DS3231_I2C_ADDRESS); // otevri komunikaci
  Wire.write(0); // nastav prvni hodnotu registru pred ctenim
  Wire.endTransmission(); // ukonci komunikaci
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // precti 7 bytu
  // dotaz na data z DS3231 zaciname v registru 00h
  second = bcdToDec(Wire.read() & 0x7f);
  minute = bcdToDec(Wire.read());
  hour = bcdToDec(Wire.read() & 0x3f);
  dayOfWeek = bcdToDec(Wire.read());
  dayOfMonth = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read());
  year = bcdToDec(Wire.read());
}
//------------------------------------------------------------------
// zobraz data z hodinoveho modulu
void displayTime() {
  Serial.print(hour, DEC);
  Serial.print(":");
  if (minute < 10) {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second < 10) {
    Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print("20");
  Serial.print(year, DEC);
  Serial.print(" Den tydne: ");
  switch (dayOfWeek) {
    case 1:
      Serial.println("Nedele");
      break;
    case 2:
      Serial.println("Pondeli");
      break;
    case 3:
      Serial.println("Utery");
      break;
    case 4:
      Serial.println("Streda");
      break;
    case 5:
      Serial.println("Ctvrtek");
      break;
    case 6:
      Serial.println("Patek");
      break;
    case 7:
      Serial.println("Sobota");
      break;
  }
}
//------------------------------------------------------------------
// prevod jednotek pro ulozeni dat do hodinoveho modulu
byte decToBcd(byte val) {
  return ((val / 10 * 16) + (val % 10));
}
//------------------------------------------------------------------
// prevod jednotek pro cteni dat z hodinoveho modulu
byte bcdToDec(byte val) {
  return ((val / 16 * 10) + (val % 16));
}
//------------------------------------------------------------------
// podprogram pro otevreni- zavreni dveri od 10:00 do 18:00
 void OtevritDvere() 
 {
 if(hour*100 + minute >= 1000 && hour*100 + minute <= 1800 && StavDveri==0){
     Serial.println(" DEN , Otvaram");
     digitalWrite(CW,HIGH);
     delay(5000);
     digitalWrite(CW,LOW);
     StavDveri=1; // nutno doplnit jinak se budou dvere dokola otvirat
     }
 if((hour*100 + minute <= 1000 || hour*100 + minute >= 1800) && StavDveri==1){
     Serial.println(" NOC , Zatvaram");
     digitalWrite(CCW,HIGH);
     delay(5000);
     digitalWrite(CCW,LOW);
     StavDveri=0; // nutno doplnit jinak se budou dvere dokola zavirat
     }
 }

Re: Automatické zatváranie kurníku pre sliepky

Napsal: 11 úno 2019, 17:36
od pavel1tu
- ještě jsem tam měl chybu pro zavirani - opraveno, melo tam být OR "||"
- pro nastaveni casu modulu musis tad poprve

Kód: Vybrat vše

// povoleni nahrani aktualniho casu
boolean adjustment_time = false;
na TRUE
a nastavit spravny cas a datum v

Kód: Vybrat vše

  // nastaveni casu pri prvnim spusteni
  // DS3231 seconds, minutes, hours, day, date, month, year
  if (adjustment_time) setDS3231time(30, 42, 21, 4, 26, 11, 14);
a nahrát

pak to opět vypnout na FALSE a zase nahrát
pokud má modul baterku, cas si udrží i po vypnutí

zlom vaz, uz nemam vice casu