Doel:€250.00
Donaties:€50.00

Per saldo:€-200.00

Steun ons nu!

Laatst bijgewerkt
op 03-01-2024

Vacature: secretaris bestuur
Algemeen

De stichting

Recente berichten

Gebruik je Arduino zonder te "programmeren" ;) door fleischmann1
Vandaag om 16:18:39
Ombouw/Pimpen Bolle neuzen door bollen neus
Vandaag om 15:58:15
Welke Vallejo kleur voor drijfstangen van een DB stoomlocomotief? door aad52
Vandaag om 15:33:13
Al mijn goede ideeën... door bask185
Vandaag om 15:23:03
US diorama in H0 door VAM65
Vandaag om 15:22:05
Beekdaelen in H0 door VulcanRaven
Vandaag om 15:15:11
Hengelo in 1981-1982, maar dan anders: Kassenberg in N door spoorijzer
Vandaag om 15:08:30
Kleine Baan in H0 (≤ 0.5m²) door Jack Black (NS1220)
Vandaag om 15:06:14
U-vorm beperkte ruimte (H0 C-rails) door Jelmer
Vandaag om 14:58:04
Onlangs gespot - gefotografeerd, de links door Jeroen Water
Vandaag om 14:33:00
N spur scenery elementen maken van gips of klei? door Dave.......
Vandaag om 14:30:06
De overeenkomst tussen een Ovaalramer en een Motorpost. door RK
Vandaag om 14:28:54
Onlangs gespot - gefotografeerd, de foto's door mass am see
Vandaag om 14:18:46
BMB-Module: “Corfe Castle Station” door Hans van de Burgt
Vandaag om 14:07:52
welk jaar ging Marklin OVP voor wagons van blauw naar wit door Railman
Vandaag om 13:40:42
GSS Jubileumbaantje (0e / 0n30) door MacArthur
Vandaag om 12:55:30
Toon hier je nieuwe (model-) spooraanwinst(en)... door Sven
Vandaag om 12:28:41
NTM P1 in Schaal-1 door MaraNCS
Vandaag om 11:39:38
Mijn eerste H0-modeltreinbaan in aanbouw door Jack Black (NS1220)
Vandaag om 11:33:00
Rio Grande Southern - Lizard Head Pass door Hans GJ
Vandaag om 11:30:20
Bauarbeiten im gange door Dave.......
Vandaag om 10:55:26
Variaties op Station Zetten Andelst in HO door Duikeend
Vandaag om 10:54:40
De IJmuider spoorlijn - korte geschiedenis en plaatjes door Vislijn
Vandaag om 10:42:29
Internationale Spoor 0 en 1 dagen in Gießen, 23 en 24 maart, 2024 door bernhard67
Vandaag om 08:42:53
De Hondsrugbaan door mass am see
Vandaag om 08:15:11
Pfarrerwinkel bahn door Jelmer
Vandaag om 08:00:19
M.s.v. De Percee bouwt aan nieuwe clubbaan door J. Moors
Vandaag om 01:00:05
30 maart Modelspoorbeurs Houten & HCC Kennisdag door WimM
Vandaag om 00:42:50
Raadplaatje door Magic
27 maart 2024, 23:27:03
Ronald en Wanda's "Southern Comfort" swamp layout! door Ronald Halma
27 maart 2024, 23:17:30
  

Auteur Topic: De CanBus komt naar Kranenberg, Arduino's en de CanBus  (gelezen 59897 keer)

Martin Hornis

  • Offline Offline
  • Berichten: 1413
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #105 Gepost op: 31 januari 2020, 03:07:29 »
Maar hoe een zg H brug werkt? geen idee.
Het horizontale deel van de 'H' is een motor. De 4 verticale delen van de 'H' zijn elektronische schakelaars. Beide uiteinden aan de bovenkant van de 'H' zijn met de PLUS verbonden. Beide onderkanten van de 'H' met de MIN. Als de linker bovenpoot en de rechter onderpoot van de 'H' in geleiding zijn dan gaat de stroom van linksboven naar rechtsonder. Door de motor dus naar rechts. Als je de rechter bovenpoot en de linker onderpoot in geleiding brengt dan gaat de stroom door de motor naar links. Het is de kunst om er voor te zorgen dat de boven- en onderpoot aan de linkerkant niet tegelijkertijd in geleiding zijn, want dan heb je een kortsluiting. Idem aan de rechterkant van de 'H'.
Märklin K-rails met boogstralen > 500 mm; NS-lichtseinen met cijferbak: 4, 6 en 8 in één bak; iTrain; Intellibox I; OC32;
eigen treindetectiesysteem aangesloten op OC32;
controleprogramma voor OC32.

bask185

  • Online Online
  • Berichten: 4007
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #106 Gepost op: 31 januari 2020, 09:53:00 »
Verlicht mij eventjes wat is halve golf aan sturing precies?

 Ik moet nu opeens aan zo'n racebaan denken waarbij een positieve spanning werd gebruikt voor 1 auto en de negatieve spanning voor de andere...maar nu heb ik het over iets anders dan jullie denk ik ???
Train-Science.com
Train-Science github
It ain't rocket science ;-)

Timo

  • Team encyclopedie
  • Offline Offline
  • Berichten: 4656
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #107 Gepost op: 31 januari 2020, 09:58:37 »
Maar hoe een zg H brug werkt? geen idee. [...] in combinatie met standaard interface kaartjes.
Gewoon behandelen als standaard interface kaartje ;D Je voeding eraan, motor aan de uitgang en dan heb je een ingang voor linksom en een ingang voor rechtsom. Volgens mij gewoon een drop in replacement voor hoe je nu de relais gebruikt. Daar vorm je nu ook een mechanische H-brug mee ;D Dus het principe snap je gewoon al ;D

Zou alleen kunnen dat ze niet heel blij worden van 3V ingangsspanning en 5V logic. Maar niets wat een weerstand niet op kan lossen :police:

Verlicht mij eventjes wat is halve golf aan sturing precies?

 Ik moet nu opeens aan zo'n racebaan denken waarbij een positieve spanning werd gebruikt voor 1 auto en de negatieve spanning voor de andere...maar nu heb ik het over iets anders dan jullie denk ik ???
Nee, eigenlijk niet. Gewoon AC door een enkele diode. Al naar gelang de oriëntatie van de diode heb je dan positieve "halve golf" of negatieve "halve golf". Het voordeel is dat je maar één zijde van de motor hoeft te schakelen.


Timo
Verzonden vanaf mijn desktop met Firefox

Klaas Zondervan

  • Offline Offline
  • Berichten: 25180
    • Pagina van klaas
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #108 Gepost op: 31 januari 2020, 12:00:55 »
Mijn toepassing van de halvegolfsturing: Without, vanaf reactie#98

meino

  • Offline Offline
  • Berichten: 2087
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #109 Gepost op: 31 januari 2020, 14:41:05 »
@Martin en @timo

bedankt voor de uitleg van een H brug. Zo leer je iedere keer wat bij. Het lijkt inderdaad erg op mijn relais oplossing.

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

Kranenberg
De CanBus komt naar Kranenberg

meino

  • Offline Offline
  • Berichten: 2087
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #110 Gepost op: 05 mei 2020, 23:40:17 »
De afgelopen weken ben ik bezig geweest met het bouwen van een AKI (Automatische Knipperlicht Installatie). Afgezien van het modelbouw gedeelte, is het meeste werk gaan zitten in het bouwen van de C++ objecten om het gedrag van de AKI d.m.v. een Arduino aan te sturen.

Even een filmpje van het resultaat:
<a href="https://www.youtube.com/v/15PcaT44G3o" target="_blank" class="new_win">https://www.youtube.com/v/15PcaT44G3o</a>

Laten we even kijken naar waar het om draait.


Dit schema toont de belangrijkste Componenten (C++ objecten) die in dit systeem te onderscheiden zijn.
  • AKI      De AKI is verantwoordelijk voor de aansturing van het model en voor het correcte licht en geluidsbeeld.
  • Sectie  Dit object is verantwoordelijk voor controleren van een spoordeel en bij te houden of het betreffende deel bezet is door een trein of niet. Dit gebeurd in samenwerking met twee sensors/bezetmelders. Het is wel zo dat dit gebaseerd is op mijn huidige implementatie en dat er voor de sectie ook alternatieven mogelijk zijn.

Ik heb bewust gekozen om in de AKI geen kennis van de secties te geven. Dit omdat de AKI een stabiel object is, met een goed omschreven gedrag, terwijl de sectie objecten dat niet zijn, er zijn veel verschillende manier waarmee bepaald kan worden of een spoordeel bezet is. Dus de terugkoppeling van een of meerdere secties naar het licht- en geluidsbeeld van de AKI vindt door een externe partij (de loop() method) plaats.

OK to zover, morgen verder.

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

Kranenberg
De CanBus komt naar Kranenberg

meino

  • Offline Offline
  • Berichten: 2087
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #111 Gepost op: 06 mei 2020, 16:03:42 »
We gaan verder.

De aansturing van de AKI is, afgezien van een paar technische probleempjes, redelijk simpel. Het is gewoon een kwestie van een paar ledjes aansturen en het geluid van een bel produceren. Verder is de functionaliteit stabiel, de overweg is open of is gesloten en beide toestanden kennen een wel omschreven functionaliteit.
De overweg (AKI, AHOB, etc) heeft twee toestanden, open of gesloten voor het kruisend verkeer. Deze toestand wordt bepaald door de aanwezigheid of afwezigheid van treinen in alle secties(spoordelen) van de overweg. De overweg gaat dan open als alle secties aangeven dat er geen trein aanwezig is anders is de overweg gesloten.

Het controleren van een sectie op de aanwezigheid van een trein is eigenlijk het meest complexe deel, daarom wil ik het daar eerst over hebben.
De technische kant is simpel, alleen de logica is wat ingewikkelder. Dat komt omdat er verschillende manieren zijn om het wel of niet aanwezig zijn van een trein te bepalen. Er zijn diverse omstandigheden die van invloed zijn, bijv. kan de hele trein (loc+wagons) gedetecteerd worden of alleen de loc, werken we met stroomdetectie of met lichtsluisjes, etc. Verder worden iedere sectie slechts in een richting bereden of kunnen een of meerdere secties in beide richtingen bereden worden., kunnen er rangeerbewegingen plaatsvinden enz.
Ik gebruik zelf stroomdetectie en lichtsluisjes, verder werk ik alleen met gehele detectie (alle wagons hebben verlichting, of assen met weerstandslak) en de beschreven AKI beveiligd een dubbelspoor waarbij ieder spoor slechts in een richting bereden kan worden. Dat zijn dus de randvoorwaarden van wat ik hier beschrijf.

Het simpelst is als de gehele sectie (die de overweg) aanstuurt in zijn geheel op 1 stroomdetecterende bezetmelder aangesloten is. In dat geval is het makkelijk, deze bezetmelder geeft dan aan of er een trein in de sectie is of niet. Echter dat is niet altijd mogelijk. In mijn geval had ik te maken met al aanwezige scheidingen in blokken, wissels en bestaande bezetmelders die dit helaas onmogelijk maakt.

SectionControl


 
Iedere sectie wordt gecontroleerd door een SectionControl object. Dit object heeft contact met twee Sensor objecten, een entrySensor en een exitSensor, welke de toestand van een bij behorende bezetmelder aangeven. In mijn systeem hebben de Sensor objecten geen contact met een fysieke bezetmelder, zij ontvangen hun toestand via Canbus boodschappen. Het is echter maareen kleine wijziging om dezeobjecten  een fysieke pin op de Arduino te laten monitoren en hun toestand daar van te laten afhangen waardoor dit buiten een Canbus omgeving ook werkt.

De toestand van dit SectionControl object doorloopt 3 toestanden. Initieel is de toestand leeg. Op het moment dat een trein de entrySensor bereikt en die aanslaat, zal de toestand van leeg naar sensor 1 komend gaan. Daarna bij het bereiken van de exitSensor gaat de toestand naar senso 2 gaand. Op het moment dat de trein de exitSensor volledig heeft verlaten en deze weer afgaat, wordt de toestand opnieuw leeg. Alleen in de toestand leeg, zal het SectionControl object melden dat er geen trein in de sectie is.
Ik weet dat dit niet volmaakt is, want er zijn een aantal scenario's die niet goed worden afgehandeld, zoals bijv. rangeerbewegingen, een trein rijdt de sectie in, stopt en rijdt terug zonder de exitSensor te bereiken. Maar voorlopig voldoet het voor mij.

OK, een paar stukjes code. Dit zijn de .h en .cpp bestanden die je in een Arduino bibliotheek kunt gebruiken.
SectionControl.h
//
//  A class that encapsulated sensors and detectors used for controlling
//  a rail section. This specific sensor receives it's state updates through
//  Canbus messages
//
class Sensor
{
private:
    int sensorAddress;  // The address/number of this sensor, derived from
                        // position on a S88 bank.
    volatile bool state;

public:
    Sensor(int aSensorAddress);

    void attach();

    int getSensorAddress();

    void heartBeat();

    void setState(bool aState);
    bool getState();
};

//
//  A finite state machine that guards a occupance of a single track
//
class SectionControl
{
public:
    enum SectionState
    {
        leeg,
        sensor1komend,
        sensor2komend,
        sensor1gaand,
        sensor2gaand
    };

    //
    // Create an instance with two sensors
    //
    SectionControl(Sensor *anEntrySensor, Sensor *anExitSensor);

    //
    //  Attach pins
    //
    void attach();

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

    //
    // Is the section occupied by a train?
    //
    bool isOccupied();

    void setEntrySensor(Sensor *aSensor);
    Sensor *getEntrySensor();
    void setExitSensor(Sensor *aSensor);
    Sensor *getExitSensor();

private:
    SectionState state = leeg;

    Sensor *entrySensor = nullptr;
    Sensor *exitSensor = nullptr;
   
    SectionControl::SectionState getState();

    //
    //  Based on the state of sensor 1 and the current state of the FSM, a new state
    //  is calculated.
    //
    void handleEntrySensor(bool trigger);

    //
    //  Based on the state of sensor 2 and the current state of the FSM, a new state
    //  is calculated.
    //
    void handleExitSensor(bool trigger);
};

SectionControl.cpp
Sensor::Sensor(int aSensorAddress)
{
    sensorAddress = aSensorAddress;
    state = false;
}

void Sensor::attach()
{

}

int Sensor::getSensorAddress()
{
    return sensorAddress;
}

void Sensor::heartBeat()
{

}

void Sensor::setState(bool aState)
{
    state = aState;
}

bool Sensor::getState()
{
    return state;
}

//
//  Based on the state of entry sensor and the current state of the FSM, a new state
//  is calculated.
//

void SectionControl::handleEntrySensor(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 (RRX_DEBUG)
            Serial.print("[SectionControl::handleEntrySensor] ON, nr: ");
            Serial.print(sectionNr);
            Serial.println(" state is sensor1komend");
            Serial.flush();
#endif
            state = sensor1komend; // so set it to state komend
        }
    } else // Sensor is OFF
    {
#if (RRX_DEBUG)
        Serial.print("[SectionControl::handleEntrySensor] OFF, nr: ");
        Serial.print(sectionNr);
        Serial.println(" ignored");
        Serial.flush();
#endif
    }
}

//
//  Based on the state of the exit sensor and the current state of the FSM, a new state
//  is calculated.
//

void SectionControl::handleExitSensor(bool trigger)
{
    if (trigger) // Sensor 2 is ON
    {
        if (state == sensor1komend) // A train has entered the section
        {
#if (RRX_DEBUG)
            Serial.print("[SectionControl::handleExitSensor] ON, nr: ");
            Serial.print(sectionNr);
            Serial.println(" state is sensor2gaand");
            Serial.flush();
#endif
            state = sensor2gaand; // Start the leaving process
        }
    } else
    {
        if (state == sensor2gaand) // A train is in the process of leaving
        {
#if (RRX_DEBUG)
            Serial.print("[SectionControl::handleExitSensor] OFF, nr: ");
            Serial.print(sectionNr);
            Serial.println("state is leeg");
            Serial.flush();
#endif
            state = leeg; // Section is empty again
        }
#if (RRX_DEBUG)
        else
        {
            Serial.print("[SectionControl::handleExitSensor] OFF, nr: ");
            Serial.print(sectionNr);
            Serial.println(" ignored");
            Serial.flush();
        }
#endif
    }
}

//
// Create an instance with two sensors
//

SectionControl::SectionControl(Sensor *anEntrySensor, Sensor *anExitSensor)
{
    entrySensor = anEntrySensor;
    exitSensor = anExitSensor;

    state = leeg; // initial state
}

//
//  Initialise and setup
//

void SectionControl::attach()
{

}

//
//  Get give the sensors a kick and check their state so we can update our own
//  state.
//

void SectionControl::heartBeat()
{
    if ((entrySensor == nullptr) || (exitSensor == nullptr))
    {
        state = leeg;
    } else
    {
        entrySensor->heartBeat();
        exitSensor->heartBeat();

#if (RRX_DEBUG)
        Serial.print("[SectionControl::heartBeat] entry sensor address: ");
        Serial.print(entrySensor->getSensorAddress());
        Serial.print(", state: ");
        Serial.println(entrySensor->getState());
#endif     
        handleEntrySensor(entrySensor->getState());

#if (RRX_DEBUG)
        Serial.print("[SectionControl::heartBeat] exit sensor address: ");
        Serial.print(exitSensor->getSensorAddress());
        Serial.print(", state: ");
        Serial.println(exitSensor->getState());
        Serial.flush();
#endif 
        handleExitSensor(exitSensor->getState());
    }
}

//
//  Ask if the section is occupied by a train. only if it's state equals
//  'leeg' we may deny it, all other states tells us that a train is active
//  in the section.
//
bool SectionControl::isOccupied()
{
    if (state == leeg)
    {
        return false;
    }
    else
    {
        return true;
    }
}

//
// Return the current state of the section
//
SectionControl::SectionState SectionControl::getState()
{
    return state;
}

void SectionControl::setEntrySensor(Sensor *aSensor)
{
    entrySensor = aSensor;
}

Sensor *SectionControl::getEntrySensor()
{
    return entrySensor;
}

void SectionControl::setExitSensor(Sensor *aSensor)
{
    exitSensor = aSensor;
}

Sensor *SectionControl::getExitSensor()
{
    return exitSensor;
}

Wat voorbeelden van het gebruik hiervan in de arduino schets.

Definities:
const int nrOfSensors = 4;
Sensor sensors[nrOfSensors] = {
  Sensor(12),   // 1.13   SectionControl 2 exit
  Sensor( 9),   // 1,10   SectionControl 1 entry
  Sensor(16),   // 2.01   SectionControl 2 entry
  Sensor(22)    // 2.07   SectionControl 1 exit
};

SectionControl section1(&sensors[1], &sensors[3]);
SectionControl section2(&sensors[2], &sensors[0]);

setup()
    //
    // Initialize the sensors
    //
    for (int i=0; i<nrOfSensors; i++)
    {
      sensors[i].attach();
    }

    section1.attach();
    section2.attach();

loop()
    //
    //  Keep the sections running, so they will update their states
    //
    section1.heartBeat();
    section2.heartBeat();

Tot zover over de spoorsecties.

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

Kranenberg
De CanBus komt naar Kranenberg

bask185

  • Online Online
  • Berichten: 4007
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #112 Gepost op: 06 mei 2020, 17:08:10 »
Je hebt qua detecties ongeveer hetzelfde gedaan als ik voor de AHOB. Ik had alleen mijn sporen bi-directioneel gemaakt. En zodoende had ik 5 states. Er zijn per spoor 2 melders die beiden als entry en exit sensors kunnen fungeren. Afhankelijk van welke sensor er als eerst gemaakt werd, werd er gewacht tot de andere sensor gemaakt was en dan werd er gewacht totdat deze sensor een x aantal tijd verbroken is geweest. En dan pas werd het de bezetmelding opgeheven

Ik leerde daarna dat in het grootbedrijf dat er ook een midden detectie gedeelte is, wist ik veel.....  maar goed, ik bedacht me dat mijn SW ook werkt als je de 2 inrij detecties parallel aansluit en als entrySensor inzet en de midden sectie als exitSensor gebruikt. Voor de exit sensor is het raadzaam om stroomdetectie te gebruiken mits je hele trein dan gedetecteerd wordt zoals je zei.
 
entry                       exit                     entry
------   ---------------------------------   ------

Ik denk dat jij hetzelfde kan doen voor jouw SW. Je kan de 2 buitenste terugmelders als entrySensor gebruiken en die parallel aansluiten. Dan moet je alleen nog melders aanbrengen voor het middengedeelte. In deze opstelling moet je er wel op letten dat de trein nog wat extra tijd heeft, om de entrySensor voorbij te gaan, wanneer hij weer weg rijdt. Dit zou dan ook met rangeerbewegingen moeten werken. Maar nogmaals als je nu net een lok parkeert op de entry sensor en er dan van af rijdt zonder de exit te raken, dan staat je overgang dus permanent dicht.

Dit allemaal gezegd hebbende. Volgens mij is wat jij doe, wat ik doe en het grootbedrijf doet allemaal onnodig moeilijk doen. Ik denk als je gewoon 1 enkele bezetmelder gebruikt voor de gehele lengte dus van je huidige entrySensor t/m je huidige exitSensor dat je dan al een perfect werkend en feilloos systeem heb. In een taal die we allemaal snappen:

 if ( Sensor == waar ) { overgang dicht }
 else                          { overgang open }

Mvg

Bas
Train-Science.com
Train-Science github
It ain't rocket science ;-)

meino

  • Offline Offline
  • Berichten: 2087
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #113 Gepost op: 06 mei 2020, 18:55:04 »
Dag bas
Je hebt qua detecties ongeveer hetzelfde gedaan als ik voor de AHOB. Ik had alleen mijn sporen bi-directioneel gemaakt. En zodoende had ik 5 states.
Ik heb voort geborduurt op een stukje code dat ik ooit voor Koen (NS264) had ontwikkeld. Dat was voor een enkel spoor dat van 2 kanten bereden kon worden. In dat systeem heb ik inderdaad 5 toestanden. Maar voor mijn situatie had ik dat niet nodig, dus heb ik het wat versimpeld.

Dit allemaal gezegd hebbende. Volgens mij is wat jij doe, wat ik doe en het grootbedrijf doet allemaal onnodig moeilijk doen. Ik denk als je gewoon 1 enkele bezetmelder gebruikt voor de gehele lengte dus van je huidige entrySensor t/m je huidige exitSensor dat je dan al een perfect werkend en feilloos systeem heb.
Dat klopt, dat geef ik ook aan in mijn verhaaltje, alleen had ik niet een stuk spoor van de goede afmetingen, de sectie is onderbroken door een aantal isolators met meerdere bezetmelders, verder zit er ook een wissel in zodat ik dynamisch de entrysensor moet aanpassen afhankelijk van de wisselstand. Dat betreffende wissel heeft ook een bezetmelder, maar die kan ik niet gebruiken omdat er ook routes over dat wissel gaan die geen invloed op de sectie mogen hebben.

Ik weet dat rangeren over deze sectie problemen gaat geven. Hoe ik dat ga oplossen heb ik voorlopig nog maar even geparkeerd.

Groet Meino
« Laatst bewerkt op: 06 mei 2020, 19:00:28 door meino »
A clean desk is a sign of an empty mind

Kranenberg
De CanBus komt naar Kranenberg

meino

  • Offline Offline
  • Berichten: 2087
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #114 Gepost op: 06 mei 2020, 23:16:07 »
Goed we gaan verder met de software die de AKI zelf aanstuurt.

Het systeem dat de AKI aanstuurt kent een aantal objecten

AKI
De AKI zelf kent twee toestanden.
  • Open      - de groene lamp van de AKI flikkert 45/minuut.
  • Gesloten - de rode lamp van de AKI flikkert 90/minuut en de bel luidt, ongeveer 240 slagen per minuut.
Het AKI object heeft methods om de AKI in een van deze toestanden te brengen.

AKI.h
//
//  A simple class that represents a complete AKI (Automatische Knipperlicht Installatie)
//  with all its leds and the sound of a bell
//
class AKI
{
public:

    enum CrossingState
    {
        OPEN, CLOSED
    };

    //
    //  Create an instance of the AKI, using the specified Led's
    //
    AKI(BlinkingLed *aRedLed, BlinkingLed *aGreenLight, int aBellPin);

    //
    //  Attach pins
    //
    void attach();

    //
    //  Activate the connected leds. TBD: the sound
    //
    void heartBeat();
   
    //
    //  Close the crossing
    //
    void close();
   
    //
    //  Open the crossing
    //
    void open();

private:
    BlinkingLed *redLight;
    BlinkingLed *greenLight;
    int bellPin;
   
    CrossingState state;
   
    void setCrossingState(CrossingState aState);
    CrossingState getCrossingState();
};

AKI.cpp
//
//  Create an instance of the AKI, using the specified Led's
//
AKI::AKI(BlinkingLed *aRedLight, BlinkingLed *aGreenLight, int aBellPin)
{
    redLight = aRedLight;
    greenLight = aGreenLight;
    bellPin = aBellPin;
}

//
//  Attach pins
//
void AKI::attach()
{
    redLight->attachPin();
    greenLight->attachPin();

    pinMode(bellPin, OUTPUT);
    digitalWrite(bellPin, LOW);
   
    setCrossingState(OPEN);
}

//
//  Activate the connected leds.
//
void AKI::heartBeat()
{
    //
    //  The leds have a flicker, so we have to keep them running
    //
    redLight->heartBeat();
    greenLight->heartBeat();
}

void AKI::setCrossingState(AKI::CrossingState aState)
{
    state = aState;

    if (state == OPEN)
    {
        redLight->setLedOn(false);
        greenLight->setLedOn(true);
        digitalWrite(bellPin, LOW); // Bell is off
    } else
    {
        redLight->setLedOn(true);
        greenLight->setLedOn(false);
        digitalWrite(bellPin, HIGH); // Bell is on
    }
}

AKI::CrossingState AKI::getCrossingState()
{
    return state;
}

void AKI::open()
{
    setCrossingState(AKI::OPEN);
}

void AKI::close()
{
    setCrossingState(AKI::CLOSED);
}

BlinkingLed
Dit object is verantwoordelijk voor de aansturing van de  rode of een groene led. Dit zijn simpele eenkleurige leds. Daarom worden ze simpel door een digitale pin aangestuurd zonder dat PWM nodig is. Omdat de lichtintensiteit van rode en groene leds onderling sterk kan afwijken moet met verschillende voorloop weerstanden de onderlinge lichtintensiteit in balans gebracht worden. Als een led is aangezet dan zorgt het object zelf dat de led met het geconfigureerde tempo aan en uit gaat. De AKI heeft dus twee van deze objecten, een voor het rode licht en een voor het groene licht.

BlinkingLed.h
class   BlinkingLed
{
private:
    int   blPin;
    short blinkInterval;
    bool  blinking;
    bool  ledOn;
    long  lastTime;
   
public:
    BlinkingLed(int, int);
    void setBlinkInterval(int);
    int  getBlinkInterval();
    void setLedOn(bool);
    bool getLedOn();
    void attachPin();
    void heartBeat();
};

BlinkingLed.cpp
BlinkingLed::BlinkingLed(int aPin, int aBlinkInterval)
{
    blPin = aPin;
    blinking = false;
    ledOn = false;
    blinkInterval = aBlinkInterval;
}

void BlinkingLed::setBlinkInterval(int aBlinkInterval)
{
    blinkInterval = aBlinkInterval;
}

int  BlinkingLed::getBlinkInterval()
{
    return blinkInterval;
}
   
void BlinkingLed::setLedOn(bool aLedOn)
{
    if (ledOn != aLedOn)
    {
        ledOn = aLedOn;
        if (!ledOn)
        {
            digitalWrite(blPin, LOW);
        }
    }
}
   
bool BlinkingLed::getLedOn()
{
    return ledOn; 
}
   
void BlinkingLed::attachPin()
{
    pinMode(blPin, OUTPUT);
    delay(100);
    lastTime = millis();
}
   
void BlinkingLed::heartBeat()
{
    if (ledOn)
    {
        unsigned long currTime = millis();
        if ((currTime - lastTime) >= blinkInterval)
        {
            lastTime = currTime;
            if (blinking)
            {
                digitalWrite(blPin, HIGH);
                blinking = false;
            }
            else
            {
                digitalWrite(blPin, LOW);
                blinking = true;
            }
        }
    }
}

Bel
Dit is het systeem dat het geluid van de bel maakt. Dit is geen klassiek object, maar een volledig apart systeem van een Arduino Namo met een speaker en RC schakeling. Deze Nano is via een digitale pin verbonden met de Arduino waar de AKI software op draait. Als deze pin hoog gezet wordt door de AKI software dan zal dit systeem de bel gaan luiden. Omdat dit een apart systeempje is, zal ik daar in de volgende post verder op in gaan.

Wat voorbeelden van het gebruik.

Definities:
AKI aki(new BlinkingLed(23,333), new BlinkingLed(22,667), 24); // Red blinks 90/minute, green 45/minute

setup()
aki.attach();

loop()
    //
    //  Update the state of the AKI based on the stateS of the sections
    //
    if ((section1.isOccupied()) || (section2.isOccupied()))
    {
      aki.close();
    }
    else
    {
      aki.open();
    }

    //
    //  Keep the AKI running
    //
    aki.heartBeat();

Tot zover de AKI software.

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

Kranenberg
De CanBus komt naar Kranenberg

Martin Hornis

  • Offline Offline
  • Berichten: 1413
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #115 Gepost op: 07 mei 2020, 01:33:48 »
Mooie toepassing. Maar het duurt wel erg lang voordat de overweg weer 'vrij' is.
Märklin K-rails met boogstralen > 500 mm; NS-lichtseinen met cijferbak: 4, 6 en 8 in één bak; iTrain; Intellibox I; OC32;
eigen treindetectiesysteem aangesloten op OC32;
controleprogramma voor OC32.

bask185

  • Online Online
  • Berichten: 4007
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #116 Gepost op: 07 mei 2020, 09:36:40 »
[Kritiek mode]
Ik weet dat deze SW past in je OO stijl manier van programmeren maar....

Je doet wel erg veel moeite en werk om een led te laten knipperen zeg  ;D en dan nog het geheugen wat je er aan toewijdt. Een hele classe om een led te laten knipperen...
private:
    int   blPin;
    short blinkInterval;
    bool  blinking;
    bool  ledOn;
    long  lastTime;
De long lastTime (volgens mij moet deze unsigned zijn, kwenie of dit problemen geeft na 25 dagen ::) nog-stop gebruik) mag hier ook een unsigned int zijn. Mits deze:
void BlinkingLed::heartBeat()
{
    if (ledOn)
    {
        unsigned long currTime = millis();

        if ((currTime - lastTime) >= blinkInterval)
dat ook wordt. Dan worden alleen de 2 LSB opgeslagen van millis() en omdat je interval ook maar een 'short' (moest nog opzoeken wat het was) is, zal dat geen problemen geven in de if-statement.

je int blPin mag hier ook een byte (aka unsigned char) zijn. Het is in dit programma al geen constante en zal daarom geheugen gebruiken. En om dan ook nog eens een signed integer te gebruiken voor een getal dat nooit hoger zal zijn dan het max aantal pinnen op een arduino mega... Wat ik eigenlijk niet weet, is of je in een constructor een const int 1 malig van een waarde kan voorzien.

Ik vind bool's  persoonlijk ondingen. Ik had er een keer ruzie mee toen ik een state wilde toevoegen en het getal 2 er in wilde stoppen. Een bool neemt ook 8 bits in gebruik terwijl je er maar 1 van nodig heb. Je hebt 2 bits nodig en je gebruikt er 16. Je kan dit geval beter gebruik maken van een bitfield
struct {
   unsigned int blinking: 1;
   unsigned int ledOn: 1;
} status;
Dit bespaart je 8 bits aan geheugen. De struct heeft nog steeds 1 byte nodig alleen beide 'bool's staan nu in dezelfde bytes.
Door de 'bare mininum' variabele types te gebruiken, kan je hier al 4 bytes per led sparen.

Deze OO manier maakt alleen het gebruik van constantes niet mogelijk. Ze verschillen per object en dat maakt het lastig. Daarom zou ik voor de leds zelf niet kiezen voor een classe. Maar zoals ik altijd zeg, what ever grinds your gears (doe wat jou goeddunkt) (y). Hij doet het iig.

Je hebt natuurlijk ook nog de standaard 'getters' (de get functies) die je eigenlijk niet gebruikt. Ik weet nog van Java les dat je die eerder tikt uit gewoonte dan uit noodzaak. Ik weet niet of de functies daadwerkelijk worden meegecompileerd op dat ze door de compiler worden weggeoptimaliseerd (schitterend woord)

Wat ik standaard ook graag als advies geef, is om ten alle tijden de intX_t en de uintX_t notaties te gebruiken vanwege de duidelijkheid er van. Ik moest nu bijvoorbeeld opzoeken wat een short ook alweer was en een 'int' kan per platform verschillen. En iedereen kan in het eerste oog opslag zien, hoeveel bits er gebruikt worden en of de waarde signed of unsigned is als je dus de uintX_t en de intX_t gebruikt.
[/kritiek mode]

Goed bezig iig (y) Kun je misschien een foto maken van het geheel zodat we ook de wissels en bezetmelders ed op 1 plaatje hebben?
Train-Science.com
Train-Science github
It ain't rocket science ;-)

ikbenerevenniet

  • Offline Offline
  • Berichten: 379
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #117 Gepost op: 07 mei 2020, 11:43:17 »
bool's [..] ruzie mee toen ik [..] het getal 2 er in wilde stoppen

Tja... ;-p

meino

  • Offline Offline
  • Berichten: 2087
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #118 Gepost op: 07 mei 2020, 17:05:23 »
Mooie toepassing. Maar het duurt wel erg lang voordat de overweg weer 'vrij' is.

Dat ben ik met je eens. Maar ik maak nu gebruik van bestaande bezetmelders en die zitten niet allemaal op een gunstige plek. Ik ben nog van plan om twee nieuwe te gaan installeren.

[Kritiek mode]
Ik weet dat deze SW past in je OO stijl manier van programmeren maar....

Je doet wel erg veel moeite en werk om een led te laten knipperen zeg  ;D en dan nog het geheugen wat je er aan toewijdt. Een hele classe om een led te laten knipperen...
....
....
Ik vind bool's  persoonlijk ondingen. Ik had er een keer ruzie mee toen ik een state wilde toevoegen en het getal 2 er in wilde stoppen. Een bool neemt ook 8 bits in gebruik terwijl je er maar 1 van nodig heb. Je hebt 2 bits nodig en je gebruikt er 16.
[preekmode=ON,  ;D]
Dat je een bool een onding vindt begrijp ik niet echt, dat soort zaken zou toch bij de minimale kennis moeten  behoren  :police:

Maar ik vind de overzichtelijkheid en helderheid van de code belangrijker dan het besparen van 8 bits. Als je op dat nivo met de code bezig moet zijn dan denk ik dat je beter een ander platform voor je systeem, met meer resources, moet vinden. Ik zelf denk dat als je alles uit de kast trekt met speciale technieken om geheugen te besparen, dat je dan eindigt met een onderhoudsnachtmerrie.
[/preekmode]

Misschien kom ik wat hard over, maar dat ik dit vindt heeft alles te maken met de jarenlange ploetering om het "werk" van anderen aan de praat te houden  ;).

Ik weet niet of je ooit van de volgende termen gehoord hebt:

  • High Cohesion
  • Low Coupling
  • Data Hiding

Dit zijn de drie hoofdzaken waarmee je een goed stuk software kunt onderscheiden van rommel software.

Dat is ook de reden dat ik OO gebruik omdat dat je de mogelijkheid biedt tot het concentreren van zaken in kleine compacte stukjes code, waarbij de functionaliteit en verantwoordelijkheid belegd wordt in kleine en compacte stukjes code.

Deze OO manier maakt alleen het gebruik van constantes niet mogelijk. Ze verschillen per object en dat maakt het lastig. Daarom zou ik voor de leds zelf niet kiezen voor een classe. Maar zoals ik altijd zeg, what ever grinds your gears (doe wat jou goeddunkt) (y). Hij doet het iig.
Huh, wat dacht je van enums, static of const. Dit zie ik niet helemaal. sorry.

Je hebt natuurlijk ook nog de standaard 'getters' (de get functies) die je eigenlijk niet gebruikt. Ik weet nog van Java les dat je die eerder tikt uit gewoonte dan uit noodzaak. Ik weet niet of de functies daadwerkelijk worden meegecompileerd op dat ze door de compiler worden weggeoptimaliseerd (schitterend woord)
Dat is nog een overblijfsel van jaren praktijk. En komt voort uit het topic van "Data Hiding". Laat nooit de interne data van een klasse direct toonbaar en modificeerbaar zijn door de buitenwereld.  Het kan zijn dat ze nu niet gebruikt worden, maar dat kan later anders zijn.

Wat ik standaard ook graag als advies geef, is om ten alle tijden de intX_t en de uintX_t notaties te gebruiken vanwege de duidelijkheid er van. Ik moest nu bijvoorbeeld opzoeken wat een short ook alweer was en een 'int' kan per platform verschillen. En iedereen kan in het eerste oog opslag zien, hoeveel bits er gebruikt worden en of de waarde signed of unsigned is als je dus de uintX_t en de intX_t gebruikt.
Het probleem is dat types als uintX-t en intX-t geen standaard types van C, C++ of Java zijn en dat je dus afhankelijk bent van de specifieke include of import bestanden die op je platform aanwezig zijn (bijv. arduino.h). Dus als in een specifiek omgeving deze niet bekend zijn, maar er andere definities geincluded worden heb je een probleem. De datatypes die jij noemt ben ik zelf nooit tegengekomen, wel heb ik vaak de typen int8_t, uint8_t, int16_t, uint16_t etc, gebruikt zien worden, maar ook die komen uit een include bestand (stdint) en zou ik zelf dus eerder gebruiken. Het probleem zit hem eigenlijk alleen in het gebruik van int, omdat dat platform afhankelijk kan zijn. Ik zelf heb eigenlijk alleen te maken gehad met systemen waarop de int 32 bit was, dus daar ben ik soms slordig in. Wil je veilig programmeren dan gebruik je byte (unsigned 8bit), short (signed 16bit), unsigned short, long (signed 32bit), unsigned long, long long (signed 64bit) of unsigned long long en de diverse floats. Dat is wat ik zelf prefereer, maar dat komt omdat ik lang geleden C geleerd heb en de laatste 25 jr hoofdzakelijk met Java bezig geweest ben waar dit allemaal niet speelt  ;D.

Goed tot zover.
Groet Meino
« Laatst bewerkt op: 07 mei 2020, 17:12:21 door meino »
A clean desk is a sign of an empty mind

Kranenberg
De CanBus komt naar Kranenberg

meino

  • Offline Offline
  • Berichten: 2087
Re: De CanBus komt naar Kranenberg, Arduino's en de CanBus
« Reactie #119 Gepost op: 07 mei 2020, 20:05:28 »
Op verzoek even een overzicht fotootje.



Alle wissels die hier te zien zijn geen onderdeel van de blokken zoals die in Koploper zijn gedefinieerd. Voor het vrijgeven van wisselstraten hebben ze alle een eigen bezetmelder. De exitsensor van sectie 1 en een van de entrysensors voor sectie 2 zijn een bezetmelder van een wissel. De andere entrysensor voor sectie1 is een stopmelder van een blok. De exitsensor voor sectie2 is gekoppeld met de stopmelder voor het zelfde blok en de entrysensor voor sectie1 is gekoppeld met de entrymelder van het betreffende blok. Die ga ik nog veranderen en vervangen door nieuwe melders die beter gepositioneerd zijn.

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

Kranenberg
De CanBus komt naar Kranenberg