Stránka 1 z 5
Modelová železnice
Napsal: 23 kvě 2023, 16:53
od daavii
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,
}
}
Re: Modelová železnice
Napsal: 23 kvě 2023, 18:04
od kiRRow
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);
}
}
Re: Modelová železnice
Napsal: 23 kvě 2023, 18:20
od kiRRow
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
}
}
Re: Modelová železnice
Napsal: 23 kvě 2023, 18:31
od daavii
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.
Re: Modelová železnice
Napsal: 23 kvě 2023, 18:48
od kiRRow
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é ?
Re: Modelová železnice
Napsal: 23 kvě 2023, 19:02
od daavii
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.
Re: Modelová železnice
Napsal: 23 kvě 2023, 19:03
od kiRRow
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
}
}
Re: Modelová železnice
Napsal: 23 kvě 2023, 19:06
od kiRRow
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
}
}
Re: Modelová železnice
Napsal: 23 kvě 2023, 19:11
od daavii
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.
Re: Modelová železnice
Napsal: 23 kvě 2023, 19:15
od kiRRow
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
}
}
}