Modelspoor en Arduino

Discussie in 'Spoor H0 en Spoor N' gestart door Arjen Rolaff, 13 feb 2024.

  1. Arjen Rolaff

    Arjen Rolaff

    Lid geworden:
    25 jan 2024
    Berichten:
    6
    Locatie:
    Vlissingen
    Hallo medehobbyisten,

    Ik wil het volgende voorleggen en hoop dat iemand een suggestie heeft voor een oplossing. Ik heb een modelspoorbaan, gelijkstroom. Voor de wisselaandrijvingen is een ciricuit ontworpen met als kern een Adruino Pro mini. Het werkt prima, hij imiteert heel netjes het langzaam omgaan van de wissels. Er is alleen één probleem. Zodra ik een trein laat rijden en ik verander van rijrichting, dan zijn er een aantal wissels die vanzelf omgaan en dus van richting veranderen. Van de 17 wissels die nu actief zijn, reageren er een zestal ongewenst op de rijrichtingverandering. De anderen hebben dat probleem niet. Ook met betrekking tot de plaats is er niets dat mij een hint geeft, Sommige boardjes zijn op 2 meter afstand en sommigen op 20cm. De loc's zijn analoog en van een ouder type. Kan iemand me op weg helpen?
     
  2. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Zonder een installatieschema en de sketch waarmee de Arduino geprogrammeerd is wordt het moeilijk om hier een onderbouwd antwoord te geven.
    Heb je de Arduino zelf geprogrammeerd of zo gekocht? Hoe worden de wissels aangedreven, met een servo?
     
  3. Arjen Rolaff

    Arjen Rolaff

    Lid geworden:
    25 jan 2024
    Berichten:
    6
    Locatie:
    Vlissingen
    Ik heb de Arduino zelf geprogrammeerd en de wissels worden inderdaad met een servo aangedreven.
    De sketch:
    #include <Servo.h>

    //constant variables used to set servo angles, in degrees
    const int straight = 100;
    const int divergent = 135;

    //constant variables holding the ids of the pins we are using
    const int divergent_led = 3;
    const int straight_led = 4;
    const int buttonpin = 13;
    const int servopin = 6;

    //servo movement step delay, in milliseconds
    const int step_delay = 70;

    //create a servo object
    Servo myservo;

    //global variables to store servo position
    int pos = straight; //current
    int old_pos = pos; //previous

    void setup()
    {
    //set the mode for the digital pins in use
    pinMode(buttonpin, INPUT);
    pinMode(straight_led, OUTPUT);
    pinMode(divergent_led, OUTPUT);

    //setup the servo
    myservo.attach(servopin); //attach to the servo on pin 6
    myservo.write(pos); // set the initial servo position

    // set initial led states
    digitalWrite(straight_led, HIGH);
    digitalWrite(divergent_led, LOW);
    }

    void loop()
    {
    // start each iteration of the loop by reading the button
    // if the button is pressed (reads HIGH), move the servo
    int button_state = digitalRead(buttonpin);
    if(button_state == HIGH){
    // turn of the lit led
    if(pos==straight){
    digitalWrite(straight_led, LOW);
    } else {
    digitalWrite(divergent_led, LOW);
    }
    old_pos = pos; //save the current position

    // Toggle the position to the opposite value
    pos = (pos == straight) ? divergent: straight;

    // Move the servo to its new position
    if(old_pos < pos){ // if the new angle is higer
    // increment the servo position from oldpos to pos
    for(int i = old_pos + 1; i <= pos; i++){
    myservo.write(i); // write the next position to the servo
    delay(step_delay); // wait
    }
    } else { // otherwise the new angle is equal or lower
    // decrement the servo position from old pos to pos
    for(int i = old_pos - 1; i >= pos; i--){
    myservo.write(i); // write the next position to the servo
    delay(step_delay); // wait
    }
    }
    // turn on the appropiate LED.
    if(pos==straight){
    digitalWrite(straight_led, HIGH);
    } else {
    digitalWrite(divergent_led, HIGH);
    }
    }
    } // end of loop

    De Arduino Pro mini zit op een door mijn zoon zelf ontworpen printplaat.
    Via een spanningsregelaar 7805 wordt 12V omgezet in 5 v waarmee de Arduino wordt gevoed.
    Na de 7805 zitten twee condensatoren 0,1 mf en 0,33mf.
    De printplaat omvat ook de voeding/aansturing voor twee LED's voor de signalering.
    Een foto kan volgen, maar die moet ik strakjes maken. Gr. Arjen
     
  4. jkoeter

    jkoeter PH-SAM

    Lid geworden:
    31 jan 2012
    Berichten:
    51
    Dit klinkt als storing op je button-input. En ik denk dat de arduino reset als je de rijrichting omdraait. Dat laatste los je op met een forse eleco vlak bij de arduino. Het tweede lijkt mij veroorzaakt als gevolg van de reset. De eerste keer dat hij door de loop functie gaat ziet de arduino de button dan als ingedrukt. Dit kan je oplossen door de knop te ontdenderen in de code. Ik zou hiervoor een van de beschikbare bibliotheken gebruiken.

    Succes!
     
  5. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Even over de sketch, ik begrijp niet helemaal hoe je de functionaliteit gedacht had. Zoals ik het lees moet je de button indrukt houden om de servo helemaal naar de andere positie te laten draaien, maar hoe je dan voorkomt dat de eindpositie voortdurend wisselt begrijp ik niet. Misschien omdat ik deze regels niet begrijp:

    // Toggle the position to the opposite value
    pos = (pos == straight) ? divergent: straight;

    Als het reguliere Arduino codering is, wat doen de dubbele punt en het vraagteken dan?
     
  6. Arjen Rolaff

    Arjen Rolaff

    Lid geworden:
    25 jan 2024
    Berichten:
    6
    Locatie:
    Vlissingen
    Mijn zoon heeft de sketch bedacht. Ikzelf ontbeer de kennis om te programmeren.
    Ik heb een hele basale kennis van Arduino, maar het zelf ontwerpen valt ver buiten mijn competentie.
    Ik hoef de knop niet ingedrukt te houden, ik druk de knop kort in en de actie volgt. Wil ik de wissel weer omgelegd hebben, dan druk ik dezelfde knop weer kort in.

    Ik zal je vraag aan mijn zoon moeten voorleggen voor een gedegen antwoord.
    Voor het antwoord kan wat tijd overheen gaan. Hij vaart op de binnenvaart, is gezagvoerder op een tanker en is nu aan het werk.
    Hij heeft tijd tussendoor, maar ik wet nooit wanneer.
    Ik waardeer je inzet om tot een oplossing te komen.
     
  7. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Ik denk trouwens niet dat het contact-dender is, door de wachttijden tussen de servo-stappen is de loop waarschijnlijk veel trager dan de fluctuaties vlak nadat je de knop ingedrukt hebt. Maar een storing op de voeding en dientengevolge een reset is heel goed mogelijk als oorzaak.
     
  8. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Ja, ik kan nu begrijpen hoe het werkt, maar mijn vraag over hoe de eindpositie-wissel geprogrammeerd is blijft.

    Als het probleem van de "valse restart" niet opgelost kan worden is het misschien een idee om de laatste positie in het EEPROM-gedeelte van de ProMini op te slaan, zodat die opnieuw opgehaald kan worden na de restart.
     
  9. martin_12

    martin_12

    Lid geworden:
    28 jun 2014
    Berichten:
    99
    Dat is een waarde toekennen op basis van een conditie. Een "if then else" op één regel:
    condition ? value_if_true : value_if_false
     
  10. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Ok Martin, dank, ik kende dat format niet.

    Iets anders waar ik aan denk is de input via de button, waarbij ik aanneem dat het een simpele drukknop is. Pin 13 is gedefinieerd als input, en reageert op een logische 1 als deze pin via de drukknop met de +5V verbonden is. Maar als de drukknop losgelaten wordt is de input zwevend!, en daarmee gevoelig voor schommelingen in de voedingsspanning. Nu is pin 13 ook verbonden met de on-board led, ik weet niet of dat dan voldoende is om dat effect tegen te gaan.
    Ik geef er de voorkeur aan om zo'n input als INPUT_PULLUP mode te definiëren, en die input via de drukknop met GND te verbinden. Knop indrukken geeft dan een logische 0, en loslaten een positieve (op twee manieren;)) logische 1. De programmering moet dan aangepast worden, if(button_state == HIGH) wordt if(button_state == LOW) .
     
    Laatst bewerkt: 13 feb 2024
  11. Arjen Rolaff

    Arjen Rolaff

    Lid geworden:
    25 jan 2024
    Berichten:
    6
    Locatie:
    Vlissingen
    Een storing op de voeding kan denk ik ook betekenen dat is het niet goed samengesteld heb, zeker gezien het feit dat het maar bij zes van de 17 boardjes/wissels voorkomt.
    En met niet goed samenstellen bedoel ik dat ik soldeerfouten kan hebben gemaakt gemaakt.
    Kan dat een juiste veronderstelling zijn?
     
  12. Arjen Rolaff

    Arjen Rolaff

    Lid geworden:
    25 jan 2024
    Berichten:
    6
    Locatie:
    Vlissingen
    Als bijlage een foto van de printplaat waar het om gaat
     

    Bijgevoegde bestanden:

  13. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Ik zie dat de verbinding tussen de drukknop en pin 13 een aftakking heeft en met weerstand R3 / 10k met GND verbonden is. Dat is effectief een pulldown, en ondervangt het zwevend zijn van pin 13 als de drukknop los is. Dus geen probleem op dat gebied (vooropgesteld dat R3 ook daadwerkelijk aanwezig is).
     
  14. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Zijn de wissels en de locomotieven op één en dezelfde transformator aangesloten? Zoja, dan zou ik eens een onafhankelijke spanningsbron voor de wissels proberen.
     
  15. hobbyist

    hobbyist Forum veteraan

    Lid geworden:
    10 mrt 2009
    Berichten:
    5.483
    Locatie:
    Noord Brabant
    Ik zit ook even mee te lezen in te kijken.

    Laat ik ook eens een duit in het zakje werpen.
    C1 en C2 zijn van die kleine condensatortjes om het oscilleren van de spanningsregelaar tegen te gaan of te voorkomen.
    Ik zou nog een elco plaatsen zo dicht mogelijk bij de 5V spanningsregelaar, tussen de 5V en de GND van zo'n 100-220uF.

    En aan de ingang, de 12V zou een extra elco van 100-220uF ook niet misstaan, wij weten niet hoelang en hoe dik de bekabeling is naar het printje.

    Enne oh ja @Ernst Grundmann wil zich hier ook altijd graag even tegen aan bemoeien.:)
     
  16. martin_12

    martin_12

    Lid geworden:
    28 jun 2014
    Berichten:
    99
    Onderstaande is wel een beetje gissen...

    Er staat dat die wissels altijd van richting veranderen dus van rechtdoor naar afslaan (noem je dat eigenlijk zo?) en omgekeerd als gevolg van het wisselen van de rijrichting van de trein. Daarmee verwacht ik dat dit een storing op de drukknop opleverde waardoor de wissel dan onbedoeld omgezet wordt.

    Als de wissels slechts van afslaan naar rechtdoor gaan en nooit van rechtdoor naar afslaan dan reset de cpu als gevolg van het wisselen van de rijrichting. Omdat de wissels na een reset in de rechtdoor positie beginnen merk je de reset niet op als ze al rechtdoor stonden.
     
  17. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Het blijft toch wel vreemd dat het verschijnsel alleen optreedt bij het wisselen van de rijrichting, wat bij een gelijkstroombaan simpelweg ompolen van de + en - van het spoor is, vermoedelijk altijd bij stilstand van de trein. En niet bijvoorbeeld bij het optrekken van de lok en de daarmee optredende hogere stroomsterkte en mogelijk inzakken van de spanning. Kan het zijn dat er bij dat omschakelen kortstondig kortsluiting ontstaat?
     
  18. Arjen Rolaff

    Arjen Rolaff

    Lid geworden:
    25 jan 2024
    Berichten:
    6
    Locatie:
    Vlissingen
    Daar heb ik nooit wat van gemerkt, een sluiting.. En ik zou ook niets kunnen bedenken wat dat kan veroorzaken. De rijtransformator is een Fleischmann 6730.
    Ik heb bij het aanzetten van de treintafel, dus het aanzetten van het hele systeem, ook dat een aantal wissels zichzelf omzetten en dat zijn volgens mij ook de wissels die reageren op de rijrichtingverandering.
    De aansturing van de arduino/wissels zijn twee verschillende transformatoren.
    R3 is bij alle boardjes aangesloten.
    Kijk, het gekke is, in mijn ogen, dat niet alle boardjes reageren op de rijrichtingverandering. Het zijn er 6 van de 17 die nu aangesloten zijn.
     
  19. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Dat zou inderdaad wijzen op een ongewilde reset door het omschakelen van de rijrichting, maar hoe dan? Dat de verdachte wissels ook bij het opstarten "zichzelf omzetten" zou erop wijzen dat de "Straight" positie hier in werkelijkheid de afslaande positie is. Ik vermoed dat je bij het installeren sowieso de eindposities hebt moeten finetunen, kan het niet zijn dat bij sommige wissels de servo met een afwijkende geometrie gemonteerd is, waardoor de rechtdoor positie een hoger getal is dan de afslaande positie? En dat daarom de startpositie ("Straight") juist de afslaande is geworden?
     
    Laatst bewerkt: 14 feb 2024
  20. max z

    max z Vriend van modelbouwforum.nl PH-SAM

    Lid geworden:
    4 dec 2009
    Berichten:
    2.421
    Locatie:
    Boskoop
    Om het ongewenst resetten te kunnen monitoren heb ik een paar regels aan jouw sketch toegevoegd, wanneer het gebeurt gaan beide led's een seconde lang allebei tegelijk branden.
    Code:
    #include <Servo.h>
    
    //constant variables used to set servo angles, in degrees
    const int straight = 100;
    const int divergent = 135;
    
    //constant variables holding the ids of the pins we are using
    const int divergent_led = 3;
    const int straight_led = 4;
    const int buttonpin = 13;
    const int servopin = 6;
    
    //servo movement step delay, in milliseconds
    const int step_delay = 70;
    
    //create a servo object
    Servo myservo;
    
    //global variables to store servo position
    int pos = straight; //current
    int old_pos = pos; //previous
    
    void setup()
    {
      //set the mode for the digital pins in use
      pinMode(buttonpin, INPUT);
      pinMode(straight_led, OUTPUT);
      pinMode(divergent_led, OUTPUT);
    
      //setup the servo
      myservo.attach(servopin); //attach to the servo on pin 6
      myservo.write(pos); // set the initial servo position
    
      // added by MZ: both led states HIGH for 1 second, to detect restart/reset
      digitalWrite(straight_led, HIGH); // added by MZ
      digitalWrite(divergent_led, HIGH); // added by MZ
      delay(1000); // added by MZ
    
      // set initial led states
      digitalWrite(straight_led, HIGH);
      digitalWrite(divergent_led, LOW);
    }
    
    void loop()
    {
      // start each iteration of the loop by reading the button
      // if the button is pressed (reads HIGH), move the servo
      int button_state = digitalRead(buttonpin);
      if(button_state == HIGH){
        // turn of the lit led
        if(pos==straight){
          digitalWrite(straight_led, LOW);
        } else {
          digitalWrite(divergent_led, LOW);
        }
        old_pos = pos; //save the current position
    
        // Toggle the position to the opposite value
        pos = (pos == straight) ? divergent: straight;
    
        // Move the servo to its new position
        if(old_pos < pos){ // if the new angle is higer
          // increment the servo position from oldpos to pos
          for(int i = old_pos + 1; i <= pos; i++){
            myservo.write(i); // write the next position to the servo
            delay(step_delay); // wait
          }
        } else { // otherwise the new angle is equal or lower
          // decrement the servo position from old pos to pos
          for(int i = old_pos - 1; i >= pos; i--){
            myservo.write(i); // write the next position to the servo
            delay(step_delay); // wait
          }
        }
          // turn on the appropiate LED.
          if(pos==straight){
          digitalWrite(straight_led, HIGH);
        } else {
          digitalWrite(divergent_led, HIGH);
        }
      }
    } // end of loop
    
     
    Laatst bewerkt: 14 feb 2024
    martin_12 vindt dit leuk.

Deel Deze Pagina