BeneluxSpoor.net forum

Vraag en antwoord => Elektronica en analoog => Topic gestart door: Cees Baarda op 10 juni 2015, 17:11:16

Titel: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 10 juni 2015, 17:11:16
Dag allemaal

Na wat jaren te hebben meegelezen en her en der wat opmerkingen te hebben gestrooid, is het nu wel tijd om mijn project(je) aan jullie voor te stellen.

Aanleiding
Op BNLS zijn wat projecten aan de gang waarbij microcontrollers een rol spelen en dan met name die waarin gebruik gemaakt wordt van een of meerdere ARDUINO's. Een paar voorbeelden:
Timo met zijn AdServo (http://forum.beneluxspoor.net/index.php?topic=61213.0)
RudyB met Nieuwe versie Arduino DCC Servo en Functie Decoders (http://forum.beneluxspoor.net/index.php/topic,62981.msg3221538721.html#msg3221538721)
Smits66 met Arduino analoge(!) modelbaan sturing (http://forum.beneluxspoor.net/index.php?topic=57884.0)
NTering met  TT-baan, met Arduino aansturing (http://forum.beneluxspoor.net/index.php?topic=63567.0)
HansQ met BNLS/RCU booster (http://forum.beneluxspoor.net/index.php/topic,54663.0.html)

Plan
Ik wil uiteindelijk uitkomen op een Inglenook rangeerpuzzelbaantje in schaal N. Die zal digitaal bestuurd worden. Niet met een computer maar met schakelingen die al eens op BNLS getoond zijn. Ik denk aan Arduino('s) met programma('s) t.b.v.:
- wissels en ontkoppelaars bedienen
- rijregelaar - naar keuze: PWM of DCC (t.b.v. locs met decoder)

Wat heb ik al
Ik heb al rails en wissels van Peco (N code 55). Nog geen ontkoppelaars. Genoeg wagentjes en een rangeerlocomotief(DCC). De onderbouw moet nog gemaakt worden.
Een eigen ontwerp servo-besturing, de hardware en een eenvoudige Arduino sketch met hard gecodeerde firmware. Zelfs delay() ergens voor gebruikt. Dat moet natuurlijk beter opgelost worden.

Hoe ga ik dit realiseren
Allereerst wil ik mijn eigen servo besturing met een aangepaste versie van de AdServo-firmware laten werken. Dat is me deels al gelukt. Ik heb e.e.a. opgebouwd in een proefopstelling (zie onderstaande foto). Daarmee ga ik alle servo dingen testen.
Als dat klaar is, dan komt de "rijregelaar" aan de beurt.

Wordt dit een project zoals BNLS/RCU boosterhub
Absoluut niet, ik heb geen behoefte om te gaan "handelen". Ik ga wel alles met jullie delen. Als er hardware ontworpen is, komen daar Eagle- en CAM-files van op deze plek beschikbaar. Code voor de Arduino natuurlijk ook.

In de volgende posts, stapsgewijs wat er al is. En daarna in een lager tempo wat volgt.
groet Cees
(https://images.beneluxspoor.net/bnls/ProefOpst_servos_800px.jpg) (https://images.beneluxspoor.net/bnls/ProefOpst_servos_800px.jpg)
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Hans van de Burgt op 10 juni 2015, 18:30:37
@Cees,

Op mijn modelbaan komt ook een Inglenook.
Zie mijn website.

Mijn mede EMV leden RudyB en Spock zijn behoorlijk actief hier op BNLS met Arduino.
Trouwens meer leden, hoor.

Zelf heb ik met Ruud de test al uitgevoerd om de Arduino als DCC decoder in te zetten in combinatie met Hornby's Railmaster/eLink als "centrale". Succesvol in ieder geval.

En over Railmaster/eLink gesproken, zie mijn proef in het koppelen en ontkoppelen met dit programma icm Kadee magneet en koppelingen. Tot op de mm nauwkeurig.
Zie: http://youtu.be/jibk1SlJb5c

Grzz, Hans
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 13 juni 2015, 11:46:47
Die print van mijn eerste post is nog niet helemaal zoals ik 'm in gedachten had. Timo (die van de "adServo") heeft naar mijn schema en opzet gekeken en een aantal opmerkingen gemaakt, die ik inmiddels in mijn schema heb verwerkt (zie afbeelding onderaan). De print gaat daarmee ook nog veranderen.
De firmware voor de APM, die ik in eerste instantie gemaakt had ziet er uit als volgt:
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 S e r v o   W i s s e l S t e l l e r
   
   Testprogramma voor het omzetten van een modelspoorwissel m.b.v.
   een modelbouw servo.
   Te testen:
   - 2 losse drukknoppen voor recht en afbuigend
   - 2 optocoupler ingangen; funtioneel als schakelaar, bedoeld
     voor besturing vanuit HCC!m-systeem of Dinamo OC32
   - 1 van de optocouplers moet later ook DCC kunnen verwerken
   Er wordt gebruik gemaakt van 2 servo's
   Ten behoeve van hartstukpolarisatie zijn er per servo 2 relais
   
   Werking per wissel:
   - na een wisselcommando valt eerst het aangetrokken relais af
   - daarna loopt het wissel om (servo)
   - dan komt het andere relais op
   Bij opstarten gebeurt er niets. Het hartstuk van het wissel heeft
   geen spanning en de servo staat in een ongedefinieerde stand.
   
   De gebruikte Arduino is een Pro Mini, 5V met ATmega328.
   
   Gebruikte libraries en voorbeelden:
   - code uit het Debounce-voorbeeld bestand van Arduino.cc
     http://www.arduino.cc/en/Tutorial/Debounce
   - Servo library uit Arduino - omgeving
   - adServo van Timo Engelgeer
   
   Created:   30-04-2015
   By:        Cees Baarda
   Modified: 
   By:       
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
   
   
// - - - - - L i b r a r i e s   i n   g e b r u i k :
  #include <Servo.h>   // hiermee besturen we de servo's

// - - - - - C o n s t a n t e n :
//           De pinnummers en vaste waarden een naam geven
   
// - - - - - voor wissel 1
  const int optoIn_1  = 3;  // voor externe aansturing met 0 of 1
  const int servo_1   = 9;
  // - - - - - t.b.v puntstukpolarisatie
  const int relaisR_1 = 7;
  const int relaisG_1 = 8;
  // - - - - - t.b.v. bediening met knoppen
  const int knopR_1   = 6;  // input; toets wissel recht leggen
  const int knopG_1   = 5;  // input; toets wissel gebogen leggen

// - - - - - voor wissel 2
  const int optoIn_2  = 2;  // voor externe aansturing met 0 of 1
  const int servo_2   = 10;   // output; Servo 2
  // - - - - - t.b.v puntstukpolarisatie
  const int relaisR_2 = 11;  // output; t.b.v. relais bij recht gelegd wisssel
  const int relaisG_2 = 12;  // output; t.b.v. relais bij gebogen gelegd wisssel
  // - - - - - t.b.v. bediening met knoppen
  const int knopR_2   = A2;  // input; toets wissel recht leggen
  const int knopG_2   = A0;  // input; toets wissel gebogen leggen

  // - - - - - beide wissels met DCC, nog niet in gebruik
  // const int DCC_in    = 2;  // input; de DCC-railspanning gaat hier aan

  const int LED = A1;        // LED op de print

// - - - - - nog niet in gebruik, zijn bedoeld voor extra print aan 8 polige
//           connector
  // const int LEDarduino   = 13; // LED op de arduino
  // const int LEDextern_1  = A2; // evt. extra LED op externe print (pin 4)
  // const int LEDextern_2  = A3; // evt. extra LED op externe print (pin 5)
  // const int externKnop_1 = A2; // evt. extra knop op externe print (pin 4)
  // const int externKnop_1 = A3; // evt. extra knop op externe print (pin 5)
  const long servoWacht = 500;

// - - - - - G l o b a l e   V a r i a b e l e n :
//
  Servo wisselServo1;                // 2 objecten van het type Servo
  Servo wisselServo2;
 
  // - - - - - voor wissel 1
  int relaisR1StateRecht    = LOW;   // de huidige staat van de output pin
  int relaisG1StateGebogen  = LOW;   // *
  int knopG_1State;                  // de huidige waarde van de input pin
  int lastknopG_1State      = LOW;   // de vorige waarde van de input pin
  int knopR_1State;                  // de huidige waarde van de input pin
  int lastknopR_1State      = LOW;   // de vorige waarde van de input pin
  int optoIn1State          = HIGH;  // de huidige waarde van de input pin
  int lastoptoIn1State      = HIGH;  // de vorige waarde van de input pin
 
  // - - - - - voor wissel 2
  int relaisR2StateRecht    = LOW;   // de huidige waarde van de output pin
  int relaisG2StateGebogen  = LOW;   // *
  int knopG_2State;                  // de huidige waarde van de input pin
  int lastknopG_2State      = LOW;   // de vorige waarde van de input pin
  int knopR_2State;                  // de huidige waarde van de input pin
  int lastknopR_2State      = LOW;   // de vorige waarde van de input pin
  int optoIn2State          = HIGH;  // de huidige waarde van de input pin
  int lastoptoIn2State      = HIGH;  // de vorige waarde van de input pin
 
  // de volgende variabelen zijn 'long', omdat de tijd gemeten in milliseconden
  // snel de max waarde van een 'int' zal overschrijden.
 
  // - - - - - voor wissel 1
  long lastDebounceTimeRecht_1 = 0;    // het laatste tijdstip waarop de ingang is veranderd
  long lastDebounceTimeGebogen_1 = 0;  // *
  long lastDebounceTimeoptoIn_1 = 0;   // *
 
  // - - - - - voor wissel 2
  long lastDebounceTimeRecht_2 = 0;    // het laatste tijdstip waarop de ingang is veranderd
  long lastDebounceTimeGebogen_2 = 0;  // *
  long lastDebounceTimeoptoIn_2 = 0;   // *
 
  const long debounceDelay = 50;       // de debounce tijd; hoger maken als de uitgang knippert


// - - - - - setup, 1 x doorlopen
//
void setup()
{
// - - - - - setup input en output
  // - - - - - voor wissel 1
  pinMode(knopG_1, INPUT_PULLUP);
  pinMode(relaisR_1, OUTPUT);
  pinMode(knopR_1, INPUT_PULLUP);
  pinMode(relaisG_1, OUTPUT);
  pinMode(optoIn_1, INPUT);
  // - - - - - voor wissel 2
  pinMode(knopG_2, INPUT_PULLUP);
  pinMode(relaisR_2, OUTPUT);
  pinMode(knopR_2, INPUT_PULLUP);
  pinMode(relaisG_2, OUTPUT);
  pinMode(optoIn_2, INPUT);
  // - - - - - LED's
  pinMode(LED, OUTPUT);

// - - - - - zet relais uit
  // - - - - - voor wissel 1
  digitalWrite(relaisR_1, relaisR2StateRecht);
  digitalWrite(relaisG_1, relaisG2StateGebogen);
  // - - - - - voor wissel 2
  digitalWrite(relaisR_2, relaisR2StateRecht);
  digitalWrite(relaisG_2, relaisG2StateGebogen);
 
// - - - - - testen van werking (moet later weg?)
  digitalWrite(LED, HIGH);
 

}

// - - - - - eindeloos doorgaan
void loop()
{
// - - - - - lokale variabelen voor inlezen 'knoppen'
  // - - - - - voor wissel 2
  int readingKnopG2;
  int readingKnopR2;
  int readingOptoIn2;
  int readingKnopG1;
  int readingKnopR1;
  int readingOptoIn1;
 
// - - - - - lees de knoppen in
  readingKnopG2 = digitalRead(knopG_2);
  readingKnopR2 = digitalRead(knopR_2);
  readingOptoIn2 = digitalRead(optoIn_2);
  readingKnopG1 = digitalRead(knopG_1);
  readingKnopR1 = digitalRead(knopR_1);
  readingOptoIn1 = digitalRead(optoIn_1);

// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH),  and you've waited
// long enough since the last press to ignore any noise: 

// If the switch changed, due to noise or pressing:
  if (readingKnopG1 != lastknopG_1State)
  {
    lastDebounceTimeRecht_1 = millis();  // reset the debouncing timer
  }
  if (readingKnopR1 != lastknopR_1State)
  {
    lastDebounceTimeGebogen_1 = millis();  // reset the debouncing timer
  }
  if (readingOptoIn1 != lastoptoIn1State)
  {
    lastDebounceTimeoptoIn_1 = millis();  // reset the debouncing timer
  }
  if (readingKnopG2 != lastknopG_2State)
  {
    lastDebounceTimeRecht_2 = millis();  // reset the debouncing timer
  }
  if (readingKnopR2 != lastknopR_2State)
  {
    lastDebounceTimeGebogen_2 = millis();  // reset the debouncing timer
  }
  if (readingOptoIn2 != lastoptoIn2State)
  {
    lastDebounceTimeoptoIn_2 = millis();  // reset the debouncing timer
  }

// - - - - - zet wissel 1 gebogen met knop
  if ((millis() - lastDebounceTimeGebogen_1) > debounceDelay)
  {
  // whatever the readingKnopG2 is at, it's been there for longer
  // than the debounce delay, so take it as the actual current state:

  // if the button state has changed:
    if (readingKnopG1 != knopG_1State)
    {
    knopG_1State = readingKnopG1;
      if (knopG_1State == LOW)
      {
        wisselServo1.attach(servo_1,1000,2500);  // zet servo aan
        digitalWrite(relaisG_1, LOW);            // relais valt af, hartstuk stroomloos
        digitalWrite(relaisR_1, LOW);            // relais valt af, hartstuk stroomloos
        wisselServo1.write(1832);                // zet servo om
        delay(servoWacht);                       // wacht op omlopen wissel
        digitalWrite(relaisR_1, HIGH);           // andere relais op, hartstuk krijgt juiste spanning
        //digitalWrite(LED, LOW);                  // LED gaat uit (kan na testen weg)
        wisselServo1.detach();                   // zet servo uit, o.a. jitter voorkomen
      }
    }
  }

// - - - - - zet wissel 1 recht met knop
  if ((millis() - lastDebounceTimeRecht_1) > debounceDelay)
  {
    // whatever the readingKnopR1 is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (readingKnopR1 != knopR_1State) {
      knopR_1State = readingKnopR1;

      // only toggle the LED if the new button state is HIGH
      if (knopR_1State == LOW)
      {
        wisselServo1.attach(servo_1,1000,2500);  // zet servo aan
        digitalWrite(relaisR_1, LOW);            // relais valt af, hartstuk stroomloos
        digitalWrite(relaisG_1, LOW);            // relais valt af, hartstuk stroomloos
        wisselServo1.write(1260);                // zet servo om
        delay(servoWacht);                       // wacht op omlopen wissel
        digitalWrite(relaisG_1, HIGH);           // andere relais op, hartstuk krijgt juiste spanning
        //digitalWrite(LED, HIGH);                 // LED gaat aan (kan na testen weg)
        wisselServo1.detach();                   // zet servo uit, o.a. jitter voorkomen
      }
    }
  }

// - - - - - zet wissel 1 om met schakelaar
  if ((millis() - lastDebounceTimeoptoIn_1) > debounceDelay)
  {

    // if the button state has changed:
    if (readingOptoIn1 != optoIn1State)
    {
      optoIn1State = readingOptoIn1;
      wisselServo1.attach(servo_1,1000,2500);   // zet servo aan

      // only toggle the LED if the new button state is HIGH
      if (optoIn1State == LOW)
      {
        digitalWrite(relaisG_1, LOW);           // zie commentaar bij
        digitalWrite(relaisR_1, LOW);           //
        wisselServo1.write(1832);               // zet wissel 1 gebogen met knop
        delay(servoWacht);
        digitalWrite(relaisR_1, HIGH);
        digitalWrite(LED, HIGH);
      }
      else
      {
        digitalWrite(relaisR_1, LOW);           // zie commentaar bij
        digitalWrite(relaisG_1, LOW);           //
        wisselServo1.write(1260);               // zet wissel 1 recht met knop
        delay(servoWacht);
        digitalWrite(relaisG_1, HIGH);
        digitalWrite(LED, LOW);
      }
      wisselServo1.detach();                    // zet servo uit
    }
  }
// - - - - - zet wissel 2 gebogen met knop
  if ((millis() - lastDebounceTimeGebogen_2) > debounceDelay)
  {
// whatever the readingKnopG2 is at, it's been there for longer
// than the debounce delay, so take it as the actual current state:

// if the button state has changed:
    if (readingKnopG2 != knopG_2State)
    {
    knopG_2State = readingKnopG2;
// only toggle the LED if the new button state is HIGH
      if (knopG_2State == LOW)
      {
        wisselServo2.attach(servo_2,1000,2500);  // zie commentaar bij
        digitalWrite(relaisG_2, LOW);            // zet wissel 1 gebogen met knop
        digitalWrite(relaisR_2, LOW);
        wisselServo2.write(1161);
        delay(servoWacht);
        digitalWrite(relaisR_2, HIGH);
        digitalWrite(LED, LOW);
        wisselServo2.detach();
      }
    }
  }

// - - - - - zet wissel 2 recht met knop
  if ((millis() - lastDebounceTimeRecht_2) > debounceDelay)
  {
    // whatever the readingKnopR2 is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (readingKnopR2 != knopR_2State) {
      knopR_2State = readingKnopR2;

      if (knopR_2State == LOW)
      {
        wisselServo2.attach(servo_2,1000,2500);  // zie commentaar bij
        digitalWrite(relaisR_2, LOW);            // zet wissel 1 gebogen met knop
        digitalWrite(relaisG_2, LOW);
        wisselServo2.write(1760);
        delay(servoWacht);
        digitalWrite(relaisG_2, HIGH);
        digitalWrite(LED, HIGH);
        wisselServo2.detach();
      }
    }
  }

// - - - - - zet wissel 2 om met schakelaar
  if ((millis() - lastDebounceTimeoptoIn_2) > debounceDelay)
  {

    // if the button state has changed:
    if (readingOptoIn2 != optoIn2State)
    {
      optoIn2State = readingOptoIn2;
      wisselServo1.attach(servo_2,1000,2500);

      // only toggle the LED if the new button state is HIGH
      if (optoIn2State == LOW)
      {
        digitalWrite(relaisG_2, LOW);           // zie commentaar bij
        digitalWrite(relaisR_2, LOW);
        wisselServo1.write(1161);               // zet wissel 1 recht met knop
        delay(servoWacht);
        digitalWrite(relaisR_2, HIGH);
        digitalWrite(LED, HIGH);
      }
      else
      {
        digitalWrite(relaisR_2, LOW);           // zie commentaar bij
        digitalWrite(relaisG_2, LOW);
        wisselServo1.write(1790);               // zet wissel 1 gebogen met knop
        delay(servoWacht);
        digitalWrite(relaisG_2, HIGH);
        digitalWrite(LED, LOW);
      }
      wisselServo1.detach();
    }
  }


  // save the readings.  Next time through the loop,
  // it'll be the last_XXX_state:
  lastknopG_1State = readingKnopG1;
  lastknopR_1State = readingKnopR1;
  lastoptoIn1State = readingOptoIn1;
  lastknopG_2State = readingKnopG2;
  lastknopR_2State = readingKnopR2;
  lastoptoIn2State = readingOptoIn2;
}
Voor mijn eerste toepassing voldoende, echter alles (ook de servostanden) hard ingecodeerd. Zelfs gebruik gemaakt van "delay()" in de mainloop. Niet zo'n elegante oplossing. Verder mis je ook nog snelheid instellen.
Daarna de firmware uit het adServo draadje (http://forum.beneluxspoor.net/index.php/topic,61213.0.html) opgepakt en het werk van Timo aangevuld met de sturing voor de relais. Hieronder de aanpassingen in de code.
define     NrRelais     sizeof(relaisMap)
.
.
.
const byte relaisMap[] = {7, 8, 12, 11};  // Pins van de relais (2 per servo) CB
.
.
. in setup()
    // Maak de pinnen voor de relais OUTPUT - CB
    for(byte i = 0; i <  NrRelais; i++)
    {
      pinMode(relaisMap[i], OUTPUT);   
    }
.
.
. in loop()
            servoControl.gotoEndPos(i / 2, 0);    //go to position A
            digitalWrite(relaisMap[i / 2], LOW);        // laat beide relais afvallen
            digitalWrite(relaisMap[i / 2 + 1], LOW);    // CB
            numButtons += 1;
.
.
            servoControl.gotoEndPos(i / 2, 1);    //go to position B
            digitalWrite(relaisMap[i / 2], LOW);        // laat beide relais afvallen
            digitalWrite(relaisMap[i / 2 + 1], LOW);    // CB
            numButtons += 1;
.
.
. aan het eind van loop()
    // zet juiste relais weer aan
    if (servoControl.isAtEndPos(0, 0)) {digitalWrite(relaisMap[0], HIGH);}
    if (servoControl.isAtEndPos(0, 1)) {digitalWrite(relaisMap[1], HIGH);}
    if (servoControl.isAtEndPos(1, 0)) {digitalWrite(relaisMap[2], HIGH);}
    if (servoControl.isAtEndPos(1, 1)) {digitalWrite(relaisMap[3], HIGH);}
Hiermee een poosje gespeeld op mijn testplankje en daar ben ik bijna tevreden mee. De volgende wens is wisselaansturing door de 2 optocouplers naast de 4 drukknoppen. Dan kun je ook met een simpele schakelaar de wisselstand zetten. Daar ga ik binnenkort aan werken.
(https://images.beneluxspoor.net/bnls/2SmHSP_schema.png) (https://images.beneluxspoor.net/bnls/2SmHSP_schema.png)
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: gvandersel op 15 juni 2015, 10:47:54
Zo een draadje van Cees. Ik zal mee kijken en naast de zaterdagse bijeen komsten (HCC!m) ook af en toe hier commentaar geven.

Succes en groeten,

Gerard van der Sel.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 20 juni 2015, 12:00:49
Het heeft weer even geduurd. Afbeelding van de printlayout maken, die ook nog wat laat zien, was niet lastig maar wel even werk. De huidige versie, nog zonder de ontkoppeldiode D2 uit het schema, zie je hieronder:
(https://images.beneluxspoor.net/bnls/2SmHSP_print.jpg) (https://images.beneluxspoor.net/bnls/2SmHSP_print.jpg)

Die heb ik 2 keer onder mijn probeerbaantje hangen en doet al goede diensten bij besturing van dat baantje in combinatie met Dinamo, de primaire hardware (zie foto 1). Het geheel wordt bestuurd met iTrain. Om de andere delen die ik voor de Inglenook wil maken te testen zal de baan een andere electronica laag krijgen; op foto 2 zie je de lege versie. Daar moet handbediening op komen.
Wil je meer willen weten over de algemene opbouw van het baantje, kijk dan op de HCC!m-site (http://www.hccm.nl/). Klik op het menu "Beursflyer".
foto 1: het baantje met Dinamo
(https://images.beneluxspoor.net/bnls/flyerbaan_Dinamo_800px.jpg) (https://images.beneluxspoor.net/bnls/flyerbaan_Dinamo_800px.jpg)
foto 2: het baantje met nog niets
(https://images.beneluxspoor.net/bnls/flyerbaan_leeg_800px.jpg) (https://images.beneluxspoor.net/bnls/flyerbaan_leeg_800px.jpg)
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Daan Neijenhuis op 23 juni 2015, 20:41:51
Die gaan we volgen  :D
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Martin Hornis op 24 juni 2015, 12:05:20
Mooi overzichtelijk. Ik laat me verrassen.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 27 juni 2015, 12:07:14
Het lijkt er op dat de updates wekelijks worden.
Afgelopen week ben ik hoofdzakelijk bezig geweest met Arduino en firmware-aanpassingen. Ik wil in mijn adServo-versie de 2 drukknoppen per wissel gaan vervangen door een schakelaar die omschakelt van 0 volt naar 5 of meer volt. Voor dat doel heeft de print al 2 optocouplers.
In de eerste post heb je mijn proefopstelling gezien met een provisorisch toetsenbordje om de servo's en relais te bedienen. Dezelfde toetsen gebruikt de adServo-firmware om de eindstanden en de draaisnelheid van de servo's in te stellen.
Voor een ander doel heb ik een schakelaar paneeltje gemaakt (foto). Door een overlay op een A4 is die ook goed bruikbaar voor de adServo. Ik gebruik dan niet alles, maar wie weet. De draaiknop, die je in het midden ziet is nu een potentiometer. Dat zou in de toekomst best wel eens een quadrature encoder kunnen worden (zo'n ding dat je eindeloos kunt doordraaien). Het display heeft nog geen functie.

(https://images.beneluxspoor.net/bnls/setup_bord_400.jpg) (https://images.beneluxspoor.net/bnls/setup_bord_400.jpg)

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: willem22 op 19 augustus 2015, 17:59:21
Hoi Cees, maak dit draadje wakker , volg deze maar zie elders update's.

Wil.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 19 augustus 2015, 22:35:41
Na een lange poos weer een kleine update. Vakantietijd en worstelen met een stukje Arduino programmering - en nog steeds mee aan het worstelen - heeft de boel wel even stil gelegd. Bovendien voor HCC!m had ik ook nog een klus aan een andere demo van mezelf. Die is deels ook noodzakelijk voor dit project.

Wim heeft wel schijnbare updates gezien in het draadje van Timo. Dat ging echter over het gebruik van Timo's firmware en het leek me beter gepast om de opmerking daar te plaatsen.

Hoe ver ben ik nu? De library van Timo op een andere manier benut om een wissel niet met 2 toetsen te hoeven bedienen. Verder een andere manier  van 'debounce' gebruikt. Ik probeer nu het instellen iets anders te doen m.b.v. o.a een LCD-display. Dat wil niet erg vlotten. Komt door keuze dilemma's in de menustructuur die nodig is.
Ik heb inmiddels ook een Arduino als Commander getest. I.p.v. een motor-shield heb ik de DCC-uitgang van de Arduino rechtstreeks aan de BNLS Boosterhub gehangen en dat functioneerde gelijk.

Vooralsnog eerst maar eens de wisselstellers afmaken.

Nog een vraag voor de modelspoorders:
Ik rijd N en wil gaan voorontkoppelen bij het uitrangeren op de Inglenook. Waar zouden jullie een ontkoppelvoorziening maken? Op ieder van de 3 opstelsporen aan het begin of slechts 1 voor het eerste verdelende wissel. Het gaat me niet om de financiën maar om de meest praktische plek.

groet, Cees.


Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Martin Hornis op 20 augustus 2015, 11:23:11
Nog een vraag voor de modelspoorders:
Ik rijd N en wil gaan voorontkoppelen bij het uitrangeren op de Inglenook. Waar zouden jullie een ontkoppelvoorziening maken? Op ieder van de 3 opstelsporen aan het begin of slechts 1 voor het eerste verdelende wissel.
Bij voorontkoppelen: vóór het eerste verdelende wissel. Hierbij mag de koppeling niet meer vastklikken bij het verder duwen van het rangeerdeel. Als dat teveel problemen geeft, dan aan het begin van de opstelsporen.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 24 augustus 2015, 12:21:37
Een update:
Onderstaand de code voor firmware van mijn print. Hier moet nog het nodige bij komen. Het instellen van de eindstanden en de bewegingssnelheid. Ik gebruik de servo-library's van de AdServo van Timo. Debounce van de knoppen gaat zonder library. Ik heb zoveel mogelijk Nederlands gebruikt. Niet omdat ik Engels niet beheers maar voor de duidelijkheid. Verder gebruik ik principieel waar mogelijk Nederlandse benamingen voor variabelen en dergelijke, om te voorkomen dat ik een "keyword" van IDE of library gebruik.

Binnenkort eerst maar eens een weekje op vakantie. Veel natuur en zo. 's Avonds misschien verder filosoferen over de manier van instellen.

M.vr.gr. Cees
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 S e r v o   W i s s e l S t e l l e r
   
   Testprogramma voor het omzetten van twee modelspoorwissels m.b.v.
   een modelbouw servo.
   Te testen:
   - 4 losse drukknoppen voor recht en afbuigend
   - 2 optocoupler ingangen; funtioneel als schakelaar, bedoeld
     voor besturing vanuit HCC!m-systeem of Dinamo OC32
   - 1 van de optocouplers moet later ook DCC kunnen verwerken
   Er wordt gebruik gemaakt van 2 servo's
   Ten behoeve van hartstukpolarisatie zijn er per servo 2 relais
   
   Werking per wissel:
   - na een wisselcommando vallen eerst beide relais af
   - daarna loopt het wissel om (servo)
   - dan komt het juiste relais op
   Bij opstarten gebeurt er niets. Het hartstuk van het wissel heeft
   geen spanning en de servo staat in een ongedefinieerde stand.
   
   De gebruikte Arduino is een Pro Mini, 5V met ATmega328.
   
   Gebruikte libraries en voorbeelden:
   - code uit het Debounce-voorbeeld bestand van Arduino.cc
     http://www.arduino.cc/en/Tutorial/Debounce
   - ServoExtend library van Timo Engelgeer
   - ServoControl library van Timo Engelgeer
   
   Created:   30-04-2015
   By:        Cees Baarda
              Eerste opzet met gebruikmaking van de library Servo uit de Arduino-
              omgeving.
   Modified:  15-07-2015
   By:        Cees Baarda
              Aangepast aan gebruik met de libraries van Timo Engelgeer
              De servo's starten nu op in de middenstand, ongeacht de stand van schakelaars.
              De relais blijven afgevallen tot het eerste wisselstel commando. Nadeel:
              Je moet het wissel 2 keer stellen als je het wissel in de stand van de
              schakelaar wilt hebben.
              Je kunt de drukknoppen en schakelaars door elkaar gebruiken.
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *   
// - - - - - L i b r a r i e s   i n   g e b r u i k :
#include <ServoExtend.h>
#include <ServoControl.h>

#include <Wire.h>
#include <LiquidCrystal_I2C.h>


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - C o n s t a n t e n :
//           De pinnummers en vaste waarden een naam geven
   
// - - - - - voor wissel 1
  const int optoIn_1  = 3;  // voor externe aansturing met 0 of 1
  const int servo_1   = 9;
  const int servo1_endPosR = 10;    // voorlopig hard coderen, later uit EEPROM
  const int servo1_endPosG = 1002;  // voorlopig hard coderen, later uit EEPROM
  // - - - - - t.b.v puntstukpolarisatie
  const int relaisR_1 = 7;
  const int relaisG_1 = 8;
  // - - - - - t.b.v. bediening met knoppen
  const int knopR_1   = 6;  // input; toets wissel recht leggen
  const int knopG_1   = 5;  // input; toets wissel gebogen leggen

// - - - - - voor wissel 2
  const int optoIn_2  = 2;  // voor externe aansturing met 0 of 1
  const int servo_2   = 10;   // output; Servo 2
  const int servo2_endPosR = 10;    // voorlopig hard coderen, later uit EEPROM
  const int servo2_endPosG = 1002;  // voorlopig hard coderen, later uit EEPROM
  // - - - - - t.b.v puntstukpolarisatie
  const int relaisR_2 = 11;  // output; t.b.v. relais bij recht gelegd wisssel
  const int relaisG_2 = 12;  // output; t.b.v. relais bij gebogen gelegd wisssel
  // - - - - - t.b.v. bediening met knoppen
  const int knopR_2   = A2;  // input; toets wissel recht leggen
  const int knopG_2   = A0;  // input; toets wissel gebogen leggen

// - - - - - beide wissels met DCC, nog niet in gebruik
  // const int DCC_in    = 2;  // input; de DCC-railspanning gaat hier aan
  const int servoSnelheid = 30;
  const int servoStepInterval = 1;
  const int LED = A1;        // LED op de print

// - - - - - nog niet in gebruik, voor servo instelmodus
//           encoder: common moet aan GND, andere aan pin 5 en 6
//  const int pgmEncA   = 6;
//  const int pgmAncB   = 5;
//  const int pgmOK     = A0;  // kan losse knop of knop van de encoder zijn

// - - - - - nog niet in gebruik, zijn bedoeld voor extra print aan 8 polige
//           connector
  // const int LEDarduino   = 13; // LED op de arduino
  // const int LEDextern_1  = A2; // evt. extra LED op externe print (pin 4)
  // const int LEDextern_2  = A3; // evt. extra LED op externe print (pin 5)
  // const int externKnop_1 = A2; // evt. extra knop op externe print (pin 4)
  // const int externKnop_1 = A3; // evt. extra knop op externe print (pin 5)
 

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - G l o b a l e   V a r i a b e l e n :
//
  ServoControl wisselServos;         // 1 object van het type ServoControl
  // - - - - - voor wissel 1
  int knopG_1State;                  // de huidige waarde van de input pin
  int lastknopG_1State      = LOW;   // de vorige waarde van de input pin
  int knopR_1State;                  // de huidige waarde van de input pin
  int lastknopR_1State      = LOW;   // de vorige waarde van de input pin
  // door de huidige PIN-waarde in te lezen wordt het wissel niet direct gesteld in een
  // stand na opstarten
  int optoIn1State          = digitalRead(optoIn_1);  // de huidige waarde van de input pin
  int lastoptoIn1State      = digitalRead(optoIn_1);  // de vorige waarde van de input pin
 
  // - - - - - voor wissel 2
  int knopG_2State;                  // de huidige waarde van de input pin
  int lastknopG_2State      = LOW;   // de vorige waarde van de input pin
  int knopR_2State;                  // de huidige waarde van de input pin
  int lastknopR_2State      = LOW;   // de vorige waarde van de input pin
  // door de huidige PIN-waarde in te lezen wordt het wissel niet direct gesteld in een
  // stand na opstarten
  int optoIn2State          = digitalRead(optoIn_2);  // de huidige waarde van de input pin
  int lastoptoIn2State      = digitalRead(optoIn_2);  // de vorige waarde van de input pin
 
  // de volgende variabelen zijn 'long', omdat de tijd gemeten in milliseconden
  // snel de max waarde van een 'int' zal overschrijden.
 
  // - - - - - voor wissel 1
  long lastDebounceTimeRecht_1 = 0;    // het laatste tijdstip waarop de ingang is veranderd
  long lastDebounceTimeGebogen_1 = 0;  // *
  long lastDebounceTimeoptoIn_1 = 0;   // *
 
  // - - - - - voor wissel 2
  long lastDebounceTimeRecht_2 = 0;    // het laatste tijdstip waarop de ingang is veranderd
  long lastDebounceTimeGebogen_2 = 0;  // *
  long lastDebounceTimeoptoIn_2 = 0;   // *
 
  const long debounceDelay = 50;       // de debounce tijd; hoger maken als de uitgang knippert




// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - prototypes
//
  void servoInstellen();


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - setup, 1 x doorlopen
//
void setup()
{
// - - - - - setup input en output
  // - - - - - voor wissel 1
  pinMode(knopG_1, INPUT_PULLUP);
  pinMode(relaisR_1, OUTPUT);
  pinMode(knopR_1, INPUT_PULLUP);
  pinMode(relaisG_1, OUTPUT);
  pinMode(optoIn_1, INPUT);
  // - - - - - voor wissel 2
  pinMode(knopG_2, INPUT_PULLUP);
  pinMode(relaisR_2, OUTPUT);
  pinMode(knopR_2, INPUT_PULLUP);
  pinMode(relaisG_2, OUTPUT);
  pinMode(optoIn_2, INPUT);
  // - - - - - LED's
  pinMode(LED, OUTPUT);

// - - - - - zet relais uit
  // - - - - - voor wissel 1
  digitalWrite(relaisR_1, LOW);
  digitalWrite(relaisG_1, LOW);
  // - - - - - voor wissel 2
  digitalWrite(relaisR_2, LOW);
  digitalWrite(relaisG_2, LOW);

// - - - - - initialiseer de servo's
  // voor wissel 1
  wisselServos.setEndPos(0, 0, servo1_endPosR);
  wisselServos.setEndPos(0, 1, servo1_endPosG);
  wisselServos.setSpeed(0, servoSnelheid, servoStepInterval);
  wisselServos.init(0, servo_1);
  // voor wissel 2
  wisselServos.setEndPos(1, 0, servo2_endPosR);
  wisselServos.setEndPos(1, 1, servo2_endPosG);
  wisselServos.setSpeed(1, servoSnelheid, servoStepInterval);
  wisselServos.init(1, servo_2);
 
// zet beide servo's in de middenstand
  wisselServos.gotoPos(0,511);
  wisselServos.gotoPos(1,511);
  wisselServos.update();

// - - - - - testen van werking (moet later weg?)
//  digitalWrite(LED, HIGH);
}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - eindeloos doorgaan
void loop()
{

// - - - - - lokale variabelen voor inlezen 'knoppen'
  // - - - - - voor wissel 2
  int readingKnopG2;
  int readingKnopR2;
  int readingOptoIn2;
  // - - - - - voor wissel 1
  int readingKnopG1;
  int readingKnopR1;
  int readingOptoIn1;
 
// - - - - - lees de knoppen in
  readingKnopG2 = digitalRead(knopG_2);
  readingKnopR2 = digitalRead(knopR_2);
  readingOptoIn2 = digitalRead(optoIn_2);
  readingKnopG1 = digitalRead(knopG_1);
  readingKnopR1 = digitalRead(knopR_1);
  readingOptoIn1 = digitalRead(optoIn_1);

// check to see if you just pressed the button
// (i.e. the input went from LOW to HIGH),  and you've waited
// long enough since the last press to ignore any noise: 

// If the switch changed, due to noise or pressing:
  if (readingKnopG1 != lastknopG_1State)
  {
    lastDebounceTimeRecht_1 = millis();  // reset the debouncing timer
  }
  if (readingKnopR1 != lastknopR_1State)
  {
    lastDebounceTimeGebogen_1 = millis();  // reset the debouncing timer
  }
  if (readingOptoIn1 != lastoptoIn1State)
  {
    lastDebounceTimeoptoIn_1 = millis();  // reset the debouncing timer
  }
  if (readingKnopG2 != lastknopG_2State)
  {
    lastDebounceTimeRecht_2 = millis();  // reset the debouncing timer
  }
  if (readingKnopR2 != lastknopR_2State)
  {
    lastDebounceTimeGebogen_2 = millis();  // reset the debouncing timer
  }
  if (readingOptoIn2 != lastoptoIn2State)
  {
    lastDebounceTimeoptoIn_2 = millis();  // reset the debouncing timer
  }

// - - - - - zet wissel 1 gebogen met knop
  if ((millis() - lastDebounceTimeGebogen_1) > debounceDelay)
  {
  // if the button state has changed:
    if (readingKnopG1 != knopG_1State)
    {
    knopG_1State = readingKnopG1;
      if (knopG_1State == LOW)
      {
        digitalWrite(relaisG_1, LOW);            // relais valt af, hartstuk stroomloos
        digitalWrite(relaisR_1, LOW);            // relais valt af, hartstuk stroomloos
        wisselServos.gotoEndPos(0,0);                // zet servo om
      }
    }
  }

// - - - - - zet wissel 1 recht met knop
  if ((millis() - lastDebounceTimeRecht_1) > debounceDelay)
  {
    // if the button state has changed:
    if (readingKnopR1 != knopR_1State) {
      knopR_1State = readingKnopR1;

      // only toggle the LED if the new button state is HIGH
      if (knopR_1State == LOW)
      {
        digitalWrite(relaisG_1, LOW);            // relais valt af, hartstuk stroomloos
        digitalWrite(relaisR_1, LOW);            // relais valt af, hartstuk stroomloos
        wisselServos.gotoEndPos(0,1);                // zet servo om
      }
    }
  }

/* - - - - - zet wissel 1 om met schakelaar--*/
  if ((millis() - lastDebounceTimeoptoIn_1) > debounceDelay)
  {

    // if the button state has changed:
    if (readingOptoIn1 != optoIn1State)
    {
      optoIn1State = readingOptoIn1;
     
// - - - - - Eerst het hartstuk stroomloos maken
      digitalWrite(relaisG_1, LOW);   // relais valt af
      digitalWrite(relaisR_1, LOW);   // relais valt af

// - - - - - stuur servo alleen aan als die nog naar een nieuwe eindpositie moet
      if (optoIn1State == LOW)
      {
        if (!wisselServos.isAtEndPos(0,1)) wisselServos.gotoEndPos(0,1);
      }
      else
      {
        if (!wisselServos.isAtEndPos(0,0)) wisselServos.gotoEndPos(0,0);
      }
    }
  }
// - - - - - zet wissel 2 gebogen met knop
  if ((millis() - lastDebounceTimeGebogen_2) > debounceDelay)
  {
// if the button state has changed:
    if (readingKnopG2 != knopG_2State)
    {
    knopG_2State = readingKnopG2;
// only toggle the LED if the new button state is HIGH
      if (knopG_2State == LOW)
      {
        digitalWrite(relaisG_2, LOW);            // relais valt af, hartstuk stroomloos
        digitalWrite(relaisR_2, LOW);            // relais valt af, hartstuk stroomloos
        wisselServos.gotoEndPos(1,0);                // zet servo om
      }
    }
  }

// - - - - - zet wissel 2 recht met knop
  if ((millis() - lastDebounceTimeRecht_2) > debounceDelay)
  {
    // whatever the readingKnopR2 is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (readingKnopR2 != knopR_2State) {
      knopR_2State = readingKnopR2;

      if (knopR_2State == LOW)
      {
        digitalWrite(relaisG_2, LOW);            // relais valt af, hartstuk stroomloos
        digitalWrite(relaisR_2, LOW);            // relais valt af, hartstuk stroomloos
        wisselServos.gotoEndPos(1,1);            // zet servo om
      }
    }
  }

/* - - - - - zet wissel 2 om met schakelaar*/
  if ((millis() - lastDebounceTimeoptoIn_2) > debounceDelay)
  {

    // if the button state has changed:
    if (readingOptoIn2 != optoIn2State)
    {
      optoIn2State = readingOptoIn2;
      digitalWrite(relaisG_2, LOW);            // relais valt af, hartstuk stroomloos
      digitalWrite(relaisR_2, LOW);            // relais valt af, hartstuk stroomloos

      // only toggle the LED if the new button state is HIGH
      if (optoIn2State == LOW)
      {
        if (!wisselServos.isAtEndPos(1,1)) wisselServos.gotoEndPos(1,1);                // zet servo om
      }
      else
      {
        if (!wisselServos.isAtEndPos(1,0)) wisselServos.gotoEndPos(1,0);            // zet servo om
      }
    }
  }

  wisselServos.update();

  // zet juiste relais weer aan
  if (!wisselServos.isMoving(0))    // zorg eerst dat het servo stil staat, dan relais aan
  {
    if (wisselServos.isAtEndPos(0, 0)) {digitalWrite(relaisR_1, HIGH);}
    if (wisselServos.isAtEndPos(0, 1)) {digitalWrite(relaisG_1, HIGH);}

  }
  if (!wisselServos.isMoving(1))    // zorg eerst dat het servo stil staat, dan relais aan
  {
    if (wisselServos.isAtEndPos(1, 0)) {digitalWrite(relaisR_2, HIGH);}
    if (wisselServos.isAtEndPos(1, 1)) {digitalWrite(relaisG_2, HIGH);}
  }

  // save the readings.  Next time through the loop,
  // it'll be the last_XXX_state:
  lastknopG_1State = readingKnopG1;
  lastknopR_1State = readingKnopR1;
  lastoptoIn1State = readingOptoIn1;
  lastknopG_2State = readingKnopG2;
  lastknopR_2State = readingKnopR2;
  lastoptoIn2State = readingOptoIn2;
}
Een update:


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - Servo instelmodus

void servoInstellen()
{
 

}
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 28 augustus 2015, 12:32:50
Dag allemaal,

nog even een update voor een weekje vakantie.
De Inglenook die ik ga gebruiken ziet er kwa baanplan als volgt uit:
(https://images.beneluxspoor.net/bnls/inglenook_op_huidige_driehoek.jpg) (https://images.beneluxspoor.net/bnls/inglenook_op_huidige_driehoek.jpg)

Ik maak gebruik van 2 bakjes van een andere demobaan met een keer driehoek. De hardware voor de bediening van de wissels en het rijden met een computer is al aanwezig (zie de tweede foto). Op de plek van de rode stip zal een ontkoppelaar komen, die wordt ook uitgevoerd met een servo. De wagens en lok krijgen profi-koppelingen. De rails is Peco N code 55 en de wissels hebben een metalen hartstuk.
(https://images.beneluxspoor.net/bnls/onderkant_bak_3_poren.jpg) (https://images.beneluxspoor.net/bnls/onderkant_bak_3_poren.jpg)

Er is inmiddels ook een soort principe schema van de opbouw van de aansturing:
(https://images.beneluxspoor.net/bnls/schema_opbouw_bediening.jpg) (https://images.beneluxspoor.net/bnls/schema_opbouw_bediening.jpg)

De beide servostellers worden mijn eigen interpretatie van de AdServo (http://forum.beneluxspoor.net/index.php/topic,61213.0.html), die ik al in een eerdere post liet zien. De rijregelaar wordt ook gemaakt op basis van een Arduino Pro Mini. De wissels en de ontkoppelaar zullen bediend worden met een schakelaar.  De rijregelaar krijgt slechts 3 knoppen. Voor rangeren ga ik gebruik maken van lage snelheden en de optrek- en remvertraging van de decoder in de lok. Zoals je  ziet wordt het totale handbediening en dat lijkt me voor deze spelsituatie ook de mooiste oplossing.

groet, Cees.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: dickkoning op 28 augustus 2015, 20:04:45
Hallo Cees

ga in de rijregelaar een dcc signaal opwekken mbv een arduino of ga je een analoge regelaar bouwen ?

De tekst van de link is in het frans (google translate ?) maar er wordt een arduino gebaseerde DCC centrale gebouwd

  http://bultez.fr/post/2013/02/08/Construction-de-la-mini-centrale   (http://bultez.fr/post/2013/02/08/Construction-de-la-mini-centrale)


vr groeten

dick koning
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 28 augustus 2015, 21:25:20
Die kende ik nog niet. Mijn Frans is wat minder, dus lastig te lezen.

Mijn bedoeling is echter alleen een "DCC-throttle" te maken. Het wordt dus geen centrale. Een voorbeeld van zo'n project heb ik o.a. hier gevonden (http://www.oscale.net/en/arduino). Ik heb even niet de library paraat, die ik zal gaan gebruiken.

groet, Cees.


Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 31 augustus 2015, 15:36:52
Verder gebruik ik principieel waar mogelijk Nederlandse benamingen voor variabelen en dergelijke, om te voorkomen dat ik een "keyword" van IDE of library gebruik.
Zoveel keyword heeft de IDE niet hoor ;) En die van een library gebruiken is ook niet zo erg omdat het vaak dan toch om een object gaat. Niet dat Nederlandse variabele niet mogen maar de reden ervoor (afgezien van dat Nederlands de moedertaal is) zijn niet echt geldig.

Ik zie alleen ook hier weer veel "dubbel werk" omdat je bijvoorbeeld alles voor wissel 1 en wissel 2 los uit schrijft. Kijk even naar mijn post in het topic van Dick (http://forum.beneluxspoor.net/index.php/topic,65787.msg3221591427.html#msg3221591427), daar stip ik dat ook aan. Nu heb je maar 2 wissels maar het schaalt zo lastig als je er misschien later toch meer wilt. Maar bijvoorbeeld bij de knoppen zou het je al heeeeel veel code schelen....

Debounce van de knoppen gaat zonder library.
Het lijkt bijna wel of je dit met trots zegt  ::) ;D Maar waarom niet gewoon een library pakken? Deze zijn juist bedacht om jou veel werk uit handen te namen en bijvoorbeeld de Bounce2 library zou je code een heeeeeeel stuk makkelijker maken. Een stuk als
// - - - - - zet wissel 1 gebogen met knop
  if ((millis() - lastDebounceTimeGebogen_1) > debounceDelay)
  {
  // if the button state has changed:
    if (readingKnopG1 != knopG_1State)
    {
    knopG_1State = readingKnopG1;
      if (knopG_1State == LOW)
      {
        digitalWrite(relaisG_1, LOW);            // relais valt af, hartstuk stroomloos
        digitalWrite(relaisR_1, LOW);            // relais valt af, hartstuk stroomloos
        wisselServos.gotoEndPos(0,0);                // zet servo om
      }
    }
  }
Is dan te herschrijven tot:
knopGebogen1.update();
if(knopGebogen1.fell()){
  digitalWrite(relaisG_1, LOW);            // relais valt af, hartstuk stroomloos
  digitalWrite(relaisR_1, LOW);            // relais valt af, hartstuk stroomloos
  wisselServos.gotoEndPos(0,0);                // zet servo om
}

Maak je van alle knoppen nog een array van 2 bij 2 zou je het hele stuk tussen regel 205 en 369 kunnen herschrijven in ik denk 15 regels.... En dan is het nog in 10 seconde op te schalen tot 8 wissels als je wilt ook... Maar again, zeg niet dat het moet, ik geef het je alleen als tip  ;) Als je tips krijgen niet erg vind zou ik je aanraden het geweldige tips and traps stuk van Nick Gammon (http://www.gammon.com.au/tips) door te lezen.


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 04 september 2015, 16:53:41
@Timo
Je hebt met je opmerking:
Citaat
Ik zie alleen ook hier weer veel "dubbel werk" omdat je bijvoorbeeld alles voor wissel 1 en wissel 2 los uit schrijft.
helemaal gelijk, echter ik ben niet voornemens om de firmware uit te breiden voor meer dan die 2 wissels. En dan heb ik de keus 1 x kopiëren en plakken met wat wijzigingen of extra code toevoegen.

Citaat
Citaat van: Cees Baarda op 24 augustus 2015, 12:21:37
Debounce van de knoppen gaat zonder library.
Het lijkt bijna wel of je dit met trots zegt 
Ik heb het geschreven als constatering en om aan te geven, dat er hiervoor geen library hoeft te worden bijgevoegd. Ik heb denk ik wel bewezen libraries te gebruiken. Zeker als het gaat om het uitvinden van een wiel, zoals met je eigen libraries, zal ik er dankbaar gebruik van maken. Ik ben overigens nog niet zo ver dat ik me wil wagen aan array's om e.e.a. te vereenvoudigen. Mijn ervaring is dat dan je eigen code cryptischer wordt, waardoor zeker ik de weg dreig kwijt te raken. Ik verwacht op een later moment je tips ter harte te nemen en alsnog de code anders op te bouwen. Plezierig gevolg wordt dan natuurlijk de vereenvoudiging richting meer te bedienen wissels.

groet Cees.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: gvandersel op 05 september 2015, 00:40:54
Cees,

Als je het wissel als object (class of library) gaat inzetten, zal bij een fout deze 'automatisch' voor het tweede wissel gerepareerd worden. Dan hoeft niet opnieuw met knippen en plakken gedaan, met kans op nog meer fouten.

Groet,

Gerard van der Sel.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: ivanzon op 05 september 2015, 07:49:22
Mijn advies is: Gebruik die knop detectie Library, dat verkleint de kans op fouten enorm door het knop status gebeuren in één functie te stoppen.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 06 september 2015, 12:56:12
@Gerard;
ik gebruik de libraries van de adServo. Je opmerking betekent dus dat ik de "ServoControl class", die Timo gemaakt heeft moet uitbreiden met twee relais, door:

1- bij de variabelen van de class ; 2 pins toe te voegen en een boolean relaisAvailable

2- bij ServoControl::init(...) ; e.e.a. mee te initialiseren
Dat wordt dus een tweede init(...) maken om de library universeel te houden

2- bij ServoControl::gotoEndPos ; beide relais-pins LOW te maken
Krijg je zoiets als
if(this->servoInfo[i].relaisAvailable)
{
  //laat relais afvallen
}

3- bij ServoControl::update ; op het juiste moment, het juiste relais weer te laten opkomen
   //time to detach
   else if(this->servoInfo[i].speed.intervalCount == 1)
   {
      this->servoInfo[i].speed.intervalCount--;
      this->servoList[i].detach();
      if(this->servoInfo.relaisAvailable)
      {
         // laat het juiste relais opkomen
      }
   }

Daar zal ik wel even mee bezig zijn. Ik ga het wel proberen.

Als ik het goed begrepen heb, kun je bij object georiënteerd programmeren een tweede init maken. Die is anders door het aantal variabele.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 06 september 2015, 14:17:13
Ik was nog niet klaar met mijn vorige post. Lunchtijd brak e.e.a. even af.

@ivanzon
Die library gaat er zeker weer inkomen.
Ik vond het wel aardig om te laten zien hoe ik begonnen ben. In die bounce2 library kon ik niet boven water halen of er nog een interrupt gebruikt word naast de timer t.b.v. "millies()". Ergens in de toekomst wil ik meer met Wire (i2c) en DCC. Dat zou tot conflicten kunnen leiden.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 07 september 2015, 16:35:38
En dan heb ik de keus 1 x kopiëren en plakken met wat wijzigingen of extra code toevoegen.
3x, want eigenlijk doe je voor zowel rechtdoor als afbuigen al hetzelfde. En dan is het echt al de moeite waard om het anders te doen.

Ik heb het geschreven als constatering en om aan te geven, dat er hiervoor geen library hoeft te worden bijgevoegd. Ik heb denk ik wel bewezen libraries te gebruiken.
Dat heb je zeker! Maar doelde er meer op de de Bounce library zo makkelijk en simpel is dat ik eigenlijk vind dat hij een standaard Arduino library zou moeten zijn. Gebruik ervan maakt de code ook zoveel leesbaarder.

Ik ben overigens nog niet zo ver dat ik me wil wagen aan array's om e.e.a. te vereenvoudigen. Mijn ervaring is dat dan je eigen code cryptischer wordt, waardoor zeker ik de weg dreig kwijt te raken.
Nouwja, cryptischer. Ipv een hele rij variabele zoals knop1, knop2, knop 3 te definiëren doe je gewoon knop[3] en gebruik je het als knop[0], knop[1] en knop[2]. Lastiger is het eigenlijk niet...

Ik heb even snel de code herschreven en is daarmee half zo lang geworden om je een idee te geven van array's en functies ipv copy past  ;D Natuurlijk niet verplicht om te gebruiken maar geeft je een idee hoeveel het scheelt en hoeveel leesbaarder de code is geworden.

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 S e r v o   W i s s e l S t e l l e r
   
   Testprogramma voor het omzetten van twee modelspoorwissels m.b.v.
   een modelbouw servo.
   Te testen:
   - 4 losse drukknoppen voor recht en afbuigend
   - 2 optocoupler ingangen; funtioneel als schakelaar, bedoeld
     voor besturing vanuit HCC!m-systeem of Dinamo OC32
   - 1 van de optocouplers moet later ook DCC kunnen verwerken
   Er wordt gebruik gemaakt van 2 servo's
   Ten behoeve van hartstukpolarisatie zijn er per servo 2 relais
   
   Werking per wissel:
   - na een wisselcommando vallen eerst beide relais af
   - daarna loopt het wissel om (servo)
   - dan komt het juiste relais op
   Bij opstarten gebeurt er niets. Het hartstuk van het wissel heeft
   geen spanning en de servo staat in een ongedefinieerde stand.
   
   De gebruikte Arduino is een Pro Mini, 5V met ATmega328.
   
   Gebruikte libraries en voorbeelden:
   - code uit het Debounce-voorbeeld bestand van Arduino.cc
     http://www.arduino.cc/en/Tutorial/Debounce
   - ServoExtend library van Timo Engelgeer
   - ServoControl library van Timo Engelgeer
   
   Created:   30-04-2015
   By:        Cees Baarda
              Eerste opzet met gebruikmaking van de library Servo uit de Arduino-
              omgeving.
   Modified:  15-07-2015
   By:        Cees Baarda
              Aangepast aan gebruik met de libraries van Timo Engelgeer
              De servo's starten nu op in de middenstand, ongeacht de stand van schakelaars.
              De relais blijven afgevallen tot het eerste wisselstel commando. Nadeel:
              Je moet het wissel 2 keer stellen als je het wissel in de stand van de
              schakelaar wilt hebben.
              Je kunt de drukknoppen en schakelaars door elkaar gebruiken.
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *   
// - - - - - L i b r a r i e s   i n   g e b r u i k :
#include <ServoExtend.h>
#include <ServoControl.h>
#include <Bounce2.h>

//#include <Wire.h>
//#include <LiquidCrystal_I2C.h>

#define R 0
#define G 1



// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - C o n s t a n t e n :
//           De pinnummers en vaste waarden een naam geven

#define AANTAL_POS 2 //Aantal posities per wissel

// - - - - - voor wissels
const byte OptoPin[]                  = {3, 2}; //Pin van de opto's in
const byte ServoPin[]                 = {9, 10};//Pin van de servo's
//eindposities sevo's {R, G} (ServoEndPos[wiselnummer][R of G])
const byte ServoEndPos[][AANTAL_POS] = {{10, 1002}, //wissel 1
                                        {10, 1002}};//wissel 2
// output; t.b.v. relais bij recht gelegd wisssel {R, G} (RelaisPin[wiselnummer][R of G])
const byte RelaisPin[][AANTAL_POS]   = {{7, 8}, //wissel 1
                                        {11, 12}}; //wissel 2
// inputs t.b.v. bediening met knoppen {R, G} (KnopPin[wiselnummer][R of G])
const byte KnopPin[][AANTAL_POS]     = {{6, 5},
                                        {A2, A0}};
#define AANTAL_SERVOS  sizeof(ServoPin)
#define AantalOptos     sizeof(OptoPin)

// - - - - - beide wissels met DCC, nog niet in gebruik
  // const int DCC_in    = 2;  // input; de DCC-railspanning gaat hier aan
  const int ServoSnelheid = 30;
  const int ServoStepInterval = 1;
  const int LedPin = A1;        // LED op de print
 
// - - - - - nog niet in gebruik, voor servo instelmodus
//           encoder: common moet aan GND, andere aan pin 5 en 6
//  const int pgmEncA   = 6;
//  const int pgmAncB   = 5;
//  const int pgmOK     = A0;  // kan losse knop of knop van de encoder zijn

// - - - - - nog niet in gebruik, zijn bedoeld voor extra print aan 8 polige
//           connector
  // const int LEDarduino   = 13; // LED op de arduino
  // const int LEDextern_1  = A2; // evt. extra LED op externe print (pin 4)
  // const int LEDextern_2  = A3; // evt. extra LED op externe print (pin 5)
  // const int externKnop_1 = A2; // evt. extra knop op externe print (pin 4)
  // const int externKnop_1 = A3; // evt. extra knop op externe print (pin 5)
 

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - G l o b a l e   V a r i a b e l e n :
//
  ServoControl wisselServos;         // 1 object van het type ServoControl
  // - - - - - Inputs
  Bounce knop[AANTAL_SERVOS][2];  //Voor alle knoppen (knop[wisselnummer][R of G])
  Bounce opto[AantalOptos];         //Voor alle opto's (opto[wisselnummer])
 
 




// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - prototypes
//
  void servoInstellen();
  void stelWissel(byte, byte);


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - setup, 1 x doorlopen
//
void setup()
{
  //Doe alles voor elke servo
  for(byte servoNr = 0; servoNr < AANTAL_SERVOS; servoNr++){ //Ga alle wissels langs
    //Setup voor alle knoppen
    for(byte posNr = 0; posNr < AANTAL_POS; posNr++){ //Ga R en G langs
      pinMode(KnopPin[servoNr][posNr], INPUT_PULLUP); //Zet alle knoppen als input met pullup
      knop[servoNr][posNr].attach(KnopPin[servoNr][posNr]);     //Koppel aan Bounce object
    }
   
    //Setup alle opto's
    pinMode(OptoPin[servoNr], INPUT_PULLUP); //Zet alle opto's als input met pullup
    opto[servoNr].attach(OptoPin[servoNr]);     //Koppel aan Bounce object
   
    //Setup voor alle relais
    for(byte posNr = 0; posNr < AANTAL_POS; posNr++){
      pinMode(RelaisPin[servoNr][posNr], OUTPUT);
      digitalWrite(RelaisPin[servoNr][posNr], LOW);
    }
   
    //Setup voor alle servo's
    for(byte posNr = 0; posNr < AANTAL_POS; posNr++){
      wisselServos.setEndPos(servoNr, posNr, ServoEndPos[servoNr][posNr]); //Stel beide/alle eindposities in
    }
    wisselServos.setSpeed(servoNr, ServoSnelheid, ServoStepInterval); //stel snelheid in
    wisselServos.init(servoNr, ServoPin[servoNr]);   //Koppel aan pin enzo
   
    wisselServos.gotoPos(servoNr, 511); //Ga naar middenstand
  }
  wisselServos.update();

// - - - - - testen van werking (moet later weg?)
//  digitalWrite(LedPin, HIGH);
}

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - eindeloos doorgaan
void loop()

  //loop alle wissels langs
  for(byte servoNr = 0; servoNr < AANTAL_SERVOS; servoNr++){
    //----De knoppen
      //Loop posities langs
      for(byte posNr = 0; posNr < AANTAL_POS; posNr++){
        knop[servoNr][posNr].update();  //Update de knop
       
        if(knop[servoNr][posNr].fell()){  //Knop is ingedrukt (gevallen) sidns vorige keer
          stelWissel(servoNr, posNr);     //Zet wissel in bijbehorende stand
        }
      }
   
    //----De opto's
      opto[servoNr].update(); //update de opto
      if(opto[servoNr].rose()){
        stelWissel(servoNr, R); //R-positie als hoog geworden
      }
      else if(opto[servoNr].fell()){ //G-positie als laag geworden
        stelWissel(servoNr, G);
      }
     
    //----De relais
      //Klaar met bewegen
      if(!wisselServos.isMoving(servoNr)){
        //Vind de eindstand waar hij is
        for(byte posNr = 0; posNr < AANTAL_POS; posNr++){
          if(wisselServos.isAtEndPos(servoNr, posNr)){
            //En zet juiste relais aan
            digitalWrite(RelaisPin[servoNr][posNr], HIGH);
          }
        }
      }
  }

  wisselServos.update(); //update alle servo's
}


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
// - - - - - Servo instelmodus

void servoInstellen()
{
 

}

void stelWissel(byte wisselNr, byte pos){
  //laat relais afvallen
  for(byte j = 0; j < AANTAL_POS; j++){
    digitalWrite(RelaisPin[wisselNr][j], LOW);      // relais valt af, hartstuk stroomloos
  }
  wisselServos.gotoEndPos(wisselNr, pos);              // zet servo om
}

[edit]Zoals vaker duurde de complete reactie iets langer dus stond even in de wacht  ;D Ondertussen dus twee extra reacties geweest. Je kan inderdaad de library aanpassen voor de relais maar er is eigenlijk ook niets tegen de huidige methode. Voordeel van de library niet aanpassen is dat eventuele latere updates van de ServoControll library gewoon over genomen kunnen worden. Maar het staat je vrij om de library aan te passen.

De bounce2 library is gewoon interrupt vrij. Het is puur makkelijk verpakt hoe je nu al met millis() een knop debounct. Het is alleen dan amper schrijfwerk  ;D
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 07 september 2015, 17:03:42
Eigenwijs als ik ben, heb ik toch de ServoControl library wat aangepast. Was maar een regel of 20. Ik heb dat natuurlijk wel met een kopie gedaan (je hebt daar een PB over Timo).
Door ook maar gelijk die leuke bounce2 library weer op te pakken is de code in mijn loop() gereduceerd tot 24 regels, zie hieronder

void loop()
{

// - - - - - zet wissel 1 en 2 om met knoppen

  for (byte i = 0; i < NrButtons; i++)
  {
    buttons[i].update();
    if (buttons[i].fell())
    {
      wisselServos.gotoEndPos(i / 2,i % 2);                // zet servo om
    }
  }
// - - - - - zet wissel 1 en 2 om met schakelaars
  for (byte j = 0; j < NrSwitches; j++)
  {
    switches[j].update();
    {
      if (switches[j].fell()) {wisselServos.gotoEndPos(j,0);}
      if (switches[j].rose()) wisselServos.gotoEndPos(j,1);
    }
  }
wisselServos.update();
 
}

Natuurlijk is daar bij de variabelen en in de setup() ook het e.e.a. veranderd. En zoals Timo eerder al schreef; aanpassen naar meer wissels is nu een eitje.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 26 maart 2016, 12:00:13
Zo, na een lange periode van niet posten, dit draadje maar eens oppoetsen.

De bouw van dit project heeft een poosje behoorlijk stil gestaan. Timo Engelgeer lijkt een enorme fan van KiCad als printontwerpomgeving te zijn. Daar wilde ik toch wel eens naar kijken. Dat heb ik geweten bij de opzet van een volgend onderdeel voor de Inglenook. Ik ben zeker 3 weken bezig geweest met het verkennen van de vele mogelijkheden van dit programma en de manier van werken daarmee. En daarna nog eens een paar weken met het ontwerpen en bouwen van een printje voor een Arduino Pro mini. Ik moet zeggen dat, als je eenmaal het programma wat meer in de vingers hebt, je niet anders meer wilt.

Wat heb ik bedacht:
Een 10 x 5 cm printje voor een Arduino Pro Mini met in- en uitvoer hardware. Wat wilde ik allemaal:
Voeding m.b.v. een laptop-voeding.
DCC-in met schroefconnector en LocoNet-B aansluiting.
DCC-uit met schroefconnector t.b.v. aansluiting aan een BNLS/RCU boosterhub.
LocoNet in/uit met 2 connectoren, waarbij de LocoNet-voeding voeding alleen wordt doorgelust.
2 relais in 2 modellen door een speciale footprint te maken.
4 LED's om seinbeelden te kunnen laten zien (rechts).
1 Servo aansturing.
i2c aansluiting, o.a. om een LCD aan te sluiten.
En extra omdat de aansluitingen nog over waren:
Makkelijker bereikbare resetknop (links).
Analoge input m.b.v. een potmeter (midden).
Een rotary-encoder met drukknop (midden).
2 extra LED's voor andere doelen (midden).

Primaire doel van het printje is te oefenen met de verschillende benodigde libraries, zoals die hier al diverse keren voorbij zijn gekomen. Het printje zal er uit gaan zien zoals op onderstaande afbeelding. Het eerste zal er een DCC loksturing gaan komen.

De uitvoer naar Gerber-files en opsturen naar iTead heb ik nog niet gedaan. Daar moet nog mee geoefend worden.

(https://images.beneluxspoor.net/bnls/print_def.png) (https://images.beneluxspoor.net/bnls/print_def.png)
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 26 maart 2016, 12:33:18
Hoi Cees,

Ziet er allemaal super uit!  (y) Het is inderdaad even verkennen maar daarna werkt het allemaal erg prettig. En ook ik ben altijd wel even bezig met een printje. Het basis ontwerp is er altijd zo, maar ben altijd zo pietluttig dat het er allemaal ook mooi en strak uit moet zien  ;D

Enige wat ik alleen nog denk als ik de print nu zie:
- De rotary lijkt me nogal dicht op de Arduino te zitten. Misschien kan deze meer naar de buitenkant?
- Weet niet wat je wilt instellen met de potmeter,  maar als je het vaak wilt aanpassen is misschien versie met as makkelijk?
- Misschien dc jack naar links laten uitkomen zodat het niet in de weg zit met eventuele heat sink?
- Ik denk dat ik 78xx zie? Je zou kunnen overwegen deze te vervangen door DC-DC converters. Maar goed,  met kleine modules zoals deze (http://www.aliexpress.com/item/Mini-360-DC-DC-Buck-Converter-Step-Down-Module-4-75-23V-to-1-17V-for/32436860547.html?ws_ab_test=searchweb201556_9,searchweb201602_2_10036_10035_301_10034_507_10032_10020_10001_10002_10017_10010_10005_10006_10011_10003_10021_10004_10022_10009_401_10008_10018_10019,searchweb201603_8&btsid=809cd01b-85ac-4be1-87f2-4da384696e9a) past het zelfs met dezelfde voetprint  ;D

Maar super bezig!  (y)


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 27 maart 2016, 12:47:05
Hoi Timo,

wat reacties en gebruik gemaakt van een tip van je uit een ander draadje.
Citaat
Enige wat ik alleen nog denk als ik de print nu zie:
- De rotary lijkt me nogal dicht op de Arduino te zitten. Misschien kan deze meer naar de buitenkant?
Dat had ik al op een eerdere versie uitgeprobeerd (zie afb.). De rotary's, die ik besteld heb, zouden ruim moeten passen.
(https://images.beneluxspoor.net/bnls/proefopstelling_papier.jpg) (https://images.beneluxspoor.net/bnls/proefopstelling_papier.jpg)

Citaat
- Weet niet wat je wilt instellen met de potmeter,  maar als je het vaak wilt aanpassen is misschien versie met as makkelijk?
Die is een beetje extra. Voor het testen is deze goed. Ik heb altijd wel een trimschroevendraaier klaar liggen. Als ik er een met een knop zou inzetten, kies ik waarschijnlijk voor een paneelpotmeter. Die moet dan toch met draadjes aangesloten worden.
Citaat
- Misschien dc jack naar links laten uitkomen zodat het niet in de weg zit met eventuele heat link?
- Ik denk dat ik 78xx zie? Je zou kunnen overwegen deze te vervangen door DC-DC converters. Maar goed,  met kleine modules zoals deze past het zelfs met dezelfde voetprint  ;D
Ik had in eerste instantie de jack naar links wijzen. Later bedacht ik  toch de DC_DC convertors te gaan gebruiken. Er zijn een aantal van  een groter model (http://nl.aliexpress.com/item/1pcs-LM2596-LM2596S-DC-DC-3-40V-adjustable-step-down-power-Supply-module-NEW-High-Quality/1116954291.html) onderweg.
Ik denk er twee staand op te zetten. Daar heb ik de maten van nodig en die heb ik nog niet gevonden. Dan kunnen de eico en 4 x 100nF condensator en de twee regelaars weg.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Fritsprt op 27 maart 2016, 12:54:34
Cees, mooi printontwerp!  Als ik het resultaat zie moet ik ook aan Kicad. Maar ik heb Eagle niet eens volledig onder de knie. Maar jouw resultaat mag er zijn na 3 weken je er in te hebben  verdiept.
 
Gr. Frits

Verstuurd vanaf mijn SM-G920F met Tapatalk

Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 27 maart 2016, 14:57:01
Nou Frits,

3 weken betekent bij mij 21 dagen met gemiddeld een uur of 4 de tijd voor die klus. Ik zou me er niet op verkijken. Achter KiCad steekt een wat andere filosofie dan Eagle. Vooral in de koppeling tussen schema- en printmodules. Dat is in KiCad duidelijk omslachtiger. Van KiCad vind ik mooi dat je tijdens het print maken af en toe naar een 3D-representatie kunt kijken hoe e.e.a. er bij benadering uit gaat zien. Dat heeft me veel geholpen met de opbouw van deze print.

@iedereen
Is er belangstelling voor het schema en/of printlayout?

groet  Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Fritsprt op 27 maart 2016, 15:09:39
Die 3D plaatjes zijn echt super mooi. Ik zelf blijf nog wel even met Eagle stoeien. ik ben wel nieuwsgierig naar het schema om te zien welke features je er in gebouwd hebt. Kunnen geïnteresseerden de print eventueel bij je bestellen?

Gr. Frits

Verstuurd vanaf mijn SM-G920F met Tapatalk

Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 27 maart 2016, 15:52:04
Dit is het schema. Je kunt het ook een paar posts terug lezen. Deze is wel heel erg gericht op mijn plannen met het baantje. Zoals in mijn reactie aan Timo zullen de 78xx regelaars nog vervangen worden door DC-DC converters. Dan gaat de print er nog anders uit zien.

(https://images.beneluxspoor.net/bnls/Schema_inglenook_print.png) (https://images.beneluxspoor.net/bnls/Schema_inglenook_print.png)

Ga ik de printjes verkopen? Nee, want ik heb geen zin in de rompslomp er om heen. Ik ga dit project wel op mijn eigen website zetten (nog geen link beschikbaar). Daar komen dan behalve plaatjes ook de Gerber-files, die ik ga gebruiken voor iTead, te staan.

groet Cees.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: tuurtje op 27 maart 2016, 16:52:17
Cees

Ik heb wel interesse in de bestanden, zal ze nog niet direct gebruiken, maar na de zomervakantie krijg ik hopelijk wat meer tijd

Groetjes

Arthur
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 29 maart 2016, 07:51:33
Hoi Cees,

Bedankt voor het posten van het schema, kan altijd veel duidelijk maken :)

De rotary's, die ik besteld heb, zouden ruim moeten passen.
Dat ze passen had ik ook niet anders verwacht  ;D Maar dat rotary aan de buitenkant iets toegankelijker zit.

Nog een paar dingen die me aan het schema opvallen
- 5v regulator zou je weg mogen laten, zit al op de Arduino
- Ik zou voor de LM311, de potmeter en Vcc out (bij de I2C) de Vcc van de Arduino gebruiken. Op die manier is de 7805/5V DC-DC alleen voor de servo en hou je alle storing gevoelige dingen op een nette losse voeding.
- R16 mag je weglaten. Deze zit al op de Pro Mini en zou zelfs de auto reset moeilijker kunnen maken
- R2 mag weg, float is volgens de data sheet een prima on-state
- R5 zou je kunnen vervangen door de interne pull up. Moet wel zeggen dat ik deze zelf ook gebruik omdat 10k iets krachtiger is dan de 30k-ish van de Arduino
- D3 en D4 zou je weg kunnen laten. Deze zitten al in de ULN2803
- De ledjes zou je kunnen voeden vanaf de 5V, scheelt vermogen

Maar goed, dit zijn allemaal minor puntjes  (y)


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 29 maart 2016, 11:32:38
Dag Timo,

wat reacties:
De rotary's hebben een vrij lange as en naar de rand brengen vond ik te lastig. Het is de vraag of die vaak voor zal komen. Dus op die plek laat ik hem maar.
Citaat
- Ik zou voor de LM311, de potmeter en Vcc out (bij de I2C) de Vcc van de Arduino gebruiken. Op die manier is de 7805/5V DC-DC alleen voor de servo en hou je alle storing gevoelige dingen op een nette losse voeding.
Kan ik het mee eens zijn, echter aan de i2c aansluiting komt mogelijk een LCD-display te hangen. Die lijkt me wat veel stroom trekken voor de 100 mA die de regulator op de APM kan leveren. En als je meer slaves er aan hangt, zonder eigen voeding en dat gaat vast gebeuren tijdens het testen, is dat ook niet zo bevorderlijk voor die regelaar.
R16 blijft, omdat ik de drukknop nog wil verhuizen naar een andere pin (RXI). De reset is door de opzet van deze print goed bereikbaar op de APM. R2 blijft onder het motto "baat het niet, het schaadt ook niet.
D3 en D4 blijven, want dicht bij de relais en dus geen tegen EMK door een dun spoortje naar de ULN. Hier ben ik in het verleden wel eens tegen aan gelopen.
Citaat
- De ledjes zou je kunnen voeden vanaf de 5V, scheelt vermogen
Ik heb die samen met de relais op 12v gezet om de  5 V te ontzien. Zeker als je 2 regelaars achter elkaar zet leek me dat handiger. Voorts met de DC-DC-converters zullen ze beide apart uit de ingang gevoed gaan worden. Overigens: het scheelt geen vermogen, het wordt alleen op een andere plek verstookt.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 29 maart 2016, 15:21:54
@Cees Baarda:
Citaat
De rotary's hebben een vrij lange as en naar de rand brengen vond ik te lastig.
Als je er zo mee kunt werken dan (y) Was maar iets wat in mijn hoofd op kwam.

Citaat
Kan ik het mee eens zijn, echter aan de i2c aansluiting komt mogelijk een LCD-display te hangen. Die lijkt me wat veel stroom trekken voor de 100 mA die de regulator op de APM kan leveren.
Als je inderdaad denkt dat het zal voorkomen dan inderdaad aan losse regulator hangen. Maar het blijft staan voor de LM311 en de potmeter. Hou je de noise van de servo lekker weg bij de analoge readings.

Citaat
R16 blijft, omdat ik de drukknop nog wil verhuizen naar een andere pin (RXI). De reset is door de opzet van deze print goed bereikbaar op de APM.
Deze snap ik even niet. Reset is toch reset? Wat heeft dat te doen met de RXI/pin1?

Twee extra dingen die ik nu gewoon opeens bedenk:
- Waarom überhaupt een reset? Die op de Pro Mini zelf is hier ook prima bereikbaar
- Gebruik maar een van de twee Arduino RST pinnen. Zo heb je geen loop en het scheelt je een printspoor.

Citaat
R2 blijft onder het motto "baat het niet, het schaadt ook niet.
Dat is wel een beetje een kul reden...  ;) Als je helemaal niets meer aan de print gaat doen snap ik het. Dan kan je hem met solderen gewoon weg laten. Maar als je toch nog gaat aanpassen kan je nutteloze componenten best weglaten toch?

Maw, het is jouw print, jij beslist. Gaat me hier vooral om de reden waarom  ;) (Lees me opmerking dus niet te kwaad....  ;D )

Citaat
D3 en D4 blijven, want dicht bij de relais en dus geen tegen EMK door een dun spoortje naar de ULN. Hier ben ik in het verleden wel eens tegen aan gelopen.
Okay, prima reden.

Ook al moet ik wel zeggen dat ik er nooit tegenaan gelopen ben. Zeker omdat het vermogen van de tegen EMK stukken lager is dan normale relais stroom. En de stroom is miniem vergeleken met de normale stroom. Het probleem zit hem alleen in het voltage.

Citaat
Ik heb die samen met de relais op 12v gezet om de  5 V te ontzien. Zeker als je 2 regelaars achter elkaar zet leek me dat handiger. Voorts met de DC-DC-converters zullen ze beide apart uit de ingang gevoed gaan worden. Overigens: het scheelt geen vermogen, het wordt alleen op een andere plek verstookt.
Ik ging hierbij uit van DCDC, dan scheelt het wel vermogen. Lineair is het inderdaad om het even.  ;D


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 29 maart 2016, 16:26:13
Dag Timo,

ik ben niet snel over de rooie te krijgen  :D. Bovendien verschillen van mening zullen er altijd zijn.
Citaat
Deze snap ik even niet. Reset is toch reset? Wat heeft dat te doen met de RXI/pin1?
Daar was mijn tekst duidelijk te kort. Ik miste nog een extra toets om in program-modus te kunnen gaan. Dat is die druktoets inmiddels geworden. R16 kan dan ook wel weg. Wat je verderop zegt over de resettoets is helemaal waar.
Citaat
Als je inderdaad denkt dat het zal voorkomen dan inderdaad aan losse regulator hangen. Maar het blijft staan voor de LM311 en de potmeter. Hou je de noise van de servo lekker weg bij de analoge readings.
Daar heb je een punt, moet ik nog maar even over nadenken  (y). Zou ik weleens kunnen gaan aanpassen.

Over R2 hebben we al eens eerder gediscussieerd. Ik heb intussen gevonden waar ik die "wijsheid" vandaan heb. Hans Kufer (OpenDCC (http://opendcc.de) bij Dekoder: beschrijving werking hardware 1) zegt hierover: Pin 7 van de 6N137 (enable ingang) moet met Pin 8 verbonden worden (= VCC). Ergens logisch, immers bij een NAND-poort wil je gedefinieerde toestanden voor 1 en 0. Een weerstand tussen die 2 kan geen kwaad. Je zou dan zelfs de datastroom naar de micro kunnen stopzetten, door Enable laag te trekken. Of je in deze toepassing daar wat aan hebt??
Er stond nog wel een aardige tip: als je D1 vervangt door een LED heb je wat indicatie van de DCC activiteit.

Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 29 maart 2016, 19:47:52
Citaat
ik ben niet snel over de rooie te krijgen  :D.
Gelukkig! ;D Maar zet het er meestal toch even bij op het forum. Voor je het weet vatten mensen het anders negatief op terwijl ik alleen mijn gedachten over de print heb laten gaan.

Citaat
Daar was mijn tekst duidelijk te kort. Ik miste nog een extra toets om in program-modus te kunnen gaan. Dat is die druktoets inmiddels geworden. R16 kan dan ook wel weg. Wat je verderop zegt over de resettoets is helemaal waar.
Ahhhh, dat verklaard!  (y)

Citaat
Daar heb je een punt, moet ik nog maar even over nadenken  (y). Zou ik weleens kunnen gaan aanpassen.
Zou anders zonde zijn als je readings schommelen door de servo.

Citaat
Over R2 hebben we al eens eerder gediscussieerd. Ik heb intussen gevonden waar ik die "wijsheid" vandaan heb. Hans Kufer [knip] Je zou dan zelfs de datastroom naar de micro kunnen stopzetten, door Enable laag te trekken. Of je in deze toepassing daar wat aan hebt??
Ah, dat was ik al weer vergeten. ::) Maar hard aan Vcc of via een pull up kan inderdaad geen kwaad. Maar volgens de truth tabel en het test circuit van de datasheet mag deze dus weggelaten worden. Was dus vooral bedoelt als opmerking dat je dus een onderdeel kon besparen. Niet dat een weerstand veel kost, meer voor de ruimte en ontwerp/montage tijd.

Citaat
Er stond nog wel een aardige tip: als je D1 vervangt door een LED heb je wat indicatie van de DCC activiteit.
Dat kan inderdaad makkelijk. (y) Maar bedenk wel dat het best een fel ledje kan worden  ;D Op een DCC signaal van 20V heb je namelijk +-12mA door het ledje, aardige schijnwerper bij moderne ledjes (waar 1mA al prima is voor een indicatie led).


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Patrick Smout op 29 maart 2016, 22:10:31
Citaat

Ook al moet ik wel zeggen dat ik er nooit tegenaan gelopen ben. Zeker omdat het vermogen van de tegen EMK stukken lager is dan normale relais stroom. En de stroom is miniem vergeleken met de normale stroom. Het probleem zit hem alleen in het voltage.
Timo
De maximale (beginwaarde van de) stroom door de flyback diode is net zo groot als de voorwaartse stroom. De maximale inverse spanning is de spoelspanning die over het relais staat op het ogenblik dat het relais afvalt.

mvg,

Patrick Smout
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 30 maart 2016, 14:04:01
Wat betreft de stroom moet ik je volledig gelijk geven, deze zal inderdaad gelijk zijn als de normale stroom. Daar deed mijn tekst inderdaad te kort.  ::) Ik doelde er op dat de stroom alleen maar kleiner wordt dan in normaal bedrijf.

Wat betreft de spanning heb je het alleen bij het verkeerde eind. Als dat het geval was dan zou het in veel gevallen geen probleem opleveren omdat 2x de normale spanning of negatief de spanning geen probleem zou zijn voor transistoren. Maar zodra de transistor uit is bestaat er nog amper een last voor de spoel, het voltage zal daarom veel hoger liggen. Welk voltage er dus ontstaat is volledig afhankelijk van de last die er nog aan de spoel hangt. Bij een diode is dit bijna een harde sluiting.

Dat is ook de hele werking waar een DC-DC boost converter op werkt :) Vandaar dat je met gemak 12V van je 4V LiPo kunt maken. Ik heb voor VFD's en Nixies wel eens een simpele step up gemaakt met een 555 om van 12V naar 50V of 200V te gaan. Prima te doen  ;D


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Patrick Smout op 30 maart 2016, 21:47:41
Timo,

de inverse spanning over het relais met flyback diode is gelijk aan de relais spanning net voor het afschakelen. Zonder flyback diode is de spanning uiteraard vele malen hoger. De diode zorgt ervoor dat de kring gesloten wordt. Als de stroom die vloeit in de gesloten kring op het moment van het afschakelen gelijk is aan de stroom net voor het afschakelen en de belasting ongewijzigd is (weerstand van het relais) dan kan de spanning niet anders dan dezelfde zijn. Zonder flyback diode is de kring open waardoor de spanning vele malen hoger is (energie die in de spoel opgeslagen is probeert er dan voor te zorgen dat er een zelfde stroom gaat vloeien door een weerstand die quasi oneindig is).
Er zullen altijd kleine verschillen zijn door onvolkomenheden in de componenten maar verder valt het wel mee.

mvg,

Patrick

 
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 01 april 2016, 10:04:13
Hoi Patrick,

Ook daar ben ik het niet met je eens. De spanning wordt nu volledig bepaald door de VI-curve van de diode. De belasting is namelijk niet hetzelfde. Enige wat de stroom in stand wil houden is het ideale deel van de spoel. Maar een echte spoel heeft ook nog een serie weerstand (niet letterlijk maar als je de spoel zou willen modelleren) die best een grote rol speelt. Zonder serie weerstand zou immers de stroom niet beperkt zijn in normaal bedrijf.
(http://www.geopodium.com/files/Craig/inductormod.gif)

Maar goed, we zijn een beetje een draadje aan het vervuilen ::) Sorry Cees! :angel: Dit is het laatste wat ik er dus hier over wil posten. Willen we het er verder over hebben moeten we maar een nieuw topic starten  ;D


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 06 april 2016, 12:13:31
Vandaag weer eens een update.
Baantje uit post #12 in elkaar gezet en deels gesloopt en weer opgebouwd.
Het baanplan zier nu zo uit (totale maten 160 x 30 cm, spoor N):
(https://images.beneluxspoor.net/bnls/inglenook_rails1.jpg) (https://images.beneluxspoor.net/bnls/inglenook_rails1.jpg)

Met de onderbouw is het mogelijk om nog een bakje rechts te maken. Die moet dan gaan dienen als fiddleyard. Ik ben er nog niet uit of ik de hoek om zal gaan of toch maar rechtuit. In mijn huidige hobbyplek is rechtuit makkelijker. Maar ja, er zit een verhuizing naar een gelijkvloers huis in het achterhoofd. Dan kan ik misschien wel de baan in een hoek gaan zetten.
De roze plakkertjes geven de ruimte aan die nodig is voor, van onder naar boven, 3, 3 en 5 twee-assige wagentjes.

De onderkant is ook niet veel van over:
(https://images.beneluxspoor.net/bnls/inglenook_onder1.jpg) (https://images.beneluxspoor.net/bnls/inglenook_onder1.jpg)

Bedraden zal nog wel even gaan duren, want ik ben nog steeds bezig met het te gebruiken printje. In een volgende post daar meer over.

groet Cees.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 06 april 2016, 14:38:00
Zoals net gezegd; ook het printje wordt nog aan gewerkt en gedacht. De 2e incarnatie ziet er als volgt uit.
(https://images.beneluxspoor.net/bnls/inglenook_print2.jpg) (https://images.beneluxspoor.net/bnls/inglenook_print2.jpg)

Nu vind ik, die 2 dc-dc converters eigenlijk een beetje groot. Timo had het al over kleinere, maar deze heb ik inmiddels binnen (van AliExpress, 10 dagen levertijd, ze worden sneller). Die dingen kunnen meer leveren dan noodzakelijk voor 1 zo'n printje. Ik heb daarom bedacht om de hele voeding weg te halen en te vervangen door een input connector en 2 diodes (om verkeerd aansluiten geen schade te laten veroorzaken). Dan kan ik het baantje voeden met 1 setje DC-DC-converters en een oude laptopvoeding van 19V en ongeveer 4 Amp.

Ik ga e.e.a. nu maar eens aanpassen.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 14 april 2016, 12:39:18
Dag allemaal,

De print voor de Arduino-taken gaat nog veranderen zei ik al in mijn vorige post. Omdat daarbij het voeding gedeelte extern wordt, heb ik eerst een voedingenprint bedacht en bij iTead besteld. Die gaat 2 vaste voedingen bevatten voor resp. 5 en 12 volt en - omdat er tocht wat ruimte over bleef een derde, die regelbaar kan zijn (zie de afbeelding).
Het geheel ga ik voeden uit een laptopvoeding. Ik heb de print zo gemaakt, dat die ook op beide spanningsrails van een breadboard kan worden geprikt. Verder zitten er losse schroefconnectoren op en een 10-polige header voor de verbinding naar de Arduino-prints. Door deze opbouw kan ik er 1 speciaal voor dit project maken en 1 voor op mijn breadboard. Een derde zal in een behuizing komen, zodat ik die als een soort labvoeding kan meenemen naar HCC!m-bijeenkomsten. Ieder van de drie toepassingen maakt gebruik van andere aansluitingen op de print.
(https://images.beneluxspoor.net/bnls/voedingen.png) (https://images.beneluxspoor.net/bnls/voedingen.png)

Later op de dag nog een update over de APM-printjes.

groet Cees.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: gvandersel op 14 april 2016, 14:18:39
Cees,

Help eens. Ik zie drie "power" diodes. Een of vier zijn te verwachten aantallen. Dus hoe zit dit?

Groet,

Gerard van der Sel.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Reinout van Rees op 14 april 2016, 14:49:26
Vraagje over die itead.cc printplaatjes: zie ik dat nou goed en is het nog geen tientje voor 10 plaatjes van 5x5 cm? Ik had gedacht dat custom printplaatjes maken alleen interessant was vanaf 100 stuks of zo iets. Maar dit is andere koek.

Ik werk normaliter met kleine experimenteerprintplaatjes. Arduino, 7805, paar weerstandjes en misschien een mosfet, dan heb je het ook wel weer gehad. Maar voor grotere aantallen is dit is waar ik aan ga denken!

Reinout
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 14 april 2016, 16:22:09
@Reinout, dat zie je goed. Nu moet ik wel zeggen dat ondanks dat het China is er nog iets aan verzendkosten bij komt. Als totaal zit je dan op iets van €15,- (exact zie je pas na het in je winkelwagen te hebben enz). Dus ja, PCB's voor prototypen is tegenwoordig een heeeeeeel stuk aantrekkelijker geworden  ;D


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 14 april 2016, 20:24:23
@Reinout
Je hebt al antwoord van Timo. Deze printjes zijn 10 x 5 cm en hebben me vandaag 19,52 euro gekost. Dat was totaal $ 21,33 ($ 14,90 voor de prints en $ 6,43 verzendkosten). Het bedrag in euro's berekent PayPal met dagkoersen.

@Gerard
Lastig he, zonder schema. Ik sluit dingen niet graag verkeerd aan. De diodes zijn daar alleen een rem voor. Waarom dan drie? Omdat iedere module in staat is 3 Amp te verstouwen heb er 1 per dc-dc-converter op gezet. Zelfs de printbanen naar de diodes heb ik apart naar de diodes gevoerd.
Als de printen in goede orde zijn aangekomen (duurt een dag of 10), dan ga ik alles daarvoor (KiCad-files en gerber-pakketje) op mijn eigen website zetten.

Belofte maakt schuld; dus ook een update van de APM-printen (onderaan de afbeeldingen)
Wat zit er op?
Voor een beter zicht op de print de RJ12 connectors en de rotary-encoder weggelaten
Blauwe headers - Arduino Pro Mini - mijn versie heeft A4 en A5 op de plek van de 2-pol header
Linksboven een drukknop - samen met de drukknop van de encoder heb je dan 2 druktoetsen
Links in het midden DCC-in - met 2 schroefconnectoren of via J1 (LocoNet B bijv. waarbij alleen het DCC-signaal is aangesloten)
Helemaal links vooraan - i2c aansluiting
Daarnaast DCC-out - alleen 2 schroefconnectoren
Dan 1 servo
Midden voor J2 en J3 - LocoNet in/out met de jumper rechts kun je 12 Volt op de connectors zetten
4 LED's rechts van het midden - Bedoeld voor een sein, als je Nederlands denkt een sein met een extra licht (lichtbak of rangeersein)
Rechts van boven naar beneden
Grijze header en wit blok - 2 relais - welke er in kunnen laat ik een volgende keer zien
Instelpotmeter - iets voor een analoge ingang, ga ik o.a. max. snelheid mee instellen
2 LED's blauw en wit - Nog geen bestemming, maar denk aan programmeermode aangeven o.i.d.
Encoder E1 - eindeloze draaiknop met drukschakelaar, kun je ook iets instelachtigs mee gaan doen
Rechts onderaan Power Input - haalt spanningen van die andere print

Waarom nou al die mogelijkheden?
iTead levert je 10 printen, als je een prototype stuurt. Voor de Inglenook baan heb ik wat verschillende dingen nodig. Die heb ik op 1 print proberen te zetten.
Welke taken krijgen de losse printjes:
1 - rijregelaar, waar ik een BNLS-boosterHub op ga aansluiten.
2 - wisselsteller, met puntstuk-omschakeling (heb er voorlopig 2 nodig)
3 - ontkoppelaar aansturen (worden er 3)
4 - sein(en) (voorlopig 1, later indien gewenst meer)

Misschien is het wat overkill en had het slimmer gekund. Dit was echter ook een goede oefening om KiCad (http://kicad-pcb.org) beter te leren kennen en zelf wat 3D-componenten te maken met FreeCad (http://www.freecadweb.org) en Wings (http://www.wings3d.com). De weerstanden, diodes, headers en LED's heb ik zo gebouwd.

groet Cees

3D representatie van de print in wording
(https://images.beneluxspoor.net/bnls/print_inglenook_def.png) (https://images.beneluxspoor.net/bnls/print_inglenook_def.png)

en het schema van het geheel
(https://images.beneluxspoor.net/bnls/schema_def.png) (https://images.beneluxspoor.net/bnls/schema_def.png)
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 14 april 2016, 21:01:56
Ziet er goed uit Cees! Netjes led_groen (waar je volgens mij nu wit of blauw mee bedoelt  ;D) aan Tx, zo geeft het inderdaad geen problemen met programmeren. Enige nadeel is dat je geen Serial voor het debug kunt starten. Of ja, dat kan wel, maar niet tegelijk met led_groen/drukknop in een functie. Nouwja, je kan niet alles hebben ::)

Nog twee vraagjes:
-Waar gaat DCC_out_inv heen?
-Waarom voer je juist de onversterkte versie van de ledjes uit en niet pas achter de ULN?


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 14 april 2016, 22:07:05
Ja Timo,

onderweg van gedachten veranderd en LED-groen blauw gemaakt net als Led rood nu wit is. Eigenlijk om onderscheid te houden met de "sein"-LED's

DCC_out_inv gaat nergens heen. Was meer een geheugensteun. De library CmdrArduino gebruikt die pin om een geïnverteerd DCC-signaal op te zetten. Dat gebruik ik niet, maar de pin wordt natuurlijk wel aangestuurd.

Die header voor de 2803 is bedoeld voor input aan de APM. Het zijn alle digitale poorten. Zo kan ik ze multifunctioneel inzetten. Mocht ik de LED's buiten de print willen, dan zet ik headers op de plek van de LED's op de print en dan zijn ze netjes gebufferd. Bijkomend voordeel de LED's na de 2803 kunnen dan wat terugkoppeling geven bij gebruik als input voor de APM.

groet Cees.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 15 april 2016, 10:37:31
DCC_out_inv gaat nergens heen. Was meer een geheugensteun. De library CmdrArduino gebruikt die pin om een geïnverteerd DCC-signaal op te zetten. Dat gebruik ik niet, maar de pin wordt natuurlijk wel aangestuurd.
Ah, kijk. Maar als je niet wil dat dit signaal naar buiten komt kan je dit natuurlijk aanpassen. Misschien is het inderdaad niet zo makkelijk in de library zelf (of moet je die echt aanpassen) maar een mooie manier van valsspelen is pin A7 opgeven. Als eerste heb je deze niet en als tweede is deze puur analoog. Elke poging tot digitaal aansturen gaat gewoon verloren zonder error  ;D

Die header voor de 2803 is bedoeld voor input aan de APM. Het zijn alle digitale poorten.
Ah, kijk. Je zou eventueel ook nog een header op de uitgang kunnen doen, ben je helemaal multifunctioneel. Iig makkelijker dan een losse 2 pin header per led.

En wat ik zelf zou doen is denk ik dan proberen de boel wat te schuiven en dan een 2x9 header (1 rij voor ULN, 1 rij na ULN) aan de rand van het bord maken zodat kabels wat makkelijker af te voeren zijn. Misschien wat gepuzzel met routen maar lijkt nog wel te passen. maar goed, dat ben ik  ;D


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 15 april 2016, 11:38:48
DCC_out_inv:
In de library veranderen is wat minder, want daar worden de pennen benoemd als PB1 e.d. op de standaard Atmel-manier. Dat uitzoeken heb ik nu niet zo'n zin in. Er staat ook de nodige machinecode in, wie weet wat je dan over het hoofd ziet. De bedoeling is overigens, dat "rijregelaar" een aparte print wordt, waarbij ik kan voorkomen, die pin te benutten. Nu zit Pin 10 aan een LED, die laat dan vast wel iets zien van DCC-out_inv.

Nog een header bij de ULN2803:
Dan krijg je zoiets als op deze print:
(https://images.beneluxspoor.net/bnls/IMG_0168_10.jpg) (https://images.beneluxspoor.net/bnls/IMG_0168_10.jpg)
de ULN2803 zit bij de Inglenook-print al bijna aan de rand, dus als je een klein strokenprintje met headers (een soort steker) maakt, kun je mooi met je snoertjes weg. De ruimte is er wel voor. Goede suggestie  (y) maar ik heb het nu (nog?) niet nodig. Daarmee heb je ook de mogelijkheid de LEDjes op een opsteekprintje te zetten. Dat schiet nu mijn doel wat voorbij. Op die ODC-print heb ik het weleens gebruikt om de ULN2803 te vervangen door 8 darlington transistoren.

Ik had nog een tweede doel voor de print in mijn achterhoofd. In deze opbouw is hij m.i. heel geschikt om allerlei libraries op 1 print te testen. De eerste die ik zelf er op wil zetten zijn de AdServo, de MarDec en die andere leuke projecten hier bij BNLS. Daar waar in deze projecten het vaak om meer van hetzelfde gaat is het best wel mogelijk dat te vertalen in 1 item.

groet Cees.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 17 april 2016, 17:10:51
In post #46 iets gezegd over de relaisposities. Ik maak veel gebruik van 2 typen relais, zie foto:
(https://images.beneluxspoor.net/bnls/2_relais_cb.png) (https://images.beneluxspoor.net/bnls/2_relais_cb.png)
Ze zijn natuurlijk niet pin-compatibel, maar het bleek wel mogelijk het zwarte relais op pennen van een 16 polige IC-voet te zetten die niet door de blauwe gebruikt worden. Op de afbeeldingen zie je: enkelpolig relais,
(https://images.beneluxspoor.net/bnls/relais_1polig_klein.png) (https://images.beneluxspoor.net/bnls/relais_1polig_klein.png)
dubbelpolig relais en
(https://images.beneluxspoor.net/bnls/Relais_2polig_klein.png) (https://images.beneluxspoor.net/bnls/Relais_2polig_klein.png)
beide samen.
(https://images.beneluxspoor.net/bnls/relais_samen_klein.png) (https://images.beneluxspoor.net/bnls/relais_samen_klein.png)
De laatste heb ik gebruikt op de print. E.e.a. heb ik zo bedraad, dat je achteraf nog kunt besluiten welk relais je wilt gaan gebruiken. Zeker in de oefen- en probeerfase is dan het gebruik van een IC-voet voor de relais een handige oplossing.
Er horen natuurlijk ook schema-symbolen bij.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Fritsprt op 17 april 2016, 18:54:34
Heel slim....

Verstuurd vanaf mijn SM-G920F met Tapatalk

Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 03 mei 2016, 17:17:35
Een update mag zo zachtjes aan wel weer.

Het printontwerp van de besturing heb ik nog niet opgestuurd naar iTead (http://www.itead.cc). Ik wacht nog even af of de voedingenprint in de gewenste vorm aan komt. Tijdens de wachtperiode begonnen met het programmeren van een rijregelaar. Die is zo ongeveer af. Van de werking heb ik een filmpje gemaakt.
Hij staat hier (https://youtu.be/Q9-6O8C-Nyc).

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 10 mei 2016, 11:38:44
Net na mijn post vorige keer, kwam een pakket melding aan. Naar het postagentschap geweest om de verrassing op te halen. De prints zien er weer goed uit. Gelijk maar eens aan het bouwen geslagen en 3 prints bestukt in verschillende varianten, zie de foto.
Bij het opbouwen van de versie voor de baan ontdekt dat een schroefconnector bij de voeding-ingang ook wel handig was geweest. Ga ik aanpassen in het printontwerp, dat beschikbaar gaat komen.
De foto laat ook de volledige proefopstelling zien voor het testen van de Arduino-software (rijden met drukknoppen, zie filmpje uit vorige post). De Arduino geeft op pin 9 een DCC-signaal af dat naar de BNLS/RCU Boosterhub gaat. Deze combinatie is eigenlijk niet meer dan een "DCC_trafo" voor de locomotief. Het geheel wordt nu gevoed met een laptopvoeding van 3,5 Amp 19 Volt en rijdt voor mijn gevoel naar behoren.
De definitieve versie van de Inglenook print gaat binnenkort naar China.

groet Cees
(https://images.beneluxspoor.net/bnls/20160509_proefopstelling.png) (https://images.beneluxspoor.net/bnls/20160509_proefopstelling.png)
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 11 mei 2016, 11:49:25
Ziet er allemaal weer mooi uit! En ja, voor power zijn schroefconnectoren altijd wel makkelijk :)


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 13 mei 2016, 14:34:33
Dag allemaal,

Wat nu nog ontbreekt is de gebruikte code voor de rijregelaar. Die vind je verderop.
Inmiddels zijn de Gerber-files voor de "Inglenook"-print naar iTead. Ik verwacht ze met een week of 3 te hebben.
Dan wordt het nu tijd mijn eigen website te gaan aanpassen en downloads te maken van prints en deze software. Zodra er iets substantieels staat zet ik hier een link.

groet Cees.

En dan nu de firmware. Ik gebruik de libraries:
CmdrArduino van Railstars (http://railstars.com/software/cmdrarduino)
Bounce2 van Thomas Fredericks (http://github.com/thomasfredericks/Bounce2/wiki)
en de standaard EEPROM van Arduino (http://www.arduino.cc/en/Reference/EEPROM)
#include <DCCPacket.h>
#include <DCCPacketQueue.h>
#include <DCCPacketScheduler.h>

#include <Bounce2.h>
#include <EEPROM.h>
Bijna bovenaan kun je van 4 loks korte adressen invoeren.
Mocht je voor lange adressen willen gaan, dan moet je onderweg een andere aanroep doen om de snelheid in te stellen.
Bovendien worden dan de constanten van het type int.
/* * * * * *
 * 4 lok-adressen invoeren. Deze zijn te kiezen m.b.v. een bcd-schakelaar of 2 jumpers.
 * De adressen mogen alleen korte adressen zijn (1..127)
 */ 
const byte lok1 = 99;
const byte lok2 = 3;
const byte lok3 = 3;
const byte lok4 = 25;
/* Einde lokadressen  invoeren */

byte lok[] = {lok4, lok3, lok2, lok1};
byte lokAdres;
byte lokIndex;
Rest van variabelen aanmaken.
DCCPacketScheduler dps;
char speed_byte, old_speed = 0, snelheid = 1;
byte prev_state = 0;
byte F0 = 0;

/* * * * * *
 *  Drukknoppen voor de besturing;
 *  DK_xxx = de gebruikte Arduino pin */
const byte DK_Vooruit = 3;    // Drukknop vooruit
const byte DK_Achteruit = 4;  // Drukknop achteruit
const byte DK_Stop = 5;       // Drukknop stop

const byte Knoppenlijst[] = {DK_Vooruit, DK_Achteruit, DK_Stop};
  // * Geef de posities in het array een naam
  const byte Vooruit = 0;
  const byte Achteruit = 1;
  const byte Stop = 2;
 
#define Aantal_Knoppen sizeof(Knoppenlijst)
// * * * * Einde Drukknoppen voor de besturing

const byte Speed_Potm = A0;   // Instelling max. snelheid

Bounce Knoppen[Aantal_Knoppen] = Bounce();

const byte Arduino_LED = 13;

void setup()
{
  Serial.begin(115200);   // voor debug, we gebruiken Pinnen 0 en 1 niet voor iets anders
  dps.setup();            //start de DCC packet schedular
  pinMode(Arduino_LED, OUTPUT);
  digitalWrite(Arduino_LED, LOW);
  /* * * * * * *
   * setup knoppen voor debounce
   */
    for (byte i = 0; i < Aantal_Knoppen; i++)  Knoppen[i].attach(Knoppenlijst[i], INPUT_PULLUP);
  // * * * * Einde setup knoppen
 
Er zijn 2 input pins, die bepalen met welk lokadres gereden gaat worden.
Je kunt daar jumpers op gebruiken maar bijv. ook een BCD-schakelaar.
De gedachte daarbij is, dat je meestal maar 1 lok gebruikt bij zo'n rangeerpuzzel.
Deze keuzemogelijkheid geeft je een vooraf ingestelde reserve lok voor als je met een baan op pad zou zijn.
  /* * * * * * *
   *  Kies huidige locomotief
   *  Aan de pinnen A1 en A2 komen voor dit programma 2 jumpers naar massa.
   *  Zonder jumpers krijgt lokIndex de waarde 3. De jumpers verlagen de waarde met resp. 1 en 2.
   *  Dus beide jumpers geplaatst geeft lokIndex de waarde 3 - 1 - 2 = 0.
   * 
   *  Als het programma eenmaal loopt kun je niet meer van DCC-adres wisselen.
   *  Hiermee voorkom je eventuele 'missers' op bijv. een tentoonstelling.
   */
     pinMode(A1, INPUT_PULLUP);
     pinMode(A2, INPUT_PULLUP);
     lokIndex = digitalRead(A1);                // index wordt 0 of 1
     lokIndex = lokIndex + 2 * digitalRead(A2); // index krijgt er 0 of 2 bij
     lokAdres = lok[lokIndex];
  // * * * * Einde kies locomotief
Ik heb er voor gekozen alleen bij het opstarten in programmeermodus te gaan.
Dit heeft het voordeel, dat je tijdens het gewone gebruik dat niet per ongeluk kunt doen.
Je stelt dan de max. snelheid van de huidige lok in. Die wordt op de juiste plek in EEPROM bewaard.
   
  if (digitalRead(DK_Vooruit) == 0)     // werd de knop ingedrukt gehouden
  {
    stel_snelheid_in();                 // stel dan de max. snelheid in
  }
  speed_byte = EEPROM.read(lokIndex);
  snelheid = 1;
  Serial.println(speed_byte, DEC);
//  if (speed_byte == 0 or speed_byte > 127)  stel_snelheid_in();
}

void loop()
{
  /* * * * * * *
  *  Knoppen afhandelen
  *  Als 1 van de knoppen gedrukt wordt, gaat de trein rijden met de ingestelde snelheid of
  *  wordt er gestopt.
  *  Er zijn 3 knoppen: Vooruit - Stop - Achteruit */
  for (byte i = 0; i < Aantal_Knoppen; i++)
  {
    Knoppen[i].update();
  }
  if (Knoppen[Stop].fell())
  {
    if (snelheid > 0) snelheid = 1;
    if (snelheid < 0) snelheid = -1;
  }
  if (Knoppen[Vooruit].fell())
  {
    if (snelheid < -1) snelheid = -1; else snelheid = speed_byte;
  }
  if (Knoppen[Achteruit].fell())
  {
    if (snelheid > 1) snelheid = 1; else snelheid = -speed_byte;
  }
  /* Einde knoppen afhandelen */
 
  Serial.print("Ingestelde snelheid: ");  // debug
  Serial.println(snelheid, DEC);          // debug
  dps.setSpeed128(lokAdres,DCC_SHORT_ADDRESS,snelheid); // zet de gekozen snelhied klaar
  dps.update();                                         // en voer uit naar DCC-booster
}

void stel_snelheid_in()
{
  Knoppen[Stop].update();
  while (!Knoppen[Stop].fell())
  {
    digitalWrite(Arduino_LED, HIGH);
    int analoge_waarde = analogRead(0);
    speed_byte = (analoge_waarde >> 2)-127 ;  // deel door vier en breng naar -126 tot 126 reeks
    if(speed_byte == 0)
    {
      if(old_speed > 0) speed_byte = 1;
      else speed_byte = -1;
    }
    old_speed = speed_byte;
    dps.setSpeed128(lokAdres,DCC_SHORT_ADDRESS,speed_byte);
    dps.update();
    Knoppen[Stop].update();
  }
  if (speed_byte < 0) speed_byte = -speed_byte;
  EEPROM.write(lokIndex, speed_byte);
  delay(500);                             // wacht tot zeker is dat EEPROM beschreven werd             
  digitalWrite(Arduino_LED, LOW);
}
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: RudyB op 15 mei 2016, 09:37:14
Cees, dit is een hartstikke leuk project geworden met ongetwijfeld vele uren hobbyplezier (en hopelijk niet al te veel frustratie momenten).

Als het klaar is ... is dan software die elke Inglenook puzzel kan oplossen, gekoppeld aan automatische besturing van jouw apparatuur, het volgende project?

Wie weet is dat een aardige prijsvraag voor de eerste te organiseren 'BNLS Arduino Hackathon'? (Hint voor het forum bestuur.) :)
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 15 mei 2016, 14:26:32
Dankjewel Rudy,

Hobbyplezier was het zeker. Frustratie viel wel mee; dat had ik meer met mezelf, omdat je wel eens semantische fouten maakt (de micro deed wat ik vroeg te doen en niet wat ik bedoelde). En ook als ik software niet snel onder de knie krijg, omdat ik de filosofie er achter nog niet helemaal door heb.

Het volgende project wordt zeker niet automatiseren van het puzzelen. Mijn bedoeling is en was een puzzelbaantje te maken, waarbij de speler het rangeerwerk zelf moet doen. Mijn locomotieven zijn alle digitaal, dus een gewone trafo voor het rijden is niet de mooiste oplossing. Verder gebruik ik servo's voor de wissels en ontkoppelrail(s). Daar moet dan ook een vorm van sturing voor zijn. De verschillende oplossingen hier op BNLS hadden net niet wat ik wilde hebben. Daarom toch een eigen servo-controller. Die is overigens wel gebaseerd op de libraries bij de AdServo (http://forum.beneluxspoor.net/index.php/topic,61213.0.html) van Timo E.

Wat ik wel zou willen proberen; is een programmaatje maken met Processing (http://www.processing.org) om te communiceren met de Arduino via USB. Daarbij denk ik vooral aan instellen van servostanden, snelheden en andere variabelen. Waarom Processing? Arduino is hier op gebaseerd. Ook multiplatform en open source. En de opzet van de IDE lijkt heel erg op elkaar.

Zo'n Hackathon is misschien best leuk initiatief.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Raages op 15 mei 2016, 15:07:06
Een mooi en interessant project, te meer daar ik zelf ook een rangeer project probeer te bouwen. Dat idee van de rangeerpuzzel "Inglenook" zat er al in, maar ga ik nog wat meer de nadruk op leggen. Je wordt door mij gevolgd Cees.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 17 mei 2016, 19:31:23
Hoi Cees,

Ziet er goed uit!  (y) Documentatie is altijd fijn :) Zou ik je toch een paar tips mogen geven? Zie het vooral dus niet als negatief iets maar puur als hulp!  (y)

if (snelheid < -1) snelheid = -1; else snelheid = speed_byte;
Van die regel gaan mijn rugharen een beetje overeind staan  ;D Voor de leesbaarheid, regels eindigen na de ;. Omdat het een simpel statement is zou je er wel een one line'er van kunnen maken maar dan als:
(snelheid < -1 ? snelheid = -1: snelheid = speed_byte);
Maar meestal gaat mijn voorkeur toch gewoon uit naar voluit omdat het vaak duidelijker is en makkelijker uit te breiden.

Overigens, wil je daar niet van richting veranderen als je op de andere richting drukt? Dus:
if (snelheid < -1)
  snelheid = 1;
else
  snelheid = speed_byte;
Dus als hij achteruit rijdt en je druk op vooruit wel de richting omdraaien maar niet rijden.

Dan een blokje variabele namen (klinkt heftig, bedoel het goed!)
Als eerste je naamgeving. Goed, het staat je vrij om een bepaalde schrijfstijl te gebruiken, dat is verder geen punt. (Standaard in C is camelCase, en dat gebruik je soms opeens ook. Probeer voor één stijl te gaan.) Maar niet alle variabele namen zijn altijd even duidelijk. Nu weet jij dat DK voor drukknop staat maar dat hoeft niet gelijk duidelijk te zijn. Of, in mijn ogen, de ergste, lok. Het verwijst naar een array met lok adressen, iets wat niet duidelijk is aan de naam. Beter een lange duidelijke naam dan een korte onduidelijke. Dus locAdressen (loc_adressen) is dan wel wat langer maar geeft gelijk weg wat het doet. En een veel gebruikte verduidelijking is het in meervoud schrijven als het een array betreft (adressen in dit geval). En speed_byte snap ik de toevoeging byte niet. Het is gewoon de snelheid in 8-bit, niet eens als byte want het is signed. snelheid of locSnelheid zou hier genoeg zijn (want waarom hiervoor opeens Engels?).

const byte lok1 = 99;
const byte lok2 = 3;
const byte lok3 = 3;
const byte lok4 = 25;
/* Einde lokadressen  invoeren */

byte lok[] = {lok4, lok3, lok2, lok1};
Waarom niet gelijk de array vullen? Dan heb je geen overhead aan variabele en bespaar je jezelf typewerk. Nu ben je gewoon werk dubbel aan het doen, altijd zonde  ;D

En locIndex heeft geen reden om global te zijn. Dus gewoon:
     pinMode(locAdresPinnen[0], INPUT_PULLUP);
     pinMode(locAdresPinnen[1], INPUT_PULLUP);
     byte lokIndex = digitalRead(locAdresPinnen[0]);  // index wordt 0 of 1
     lokIndex += 2 * digitalRead(locAdresPinnen[1]); // index krijgt er 0 of 2 bij
     lokAdres = lok[lokIndex];
Gelijk ze een naam gegeven, naamloos is nooit echt duidelijk  ;) Of meer schaalbaar (mocht je uit willen breiden):
byte locIndex = 0;
for(byte i = 0; i < sizeof(locAdresPinnen); i++){
  locIndex <<= 1;
  pinMode(locAdresPinnen[i], INPUT_PULLUP);
  locIndex |= !!digitalRead(locAdresPinnen[i]);
}
Edit Ik zie dat je de index gebruikt voor eeprom. Ik zou dan alleen de index opslaan en adres weg doen en dan adres altijd ophalen uit de lijst. Zo heb je niet twee variabele die eigenlijk beide naar het adres moeten wijzen maar per ongeluk toch verschillend zouden kunnen zijn.

char speed_byte, old_speed = 0, snelheid = 1;
Zoals je zelf ook gemerkt hebt is char niet echt het handigste type om hier te gebruiken. Dit omdat char door veel functies afgehandeld wordt als een ASCII karakter.  Ik zou het vervangen door int8_t. Is ook gewoon signed 8-bit maar wordt niet gelijk gezien als karakter.

void stel_snelheid_in()
{
Paar opmerkingen over die functie.

Waarom iedere keer de led high maken? Deze kan buiten de while.

Wat is het hele idee van de variabele old_speed? Is dat alleen maar om te zorgen dat je niet op 0 kunt instellen? Als dat zo is, aangezien je toch niet als snelheid 0 zou willen hebben als ingestelde snelheid, kan je het dan niet veel makkelijker gewoon
if(speed_byte == 0){
  speed_byte = 1; //richting maakt niet uit, 0 wil je toch niet en nu heb je één extra stapje voor "0 vooruit"
}
Ook heeft old_speed geen enkel recht om global te zijn  ;D

speed_byte = (analoge_waarde >> 2)-127 ;
Besef dat je dit ook ongewenst -127 als snelheid kan geven.

  if (speed_byte < 0) speed_byte = -speed_byte;
  EEPROM.write(lokIndex, speed_byte);
  delay(500);                             // wacht tot zeker is dat EEPROM beschreven werd
Nergens voor nodig  ;) Komt gewoon in EEPROM. Je had ook abs() kunnen gebruiken.

Je zou ook tijdens het instellen van de snelheid de optrek vertraging uit kunnen zetten. Kan je het allemaal net wat sneller zien of het idd de juiste snelheid is.



Goed, weer erg lange post. Absoluut niet negatief bedoelt, vind het een leuk project!  (y) (y) Maar dit was wat me op viel toen ik het las.

Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 18 mei 2016, 12:33:51
@Timo
fijn dat je weer meegelezen hebt (y). Ik heb nog wat erfenissen van de voorbeeldsketch laten staan. Het aardige is dat ondanks een paar missers, zoals het direct omkeren van de rijrichting als je de andere richtingknop indrukt e.e.a. al een aantal dagen probleemloos blijft werken. Je hebt me aan het werk gezet met stijl en leesbaarheid aanpassen en een aantal zaken consequenter maken. Ga ik zo maar eens aan beginnen.
Wat betreft de "overkill" aan benamingen:
- Als ik er een handleiding bij maak, wil ik graag dat degene die deze sketch gebruikt duidelijke plekken heeft om bijv. de lokadressen in te vullen. Het is veel lastiger op papier uit te leggen, dat iemand de 4 adressen in omgekeerde volgorde in een arraydefinitie moet stoppen.
- Verder wil ik verderop in de file liever geen niet benoemde zaken zetten. Dus A0, A1 en A2 krijgen wat mij betreft ook nog namen, die iets zeggen over de functie.
E.e.a. levert wel meer tikwerk op, maar maakt het hopelijk ook veel duidelijker voor iemand, die veel minder programmeert dan wij.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 18 mei 2016, 22:15:38
Hoi Cees,

Hehe, ja, als je code van andere gebruikt ben je altijd even bezig de boel wat leesbaarder te maken ja. Tenminste, als je zelf duidelijke en mooie code wilt overhouden. Goed bezig dus! (y)

Wat betreft duidelijke plekken, de extra namen zou ik nu juist als verwarrend zien. En waarom zou dat in omgekeerde volgorde moeten? Wat is er mis met iets als
//Hier de locadressen invullen
byte locAdressen[] = {60,  //Adres 1
                      45,  //Adres 2
                      67,  //Adres 3
                      32}; //Adres 4

En wat betreft niet benoemde zaken, totaal mee eens. Door het bovenaan te noemen kan je het snel terug vinden en eventueel wijzigen zonder alle code door te spitten. Ook is bij het gebruik dan sneller duidelijk wat je precies doet.

E.e.a. levert wel meer tikwerk op, maar maakt het hopelijk ook veel duidelijker voor iemand, die veel minder programmeert dan wij.
Niet alleen voor iemand die minder programmeert. Maar zeker ook voor future you. Als je een project een jaar in de kast heb laten liggen (af of niet  ::) ) is het altijd een stuk makkelijker wat aanpassen als de code duidelijk, gestructureerd en becommentarieerd is.


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 20 mei 2016, 12:09:20
Dag Timo (en anderen)

Wat betreft duidelijke plekken, de extra namen zou ik nu juist als verwarrend zien. En waarom zou dat in omgekeerde volgorde moeten? Wat is er mis met iets als
//Hier de locadressen invullen
byte locAdressen[] = {60,  //Adres 1
                      45,  //Adres 2
                      67,  //Adres 3
                      32}; //Adres 4
Waarom had ik gekozen voor losse declaraties:
1 - Eigenlijk om het echte programmagedeelte helemaal gescheiden te houden van de invulactie.
2 - Als ik in een handleiding het ga hebben over lok 0 t/m lok 3, zou ik niet willen uitleggen waarom men achterste voren moet tellen. Immers door mijn hardware-oplossing {als er geen schakelaar aan de lokKeuzePinnen zit} zijn de pinnen hoog voor de situatie waar de BCD-schakelaar 0 aangeeft.
3 - Door mijn opzet is het minder waarschijnlijk dat iemand, die gaat invullen het array aanvult met bijv. een 5e lok zonder verderop het inlezen van BCD-pins te veranderen. En daarna zich gaat afvragen waarom die 5e lok niet gekozen kan worden. Wellicht begrijp je nu waarom ik voor de langere weg heb gekozen.

Jouw oplossing met de andere opzet van het array is schitterend (y). Als dan ook bij het inlezen van de 2 pinnen de telling omgekeerd wordt (zie de code) dan zou het allemaal ook gaan kloppen.
    huidigeLok = digitalRead(lokKeuzePin1);                // index wordt 0 of 1
     huidigeLok = huidigeLok + 2 * digitalRead(lokKeuzePin2); // index krijgt er 0 of 2 bij
     lokAdres = 3 - lokAdressen[huidigeLok];   // keer de telling om
Maar door de keuze van aparte constanten voor de lokAdressen kon ik dat al oplossen in de array declaratie.

Ik heb inmiddels de hele file aangepast aan een stijl met o.a. "kamelenKaas" en geen Engelse namen (eigenwijze keus en beter leesbaar voor al die figuren, die zelfs geen Engels beheersen). Ik post die file maar niet meer hier. Zodra de uitbreiding van mijn site een feit is, zal die daar komen te staan.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Karst Drenth op 20 mei 2016, 14:46:36
if (snelheid < -1) snelheid = -1; else snelheid = speed_byte;
Van die regel gaan mijn rugharen een beetje overeind staan ;D Voor de leesbaarheid, regels eindigen na de ;. Omdat het een simpel statement is zou je er wel een one line'er van kunnen maken maar dan als:
(snelheid < -1 ? snelheid = -1: snelheid = speed_byte);
Maar meestal gaat mijn voorkeur toch gewoon uit naar voluit omdat het vaak duidelijker is en makkelijker uit te breiden.

Overigens, wil je daar niet van richting veranderen als je op de andere richting drukt? Dus:
if (snelheid < -1)
  snelheid = 1;
else
  snelheid = speed_byte;


Van deze:

(snelheid < -1 ? snelheid = -1: snelheid = speed_byte);

...gaan mij de haren overeind. Als je dan toch les wilt geven in on-liners, dan zo:

snelheid = (snelheid < -1) ? -1 : speed_byte;

oftwel een conditional assignment statement ;) :P Deze vorm van 'if-then-else' heeft als groot voordeel, dat je de 'else' niet kunt vergeten. Het is overduidelijk, dat 'snelheid' altijd een waarde moet krijgen. De geeigende manier is dan het conditional assignment statement ;)


Grtzz,

Karst

P.S.
Citaat
Zou ik je toch een paar tips mogen geven? Zie het vooral dus niet als negatief iets maar puur als hulp!  (y)

P.S.2. Trouwens leuk project Cees (y) (y)

Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 20 mei 2016, 15:52:39
@Karst, je hebt gelijk! Dat is netter. Ik moet toegeven dat ik zelf bijna nooit one liners gebruik (maar hier is hij best mooi zoals jij hem neer zet). Meestal schrijf ik ze uit omdat je altijd zult zien dat je precies daar later toch wat wil toevoegen. Daarom laat ik ook nooit de blockhaken weg bij een statement om niet te fout te maken iets toe te voegen en te denken dat hij in de statement zit.  ::)

@Cees, Ik snap je redenering wel maar door de opzet is de schaalbaarheid (en ik vind ook de duidelijkheid) lager. Even punt voor punt  ;D
1) Tja, je bent toch al in code bezig. De hele array declaratie kan toch ook al in het invuldeel staan?
2) Simpel op te lossen, lees gewoon de switch inverse ;) En klaar is Kees Cees
3) Dat valt tegen denk ik  ;D Mensen zonder programmeerkennis zullen net zo makkelijk gewoon een variabele lok5 toevoegen en verwachten dat het werkt.  ;D

En de hele BCD loc selectie zou je natuurlijk al uit kunnen breiden als je de pinnen hebt. Uitgaande van een BCD schakelaar is dan 4 pinnen. (en zou je zelfs tot 16 locs kunnen selecteren als je jumpers doet.) Als je altijd gewoon 4 pinnen leest ben je altijd veilig als je meer adressen toevoegt.
//Hier de locadressen invullen
byte locAdressen[] = {60,  //Adres 1
                      45,  //Adres 2
                      67,  //Adres 3
                      32}; //Adres 4

const byte LokKeuzePinnen[] = {A1, A2, A3, A4};

byte locIndex;


void kiesLoc(){
  locIndex = 0;
 
  for(byte 1 = 0; i < sizeof(LokKeuzePinnen); i++){
    pinMode(LokKeuzePinnen[i], INPUT_PULLUP);
   
    //schuif eens op
    locIndex <<= 1;
   
    //Inverse lezen om het omdraaien van de loc adressen ongedaan te maken.
    locIndex |= !digitalRead(LokKeuzePinnen[i]);
  }
}

inline byte locAdres(){
  //Als er een te hoge geselecteerd wordt geef gewoon de 1e.
  if(locIndex >= sizeof(locAdressen)){
    return locAdressen[0];
  }
  return locAdressen[locIndex];
}
Let wel op dat hierdoor locKeuzePinnen[0] MSB is van de index. Wil je dat niet dan
    locIndex |= !digitalRead(LokKeuzePinnen[sizeof(LokKeuzePinnen) -1 - i]);
Om de array andersom te gebruiken.


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 20 mei 2016, 23:13:03
@Timo
Met alle respect voor je opmerkingen: het wordt nu te veel een discussie over schaalbaarheid. Dat is niet mijn bedoeling in dit project. Dan had ik wel aangekondigd e.e.a. in een library te gaan frotten.
Het programmaatje zoals ik het nu heb, laat m.i. wel zien hoe je zo'n simpele rijregelaar zou kunnen opbouwen. De andere stukjes, die je voorstelt schieten voor mij het doel een beetje voorbij. Ik laat het graag aan een ander over om het op zijn manier te doen. Onder mijn invulgedeelte zal ik het volgende commentaar gaan zetten.
/* * * * * * O n d e r s t a a n d e   c o d e   a l l e e n  * * * *
 * * * * * * a a n p a s s e n  a l s  j e  v e r t r o u w d * * * *
 * * * * * * b e n t   m e t   C-p r o g r a m m e r e n   e n  * * * 
 * * * * * * A R D U I N O                                    * * * *
 */
En ergens bovenaan komt ook nog iets te staan dat iedereen vrij is te doen met dit stukje code wat men wil.

@iedereen
Ik heb van deze discussie wel weer iets geleerd:
- ik was nog niet consequent genoeg met de gebruikte (programmeer-) stijl.
- oneliners zijn voor mij achteraf gezien ook ondingen, vooral omdat ze minder goed leesbaar zijn.
- schaalbaarheid is een groot ding, maar moet niet het doel van het programmeren zijn.
- efficiente code is soms niet noodzakelijk.
- soms leiden er meer wegen naar Rome, waarbij de kortste of beste niet altijd te prefereren valt.
- alvast vooruit denken naar een handleiding levert niet altijd de mooiste code op.

Ik ga vrolijk verder met dit project. Komende week verwacht ik mijn volgende printjes. Dan ga ik een echte rijregelaar opbouwen. En dan beginnen met de printjes, die ik al heb om servo's aan te sturen met schakelaars. Tussendoor baantje nog aanvullen met een uithaalspoor.
De posts worden misschien even wat minder omdat ik een workshop over iets heel anders bij HCC!m ga voorbereiden.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 23 mei 2016, 13:27:40
Hoi Cees,

Allereerst probeer ik geen discussie aan te gaan! (y) En is en blijft jou project, probeerde alleen wat tips te geven. En ik weet dat het af en toe wat "dringend" over kan komen op een forum vandaar dat ik het niet vaak genoeg aan kan halen en niet genoeg smileys in mijn berichten kan verwerken.  ;D (y)

Mijn opmerking was ook niet zo zeer voor schaalbaarheid of code efficiëntie bedoelt maar om gebruikers fouten op te vangen. Wat ik zei, iemand zonder kennis voegt net zo makkelijk een loc5 toe en verwacht dat het werkt  ;D Maar ook om je te laten zien dat die "omgekeerde volgorde" geen dingetje is. Ik weet dat je af en toe met code je zo vast kunt kijken op iets (mm, ik moet de array omgekeerd maken) terwijl iemand anders met een verse blik denkt van, "mm, je zou de locIndex ook gewoon kunnen omdraaien." Net als Karst met een veel betere one-liner kwam enz. En ja, die "iemand anders met een verse blik" is meer dan eens je toekomstige zelf  ;D ;D ;D

Dus nogmaals, niets negatiefs bedoelt! Het waren maar "my two cents" over de punten die je noemde.  (y) Je noemt namelijk zelf al een punt wat ik ook niet vaak genoeg aan kan halen op het forum:
- somser leiden meer wegen naar Rome, waarbij de kortste of beste niet altijd te prefereren valt.
Maar ik vind het dan wel altijd fijn om een paar wegen te kennen zodat je de voor en nadelen van een route vooraf kunt vaststellen  8)

Veel succes weer verder met het project! Blijf het natuurlijk volgen en hoop dat je mijn opmerkingen luchtig blijft lezen  :)

Timo

PS. Misschien had ik het al gevraagd maar ben ik het vergeten ::) , maar wilde je alles openbaar maken (GitHub bijvoorbeeld)?
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 07 juni 2016, 17:30:10
In post #55 had ik een foto gezet van mijn proefopstelling waar nog een breadboard gebruikt werd om de APM te huisvesten. Inmiddels zijn mijn "universele" printjes binnengekomen met een grappige en een slechte ontwerpfout. Ik heb er toch 1 in elkaar gezet om van dat braadbord af  te komen. De opstelling is nu zoals op de foto hieronder. Links de voedingenprint (de laptopvoeding heb ik weggelaten). Dan de "universele print" met een minimum bezetting. Daarboven een BNLS/RCU boosterprint. Rechts nog een noodprintje met drukknoppen. Naast de APM zie nog een duimwielschakelaartje om de keuze 0 t/m 4 van loc's te kunnen maken. Met dit alles valt er inmiddels te rijden op het baantje. Nu maar eens aan de servo-besturing beginnen.

(https://images.beneluxspoor.net/bnls/opstelling2.jpg) (https://images.beneluxspoor.net/bnls/opstelling2.jpg)

edit: laatopvoeding moest zijn laptopvoeding (correctie van mijn MAC over het hoofd gezien)
Grappige fout was dat de RJ12 connectoren naar de onderkant moesten. Achteraf misschien niet eens zo erg.
Slechte fout: de afbeelding van de 1N4148 diodes staat fout op de print.

(https://images.beneluxspoor.net/bnls/gemonteerd_compl.jpg) (https://images.beneluxspoor.net/bnls/gemonteerd_compl.jpg)

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Raages op 07 juni 2016, 17:36:19
Je bent weer een flinke stap verder en ach, een klein foutje mag. Toch?  ::)
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 07 juni 2016, 20:22:22
Ziet er weer goed uit Cees!

Maar hoe is dat met de diode gebeurd? Net even gekeken en bij mij hebben zowel alle components (van de standaard device library) als alle footprints (vand e standaard throughhole library) de kathode op pin 1 zitten. Welk component en welke footprint heb jij gebruikt?

En de RJ12, was dat echt foutje doordat je hem aan de verkeerde kant van de print geplaatst hebt of klopte die footprint niet?


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: gvandersel op 07 juni 2016, 21:06:01
IK ben ook benieuwd. Bij mij zitten de tekeningen op de print van de 1N4148 ook verkeerd om. Gebruikte combinatie:
- standaard diode
- Walter footprint en 3D weergave (DO35).

Ben al enige tijd aan het zoeken.

Groet,

Gerard van der Sel.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 07 juni 2016, 23:20:24
@Timo,
de footprint van de RJ12 had ik gekopieerd uit w_con_misc van deze website (http://smisioto.no-ip.org/elettronica/kicad/kicad-en.htm). Daarna alleen de outline van de component wat aangepast. In het origineel zitten de 6 eilandjes al gespiegeld. Ga ik later nog wel aanpassen, door een onder en boven de print versie te maken. En nog even goed kijken of de padnummers blijven kloppen met het schema-symbool.

@Gerard
de pinnummering van de footprint moet overeenkomen met die van het schema-symbool. Ik heb het inmiddels in mijn eigen footprint aangepast. Kwestie van boven het padje gaan staan in de footprint-editor met je muis E intoetsen en nummer veranderen. En bewaren. Dan nog in je printlayout bij de betreffende footprint Change footprint kiezen, niets veranderen en OK klikken. Daarna mag je opnieuw bedraden of positioneren.

groet Cees.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 08 juni 2016, 08:13:02
@gvandersel, Ahh, kijk, de Walter versie heeft gek genoeg pin 1 als Anode ipv, wat in de rest gebruikelijk is, kathode... Toen even een oude component van mij geopend en ja hoor, omgedraaid. Zowel de diode als de led zijn omgedraaid. Dit is dus een van de wijzigingen geweest in KiCad 4. Veel verbeteringen in 4 maar de overgang naar 4 is niet altijd even soepel geweest... Als ik nu ook probeer de adServo te openen gaat er het een en ander mis  :(

De diode moet ik dan ook weer even aan gaan passen. Ik had ook zelf een footprint gemaakt omdat ik 200mil tussen de pinnen van een 1N4148 genoeg ruimte vind.

@Cees, gek dat de RJ12 van Walter gespiegeld is, zie het nu ook ja. Nummers zouden moet blijven kloppen aangezien de connector nu op zijn kop werkt. Er is overigens geen enkele reden een boven en onder de print versie te maken. Gewoon een versie (voor boven de print). Wil je hem aan de andere kant van plaats je hem gewoon op de achterkant van de PCB en klaar.


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 08 juni 2016, 11:31:47
@Timo
Citaat
@Cees, gek dat de RJ12 van Walter gespiegeld is, zie het nu ook ja. Nummers zouden moet blijven kloppen aangezien de connector nu op zijn kop werkt. Er is overigens geen enkele reden een boven en onder de print versie te maken. Gewoon een versie (voor boven de print). Wil je hem aan de andere kant van plaats je hem gewoon op de achterkant van de PCB en klaar.
Zo heb ik dat nu gedaan en dat werkt voor LocoNet. Als je echter de connector ook anders wilt gebruiken, waarbij de 6 aders verschillend zijn, dan heb je wel 2 versies nodig.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 08 juni 2016, 11:48:04
Nee hoor Cees, 1 versie voldoet. Deze moet, in tegenstelling tot de versie van Walter, dan wel kloppen. Maar zodra je deze naar de andere kant flipt blijft deze gewoon kloppen. Zou nogal onhandig zijn als je voor elk onderdeel twee footprints zou moeten hebben.


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 08 juni 2016, 13:03:12
Kijk, die had ik nog niet gevonden/gebruikt in KiCad (Flip). Dat maakt je leven weer wat plezieriger. Scheelt een aardige klus in de footprint editor.

Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 08 juni 2016, 16:44:32
Welkom in de wereld van double sided PCB's  ;D ;D ;D De sneltoets, mocht je die nog niet gevonden hebben, is gewoon F. Zonder een functie als deze zou het maken van een dubbelzijdige printplaat wel erg lastig worden.

Heb overigens gevonden dat er best veel RJ12 connectoren bestaan... Wisselend van lipje boven en lipje onder etc. Dus daar zit de fout in de library. De footprint zelf is dus niet fout, maar ij hort niet bij deze connector  ;D


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: gvandersel op 08 juni 2016, 19:42:38
Zelfde met de kleine transistors (sot-92). Daar roteren basis, emiter en collector eveneens. In Kicad zijn een stuk of 8 varianten te vinden.

Groet,

Gerard van der Sel.
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 09 juni 2016, 11:34:27
Maar van de so-92 zijn de pinnummers wel altijd gelijk. Alleen de plaatsing van de pads verschilt een beetje. Maar iedere footprint moet gewoon werken, misschien met een beetje buigen van de pootjes. Dit omdat de pinnummers van een so-92 vast liggen  ;D


Timo (die vanavond ook weer KiCad opstart om een Phono pre-amp op een PCB te krijgen  ;D )
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 25 juli 2016, 17:05:19
Zo, na een tijdje minder aandacht voor dit baantje, weer eens een update>

Ik ben nu zo ver, dat er nieuwe zaken geprogrammeerd moeten worden. Om te beginnen de Arduino voor servo-aansturing. In de eerste versie had ik de eindstanden van de wissels hard gecodeerd in de sketch. Niet zo handig natuurlijk, maar ik was nog niet zo ver om dat anders te doen. Inmiddels ben ik met wat proeven bezig. 1 daar van is gebruik maken van de methode uit de MARDEC van NTeering. Een terminalprogramma is dan de hulp bij het instellen van de eindstanden. Nadeel; als je met een MAC werkt doet het terminalprogramma geen kleurtjes, zoals Nico had voorzien. Dat moet anders kunnen. Naast Arduino bestaat er ook het programma Processing (http://www.processing.org). Als ik dat programma kon gaan gebruiken als de terminal, zou dat voor mij leuk zijn. Na een poosje fröbelen met dat programma en bedenken van een manier van communiceren (protocol vind ik een te groot woord) ben ik nu zover dat ik een servo van positie kan veranderen op mijn beeldscherm. Het schermpje van processing zou er uit kunnen zien als in onderstaande afbeelding:
(https://images.beneluxspoor.net/bnls/instelscherm.jpg) (https://images.beneluxspoor.net/bnls/instelscherm.jpg)
Met de knopjes kun je in stappen van 1, 5 en 10 graden de servoarm verdraaien. Ik heb de standen groen en rood genoemd analoog aan de knoppen op bijv. een Intellibox. Dan is dat gelijk duidelijk.
Cancel betekent voor mij, de actie afbreken - er moet dan een code naar de Arduino, die dat duidelijk maakt.
Bewaar (OK) zal tegen de Arduino gaan zeggen deze stand op te slaan in EEPROM.
Zolang je de verticale rij knoppen bedient gaat er alleen een commando om de servo te verzetten naar de Arduino.

Ik zal proberen het instellen in een filmpje te zetten.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 26 juli 2016, 15:04:39
Kijk, dat lijkt mij al een heel stuk makkelijker dan via terminal. (y) Ook al heb ik zelf een hekel aan Java  ;D :-X Misschien nog iets toevoegen om van servo/stand te wisselen? En een invulbox voor de stand? En was een slider met + en - knop niet makkelijker geweest?

En kom je een beetje uit met hele graden? Naar mijn mening is dat altijd nogal een grove schaal geweest voor wissels. Anders zou je nog over kunnen stappen op halve graden.


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 26 juli 2016, 18:50:40
@Timo
Citaat
Ook al heb ik zelf een hekel aan Java  ;D :-X
Dat was nou net de reden om geen velden en menu's te maken. Slider had ook leuk geweest, maar de implementatie was me te ingewikkeld.
Wat ik nu doe, gaat als volgt:
- de Arduino stuurt het commando: ik wil van servo1 de 'groene' stand ingesteld hebben.
- Processing fungeert dan als potmeter of 'stappen zetter', de gebruiker kijkt zelf of de stand voldoet en klikt dan OK
- dan vraagt de Arduino om de 'rode' kant te doen
- Processing is weer de regelaar
- Daarna volgt nog de snelheid
- de Arduino begint dan met het volgende servo, enz.

Kom ik met die graden uit?
Ik denk het niet, maar als proof of concept voldeed dit. Aangezien ik jouw library voor de servo's gebruik zal ik waarschijnlijk overstappen op de stapjes voor die library. Voorlopig is het me alleen te doen om de 2 servo's van mijn eerste printje te kunnen instellen.

Het voordeel van Processing is dat het meer dan een terminal kan zijn. (Er gaan trouwens gewoon strings heen en weer.) Ik werd getriggerd door een opmerking van Nico over gebrek aan ruimte in de Arduino Uno t.b.v. MARDEC. Door het vele gebruik van teksten naar de terminal was de Arduino snel vol. Processing geeft je dan de mogelijkheid een deel van de teksten daarheen te verhuizen, zodat je meer ruimte overhoudt voor leukere dingen. Misschien is het zelfs mogelijk om een deel van de instelprocedures naar de computer te verhuizen. Dat zeg je eigenlijk ook al met:
Citaat
Misschien nog iets toevoegen om van servo/stand te wisselen?


groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 26 juli 2016, 21:16:23
Hehe, dat snap ik.  ;D

Processing geeft je dan de mogelijkheid een deel van de teksten daarheen te verhuizen, zodat je meer ruimte overhoudt voor leukere dingen.
Dat is dan ook meer "zoals het hoort". Altijd al zonde gevonden om bergen karakters op te slaan op een kleine uC.

En inderdaad, het PC-einde de boel laten bepalen. Maakt het aan de Arduino zijde ook alleen maar makkelijker. Deze hoeft nu alleen state-less opdrachten uit te voeren als "geef huidige postitie servo 1 groen", "servo y, ga naar positie x", "sla x op als positie rood voor servo y" enz. Dan is het bijvoorbeeld ook makkelijk om eventueel een andere Arduino met scherm als "instel device" te bouwen bijvoorbeeld  :)


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 15 augustus 2016, 07:53:45
In post #80 heb ik een filmpje beloofd. Je kunt hem hier bekijken (https://www.youtube.com/watch?v=pLoLwI1jSS0).

Wat zie je daar allemaal? Allereerst mijn testopstelling uit mijn eerste post. Een schakeling voor 2 wissels met relais voor het polariseren van het hartstuk. Het geheel wordt hier met de hand bediend door 2 schakelaars, die je ook kunt vervangen door 2 uitgangen van een decoder. Met deze werking ben ik tevreden.
Niet tevreden was ik met hoe ik e.e.a. toen heb opgelost met het zetten van de wisselstanden in de servo-sturing.  Ik had toen de eindstanden en de draaisnelheid hard gecodeerd in de Arduino. Dat is voor mij nu opgelost met deze hardware/software combinatie. Processing (http://processing.org) op de computer fungeert als bediening van de programmeermodus in het Arduino programma.
De software in de Arduino is hier al eens voorbijgekomen en is gebaseerd op de AdServo oplossing van Timo Engelgeer. Voor de programmeermodus en communicatie met Processing moest ik de code nog maken.
Om de programmeermodus in te komen heb ik een wat lastige methode die werkt, maar ook tegenstaat: houd de programmeerknop op de Arduino ingedrukt en start de processing-sketch. Doordat de Arduino herstart bij het ontstaan van een seriële verbinding en de test op de programmeerknop in Setup() staat, kom je in de programmeersituatie zoals in het filmpje. Hoe ik dat anders/eenvoudiger kan doen ben ik niet uitgekomen.

Het wordt nu tijd om e.e.a. onder het baantje te bouwen en eens te gaan rijden met de wisselsturing. Daarna zijn de "ontkoppelaars" aan de beurt.

groeit Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 15 augustus 2016, 10:58:22
Een aanvulling op de vorige post:

In de Arduino wordt de programmeermodus in setup() geactiveerd:
void setup()
{
...
...
  if (digitalRead(progKnop) == 0)
  {
    ....
    ....
   digitalWrite(LED, HIGH);
   servoInstellen();
  }

Dan komt het volgende aan bod:
void servoInstellen()
{
  String tekst = "";
  for (byte servoNummer = 0; servoNummer < NrServos; servoNummer++)
  {
    // local variables
    boolean done = false;
    boolean wiggel = false;
   
    // stuur commando naar processing (evt. terminal)
    tekst = "SS " + String(servoNummer + 1, HEX) + String(" ");
    Serial.println(tekst);
    Serial.flush();

    // zet servo in de middenstand
    wisselServos.gotoPos(servoNummer,servoMid);
    wisselServos.update();
    while (!done)
    {
      while (Serial.available() > 0)
      {
        // De te ontvangen string bevat altijd: "CCCCC xxx yyy zzz" en wordt afgesloten met \n
                                              // de delen worden gescheiden door een spatie
                                              // CCCCC maximaal 10 karakters, hier gebruiken we er 2
                                              // xxx een int (10 .. 1012) voor een eindstand rood van de servo
                                              // yyy een int (10 .. 1012) voor een eindstand groen van de servo
                                              // zzz een int () voor de servosnelheid
                                              // De commando's kunnen zijn:
                                              // "SK" = skip deze servo
                                              // "SA" = save de meegestuurde waarden
                                              //        en save de ingestelde snelheid
                                              // "SR" = set servo in de stand xxx
                                              // "SG" = set servo in de stand yyy
                                              // "SW" = set wiggelen servo aan
                                              // "SD" = servo speed down
                                              // "SU" = servo speed up
        String commando = "";
        char comm[10];
        int aantal;
        aantal = Serial.readBytesUntil(' ', comm, 10);
        int standGroen, standRood, val3;
       
        for (int i = 0; i < aantal; i++)
        {
          commando = commando + String(comm[i]);
        }
     
        // look for the 3 next valid integers in the incoming serial stream:
        standGroen = Serial.parseInt();
        standRood = Serial.parseInt();
        val3 = Serial.parseInt(); // reserved, not used in this sketch
   
        // wacht op newline, dan zijn we aan het eind van een zin
        if (Serial.read() == '\n')
        {
          commando.toUpperCase();
          if (commando == "SG")
          {
            wisselServos.gotoPos(servoNummer, standGroen);
          }
          if (commando == "SR")
          {
          wisselServos.gotoPos(servoNummer, standRood);
          }
          if (commando == "SK")
          {
            done = true;
          }
          if (commando == "SA")
          {
            wisselServos.setEndPos(servoNummer, 0, standGroen);
            wisselServos.setEndPos(servoNummer, 1, standRood);
            //bewaar ze in EEPROM
            EEPROM.write(EEServoDirs + (servoNummer*2), (standGroen / 4));
            EEPROM.write(EEServoDirs + (servoNummer*2) + 1, (standRood / 4));
            servoSpeed_t servoSpeed = wisselServos.getSpeed(servoNummer);
            EEPROM.write(EEServoSpeedStep + servoNummer, servoSpeed.step);
            EEPROM.write(EEServoSpeedInterval + servoNummer, servoSpeed.interval);
            done = true;
          }
          if (commando == "SW")
          {
            wisselServos.gotoEndPos(servoNummer,0);
            wiggel = true;
          }
          if (commando == "SD")
          {
            wisselServos.speedDown(servoNummer);
          }
          if (commando == "SU")
          {
            wisselServos.speedUp(servoNummer);
          }
        }  // end if (Serial.read()
      } // end while (Serial.available(
      if (wiggel == true)
      {
        wiggelServo(servoNummer);
      }
      wisselServos.update();
    }  // end while (!done)
  } // end for-loop 1
  // We're done setting up. Let processing now.
  tekst = "XX " + String(255, HEX) + String(" ");
  Serial.println(tekst);
  Serial.flush();
  digitalWrite(LED,LOW);
} //end servoInstellen()

void wiggelServo(int i)

{
  if(!wisselServos.isActive(i)) //only change endPos after detached to wait @ endPos
  {   
    if(wisselServos.isAtEndPos(i, 0))
    {
        wisselServos.gotoEndPos(i, 1);
    }
    else if(wisselServos.isAtEndPos(i, 1)) 
    {
        wisselServos.gotoEndPos(i, 0);
    }
  }
}


De sketch in Processing (± 380 regels code) doet de rest zoals getoond in de film. Die code is nog niet voorzien van commentaar, dus die publiceer ik later of maak er een download van.

groet Cees
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 15 augustus 2016, 13:39:21
Hoe ik dat anders/eenvoudiger kan doen ben ik niet uitgekomen.
Aangezien de knop indrukken en dan Prcessing starten met je andere hand misschien wat lastiger is zou je ook kunnen gaan voor Processing starten, dan knopje indrukken en even de reset knop indrukken. Voorwaarde is dan wel dat je PRocessing sketch niet in de stress schiet als deze niet gelijk contact heeft ;D

Je code zou ik alleen nog wat aanpassen. Vooral, laat String zo snel mogelijk vallen. Het is traag, omslachtig en vraagt heeeeel veel geheugen (iets waar menig persoon zijn sketch door heeft laten crashen door een aantal String objecten aan te maken). De regel
tekst = "SS " + String(servoNummer + 1, HEX) + String(" ");
Vraagt bijvoorbeeld nu belachelijk veel geheugen doordat je werkt met drie String objecten!

Ook check je niet of wat je binnen krijgt correct is. Bijvoorbeeld de int's. Als deze niet komen en je krijgt een 0 terug dan voer je dit zonder nadenken uit. Nu is 0 instellen natuurlijk niet heel erg maar goed. Maar als er 30000 van gemaakt wordt voer je dit ook uit :)

En duurt een als SG nu niet erg lang? Of stuur je vanuit processing dan loze data mee voor xxx, yyy en zzz?

En zzz lijkt je als nog niet te gebruiken, correct?

// wacht op newline, dan zijn we aan het eind van een zin
        if (Serial.read() == '\n')
Lijkt me niet zo handig. Wat als deze nooit komt? Of als het een ander character is? Wil je dan echt alles weggooien?

Ik heb de code iets aangepast, vooral wegens de String. De checks heb ik geladen, om dat goed te doen zou ik de hele code overhoop moeten gooien....  :angel: Zou ik zelf nog wel voor gaan.

void servoInstellen(){
  for (byte servoNummer = 0; servoNummer < NrServos; servoNummer++){
    bool done = false;
    bool wiggel = false;
   
    Serial.print(F("SS"));
    Serial.print(servoNummer + 1, HEX);
    Serial.println(" "); //<--- deze kan deze ik wel weg, de '\n' lijkt me genoeg?
   
    // zet servo in de middenstand
    wisselServos.gotoPos(servoNummer,servoMid);
    wisselServos.update();
   
    while(!done){
      //wachten op serial
      while(Serial.available())
      { 
        // De te ontvangen string bevat altijd: "CCCCC xxx yyy zzz" en wordt afgesloten met \n
        // de delen worden gescheiden door een spatie
        // CCCCC maximaal 10 karakters, hier gebruiken we er 2
        // xxx een int (10 .. 1012) voor een eindstand rood van de servo
        // yyy een int (10 .. 1012) voor een eindstand groen van de servo
        // zzz een int () voor de servosnelheid
        // De commando's kunnen zijn:
        // "SK" = skip deze servo
        // "SA" = save de meegestuurde waarden
        //        en save de ingestelde snelheid
        // "SR" = set servo in de stand xxx
        // "SG" = set servo in de stand yyy
        // "SW" = set wiggelen servo aan
        // "SD" = servo speed down
        // "SU" = servo speed up
       
        char command[11]; //een plaats extra voor een '\n'
        byte aantalBytes = Serial.readBytesUntil('', command, 10);
        command[aantalBytes] = '\n'; //altijd eindigen met een '\n'
       
        int standGroen = Serial.parseInt();
        int standRood = Serial.parseInt();
        int servoSpeed = Serial.parseInt();
       
        toUpper(command);
       
        //laten staan omdat je het nu eenmaal stuurt
        if (Serial.read() == '\n')
        {
          if (!strcmp(command, F("SG")))
          {
            wisselServos.gotoPos(servoNummer, standGroen);
          }
          //else if, want als het SG was kunnen we gewoon stoppen met zoeken
          else if (!strcmp(command, F("SR")))
          {
            wisselServos.gotoPos(servoNummer, standRood);
          }
          else if (!strcmp(command, F("SK")))
          {
            done = true;
          }
          else if (!strcmp(command, F("SA")))
          {
            wisselServos.setEndPos(servoNummer, 0, standGroen);
            wisselServos.setEndPos(servoNummer, 1, standRood);
            //bewaar ze in EEPROM
            EEPROM.write(EEServoDirs + (servoNummer*2), (standGroen / 4));
            EEPROM.write(EEServoDirs + (servoNummer*2) + 1, (standRood / 4));
            servoSpeed_t servoSpeed = wisselServos.getSpeed(servoNummer);
            EEPROM.write(EEServoSpeedStep + servoNummer, servoSpeed.step);
            EEPROM.write(EEServoSpeedInterval + servoNummer, servoSpeed.interval);
            done = true;
          }
          else if (!strcmp(command, F("SW")))
          {
            wisselServos.gotoEndPos(servoNummer,0);
            wiggel = true;
          }
          else if (!strcmp(command, F("SD")))
          {
            wisselServos.speedDown(servoNummer);
          }
          else if (!strcmp(command, F("SU")))
          {
            wisselServos.speedUp(servoNummer);
          }
        }  // end if (Serial.read()
      } // end while (Serial.available(
       
      if (wiggel == true)
      {
        wiggelServo(servoNummer);
      }
      wisselServos.update();
    }  // end while (!done)
  } // end for-loop 1

  // We're done setting up. Let processing know.
  Serial.println(F("XX FF"));

  digitalWrite(LED,LOW);
} //end servoInstellen()

//Hele string naar uppercase
void toUpper(&in){
  for(unsigned int i = 0; i < strlen(in); i++){
    in[i] = toupper(in[i]);
  }
 
}


Timo
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Cees Baarda op 16 augustus 2016, 12:21:18
Ik hou wel van een beetje spitsroeden lopen.
Ook in de Processing sketch doe ik net alsof mijn Arduino, de MAC en de USB-verbinding perfect hun werk doen. Uiteindelijk moeten er natuurlijk gedegen controles om de hele communicatie heen komen. Ik was begonnen met heen en weer sturen van strings omdat decoderen dan wat eenvoudiger leek. Daarbij ben ik er vanuit gegaan dat per servo de 3 in te stellen waarden steeds heen en weer zouden gaan. Gaandeweg bleek natuurlijk dat op een andere ook manier kan en misschien beter is. Bij het instellen van de snelheid is de oplossing daardoor al anders geworden dan bedacht. Vandaar de inmiddels overbodige 'zzz'.
@Timo ik kan tussen de regels lezen dat je de processing-kant mist. Je krijgt een PB.

Nog te doen (kan wel een paar weken duren, eerst andere prioriteiten):
- Ik stuur pas een 'save'-commando als de hele servo ingesteld is. Tot dat moment bewaart Processing de waarden voor 'groen' en 'rood'. Daarna gaat e.e.a. in de Arduino pas naar EEPROM. Je zou eigenlijk in staat moeten zijn iedere instelling apart over te slaan, terwijl ik nu 'skip servo' heb gedaan. Het is immers niet nodig opnieuw in te stellen als de servo al goed staat. Dat betekent dat de beginsituatie (de twee eindstanden) ook naar Processing moet.
- Overbodige code is nog niet helemaal opgeruimd.
- De communicatie kan anders, daar is de reactie van Timo een grote hulp bij (y).
Titel: Re: Rangeerpuzzel (Inglenook) met Arduino besturing
Bericht door: Timo op 16 augustus 2016, 22:36:52
 ;D ;D Maar goed bezig hoor Cees!

Wat betreft de communicatie zou ik vooral kijken of je het meer als een parallel proces kunt opzetten icm een soort state machine ipv alles sequentieel afhandelen. Dus misschien ipv de huidige lange commando's ook meer een soort command en payload structuur die heen en weer werkt.

Hopelijk kan ik binnenkort adServo ook weer wat beter oppakken. Ik ben eigenlijk niet zo tevreden met de huidige libraries waar het op draait, zowel ServoExtend als ServoController. Ik wil deze toch wat makkelijker zien te maken. En überhaupt het programma wat meer stroomlijnen en eindelijk DCC! Dat is toch eigenlijk de grootste reden geweest voor adServo nietwaar  ::)


Timo