Random één pin aan na het maken van contact...

Al 1,5 week zeer frustrerend met het ding bezig wat Arduino Uno heet... Toen ik hem net bijna in de vuilnisbak wilde gooien, toch maar besloten dit forum te raadplegen. Ik kom er niet meer uit, ik krijg het niet voor elkaar.

Wat ik wil, is heel simpel in feite:
Op een modelspoorbaan zijn 6 sporen naast elkaar beschikbaar om treinen op te stellen (schaduwstation).
Eén willekeurig spoor is altijd leeg, die trein rijdt op de baan rond, de andere 5 wachten.
Er kan er maar één per keer rondrijden.

Vlak vóór het schaduwstation komt een contactje wat geactiveerd wordt als een trein het schaduwstation nadert.
Met het maken van contact moet één van de 6 sporen (en dat mag ook het lege spoor zijn, dan rijdt diezelfde trein nog een rondje) met een relais onder spanning worden gezet voor 10 a 15 seconde. Ná die 10 a 15 seconde, moet het relais weer afvallen en de spanning er weer af gaan.

Dit moet zich eigenlijk continu herhalen.

Wat er nu gebeurt, is dat ALLE 6 de sporen vrijgegeven worden en ook niet meer spanningsloos worden gesteld. Dus, één grote ravage als het straks aangesloten wordt.

Vanwege de gebruikte relaiskaart is HIGH en LOW omgedraaid, dat kan voor verwarring zorgen.
Wie kan me helpen met het laatste stukje code om dit werkend te krijgen?
Ik geef het op na vele uren en dagen ploeteren en testen...

Alvast bedankt,
Roland.

const int buttonpin = 2;    //Rijcontact M-rails vóór het schaduwstation
int buttonState;

const int relay_1 = 7;      //Relais 1
const int relay_2 = 8;      //Relais 2
const int relay_3 = 9;      //Relais 3
const int relay_4 = 10;     //relais 4
const int relay_5 = 11;     //Relais 5
const int relay_6 = 12;     //Relais 6

const int maxLedPins = 6;

int ledpins[maxLedPins] = {relay_1, relay_2, relay_3, relay_4, relay_5, relay_6};

unsigned long starttijd = 0;               // Zet de standaard timer (voor millis) op nul
unsigned long interval_vertrek = 15000;    // De tijd dat een spoor geactiveerd is om te vertrekken (15 sec)

void setup() {

  pinMode(buttonpin, INPUT_PULLUP);           //Door interne weerstand: LOW = HIGH, HIGH = LOW
  
  pinMode(relay_1, OUTPUT);
  pinMode(relay_2, OUTPUT);
  pinMode(relay_3, OUTPUT);
  pinMode(relay_4, OUTPUT);  
  pinMode(relay_5, OUTPUT);
  pinMode(relay_6, OUTPUT);

  pinMode(LED_BUILTIN, OUTPUT);



  digitalWrite(relay_1, HIGH);  //Bij opstarten dit relais uitgeschakeld houden
  digitalWrite(relay_2, HIGH);  //Bij opstarten dit relais uitgeschakeld houden
  digitalWrite(relay_3, HIGH);  //Bij opstarten dit relais uitgeschakeld houden
  digitalWrite(relay_4, HIGH);  //Bij opstarten dit relais uitgeschakeld houden
  digitalWrite(relay_5, HIGH);  //Bij opstarten dit relais uitgeschakeld houden
  digitalWrite(relay_6, HIGH);  //Bij opstarten dit relais uitgeschakeld houden
  
}

void loop() {


buttonState = digitalRead(buttonpin);

if (buttonState == LOW) {                               //Laat de volgende trein vertrekken indien er contact is.

    starttijd = millis();
    while ((millis() - starttijd) < interval_vertrek)
    {
                            
  digitalWrite (ledpins[random(maxLedPins)], LOW);     //Random een trein uitkiezen, eventueel dezelfde.
  digitalWrite(LED_BUILTIN, HIGH);                     //Interne LED, is aan/of uit, tegengesteld met relais.
    }
    
if (buttonState == HIGH)                                 //Stop de schakeling. (pull_up, dus andersom)

{

}
}
}

janzzen:
digitalWrite (ledpins[random(maxLedPins)], LOW);

1: De random()-functie doet niet wat je ervan verwacht, begrijp ik. Kijk even hier, en let ook vooral op wat daar staat over randomSeed().

2: Je hebt nog geen code geschreven om het relais weer af te laten vallen na de wachttijd.

3: Beter bewaar je het resultaat van random() in een locale variabele, dan kun je die eerst gebruiken om het relais op te laten komen, en in een volgende regel weer om het af te laten vallen.

4: Na pinMode(x,y) is de betreffende outputpin LOW, waardoor de relais misschien net even bekrachtigd zouden kunnen worden! Los dat op door (in setup() ) eerst digitalWrite(X, HIGH) te geven en daarna pas pinMode(X, OUTPUT).

5: Je hebt nu twee arrays met dezelfde inhoud, dat is nogal zinloos. Drop int ledpins[] en gebruik nu relayPins[]. Maak het array als volgt:

 const int relayPins[] = {7, 8, 9, 10, 11, 12};

Dan kun je in één for-loop met twee regels code voor alle 6 pins OUTPUT en pinMode instellen.

6: Verander ook maxLedPins in maxRelayPins. Dat is logischer.

Hallo Erik,

  1. Nee, nu gaan álle relais tegelijk aan, hetgeen voor de nodige puinhoop gaat zorgen :slight_smile:
  2. Klopt, want, na die 10 a 15 seconde zal het contact low zijn en dus eindigt de loop... toch?
    3, 4, 5 en 6... Dat zal nog een hele puzzel worden, dacht het allemaal wel een beetje te snappen, maar ik begrijp dat mijn doel wat ik voor ogen had, nog een hele opgave wordt om te doorgronden en te realiseren...

Anyway, dank voor de hulp, ik heb de komende dagen wel weer wat om uit te zoeken.
Voor nu ga ik 'avond' houden, al vanaf 14.30 bezig met dit stomme script en heb nog niks bereikt, haha!

Oh bijna vergeten, low = high in mijn geval. Ben ik ook proefondervindelijk achter gekomen.
Die relais gaan aan, worden actief, als ik de opdracht LOW geef en vallen af met de opdracht HIGH.
Zorgt voor verwarring, ook bij mij, haha!

Nogmaals dank voor je reactie,

Roland.

Hoi Roland, welkom.

Ik zie jouw verwarring over het aan of uitzetten van je relais, en dat komt heel veel voor.
Voor de meesten die al lang bezig zijn met dit soort dingen, werkt het andersom.
Namelijk dat je een relais inschakelt met een LOW, en dat heeft te maken met de hardware die daar net iets beter mee overweg kan.
Je kunt er voor kiezen jezelf dat aan te wennen zodat dat ook voor jou een 2e natuur word.

Maar je kunt er ook voor kiezen dat in 1 oogopslag duidelijk te maken.
Voor dat laatste doe je het volgende helemaal bovenaan in jouw sketch; dus nog voor void.setup()

#define AAN LOW
#define UIT HIGH

Merk op dat je deze regels niet met een puntkomma ; beëindigt.

Nu kun je overal in jouw sketch AAN gebruiken in plaats van LOW, en UIT in plaats van HIGH.
Dit kost je geen programma geheugen, behalve op de schijf van je PC.
Je leert de compiler zo dat wanneer jij in deze sketch het betreffende woord typt, eigenlijk dat woord bedoelt dat de compiler wel kent (maar je kunt dit ook doen om een woord te gebruiken wanneer je een getal bedoelt, of een ander woord bedoelt dat in werkelijkheid voor de compiler ook al een getal was (A0 of D3 bijvoorbeeld om een pinnummer te benoemen).

Je kunt natuurlijk helemaal zelf andere duidelijke woorden bedenken, bijvoorbeeld:

#define Hopsakee LOW

Maar natuurlijk moet je dan wel woorden kiezen die de compiler niet al kent.

Wat punt 2 betreft: ik begrijp je gedachtengang, maar je moet echt nog iets meer programmeren voordat dat goed werkt.

janzzen:
5 en 6...

... zijn niet urgent. Wat MAS3 schrijft over AAN en UIT moet je zeker wél meteen toepassen, dat is veel duidelijker (ook voor ons).

heb nog niks bereikt

Da's niet waar, het begin is er en het werkt gedeeltelijk. :slight_smile:

Nog een tip: je kunt de werking goed volgen door op strategische plaatsen een Serial.print(variabele) of bv. Serial.print("functienaam") in te voegen. NB.: Plaats dan eerst Serial.begin(9600); in setup(.

@janzzen, Erik_Baas schrijft precies wat nodig is om je sketch wat te verbeteren. Daarna nog even die random goed doen en de 15 seconden netjes toevoegen en klaar. Ik had precies hetzelfde kunnen schrijven als Erik_Baas.

Wat wil je dat er gebeurt als het contact 'aan' blijft ?
Wil je dat de 15 seconden start op het moment dat het contact 'aan' gaat of is het goed als dat start als het contact 'uit' gaat ?
Dat laatste is gemakkelijker. Dat is zo iets als mijn: millis_single_delay.ino.

Dit zou een voorbeeldje kunnen zijn.
Met opzet zit er foutje in, voor de oplossing moet je Koepel zijn suggestie goed onder de loep nemen.
Het opschonen, ,juiste variabel namen kiezen en hun range ,alsook goed commentaar bij de regels voegen is een taak voor jouw.

#define AAN LOW
#define UIT HIGH
#define ON true
#define OFF false

const uint8_t butPin = 2;//Rijcontact M-rails vóór het schaduwstation
uint8_t butState;//Status rijcontact
uint8_t traceFlag = OFF;//Status geselecteerd spoor
int32_t randNum;
uint32_t prevMillis;
const uint32_t holdTime = 1500UL;

void setup() {
  Serial.begin(9600);
  pinMode(butPin, INPUT_PULLUP);
  for ( uint8_t thisPin = 4; thisPin < 9; thisPin++) {
    digitalWrite(thisPin, AAN);
    pinMode(thisPin, OUTPUT);
  }
  randomSeed(analogRead(5));//Stukje draad aan A5 (antenne)
}

void loop() {
  uint32_t curMillis = millis();
  butState = digitalRead(butPin);//Lees het Rail contact

  if ((butState == LOW) && (traceFlag == OFF)) {
    //Select a Random Output from 4 to 8
    randNum = random(4, 9);
    digitalWrite(randNum, AAN);//Laat de trein vertrekken
    traceFlag = ON;//Er is een spoor geselecteerd
    prevMillis = millis();//Onthoud de tijd
    Serial.print("Spoor ");
    Serial.print(randNum);
    Serial.println(" AAN");
  }
  
  //Reset het boeltje
  if (traceFlag == ON) {
    if (curMillis - prevMillis >= holdTime) {
      digitalWrite(randNum, UIT);
      traceFlag = OFF;
      Serial.print("Spoor ");
      Serial.print(randNum);
      Serial.println(" UIT");
      Serial.println(" ");//Print lege lijn
    }
  }
}

Beste programmeurs... enorm bedankt voor de reacties en jullie tijd! ???

Allereerst, ik heb wel een ICT-achtergrond, echter, het programmeren was (is?) écht niet mijn ding. Gelukkig (of niet in dit geval?) was het ook niet mijn keuze-richting binnen de ICT. Ik blijf het lastig vinden, maar aan de andere kant, als ik codes zie, zoals die van @GijKieken, dan snap ik redelijk hoe e.e.a. wordt aangestuurd, alleen zijn er nog een paar dingen die ik (nog) niet begrijp of waarvan de werking me onduidelijk is.

Het 'define' verhaal, daar had ik al wat van gelezen, maar nog niet voldoende om het truukje "UIT LOW" te kunnen toepassen. Ik weet niet hoe het in de programmeer-wereld zit, maar in mijn beleving is een relais AAN op het moment dat het LEDje brandt op de relaiskaart en het relais daadwerkelijk bekrachtigd wordt. Maar... ik heb ook ergens gezien dat er HOGE en LAGE relaiskaarten zijn, dus wellicht dat daarom bij mij LOW HIGH is en andersom. Helaas stond dat niet op de kaart zelf of op de site waar ik hem vandaan heb, maakt verder ook niet uit, de Arduino en de relaiskaart blijven sowieso met elkaar verbonden.

Voor @Koepel en ook de rest; het contact wat gemaakt wordt, is geen zuiver contact. Het wordt gemaakt met de wielen van de rails in feite. Maar omdat de spoorbaan wisselstroom is én maximaal 16 Volt, kan dit niet direct op de Arduino aangesloten worden. Ook hier zal een relais worden gebruikt (na een gelijkrichter die van wisselspanning een gelijkspanning maakt). Echter, het contact wordt geschakeld met de wielen. Op de spoorstaaf zit een contactje gemonteerd en via de wielen wordt er een massa-contact gemaakt (en dus straks ook een relais aangestuurd). Een trein met meerdere wagons zal dus meerdere contacten maken tijdens het voorbij rijden van het contact. Vanaf het éérste moment dat er contact is, mag die 15 seconde gaan lopen. Het is wel van belang dat meerdere schakelcontacten, NIET gaan zorgen voor meer vertrekkende treinen. Dus, eenmaal contact gemaakt, minstens 15 seconde wachten voor het schakelcontact opnieuw actief wordt (en in die tijd een andere trein laten vertrekken). Hoop dat het zo duidelijk is.

Nou, dan de uiteindelijke code die werd gegeven door GijKieken. Die instinker was eigenlijk snel gevonden, álle relais waren AAN zodra de Arduino tot leven kwam. Kwestie van uitzetten, zo ver kon ik de code al wel lezen :slight_smile:

Verder had ik gisteravond toch nog even de tablet gepakt en toch weer aan het zoeken geslagen. Toen kwam ik ook een sketch tegen waarin dus een analoge input pin werd uitgelezen. Het blijkt dus dat de door mij gebruikte random in mijn openingspost, toch niet zo random is en weldegelijk een vaste volgorde schijnt te hebben. Dus, een analoge poort uitlezen zou inderdaad dé oplossing zijn.

De initialisering, de gebruikte UINT8_T en INT32_T snap ik nog niet, ik heb dat nog nergens gezien, althans, niet in de script die ik bekeken heb. Zoek ik uit. Verder één verbazend dingetje, en dat is de regel:
if ((butState == LOW) && (traceFlag == OFF))
Moet die LOW geen HIGH zijn? Of... zit ik me nu te bedenken, is het die PULL_UP die dat weer andersom zet?

Mijn code met uitleg:

#define AAN LOW             // Definities omkeren
#define UIT HIGH            // Definities omkeren
#define ON true             // definities omkeren
#define OFF false           // Definities omkeren

const uint8_t butPin = 2;     //Rijcontact M-rails vóór het schaduwstation
uint8_t butState;             //Status rijcontact
uint8_t traceFlag = OFF;      //Status geselecteerd spoor (uint8_t ???)
int32_t randNum;              // int32-t ?????
uint32_t prevMillis;          // Tijdsopgave
const uint32_t holdTime = 15000UL;   // Wachttijd van 15 sec.

void setup() {

  
  Serial.begin(9600);                                   //Start seriele output
  pinMode(butPin, INPUT_PULLUP);                        //Input pin2 met interne pull_up
  for ( uint8_t thisPin = 4; thisPin < 10; thisPin++) { //Pin-definities, 4 t/m 10, zelf even aangepast)
    digitalWrite(thisPin, UIT);                         // De instinker, de relais moeten bij opstarten UIT zijn ;)
    pinMode(thisPin, OUTPUT);                           // Definities output-pin
  }
  randomSeed(analogRead(5));       //Stukje draad aan A5 (antenne) Had ik gevonden op internet, analoog uitlezen, is altijd een andere waarde
}

void loop() {
  uint32_t curMillis = millis();    // Millis tijdberekening
  butState = digitalRead(butPin);   //Lees het Rail contact

  if ((butState == LOW) && (traceFlag == OFF)) {    //butstate LOW ????? Moet toch HIGH zijn?
    //Select a Random Output from 4 to 10
    randNum = random(4, 10);
    digitalWrite(randNum, AAN);   //Laat een willekeurige trein vertrekken
    traceFlag = ON;               //Er is een spoor geselecteerd
    prevMillis = millis();        //Onthoud de tijd
    Serial.print("Spoor ");  //Output serieel
    Serial.print(randNum);        //Output serieel
    Serial.println(" AAN");       //Output serieel
  }
 
  //Reset het boeltje
  if (traceFlag == ON) {                        //Die is dus aan, valt binnen die 15 sec.
    if (curMillis - prevMillis >= holdTime) {   //Tijdberekening
      digitalWrite(randNum, UIT);               //Random nummer uit
      traceFlag = OFF;                          //Traceflag uit
      Serial.print("Spoor ");
      Serial.print(randNum);
      Serial.println(" UIT");
      Serial.println(" ");        //Print lege lijn
    }
  }
}

Wat ik al zei, ik snap wat er bedoeld wordt, maar kan het niet goed omschrijven, niet in de woorden die de echte programmeurs gebruiken, hi.

Anyway, ik heb hiermee al héél goed geholpen, ik had dit zelf nooit gered denk ik, met name die seriële output is erg handig, maar ook daar was ik nog niet mee bezig geweest en eigenlijk ook geen moment gedacht dat dat handig was om hierin te integreren... wat dat betreft moet ik met dit programmeerwerk anders of omdenken :slight_smile:

Goed, nu eens kijken wat UINT8-T en INT32-T precies doen...
Nu wil ik ook alles weten ook :smiley:

Ik vind het fijn en belangrijk dat je reageert en zelf opzoek werk verricht.
Nu een tip ,de fout zit in de regel waar het commentaar //Onthoud de tijd bij staat.
De oplossing kun je vinden bij, koepel fun with millis.

En het zou inderdaad duidelijker geweest zijn als ik ipv <uint8_t traceFlag = OFF;>
bool traceFlag = false; had geschreven.
Maar het maakte jouw nieuwsgierig,,,

Hahaha, ja, voorgenomen dat ik superblij ben met de code, ik ben niet zo iemand die hem klakkeloos overneemt, hem in de Arduino schiet en vervolgens achterover ga leunen... Ik wil wéten wat ik in die Arduino zet en hoewel ik het wellicht niet goed omschrijf in de juiste termen, ik wil gewoon weten wat die code doet. Ik ben nog (lang) niet zo ervaren dat ik iets dergelijks zelf kan schrijven, ik heb wel talloze codes aan proberen te passen, maar dan kwam die onverbiddelijke compiler weer met diverse foutmeldingen en bleef de Arduino leeg :slight_smile:

Goed, die uint_8-t en int32_t schijnt dus compiler-technisch te zijn, iets wat niet alleen voor Arduino, maar ook breder inzetbaar is. Die int32_t had ook gekund met unsigned long... althans, als ik dit forum mag geloven...

Goed, ga ik nu op zoek naar "koepel fun with millis", ik ben nog niet uit-ontdekt :slight_smile: :slight_smile:

janzzen:
int32_t had ook gekund met unsigned long...

Bijna:

  • int32_t declareert een "long" van 32 bits die alleen gehele getallen kan bevatten, positief of negatief.
  • uint32_t geeft een unsigned long: idem, maar dan alleen voor positieve getallen.

Een programmeur en zelfs hobbyisten ontwikkelen in de loop van de tijd zo hun eigen voorkeuren.
Daar loop je nu tegenaan.

Voor iets met millis() gebruik ik altijd "unsigned long".
Voor een pin gebruik ik altijd "int", dat vind ik beter voor de leesbaarheid van de code. Die paar bitjes die verloren gaan, pffft, het zou wat ::slight_smile:
Voor een true/false variabele gebruik ik altijd "bool".

De basis van de sketch is:
De 'traceFlag' geeft de twee toestanden aan waarin de sketch zich kan bevinden: De 15 seconden timer loopt, of die loopt niet. Als de tijd van de millis-timer bereikt is, dan zet die zelf die vlag weer uit. Zo wordt de millis-timer een eenmalige gebeurtenis.

Je mag die 'traceFlag' zelf een naam geeft die je beter lijkt. Wat dacht je van:
bool een_variabele_die_de_sketch_stuurt;
bool de_timer_loopt_op_dit_moment;
bool enableTimer;
bool timerIsRunningRightNow;

Mijn voorbeelden met millis(): Fun with millis
Daar gebruik ik ook de analoge inputs voor een random seed (tweede helft van de setup functie): millis_reaction_timer.ino, waarom zou je één analoge ingang gebruiken als je er meer hebt ?

Even snel een reactie in de pauze van het werk. Ik heb een aanvulling bedacht, hetgeen ik zou kunnen realiseren met een tweede Arduino, maarrrr... volgens mij moet dit ook kunnen met deze sketch.

Even vanuit deze sketch: een trein komt aan en laat een andere trein vertrekken, random. De vertrekkende trein gaat weg vanaf spoor 6. Ondertussen rolt op spoor 1 de andere trein binnen. Sporen 1 t/m 5 zijn nu bezet, spoor 6 is dus net vertrokken.

Ná de timer van 15 seconde (de tijd dat de aankomende trein op spoor 1 komt en spanningsloos wordt gesteld), zou het mooi zijn als de wissels worden geschakeld, zodanig dat de trein van spoor 6 weer terug komt op spoor 6.

Hiertoe zijn 6 extra relais nodig en dus ga ik dat niet redden met een Unio, wel met een Mega, maar dat even ter info.

De sketch nu, pakt een random spoor, spoor 6 dus. Ik zou eigenlijk willen dat ná die 15 seconde, een relais wordt aangezet voor een duur van ca. 300ms. Die tijd is lang genoeg om de wissels om te zetten, zodat de trein die vertrokken is, weer netjes terug komt op spoor 6 en NIET bovenop de trein knalt die daarvoor op spoor 1 is binnen gekomen. Uiteraard moet dit voor alle sporen gaan werken.

Ik kan elke vertrekkende trein (op elk spoor) ook apart over een contact laten rijden en een tweede arduino gebruiken, die nog een 20 seconde laten wachten, waarna alsnog het juiste relais wordt geschakeld, maar ik vroeg me af of de eerste optie ook kon...

Ga ik me nu nog even verdiepen in de treath over de millis en een boterham naar binnen werken.

Ik kom hier vanavond nog even op terug, dank voor de voorgaande reacties!

Groet,
Roland.

De 6 analoge ingangen van een Arduino Uno zijn ook digitale pinnen en kunnen dus ook digitale uitgangen zijn.
Pin 0 en 1 zijn voor de seriële verbinding naar de computer, dan heb je nog 18 pinnen over.

Alles wat je kunt bedenken met tijden en condities kan in code gezet worden. Met millis() is alles mogelijk, maar ik begrijp niet helemaal wat je wilt.

Ik schreef: "De 'traceFlag' geeft de twee toestanden aan...", maar stel dat je geen twee toestanden hebt, maar tien !
Daar is een standaard manier voor om dat te programmeren, dat heet een Finite State Machine. Dat is een deftige term voor iets eenvoudigs.

Dus er zijn mogelijkheden genoeg.

Hiertoe zijn 6 extra relais nodig en dus ga ik dat niet redden met een Unio

Voordat je plannen gaat maken:

  • Een Uno heeft 19 tot 22 I/O-pins, afhankelijk van de vraag hoeveel andere functies je wilt opofferen.
  • Er bestaan zg. I/O-extenders waarmee je grote aantallen pins aan het systeem kunt toevoegen:
    ** 74HC595: 3 draden (en VCC/GND) naar de Uno, 8 extra I/O- outputpins. Je kunt ze achter elkaar schakelen, elke '595 geeft nóg 8 pins. Theoretisch kun je eindeloos doorgaan, maar dan wordt alles wel steeds trager.
    ** PCF8574: 2 draden (en VCC/GND), 8 extra I/O-pins. Parallel aansluiten op de I2C-bus, elk IC heeft een eigen adres, dat geeft max. 8 ic's met in totaal 64 extra pins.
    ** PCF8574A: idem, maar op andere adressen, dus nogmaals 64.
    ** PCF8575: idem, maar 16 extra pins per IC. Max. 8 op de bus, dus 128 extra pins.

Je kunt dus echt nog wel even vooruit. :wink: PS.: Zelfs met een Nano (2 euro bij Ali) kan het.

Later meer.

Edit: "I/O-pins" 74HC595 gecorrigeerd, het zijn nl. outputpins.

Oke oke oke! :slight_smile:

Blijkt dus dat ik met die Uno nog best alle kanten op kan en nog best 6 relais kan aansturen.
Of, als het allemaal niet snel hoeft, ook wel 60, haha!

Ja, ik heb me flink ingelezen in de delen van het programmeren waarvan ik dacht dat ze nuttig waren, maar het blijkt dus dat er nog véél meer aan te pas moet komen. leuk en leerzaam!

Ik baal er alleen van dat ik de fout in de millis nog niet gevonden heb! :angry:
Ga ik me nog verder in verdiepen.

Ik heb ook al in de gaten (mijn eigen tekst terug lezend), dat het best wel onduidelijk is wat ik voor mekaar wil krijgen... Speciaal daarom; we gaan video kijken! Popcorn erbij en druk maar op play! :slight_smile:

De bedoeling van deze sketch

Duik ik nog even in de millis... ik moet die fout toch kunnen vinden?? :smiling_imp:

het random getal zorgt ervoor dat zowel de vertekwissels als de aankomstwissels goed staan en een trein gaat rijden, na 2 seconden kan het rijden uit want trein is weg,als de trein terug is door de bezetmelding dan laat je weer een random spoor vertrekken en ja misschien is dat dezelfde.
Ook zonder bezetmelding kan het werken maar dan pak je gewoon de langste rijtijd als minimum wachttijd. eigenlijk heb je maar 3 relais nodig voor 8 sporen en dan nog een rijrelais om het juiste spoor te laten rijden.
de relais staan digitaal achter elkaar dus 1 contact om rechtdoor of te buigen. plus een pulsrelais om te schakelen, en dan heb je nog een contact nodig voor de rijspanning. dus in totaal 5 uitgangen. als je meer wilt weten laat maar horen dan maak ik er een schema voor.

Hier ging het fout met de timing,door prevMillis gelijk te stellen aan millis().
Het moest zijn prevMillis = curMillis;//Onthoud de tijd
Eigenlijk was het een fout wat ik zelf tegenkwam door vlug wat te typen.
Het probleem was dat ik erover heen las en het ook niet direct zag.
Maar één ding is zeker , je kent het gebruik van millis() nu op een draadje dankzij de voorbeelden van Koepel.
In de veronderstelling dat je de flow van de sketch onder de knie hebt ,op naar de suggestie van Koepel.
FSM finite state machine ,om je volgende verwachtingen te vervullen.

Zoiets is de bedoeling. De met zwart aangegeven optie, is eigenlijk vals spelen. Althans, niet geheel, zo wilde ik het in eerste instantie gaan doen, voor de Arduino zeg maar, hi.

Paul, ik ben heel benieuwd naar hoe je dit met minder relais wil gaan doen. Ik moet erbij vermelden, de 'puls' (want meer is die 300ms niet) die voor de wissels bestemd is, mag absoluut geen langeduur-contact zijn. De wisselspoelen hebben namelijk géén eindafschakeling! Dus, bij langdurig contact zullen de wisselspoelen onherstelbaar beschadigen. Zeg maar gerust; eruit fikken. Nou zijn een paar M-rail wissels niet zo duur, voor onder de twee tientjes ben je klaar, maar dat wil je gewoon niet, zeker niet bij een schaduwstation wat niet zo makkelijk te bereiken is.

Hieronder even de schematische voorstelling...

Jammer de tekening is niet heel zuiver,kan ze slecht lezen.
Maar een puls geven van een paar milli seconden is echt geen probleem hoor.
Best kun je daarvoor een functie schrijven die je aanroept van uit de loop.
Dit alles kan nog op je Uno.
Het is aan jouw beurt om een gestroomlijnde flowchart te maken van wat moet gebeuren op welke tijdstippen.
Nothing fancy ,doet dat gewoon met pen of potlood op een stuk papier .
Voor de rail detectie kun je misschien opteren voor opto coupler of reed-contact,etc...
Ook bij het random gedeelte zou je ervoor kunnen zorgen dat niet 2-maal het zelfde spoor gekozen wordt.(een paar voorwaarden bijbouwen in de keuze van random)
Leuk projectje .