BeneluxSpoor.net forum

Vraag en antwoord => Elektronica en analoog => Topic gestart door: Edsko Hekman op 14 mei 2018, 10:59:15

Titel: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 14 mei 2018, 10:59:15
Hi,

misschien vervuil ik dit draadje nu wel (te veel?), maar ik leg mijn vraag nu even hier neer. Want ik weet het niet allemaal.

Zie onderstaande foto/. Dit is mijn black box voor Grasland, de linkerkant om precies te zijn.

(https://images.beneluxspoor.net/bnls/20180514-102106-1.jpg) (https://images.beneluxspoor.net/bnls/20180514-102106-1.jpg)

Geel (?) is het "Ben sluisje" in de rail gelegd, rood is als ik het als lichtsluis ga gebruiken. Want dat is wat ik er van begrepen heb, corrigeer me als ik er naast zit. Ik dacht te lezen dat als je de ontvanger (of zender) losknipt en op een andere plek plaatst (en weer verbind natuurlijk) dat je dan ook gebruik kunt maken van dit sluisje. Ik hoef me over camouflage geen zorgen te maken, want het zit achter een schot, dus geen hond die het ziet op een beurs oid. Wellicht wel even een beveiliging voor de componenten er overheen, maar meer ook niet lijkt me.
Is de rode optie iets dat kan werken met het sluisje?

Dank voor de uitleg alvast.

Gr.

Edsko
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 14 mei 2018, 11:07:12
Edsko,

Gezien het feit dat jij het op een beurs wilt gaan gebruiken in een module baan, zal er niet alleen eigen materieel de overweg bedienen. Een reflectie sluis kan werken, maar heeft zijn beperkingen (Zie inhoud draadje). Een straal lichtsluis (je rode stippen) heeft dan de voorkeur. Je hebt de straal keurig schuin over het spoor gericht, hierdoor zal je trein als een geheel worden gezien. Ik vraag me alleen af of de hoek groot genoeg is, gezien de afstand bij bv goederenwagens (twee ketelwagens met bordes). Iets schuiner over het spoor zal denk ik dat probleem oplossen. De afstand tussen de punten mag vrij fors zijn.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Te 2/2 op 14 mei 2018, 11:17:46
Goeie visualisatie, zeg!

straal breking (rode stippen)
Met "Ben's sluisje" werkt diagonaal over de rails betrouwbaar,
dat is transmissief gebruik, de trein onderbreekt de lichtstraal.
Hoe goed het werkt, is afhankelijk van de afstand tussen de wagons,
en de afscherming van zender en ontvanger tegen licht van boven af.
Een simpel petje op zender en ontvanger, meterkastje erom, plankje, verzin het wat,
houdt direct licht van boven weg.
Friedel Weber, in Lichtschranke, plaatste zijn zenders en ontvangers recht tegenover elkaar,
en op exact dezelfde hoogte, en dat maakt zijn oplossing een stuk minder betrouwbaar.
Als zijn straalhoogte niet exact gelijk valt met de treinkoppelingen,
dan krijgt hij een onderbreking na elke passerende wagon:
(https://werthof.home.xs4all.nl/treintjes/dc/fw_recht.jpg).

Diagonaal geplaatst (en ook in hoogte diagonaal) heeft een aantal voordelen
boven recht tegenover elkaar en op dezelfde hoogte.

straal weerkaatsing (gele stippen)
De gele stippen staan voor het reflexief gebruik (weerkaatsing):
op zo'n plek heb je zender+ontvanger op zeer geringe afstand van elkaar
tussen de bielsen, en ze wijzen allebei omhoog.
Dat gaat alleen goed als je er een segment met b.v. een blokje huizen of heuvel boven zet.

Niet zo heel veel anders dan wat er in de TCRT5000 behuizing zit.
Je bent alleen iets vrijer in de afstand tussen zender en ontvanger,
en de richtingen waarheen ze wijzen.
Vanuit de TCRT-behuizing kijken ze recht omhoog.

En volgens mij wijkt Ben daar wat af bij plaatsing van zender en ontvanger.
Maar hij zal er zelf wel mee komen als ik abuis ben.
Pssst.... Ben....   ;D

Dit is ook reflexief gebruik (foto van Ben, eerder uit dit draadje):
(https://imagizer.imageshack.com/v2/1280x1024q90/922/Y069x5.jpg)
En dat zou je bij een 2-baans overweg ook kunnen gebruiken,
om treinen in beide banen met een en het zelfde lichtsluisje te bewaken.
Maar juist bij een overweg heb je dan ook nog een andere kant om te bewaken.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 14 mei 2018, 12:09:41
Hi guys,

dank voor de uitleg.

@Gerard: de hoek kan best groter, er ligt ongeveer 30cm rails op de BB, dus dat zou ruimte genoeg moeten geven qua hoek.

Goeie visualisatie, zeg!
dank. :)

straal breking (rode stippen)
en de afscherming van zender en ontvanger tegen licht van boven af.
Een simpel petje op zender en ontvanger, meterkastje erom, plankje, verzin het wat,
houdt direct licht van boven weg.
Ik heb over de gehele lengte van de BB (+/- 30 cm) een "tunnel" staan (binnenkant zwart geverfd). Er valt dus geen licht van boven op de zender en ontvanger. Dus dat is alvast geregeld. ;)

Maar ik begrijp dat ik bijvoorbeeld de ontvanger los kan knippen van de print en ander de andere zijde van de rails kan plaatsen, waarbij ik natuurlijk wel "even" de ontvanger weer verbind met de print. Klopt dit? Zo ja, dan maak ik er gewoon een straal onderbreking van. Ik vind het wat te ver gaan om van iedere BNLS baan deelnemer te vragen om zijn materieel van koper- of alu tape te voorzien aan de onderzijde.  :-\

Ik heb 20 van die dingen bestelt als het goed is, dus ik kan wat oefenen zal ik maar zeggen. ;)

Gr.

Edsko
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: nederbelg op 14 mei 2018, 12:43:05
Hoi,

Ben zijn opstelling in de loods is op +/- 5 - 10 cm van de detectie zone.
Waarom zou een detectie ingebouwd in het baanlichaam dan niet werken?
De detectie (reflexie) is dan maar op 1 cm afstand!

Ik heb ze ook besteld, testen zal uitwijzen welke opstelling ik zal gebruiken.

Dave


Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Fransx op 14 mei 2018, 22:19:57
Hoi
Dacht, reageer toch even want over IR reflectie is al voldoende geschreven, zie deze topic:

https://forum.beneluxspoor.net/index.php?topic=72888.msg32

Echter door ervaring zal deze toch soms om onderling storing te voorkomen ontkoppeld moeten worden, een diode in de plus voeding en daarachter een condensator over de plus en min, komt neer op het eerdere omschreven schema in deze topic. Gebruikte diode bij mij is een 1N4148 en de uitgang kan rechtstreeks op een S88 ingang.

Frans
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 14 mei 2018, 23:55:54
POST!!

(https://images.beneluxspoor.net/bnls/20180514-195034.jpg) (https://images.beneluxspoor.net/bnls/20180514-195034.jpg)

De boel kan beginnen. :)

Wat is nu de zender en wat de ontvanger? En maakt het nog uit welke ik losmaak en op afstand weer verbind? Ik heb zelf het idee dqat het niet uitmaakt, maar hoor dat graag bevestigd door iemand die er meer van weet dan ikke. :)

Ik heb er nu dus 20, dus als er één sneuvelt, och... ;)

Gr.

Edsko
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 15 mei 2018, 06:40:45
Edsko,

Het maakt inderdaad niet uit. Als je het echt wilt weten, maak dan een foto van onder en bovenkant. Kijk ik even of ik het langs deze weg kan vertellen. Vaak is de donkere LED de zender.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Te 2/2 op 15 mei 2018, 09:51:15
@Fransx
Citaat
over IR reflectie is al voldoende geschreven
Klopt, maar ik begon het draadje over de toepassing van reedrelais, en Ali-lichtsluisjes.
Ali-lichtsluisjes hebben goedkope fotodiodes als ontvanger, geen IS471 dus.

Citaat
Echter door ervaring zal deze toch soms om onderling storing te voorkomen ontkoppeld moeten worden
Bedoel je daarmee dat de combinatie lichtsluisje(met IS471) + S88 soms ontkoppeld moet worden?

Waarom zou een detectie ingebouwd in het baanlichaam dan niet werken?
De detectie (reflexie) is dan maar op 1 cm afstand!
Ik hoop dat  je gelijk hebt. Dat ligt absoluut binnen de optimale marge van b.v. een TCRT5000 en ook binnen de marge van menig andere fotodiode.

Echter, het voorgaande samenvattend: Eerder in dit draadje (https://forum.beneluxspoor.net/index.php?topic=79736.msg3221854208#msg3221854208)
Citaat
Bij reflexie

Omgevingslicht (ambient light) heeft invloed op de ontvanger:
-Sterke directe straling verblindt de ontvanger. 
-Minder sterke maar constante straling maakt ontvanger slecht ziend.
-Variërende straling maakt dat ontvanger spoken ziet.
=>En vandaar een voorkeur voor afscherming boven de baan, bij gebruik van goedkope fotodiodes.

Omgevingslicht heeft invloed op het bestraalde object.
- totaal geen waarneming (met name bij plastics, en met name bij zwarte kleuren),
- sterk verminderde waarneming (met name bij plastics met grijze kleur),
- achtergrond krijgt soms groter contrast dan bestraalde object

=>En vandaar het idee om bij zwart plastic of grijs plastic onderkanten van treintjes
    de zichtbaarheid te vergroten, bij gebruik van goedkope fotodiodes.

Er zijn 3 workarounds genoemd (bij reflexief gebruik van goedkope fotodiodes):
- behuizing met omgevingslicht-filter (zoals de TCRT5000)
- mechanische voorzieningen treffen (bij treintjes gaatje boren tussen de bielsen)
- wisselstroom gebruiken

=>Wisselstroom toepassing is een manier om met een goedkope fotodiode te doen wat de IS471 zelf kan (tacten van zender en ontvanger).
Het gebeuren staat uitgelegd in Vishay (application of optical sensors 80107, 2002).
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 15 mei 2018, 09:51:44
Hi,

zie hieronder de foto.

(https://images.beneluxspoor.net/bnls/20180515-091320.jpg) (https://images.beneluxspoor.net/bnls/20180515-091320.jpg)

Gr.

Edsko
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Te 2/2 op 15 mei 2018, 10:00:32
MH-Sensor Series Flying Fish, wow, wat zien ze er mooi uit.  (y)
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 15 mei 2018, 10:05:10
Hopelijk werken ze ook mooi.  ;)
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 15 mei 2018, 10:30:13
Op de foto is helaas geen spoor te zien. Ze mogen mooi zijn, als ze maar goed werken.
Mooi werken is voor mensen die creatief werken (behalve ICT-ers). Ik kan een print er mooi uit laten zien, maar dat is bij een stuk code nog nooit gelukt. Het inspringen en korte en lange regels zorgt er voor dat zo'n listing er niet uit ziet.
(Sorry even een stukje persoonlijke frustratie)

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 15 mei 2018, 15:59:12
Maakt het trouwens nog uit hoe ik de LED's aanbreng? Kan ik ze gewoon rechtop plaatsen of moet ik ze haaks op het houtwerk plaatsen? Ik ben geneigd ze haaks te plaatsen, maar dat is meer een gevoel. Moet ik zo op elkaar richten? Hoe nauwkeurig moet dat? De hoek kom ik wel uit, dat is niet het moeilijkste.

Wat ik wil doen, is op beide black boxen een lichtsluis maken, per spoor één. Als op het voorste spoor een trein van links naar rechts rijdt, dan zou op de linker black box de AKI met geluid aan moeten gaan en op de rechter black box de AKI met geluid weer uit moeten gaan. Is dat mogelijk? Ik gebruik de lichtsluizen dan als aan-/uit schakelaar. Stel dat dit zo geimplementeerd kan worden, zou het dan ook automatisch goed werken als er op het voorste spoor van rechts naar links gereden wordt?

Er is een Arduino in huis die ik hier voor wil/kan gebruiken.

Nieuwe materie voor me, wel geinig. :)

Gr.

Edsko
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 15 mei 2018, 17:56:28
Maakt het trouwens nog uit hoe ik de LED's aanbreng? Kan ik ze gewoon rechtop plaatsen of moet ik ze haaks op het houtwerk plaatsen? Ik ben geneigd ze haaks te plaatsen, maar dat is meer een gevoel. Moet ik zo op elkaar richten? Hoe nauwkeurig moet dat? De hoek kom ik wel uit, dat is niet het moeilijkste.
Richt ze naar elkaar, de stralingshoek van de led is beperkt. Ik gebruik ze ook maar dan reflectief.

Citaat
Wat ik wil doen, is op beide black boxen een lichtsluis maken, per spoor één. Als op het voorste spoor een trein van links naar rechts rijdt, dan zou op de linker black box de AKI met geluid aan moeten gaan en op de rechter black box de AKI met geluid weer uit moeten gaan. Is dat mogelijk? Ik gebruik de lichtsluizen dan als aan-/uit schakelaar. Stel dat dit zo geimplementeerd kan worden, zou het dan ook automatisch goed werken als er op het voorste spoor van rechts naar links gereden wordt?

Er is een Arduino in huis die ik hier voor wil/kan gebruiken.
Niet automatisch. Als je per spoor links en rechts een aparte lichtsluis hebt, zeg voor het voorste spoor in de linker BB ,noem die detector VL. Voor het voorste spoor rechter BB, noem die VR etc. dan kun je op het afgaan van VL de AKI aan zetten en op het aangaan van VR de AKI uitzetten. Voor het achterste spoor is dan de volgorde AR AKI aan, AL AKI uit. Het probleem is dan als een trein op het verkeerde spoor zit. Dan zul je iets meer met de triggers moeten doen. Bijvoorbeeld, de AKI is standaard uit, zodra nu een van de lichtsluisjes uit een paar (VL en VR of AR en AL) triggered gaat de AKI aan, zodra nu de andere uit het paar triggered gaat de AKI weer uit. Dit werkt alleen goed als de lichtsluis zodanig schuin staat dat er niet tijdens het passeren van een trein de detector uit en aan gaat. Als dat gebeurd zul je met timers moeten werken om korte onderbrekingen uit te filteren. Een ander probleem is, wat gebeurd er als er twee treinen tegelijkertijd (een van links en een van rechts) komen. Dan zul je tellers moeten bijhouden over het aantal treinen dat in je module zit .

Ik hoop dat ik het niet te complex maak.

Groet
Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 15 mei 2018, 18:08:35
Mooi werken is voor mensen die creatief werken (behalve ICT-ers). Ik kan een print er mooi uit laten zien, maar dat is bij een stuk code nog nooit gelukt. Het inspringen en korte en lange regels zorgt er voor dat zo'n listing er niet uit ziet.
(Sorry even een stukje persoonlijke frustratie)

Gerard

als ik dat stukje code, dat ik van je heb, bekijk, dan valt het wel mee. Maar je hoeft natuurlijk commentaar niet op de zelfde instructie regel te zetten, dat kun je ook erg goed voor de instructie te zetten. Dan kun je ook veel meer commentaar kwijt en houd je de regels korter. Overigens ook sommige ICT-ers houden van net werk en ook een programma kan een zekere schoonheid hebben. Maar er is natuurlijk wel een officiele wedstrijd in onbegrijpelijk coderen, nl. de Obfuscated C contest (https://www.ioccc.org/)

Groet
Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 15 mei 2018, 22:01:01
Esso,

Doe zoals het grootbedrijf het doet. Als je de sensoren van de linker BB een teller met 1 laat verhogen en de sensoren  van de rechter BB de teller met 1 last verlagen ben je klaar. Zolang de teller 0 is is je Aki uit. Alleen met trein plaatsen in grasland geeft dan nog problemen. Maar even met je hand door de lichtsluis achter de trein en dat is ook opgelost.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 15 mei 2018, 22:41:27
Richt ze naar elkaar, de stralingshoek van de led is beperkt. Ik gebruik ze ook maar dan reflectief.
Check! Ga ik doen.

Een ander probleem is, wat gebeurd er als er twee treinen tegelijkertijd (een van links en een van rechts) komen. Dan zul je tellers moeten bijhouden over het aantal treinen dat in je module zit .
Deze had ik idd ook bedacht nadat ik mijn vorige bericht had ingetypt. Maar geen oplossing nog bedacht. Maar het klinkt alsof het op te lossen is. Dat is fijn. Ik krijg steeds meer zin om de zaken eens uit te gaan proberen. Nu nog voeding voor die vliegende vissen. ;)

Ik hoop dat ik het niet te complex maak.
Ben je gek! Fijn dat je meedenkt! (y)

Denk dat ik eerst alles maar eens ga proberen met een lampje dat aan en uit gaat. Moet ik nog technisch gaan doen ook. Wie had dat gedacht...

Gr.

Edsko
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 15 mei 2018, 22:43:19
Esso,
Het is meer dan 30 jaar geleden toen mijn 8 jarige buurjongen mij zo noemde...  ;D

Gr.

Edsko ;)
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 15 mei 2018, 23:56:14
Nu nog voeding voor die vliegende vissen. ;)

Dat is makkelijk, VCC op de 5v van de Arduino, gnd op een gnd van de Arduino en de output op een pin van de Arduino die je kunt uitlezen.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 16 mei 2018, 00:02:16
Check!  (y)
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 16 mei 2018, 10:08:12
<off topic>
Even een domper voor je Edsko (sorry voor de verschrijving net), ga in gedachten is met een trein van circa 80 cm over je module bak. Je zult zien dat het geheel dan niet goed werkt.
</off topic>

Ik denk dat je even voor je overweg een nieuw draadje moet openen, want dit gaat over de Ali lichtsluisjes (Sorry is mijn mening en ik ben geen moderator, dus heb eigenlijk niets te zeggen).

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 16 mei 2018, 10:10:29
Ik twijfelde ook al of ik dit niet gewoon in Grasland moet bespreken. Laten we dat dan maar doen. Ik meld het bij de mods.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Te 2/2 op 16 mei 2018, 11:23:01
Ik zie dat je de link aan de grasland kant (https://forum.beneluxspoor.net/index.php?topic=60837.msg3221857796#msg3221857796) al gelegd hebt.

Als je overwegbesturing (Arduino en lichtsluizen) in een aparte rubriek  (Elektronica en analoog  of Digitaal) stopt, dan draagt dat bij aan de forumordening, en daarmee de kans op repliek. In beide rubrieken zitten Arduino toepassingen. Duidelijk is met zoekopdracht (overweg arduino) dat zulke draadjes nu nog echt overal te verwachten zijn

Het zal voor de moderators inmiddels wel te veel werk zijn om een aparte rubriek Arduino te maken.  Met daaronder apart analoge en digitale toepassingen, of aparte deelgebieden zoals bezetmelding, koppelrails, lokomloop, lokwissel, overwegen, pendelen, seinen, wissels.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 16 mei 2018, 12:24:34
Bericht gemeld. Nu even wachten op een mod. Komt goed.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Te 2/2 op 19 mei 2018, 18:12:46
Friedel Weber, in Lichtschranke, plaatst zijn zenders en ontvangers recht tegenover elkaar,
en op exact dezelfde hoogte, en dat maakt zijn oplossing een stuk minder betrouwbaar.
Als zijn straalhoogte niet exact gelijk valt met de treinkoppelingen,
dan krijgt hij een onderbreking na elke passerende wagon.
(...)
Diagonaal geplaatst (en ook in hoogte diagonaal) heeft een aantal voordelen
boven recht tegenover elkaar en op dezelfde hoogte.(...)

Dat denk je dan, tot deze reactie in het digitale draadje (lichtsluis, waar verkrijgbaar) (https://forum.beneluxspoor.net/index.php?topic=79634.msg3221858783#msg3221858783):

Blausee-Mitholz heeft z'n lichtsluis schuin (niet haaks erop) over het spoor gericht, en de zender staat hoger opgesteld dan de ontvanger. Toch gaat het fout: want de lichtstraal vangt de koppelingen niet.

Mogelijke oorzaak: in een boog met krappe radius (circa 36 mm) zwenken de koppen van rijtuigen te ver uit, en kan de straal er tussen door piepen (indien niet gericht op de koppelingen zelf).

Mogelijke oplossing in termen van Ali-lichtsluisjes: je neemt  2 sluisjes om een bepaalde situatie af te dekken, en de OUT van beide sluisjes sluit je aan op het zelfde relais of op de zelfde s88 melder. 
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Reinout van Rees op 19 mei 2018, 20:55:03
Op verzoek afgesplitst. Ik heb het bij "elektronica en analoog" als categorie gehouden en de titel aangepast. De vlag dekt de lading zo, neem ik aan?

Reinout-als-moderator
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 19 mei 2018, 21:14:57
Het feit dat Edsko met een Arduino gaat werken, maakt het leven een stuk gemakkelijker. In de programmering kun je allerlei scenario's opvangen. Het probleem van korte onderbrekingen omdat tussen de wagons de sensors elkaar weer kort zien, is simpel op te lossen met een timer. Ook de situatie van een korte trein kun je makkelijk programmatisch oplossen.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Te 2/2 op 19 mei 2018, 22:32:26
Ook de situatie van een korte trein kun je makkelijk programmatisch oplossen.
Daar had ik nog niet bij stilgestaan.  (y)
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 19 mei 2018, 23:03:01
Eigenlijk kun je het probleem reduceren tot een "finite State Machine" (Eindigetoestandautomaat). Dus is het een kwestie van alle mogelijke toestanden (states) van het systeem en de bijbehorende mogelijke overgangen te bepalen. Bijvoorbeeld, toestand 1 is "Er is geen trein in de module", dit zou de begin toestand kunnen zijn.
Toestand 2 zou kunnen zijn "een lichtsluis detecteert het passeren van een trein". Toestand 3 zou kunnen zijn "Er is geen lichtsluis meer over die een trein detecteert". De mogelijke overgangen zouden dan zijn van 1 naar 2, maar van 1 naar 3 kan niet. van 3 naar 1 kan weer wel en van 2 naar 3 ook, maar van 2 naar 1 weer niet.
Het is een beetje puzzelen, want je hebt te maken met 2 sporen en dus meerdere mogelijkheden, maar het staat los van het programmeren, het is gewoon goed nadenken over wat er gebeurd. Maar als je dit eenmaal op papier hebt is het programma zelf voor dit gedeelte makkelijk te schrijven. Je houdt natuurlijk nog genoeg uitdagingen over, zoals het aansturen van de aki's en de generatie van de bellen.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 22 mei 2018, 11:54:37
Oke,

Alles even samenvatten:

Eisen/Wensen:

Aansturing van een AKI door een trein. Aan de trein mogen geen aanpassingen gedaan worden. De AKI is dubbelsporig en moet van beide zijde op hetzelfde spoor aangestuurd worden. Gekozen is voor aansturing via "lichtsluizen" en een Arduino.
Eventuele knippenringen door de lichtsluizen worden door een schuine opstelling verminderd, geheel voorkomen kan niet. Dit wordt niet door extra hardware opgelost.

Opstelling:

(https://images.beneluxspoor.net/bnls/Lichtsluizen.jpg) (https://images.beneluxspoor.net/bnls/Lichtsluizen.jpg)
Even in "Grasland" gekeken voor de juiste opstelling. De overweg bevind zich links op de module. Dus er is een ongelijke tijd voor het aanrijden van de AKI. Is in dit geval niet storend, daar de korte aanrijtijd door de BBL (blackbox links) gecamoufleerd wordt. De rode lijnen zijn de 4 sensoren voor de AKI aansturing.


Schema:

(https://images.beneluxspoor.net/bnls/SchemaLichtsluizen.jpg) (https://images.beneluxspoor.net/bnls/SchemaLichtsluizen.jpg)
Voeden uit de Arduino. De sensoren zullen ieder zo'n 30mA trekken, dus dat moet kunnen. Voeden uit de USB poort van de PC is dan niet meer mogelijk. De voeding van de Arduino gebruiken. Waar de 4 sensoren aangesloten worden is niet van belang, zolang pen 0 (RX), 1 (TX) en 13 (LED) maar niet gebruikt worden. Probeer zoveel mogelijk de pennen 2 (INT0) en 3 (INT1) te vermijden. In dit geval is dat niet nodig, daar we deze functionaliteit toch niet nodig hebben.

Software:

// Definitie van de 4 ingangen voor de sensoren
#define SBBLSP1    3   // BlackBox Links, Spoor 1
#define SBBLSP2    4   // BlackBox Links, Spoor 2
#define SBBRSP1    5   // BlackBox Rechts, Spoor 1
#define SBBRSP2    6   // BlackBox REchts, Spoor 2

#define DELAY    500   // Vertraging in milli seconde

// Laatste stand van de melder
bool MBBLSP1;
bool MBBLSP2;
bool MBBRSP1;
bool MBBRSP2;

// Timers om het vrijgeven te vertragen
unsigned long TSBBLSP1;
unsigned long TSBBLSP2;
unsigned long TSBBRSP1;
unsigned long TSBBRSP2;

// Variabelen die richting in de sporen bij houden
// < 0: trein rijdt van rechts naar links
// 0: geen trein
// > 0: trein rijdt van links naar rechts
byte DIRSP1;
byte DIRSP2;


// Functies om de melders te lezen (true = bezet)
bool readBBLSP1() {
  // if (digitalRead(SBBLSP1) > 0) {
  if (digitalRead(SBBLSP1) == 0) {
    TSBBLSP1 = millis() + DELAY;
  }
  return (TSBBLSP1 > millis());
}

bool readBBLSP2() {
  // if (digitalRead(SBBLSP2) > 0) {
  if (digitalRead(SBBLSP2) == 0) {
    TSBBLSP2 = millis() + DELAY;
  }
  return (TSBBLSP2 > millis());
}

bool readBBRSP1() {
  // if (digitalRead(SBBRSP1) > 0) {
  if (digitalRead(SBBRSP1) == 0) {
    TSBBRSP1 = millis() + DELAY;
  }
  return (TSBBRSP1 > millis());
}

bool readBBRSP2() {
  // if (digitalRead(SBBRSP2) > 0) {
  if (digitalRead(SBBRSP2) == 0) {
    TSBBRSP2 = millis() + DELAY;
  }
  return (TSBBRSP2 > millis());
}

// Initialialatie van de Arduino
void setup() {
  // put your setup code here, to run once:
  // Maak de inputs met extra pullups
  pinMode(SBBLSP1, INPUT_PULLUP);
  pinMode(SBBLSP2, INPUT_PULLUP);
  pinMode(SBBRSP1, INPUT_PULLUP);
  pinMode(SBBRSP2, INPUT_PULLUP);
  // Zet de interne LED output
  pinMode(LED_BUILTIN, OUTPUT);
  // Initialiseer de laatste waarde
  MBBLSP1 = readBBLSP1();
  MBBLSP2 = readBBLSP2();
  MBBRSP1 = readBBRSP1();
  MBBRSP2 = readBBRSP2();
  // Initialiseer de timers
  TSBBLSP1 = millis();
  TSBBLSP2 = millis();
  TSBBRSP1 = millis();
  TSBBRSP2 = millis();
  // Meld geen trein (waarde 0)
  DIRSP1 = 0;
  DIRSP2 = 0;
  // LED uit
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:

  // fase: toestand nu en de vorige keer van de melder
  // volgorde:
  //  0: geen trein
  //  1: trein komt binnen
  //  2: trein verlaat
  //  3: trein aanwezig
  byte fase;

  // Spoor 1 (links)
  fase = (MBBLSP1 ? 2 : 0);
  MBBLSP1 = readBBLSP1();
  fase += (MBBLSP1 ? 1 : 0);
  if (fase == 1) {
    // Trein komt binnen
    if (DIRSP1 == 0) {      // Bij het bereiken van de andere kant alleen reageren op het verlaten
      DIRSP1++;       
    }
  }
  if (fase == 2) {
    // Trein verlaat
    if (DIRSP1 < 0) {       // Bij het verlaten van de binnen melder niet een extra puls geven.
      DIRSP1++;
    }
  }
  // Spoor 1 (rechts)
  fase = (MBBRSP1 ? 2 : 0);
  MBBRSP1 = readBBRSP1();
  fase += (MBBRSP1 ? 1 : 0);
  if (fase == 1) {
    // Trein komt binnen
    if (DIRSP1 == 0) {      // Bij het bereiken van de andere kant alleen reageren op het verlaten
      DIRSP1--;       
    }
  }
  if (fase == 2) {
    // Trein verlaat
    if (DIRSP1 > 0) {       // Bij het verlaten van de binnen melder niet een extra puls geven.
      DIRSP1--;
    }
  }
 
  // Spoor 2 (links)
  fase = (MBBLSP2 ? 2 : 0);
  MBBLSP2 = readBBLSP2();
  fase += (MBBLSP2 ? 1 : 0);
  if (fase == 1) {
    // Trein komt binnen
    if (DIRSP2 == 0) {      // Bij het bereiken van de andere kant alleen reageren op het verlaten
      DIRSP2++;       
    }
  }
  if (fase == 2) {
    // Trein verlaat
    if (DIRSP2 < 0) {       // Bij het verlaten van de binnen melder niet een extra puls geven.
      DIRSP2++;
    }
  }
  // Spoor 2 (rechts)
  fase = (MBBRSP2 ? 2 : 0);
  MBBRSP2 = readBBRSP2();
  fase += (MBBRSP2 ? 1 : 0);
  if (fase == 1) {
    // Trein komt binnen
    if (DIRSP2 == 0) {      // Bij het bereiken van de andere kant alleen reageren op het verlaten
      DIRSP2--;       
    }
  }
  if (fase == 2) {
    // Trein verlaat
    if (DIRSP2 > 0) {       // Bij het verlaten van de binnen melder niet een extra puls geven.
      DIRSP2--;
    }
  }
 
  // Aansturen van de AKI / AHOB (overweg)
  if ((DIRSP1 == 0) && (DIRSP2 == 0)) {
    // Overweg geopend
    digitalWrite(LED_BUILTIN, LOW);
  } else {
    // Overweg gesloten
    digitalWrite(LED_BUILTIN, HIGH);
  }
}
Uitleg bij de code:
In de eerste regels zijn de ingangen gedefinieerd. Gebruik gewoon de nummers die op het Arduino bordje staan. Doordat de ingangen nu een naam hebben gekregen zijn ze gemakkelijk te gebruiken in de code.
Hierna is de vertraging gedefinieerd, die bij het wegvallen van de detektie opgeteld wordt om in de software korte onderbrekingen op te vangen.

Dan volgen de variabelen zoals die gebruikt worden in het programma. Als eerste 4 booleans om de stand van de melder te onthouden. Daarna 4 timers om bij te houden wanneer voor het laatst een sensor is gezien.
Tenslotte een tweetal variabelen om de toestand van de sporen vast te leggen. Dit is een zogenaamde state variabele (zie uitleg Meino).

Nu volgens de functies waaruit het programma is opgebouwd, naast de verplichte functies setup() en loop().
Dit zijn 4 functies die ieder een sensor behandelen.
De werking van de functie is als volgt:
Eerst wordt het niveau van de ingang vastgesteld. Meld deze dat er een trein aanwezig is, dan wordt de timer van deze ingnag geladen met de huidige stand van de millis teller (interne teller van de Arduino) plus de vertraging.
Tenslotte wordt er boolean gemaakt die aangeeft of de huidge stand van de millis teller kleiner is dan de timer value.
Dit is om te zorgen dat het resultaat van deze functies niet gestoord wordt door verstoringen, doordat de uitgang van de sensor even van stand veranderd.
Dan volgen de verplichte functies setup() en loop(). Setup zal alle in- en uitgangen goed zetten en de variabelen van hun begin waarde voorzien.
Loop() is het uiteindelijke programma. Ook hier wordt weer een finite state pattern gebruikt (het is tenslotte mijn favoriete pattern en ben de "Gang of four" dankbaar voor het definiëren.) Het gaat in dit geval om de variabele fase. Deze kent de waardes 0 t/m 3 en ontstaat uit de waarde van de sensor van de vorige loop() doorloop en de huidige. De waarde van fase doorloopt de 4 waardes op de volgende manier:
De waarde van de melder uit de vorige loop zal de waarde van fase vullen met 0 (geen trein) of 2 (trein). Hierna wordt naar aanleiding van de huidige weaarde er 0 (geen trein) of 1 (trein) bij opgeteld. Als een trein door de sensor (lichtsluis) rijdt, ontstaat nu het volgende patroon:
.......000013333........333320000........
De waardes 0 en 3 komen vaak voor en vertellen dat de situatie constant is gebleven. Echter 1 (voorkant van de trein) en 2 (achterkant van de trein) komen per passage maar een keer voor. Nu moet alleen nog uitgezocht worden hoe de toestand waarin het spoor rond de AKI zich bevind is. Hiervoor zal de volgende finite state variabele gebruikt worden. Dit is dirSPx. Deze variabele kent de waardes 0 (geen trein), 1 (trein rijdt van links naar rechts) en -1 (trein rijdt van rechts naar links). De variabele idrSPx mag alleen onder bepaalde voorwaarde verhoogd / verlaagd worden.
Uiteindelijk zal dirSPx altijd terug komen op 0. Als alle dirSPx variabelen 0 zijn, mag de AKI geopend worden. Indien een disSPx niet 0 is moet de AKI gesloten worden. In dit geval zal bij gesloten AKI de LED op de Arduino oplichten en pen 13 5V voeren, ten teken dat de AKI dicht moet.
(Verderop gaan we de code uitbreiden met het aansturen van de LEDs van de AKI.)

Huiswerk:  ;D
@Edsko (en wie nog meer wil):
Schakeling bouwen en testen. We zijn hier nieuwsgierig naar het resultaat. Gezien het weer verwachten we dat je een poosje bezig zult ziijn.

@Allen:
Mochten er vragen opmerkingen of andere dingen zijn, post ze gerust.

@C goeroes:
Het programma roept om optimalisatie. Ik weet dat dit mogelijk is, maar moet te veel research op het internet doen om het in C voor elkaar te krijgen.
Help mij en Edsko door met voorbeelden te komen hoe stukken code geoptimaliseerd kunnen worden. Zie het als een een simpele wedstrijd zoals Meino aangaf.

Zo ik ga met vakantie en zal alleen via mijn mobiel meelezen en reageren. Dus verwacht de komende dagen geen lappen tekst meer.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 22 mei 2018, 12:28:19
Oke,

Alles even samenvatten:

Eisen/Wensen:

Aansturing van een AKI door een trein. Aan de trein mogen geen aanpassingen gedaan worden. De AKI is dubbelsporig en moet van beide zijde op hetzelfde spoor aangestuurd worden. Gekozen is voor aansturing via "lichtsluizen" en een Arduino.
Eventuele knippenringen door de lichtsluizen worden door een schuine opstelling verminderd, geheel voorkomen kan niet. Dit wordt niet door extra hardware opgelost.

Je bent snel. Ik vind het ook een mooie uitdaging/puzzle, dus ben ik ook maar aan een stukje code begonnen, alleen mijn code is totaal anders (Object oriented met classes), wel gebruik ik de zelfde toestanden als jij. Als ik klaar ben zal ik mijn versie ook wel even publiceren.

Citaat
@C goeroes:
Het programma roept om optimalisatie. Ik weet dat dit mogelijk is, maar moet te veel research op het internet doen om het in C voor elkaar te krijgen.
Help mij en Edsko door met voorbeelden te komen hoe stukken code geoptimaliseerd kunnen worden. Zie het als een een simpele wedstrijd zoals Meino aangaf.
Ik ben lang geleden gestopt om de code zelf te optimaliseren, mijn ervaring is dat de GNU compilers dermate goed zijn in het optimaliseren, dat eigen pogingen vaak averechts werken of hooguit geen invloed hebben. Ik vind het veel belangrijker dat de code goed leesbaar is.

Citaat
Zo ik ga met vakantie en zal alleen via mijn mobiel meelezen en reageren. Dus verwacht de komende dagen geen lappen tekst meer.
Prettige vakantie, ook ik vertrek van de week. Heb wel de laptop bij me, dus zolang er wifi is kan ik kontact houden.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 22 mei 2018, 13:47:34
<off topic>
(https://images.beneluxspoor.net/bnls/DelChatoDeltebre.jpg) (https://images.beneluxspoor.net/bnls/DelChatoDeltebre.jpg)
Kom er al 11 jaar. In geen velden of "asfaltwegen" wifi te vinden. De telefoon gaat terug naar 3G. Internet is er traaaaaaaaag (dankzij de EU is er tenminste internet voor buitenlanders). Gaan twee keer per dag koffie drinken om "up to date" te blijven. Verder genieten van het groeien van de rijst in de rijstvelden (ja, ik ben in Europa). Maar eerst vrijdag en zaterdag 1700 km rijden met dit:
(https://images.beneluxspoor.net/bnls/20170609-093540-min.jpg) (https://images.beneluxspoor.net/bnls/20170609-093540-min.jpg)
<on topic>

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: NS264 op 22 mei 2018, 13:56:47
Met interesse kijk ik mee:

Ik heb een leuke voor jullie.

Zelfde situatie, alleen driesporig.

- knipperleds(oranje)
- stepper controller voor 2 servos voor slaghekwerk.
- fotocellen als lichtsluis.

Verder breadboard en verzameling weerstanden en toebehoren aan draad tot beschikking om te experimenteren.

Ben nu alleen ook niet thuis, maar wel van plan dit te gebruiken met een Arduino Mega 2560.

Zonodig in eigen draadje want het is niet met Ali-lichtsluisjes.

Heb een  leuk tutorial  (https://www.stummiforum.de/viewtopic.php?f=21&t=127532) (klik) gezien van een Duitser die ook nastuiterende slagboom geprogrammeerd heeft.
Erg interessant, moet ik ff opzoeken
Sketch staat er ook bij.

Start bij terugkomst uit het verre Lettele ::) wel een topic in deze hoek van het forum.

Gr Koen.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 22 mei 2018, 14:25:00
Hm een forum moderator. Nu even voorzichtig zijn, want voor het weet mag je niet meer op de site.

De code is "per spoor" geschreven. Als je de namen volgt dan zie je dat er SP1 en SP2 gebruikt wordt. Copieer iedere SP2 en maak daar SP3 van dan ben je al halverwege (SBBLSP3, SBBRSP3, MBBLSP3, MBBRSP3, TSBBLSP3, TSBBRSP3 en DIRSP3 ). Van de read functies de laatste twee copieren en de 2 vervangen door een 3 en tenslotte in setup() de nieuwe variabelen toevoegen en initialiseren.
In loop() het stuk gemarkeerd met spoor 2 (links) en spoor 2 (rechts) copieren (eronder). De 2-en vervangen door 3-en. en tenslotte de regel
if ((DIRSP1 == 0) && (DIRSP2 == 0)) {
vervangen door:
if ((DIRSP1 == 0) && (DIRSP2 == 0) && (DIRSP3 == 0)) {

Je hebt de code nu voor 3 sporen.
Het knipperen komt als Edsko er aan toe is, want ook zijn AKI gaat knipperen.

Groet,

Gerard van der Sel.

Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 22 mei 2018, 14:44:49
Met interesse kijk ik mee:

Ik heb een leuke voor jullie.

Zelfde situatie, alleen driesporig.

- knipperleds(oranje)
- stepper controller voor 2 servos voor slaghekwerk.
- fotocellen als lichtsluis.

Ik weet nog niet hoe het met Gerards code zit (dat nog niet goed bestudeerd), maar mijn code heeft daar geen probleem mee. Ik hanteer voor ieder spoor een aparte state machine. De stand voor de AKI wordt bepaald door een AND conditie over de staat van alle sporen. Dus het is simpel te imlementeren door de de AND conditie met extra sporen uit te breiden.
Het aansturen van steppers in plaats van leds is een wijziging in de techniek. en niet zo moeilijk.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: NS264 op 22 mei 2018, 15:13:24
@Gerard,

Ik maak gewoon dankbaar gebruik van alle technische kennis die er is hier.
Mijn kennis is 0.
Maar het lijkt me niet het allermoeilijkste om dit voorelkaar te krijgen.
Achter de forum schermen al een beetje opweg geholpen door Meino.
Loop wel iets vooruit op mijn eigen planning want ik wou eerst een enkele servo en een enkele led laten werken voor oefening, maar dat geloof ik naar aanleiding van de vele filmpjes op YouTube eerlijk gezegd wel en maakt het interessant voor mij om gelijk maar een stap verder te gaan.

Zoals ik al zei ben ik ook nu niet thuis, maar ik heb al een testplankje klaar liggen met stukje spoor om van start te gaan.

Zal het as weekend starten ;D
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 22 mei 2018, 19:03:56
Gerard was sneller met zijn code. maar ik was ook al begonnen omdat ik ook op Kranenberg wel een werkende AKI wil hebben.

Dit is mijn stukje code. Let wel het is nog niet getest. Voor test doeleinden kun je de define DEBUG op 1 zetten dan genereert de code log output op de seriele monitor van de Arduino IDE.

#define DEBUG 0

enum SpoorState {leeg,
                 sensor1komend,
                 sensor2komend,
                 sensor1gaand,
                 sensor2gaand
                };
//
//  Class for a single (white) led which flickers 50 times per
//  minute when on
//             
class SingleLed
{
  private:
    int ledPin;
    bool ledOn = true;
    int interval = 600;      // *** 50 keer per minuut
    bool lightOn = false;
    unsigned long lastTime;

  public:
    //
    //  Create a new instance of a (white) led, connect it to the specified
    //  digital pin and put it in the specified state (true = on, false = off)
    //
    SingleLed(int aPin, bool state)
    {
      ledPin = aPin;
      ledOn = state;
      lightOn = false;
      pinMode(ledPin, OUTPUT);

      lastTime = millis();
    }

    //
    //  Set the state of the led (true = on, false = off)
    //
    void setOn(bool state)
    {
      ledOn = state;
    }

    //
    //  If the state is on, put power on the pin of the led, using timers
    //  to make the flicker work.
    //  If the led is off, remove the power from the pin of the led.
    //
    void heartBeat()
    {
      if (ledOn)                               // Do we need to light the led?
      {
        unsigned long currTime = millis();
        if ((currTime - lastTime) >= interval) // Has the interval time passed?
        {
          lastTime = currTime;                 // Start new interval
          if (!lightOn)                        // Was the led lighted?
          {
            digitalWrite(ledPin, HIGH);        // No, so switch it on
            lightOn = true;
          }
          else
          {
            digitalWrite(ledPin, LOW);         // Yes, so switch it off
            lightOn = false;
          }
        }
      }
      else if (lightOn)                        // No light, but is the led still on?
      {
        digitalWrite(ledPin, LOW);             // Switch ir off
        lightOn = false;
      }
    }
};

//
//  Class for a set of two (red) leds which alternate(flicker) 50 times per
//  minute when on
//
class DuoLed
{
  private:
    int led1Pin;
    int led2Pin;
    bool ledOn = true;
    int interval = 600;      // *** 50 keer per minuut
    bool lightOn = false;
    unsigned long lastTime;

  public:
    //
    //  Create a new instance, connect it to the specified
    //  digital pins and put it in the specified state (true = on, false = off)
    //
    DuoLed(int aPin1, int aPin2, bool state)
    {
      led1Pin = aPin1;
      led2Pin = aPin2;
      ledOn = state;
      lightOn = false;
      pinMode(led1Pin, OUTPUT);
      pinMode(led2Pin, OUTPUT);

      lastTime = millis();
    }

    //
    //  Set the state of the leds (true = on, false = off)
    //
    void setOn(bool state)
    {
      ledOn = state;
    }

    //
    //  If the state is on, put power on the pins of the leds, using timers
    //  to make the alternating flicker work.
    //  If the led is off, remove the power from the pins of the leds.
    //
    void heartBeat()
    {
      if (ledOn)                                  // Are the leds activated
      {
        unsigned long currTime = millis();
        if ((currTime - lastTime) >= interval)    // Has the interval passed?
        {
          lastTime = currTime;                    // Yes, start new interval
          if (!lightOn)                           // The leds alternate, are we in phase1 (led1 on, led2 off)
          {
            digitalWrite(led1Pin, HIGH);          // Yes, led1 on
            digitalWrite(led2Pin, LOW);           // led2 off
            lightOn = true;                       // When the interval expires, switch the leds
          }
          else                                    // We are in phase2 (led1 off, led2 on)
          {
            digitalWrite(led1Pin, LOW);           // Led1 off
            digitalWrite(led2Pin, HIGH);          // Led2 on
            lightOn = false;                      // When the interval expires, switc the leds
          }
        }
      }
      else                                        // The leds are not active, switch of both leds
      {
        digitalWrite(led1Pin, LOW);
        digitalWrite(led2Pin, LOW);
        lightOn = false;
      }
    }
};

enum AkiStaat {aan, uit};

//
//  A simple class that represents a complet AKI with all its leds
//
//  TBD, the sound of the bells
//
class AKI
{
  private:
    SingleLed *whiteLight;
    DuoLed    *redLights;
    AkiStaat state = uit;
   
  public:
    //
    //  Create an instance of the AKI, using the specified Led objects
    //
    AKI(SingleLed *aWhiteLed, DuoLed *aRedLed)
    {
      whiteLight = aWhiteLed;
      redLights = aRedLed;
      state = uit;
    }

    //
    //  Activate the connected leds. TBD: the sound
    //
    void heartBeat()
    {
      redLights->heartBeat();
      whiteLight->heartBeat();
    }

    void set(AkiStaat aState)
    {
      state = aState;
     
      if (state == uit)
      {
#if (DEBUG)
          Serial.println("[AKI::set] AKI uit");
#endif
        redLights->setOn(false);
        whiteLight->setOn(true);
      }
      else
      {
#if (DEBUG)
          Serial.println("[AKI::set] AKI aan");
#endif
        redLights->setOn(true);
        whiteLight->setOn(false);
      }
    }
};

//
//  Some sensors use a digital signal and keep it high when not active and drop the signal
//  when the sensor trips, use in that case the laag setting. Others use a digital signal
//  and are low when not active and make the signal high when the sensor trips, use in that case
//  the hoog setting.
//  if the sensor doesn't generate a digital signal, you have to use a pullup resistor (or INPUT_PULLUP)
//  and in that case specify hoog.
//
enum SensorTrigger {laag, hoog};

//
//  A simple class which represents the state of a single sensor
//
class Sensor
{
  private:
    int sensorPin;
    SensorTrigger type = hoog;
    bool state = false;           // true = on, false = off 

    unsigned long lastTime = 0;   // Timer to ignore short interrupts
    #define JITTER_TIME   1000    // wait a second before the sensor goes off

  public:
    //
    //  Create a new instance
    //
    Sensor(int aPin)
    {
      sensorPin = aPin;
      pinMode(sensorPin, INPUT);
    }

    //
    //  Create a new instance
    //
    Sensor(int aPin, SensorTrigger aType)
    {
      sensorPin = aPin;
      type = aType;
      pinMode(sensorPin, INPUT);
    }

    //
    //  Return the current logical state of the sensor
    //
    bool getState()
    {
      return state;
    }

    //
    //  Monitor the physical sensor and update the state accordingly
    //
    void heartBeat()
    {
      if (digitalRead(sensorPin) == HIGH)
      {
        if (type == laag)       // For sensors type laag an high signal means they are in the off state     
        {
          if (state != false)   // Process this signal only when the current state is ON
          {
            if (lastTime == 0)
            {
              lastTime = millis();  // start Interval
            }
            else
            {
              unsigned long currTime = millis();
              if ((currTime-lastTime) >= JITTER_TIME)
              {
#if (DEBUG)
                Serial.println("[Sensor::heartBeat] sensor goes off");
#endif
                state = false;       // sensor goes OFF
                lastTime = 0;        // Reset interval timer
              }
            }
          }
        }
        else
        {
#if (DEBUG)
          Serial.println("[Sensor::heartBeat] sensor goes on");
#endif
          state = true;        // Sensor goes ON
          lastTime = 0;        // Reset interval timer
        }
      }
      else          // sensorPin  = LOW
      {
        if (type == laag)
        {
#if (DEBUG)
          Serial.println("[Sensor::heartBeat] sensor goes on");
#endif
          state == true;       // Sensor goes ON
          lastTime = 0;        // Reset interval timer;
        }
        else
        {
          if (state != false)   // Process this signal only when the current state is ON
          {
            if (lastTime == 0)
            {
              lastTime = millis();  // start Interval
            }
            else
            {
              unsigned long currTime = millis();
              if ((currTime-lastTime) >= JITTER_TIME)
              {
#if (DEBUG)
                Serial.println("[Sensor::heartBeat] sensor goes off");
#endif
                state = false;       // sensor goes OFF
                lastTime = 0;        // Reset interval timer
              }
            }
          }
        }
      }     
    }   
};

//
//  A finite state machine that guards a occupance of a single track
//
class SpoorControl
{
  private:
    Sensor *sensor1;
    Sensor *sensor2;
   
    SpoorState  state = leeg;

    //
    //  Based on the state of sensor 1 and the current state of the FSM, a new state
    //  is calculated.
    //
    void handleSensor1(bool trigger)
    {
      if (trigger)                      // Sensor 1 is ON
      {
        if (state == leeg)              // If the state is "leeg" it means that a train enters the section
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor1] state is sensor1komend");
#endif
          state = sensor1komend;        // so set it to state komend
        }
        else if (state == sensor2komend) // if the other sensor tripped first
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor1] state is sensor1gaand");
#endif
          state = sensor1gaand;          // The train is starting to leave the section
        }
      }
      else
      {                                  // Sensor went OFF
        if (state == sensor1gaand)       // If the train started to leave via sensor 1
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor1] state is leeg");
#endif
          state = leeg;                  // the section is "leeg"
        }
      }
    }

    //
    //  Based on the state of sensor 2 and the current state of the FSM, a new state
    //  is calculated.
    //
    void handleSensor2(bool trigger)
    {
      if (trigger)                          // Sensor 2 is ON
      {
        if (state == leeg)                  // Is the section "leeg"?
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor2] state is sensor2komend");
#endif
          state = sensor2komend;            // A Train entered the section via sensor 2
        }
        else if (state == sensor1komend)    // No a train entered the section via the other sensor
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor2] state is sensor2gaand");
#endif
          state = sensor2gaand;             // Start the leaving process
        }
      }
      else
      {
        if (state == sensor2gaand)          // A train is in the process of leaving
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor2] state is leeg");
#endif
          state = leeg;                     // Section is empty again
        }
      }
    }

  public:
    //
    // Create an instance with two sensors
    //
    SpoorControl(Sensor *aSensor1, Sensor *aSensor2)
    {
      sensor1 = aSensor1;
      sensor2 = aSensor2;
    }

    //
    //  Get give the sensors a kick and check their state so we can update our own
    //  state.
    //
    void heartBeat()
    {
      sensor1->heartBeat();
      sensor2->heartBeat();

      handleSensor1(sensor1->getState());
      handleSensor2(sensor2->getState());
    }

    //
    // Return the current state of the section
    //
    SpoorState getState()
    {
      return state;
    }
};

//
//  Create 2 FSM controling two track sections
//
SpoorControl spoor1(new Sensor(A0, hoog), new Sensor(A1, hoog));
SpoorControl spoor2(new Sensor(A2, hoog), new Sensor(A3, hoog));

//
// Create an instance of the AKI
//
AKI aki(new SingleLed(A4, true), new DuoLed(A5, A6, false));

void setup()
{
#if (DEBUG)
  //Serial.begin(9600);
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Starting");
  Serial.flush();
#endif //DEBUG
 

}

void loop()
{
  spoor1.heartBeat();     // These object must monitor their sensors
  spoor2.heartBeat();     // so they can update their states

  if ((spoor1.getState() == leeg) && (spoor2.getState() == leeg))
  {
    aki.set(uit);         // Stop sound and flashing red lights
  }
  else
  {
    aki.set(aan);         // Start flashing red lights and sound
  }

  aki.heartBeat();        // Let the AKI update it's connected bells and leds
}

Zoals jullie kunnen zien kom ik uit een andere IT wereld dan Gerard, dus ik probeer altijd zoveel mogelijk de functionaliteit in aparte classes (objecten) te stoppen.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 23 mei 2018, 00:09:56
Ik heb een kleine opmerking over de code van Gerard. Ik zie dat hij de sensor pins initialiseer met INPUT_PULLUP, ik denk dat dat niet goed gaat werken, omdat deze bordjes zelf een goede 5v of een goede gnd maken. Ik initialiseer de pinnen dus met INPUT. Verder als de IR receiver geen IR ziet, dan zet hij het signaal hoog (5v), op het moment dat hij IR ziet, gaat het signaal naar low (0v). Dat betekend dat als de detector gemodificeerd wordt om als lichtsluis te werken, een HIGH signaal betekend dat de IR is onderbroken en een LOW signaal betekend dat IR niet onderbroken is.
Tenminste dat is de situatie met de benadering detectors die ik heb van het merk "Flying fish", die het zelfde zijn als die Edsko heeft aangeschaft.

@Gerard
Leuk stekje waar je naar toe gaat.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Hennik op 23 mei 2018, 00:55:31
Geïnspireerd door de vele berichten op dit forum wat je allemaal met Arduino kan, heb ik me er de laatste weken flink in verdiept en mee geëxperimenteerd. Geweldig hoeveel kennis hier gedeeld wordt!

Ik ben zelf meer een lezer dan een reageerder (sorry), maar wellicht kan ik hier toch even wat zinvols toevoegen als het gaat om stuiterende slagbomen.

Volgende link kwam ik namelijk tijdens mijn zoektochten op internet tegen. Het toont weliswaar een sketch voor locloodsdeuren, het principe van de versnelling en vertraging bij openen, en ook de terugvering, kan met kleine wijzigingen het gedrag van de eerder genoemde Duitse tutorial leuk benaderen.
Zie: http://www.locoduino.org/spip.php?article159
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Te 2/2 op 23 mei 2018, 09:46:03
Jaren geprogrammeerd in zowel de Gerard als de Meino stijl, in alles waarmee te  programmeren viel, maar toch allermeest als glu'er (5 regeltjes code schrijven om 2 programma's die niet voor elkaar gemaakt zijn, te laten samensmelten alsof ze een geheel zijn). Beide codes laten zich lezen als een speer.  Mooie codes ook.

Maar ik voel me 't meest aangetrokken door Meino's aanpak (https://forum.beneluxspoor.net/index.php?topic=80179.msg3221861964#msg3221861964) vanwege het bereikte abstractieniveau:
//class SpoorControl
//
//  Create 2 FSM controling two track sections
//
SpoorControl spoor1(new Sensor(A0, hoog), new Sensor(A1, hoog));
SpoorControl spoor2(new Sensor(A2, hoog), new Sensor(A3, hoog));

Ik ben alweer jaren geleden gestopt met dat werk als "mastergluer" (=lijmen-jan)  ;D
Maar ik nam de code even door, en toen kwam het allemaal weer boven.

Ik zie nu in waarom Gerard en Meino van 4 sluisjes uit gaan op 4 aparte pinnen en niet van 4, 2 aan 2 aangesloten, sluisjes (wat weliswaar 2 arduino pinnen scheelt, maar ook aanzienlijk minder flexibel is).

Toch vraag ik me af of je met twee sluizen over 2 of meer sporen, niet beter af bent dan met 2 sluizen per spoor.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 23 mei 2018, 09:50:17
Aangespoord door de opmerking van NS264 toch maar de code herzien naar objecten. Ik werk graag met de classes in aparte files dus in mijn geval spat de sketch uiteen in drie files, de sketch en 2 ander files voor een class.
In tegen stelling tot wat Meino in zijn code alvast heeft gedaan, heb ik nog niet de AKI knipper-lichten van aansturing voorzien. Dit komt wel als dit door Edsko wat duidelijker gedefinieerd is.

Hieronder de nieuwe sketch:
// Definitie van de 4 ingangen voor de sensoren (2 per spoor)
#define SBBLSP1    2   // BlackBox Links, Spoor 1
#define SBBRSP1    3   // BlackBox Rechts, Spoor 1
#define SBBLSP2    4   // BlackBox Links, Spoor 2
#define SBBRSP2    5   // BlackBox Rechts, Spoor 2

#define DELAY    500   // Vertraging in milli seconde

#define NUMSPOREN  2   // Aantal sporen

#include "Spoor.h"

Spoor sporen[NUMSPOREN];

// Initialialatie van de Arduino
void setup() {
  // put your setup code here, to run once:

  // Define sporen
  sporen[0] = Spoor(SBBLSP1, SBBRSP1, DELAY);     // Spoor 1
  sporen[1] = Spoor(SBBLSP2, SBBRSP2, DELAY);     // Spoor 2
 
  // LED uit
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop() {
  // put your main code here, to run repeatedly:

  bool bezet = false;
  for(int i = 0; i < NUMSPOREN; i++)
  {
     bezet |= sporen[i].calcBezet();
  }
 
  // Aansturen van de AKI / AHOB (overweg)
  if (bezet) {
    // Overweg gesloten
    digitalWrite(LED_BUILTIN, HIGH);
  } else {
    // Overweg geopend
    digitalWrite(LED_BUILTIN, LOW);
  }
}

En in dezelfde directory als de sketch komen de twee volgende bestanden:
Filenaam Spoor.h (definitie van de class):
#ifndef Spoor_h
#define Spoor_h

#include "Arduino.h"

class Spoor {
public:
  Spoor();      // for array
  Spoor(byte sensorLinks, byte sensorRechts, int sensorDelay);
  bool calcBezet();

private:
  bool readLinks();
  bool readRechts();

  byte _sensorLinks;
  byte _sensorRechts;
  bool _memLinks;
  bool _memRechts;
  unsigned long _timerLinks;
  unsigned long _timerRechts;
// < 0: trein rijdt van rechts naar links
// 0: geen trein
// > 0: trein rijdt van links naar rechts
  byte _dir;
  int _sensorDelay;
};

#endif

Filenaam Spoor.cpp (functionaliteit van de class):
#include "Spoor.h"

Spoor::Spoor() {
  // Empty constructor, don't use (for array)
}

Spoor::Spoor(byte sensorLinks, byte sensorRechts, int sensorDelay) {
  // Variabelen met externe waardes
  _sensorLinks = sensorLinks;
  _sensorRechts = sensorRechts;
  _sensorDelay = sensorDelay;
    // Maak de inputs met extra pullups
  pinMode(_sensorLinks, INPUT_PULLUP);
  pinMode(_sensorRechts, INPUT_PULLUP);
  // Voorzie overige variabelen van een default value
  _timerLinks = millis();
  _timerRechts = millis();
  _memLinks = readLinks();
  _memRechts = readRechts();
  _dir = 0;
}

bool Spoor::readLinks() {
  // if (digitalRead(_sensorLinks) > 0) {
  if (digitalRead(_sensorLinks) == 0) {
    _timerLinks = millis() + _sensorDelay;
  }
  return (_timerLinks > millis());
}

bool Spoor::readRechts() {
  // if (digitalRead(_sensorRechts) > 0) {
  if (digitalRead(_sensorRechts) == 0) {
    _timerRechts = millis() + _sensorDelay;
  }
  return (_timerRechts > millis());
}

// return true als bezet
bool Spoor::calcBezet() {
  // fase: toestand nu en de vorige keer van de melder
  // volgorde:
  //  0: geen trein
  //  1: voorkant trein
  //  2: achterkant trein
  //  3: trein aanwezig
  byte fase;

  // Links
  fase = (_memLinks ? 2 : 0);
  _memLinks = readLinks();
  fase += (_memLinks ? 1 : 0);
  if (fase == 1) {
    // Trein komt binnen
    if (_dir == 0) {      // Bij het bereiken van de andere kant alleen reageren op het verlaten
      _dir++;       
    }
  }
  if (fase == 2) {
    // Trein verlaat
    if (_dir < 0) {       // Bij het verlaten van de binnen melder niet een extra puls geven.
      _dir++;
    }
  }
  // Rechts
  fase = (_memRechts ? 2 : 0);
  _memRechts = readRechts();
  fase += (_memRechts ? 1 : 0);
  if (fase == 1) {
    // Trein komt binnen
    if (_dir == 0) {      // Bij het bereiken van de andere kant alleen reageren op het verlaten
      _dir--;       
    }
  }
  if (fase == 2) {
    // Trein verlaat
    if (_dir > 0) {       // Bij het verlaten van de binnen melder niet een extra puls geven.
      _dir--;
    }
  }
  return (_dir != 0);
}

Bij het openen van de sketch zal de Arduino IDE automatisch de beide class files mede openen in extra tabs.

PS. Mocht iemand Hilversum in de jaren 80 na willen bouwen, dan kan nu eenvoudig het aantal sporen uitgebreid worden.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 23 mei 2018, 09:57:45
Ik heb een kleine opmerking over de code van Gerard. Ik zie dat hij de sensor pins initialiseer met INPUT_PULLUP, ik denk dat dat niet goed gaat werken, omdat deze bordjes zelf een goede 5v of een goede gnd maken. Ik initialiseer de pinnen dus met INPUT. Verder als de IR receiver geen IR ziet, dan zet hij het signaal hoog (5v), op het moment dat hij IR ziet, gaat het signaal naar low (0v). Dat betekend dat als de detector gemodificeerd wordt om als lichtsluis te werken, een HIGH signaal betekend dat de IR is onderbroken en een LOW signaal betekend dat IR niet onderbroken is.
Tenminste dat is de situatie met de benadering detectors die ik heb van het merk "Flying fish", die het zelfde zijn als die Edsko heeft aangeschaft.
Waarom INPUT_PULLUP in plaats van INPUT. Edsko gaat werken met straal breking. Dit betekend dat de pen van de uitgang altijd laag is, tenzij er een trein de straal onderbreekt. Als extra beveiliging gebruik ik de INPUT_PULLUP, zodat bij draadbreuk tussen sensor en Arduino de Ardiono een bezette sensor ziet. Dit heeft bij reflectie geen zin en kan zelfs tot misvattingen leiden.

@Meino: Er is nog een verschil. Ik heb 30 jaar bij de NS (waaronder Movares) gewerkt. Je krijgt dan tussen je oren gestampt dat een fout in de software mensenlevens kan kosten. Dus veel code en hardware ontwerpen hebben dit nog steeds als achtergrond. Ik ben onbewust altijd opzoek naar passieve beveiligingen.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 23 mei 2018, 12:02:59
Jan Willem,

Toch vraag ik me af of je met twee sluizen over 2 of meer sporen, niet beter af bent dan met 2 sluizen per spoor.

Ik zal het proberen te verklaren. Stel je voor twee parallelle sporen met hierover zoals jij aangeeft een sluis op basis van straal onderbreking.
Op beide sporen rijdt een trein, en ze rijden naar elkaar toe (moet kunnen toch  ;D).
Een van beide treinen komt aan bij de sluis en doorbreekt de straal. De trein wordt gemeld. Terwijl deze trein door de sluis rijdt komt de andere trein ook bij de sluis. Deze kan zich niet melden, want de eerste trein heeft de straal al onderbroken. Als de eerste trein geheel weg is en de tweede trein bevindt zich nog in de sluis zal deze het onderbreken van de straal voor zijn rekening nemen. Als tenslotte de sluis weer vrij is, zal de sluis een trein gemeld hebben, terwijl er toch twee door gegaan zijn.

Ik hoop dat het voorbeeld helpt om het beveiligen te begrijpen. Je kan met een sluis over meerdere sporen werken, als je zeker weet dat er maar een trein tegelijk door de sluis gaat. Een voorbeeld hiervan is in een schaduw station. Je kunt met een straal de einden van alle sporen bewaken, als je maar zorgt dat de trein die het laatst de straal heeft doorbroken een stukje terug rijdt. Dit kan je bij Koploper zien in een schaduwstation.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: nighttrain1 op 23 mei 2018, 13:01:35
Even in "Grasland" gekeken voor de juiste opstelling. De overweg bevind zich links op de module. Dus er is een ongelijke tijd voor het aanrijden van de AKI. Is in dit geval niet storend, daar de korte aanrijtijd door de BBL (blackbox links) gecamoufleerd wordt. De rode lijnen zijn de 4 sensoren voor de AKI aansturing.

Tenzij je in de rechter BB van je linker buurman/vouw een uitschuifbare set lichtsensoren monteert zodat de in/uitrij tijd iets verlengt kan worden...
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: nighttrain1 op 23 mei 2018, 13:09:51
En als Edsko besluit voor een keer mee te doen met de BMB, waar men links rijdt?!? werkt het dan ook nog zo goed?
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 23 mei 2018, 14:31:52
Richard,

Het geheel is door Edsko "gespecificeerd" op twee richtingen per spoor. Dus IEDER spoor kan zowel van links naar rechts als van rechts naar links bereden worden met een werkende AKI.
Dus mocht Edsko ooit met BMB mee willen doen, dan zal de AKI geen spelbreker zijn.

Ik denk dat het grootste probleem het uitschakelen van de AKI wordt. Aan beide kanten rijdt de trein volledig van de module af voordat de AKI open gaat en de bel stopt.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 23 mei 2018, 14:34:51
Tenzij je in de rechter BB van je linker buurman/vouw een uitschuifbare set lichtsensoren monteert zodat de in/uitrij tijd iets verlengt kan worden...
Leuk idee, maar dat ga ik niet doen. Lekker simpel houden. Het ding komt zo veel als mogelijk tegen de BB van de buurman aan.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 23 mei 2018, 14:36:05
Ik denk dat het grootste probleem het uitschakelen van de AKI wordt.
Oplossing: hamer (niet erg vriendelijk) of stekker eruit (wel vriendelijk)
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: 72sonett op 23 mei 2018, 16:28:42
Wat gebeurt er als een (korte) trein helemaal tussen twee lichtsluizen past? Op dat moment melden beide 'laag' en dan zou de aki open gaan, terwijl er een trein overheen rijdt.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 23 mei 2018, 16:33:44
Waarom INPUT_PULLUP in plaats van INPUT. Edsko gaat werken met straal breking. Dit betekend dat de pen van de uitgang altijd laag is, tenzij er een trein de straal onderbreekt. Als extra beveiliging gebruik ik de INPUT_PULLUP, zodat bij draadbreuk tussen sensor en Arduino de Ardiono een bezette sensor ziet. Dit heeft bij reflectie geen zin en kan zelfs tot misvattingen leiden.

@Meino: Er is nog een verschil. Ik heb 30 jaar bij de NS (waaronder Movares) gewerkt. Je krijgt dan tussen je oren gestampt dat een fout in de software mensenlevens kan kosten. Dus veel code en hardware ontwerpen hebben dit nog steeds als achtergrond. Ik ben onbewust altijd opzoek naar passieve beveiligingen.

Dat wist ik niet Gerard, dat maakt wel een verschil. Overigens ik heb geen electronica achtergrond maar ik weet ondertussen wel waarvoor een pullup weerstand dient. Maar omdat hierdoor er twee bronnen zijn die 5v leveren op de input pin, vertrouwde ik dat niet. Maar dat kan dus zonder problemen, weer wat geleerd.

Voordat ik morgen ook vertrek heb ik nog even mijn code uitgeprobeerd op een test opstelling met twee sensors (mijn snelheids meter voor het ijken van locomotieven), daar kwam nog een klein foutje in de code uit, vandaar nog even een nieuwe versie.
#define DEBUG 0

enum SpoorState {leeg,
                 sensor1komend,
                 sensor2komend,
                 sensor1gaand,
                 sensor2gaand
                };
//
//  Class for a single (white) led which flickers 50 times per
//  minute when on
//
class SingleLed
{
  private:
    int ledPin;
    bool ledOn = true;
    int interval = 600;      // *** 50 keer per minuut
    bool lightOn = false;
    unsigned long lastTime;

  public:
    //
    //  Create a new instance of a (white) led, connect it to the specified
    //  digital pin and put it in the specified state (true = on, false = off)
    //
    SingleLed(int aPin, bool state)
    {
      ledPin = aPin;
      ledOn = state;
      lightOn = false;
      pinMode(ledPin, OUTPUT);

      lastTime = millis();
    }

    //
    //  Set the state of the led (true = on, false = off)
    //
    void setOn(bool state)
    {
#if (DEBUG)
      if (ledOn != state)
      {
        Serial.print("[SingleLed::setOn]");
        if (state)
          Serial.println(" aan");
        else
          Serial.println(" uit");
      }
#endif
      ledOn = state;
    }

    //
    //  If the state is on, put power on the pin of the led, using timers
    //  to make the flicker work.
    //  If the led is off, remove the power from the pin of the led.
    //
    void heartBeat()
    {
      if (ledOn)                               // Do we need to light the led?
      {
        unsigned long currTime = millis();
        if ((currTime - lastTime) >= interval) // Has the interval time passed?
        {
          lastTime = currTime;                 // Start new interval
          if (!lightOn)                        // Was the led lighted?
          {
#if (DEBUG)
            Serial.println("[SingleLed::heartBeat] led aan");
#endif
            digitalWrite(ledPin, HIGH);        // No, so switch it on
            lightOn = true;
          }
          else
          {
#if (DEBUG)
            Serial.println("[SingleLed::heartBeat] led uit");
#endif
            digitalWrite(ledPin, LOW);         // Yes, so switch it off
            lightOn = false;
          }
        }
      }
      else if (lightOn)                        // No light, but is the led still on?
      {
#if (DEBUG)
        Serial.println("[SingleLed::heartBeat] led uit");
#endif
        digitalWrite(ledPin, LOW);             // Switch ir off
        lightOn = false;
      }
    }
};

//
//  Class for a set of two (red) leds which alternate(flicker) 50 times per
//  minute when on
//
class DuoLed
{
  private:
    int led1Pin;
    int led2Pin;
    bool ledOn = true;
    int interval = 600;      // *** 50 keer per minuut
    bool lightOn = false;
    bool phase = false;
    unsigned long lastTime;

  public:
    //
    //  Create a new instance, connect it to the specified
    //  digital pins and put it in the specified state (true = on, false = off)
    //
    DuoLed(int aPin1, int aPin2, bool state)
    {
      led1Pin = aPin1;
      led2Pin = aPin2;
      ledOn = state;
      lightOn = false;
      phase = false;
      pinMode(led1Pin, OUTPUT);
      pinMode(led2Pin, OUTPUT);

      lastTime = millis();
    }

    //
    //  Set the state of the leds (true = on, false = off)
    //
    void setOn(bool state)
    {
#if (DEBUG)
      if (ledOn != state)
      {
        Serial.print("[DuoLed::setOn]");
        if (state)
          Serial.println(" aan");
        else
          Serial.println(" uit");
      }
#endif
      ledOn = state;
    }

    //
    //  If the state is on, put power on the pins of the leds, using timers
    //  to make the alternating flicker work.
    //  If the led is off, remove the power from the pins of the leds.
    //
    void heartBeat()
    {
      if (ledOn)                                  // Are the leds activated
      {
        lightOn = true;
       
        unsigned long currTime = millis();
        if ((currTime - lastTime) >= interval)    // Has the interval passed?
        {
          lastTime = currTime;                    // Yes, start new interval
          if (!phase)                           // The leds alternate, are we in phase1 (led1 on, led2 off)
          {
#if (DEBUG)
            Serial.println("[DuoLed::heartBeat] led1 aan, led2 uit");
#endif
            digitalWrite(led1Pin, HIGH);          // Yes, led1 on
            digitalWrite(led2Pin, LOW);           // led2 off
            phase = true;                       // When the interval expires, switch the leds
          }
          else                                    // We are in phase2 (led1 off, led2 on)
          {
#if (DEBUG)
            Serial.println("[DuoLed::heartBeat] led1 uit, led2 aan");
#endif
            digitalWrite(led1Pin, LOW);           // Led1 off
            digitalWrite(led2Pin, HIGH);          // Led2 on
            phase = false;                      // When the interval expires, switc the leds
          }
        }
      }
      else                                        // The leds are not active, switch of both leds
      {
        if (lightOn)
        {
#if (DEBUG)
          Serial.println("[DuoLed::heartBeat] led1 uit, led2 uit");
#endif
          digitalWrite(led1Pin, LOW);
          digitalWrite(led2Pin, LOW);
          lightOn = false;
        }
      }
    }
};

enum AkiStaat {aan, uit};

//
//  A simple class that represents a complet AKI with all its leds
//
//  TBD, the sound of the bells
//
class AKI
{
  private:
    SingleLed *whiteLight;
    DuoLed    *redLights;
    AkiStaat state = uit;

  public:
    //
    //  Create an instance of the AKI, using the specified Led objects
    //
    AKI(SingleLed *aWhiteLed, DuoLed *aRedLed)
    {
      whiteLight = aWhiteLed;
      redLights = aRedLed;
      state = uit;
    }

    //
    //  Activate the connected leds. TBD: the sound
    //
    void heartBeat()
    {
      redLights->heartBeat();
      whiteLight->heartBeat();
    }

    void set(AkiStaat aState)
    {
#if (DEBUG)
      if (state != aState)
      {
        Serial.print("[AKI::set]");
        if (aState == uit)
          Serial.println(" uit");
        else
          Serial.println(" aan");
      }
#endif
      state = aState;

      if (state == uit)
      {
        redLights->setOn(false);
        whiteLight->setOn(true);
      }
      else
      {
        redLights->setOn(true);
        whiteLight->setOn(false);
      }
    }
};

//
//  Some sensors use a digital signal and keep it high when not active and drop the signal
//  when the sensor trips, use in that case the "laag" setting. Others use a digital signal
//  and are low when not active and make the signal high when the sensor trips, use in that case
//  the "hoog" setting.
//  if the sensor doesn't generate a digital signal, you have to use a pullup resistor (or INPUT_PULLUP)
//  and in that case specify hoog.
//
//  The Flying Fish proximity detectors, when used in reflective mode, need the "laag" setting,
//  when their sensors are removed and positioned opposit each other, they need the "hoog" setting
//
enum SensorTrigger {laag, hoog};

//
//  A simple class which represents the state of a single sensor
//
class Sensor
{
  private:
    int sensorPin;
    SensorTrigger type = hoog;
    bool state = false;           // true = on, false = off

    unsigned long lastTime = 0;   // Timer to ignore short interrupts
#define JITTER_TIME   1000    // wait a second before the sensor goes off

  public:
    //
    //  Create a new instance
    //
    Sensor(int aPin)
    {
      sensorPin = aPin;
      pinMode(sensorPin, INPUT);
    }

    //
    //  Create a new instance
    //
    Sensor(int aPin, SensorTrigger aType)
    {
      sensorPin = aPin;
      type = aType;
      pinMode(sensorPin, INPUT);
    }

    //
    //  Return the current logical state of the sensor
    //
    bool getState()
    {
      return state;
    }

    //
    //  Monitor the physical sensor and update the state accordingly
    //
    void heartBeat()
    {
      if (digitalRead(sensorPin) == HIGH)
      {
        if (type == laag)       // For sensors type laag an high signal means they are in the off state
        {
          if (state != false)   // Process this signal only when the current state is ON
          {
            if (lastTime == 0)
            {
              lastTime = millis();  // start Interval
            }
            else
            {
              unsigned long currTime = millis();
              if ((currTime - lastTime) >= JITTER_TIME)
              {
#if (DEBUG)
                Serial.println("[Sensor::heartBeat] sensor(laag) goes off");
#endif
                state = false;       // sensor goes OFF
                lastTime = 0;        // Reset interval timer
              }
            }
          }
        }
        else
        {
#if (DEBUG)
          if (state != true)
          {
            Serial.println("[Sensor::heartBeat] sensor(hoog) goes on");
          }
#endif
          state = true;        // Sensor goes ON
          lastTime = 0;        // Reset interval timer
        }
      }
      else          // sensorPin  = LOW
      {
        if (type == laag)
        {
#if (DEBUG)
          if (state != true)
          {
            Serial.println("[Sensor::heartBeat] sensor(laag) goes on");
          }
#endif
          state = true;       // Sensor goes ON
          lastTime = 0;        // Reset interval timer;
        }
        else
        {
          if (state != false)   // Process this signal only when the current state is ON
          {
            if (lastTime == 0)
            {
              lastTime = millis();  // start Interval
            }
            else
            {
              unsigned long currTime = millis();
              if ((currTime - lastTime) >= JITTER_TIME)
              {
#if (DEBUG)
                Serial.println("[Sensor::heartBeat] sensor(hoog) goes off");
#endif
                state = false;       // sensor goes OFF
                lastTime = 0;        // Reset interval timer
              }
            }
          }
        }
      }
    }
};

//
//  A finite state machine that guards a occupance of a single track
//
class SpoorControl
{
  private:
    Sensor *sensor1;
    Sensor *sensor2;

    SpoorState  state = leeg;

    //
    //  Based on the state of sensor 1 and the current state of the FSM, a new state
    //  is calculated.
    //
    void handleSensor1(bool trigger)
    {
      if (trigger)                      // Sensor 1 is ON
      {
        if (state == leeg)              // If the state is "leeg" it means that a train enters the section
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor1] state is sensor1komend");
#endif
          state = sensor1komend;        // so set it to state komend
        }
        else if (state == sensor2komend) // if the other sensor tripped first
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor1] state is sensor1gaand");
#endif
          state = sensor1gaand;          // The train is starting to leave the section
        }
      }
      else
      { // Sensor went OFF
        if (state == sensor1gaand)       // If the train started to leave via sensor 1
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor1] state is leeg");
#endif
          state = leeg;                  // the section is "leeg"
        }
      }
    }

    //
    //  Based on the state of sensor 2 and the current state of the FSM, a new state
    //  is calculated.
    //
    void handleSensor2(bool trigger)
    {
      if (trigger)                          // Sensor 2 is ON
      {
        if (state == leeg)                  // Is the section "leeg"?
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor2] state is sensor2komend");
#endif
          state = sensor2komend;            // A Train entered the section via sensor 2
        }
        else if (state == sensor1komend)    // No a train entered the section via the other sensor
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor2] state is sensor2gaand");
#endif
          state = sensor2gaand;             // Start the leaving process
        }
      }
      else
      {
        if (state == sensor2gaand)          // A train is in the process of leaving
        {
#if (DEBUG)
          Serial.println("[SpoorControl::handleSensor2] state is leeg");
#endif
          state = leeg;                     // Section is empty again
        }
      }
    }

  public:
    //
    // Create an instance with two sensors
    //
    SpoorControl(Sensor *aSensor1, Sensor *aSensor2)
    {
      sensor1 = aSensor1;
      sensor2 = aSensor2;
    }

    //
    //  Get give the sensors a kick and check their state so we can update our own
    //  state.
    //
    void heartBeat()
    {
      sensor1->heartBeat();
      sensor2->heartBeat();

      handleSensor1(sensor1->getState());
      handleSensor2(sensor2->getState());
    }

    //
    // Return the current state of the section
    //
    SpoorState getState()
    {
      return state;
    }
};

//
//  Create 2 FSM controling two track sections
//
SpoorControl spoor1(new Sensor(A0, laag), new Sensor(A1, laag)); // Sensor works reflective
SpoorControl spoor2(new Sensor(A2, laag), new Sensor(A3, laag));

//
// Create an instance of the AKI
//
AKI aki(new SingleLed(A4, true), new DuoLed(A5, A6, false));

void setup()
{
#if (DEBUG)
  //Serial.begin(9600);
  Serial.begin(115200);
  while (!Serial);
  Serial.println("Starting");
  Serial.flush();
#endif //DEBUG


}

void loop()
{
  spoor1.heartBeat();     // These object must monitor their sensors
  spoor2.heartBeat();     // so they can update their states


  if ((spoor1.getState() == leeg) && (spoor2.getState() == leeg))
  {
    aki.set(uit);         // Stop sound and flashing red lights
  }
  else
  {
    aki.set(aan);         // Start flashing red lights and sound
  }

  aki.heartBeat();        // Let the AKI update it's connected bells and leds
}

Uit het testen bleek wel dat deze Flyijng Fish sensors erg gevoelig zijn voor omgevings licht. Ik deed de test even in mijn serre, maar daar werkte het voor geen meter. Totdat ik me realiseerde (aan de hand van de ledjes op de sensor) dat ze altijd aan waren. Pas toen ik weer in de kelder met de treinbaan was, werkte het naar behoren. Dus let op voor omgevings licht.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 23 mei 2018, 16:41:59
Wat gebeurt er als een (korte) trein helemaal tussen twee lichtsluizen past? Op dat moment melden beide 'laag' en dan zou de aki open gaan, terwijl er een trein overheen rijdt.

dat is geen probleem, omdat zowel bij mijn code als de code van Gerard het treinvak pas weer vrijgegeven wordt op het moment dat de trein de tweede sensor activeert en vervolgens de tweede sensor in zijn geheel gepasseerd is. Het feit dat de eerste sensor gepasseerd is heeft geen invloed op de status van het treinvak. Het gaat dus niet om de status van een enkele sensor, maar de volgorde van de statussen van de sensors die bepalen of een treinvak bezet of vrij is.
Overigens zijn er wel scenario's dat het niet goed gaat. Bijv. als een trein de module binnen komt, stopt en dan terug rijdt, kan niet correct afgehandeld worden met de informatie die beschikbaar komt van de lichtsluisjes.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 23 mei 2018, 17:00:42
@Meino,

Kijk even in mijn code. De situatie die ontstaat is niet correct,maar wel veilig. De AKI blijft gewoon gesloten. Pas een volgende trein uit de richting waar de eerdere trein kwam zal de boel herstellen, naast opnieuw starten.

Groet,

Gerard van der Sel.

PS. Goede reis en tot over een week dan maar.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: meino op 23 mei 2018, 17:38:24
Dag Gerard

ik had je code bekeken en wat ik zag leek voor betreffende de states erg op mijn code (ook 3 states)
Ik hanteer voor een spoor de volgende states, leeg, komend en gaand. Alleen bij status leeg zal de AKI uit zijn. De volgorde van de gebeurtenissen is bij mij:

Als de trein van de andere kant komt, vindt in principe de zelfde volgorde van state wisselingen plaats. Ik heb je code niet al te diep bekeken, maar ik had het idee dat je de zelfde volgorde van soortgelijke state wisseling hebt geimplementeerd.

Bedankt en jij ook nog een goede reis.

Groet Meino
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: 72sonett op 23 mei 2018, 18:42:34
Is het niet veel handiger om met een bezetmelder op basis van stroomdetectie te werken - aangenomen dat  behalve de loc ook iedere wagon stroom trekt en voor zover dat niet in strijd is met de eis dat er niets aan de trein veranderd mag worden?

Dat betekent dan dat het met een eenvoudige elektronische schakeltrap (zonder processor) kan worden gerealiseer: bezet = dicht, vrij = open (en je hebt ook geen last van omgevingslicht).
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 23 mei 2018, 20:35:32
Hi,

dat zou in principe kunnen. Echter, dan moet ik van alle deelnemers aan de baan gaan vragen of ze al hun rijdend materieel dat op de baan gaat rijden, stroom moeten afnemen op ale wielen. Dat kan ik niet vragen, vandaar de lichtsluis.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 28 mei 2018, 11:45:30
NS264 (Koen),

Gebruik jij een servo of een stappenmotor voor je overgenomen. Een servo is gemakkelijker.
Ik kan in de linken die jij gegeven hebt niet echt het stuiteren van de boom terugvinden, wel mooie lineaire bewegingen. Is het de bedoeling dat de bomen ook na stuiteren? Beneden en boven neem ik aan.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 28 mei 2018, 11:55:18
Hte is hier nog een beetje rustig. Te warm om nu te gaan knutselen en ook mijn tuin vraagt wel wat aandacht momenteel.
Ik heb echter wel goede hoop dat ik er deze week nog ergens aan toe ga komen. :)
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: NS264 op 28 mei 2018, 12:10:45
Ook laatste restje vakantie aan het vieren.

Ik kom er later vandaag op terug.

Een stuiterende boom is leuk maar niet perse noodzakelijk, slechts detail.
De link nr de Duitse forum laat ook vertraging zien met behulp van tandwielen, leuk, maar als je al een mooie beweging hebt met en servo is dat genoeg.

BTW ik heb een steppen controller voor de arduino om of 2 servo te bedienen of een motor.

Ik open een eigen draadje straks omdat het afwijkt van Edsko's plan.

Gr Koen.

Ow, en fotocellen voor detectie.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 28 mei 2018, 18:14:39
Servo's  kun je direct aan de Arduino aansluiten. Daar heb je geen versterker bij nodig. Stuiteren vergt een patroon ipv een lineaire beweging. Die komt uit een formule of een tabel. Is het wel goed dat we een versie van de software maken?

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: NS264 op 28 mei 2018, 18:25:13
Weet niet of Edsko het er mee eens is maar ik ben  hier  (https://forum.beneluxspoor.net/index.php?topic=80381.msg3221865206;topicseen#msg3221865206)begonnen.

Gr Koen.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: Edsko Hekman op 28 mei 2018, 23:43:39
Zo. Ik heb eindelijk eens de Arduino IDE geïnstalleerd en de code van Gerard gecompiled. Ik wil uiteindelijk zowel de code van Gerard als van Meino eens proberen om te zien wat de evt verschillen zijn, zo die er al zijn.

Ik ben een complete leek op het gebied van Arduino's, dus heb aub even geduld met mijn onkunde in deze toch wel interessante materie. ;)

Ik heb de code dus gecompiled en zal deze morgen eens proberen te laden in de Arduino UNO die ik heb.
Maar nu het volgende. :) Ik heb hier ook twee ali lichtsluisjes voor me liggen. Ik neem maar even aan dat ik de witte led er ongestraft af kan solderen. Maar dan? Ik heb hier een solderless breadboard voor me liggen en wat draadjes met stekkertjes eraan en zo. Allemaal leuk, maar ik heb (nog) geen idee van hoe en of wat. Dat zal allemaal wel goed komen, maar hoe nu verder?
Ik heb ook nog een zakje met losse ledjes erin en wat weerstandjes. Maar ik weet dus niet hoe ik zo'n breadboard opbouw. :-\ Wie helpt me op weg?

Gr.

Edsko
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: 72sonett op 29 mei 2018, 00:14:48
Citaat van: Edsko Hekman
...  ik weet dus niet hoe ik zo'n breadboard opbouw.
Je prikt de onderdelen in de gaatjes en verbindt ze volgens het schema met elkaar met die insteekdraadjes. De kolommen met gaatjes zijn al met elkaar verbonden. De twee regels (blauw en rood) langs de boven- en onderrand ook.
 
https://en.wikipedia.org/wiki/Breadboard (https://en.wikipedia.org/wiki/Breadboard)
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: jakeman op 29 mei 2018, 00:17:41
Heyhoi Edsko hier zijn we ook al wat aan het testen geslagen met lichtsluizen en oplossingen mbt de treinlift, seinen en laad/lossysteem. Kom eens kijken hier als met name Ruud en Paul van de EMV en/of Nico hier ook aanwezig zijn.    (y)

Groetjes Jake
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 29 mei 2018, 08:17:07
Edsko,

Als je een Led lossoldeert, dan kun je deze niet in het breadboard prikken. De pootjes zijn te kort, vervuild met resten tin. Probeer er draden aan te solderen en doe die in je breadboard. Dit werkt voor experimenten hardstikke leuk.

Groet,

Gerard van der Sel.
Titel: Re: Ali-lichtsluisjes en overwegaansturing met arduino
Bericht door: gvandersel op 05 juni 2018, 12:05:37
Terug van de korte vakantie. Nu volgende aanpakken verbouwen en verhuizen. Wel nieuwe tandwielen met motor (https://images.beneluxspoor.net/bnls/TandwielenMotor.jpg) voor de draaischijf gekocht. Moeten nog op de Arduino aangesloten worden.

Hoe staat het met het testen. Krijg je al wat aan de gang?

Groet,

Gerard van der Sel.