Modelspoor en Arduino

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?
 
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?
 
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
 
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!
 
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?
 
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.
 
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.
 
Ik hoef de knop niet ingedrukt te houden, ik druk de knop kort in en de actie volgt.
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.
 
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?

Dat is een waarde toekennen op basis van een conditie. Een "if then else" op één regel:
condition ? value_if_true : value_if_false
 
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:
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?
 
Als bijlage een foto van de printplaat waar het om gaat
 

Bijlagen

  • print  ontwerp Niels.jpg
    print ontwerp Niels.jpg
    285,7 KB · Weergaven: 142
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).
 
Zijn de wissels en de locomotieven op één en dezelfde transformator aangesloten? Zoja, dan zou ik eens een onafhankelijke spanningsbron voor de wissels proberen.
 
Als bijlage een foto van de printplaat waar het om gaat
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.:)
 
Hallo medehobbyisten,
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.

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.
 
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?
 
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.
 
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.
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:
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:
Back
Top