Pomoc s kódem (zavlažování)-začátečník

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
Rudy
Příspěvky: 3
Registrován: 23 dub 2020, 10:30
Reputation: 0

Pomoc s kódem (zavlažování)-začátečník

Příspěvek od Rudy » 23 dub 2020, 10:47

Dobrý den,
potřeboval bych poradit. Jsem začátečník a nevím si rady s tím, jak naprogramovat zavlažování zahrady o třech větvích postřikovačů. Princip je takový, že Arduinem chci ovládat jak čerpadlo, tak elektroventily ve třech větvích. Čili budu mít celkem čtyři tlačítka. Dvě budou ovládat přes relátka čerpadlo start/stop a dvě tlačítka taky přes relátka celkem tři elektroventily. Má představa je, že příjdu, zapnu tlačítkem start čerpadlo a druhým tlačítkem start program, kdy se v určitých intervalech budou spínat jednotlivé větve (každá cca 3min+/-).Toto spínání bude zacyklované do 10 cyklů. Může ale nastat situace, kdy budu chtít ručně tyto cykly přerušit tlačítkem stop. Pokud používám delay(), tak přerušení není možné (cyklus musí dojet). Snažil jsem to nějak vymyslet přes millis() ale popravdě moc si nevím rady. Můžete mi někdo prosím pomoci? Nebo aspoň navést, jak toto vyřešit? Přemýšlel jsem, že bych mohl arduino pokaždé resetovat, ale to mi příjde trochu barbarské, raději bych to vyřešil elegantněji.

Děkuji za odpověď

Posílám program:


int cerp = 13;
int vetev1 = 12;
int vetev2 = 11;
int vetev3 = 10;
int starttlaccerp = 9;
int stoptlaccerp = 8;
int starttlacprog = 7;
int stoptlacprog = 6;
int poc;


void setup() {
pinMode(cerp, OUTPUT);
pinMode(vetev1, OUTPUT);
pinMode(vetev2, OUTPUT);
pinMode(vetev3, OUTPUT);
pinMode(starttlaccerp, INPUT_PULLUP);
pinMode(stoptlaccerp, INPUT_PULLUP);
pinMode(starttlacprog, INPUT_PULLUP);
pinMode(stoptlacprog, INPUT_PULLUP);

}

void loop() {


if (digitalRead(starttlaccerp) == 0 && digitalRead(stoptlaccerp) == 1){
digitalWrite(cerp, HIGH);
}
if (digitalRead(starttlaccerp) == 1 && digitalRead(stoptlaccerp) == 0){
digitalWrite(cerp, LOW);
}
if (digitalRead(starttlacprog) == 1 && digitalRead(stoptlacprog) == 0){
digitalWrite(vetev1, LOW);
digitalWrite(vetev2, LOW);
digitalWrite(vetev3, LOW);
}

if(digitalRead(starttlacprog) == 0 && digitalRead(stoptlacprog) == 1){
while(poc<10){
digitalWrite(vetev1, HIGH);
digitalWrite(vetev2, LOW);
digitalWrite(vetev3, LOW);
delay(1000);
digitalWrite(vetev1, LOW);
digitalWrite(vetev2, HIGH);
digitalWrite(vetev3, LOW);
delay(1000);
digitalWrite(vetev1, LOW);
digitalWrite(vetev2, LOW);
digitalWrite(vetev3, HIGH);
delay(1000);
poc++;
}
}
}

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

Re: Pomoc s kódem (zavlažování)-začátečník

Příspěvek od pavel1tu » 23 dub 2020, 13:32

Vystřeleno od boku:
#DEBUG když je nezakomentovany, cyklus je v sekundách
#DEBUG když je zakomentovaný - cyklus je v minutách

- netestoval jsem rele, nemám je, testoval jsem jen vystup na serial a jen s nastavením 3 cykly

Kód: Vybrat vše

13:29:20.938 -> PROGRAM - RESTART
13:29:29.705 -> CERPADLO - START
13:29:38.191 -> PROGRAM - START
13:29:38.191 ->      - VETEV 1 - cyklus1
13:29:41.233 ->      - VETEV 2
13:29:44.213 ->      - VETEV 3
13:29:47.224 ->      - VETEV 1 - cyklus2
13:29:50.188 ->      - VETEV 2
13:29:53.183 ->      - VETEV 3
13:29:56.209 ->      - VETEV 1 - cyklus3
13:29:59.189 ->      - VETEV 2
13:30:02.231 ->      - VETEV 3
13:30:02.231 -> PROGRAM UKONCEN AUTOMATICKY

Kód: Vybrat vše


#define DEBUG              // zakomentovat PRO PROVOZ
#define cerp 13            // vystup na rele pro cerpadlo
#define vetev1 12          // vystup na rele pro ventil 1
#define vetev2 11          // vystup na rele pro ventil 2
#define vetev3 10          // vystup na rele pro ventil 3
#define starttlaccerp 9    // tlacitko cerpadlo START
#define stoptlaccerp 8     // tlacitko cerpadlo STOP
#define starttlacprog 7    // tlacitko program START
#define stoptlacprog 6     // tlacitko program STOP
#define cas 3                // cas - minuty zavlazovani jedne vetve
#define cyklus 10          // pocet cyklu zavlazovani v programu
#ifdef DEBUG
#define konstanta 1000    // prevod minut na sekundy
#else
#define konstanta 60000    // prevod minut na milisekundy
#endif

// pomocne promenne
byte cykl = 0, ventil = 0;
unsigned long startMillis;   //start cyklu zavlazovani
unsigned long currentMillis;
bool cerpadlo,program; 


void setup() {
   Serial.begin(115200);  //pro ladění
   pinMode(cerp, OUTPUT);
   pinMode(vetev1, OUTPUT);
   pinMode(vetev2, OUTPUT);
   pinMode(vetev3, OUTPUT);
   pinMode(starttlaccerp, INPUT_PULLUP);
   pinMode(stoptlaccerp, INPUT_PULLUP);
   pinMode(starttlacprog, INPUT_PULLUP);
   pinMode(stoptlacprog, INPUT_PULLUP);
   Serial.println("PROGRAM - RESTART");
}

void loop() {

// START cerpadla
if (digitalRead(starttlaccerp) == 0 && digitalRead(stoptlaccerp) == 1 && cerpadlo == 0){
   digitalWrite(cerp, HIGH);
   cerpadlo = 1;
   Serial.println("CERPADLO - START");
   }

// STOP cerpadla
if (digitalRead(starttlaccerp) == 1 && digitalRead(stoptlaccerp) == 0 && cerpadlo == 1){
   digitalWrite(cerp, LOW);
   digitalWrite(vetev1, LOW);
   digitalWrite(vetev2, LOW);
   digitalWrite(vetev3, LOW);   
   cerpadlo = 0;
   program = 0;
   Serial.println("CERPADLO - STOP");
   }

// STOP program   
if (digitalRead(starttlacprog) == 1 && digitalRead(stoptlacprog) == 0 && program == 1 ){
   program =0;
   digitalWrite(vetev1, LOW);
   digitalWrite(vetev2, LOW);
   digitalWrite(vetev3, LOW);
   Serial.println("PROGRAM - STOP");
}

// START program
if(digitalRead(starttlacprog) == 0 && digitalRead(stoptlacprog) == 1 && program == 0 && cerpadlo == 1){
  program = 1;
  cykl = 1;
  ventil = 1;
  startMillis = millis();
  digitalWrite(vetev1, HIGH);
  digitalWrite(vetev2, LOW);
  digitalWrite(vetev3, LOW);
  Serial.println("PROGRAM - START");
  Serial.print("     - VETEV 1");
  Serial.print(" - cyklus");
  Serial.println(cykl);
  }

// vlastni program - psano polopate abych tomu rozumel ja i vy i deti na krouzku
if(program == 1) {
  currentMillis = millis(); //nacteni aktualniho casu

  // pokud ventil 1 zavlažuje dele než X minut sepnu ventil 2
  if(ventil == 1 && (currentMillis - startMillis) >= cas * konstanta) {
     startMillis = millis();
     ventil = 2;
     digitalWrite(vetev1, LOW);
     digitalWrite(vetev2, HIGH);
     digitalWrite(vetev3, LOW);
     Serial.println("     - VETEV 2");
  }

  // pokud ventil 2 zavlažuje dele než X minut sepnu ventil 3
  if(ventil == 2 && (currentMillis - startMillis) >= cas * konstanta) {
     startMillis = millis();
     ventil = 3;
     digitalWrite(vetev1, LOW);
     digitalWrite(vetev2, LOW);
     digitalWrite(vetev3, HIGH);
     Serial.println("     - VETEV 3");
  }   

  // pokud ventil 3 zavlažuje dele než X minut sepnu ventil 1, pricti cyklus
  if(ventil == 3 && (currentMillis - startMillis) >= cas * konstanta) {
     startMillis = millis();
     ventil = 1;
     cykl++;
     digitalWrite(vetev1, HIGH);
     digitalWrite(vetev2, LOW);
     digitalWrite(vetev3, LOW);
     Serial.print("     - VETEV 1");
     Serial.print(" - cyklus");
     Serial.println(cykl);
  }
  
  if (cykl == cyklus && ventil == 3) {
    program = 0;
    Serial.println("PROGRAM UKONCEN AUTOMATICKY");
  }
 }
}

UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Rudy
Příspěvky: 3
Registrován: 23 dub 2020, 10:30
Reputation: 0

Re: Pomoc s kódem (zavlažování)-začátečník

Příspěvek od Rudy » 23 dub 2020, 14:09

Děkuji za pomoc, trochu se tím budu muset prokousat, jak jsem psal, jsem začátečník. A nechci jen Váš kód bez mozku okopírovat, chci ho i pochopit.
Ještě jednou moc děkuji. Dám vědět jak to dopadlo :)

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

Re: Pomoc s kódem (zavlažování)-začátečník

Příspěvek od pavel1tu » 23 dub 2020, 14:19

Děti to zaujalo, už mám asi 7 verzí včetně využití funkcí.
Nejstarší pracují na "dálkovém" ovládání ...

Odhalena chyba v ukončení programu zalévání ... vetev 3 v posledním cyklu neodčasuje
Tak opraveno - DEBUG je zapnutý, takže to časuje po sekundách, když se zakomentuje po minutách
Testováno i bez DEBUG 10 cyklů po 1 minutě

Kód: Vybrat vše


#define DEBUG              // zakomentovat PRO PROVOZ
#define cerp 13            // vystup na rele pro cerpadlo
#define vetev1 12          // vystup na rele pro ventil 1
#define vetev2 11          // vystup na rele pro ventil 2
#define vetev3 10          // vystup na rele pro ventil 3
#define starttlaccerp 9    // tlacitko cerpadlo START
#define stoptlaccerp 8     // tlacitko cerpadlo STOP
#define starttlacprog 7    // tlacitko program START
#define stoptlacprog 6     // tlacitko program STOP
#define cas 3              // cas - minuty zavlazovani jedne vetve
#define cyklus 10          // pocet cyklu zavlazovani v programu
#ifdef DEBUG
#define konstanta 1000     // prevod minut na sekundy
#else
#define konstanta 60000    // prevod minut na milisekundy
#endif

// pomocne promenne
byte cykl = 0, ventil = 0;
unsigned long startMillis;   //start cyklu zavlazovani
unsigned long currentMillis;
bool cerpadlo,program; 


void setup() {
   Serial.begin(115200);  //pro ladění
   pinMode(cerp, OUTPUT);
   pinMode(vetev1, OUTPUT);
   pinMode(vetev2, OUTPUT);
   pinMode(vetev3, OUTPUT);
   pinMode(starttlaccerp, INPUT_PULLUP);
   pinMode(stoptlaccerp, INPUT_PULLUP);
   pinMode(starttlacprog, INPUT_PULLUP);
   pinMode(stoptlacprog, INPUT_PULLUP);
   Serial.println("PROGRAM - RESTART");
}

void loop() {

// START cerpadla
if (digitalRead(starttlaccerp) == 0 && digitalRead(stoptlaccerp) == 1 && cerpadlo == 0){
   digitalWrite(cerp, HIGH);
   cerpadlo = 1;
   Serial.println("CERPADLO - START");
   }

// STOP cerpadla
if (digitalRead(starttlaccerp) == 1 && digitalRead(stoptlaccerp) == 0 && cerpadlo == 1){
   digitalWrite(cerp, LOW);
   digitalWrite(vetev1, LOW);
   digitalWrite(vetev2, LOW);
   digitalWrite(vetev3, LOW);   
   cerpadlo = 0;
   program = 0;
   Serial.println("CERPADLO - STOP");
   }

// STOP program   
if (digitalRead(starttlacprog) == 1 && digitalRead(stoptlacprog) == 0 && program == 1 ){
   program =0;
   digitalWrite(vetev1, LOW);
   digitalWrite(vetev2, LOW);
   digitalWrite(vetev3, LOW);
   Serial.println("PROGRAM - STOP");
}

// START program
if(digitalRead(starttlacprog) == 0 && digitalRead(stoptlacprog) == 1 && program == 0 && cerpadlo == 1){
  program = 1;
  cykl = 1;
  ventil = 1;
  startMillis = millis();
  digitalWrite(vetev1, HIGH);
  digitalWrite(vetev2, LOW);
  digitalWrite(vetev3, LOW);
  Serial.println("PROGRAM - START");
  Serial.print("     - VETEV 1");
  Serial.print(" - cyklus");
  Serial.println(cykl);
  }

// vlastni program - psano polopate abych tomu rozumel ja i vy i deti na krouzku
if(program == 1) {
  currentMillis = millis(); //nacteni aktualniho casu

  // pokud ventil 1 zavlažuje dele než X minut sepnu ventil 2
  if(ventil == 1 && (currentMillis - startMillis) >= cas * konstanta) {
     startMillis = millis();
     ventil = 2;
     digitalWrite(vetev1, LOW);
     digitalWrite(vetev2, HIGH);
     digitalWrite(vetev3, LOW);
     Serial.println("     - VETEV 2");
  }

  // pokud ventil 2 zavlažuje dele než X minut sepnu ventil 3
  if(ventil == 2 && (currentMillis - startMillis) >= cas * konstanta) {
     startMillis = millis();
     ventil = 3;
     digitalWrite(vetev1, LOW);
     digitalWrite(vetev2, LOW);
     digitalWrite(vetev3, HIGH);
     Serial.println("     - VETEV 3");
  }   

  // pokud ventil 3 zavlažuje dele než X minut sepnu ventil 1, pricti cyklus
  if(ventil == 3 && (currentMillis - startMillis) >= cas * konstanta && cykl < cyklus) {
     startMillis = millis();
     ventil = 1;
     cykl++;
     digitalWrite(vetev1, HIGH);
     digitalWrite(vetev2, LOW);
     digitalWrite(vetev3, LOW);
     Serial.print("     - VETEV 1");
     Serial.print(" - cyklus");
     Serial.println(cykl);
  }
  
  if (ventil == 3 && (currentMillis - startMillis) >= cas * konstanta && cykl == cyklus) {
    program = 0;
    digitalWrite(vetev1, LOW);
    digitalWrite(vetev2, LOW);
    digitalWrite(vetev3, LOW);
    Serial.println("PROGRAM UKONCEN AUTOMATICKY");
  }
 }
}

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: Pomoc s kódem (zavlažování)-začátečník

Příspěvek od pavel1tu » 23 dub 2020, 14:22

Rudy píše:
23 dub 2020, 14:09
Děkuji za pomoc, trochu se tím budu muset prokousat, jak jsem psal, jsem začátečník. A nechci jen Váš kód bez mozku okopírovat, chci ho i pochopit.
Ještě jednou moc děkuji. Dám vědět jak to dopadlo :)
Děti využily Váš program a podle toho co je učíme ho "upravily".
Strašně se nudí a za řešení mají "medaile" kulatou fidorku ;) tak mají motivaci.

Řešení už je 12, nevím kdy jim to budu kontrolovat, ach ...
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Rudy
Příspěvky: 3
Registrován: 23 dub 2020, 10:30
Reputation: 0

Re: Pomoc s kódem (zavlažování)-začátečník

Příspěvek od Rudy » 23 dub 2020, 15:13

Klobouk dolů, co já bych dal za takové vyučování... :D :oops:

Odpovědět

Kdo je online

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