Automatické zatváranie kurníku pre sliepky

Nedaří se vám s projektem a nenašli jste vhodné místo, kde se zeptat? Napište sem.
Pravidla fóra
Tohle subfórum je určeno pro konzultaci ucelených nápadů, popřípadě řešení komplexnějších projektů, které opravdu není možné rozdělit na menší části.
Většinu problémů jde rozdělit na menší a ptát se na ně v konkrétních subfórech.
Odpovědět
Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

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

Příspěvek od pavel1tu » 02 kvě 2020, 21:05

Dadasys píše:
02 kvě 2020, 20:10
Celý kód je o několik příspěvků výš. Napájí se 12V ten můstek a z něj je 5V výstup do arduina. Zapojení kdyžtak nakreslím. D

Odesláno z mého Lenovo P2a42 pomocí Tapatalk
No a o tom píši, a ne jedinej,
v setup() doplň , nikde to tam nevidím

Kód: Vybrat vše

  //Nastavení STOP pro motor
      digitalWrite(CloseDoorPin, LOW);
      digitalWrite(OpenDoorPin, LOW);
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Dadasys
Příspěvky: 18
Registrován: 17 dub 2020, 14:52
Reputation: 0

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

Příspěvek od Dadasys » 02 kvě 2020, 21:26

Ano, přesně to jsem tam doplnil, ale efekt to nemá..

Kód: Vybrat vše

// darkthreshold 20 
// daythreshold = 400

// Define pins & variables

const int EnMotorPin = 9;    // enable motor  - pin 9  PWM
const int CloseDoorPin = 8;  // direction close motor - pin 8
const int OpenDoorPin = 7;   // direction open motor  - pin 7
const int photocellPin = A0; // photocell connected to analog 0

const long eventTime_1_LDR = 2000; // 2 vteřin
unsigned long previousTime_1 = 0;

int photocellVal;            // analog reading of the photocel

bool daylight = true;        // daylight status
int darkthreshold = 20;
int daythreshold = 350;      

int systemState = 0;
int SPEED = 220;

int bottomSwitchPin = 2;  // Reed switches top and bottom of coop door
int topSwitchPin = 4;

bool topSwitchState; // true if door is up
bool bottomSwitchState; // true if door is down

void setup() {

  Serial.begin(9600);
  pinMode(bottomSwitchPin, INPUT);
  pinMode(topSwitchPin, INPUT);
  pinMode(EnMotorPin, OUTPUT);
  pinMode(CloseDoorPin, OUTPUT);
  pinMode(OpenDoorPin, OUTPUT);

      digitalWrite(CloseDoorPin, LOW);
      digitalWrite(OpenDoorPin, LOW);
     
  }

void loop() {

  systemState = 0;

  unsigned long currentTime = millis();
  if ( currentTime - previousTime_1 >= eventTime_1_LDR) 
    
    {
        photocellVal = analogRead(photocellPin); // read inputs
        
        previousTime_1 = currentTime;
    }

    if (photocellVal > daythreshold)

   {
    daylight = true;
   }
   if (photocellVal < darkthreshold)
    {
    daylight = false;
    }
  
  topSwitchState = digitalRead(topSwitchPin);
  bottomSwitchState = digitalRead(bottomSwitchPin);
  
  //  read system status
  if (daylight == true && topSwitchState == true)
  {
    systemState = 0;   // motor stop
  }
  if (daylight == true && topSwitchState == false)
  {
    systemState = 1;  // drive door up
  }
  if (daylight == false && bottomSwitchState == true)
  {
    systemState = 0;    // motor stop
  }
  if (daylight == false && bottomSwitchState == false)
  {
    systemState = 2;  // drive door down
  }
  DispVals();
  switch (systemState) {
    case 0: // motor stop
      digitalWrite(CloseDoorPin, LOW);
      digitalWrite(OpenDoorPin, LOW);
      analogWrite(EnMotorPin, 0);
      break;
    case 1:  //drive door up
      digitalWrite(CloseDoorPin, LOW);
      digitalWrite(OpenDoorPin, HIGH);
      analogWrite(EnMotorPin, SPEED);
      break;
    case 2:  // drive door down
      digitalWrite(CloseDoorPin, HIGH);
      digitalWrite(OpenDoorPin, LOW);
      analogWrite(EnMotorPin, SPEED);
      break;
    default:
      digitalWrite(CloseDoorPin, LOW);
      digitalWrite(OpenDoorPin, LOW);
      analogWrite(EnMotorPin, 0);
      break;
    
      }
}

void DispVals()
{
  Serial.print("topSW ");
  Serial.print(topSwitchState);
  Serial.print("\t");
  Serial.print("botSW ");
  Serial.print(bottomSwitchState);
  Serial.print("\t");
  Serial.print("PhotoVal ");
  Serial.print(photocellVal);
  Serial.print("\t");
  Serial.print("daylight ");
  Serial.print(daylight);
  Serial.print("\t");
  Serial.print("systemState ");
  Serial.print(systemState);
  Serial.print("\t");
  if (systemState == 0)
  {
    Serial.println("\t door stopped");
  }
  if (systemState == 1)
  {
    Serial.println("\t door driving up");
  }
  if (systemState == 2)
  {
    Serial.println("\t door driving down");
  }
}

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

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

Příspěvek od pavel1tu » 02 kvě 2020, 22:50

Celý program je takový paskvil, možná jednou bude funkční, ale ...
- proč se na začátku loop pořád nahazuje systemstate do "0" ? - já to smazal
- proč se v IF nahazuje systemstate a pak zase v CASE se od toho jen nahazují výstupy ? Udělal bych to rovnou v tom IF - nechal jsem jak máš ty
- digitalRead podle Arduino reference by se měl ukládat do proměnné typu int a ne bool opravil jsem
intl topSwitchState = 0; // true if door is up
intl bottomSwitchState = 0; // true if door is down
(nevím jestli to může mít vliv, ale držel bych se Arduino reference a je to tak ve všech příkladech)
- s tím upravit i podmínky a "true" a "false" upravil na "0" a "1"
- DispVals(); probíhá každý cyklus Arduina - no to je asi mazec ve výpisu, ale budiž
- do setup doplnit photocellVal = analogRead(photocellPin); // read inputs

Celé bych to učesal, vstupy a výstupy jsou deklarované na dvou místech, jednou jako konstatnty, pak zase jako proměnné, je to asi funkční ale na přehledu to nepřidá, osobně bych pro věci které se mohou měnit nadrátováním definoval pomocí #define

když nahraji tvůj program,blbne to - hlavní příčina je že hodnota světla je 0 (noc) a dveře máš asi otevřené, tak se začnou zavírat a během 2s až se vyčte analog jaké je světlo se začnou zase otvírat
Po mých úpravách je to OK ale nějak pečlivě jsem to netestoval

PS: osobně bych to psal jinak, ale snad se to takhle rozeběhne
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

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

Příspěvek od kiRRow » 03 kvě 2020, 10:51

Zaujalo mě to stím int a digitalRead. Já osobně datový typ volím dle očekávané velikosti informace, které tam budou. Když čtu digitalRead, očekávám 0 nebo 1 (nic jiného ani nemůže být) a logicky proto zvolím datový typ boolean.
I když v příkladech na arduino.cc používají int, osobně si myslím, že spíš jen z důvodu aby nepletli nováčkům hlavy s tím, že jsou ještě jiné datové typy. Si vemte ... kde v jakém example příkladě jste viděli #define ... čísla pinů jsou zapsaná jako int proměná. A proč ? Protože to je zatím netřeba vysvětlovat a fungovat to bude tak i tak.

Dadasys
Příspěvky: 18
Registrován: 17 dub 2020, 14:52
Reputation: 0

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

Příspěvek od Dadasys » 03 kvě 2020, 11:41

Pánové moc vám děkuji za odpovědi. Koukám, že kód pro Arduino není zcela exaktní záležitost. Každopádně jsem vzal rady od Vás obou a přimíchal je do svého kurníku a voila, funguje to jak chci. (zatím.. :lol: ) Motor po zapnutí, resp. výpadku proudu stojí, případně pokud je pootevřeno, dojede podle světelných podmínek. Koncáky jsou aktivní hned, takže se nic nezašmodrchá. Hurá a ještě jednou díky.

Kód: Vybrat vše

// Define pins & variables

const int EnMotorPin = 9;    // enable motor  - pin 9  PWM
const int CloseDoorPin = 8;  // direction close motor - pin 8
const int OpenDoorPin = 7;   // direction open motor  - pin 7
const int photocellPin = A0; // photocell connected to analog 0

const long eventTime_1_LDR = 20000; // 20 vteřin
unsigned long previousTime_1 = 0;

int photocellVal;            // analog reading of the photocel

bool daylight = true;        // daylight status
int darkthreshold = 20;
int daythreshold = 350;      

int systemState = 0;
int SPEED = 220;

int bottomSwitchPin = 2;  // Reed switches top and bottom of coop door
int topSwitchPin = 4;

bool topSwitchState; // true if door is up
bool bottomSwitchState; // true if door is down

void setup() {

  Serial.begin(9600);
  pinMode(bottomSwitchPin, INPUT);
  pinMode(topSwitchPin, INPUT);
  pinMode(EnMotorPin, OUTPUT);
  pinMode(CloseDoorPin, OUTPUT);
  pinMode(OpenDoorPin, OUTPUT);
  photocellVal = analogRead(photocellPin); // díky Pavel1TU
  digitalWrite(CloseDoorPin, LOW); // díky kiRRow
  digitalWrite(OpenDoorPin, LOW);
  analogWrite(EnMotorPin, 0);
   
}

void loop() {

  unsigned long currentTime = millis();
  if ( currentTime - previousTime_1 >= eventTime_1_LDR) 
    
    {
        photocellVal = analogRead(photocellPin); // read inputs
        previousTime_1 = currentTime;
    }
    if (photocellVal > daythreshold)
   {
    daylight = true;
   }
   if (photocellVal < darkthreshold)
    {
    daylight = false;
    }
  
  topSwitchState = digitalRead(topSwitchPin);
  bottomSwitchState = digitalRead(bottomSwitchPin);
  
  //  read system status
  
  if (daylight == true && topSwitchState == true)
  {
    systemState = 0;   // motor stop
  }
  if (daylight == true && topSwitchState == false)
  {
    systemState = 1;  // drive door up
  }
  if (daylight == false && bottomSwitchState == true)
  {
    systemState = 0;    // motor stop
  }
  if (daylight == false && bottomSwitchState == false)
  {
    systemState = 2;  // drive door down
  }
  DispVals();
  switch (systemState) {
    case 0: // motor stop
      digitalWrite(CloseDoorPin, LOW);
      digitalWrite(OpenDoorPin, LOW);
      analogWrite(EnMotorPin, 0);
      break;
    case 1:  //drive door up
      digitalWrite(CloseDoorPin, LOW);
      digitalWrite(OpenDoorPin, HIGH);
      analogWrite(EnMotorPin, SPEED);
      break;
    case 2:  // drive door down
      digitalWrite(CloseDoorPin, HIGH);
      digitalWrite(OpenDoorPin, LOW);
      analogWrite(EnMotorPin, SPEED);
      break;
    default:
      digitalWrite(CloseDoorPin, LOW);
      digitalWrite(OpenDoorPin, LOW);
      analogWrite(EnMotorPin, 0);
      break;    
      }
}

void DispVals()
{
  Serial.print("topSW ");
  Serial.print(topSwitchState);
  Serial.print("\t");
  Serial.print("botSW ");
  Serial.print(bottomSwitchState);
  Serial.print("\t");
  Serial.print("PhotoVal ");
  Serial.print(photocellVal);
  Serial.print("\t");
  Serial.print("daylight ");
  Serial.print(daylight);
  Serial.print("\t");
  Serial.print("systemState ");
  Serial.print(systemState);
  Serial.print("\t");
  if (systemState == 0)
  {
    Serial.println("\t door stopped");
  }
  if (systemState == 1)
  {
    Serial.println("\t door driving up");
  }
  if (systemState == 2)
  {
    Serial.println("\t door driving down");
  }
}

sklipky
Příspěvky: 14
Registrován: 01 srp 2018, 07:55
Reputation: 0

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

Příspěvek od sklipky » 03 kvě 2020, 15:45

Taky řešim otevírání a zavírání slepic. napsal jsem následující kód. Protože neumím interupty a celkově neprogramuju, tak je to napsáno takto jednoduše. Prosím o radu, zda musím nastavit piny pro koncáky jako PULLUP a nebo ne. Plánuju použít tyto koncáky

Obrázek

Kód: Vybrat vše

// defines pins numbers
// DS3231:  SDA A4
//          SCL A5
// A4988  step D5
// A4988  direction D6
// Koncák otevřeno D7
// Koncák zavřeno D8

#include <Wire.h>
#include "RTClib.h"
 
DS3231 rtc;
char daysOfTheWeek[7][12] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday","Sunday"};

const int stepPin = 5; 
const int dirPin = 6;
const int koncakOtevreno=7;
const int koncakZavreno=8;


int casOtevreniHod=6;
int casOtevreniMin=30;
int casZavreniHod=19;
int casZavreniMin=0;

int casOtevreni=casOtevreniHod*60+casOtevreniMin;
int casZavreni=casZavreniHod*60+casZavreniMin;

int aktualniCas;


void otevri(){
	Serial.println("oteviram dvere");
	digitalWrite(dirPin,HIGH); // Enables the motor to move in a particular direction
  // Makes 200 pulses for making one full cycle rotation, M5 závit má stoupání 0,8mm/otáčku, potřebuji 250 otáček = 250*200= 50000 pulzů
  for(int x = 0; x < 50000; x++) {
    digitalWrite(stepPin,HIGH); 
    delayMicroseconds(500); 
    digitalWrite(stepPin,LOW); 
    delayMicroseconds(500); 
  }
}

void zavri(){
  Serial.println("zaviram dvere");
digitalWrite(dirPin,LOW); //Changes the rotations direction
  // Makes 200 pulses for making one full cycle rotation
  for(int x = 0; x < 50000; x++) {
    digitalWrite(stepPin,HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin,LOW);
    delayMicroseconds(500);
  }
}
 
void setup() {

Serial.begin(9600);
delay(3000);
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
DS3231 rtc; // inicializace RTC z knihovny


pinMode(stepPin,OUTPUT); //Nastavení pinů pro krokový motor jako výstup
pinMode(dirPin,OUTPUT);
pinMode(koncakOtevreno, INPUT_PULLUP); 
pinMode(koncakZavreno, INPUT_PULLUP);
}


void loop() {
  DateTime now = rtc.now();
  aktualniCas=now.hour()*60+now.minute(); //převedení aktuálního čas z hodin a minut na pouze minuty
  
  if(aktualniCas>=casOtevreni && aktualniCas<=casZavreni)
  {
    if (digitalRead(koncakZavreno) == LOW)
      {
        otevri();
        delay(3000);
      }
    else
    {
    delay(3000);
    }
  }
  
  else if(aktualniCas>casZavreni || aktualniCas<casOtevreni)
 {
  if (digitalRead(koncakOtevreno) == LOW)
      {
        zavri();
        delay(3000);
      }
    else
    {
    delay(3000);
    }
}


delay(1000); // One second delay

}




Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

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

Příspěvek od pavel1tu » 03 kvě 2020, 16:22

kiRRow píše:
03 kvě 2020, 10:51
Zaujalo mě to stím int a digitalRead. Já osobně datový typ volím dle očekávané velikosti informace, které tam budou. Když čtu digitalRead, očekávám 0 nebo 1 (nic jiného ani nemůže být) a logicky proto zvolím datový typ boolean.
I když v příkladech na arduino.cc používají int, osobně si myslím, že spíš jen z důvodu aby nepletli nováčkům hlavy s tím, že jsou ještě jiné datové typy. Si vemte ... kde v jakém example příkladě jste viděli #define ... čísla pinů jsou zapsaná jako int proměná. A proč ? Protože to je zatím netřeba vysvětlovat a fungovat to bude tak i tak.
Já jsem programátor samouk - vycházím z "Reference" na arduino.cc - abych se přiznal, bool jsem u digitalRead nikdy nepoužil i když to evidentně jde.
Tak kdybych někde honil paměť, ušetřím ;)
#define na arduino.cc normálně je, podmínky pro kompilátor (#ifdef) ale i další fičurky bohužel ne.

Ale jak píše Dadasys - každý programuje jinak, každý má svuj styl. Styl netřeba lámat, ale je dobré začínající usměrnit k nějaké "štábní kultuře", aby byl program přehledný a lehce čitelný i pro jiné uživatele + psaní komentářů (co mají smysl).

PS: Já jsem mnohým na tomto foru vděčný jak za jejich čas, trpělivost, ale i zveřejněné projekty z kterých lze čerpat ...
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
pavel1tu
Příspěvky: 2054
Registrován: 26 říj 2017, 08:28
Reputation: 0
Bydliště: Trutnov
Kontaktovat uživatele:

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

Příspěvek od pavel1tu » 03 kvě 2020, 16:46

sklipky píše:
03 kvě 2020, 15:45
Taky řešim otevírání a zavírání slepic. napsal jsem následující kód. Protože neumím interupty a celkově neprogramuju, tak je to napsáno takto jednoduše. Prosím o radu, zda musím nastavit piny pro koncáky jako PULLUP a nebo ne. Plánuju použít tyto koncáky
Tyto koncáky (snad tyto) mám a pokud se chce brát že zmáčknutí je "aktivace", dávám tam PULLUP, protože ten "neguje" standartní funkci vstupu.
Tyto koncáky v rozepnutém stavu posílají +5V, při přepínání pořád +5V ale přes ten rezistor 10k (to je mžik), při sepnutí GND
Pak koresponduje stav vstupu "1" při sepnutém koncáku.

Když nedáš PULLUP, ničemu to nevadí, ale při sepnutém koncáku bude stav vstupu "0" - tedy obráceně.
Takže jen stačí přizpůsobit logiku tomu jak vstup přepneš - jestli s PULLUP nebo bez něj.

Jen doufám že jsem se do toho nezamotal a nenapsal to blbě, použil jsem je kdysi dávno i laserové řezačky.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
kiRRow
Příspěvky: 1151
Registrován: 07 kvě 2019, 07:03
Reputation: 0
Bydliště: Opava

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

Příspěvek od kiRRow » 03 kvě 2020, 18:16

PULL_UP nebo PULL_DOWN resistory jsou nutnost. Zabraňují tomu aby PIN při nesepnutém stavu takzvaně nevisel ve vzduchu ... jinak se pak chová jako anténa a pouhé přiblížení ruky může způsobit ruch, který procesor následně zpracuje jako 500x stisknuté tlačítko např.

sklipky
Příspěvky: 14
Registrován: 01 srp 2018, 07:55
Reputation: 0

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

Příspěvek od sklipky » 03 kvě 2020, 20:45

kiRRow píše:
03 kvě 2020, 18:16
PULL_UP nebo PULL_DOWN resistory jsou nutnost. Zabraňují tomu aby PIN při nesepnutém stavu takzvaně nevisel ve vzduchu ... jinak se pak chová jako anténa a pouhé přiblížení ruky může způsobit ruch, který procesor následně zpracuje jako 500x stisknuté tlačítko např.
Toho jsem si právě vědom, ale nejsem si jistej, zda je ten koncák sám od sebe vybaven pullupem a tím pádem bych nemusel aktivovat pullup integrovaný v arduino desce.

Pokud ten koncák není vybaven pullupem, tak bych musel vyvolat ten co je již zabudovaný v arduino desce.

Tady si právě nejsem jistý :?:

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 16 hostů