Google+
Doel:€250.00
Donaties:€19.65

Per saldo:€-230.35

Steun ons nu!

Laatst bijgewerkt
op 13-05-2018
Algemeen

De stichting

Recente berichten

Rangeerbaantje door Bert V
Vandaag om 23:12:21
Oersik in schaal 1 door FritsT
Vandaag om 22:59:07
"Litter Bin" voor Brits spoor en Britse modelspoorprojecten door Thijs1271
Vandaag om 22:58:33
1700 NS enzo (reacties op slooptransportfoto) door Thom
Vandaag om 22:55:05
BMB 00-modulebaan, Algemeen. door St00mboy
Vandaag om 22:35:03
Raadplaatje door GerardvV
Vandaag om 22:29:46
HO-wagen, wie kan er een tekst op maken? door RhBfan
Vandaag om 22:22:05
Hulp gevraagd bij schaalkeuze. Van n naar z of toch maar niet. door C_cornelis_S
Vandaag om 22:11:53
Rhb (H0m) - Station “Versam-Safien” (Swiss-Almere) door Wouter_
Vandaag om 21:32:04
Roco draadloze muis koppelen met DR5000? door Dirk
Vandaag om 21:17:06
MFX-loc met DCC aansturen, Märklin CS3+, probleem met functies door Supercitroen
Vandaag om 21:15:40
BNLS Module: "Chicago Union" door jakeman
Vandaag om 21:13:25
Artitec Mat '54, aanpassen en verbeteren door MDK193
Vandaag om 21:12:11
BNLS Baanbreker - Project 083 tot 338 door 44
Vandaag om 21:01:09
Artitec Mat '54, materieelbespreking. door NS8714
Vandaag om 20:50:28
Fleischmann draaischijf wil niet meer! door Leolin
Vandaag om 20:25:16
Everskerke, een fictief station aan de Zeeuwse lijn in de jaren '70 in H0. door Ronald Halma
Vandaag om 19:38:52
Mijn eerste H0 modeltreinbaan in aanbouw door Wim Vink
Vandaag om 19:33:35
Station N-Spoor 2018 door Martin Domburg
Vandaag om 19:15:11
Toon hier je nieuwe (model) spooraanwinst(en)... door Tomasso
Vandaag om 19:04:05
  

Auteur Topic: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen  (gelezen 2235 keer)

Robert E

  • Offline Offline
  • Berichten: 794
    • Micro controllers en modelspoor
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #15 Gepost op: 22 april 2018, 14:45:33 »
Je kunt nog eens naar CAN kijken (link is eerste beste die ik zag)

http://henrysbench.capnfatz.com/henrys-bench/arduino-projects-tips-and-more/arduino-can-bus-module-1st-network-tutorial/

Of Bidib

https://www.opendcc.de/bidib/overview/overview.html

Verkijk je niet op de Arduino's en ENC28J60, daar haal je geen 1GByte mee :)

Welke Arduino's gebruik je eigenlijk?

Mvg

Robert
MDRRC-II goedkope DIY centrale voor DCC en MM

meino

  • Offline Offline
  • Berichten: 153
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #16 Gepost op: 22 april 2018, 15:12:09 »
 Dag Robert

nee dat ik geen 1Gb haal weet ik, de betreffende kaartjes gaan niet verder dan 10Mb, maar dat is al 100x sneller dan de 100Kb van I2C. Dus voor mijn toepassing is dat ruim voldoende. Ik gebruik Mega's. Ik denk zelf dat een Uno (of Nano) misschien aan de krappe kant is voor wat ik wil, maar dat ga ik uitproberen.

Bedankt voor de tips over CAN en Bidip daar ga ik ook nog eens naar kijken.

Groet Meino
A clean desk is a sign of an empty mind

meino

  • Offline Offline
  • Berichten: 153
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #17 Gepost op: 22 april 2018, 16:35:38 »
Dag Robert

ik heb nog eens naar die andere bussen gekeken. Bidib is zoals Karst zegt de natte droom voor electrotechnici, Dat ben ik niet en vindt de oplossing voor mijn toepassing veel te zwaar, met al die hardware. Echter om eerlijk te zijn de CAN bus is misschien precies wat ik zoek, net als I2C een simpele oplossing met 2 draadjes en een simpel protocol om pakketjes van de ene node naar de andere node te krijgen, met een zeer ruime adres ruimte en voldoende snelheid, dus heb ik ook maar 2 kaartjes (MCP2515 CAN Bus Module TJA1050) uit China besteld om dat ook eens uit te proberen.

Groet Meino
A clean desk is a sign of an empty mind

gvandersel

  • HCC!m maar toch Selectrix (RMX)
  • Offline Offline
  • Berichten: 2955
  • Als het maar elektrisch is.
    • Homepage Gerard van der Sel
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #18 Gepost op: 23 april 2018, 12:03:27 »
\Oke dan nog een alternatief. Volledig zelfbouw, maar toch maar eens geschoten. De SX-bus. Je richt een van je Arduino's in als master en je "klikt" de volgende er snel op. Eigenschappen SX-bus: bidirectioneel, opgebouwd rond een LM339/4049, geen speciale kabel nodig (tenzij je fabrieks apparatuur gebruikt), 112 adressen (van 8 bit). Het communicatie protocol is synchroon en iedere 76,8 msec worden alle adressen langs gestuurd.
Zowel een master als een slave zijn beschikbaar voor de Arduino.
(Wordt op dit moment door Railclub Utrecht voor cimmunicatie onder hun modelbaan gebruikt.)


Groet,

Gerard van der Sel.
Holzburg (IIIb/IVa) schaal N.
Kijk ook eens bij de bouw en lees de avonturen.

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 3829
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #19 Gepost op: 23 april 2018, 12:42:49 »
Allereerst I2C. In de ideale wereld is inderdaad de capaciteit de bottle neck. Maar naast dat je waarschijnlijk niet ideale kabel gebruikt wordt in die "several meters" geen storing meegenomen. Dat is puur en alleen de gestelde steilheid van de flanken kunnen halen.

nee dat ik geen 1Gb haal weet ik, de betreffende kaartjes gaan niet verder dan 10Mb, maar dat is al 100x sneller dan de 100Kb van I2C.
Nouwwwwwwww, verkijk je niet. De module meldt zich als 10Mbit maar met een 8-bit micro zonder hardware ethernet support of DMA mag je denk ik blij zijn met dezelfde snelheid als fast-I2C (400kbit) en dat is zonder de overheid van ethernet. En van dat laatste heb je wel het een en ander. Adressering nog niet eens bekeken maar goed, dat heb je met I2C nu ook. In mijn optiek is ethernet dus een beetje zwaar voor deze toepassing. Maar laat je je daardoor zeker niet weerhouden om het te proberen ;D

CAN lijkt me dan wel weer een aardige zeker met de goedkope CAN-drivers en CAN-receiver die er zijn. Maar zelf helaas nog niet mee gespeeld.

En denk je echt zoooo veel snelheid nodig te hebben voor wat commando's? :o Met zowel XpressNet als LocoNet worden toch aardig grote banen aangestuurd zonder problemen.


Timo
Verzonden vanaf mijn desktop met Firefox

meino

  • Offline Offline
  • Berichten: 153
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #20 Gepost op: 23 april 2018, 13:28:14 »
Hoi Timo

die Ethernet oplossing heeft een grote nostalgische aantrekkingskracht, van 85-97 was ik o.a. IP en netwerk architect. Dus IP (en Ethernet) ken ik als mijn broekzak. Ik weet dus ook wat overhead etc doet ten aanzien van de performance.

Maar ik heb nu eigenlijk besloten om voor deze toepassing de CAN bus te gaan gebruiken. Ik had dat eerder kunnen weten, want ik ben lid van MERG en die hebben een eigen systeem van modules, nl de CBUS. Die gebruiken ook de CAN bus voor de communicatie. Ze hebben een interessante oplossing, nl een Producer-Consumer model voor hun communicatie, ik denk dat ik dat ook maar ga implementeren.
Ik geloof best dat de performance van Loconet, XpressNet, Bidib, Cbus etc meer dan voldoende is, de reden dat ik toch die kant niet opga is dat al deze oplossingen te groot zijn. Ze leveren een complete oplossing met uitgedefinieerde protocollen en complete hardware oplossingen. Ik zoek eigenlijk alleen een goed en betrouwbaar transport medium waarmee ik informatie van Node A naar Node B kan krijgen, waarbij de benodigde hardware zo simpel mogelijk is. Dat sprak me aan met de I2C bus en nu bij de CAN bus. Overigens ook de Ethernet oplossing spreekt me om die reden aan, afgezien van het feit dat ik met Ethernet en IP weer terug ben op mijn "Stomping Ground"

@Gerard, bedankt voor het idee van de SX bus, maar interface kaartjes voor de CAN bus kosten nog geen 1,5 euro en op een gegeven moment moet je een keus maken voor iets, en daarom ga ik op dit moment  eerst de CAN bus eens proberen.

Groet Meino
« Laatst bewerkt op: 23 april 2018, 13:34:52 door meino »
A clean desk is a sign of an empty mind

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 3829
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #21 Gepost op: 23 april 2018, 13:35:31 »
(y) Wat ik al zei, jij moet er lol in hebben dan heeft het zijn doel bereikt ;D

Toch nog één ding. ;D


Timo
Verzonden vanaf mijn desktop met Firefox

meino

  • Offline Offline
  • Berichten: 153
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #22 Gepost op: 23 april 2018, 13:45:11 »
Leuk

Groet Meino
A clean desk is a sign of an empty mind

Klaas Zondervan

  • Online Online
  • Berichten: 15340
    • Pagina van klaas
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #23 Gepost op: 23 april 2018, 14:40:03 »
Toch nog één ding. ;D
Had hem al eens eerder gezien, maar geeft treffend de situatie weer. Ik snap ook niet waarom elke firma zijn eigen bus moet uitvinden. Volgens mij verschillen ze alleen maar op hardware level.
Take it slow, the pace is not what matters, it's the direction that you go. (J.R. Cash)

Robert E

  • Offline Offline
  • Berichten: 794
    • Micro controllers en modelspoor
Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
« Reactie #24 Gepost op: 23 april 2018, 20:33:24 »
    Citaat
    nl de CBUS.

    Je kunt ook voor de Maerklin variant gaan :)

    https://www.maerklin.de/fileadmin/media/produkte/CS2_can-protokoll_1-0.pdf

    Meen dat in dit document de terugmelding niet is beschreven....

    Citaat
    Ik snap ook niet waarom elke firma zijn eigen bus moet uitvinden.

     * Geld verdienen
     * IP bescherming
     * Laat je concurrent NIET simpel connectie maken met hun goedkope apparaat aan jouw eigen (duurdere) apparatuur.....
     * Dat kan veeeeeeeeeeeeeeeeel beter....
     * .....

    Maar back on topic :)

    Mvg

    Robert

    [/list]
    « Laatst bewerkt op: 23 april 2018, 20:39:03 door Robert E »
    MDRRC-II goedkope DIY centrale voor DCC en MM

    meino

    • Offline Offline
    • Berichten: 153
    Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
    « Reactie #25 Gepost op: 29 april 2018, 22:20:28 »
    Ok, op basis van alle reacties en de discussie die daar opvolgde, ga ik toch een versie 2 bouwen.



    Dit is niet zoals het momenteel gebouwd is, het gebruik van de I2C bus is toch te beperkt en kan bij nabouw tot onvoorziene problemen leiden. Dus dit gaat meer een bouw verslag worden waarin ik de (ver)bouw van de diverse modules beschrijf. Voor het ontwerp en de realisatie zijn de volgende zaken van belang.

    - Als bus ga ik voor de CAN bus, dat is een bewezen oplossing en algemeen in gebruik. Interface kaartjes zijn makkelijk te krijgen en kosten weinig.
    - De communicatie tussen de verschillende componenten volgt het Producer-Consumer model. Dat betekend dat sommige componenten (Producenten) gebeurtenissen (events) registreren en dat als bericht op de bus publiceren zonder te weten voor wie dit belangrijk is. Andere componenten (Consumenten) lezen alle gepubliceerde berichten en handelen eventueel een bericht af.  Dit is een model dat gevolgd wordt door Marklin met de CS2 en MERG met de CBUS.
    - De keuze voor een van deze twee protocollen wordt uitgesteld tot later. Doordat C++ een object oriented taal is, kan ik dat makkelijk achter de facade van de protocol objecten verbergen.
    - In de huidige implementatie zijn een aantal functionele componenten samen op een Arduino actief. Door de keuze van het Producer-Consumer model is het verstandiger om deze componenten (DCC interface en S88 interface) te scheiden en uit te rollen op een eigen Arduino.

    Nog even wat anders, waarom doe ik dit terwijl er kant en klare oplossingen zijn?
    - Ik vind programmeren en het oplossen van dit soort technische problemen leuk.
    - Het kostenaspect.

    Zo dit is het voor nu, het wachten is op de CAN bus kaartjes.

    Groet Meino
    A clean desk is a sign of an empty mind

    meino

    • Offline Offline
    • Berichten: 153
    Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
    « Reactie #26 Gepost op: 01 mei 2018, 17:37:50 »
    Voordat ik verder ga met de beschrijving van de meeste componenten, wacht ik totdat ik de CAN-bus heb geïmplementeerd.

    Er is echter een component waarbij de implementatie van de CAN-bus niet erg relevant is voor de werking, die zal ik dan nu proberen te beschrijven. Dit is ook een buitenbeentje voor wat betreft de functionaliteit, dat is de SeinController.
    Een klein beetje achtergrond, oorspronkelijk was ik van plan om alles met klassieke armseinen te doen aangestuurd vanuit Koploper. Maar ik ontdekte dat er 3D geprinte driehoogte seinen van het seinstelsel 1946 bestonden. Nadat ik als proef er een gebouwd had en het bleek dat het mogelijk was om deze werkend te krijgen (zie draadje https://forum.beneluxspoor.net/index.php?topic=34476.msg3221800162#msg3221800162), besloten om voor het grootste deel (hoofdbaan + Emplacement) met seinstelsel '46 te beveiligen.
    Maar er waren wel een aantal complicerende factoren, Koploper heeft geen definities voor dit seinstelsel, en voor Koploper gurus is het misschien simpel, maar mijn ervaring met Koploper bij het configureren van de NS Armseinen was niet van dien aard dat ik het met Koploper wilde proberen te doen, ik vindt het makkelijker om een Arduino programma te ontwikkelen dan me in krochten van Koploper te begeven.
    Het seinstelsel '46 heeft als bijzonderheid dat het verschillende seinbeelden kent die afhankelijk zijn van de toegestane snelheid op het huidige en verwachte baanvak.
    Wat voorbeelden, waarbij ik een versimpeld deel van Kranenberg gebruik. Het betreft het hoofdspoor dat door het station gaat en twee parallel sporen, de treinen rijden van links naar rechts.



    Wissel 1 staat rechtdoor, sein en wissel mogen met 120km/u gepasseerd worden, voor het perronspoor geldt een maximum
                                             van 80km/u.
       Stop voor sein 2                                    seinbeeld sein 2: rood-zwart-zwart
       Doorrijden sein 2, doorrijden sein 4      seinbeeld sein 2: groen-groen-wit
       Doorrijden sein 2, stop sein 4               seinbeeld sein 2: geel-wit-wit



    Wissel 1 rechtsaf, wissel 2 linksaf , sein en wissel mogen met 60 km gepasseerd worden wat ook geldt voor het
                                                            perronspoor.
       Stop voor sein 2                                    seinbeeld sein 2: zwart-rood-zwart
       Doorrijden sein 2, doorrijden sein 6      seinbeeld sein 2: wit-groen-wit
       Doorrijden sein 2, stop sein 6               seinbeeld sein 2: wit-geel-wit



    Wissel1 rechtsaf, wissel2 rechtsaf, sein en wissel mogen met 60km/u gepasseerd worden, voor het volgende
                                                            wissel en spoor geld een limiet van 40km/u.
       Stop voor sein 2                                    seinbeeld sein 2: zwart-zwart-rood
       Doorrijden sein 2, doorrijden sein 8      seinbeeld sein 2: wit-groen-groen
       Doorrijden sein 2, stop sein 8               seinbeeld sein 2: wit-geel-wit

    De drie stop seinbeelden mogen ook vervangen worden door een beeld nl. rood-zwart-zwart, dan
    komt het er op neer dat een driehoogte sein 13 verschillende seinbeelden kan vertonen -10 standaard plus 3 extra, nl. geel knipper (75/min)-. De drie andere seinbeelden, geel knipper snel (180/min) die later toegevoegd zijn, vergeet ik dan gemakshalve maar. Het eenhoogte sein kent 4 seinbeelden (rood, groen, geel en geel knipper (75/min), ook hier is later het seinbeeld geel knipper snel (180/min) aan toegevoegd. Overigens nog een korte opmerking, het baanplan dat ik gebruik in de voorbeelden is een schema van dit deel, het komt fysiek niet overeen en verder de snelheidsbeperkingen heb ik ook gedefinieerd om een wat gevarieerder seinbeeld te krijgen.
    Een zeer uitgebreide beschrijving van het seinstelsel '46 is te vinden op Seinarm.nl en vooral de uitleg over de situatie bij Blauwkapel 1949-1961 is erg verhelderend.

    Een andere factor om rekening mee te houden zijn de karakteristieken van de gebruikte smd ledjes. In het geval van het eenhoogte sein gebruikt ik een tweekleurige (rood-groen) smd ledje, geel maak ik door de rode en groene led tegelijkertijd aan te sturen. Helaas moet de intensiteit van iedere kleur apart geregeld kunnen worden om een goede tint geel te krijgen, verder zit er ook intensiteit verschil tussen het rood en het groen. Voor een deel kun je dit compenseren door met de waarden van de voorloop weerstand te spelen, maar een precieze afstemming doe ik door de leds aan te sturen via een PWM pin. Het zelfde geldt voor de driehoogte seinen, waar ik een drie kleuren (rood, groen en blauw) smd ledje gebruikt. De kleuren wit en geel worden ook weer geproduceerd door de kleur te mengen. Ook hier is het voor een optimale kleur nodig om ieder led kleur apart te kunnen afregelen, Vandaar dat ook hier de ledjes via een PWM pin worden aangesloten. Dat betekend dat voor een driehoogte sein ik 9 PWM pinnen, en voor een eenhoogte sein 2 PWM pinnen nodig heb. Vandaar mijn keuze om voor de SeinController een Arduino Mega te gebruiken.

    In de volgende stukje zal ik in gaan op de programmatuur voor de arduino die dit regelt.

    Groet Meino
    « Laatst bewerkt op: 01 mei 2018, 18:36:46 door meino »
    A clean desk is a sign of an empty mind

    meino

    • Offline Offline
    • Berichten: 153
    Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
    « Reactie #27 Gepost op: 07 mei 2018, 21:53:39 »
    Hallo dan nu een stukje techniek. Ik heb voor de bouw van dit systeem een Arduino bibliotheek gemaakt (NS_Seinstel46) die de werking van het geheel realiseert. De Arduino schets bevat dan alleen maar de configuratie, een interrupt routine voor het afhandelen van de (DCC) commando's en een aantal functie aanroepen om het geheel te laten werken. Indien er belangstelling voor is, stuur me een PB voor een zip bestand met de bibliotheek.

    De werking van het geheel bespreek ik aan de hand van een versimpeld deel van het stations emplacement van Kranenberg.



    De volgende typen seinen komen daar op voor; een driehoogte sein, diverse eenhoogte seinen en een versimpeld arm vertakkingssein. Het driehoogte sein maakt gebruik van een driekleurige led, de eenhoogte seinen gebruiken tweekleurige leds en het armsein wordt met twee servo's aangestuurd en heeft een witte led voor de verlichting.

    Opmerking:
    De leds zijn verschillend, de driekleuren leds werken met een gemeenschappelijke anode, welke aan de 5v pin van de arduino is aangesloten, Dat betekend dat de werking van de PWM pinnen anders is, Als een PWM pin vol uitstuurt wordt, zal de aangesloten kleur gedoofd zijn. De twee kleuren leds en de witte led werken met de kathode die aan gnd aangesloten is. De C++ classes die de werking van de leds aansturen houden hier rekening mee. Mocht iemand driekleuren leds met common kathode willen gebruiken dan zal de RGBLed class aangepast moeten worden.

    Het arduino programma met de configuratie voor bovenstaand schema.
    /*
      A program do control railroad semaphores from the Dutch Railways (NS) system 1946

      Copyright (C) Meino de Graaf, all rights reserved

      This program is free software; you can redistribute it and/or
      modify it under the terms of the GNU General Public License
      as published by the Free Software Foundation, version 2
      of the License.

      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.
    */

    #include <Servo.h>
    #include <Wire.h>
    #include <NS_Seinstelsel46.h>


    #define I2C_BASE            8
    #define I2C_CONTROLLERS     2

    #define I2C_BEZETMELDER_ID  8
    #define I2C_SEINCONTROL1_ID 9
    #define I2C_SEINCONTROL2_ID 10
    #define I2C_SEINCONTROL3_ID 11

    //
    //  ID that defines this specific instance of the controller.
    //  It's actual value is established during setup and is based on some jumpers
    //
    int i2cId = 0;

    //
    //  Table with all active turnouts
    //
    const int nrOfTurnouts = 12;

    Turnout turnouts[nrOfTurnouts] =
    {
      Turnout(1),
      Turnout(2),
      Turnout(3),
      Turnout(4),
      Turnout(5),
      Turnout(6),
      Turnout(7),
      Turnout(8),
      Turnout(9),
      Turnout(10),
      Turnout(11),
      Turnout(12)
    };

    //
    //  Table of all defined semaphores
    //
    const int nrOfSemaphores = 7;

    Semaphore semaphores[nrOfSemaphores] = {
      //------------------- Semaphore 55 on controller 2 --------------------------//
      Semaphore(CONTROLLER(2), SEMAPHORE(55), NO_STOP_DELAY,
                new Route(TURNOUT(10),
                          new Route(TURNOUT(11),    // Turnout 10 straight
                                    new Route(SEMAPHORE(58)), // Turnout 11 Straight
                                    SPEED_HIGH,
                                    new Route(ROUTE_BARRED),  // Turnout 11 Diverting
                                    SPEED_STOP),
                          SPEED_HIGH,
                          new Route(ROUTE_BARRED), // Turnout 10 diverting
                          SPEED_STOP),
                SEIN46_EENHOOG,
                new RGLed(PWM_PIN(13), INTENSITY(255), PWM_PIN(44), INTENSITY(160))),
      //------------------- Semaphore 56 on controller 3 --------------------------//
      Semaphore(CONTROLLER(3), SEMAPHORE(56), NO_STOP_DELAY,
                new Route(TURNOUT(8),
                          new Route(TURNOUT(9),               // Turnout 8 straight
                                    new Route(SEMAPHORE(60)),     // Turnout 9 straight
                                    SPEED_MIDDLE,
                                    new Route(TURNOUT(10),        // Turnout 9 diverting
                                              new Route(ROUTE_BARRED), // Turnout 10 straight
                                              SPEED_STOP,
                                              new Route(TURNOUT(11),   // Turnout 10 diverting
                                                        new Route(SEMAPHORE(58),SPEED_LOW,DANGER),
                                                        SPEED_LOW,
                                                        new Route(ROUTE_BARRED), 
                                                        SPEED_STOP),
                                              SPEED_LOW),
                                    SPEED_LOW),
                          SPEED_HIGH,
                          new Route(ROUTE_BARRED), // Turnout 8 diverting
                          SPEED_STOP),
                SEIN46_EENHOOG,
                new RGLed(PWM_PIN(4), INTENSITY(18), PWM_PIN(5), INTENSITY(20))),
      //------------------- Semaphore 57 on controller 3 --------------------------//
      Semaphore(CONTROLLER(3), SEMAPHORE(57), NO_STOP_DELAY,
                new Route(TURNOUT(8),
                          new Route(ROUTE_BARRED), // Turnout 8 straight
                          SPEED_STOP,
                          new Route(TURNOUT(9),    // Turnout 8 diverting
                                    new Route(SEMAPHORE(60)),     // Turnout 9 straight
                                    SPEED_LOW,
                                    new Route(TURNOUT(10),        // Turnout 9 diverting
                                              new Route(ROUTE_BARRED),    // Turnout 10 straight
                                              SPEED_STOP,
                                              new Route(TURNOUT(11),      // Turnout 10 diverting
                                                        new Route(SEMAPHORE(58),SPEED_LOW,DANGER),
                                                        SPEED_LOW,
                                                        new Route(ROUTE_BARRED), 
                                                        SPEED_STOP),
                                              SPEED_LOW),
                                    SPEED_LOW),
                          SPEED_LOW),
                SEIN46_EENHOOG,
                new RGLed(PWM_PIN(6), INTENSITY(5), PWM_PIN(7), INTENSITY(6))),
      //------------------- Semaphore 58 (Dummy) ----------------------------------//
      Semaphore(58),
      //------------------- Semaphore 60 (Dummy) ----------------------------------//
      Semaphore(60),
      //------------------- Semaphore 66 on controller 1 --------------------------//
      Semaphore(CONTROLLER(1), SEMAPHORE(66), NO_STOP_DELAY,
         new Route(Turnout(2),
                          new Route(TURNOUT(3),      // Turnout 2 straight
                                    new Route(SEMAPHORE(55), SPEED_MIDDLE),// Turnout 3 straight
                                    SPEED_HIGH,
                                    new Route(TURNOUT(4),                  // Turnout 3 diverting
                                              new Route(ROUTE_BARRED),        // Turnout 4 straight
                                              SPEED_STOP,
                                              new Route(TURNOUT(5),           // Turnout 4 diverting
                                                        new Route(SEMAPHORE(56)), // Turnout 5 straight
                                                        SPEED_MIDDLE,
                                                        new Route(SEMAPHORE(57)), // Turnout 5 diverting
                                                        SPEED_LOW),
                                              SPEED_MIDDLE),
                                    SPEED_MIDDLE),
                           SPEED_HIGH,
                           new Route(ROUTE_BARRED),  // Turnout 2 diverting
    SPEED_STOP),
                SEIN46_DRIEHOOG,
                new RGBLed(PWM_PIN(2),INTENSITY(18),PWM_PIN(3),INTENSITY(15),PWM_PIN(4),INTENSITY(9)),
                new RGBLed(PWM_PIN(5),INTENSITY(20),PWM_PIN(6),INTENSITY(22),PWM_PIN(7),INTENSITY(9)),
                new RGBLed(PWM_PIN(8),INTENSITY(21),PWM_PIN(9),INTENSITY(14),PWM_PIN(10),INTENSITY(9))),
      //------------------- Semaphore 67 on controller 3 --------------------------//
      Semaphore(CONTROLLER(3), SEMAPHORE(67), DELAY_STOP,
                new Route(TURNOUT(4),
                          new Route(TURNOUT(5),                // Turnout 4 straight
                                    new Route(SEMAPHORE(56)),     // Turnout 5 straight
                                    SPEED_HIGH,
                                    new Route(SEMAPHORE(57)),     // Turnout 5 diverting
                                    SPEED_LOW),
                          SPEED_HIGH,
                          new Route(ROUTE_BARRED),             // Turnout 4 diverting
                          SPEED_STOP),
                ARMSEIN_VERTAKKING,
                new ArmServo(PWM_PIN(11), 25, 104, 66),
                new ArmServo(PWM_PIN(12), 23, 50, 93),
                new WhiteLed(PWM_PIN(13), INTENSITY(60))), // (blok 14)
    };

    //
    //  A function that executes whenever data is received from the bus
    //  this function is registered as an interupt event, see setup()
    //  It's purpose is to analyze the received event (Signal or turnout) and
    //  update the proper element in the semaphore table or turnout table.
    //
    void receiveI2CEvent(int howMany)
    {
      unsigned int x = Wire.read();    // receive byte as an integer

      unsigned int dccId = x / 2;
      unsigned int dccState = x % 2;

      //
      //  Find the proper turnout detector with the matching address
      //  and sets its state.
      //
      if (Turnout::updateDirection(dccId, dccState))
      {
        //
        //  The dcc id matched a turnout no need to try the semaphores
        //
        return;
      }
      else
      {
        //
        //  the dcc id didn't match a turnout, so try the semaphores
        //
        Semaphore::updateState(dccId, dccState);
      }
    }

    //
    //  Pins used to define the ID of this controller
    //  It is used to filter out all semaphores which aren't controlled by
    //  this instance of the SeinController
    //
    #define PIN_ID_1  51
    #define PIN_ID_2  52
    #define PIN_ID_3  53

    void setup()
    {
      //
      //  Based on which pin is connected to ground, the controller ID is established
      //
      i2cId = 0;

      pinMode(PIN_ID_1, INPUT_PULLUP);
      pinMode(PIN_ID_2, INPUT_PULLUP);
      pinMode(PIN_ID_3, INPUT_PULLUP);

      if (!digitalRead(PIN_ID_1)) i2cId = 1;
      else if (!digitalRead(PIN_ID_2)) i2cId = 2;
      else if (!digitalRead(PIN_ID_3)) i2cId = 3;

      //
      //  Tell the semaphore control where to find its turnouts and semaphores
      //  and initialize the whole shebang
      //
      Semaphore::init(i2cId, nrOfTurnouts, turnouts, nrOfSemaphores, semaphores);

      //
      //  Start the I2C communication
      //
      Wire.begin(I2C_BASE + i2cId);     // join i2c bus
      Wire.onReceive(receiveI2CEvent);  // register event handler
    }

    void loop()
    {
      //
      //  Scan all semaphores for updates in states and routes and change their
      //  image if necessary
      //
      Semaphore::loop();
    }

    De code bevat de volgende configuratie tabellen,
    Turnout turnouts[nrOfTurnouts] =
    {
      Turnout(1),    // Wissel met dcc adres 1
      …....
    };
    Deze tabel definieert alle wissels die van belang zijn voor de mogelijke routes die van sein tot sein gevolgd kunnen worden. De definitie van een wissel is simpel, nl. Turnout(dcc adres).

    Verder een tabel waarmee alle seinen worden beschreven
    Semaphore semaphores[nrOfSemaphores] = {
    …...
    };

    Laten we eens kijken naar de definitie van één Sein
    Semaphore(CONTROLLER(1), SEMAPHORE(66), NO_STOP_DELAY,
    De leds van dit sein worden aangestuurd door de Arduino met controller id 1(CONTROLLER(1)). Aangezien ik voor de aansturing van de seinen soms veel pwm pinnen nodig heb, gebruik ik meerdere arduino's. Echter ieder arduino moet een volledig beeld hebben van de staat van alle wissels en alle seinen. Alleen de controller van het betreffende sein stuurt uiteindelijk ook de leds of de arm servo's aan. SEMAPHORE(66) geeft aan dat dit sein het DCC adres 66 heeft.  NO_STOP_DELAY geeft aan dat het sein onmiddellijk een onveilig beeld geeft na de ontvangst van onveilig van Koploper. Soms wil je dit wat uitstellen zodat het sein iets later pas reageert en niet onmiddellijk als een trein het volgende blok inrijd. Dan kun je DELAY_STOP op geven, dan wacht het sein 1,5 sec voor dat hij het onveilig seinbeeld geeft.

                       new Route(Turnout(2),
                          new Route(TURNOUT(3),      // Turnout 2 straight
                                    new Route(SEMAPHORE(55), SPEED_MIDDLE),// Turnout 3 straight
                                    SPEED_HIGH,
                                    new Route(TURNOUT(4),                  // Turnout 3 diverting
                                              new Route(ROUTE_BARRED),        // Turnout 4 straight
                                              SPEED_STOP,
                                              new Route(TURNOUT(5),           // Turnout 4 diverting
                                                        new Route(SEMAPHORE(56)), // Turnout 5 straight
                                                        SPEED_MIDDLE,
                                                        new Route(SEMAPHORE(57)), // Turnout 5 diverting
                                                        SPEED_LOW),
                                              SPEED_MIDDLE),
                                    SPEED_MIDDLE),
                           SPEED_HIGH,
                           new Route(ROUTE_BARRED),  // Turnout 2 diverting
    SPEED_STOP),
    Dit beschrijft welke mogelijke routes er zijn vanaf dit sein tot een of meerdere ander seinen en welke snelheidsbeperkingen er gelden op deze route. Er zijn verschillende Route objecten. Route(adres) en Route(adres, snelheid) beschrijven een sein dat bereikt wordt via de actieve route, adres is het dcc adres van het betreffende sein. Als voor een sein ook snelheid is gespecificeerd, dan betekend dat dat de maximum snelheid is waarmee dit sein mag worden benaderd.
    Route(adres, route1, snelheid1, route2, snelheid2) beschrijft een wissel. Adres is het dcc adres van het betreffende wissel, route1 is de route die gevolgd wordt als het wissel rechtdoor gaat, route2 is de route voor een afbuigende stand. Snelheid1 is de snelheid waarmee het wissel rechtdoor gaand bereden mag worden, snelheid2 is de snelheid voor een afbuigende stand. Route1 en route 2 kunnen dus weer nieuwe routes zijn over vervolg wissels.
                SEIN46_DRIEHOOG,
    Type van het sein, in dit geval een Driehoog sein.
                new RGBLed(PWM_PIN(2),INTENSITY(18),PWM_PIN(3),INTENSITY(15),PWM_PIN(4),INTENSITY(9)),
                new RGBLed(PWM_PIN(5),INTENSITY(20),PWM_PIN(6),INTENSITY(22),PWM_PIN(7),INTENSITY(9)),
                new RGBLed(PWM_PIN(8),INTENSITY(21),PWM_PIN(9),INTENSITY(14),PWM_PIN(10),INTENSITY(9))),
    Een Driehoogte sein heeft 3 driekleurenleds, boven, midden, laag. Iedere driekleuren led is aangesloten op 3 PWM pinnen (rood, groen en blauw), ieder met een gespecificeerde licht intensiteit.

    Tot zover de configuratie. Nu de actieve delen van de schets.
    void setup()
    {
      //
      //  Based on which pin is connected to ground, the controller ID is established
      //
      i2cId = 0;

      pinMode(PIN_ID_1, INPUT_PULLUP);
      pinMode(PIN_ID_2, INPUT_PULLUP);
      pinMode(PIN_ID_3, INPUT_PULLUP);

      if (!digitalRead(PIN_ID_1)) i2cId = 1;
      else if (!digitalRead(PIN_ID_2)) i2cId = 2;
      else if (!digitalRead(PIN_ID_3)) i2cId = 3;

      //
      //  Tell the semaphore control where to find its turnouts and semaphores
      //  and initialize the whole shebang
      //
      Semaphore::init(i2cId, nrOfTurnouts, turnouts, nrOfSemaphores, semaphores);

      //
      //  Start the I2C communication
      //
      Wire.begin(I2C_BASE + i2cId);     // join i2c bus
      Wire.onReceive(receiveI2CEvent);  // register event handler
    }
    In de setup functie worden een aantal zaken geïnitialiseerd. Als eerste wordt de controller id bepaald, in dit geval aan de hand van 3 pinnen, door een van deze pinnen aan gnd te verbinden, is het makkelijk om met de zelfde schets 3 verschillende arduinros te gebruiken. Daarna Semaphore::init(..) verteld de bibliotheek wat de controller id is van deze arduino, hoeveel wissels er zijn en waar de tabel is. Verder hoeveel seinen er zijn en waar de tabel met sein definities is.
    void receiveI2CEvent(int howMany)
    {
      unsigned int x = Wire.read();    // receive byte as an integer

      unsigned int dccId = x / 2;
      unsigned int dccState = x % 2;

      //
      //  Find the proper turnout detector with the matching address
      //  and sets its state.
      //
      if (Turnout::updateDirection(dccId, dccState))
      {
        //
        //  The dcc id matched a turnout no need to try the semaphores
        //
        return;
      }
      else
      {
        //
        //  the dcc id didn't match a turnout, so try the semaphores
        //
        Semaphore::updateState(dccId, dccState);
      }
    }
    Dit is een interrupt routine die aangeroepen wordt als er over de I2C bus een bericht binnenkomt. Deze routine kan makkelijk vervangen worden door een interrupt routine voor een andere techniek (DCC, CAN-bus etc). Turnout::updateDirection() gaat alle bekendende wissel definities langs en als  er een wissel is met het gegeven adres (dccId) dan zal de positie van dit wissel gewijzigd worden naar de stand die in de dccState staat. Als er geen wissel is die overeenkomt met het adres, dan zal de aanroep van Semaphore::updateState() het zelfde doen voor alle bekende seinen.
    void loop()
    {
      //
      //  Scan all semaphores for updates in states and routes and change their
      //  image if necessary
      //
      Semaphore::loop();
    }
    Door de arduino loop functie wordt continu Semaphore::loop(..) aan geroepen. Deze bibliotheek functie checkt continu de staat van alle wissels en seinen en past het seinbeeld aan als dat nodig is.

    Dit was het voor dit moment, ik hoop dat het duidelijk genoeg is en bruikbaar.

    Groet Meino
    « Laatst bewerkt op: 07 mei 2018, 21:55:26 door meino »
    A clean desk is a sign of an empty mind

    Timo

    • Team encyclopedie
    • Offline Offline
    • Berichten: 3829
    Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
    « Reactie #28 Gepost op: 08 mei 2018, 11:56:53 »
    Leuk om te zien hoe hard je bezig bent! (y) Vooral het CAN deel vind ik erg interessant :)

    Paar random opmerkingen. Geen enkele opmerking is slecht bedoelt! (y) Ook al kan het over komen als gezeur ::)

    Alleen een Mega gebruiken voor het aantal PWM pinnen lijkt me beetje overkill. Ding is nogal groot en lomp. Heb je er ook over gedacht om iets als een PCA9685 te gebruiken? Goedkoop, I2C, 16 kanalen en 12-bit (komt fading ten goede).

    En zo te zien gebruik je niet de Arduino IDE voor eht schrijven van de code ;D Nogal heftige indentatie zo :P Waar schrijf / compile jij mee?

    En qua code, het is inderdaad C++. Weet je dan ook dan het gebruik van macro's voor pin definities als slecht wordt gezien? :angel: Mooie aan C++ is juist dat er type safe alternatieven zijn.

    Ook valt me op dat je een beetje de Arduino gekte met betrekking tot het altijd gebruiken van int hebt opgepikt. Ik denk dat op veel plekken een byte / uint_8 of in ieder geval een unsigned type logischer is. Lijkt me sterk dat je -300 als 'nrOfTurnouts' zou willen gebruiken  ;D

    Mag ik vragen hoe je de PWM hebt inverted? Doe je gewoon analogWrite(pin, 255 - x)? Er zit namelijk een kleine valkuil / rariteit in analogWrite(). Bij gebruik van de hardware PWM kan je namelijk nooit een duty cycle van 100% krijgen en zit je vast op 255/256. Omdat men dit als raar zag (mensen verwachten 100% duty) doet Arduino:
    void analogWrite(uint8_t pin, int val)
    {
    else if (val == 255)
    {
    digitalWrite(pin, HIGH);
    }
    Gevolg is dus dat de PWM van 254/256 naar 256/256 gaat, een stap van 2 dus. Geen probleem als dat de maximale waarde aan geeft maar jammer als dat juist het onderste bereik van je led is waar dit goed op valt.


    Timo
    Verzonden vanaf mijn desktop met Firefox

    meino

    • Offline Offline
    • Berichten: 153
    Re: Automatisering voor Kranenberg - Arduino's, bezetmelders, wissels, seinen
    « Reactie #29 Gepost op: 08 mei 2018, 18:14:01 »
    Hoi Timo

    nee hoor, het is altijd goed om te horen hoe een ander er tegenaan kijkt. Dat ik een mega gebruik is gewoon omdat ik niet meer weet. Mijn achtergrond is puur software, van PIC's en dergelijke weet ik, buiten het feit dat ze bestaan, niets. Verder kosten die dingen zo weinig dat ik niet de moeite neem om kleinere alternatieven te vinden. Alhoewel ik nu toch er over na denk om Arduino Nano's te gaan gebruiken voor bepaalde functionaliteit.
    Toen ik met Arduino's begon, was dat ook omdat het makkelijk was met een simpele IDE en geen gedoe met configuren van cross compilers en Makefiles.
    Tot nu toe red ik me met de Arduino IDE aangevuld met notepad. Wel denk ik iedere keer na een exercitie zoals dit dat ik toch maar Netbeans (mijn preverente IDE voor Java) ga optuigen voor Arduino ontwikkelwerk. Maar dat is er tot nu toe nog niet van gekomen.

    Wat je zegt over macro's kan wel zijn dat dat als slecht wordt gezien, maar dat zit gewoon in mijn systeem, net als het gebruik van int's. Lang geleden was ik assembler programmeur (IBM 360, Sperry Univac 9000-90 serie) daar heb ik het gebruik van macro's geleerd. Toen ik in '83 in het Unix kamp verzeild raakte, was dat ook in C de methode om standaard zaken dmv defines en complete functies definities vast te leggen.

    Het hele gedoe rondom de grootte van een int is ook langs mij heen gegaan. Toen ik in de Unix wereld terecht kwam, waren de systemen waar wij op werkten gebaseerd op motorola 68020-68040 met VME bus, later in Berkeley kwamen daar Sun Sparc's en intel systemen bij, allemaal 32 (en later 64) bit systemen, dus de grootte van een int (minimaal 32 bit) was niet zo belangrijk, zolang je maar wist dat de maximale waarde groot genoeg was voor je toepassing. Als we echt iets wilden afdwingen gebruikten we byte, short, long of long long. Overigens was dat vaak alleen het geval als je met memcpy of menset aan de gang moest gaan. Vanuit die achtergrond let ik dus absoluut niet op geheugen beslag, ook een reden om Mega's te gebruiken - die hebben 256kb aan boord, Als je in 4kb of 8kb iets aan de praat wilt krijgen, zul je wel op dat soort zaken moeten letten.

    Overigens gebruik ik in een aantal situaties -1 als adres om het systeem iets te laten weten (ROUT_BARRED is -1).
    Ik gebruik de inverted PWM inderdaad op de simpele manier, maar ik probeer de voorloop weerstanden voor de led's zodanig te kiezen dat ik voor de PWM waardes ergens in het middengebied uit kom. Omdat de stapjes voor PWM lineair zijn (als je van waarde 1 naar waarde 2 gaat, dan verdubbeld de licht intensiteit). Eigelijk zou ik een gamma functie daar voor willen hebben. Ik heb nog gekeken of het makkelijk was om een PWM implementatie met een hogere resolutie te bouwen, maar dat uiteindelijk niet gedaan. Vandaar.

    Groet Meino
    A clean desk is a sign of an empty mind