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, ...)
-
daavii
- Příspěvky: 20
- Registrován: 22 kvě 2023, 11:41
Příspěvek
od daavii » 23 kvě 2023, 16:53
Dobrý den, a děkuji předem. V 50 letech jsem se rozhodl že zkusím svět Arduina. S vnoučaty stavíme modelovou železnici a zkouším lehce z automatizovat zastavení ve stanici. Něco jsem sesmolil co mi vyhovuje ale má to ale, je tam jedem delay který by brzdil prog. ale nejsem schopen se ho zbavit. Funguje to následně: vlak přijede do zastávky na přerušenou kolej bez napětí - zastaví a sepnete infračidlo, časuje se 5 sec. a sepne rele a led, po 2 sec. potřebných pro odjezd vlaku je rele a led zase OFF. Stačí mi ukázat co a kde do kódu přidat, zbytek zvládnu snad ale věřím si. Zobrazený sketch mi dělá co potřebuji. Prolezl jsem to hodně a nic co by mě přivedlo k úspěchu jsem nenašel, všude samé blikání. Díky za pomoc.
Kód: Vybrat vše
const byte IR1 = 2; //infrared sensor
//const byte IR2 = 5;
const byte led1 = 3; // led stavu koleje
//const byte led2 = 6//;
const byte rele1 = 4;
//const byte rele2 = 7;
unsigned long startMillis;
unsigned long currentMillis;
unsigned long period2 = 5000; //kdyz IR HIGH tak ceka led 5 sec. nez HIGH
unsigned long period1 = 2000; // led bude HIGH 2sec.,IR bude i HIGH i LOW, nez odjede vlak
void setup()
{
Serial.begin(9600);
pinMode(led1, OUTPUT);
pinMode(IR1,INPUT);
pinMode(rele1,OUTPUT);
}
void loop(){
int IR1Value = digitalRead(IR1);
Serial.println(IR1);
if (IR1Value==HIGH) {
digitalWrite(led1, LOW);
digitalWrite(rele1, HIGH);
startMillis = millis();
startMillis = currentMillis;
}
currentMillis = millis();
if (currentMillis - startMillis >= period2)
{
digitalWrite(led1, HIGH);
digitalWrite(rele1, LOW);
}
{
delay (2000); // s timto delay to funguje jak potrebuji, ale nechci to tak,
}
}
-
kiRRow
- Příspěvky: 1240
- Registrován: 07 kvě 2019, 07:03
- Bydliště: Opava
Příspěvek
od kiRRow » 23 kvě 2023, 18:04
Kód: Vybrat vše
if (IR1Value==HIGH) {
digitalWrite(led1, LOW);
digitalWrite(rele1, HIGH);
startMillis = millis();
startMillis = currentMillis; // <--- zde, omylem si tu přepíšeš startMillis
}
ono to spíš bylo myšleno nějak takhle původně
Kód: Vybrat vše
void loop(){
int IR1Value = digitalRead(IR1);
Serial.println(IR1);
currentMillis = millis(); // tady si zjistím aktuální čas
if (IR1Value==HIGH) {
digitalWrite(led1, LOW);
digitalWrite(rele1, HIGH);
startMillis = currentMillis; // tady akutální čas zjištěný na začátku loopu uložím
}
if (currentMillis - startMillis >= period2) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven period2
digitalWrite(led1, HIGH);
digitalWrite(rele1, LOW);
}
}
-
kiRRow
- Příspěvky: 1240
- Registrován: 07 kvě 2019, 07:03
- Bydliště: Opava
Příspěvek
od kiRRow » 23 kvě 2023, 18:20
Akorát následně vznikne problém v tom, že když ten vlak bude v cílové stanici stát v tom senzoru, tak se bude neustále přepisovat startMillis a nikdy nebude ten rozdíl mezi currentMillis a startMillis větší než perioda ... buď tam ten vlak nebude stát a nebo si přidáš ještě jednu proměnnou typu bool, kde si zapamatuješ, že čas příjezdu byl poznamenán a není třeba ho aktualizovat, po odjezdu tuto proměnnou zase smažeš.
Kód: Vybrat vše
boolean vlak = false; // vlak není ve stanici
void loop(){
int IR1Value = digitalRead(IR1);
Serial.println(IR1);
currentMillis = millis(); // tady si zjistím aktuální čas
if (IR1Value==HIGH) { // něco se děje na senzoru
if (vlak == false) { // nepamatuji si že by tam kdy byl vlak, sepnu relé a diodu
digitalWrite(led1, LOW);
digitalWrite(rele1, HIGH);
startMillis = currentMillis; // tady akutální čas zjištěný na začátku loopu uložím
vlak = true; // zapamatuji si že tam je vlak
}
}
if (currentMillis - startMillis >= period2) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven period2, tak vlak odjel
digitalWrite(led1, HIGH);
digitalWrite(rele1, LOW);
vlak = false; // zapomenu na vlak
}
}
-
daavii
- Příspěvky: 20
- Registrován: 22 kvě 2023, 11:41
Příspěvek
od daavii » 23 kvě 2023, 18:31
Děkuji za odpověď, ani sem netušil, že je tam chyba, ale odčasování 5sec.fungovalo dle mých představ, ale řeším ty 2 sec (period1) viz. popis jak to má fungovat. Asi takto: na koleji zastaví vlak, sepne IR, zapne časování 5 sec. sepne relé, vlak jede ALE potřebuji aby to sepnutí trvalo 2-3sec. bez IR HIGH, protože vlak má mezery a když je přerušená kolej delší tak tak neodjede. Mezera vypne rele.
-
kiRRow
- Příspěvky: 1240
- Registrován: 07 kvě 2019, 07:03
- Bydliště: Opava
Příspěvek
od kiRRow » 23 kvě 2023, 18:48
Přiznávám, že se trošku ztrácím v zadání ...
Kód: Vybrat vše
boolean vlak = false; // vlak není ve stanici
void loop(){
int IR1Value = digitalRead(IR1);
Serial.println(IR1);
currentMillis = millis(); // tady si zjistím aktuální čas
if (IR1Value==HIGH) { // něco se děje na senzoru
if (vlak == false) { // nepamatuji si že by tam kdy byl vlak, sepnu relé a diodu
digitalWrite(led1, LOW);
digitalWrite(rele1, HIGH);
startMillis = currentMillis; // tady akutální čas zjištěný na začátku loopu uložím
vlak = true; // zapamatuji si že tam je vlak
}
}
if (currentMillis - startMillis >= period1) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven period1
// zde provést za dvě vteřiny
digitalWrite(led1, HIGH); // ledka off
digitalWrite(rele1, LOW); // relé off
}
if (currentMillis - startMillis >= period2) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven period2, tak vlak odjel
// tady jsou věci co se provádí za pět vteřin
vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
}
}
Nebo jako ten vlak tam má přijet, 5vteřin stát a pak se na dvě vteřiny zapne led a relé ?
-
daavii
- Příspěvky: 20
- Registrován: 22 kvě 2023, 11:41
Příspěvek
od daavii » 23 kvě 2023, 19:02
Přesně tak!. Vlak přijede do stanice, zastaví na 5s. a pak odjede. a na odjezd potřebuje čas 2-3 sec, v průběhu odjezdu mezery vypnou relé a to je ta chyba kterou řeším tím delay a to nechci. Ty 2 sec. jsou jakoby přidržení sepnutého relé na jakémkoliv stavu IR.
-
kiRRow
- Příspěvky: 1240
- Registrován: 07 kvě 2019, 07:03
- Bydliště: Opava
Příspěvek
od kiRRow » 23 kvě 2023, 19:03
i když dávalo by to smysl, že .... vlak přijede ... 5s počká a pak se mu pustí napájení na 2s, aby odjel
Kód: Vybrat vše
boolean vlak = false; // vlak není ve stanici
void loop(){
int IR1Value = digitalRead(IR1);
Serial.println(IR1);
currentMillis = millis(); // tady si zjistím aktuální čas
if (IR1Value==HIGH) { // něco se děje na senzoru
if (vlak == false) { // nepamatuji si že by tam kdy byl vlak, sepnu relé a diodu
digitalWrite(led1, LOW);
digitalWrite(rele1, HIGH);
startMillis = currentMillis; // tady akutální čas zjištěný na začátku loopu uložím
vlak = true; // zapamatuji si že tam je vlak
}
}
if (currentMillis - startMillis >= period2) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven period2 - tzn stojí tu pět vteřin
digitalWrite(led1, LOW); // zapnout ledku
digitalWrite(rele1, HIGH); // zapnout relé
}
if (currentMillis - startMillis >= period1 + period2) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven oboum periodám, tak vlak odjel - 2s na odjezd + 5s stání
digitalWrite(led1, HIGH); // vypnout ledku
digitalWrite(rele1, LOW); // vypnout relé
vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
}
}
-
kiRRow
- Příspěvky: 1240
- Registrován: 07 kvě 2019, 07:03
- Bydliště: Opava
Příspěvek
od kiRRow » 23 kvě 2023, 19:06
Pozor, udělal jsem chybu : zapoměl jsem zrušit zapnutí relé a diody v dění se něco na senzoru ...
Oprava :
Kód: Vybrat vše
boolean vlak = false; // vlak není ve stanici
void loop(){
int IR1Value = digitalRead(IR1);
Serial.println(IR1);
currentMillis = millis(); // tady si zjistím aktuální čas
if (IR1Value==HIGH) { // něco se děje na senzoru
if (vlak == false) { // nepamatuji si že by tam kdy byl vlak - nespínám relé a diodu, chci si jen pamatovat čas a že vlak přijel - sepnu to později
startMillis = currentMillis; // tady akutální čas zjištěný na začátku loopu uložím
vlak = true; // zapamatuji si že tam je vlak
}
}
if (currentMillis - startMillis >= period2) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven period2 - tzn stojí tu pět vteřin
digitalWrite(led1, LOW); // zapnout ledku
digitalWrite(rele1, HIGH); // zapnout relé
}
if (currentMillis - startMillis >= period1 + period2) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven oboum periodám, tak vlak odjel - 2s na odjezd + 5s stání
digitalWrite(led1, HIGH); // vypnout ledku
digitalWrite(rele1, LOW); // vypnout relé
vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
}
}
-
daavii
- Příspěvky: 20
- Registrován: 22 kvě 2023, 11:41
Příspěvek
od daavii » 23 kvě 2023, 19:11
Děkuji, vyzkouším, nic se testovat nebude a v provozu to nebude déle jak 1-2hod. Kdyby něco nebylo dle mých představ tak se ozvu. Ještě jednou Díky jdu testovat.
-
kiRRow
- Příspěvky: 1240
- Registrován: 07 kvě 2019, 07:03
- Bydliště: Opava
Příspěvek
od kiRRow » 23 kvě 2023, 19:15
A další chyba
- je potřena ještě otestovat, jestli tam ten vlak vůbec je .... protože když se to spustí, začnou se počítat currentMillis, ale dokud tam ten vlak nenajede, tak bude startMillis 0 ... a pak projde podmínka že currentMillis - startMillis ...
Kód: Vybrat vše
boolean vlak = false; // vlak není ve stanici
void loop(){
int IR1Value = digitalRead(IR1);
Serial.println(IR1);
currentMillis = millis(); // tady si zjistím aktuální čas
if (IR1Value==HIGH) { // něco se děje na senzoru
if (vlak == false) { // nepamatuji si že by tam kdy byl vlak - nespínám relé a diodu, chci si jen pamatovat čas a že vlak přijel - sepnu to později
startMillis = currentMillis; // tady akutální čas zjištěný na začátku loopu uložím
vlak = true; // zapamatuji si že tam je vlak
}
}
if (currentMillis - startMillis >= period2) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven period2 - tzn stojí tu pět vteřin
if(vlak){ // je tam ten vůbec vlak
digitalWrite(led1, LOW); // zapnout ledku
digitalWrite(rele1, HIGH); // zapnout relé
}
}
if (currentMillis - startMillis >= period1 + period2) { // pokud je rozdíl mezi aktuálním časem a tím co jsem si uložil, když bylo IR1 HIGH větší nebo roven oboum periodám, tak vlak odjel - 2s na odjezd + 5s stání
if(vlak){ // je tam ten vůbec vlak
digitalWrite(led1, HIGH); // vypnout ledku
digitalWrite(rele1, LOW); // vypnout relé
vlak = false; // zapomenu na vlak - tohle bych dal do nejdelšího intervalu, pokud nechceš testovat zda-li všechny intervaly uplynuly
}
}
}
Kdo je online
Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 1 host