Hallo, ik ben samen met mijn zoon een bergbaan aan het bouwen.
Er zijn 3 lussen, waarvan de laatste nog gemaakt moet worden met spiralen.
Elke lus krijgt een eigen snelheids regeling.
Het geheel wordt aangestuurd door arduino waarvan elke arduino mega een deel voor zijn rekening neemt.
De besturing is al aardig rond, alleen de blokken en wat leds moeten nog geinstalleerd en aangesloten worden.
Ben wel benieuwd op welke manier je de mega's gebruikt. Wil je daar wat meer over kwijt?
Heb zelf een mega compatible klaar liggen die straks een lus met 5 opstelsporen moet gaan aansturen (als i2c slave op een RPi) met een aftakking naar mijn voorgrond station. In mijn situatie zorgt de RPi ook voor de interface met mij.
Ik gebruik 1 mega voor de servo sturing van de wissels en de 2e voor stroomloos schakelen van niet doorgaand spoor.
Beide verzorgen de duo leds in het controlepaneel. Schakelaar input gaat naar beide arduino's.
Een 3e verzorgd het bloksysteem. Input van hall sensoren en soms een wissel, outputs gaan naar een relaismodule en een aantal seinposten.
Een 4e verzorgd het rijden zelf via een pwm aangestuurde motor controller. Potmeters regelen rijsnelheid.
Tzt komen er meer arduino's bij.
Ik vind het fijn om per regeltaak een aparte arduino te hebben, zo is het makkelijker te programmeren en overzicht te houden. En eenvoudiger uit te breiden.
Leuk om dit te lezen. Ik ben zelf nu ook een jaartje bezich met Arduino's (Ik gebruik ze alleen om de verlichtingen op mijn baan te sturen.)
Je kunt de Arduino volgens mij ook gebruiken om je baan met DCC aan te sturen (heb ik wel eens gehoord)
Dat is natuurlijk ook weer een uitdaging als je alles met Arduino's doe.
Het begon met veel zoeken op het internet en een test pendelbaantje.
Experimenteren met de programma's en sensoren. Van ldr naar reed naar infra rood naar uiteindelijk hall sensoren.
En natuurlijk nog veel meer...
Interessant om te lezen ..
En hoe hou je de timing tussen de verschillende arduino's in de pas of is dat niet aan de orde?
Ben je ook bereid om je sketches te delen?
Naar het gebruik van de Hall sensoren ben ik ook wel nieuwsgierig. Zijn die gevoelig genoeg om het magnetisch veld van de motoren in de treintjes te herkennen (en zo ja, kan er onderscheid worden herkend tussen verschillende treinen?) of gebruik je losse magneten?
Ik heb magneetjes onder de locs, op de motoren reageren ze niet.
De ene module is de andere niet en heb een paar van robotdyn moeten verbouwen op reed sensoren die ik had liggen omdat ze maar 3,3V naar de DI van de arduino zonden, deze detecteerde dan geen hoog signaal.
De sketches kan ik wel op de site zetten, die volgen nog.
Alle arduino's doen hun eigen ding afzondelijk van elkaar en hebben dus geen klok nodig.
Ik was even nieuwsgierig of hall sensoren gevoelig genoeg zijn om het magnetisch veld van een electro motortje in een modeltrein op te pikken. kennelijk niet dus (zo leer ik er ook weer van )
Ja, met digitale modules rond arduino is het wel handig om de 3.3 of 5v in de gaten te houden
Er bestaan overigens 'level shifters' die vertalen bv 3,3v digitale signalen naar 5v en omgekeerd (ik gebruik zo'n level shifter om de 3.3v I2C van de RPi te laten praten met de 5v I2C van de arduino).
Begrijp ik goed dat de leds door de ene arduino worden geschakeld op basis van de stand van de schakelaar en dat diezelfde schakelaar via een andere arduino een wissel laat omzetten mbv een servo?
Heb je nog iets van terugmelding door het wissel zelf?
Dat klopt, sterker nog, 3 arduino's krijgen eenzelfde input van tuimelschakelaars. Een stuurt een servo aan en leds, de ander een relais voor stroomloos afh van de wisselstand en ook een aantal leds en een 3e geeft een blok vrij afh van een wisselstand (state change detection) om een trein te laten passeren op dubbelspoor.
De servo's hebben geen terugmelding oid.
Een indrukwekkende hoeveelheid draadjes zo bij de baan.
Ikzelf ben bezig om het gebruik van een Arduino Mega icm electronica onder de knie te krijgen met een kleine testbaan.
Op de Arduino heb ik ControlStation EX 3.0.0 DCC centrale sketch gezet. Leuk om uit te zoeken.
// W1 is toggle switch position for turnout 1, comes via DB37 plug and Arduino Mega 1/ 2
pinMode(W1, INPUT_PULLUP);
pinMode(W2, INPUT_PULLUP);
pinMode(W5, INPUT_PULLUP);
pinMode(W12, INPUT_PULLUP);
}
void loop()
{
// read the Hall sensor (Block) input pin:
int Ha1aState = digitalRead(Ha1a); int Ha1bState = digitalRead(Ha1b);
int Ha2State = digitalRead(Ha2);
int Ha3State = digitalRead(Ha3);
int Ha4State = digitalRead(Ha4);
int Ha5State = digitalRead(Ha5);
int Ha6State = digitalRead(Ha6);
int Ha7State = digitalRead(Ha7);
int Ha8State = digitalRead(Ha8);
int Ha9State = digitalRead(Ha9);
int Ha10State = digitalRead(Ha10);
int Ha11State = digitalRead(Ha11);
int Ha12aState = digitalRead(Ha12a); int Ha12bState = digitalRead(Ha12b);
int Ha13State = digitalRead(Ha13);
// read status free block 1
int L1aState = digitalRead(S1a);
int L9State = digitalRead(S9);
int L12aState = digitalRead(S12a);
// read the turnout (toggle switch) position)
int W1State = digitalRead(W1);
int W2State = digitalRead(W2);
int W5State = digitalRead(W5);
int W12State = digitalRead(W12);
// Timer reference
unsigned long currentMillis = millis();
// Hall sensor LOW, means activated (set previous Block powerless), relay set to LOW (indicator led ON)
// Track Wires connected to relay in NC position
// Block 1 occupied = Block 1 is double track with 2 light signals.
if ((Ha1aState == HIGH && lastHa1aState == LOW) || (Ha1bState == HIGH && lastHa1bState == LOW))
{
digitalWrite(S4, HIGH); // 34
digitalWrite(S7, HIGH); // 37
digitalWrite(S5, LOW); // 35
delay(10);
lastHa1aState = Ha1aState;
lastHa1bState = Ha1bState;
}
if (W1State != lastW1State) // Checks if turnout 1 has shifted since last position (which the train used to occupy track Ha1a or Ha1b)
{
relaisS5Millis = currentMillis;
enabledS5 = true; // turn on software timer
}
if ( enabledS5) // software timer is active ?
{
if ( currentMillis - relaisS5Millis >= interval)
{
digitalWrite( S5, HIGH); // turn off led
enabledS5 = false; // stop software timer
}
}
// Block 2 occupied
if (Ha2State == HIGH && lastHa2State == LOW)
{
digitalWrite(S5, HIGH); // 35
digitalWrite(S1a, LOW); // 30
digitalWrite(S1b, LOW); // 31
lastHa2State = Ha2State;
delay(10);
}
// Block 3 occupied
if (Ha3State == HIGH && lastHa3State == LOW)
{
digitalWrite(S1a, HIGH); // 30
digitalWrite(S1b, HIGH); // 31
digitalWrite(S2, LOW); // 32
delay(10);
}
// Block 4 occupied
if (Ha4State == HIGH && lastHa4State == LOW)
{
digitalWrite(S2, HIGH); // 32
digitalWrite(S3, LOW); // 33
delay(10);
}
// Block 5 occupied
if (Ha5State == HIGH && lastHa5State == LOW)
{
digitalWrite(S4, LOW); // 34
digitalWrite(S7, LOW); // 37
digitalWrite(S3, HIGH); // 33
digitalWrite(S6, HIGH); // 36
digitalWrite(S10, HIGH); // 40
delay(10);
}
// Block 6 occupied
if (Ha6State == HIGH && lastHa6State == LOW)
{
digitalWrite(S1a, HIGH); // 30
digitalWrite(S1b, HIGH); // 31
digitalWrite(S2, LOW); // 32
delay(10);
}
// Block 7 occupied
if (Ha7State == HIGH && lastHa7State == LOW)
{
digitalWrite(S2, HIGH); // 32
digitalWrite(S9, HIGH); // 39
digitalWrite(S13, HIGH); // 43
digitalWrite(S6, LOW); // 36
digitalWrite(S10, LOW); // 40
delay(10);
}
// Block 8 occupied
if (Ha8State == HIGH && lastHa8State == LOW)
{
digitalWrite(S2, HIGH); // 32
digitalWrite(S9, HIGH); // 39
digitalWrite(S13, HIGH); // 43
digitalWrite(S6, LOW); // 36
digitalWrite(S10, LOW); // 40
delay(10);
}
// Block 9 occupied
if (Ha9State == HIGH && lastHa9State == LOW && Ha8State == LOW)
{
digitalWrite(S6, HIGH); // 36
digitalWrite(S10, HIGH); // 40
digitalWrite(S8, LOW); // 38
delay(10);
}
// Block 10 occupied
if (Ha10State == HIGH && lastHa10State == LOW)
{
digitalWrite(S8, HIGH); // 38
digitalWrite(S12a, HIGH); // 42
digitalWrite(S12b, HIGH); // 44
digitalWrite(S9, LOW); // 39
digitalWrite(S13, LOW); // 43 Bergspoor komt binnen op binnenlus
digitalWrite(S6, LOW); // 36 Binnenlus krijgt hiermee voorrang op buitenlus wanneer er een trein naar de binnenlus gaat
delay(10);
}
// Block 11 occupied
if (Ha11State == HIGH && lastHa11State == LOW)
{
digitalWrite(S9, HIGH); // 39
digitalWrite(S13, HIGH); // 43
digitalWrite(S10, LOW); // 40
delay(10);
}
// Block 12 occupied = Block 12 is double track with 2 light signals.
if ((Ha12aState == HIGH && lastHa12aState == LOW) || (Ha12bState == HIGH && lastHa12bState == LOW))
{
digitalWrite(S10, HIGH); // 40
digitalWrite(S11, LOW); // 41
delay(10);
lastHa12aState = Ha12aState;
lastHa12bState = Ha12bState;
}
if (W12State != lastW12State) // Checks if turnout 1 has shifted since last position (which the train used to occupy track Ha1a or Ha1b)
{
digitalWrite(S11, HIGH); // 35
delay(10);
}
// Block 13 occupied
if (Ha13State == HIGH && lastHa13State == LOW)
{
digitalWrite(S11, HIGH); // 35
digitalWrite(S12a, LOW); // 30
digitalWrite(S12b, LOW); // 31
delay(10);
}
// licht signaal Blok 1 na vrijgave door blok 3 afhankelijk van wissel 2
if (W2State == HIGH && L1aState == HIGH) // L1aState is de blok vrijgave, zolang deze er niet is blijft alles rood W2State is wisselsturing wissel 2 vanuit arduino Mega 2 pin ...
{
digitalWrite(relaisL1a, HIGH);
digitalWrite(relaisL1b, LOW);
delay(10);
}
else if (W2State == LOW && L1aState == HIGH)
{
digitalWrite(relaisL1a, LOW); // ene spoor rood andere groen door wisselstand
digitalWrite(relaisL1b, HIGH);
delay(10);
}
else
{
digitalWrite(relaisL1a, LOW); // Alles op rood, blok bezet
digitalWrite(relaisL1b, LOW);
delay(10);
}
// licht signaal Blok 9 na vrijgave door blok 7, 8 of 11 (1 relais ivm licht signaal enkel spoor)
if (W5State == HIGH && L9State == HIGH) // L9State is de blok vrijgave, zolang deze er niet is blijft alles rood W5State is wisselsturing vanuit arduino Mega 2 pin ...
{
digitalWrite(relaisL9, HIGH);
delay(10);
}
else if (W5State == LOW && L9State == HIGH)
{
digitalWrite(relaisL9, LOW); // enkel licht signaal op block 9
delay(10);
}
else
{
digitalWrite(relaisL9, LOW); // Alles op rood, blok bezet
delay(10);
}
// licht signaal Blok 12 na vrijgave door blok 10
if (W12State == HIGH && L12aState == HIGH) // L12State is de blok vrijgave, zolang deze er niet is blijft alles rood W12State is wisselsturing vanuit arduino Mega 2 pin ...
{
digitalWrite(relaisL12a, HIGH);
digitalWrite(relaisL12b, LOW);
delay(10);
}
else if (W12State == LOW && L12aState == HIGH)
{
digitalWrite(relaisL12a, LOW); // ene spoor rood andere groen door wisselstand
digitalWrite(relaisL12b, HIGH);
delay(10);
}
else
{
digitalWrite(relaisL12a, LOW); // Alles op rood, blok bezet
Include the VarSpeedServo.h and Bounce2.h libraries in IDE before compiling !
***
A maximum of 12 servo objects can be created from library.
A maximum of 11 servoes can be controlled by the latest variants
Uno, Nano & Mini having pins A6 & A7 on the board.
Change constants : pin no, speed, range_low, range_high, and
detachTime to trim your layout switches operation. In fact
everything moving the servos and for how long can be trimmed.
Define Arduino pin usage, which are constants :
Arduino pins 0 & 1 are here reserved for any serial communication
i.e. for debugging or future inter comm (TCC) between arduino units.
The pin numbers are those found printed on the arduino board.
They apply to all Arduino Uno, Nano & Mini variants,
but can of course be re-arranged to suit the extra A6 & A7 pins
found on later revisions of Uno derivatives.
This can make for an extra servo channel.
All input pins are set to mode PULL_UP for noise reduction and
the state of input pins are debounced by code.
An override toggle switch can be added to pin 2 as input.
A LOW (GND) level on this pin will set all servo channels to
mid position 90° for physical installation of the servos.
If the input is left open, the internal PULL_UP will set the
input high, which disables the mid position feature.
The internal LED is set to blink every time loop() is
traversed, to indicate activity. If the code is trapped, the
LED will stay dark or at full intensity.
If midpoint input is set active LOW, the blink pace is decreased.
The LED output is availabe at pin13, for a remote LED indication
of the controller status.
2. Verbind de juiste nummer digitale ingang met de common van het relais of tuimelschakelaar. Dus pin 1 naar relais 1 voor servo 1 etc.
3. Verbind de GND, oftewel 0 Volt met de NC of één van buitenste pinnen van de schakelaar. Je kunt later nog de NC of NO omwisselen indien gewenst.
4. Verbind de 5V met 10kOhm naar de signaal draad op de Common poot van de schakelaar of relais. (zonder weerstand loopt er te veel stroom door de arduino, je maakt dan sluiting)
5. Laad de code in op de aruino. Code volgt, of op aanvraag.
6. Steek de servo in op 8/tm12. Voor servo 2 gebruik je pin 8 etc [dus servo n= pin n+6]. Het beste is om pin 1 en 2 niet te gebruiken.
7. Stel de middenstand van de servo goed af. Standaard staat de code op Low= 85 graden High is 95 graden. Dit kun je aanpassen maar hou 90 graden altijd in het bereik omdat dit de 0 stand is bij opstart, doe je dit niet heb je kans op schade.
8. Ga nu de High en Low fine tunen zodat de servo ver genoeg komt maar niet blijft brommen. Zie ** 85 en 95 graden. Beide grenzen kun je dus fine tunen per servo. Het advies is om een servo tester te gebruiken om met de potentiometer de grenzen op te zoeken en die dan in het arduino programma aan te passen. 1500hz is 90 graden, 800hz is 0 en 2200hz is 180 graden.
NOTES :
Switch = turnout.
Button = input control toggle switch or relay wiper contact.
The reset input pin RST may be remote controlled by an external
pushbutton or a springloaded SPST toggle switch to ground.
CHECK!
digitalWrite(servoPins[8], !digitalRead(servoPins[8])); Was [2] [2]
bounceReadInput(8); Was (2)
void bounceReadInput(byte i)
{
debouncer.update(); Was (i < 2)
if (i < 8)
*/
#include <VarSpeedServo.h> // These 2 includes have to be in the library folder, otherwise the ide gives a error message
#include <Bounce2.h>
// Constants to trim switch servo behaviour, mid = midpoint parameters
const byte LedStraight[] = {20, 22, 24, 26, 28, 30, 32, 34, 36}; // green led to indicate servo position 1, 2nd connected led in parallel is red color (bend)
const byte LedBend[] = {21, 23, 25, 27, 29, 31, 33, 35, 37}; // led to indicate servo position 2, 2nd connected led in paralled is red color (straight)
In de eerste leesronde valt me op dat je bij de blok besturing elk blok helemaal afzonderlijk hebt uitgeschreven. Is er niet een 'gemene deler' die je in een aparte functie kunt stoppen en dan in je bloksturing kunt aanroepen?
(mijn persoonlijke uitgangspunt is om dat al te doen als een aantal regels code 2 keer wordt gebruikt op verschillende plaatsen en ik zou daarin zelfs zover gaan dat ik een universele functie schrijf die per blok met de voor dat blok unieke variabelen wordt aangeroepen. Daarmee zeg ik niet welke manier de juiste is hoor, want wat voor mij werkt, hoeft niet voor jou te werken en andersom. Dit is jouw code en het is vooral handig als jezelf goed de weg weet te vinden in die code )
Die 2e sketch ga ik zeker wat uitgebreider bekijken. Denk dat daarin wel wat dingetjes zitten die voor mij ook kunnen gaan werken
Specifiek voor mijn project doet de arduino alleen het suffe loopwerk van wissels schakelen, wisselstand terugmelden, bezetting en rijrichting melden en rijspanning schakelen (of dat een pwm vanuit de arduino wordt of een externe rijspanning ben ik nog niet helemaal uit)
Via de I2C bus rapporteerd de arduino dan aan de RPI die het slimmere deel voor zijn rekening neemt en de interface met mij verzorgd (oa dead-reckoning welke trein op welk moment waar op de baan is en dan beslist of in het station de locomotief (getrokken trein) moet omlopen of niet (trek-duw combi) Tot zover de showspoor lus.
Himbeeren Wald zelf gaat voornamelijk rechtstreeks op de RPi Alleen de sector draaischijf en de secties waar een loc kan omlopen krijgen elk een aparte arduino die via de I2C bus contact hebben met de RPi. De RPi blijft bij mij altijd de centrale hub voor alles wat er gebeurt op de baan.
Whoa, meteen lekker de diepte in.
Is er iets van een totaaloverzicht of systeemarchitectuur waar je de samenhang der dingen ziet?
(begrijp me goed, ik vind dit bere-interessant als oud-systeembakker, maar probeer vooral het totaal te snappen)
Steven
Hier is mijn baan op het forum Hier is mijn vorige baan op het forum Hier is mijn voor-vorige baan op het forum
>>> Filmpjes van de baan
De blokbesturing sketch is idd vrij basic, ik wilde snel bezig met de baan dus heb wel iets zitten experimenteren, maar dat liep nog op niets uit. Wellicht iets voor later om de sketch om te bouwen, maar dan moet ik me er echt in verdiepen hoe ik dat het beste kan doen.
Zoals je ziet is de 2e sketch ook geleend en aangepast ( dat gaat me makkelijker af dan een geheel nieuwe schrijven).
Ik heb her en der comments geplaatst om de sketch te verduidelijken, ik zal nog een overzichts tekening van de baan met codering sturen ter verduidelijking.
Mooi om te zien dat er steeds meer mensen zijn die zelf proberen het wiel opnieuw uit te vinden. Dat bedoel ik overigens op een positieve manier! Het toont aan dat 'met treintjes spelen' zoveel meer is (of kan zijn) dan wat 'de buitenwereld' altijd denkt.
@mtukker75
Ik ben me net een beetje aan het verdiepen in de Arduino (bij mij de Uno).
Ik heb al een paar voorbeelden nagebouwd en dat werkt erg leuk zie ik.
Ik rij digitaal met een Z21 Start op een kleine baan maar bedien mijn wissels gewoon nog handmatig met de Minitrix schakelaars (de groene) (en dat wil ik blijven doen).
Waar ik een Arduino voor wil gebruiken is ledjes aansturen die aangeven hoe de wissels staan dus, als ik de drukknopkleuren wil gebruiken een gele led voor rechtdoor, een groene led voor afbuigend.
De wissels schakelen met een 12V= puls om.
Dus bij bv een "gele" puls op een ingang moet er een gele led gaan branden en bij een "groene" puls een groene led.
De 12V= is te hoog lijkt me dus hoe krijg ik die op een simpele manier omlaag zodat ik die als ingangspuls kan gebruiken voor de arduino?
Hoe zorg ik dat er maar naar 1 puls wordt gekeken (dus 2, 3, 4 x op dezelfde toets drukken moet niets wijzigen in de status van de led, alleen bij een puls van de andere drukknop moet de ene led doven en de andere constant aan gaan.
Veel vragen van een beginner maar hopelijk kan je me een beetje op weg helpen.
Om een led te gebruiken moet je de spanning verlagen, dat doe je met een voorschakelweerstandje.
Hier zijn wat tools om hem te berekenen.
Ik gebruik vaak deze:
maarten schreef: ↑11 dec 2020 10:17
Da's dan weer een old fashioned analog sketch.
Mooi om te zien dat er steeds meer mensen zijn die zelf proberen het wiel opnieuw uit te vinden. Dat bedoel ik overigens op een positieve manier! Het toont aan dat 'met treintjes spelen' zoveel meer is (of kan zijn) dan wat 'de buitenwereld' altijd denkt.
Inderdaad, leuk om te zien.
Het aardige aan de Arduino is dat er meerdere uitvoeringen zijn voor verschillende doeleinden. De kleinste (ATTiny) koop je voor iets van een euro bij onze Chinese vrienden en zijn heel geschikt om bijvoorbeeld lampjes aan te sturen of een bewegend onderdeel van je baan.
Steven
Hier is mijn baan op het forum Hier is mijn vorige baan op het forum Hier is mijn voor-vorige baan op het forum
>>> Filmpjes van de baan
Bedankt voor je info.
Dat een led een voorschakelweerstand nodig heeft is me bekend.
Het gaat meer om hoe ik eea werkend krijg met een Arduino Uno.
Je linkjes zijn zeker handig en ik heb ze bij mijn favorieten gezet.
@who2010
Om een knop te onthouden werk je met state changes, zie eerste sketch. Een trein rijd over een sensor, deze is even hoog tot de trein gepasseerd is. De state veranderd en word onthouden, bij mij schakelen dan een relais en leds... tot een andere sensor geactiveerd wordt en de boel terug schakelt. Met knopjes werkt dat net zo.