jednoduchý kód

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
czhory
Příspěvky: 4
Registrován: 13 črc 2019, 17:48
Reputation: 0

jednoduchý kód

Příspěvek od czhory » 21 črc 2019, 15:13

Dobrý den, koupil jsem Arduino a myslel si, že to zvládnu, ale ejhle... =)

Potřeboval bych poradit s kódem. Uvedu obecný příklad:

Při stisku vstupu č.1 bych chtěl sepnout výstup č.1 na 5s a výstup č.2 na 10s.
A při stisku vstupu č.2 bych chtěl sepnout výstup č.3 na 15s a výstup č.4 na 20s.
A nejlépe, pokud by to šlo, aby se po stisknutí vstupu č.1 dal stisknout už pouze vstup č.2 a naopak (jakési zablokování opakování zmáčknutí toho samého vstupu).

Pomůžete mi prosím? Pomalu se s tím učím, ale nějak jsem se teď zasekl a potřebuji posunout dále.

Moc děkuji.

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

Re: jednoduchý kód

Příspěvek od pavel1tu » 21 črc 2019, 17:12

Nemám čas to testnout ... až večer nebo někdy ...
A vůbec netuším jestli to bude fungovat :lol
Jo a musíš si doinstalovat tuto knihovnu
https://github.com/brunocalou/Timer

Na tlacitko to nebude reagovat pokud casujeme (asi by slo dodělat i stop)
a nebo pokud bylo naposledy stisknute to same tlacitko (jdou na stridacku mackat 1 -2 -1 -2 ......)

Kód: Vybrat vše

// verze 1.03 - opraveny preklepy, decka to i vyzkousely bez relatek jen sledovaly serialmonitor

#include "timer.h"

Timer timer1; // 5s
Timer timer2; // 10s
Timer timer3; // 15s
Timer timer4; // 20s

#define vstup1 6
#define vstup2 7
#define rele1 9
#define rele2 10
#define rele3 11
#define rele4 12

byte PosledniVstup = 0;
byte casujeme = 0;



void Casovac1() {
  Serial.println("Rele 1 OFF");
  digitalWrite(rele1, LOW);
  timer1.stop();
  // casujeme = 0;
}

void Casovac2() {
  Serial.println("Rele 2 OFF");
  digitalWrite(rele2, LOW);
  timer2.stop();
  casujeme = 0;
}

void Casovac3() {
  Serial.println("Rele 3 OFF");
  digitalWrite(rele3, LOW);
  timer3.stop();
  // casujeme = 0;
}

void Casovac4() {
  Serial.println("Rele 4 OFF");
  digitalWrite(rele4, LOW);
  timer4.stop();
  casujeme = 0;
}


void setup() {
  Serial.begin(9600);

  //nastavení vstupu a zapnutí interního pull-up rezistoru
  pinMode(vstup1, INPUT);
  pinMode(vstup2, INPUT);

  //nastavení výstupu
  pinMode(rele1, OUTPUT); 
  pinMode(rele2, OUTPUT); 
  pinMode(rele3, OUTPUT); 
  pinMode(rele4, OUTPUT); 

  //Set the interval in milliseconds
  timer1.setTimeout(5000);
  timer2.setTimeout(10000);
  timer3.setTimeout(15000);
  timer4.setTimeout(20000);


  //Set our callback function
  timer1.setCallback(Casovac1);
  timer2.setCallback(Casovac2);
  timer3.setCallback(Casovac3);
  timer4.setCallback(Casovac4);

  Serial.println("Jsem pripraven na start casovacu ....");
}

void loop()
{
  //Update all the timers at once
  timer1.update();
  timer2.update();
  timer3.update();
  timer4.update();



  if(digitalRead(vstup1) == HIGH && PosledniVstup != 1 && casujeme == 0)
     {
      PosledniVstup = 1;
      casujeme = 1;
      digitalWrite(rele1, HIGH);
      Serial.println("Rele 1 ON");
      digitalWrite(rele2, HIGH);
      Serial.println("Rele 2 ON");
      timer1.start();
      timer2.start();
      delay(200);   // pro jistotu
     }

  if(digitalRead(vstup2) == HIGH && PosledniVstup != 2 && casujeme == 0)
     {
      PosledniVstup = 2;
      casujeme = 1;
      digitalWrite(rele3, HIGH);
      Serial.println("Rele 3 ON");
      digitalWrite(rele4, HIGH);
      Serial.println("Rele 4 ON");
      timer3.start();
      timer4.start();
      delay(200);   // pro jistotu
     }     


  
}

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: jednoduchý kód

Příspěvek od pavel1tu » 21 črc 2019, 17:47

Ještě by to šlo vylepšit a sledovat každý časovač zvlášť (každému přiřadit "váhu" - 1-2-4-8).

Na kroužku si na tom smlsla 11 letá dívenka a 10 hoch ... já jen asi 2x vypomohl.

Bylo to pro ně zpestření - nedaří se nám rozchodit data na GSM modulu (už 2 den).
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

czhory
Příspěvky: 4
Registrován: 13 črc 2019, 17:48
Reputation: 0

Re: jednoduchý kód

Příspěvek od czhory » 21 črc 2019, 20:39

Vypadá to na naprostou špičku =) Moc děkuji jak Vám, tak hlavně těm Vaším programátorům !! A btw. kde se to naučili?
Ještě jednou moc děkuji !!!!

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

Re: jednoduchý kód

Příspěvek od pavel1tu » 21 črc 2019, 20:42

Kamarád už 10 let vede prázdninový příměstský tábor elektroniků.

Posledních 5 let se to zvrhlo na Arduina a programování.

Trochu mu tam vypomáhám a sháním sponzory na HW + sem tam dozor.
To on mne k tomu přivedl.
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: jednoduchý kód

Příspěvek od gilhad » 22 črc 2019, 00:08

Já bych to viděl nějak takhle :)

Kód: Vybrat vše

#define tlacitkoApin 7
// na kterem pinu je tlacitko A (pripojeno proti zemi)

bool tlacitkoAenabled;	// je zrovna povoleno ho zmacknout?
bool tlacitkoAactive;	// probiha prave jeho akce?
unsigned long tlacitkoAfrom; 	// odkdy ta akce probiha?

#define tlacitkoBpin 8
// na kterem pinu je tlacitko B (pripojeno proti zemi)
bool tlacitkoBenabled;	// je zrovna povoleno ho zmacknout?
bool tlacitkoBactive;	// probiha prave jeho akce?
unsigned long tlacitkoBfrom; 	// odkdy ta akce probiha?

// kde je která dioda (prez odpor 330 Ohm proti zemi)
#define ledA1pin 9
#define ledA2pin 10
#define ledB1pin 11
#define ledB2pin 12

// jak dlouho má svítit?
#define timeA1 5000
#define timeA2 10000
#define timeB1 15000
#define timeB2 20000

// Časy a piny jsou zavedeny pomocí #define, protože se nemění a kompilátor ani změnu nepřipustí. Nemluvě o tom, že to šetří RAM.


void setup() {
	pinMode(ledA1pin,OUTPUT);
	digitalWrite(ledA1pin,LOW);	// zaciname se zhasnutou diodou
	
	pinMode(ledA2pin,OUTPUT);
	digitalWrite(ledA2pin,LOW);	// zaciname se zhasnutou diodou
	
	pinMode(ledB1pin,OUTPUT);
	digitalWrite(ledB1pin,LOW);	// zaciname se zhasnutou diodou
	
	pinMode(ledB2pin,OUTPUT);
	digitalWrite(ledB2pin,LOW);	// zaciname se zhasnutou diodou
	
	pinMode(tlacitkoApin, INPUT_PULLUP);	// tahneme vnitrnim odporem nahoru, takze normalne je HIGH, stisknutim se pripoji na zem a je LOW
	pinMode(tlacitkoBpin, INPUT_PULLUP);	// tahneme vnitrnim odporem nahoru, takze normalne je HIGH, stisknutim se pripoji na zem a je LOW
	
	tlacitkoAenabled = true; // smíme ho teď stisknout
	tlacitkoBenabled = true; // smíme ho teď stisknout, kdyby se muselo povinně začínat tlačítkem A, tak tady to tlačítko B zakážeme a budeme čekat, až ho A uvolní
	
	tlacitkoAactive = false; // jeho akce neprobíhá
	tlacitkoBactive = false; // jeho akce neprobíhá
}

void loop() {
	unsigned long CurrentMillis=millis();	// jaký je čas (a předejdeme zmatkům, kdyby se zrovna překlápěl) - viz též https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay
	
	if (tlacitkoAenabled && !tlacitkoAactive && digitalRead(tlacitkoApin)==LOW) {	// je povoleno ho stisknout, jeho akce ještě neběží a fakt je stisknuté - čas zahájit akci
		tlacitkoAactive = true; 	// akce běží
		tlacitkoAfrom = CurrentMillis; 	// od teď
		tlacitkoAenabled = false; 	// už se nesmí zmáčknout znovu
		tlacitkoBenabled = true; 	// ale B se od teď stisknout smí (takže akce se mohou částečně překrývat)
	};
	
	if (tlacitkoBenabled && !tlacitkoBactive && digitalRead(tlacitkoBpin)==LOW) {	// je povoleno ho stisknout, jeho akce ještě neběží a fakt je stisknuté - čas zahájit akci
		tlacitkoBactive = true; 	// akce běží
		tlacitkoBfrom = CurrentMillis; 	// od teď
		tlacitkoBenabled = false; 	// už se nesmí zmáčknout znovu
		tlacitkoAenabled = true; 	// ale A se od teď stisknout smí (takže akce se mohou částečně překrývat)
	};
	
	if (tlacitkoAactive) { // řešíme akci A
		digitalWrite(ledA1pin, (CurrentMillis - tlacitkoAfrom) < timeA1);	// pravda pouze od stisknutí, do vypršení času, jinak LED zhasne (false == 0 )
		digitalWrite(ledA2pin, (CurrentMillis - tlacitkoAfrom) < timeA2);	// pravda pouze od stisknutí, do vypršení času, jinak LED zhasne (false == 0 )
		// pozor, trik - ty nerovnosti nahoře a dole nejsou nikdy splněné naráz, takže vím, že diody zhasnou dřív než skončíme akci
		if ( ((CurrentMillis - tlacitkoAfrom) >= timeA1 ) &&  ((CurrentMillis - tlacitkoAfrom) >= timeA2 ) ) {	// už není co dělat, uklidíme
			tlacitkoAactive = false; // jeho akce neprobíhá
			// kdyby akce nesměly běžet naráz, tak povolíme druhé tlačítko až tady
		};
	};
	
	if (tlacitkoBactive) { // řešíme akci B
		digitalWrite(ledB1pin, (CurrentMillis - tlacitkoBfrom) < timeB1);	// pravda pouze od stisknutí, do vypršení času, jinak LED zhasne (false == 0 )
		digitalWrite(ledB2pin, (CurrentMillis - tlacitkoBfrom) < timeB2);	// pravda pouze od stisknutí, do vypršení času, jinak LED zhasne (false == 0 )
		if ( ((CurrentMillis - tlacitkoBfrom) >= timeB1 ) &&  ((CurrentMillis - tlacitkoBfrom) >= timeB2 ) ) {	// už není co dělat, uklidíme
			tlacitkoBactive = false; // jeho akce neprobíhá
			// kdyby akce nesměly běžet naráz, tak povolíme druhé tlačítko až tady
		};
	};
	
}


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

Re: jednoduchý kód

Příspěvek od pavel1tu » 22 črc 2019, 06:16

gilhad píše:
22 črc 2019, 00:08
Já bych to viděl nějak takhle :)
Proto jsem to nechal vyřešit s knihovnou,
aby to bylo pro začátečníka přehlednější a mohl si to snáze upravit

No uznávám popisky v kodu chybí, ale je to tak přehledné, že až zbytečné ....
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: jednoduchý kód

Příspěvek od gilhad » 22 črc 2019, 09:42

Nevím, mě tam ta knihovna s callbacky naopak přijde jako trochu složitější koncept, oproti prostému počítání času, navíc to s ní vychází delší (a to nepočítám kód té knihovny) a kód se čato "ztrácí z dohledu", takže IMHO začátečník hůř zjistí, co se mu tam vlastně na pozadí děje.

A asi by bylo dobré si u těch vstupů opravdu zapnout ten interní pull-up, když to je i v komentáři. Takhle ta tlačítka zůstávají ve stavu vysokého odporu a není zaručeno, co bude vracet digitalRead, pokud je tlačítko puštěné :) A je potřeba opravdu používat delay "pro jistotu"? Pokud není v té knihovně nějaká chyba, tak by to snad potřeba být nemělo a používání delay beru jako nutné zlo (a Arduino zlozvyk) jen tam, kde to nejde rozumně jinak a program musí být opravdu zablokován.

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

Re: jednoduchý kód

Příspěvek od pavel1tu » 22 črc 2019, 10:50

Nepruď :-D

Ten pullup tam byl, původně.
Ale nevím co půjde na vstupy (plus, minus), tak se zrušil, ne v popisu což je chyba. A já se mu osobně vyhýbám, ošetřuji raději vstupy svým odporem, kondikem.

Knihovnu mám dlouhodobě prověřenou, funguje skvěle a jen nahrazuje ten opruz s milis.
Těch 200ms delay jde smazat - nic to neovlivní v takto jednoduchém programu. Ani nevím proč tam je :-) - přehlédl jsem ho

PS: dělali to děti, tak to beru jako OK, sám bych to neudělal jinak a měli to za hodinu včetně sestavení a vyzkoušení
UNO, NANO, Mikro, PRO mini, DUE, ESP32S2, RPi PICO
Pavel1TU
"Správně napsaný kod lze číst jako knihu"

Uživatelský avatar
gilhad
Příspěvky: 779
Registrován: 07 bře 2018, 11:22
Reputation: 0

Re: jednoduchý kód

Příspěvek od gilhad » 22 črc 2019, 11:22

Ale jo :) Já to taky psal z jedný vody na plot :)

Ale zatímco ty tu knihovnu znáš a já odhadnu, co asi tak dělá, tak tázající je začátečník a tohle skoro jistě neví.

Takže teď má na výběr dva fungující styly a má o čem přemýšlet (ono to obojí vyjde skoro nastejno a nejspíš to pod kapotou dělá skoro to samé), místo aby měl jednu zjevenou pravdu, kterou by nabifloval, ale nikoli nutně pochopil. A ukázat, že je víc jak jedna možná cesta je IMHO docela vhodné už od začátku.

Odpovědět

Kdo je online

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