Onderhoud, reparatie en ombouwtechniek > Mechanische techniek

Aandrijving inbouwen in handdraaischijf

(1/22) > >>

Rob:
Hier een projectje dat ik al een tijdje geleden heb gedaan: een Fleischmann handdraaischijf aandrijven met een stappenmotor, besturing met een Arduino.
Het geheel heeft ongeveer 25 euro gekost (inclusief de 12,50 voor de draaischijf op Marktplaats), dus voor de prijs hoef je het niet te laten. De draaischijf wordt als segmentdraaischijf later in een kopstation ingebouwd. Maar met de stappenmotor is de draaischijf ook helemaal rond te draaien, dus deze ombouw is ook te gebruiken voor 'echte' draaischijven. (ik had op enig moment bijna spijt om er een segmentdraaischijf van te maken).

Benodigdheden:
- Een handdraaischijf van Fleishmann
- Een Arduino microcontroller
- Een stappenmotor (ik heb de stappenmotor gebruikt die in het Arduino assortiment zit)
- Een beetje programmeerkennis (voor het programmeren van de Arduino)
- en wat schroefjes, boutjes, draadjes enzo.

Dit is de basis




De mechanische kant eerst maar eens aangepakt. De brug van de draaischijf zit met een soort popnageltje vast aan de basis (de kuil). Die voorzichtig los gemaakt.






Op de stappenmotor (met 1:64 vertraging) zit een as met platte kanten. Het gat in de brug heb ik voorzichtig uitgevijld tot deze klem over de as van de motor gaat.




Daarna provisorisch de boel gemonteerd, en de brug loopt af en toe vast. Dat kan geen kwaad voor de stappenmotor zelf, maar nauwkeurig draaien en stoppen voor de sporen wordt zo wel een probleem. Na wat onderzoek zijn het de railcontacten die af en toe haken of stroef lopen. Die contacten zijn niet echt nodig, want de sporen worden apart van stroom voorzien en de brug heeft 2 glij contacten om stroom op te nemen. Dus de rail contacten zo verbogen dat ze nauwelijks nog tegen de randen veren.




Ook zitten er een soort van nokjes onder de rails. Hier klikt de brug enigszins in vast. Handig bij bij handbediening, maar ook niet meer nodig. Die vijlen we ook maar weg.




Tijd om de motor goed te bevestigen. Het gat in het midden groter geboord, zodat de as van de motor er doorheen kan. Ook 2 gaatjes geboord voor de bouten waar de motor mee wordt vast gezet. Twee M4 boutjes en moeren volstaan.






Een sensor is met name nodig bij het starten van draaischijf als de stroom weer aan gaat om te weten waar de beginstand is. De sensor is de verbinding een van de buitenste rails en een rail van brug geworden. Ik heb de contactjes weer iets teruggebogen.




Daarna bleek het erg moeilijk de brug zuiver te laten bewegen en op de goede plek te laten stoppen. Het bleek dat de draaischijf constructie niet erg stabiel is ( de bodem tordeert makkelijk). Maar er zitten 3 schroefgaten onder de afdekplaatjes, dus eerst maar eens een stabiele ondergrond gemaakt uit een stevige spaanplaat van een afgedankte IKEA koffietafel.

.


De ondergrond helpt, dus klaar voor een uitgebreidere test. De bewegingen voor:
- V60: soepel
- BR64: soepel
- BR78: soepel
- V160: stroef en onnauwkeurig
- V100: stroef en onnauwkeurig

Wat blijkt: locs met een goede gewichtsverdeling in het midden of over de hele lengte draaien heel sopel op de brug, maar locs met het gewicht op de uiteinden (draaistellen), geven veel druk op de plastic wieltjes en rails. De wrijving wordt te groot....
Uiteindelijk bleek dit op te lossen door de hoogte van de brug op de as nauwkeurig af te stellen. Een ringetje zorgt voor de juiste afstand.




Nu doen zowel de V60 als V160 het goed.






De test van het oprijden, draaien en afrijden met de BR64 is vastgelegd op film:




Dus klaar voor de definitieve aansturing met de Arduino Nano (veel goedkoper dan zijn grote broer).

Om het een en ander in te kunnen bouwen in een compact schroeven-doosje van de bouwmarkt, zijn er andere pinnen gebruikt dan op de grote Nano, maar met wat andere definities in het stuurprogramma is dat snel op te lossen. Verder is de controller van de stappenmotor hier ingebouwd en is een 7-polige platte kabel voor het bedieningspaneel aangesloten: massa, plus, sensor en 4 draadjes voor de terugmeldings-LEDs.
 De mini-USB aansluiting wordt straks ook gebruikt als voedingskabel. Het geheel trekt minder dan 500mA, dus kan makkelijk op een telefoonlader draaien.



Het bedieningspaneel is nog even los opgezet, zodat de knoppen en de LEDs later in het paneel van het station kunnen worden ingebouwd. Spanningsverdeler met 4 knoppen , 1 voor elk spoor, en 4 LEDs, ook voor elk spoor. Als je een knop indrukt, gaat de LED erbij knipperen zolang de draaischijf naar het spoor aan het draaien is. Eenmaal op de plek aangekomen brandt de led continue.




Nog even een overzicht van de gehele constructie.




En @mark mms , zal ik de Arduino sketch ook nog ergens neerzetten?

Rob

Raages:
Dat is een mooie duidelijke uitleg van een interessant project.

Dirk T:

--- Citaat van: Robvd op 17 juli 2017, 22:42:32 ---En mark mms, zal ik de Arduino sketch ook nog ergens neerzetten?
--- Einde van citaat ---

Niet dat ik Mark ben, maar ik vind dat wel een goed idee. Mooi project, en mooi om na te bouwen!

Wim Corduwener:
Mooie beschrijving.
Blijf ons verrassen.
Ik ben natuurlijk zo analoog als een spaarvarken, maar dat principe van die stappenmotor verdient bij mij ook nog wel enige uitleg.
Ik heb ooit een draaischijfje voor H0e gemaakt...


....maar daar zat een servo onder omdat die draaischijf niet helemaal rond hoefde te draaien.  ::)

Rob:
Voor de Arduino ingewijden, hier de 'sketch' waarmee de draaischijf wordt bestuurd.

Belangrijkste zaken:
- op de as zit speling ('slack'), die vooral opspeelt bij het veranderen van draairichting. Daar compenseert de software voor
- de knoppen zitten op een spanningsdeler (rijtje weerstanden tussen + en -) op een analoge input. Daarmee heb ik minder draden nodig (3) om de vier knoppen uit te lezen dan dat elke knop op een input pin zou zitten (5). De spanningsverdeler werkt niet precies in stappen van 1 volt, maar dat maakt niet uit, zolang het verschil maar groot genoeg is om de ingedrukte knop nauwkeurig te kunnen lezen.
- Bij het opstarten wordt de brug een beetje een kant op bewogen, om vervolgens weer terug te draaien naar de 'sensor' rail, Dit is dan het nulpunt waar vanuit alle bewegingen naar de andere sporen worden uitgeteld in stappen.
- De stappenmotor bediening is gedaan me Accelstepper. Daarmee kun je eenvoudig van een punt naar een andere draaien met een ooie versnelling en vertraging.
- Commentaar in de sketch is in het Engels... Voormalige beroepsdeformatie.

Daar gaat-ie dan:

--- Code: ---/*
 * Turntable control
 * (partial turntable. 4 tracks at 15 degrees angle)
 */
/*-----( Import needed libraries )-----*/
#include <AccelStepper.h>

/***** Declare Constants and Pin Numbers *******/
#define FULLSTEP 4
#define HALFSTEP 8
// motor pins
#define motorPin1  12   // Blue   - 28BYJ48 pin 1
#define motorPin2  11   // Pink   - 28BYJ48 pin 2
#define motorPin3  10   // Yellow - 28BYJ48 pin 3
#define motorPin4  9    // Orange - 28BYJ48 pin 4

// sensor pins (analog)
#define startPin A0     // pin to detect turntable start position
#define buttonsPin A1   // analog pin to read buttons

# define trackled1 5   // led for track 1
# define trackled2 4   // led for track 2
# define trackled3 3   // led for track 3
# define trackled4 2   // led for track 4

const int ledpin = 13;  // LED on Arduino

// Turntable
const int slack = 11;      // steps of slack in stepper motor axel from middle
const int startcorr = 16;  // steps to move further after sensor active
const int initMove  = -70; // steps to move at initialisation before sensor read

// Led display
unsigned long prevms = 0;        // blinking led milisecs last on/off
unsigned long curms = millis();  // blinking led milisecs now
const long blnkint = 250;        // blink interval

/******* Global variables ******/
// Turntable variables
int currentTrack = 0;            // position after initialisation
int newTrack = 2;                // 1st position to move to after initialisation
int prevTurnDirection = 0;       // prev direction in Turntable = calculate for slack in movement
int curTurnDirection = 0;        // current direction in Turntable = calculate for slack in movement
int button = -1;                 // button pressed (0, 1 2 or 3, -1 is no button)
int track[] {0, -174, -343, -514};   //positions for 4 turntable tracks (motor steps from 0)

// Led display variables
int ledPins[] {trackled1 ,trackled2, trackled3, trackled4};   // array to light op track moving to or pointing at
int blnk = HIGH;

/****** Objects *******/
// NOTE: The sequence 1-3-2-4 is required for proper sequencing of 28BYJ48
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);

/****** Functions ******/
// ---- initialiation ----
// Turntable initialisation after starting/resetting Arduino.
// It moves turntable clockwise untill last track is sensed and then
// positions turntable exactly in front of the last track.
// When last track sensed directly, it assumes turntable is positioned
// precisely in front this track already and no movement is done.
// maximum steps is 700. When last track not sensed, error is returned.

bool initTurntable () {
  bool succesfull = true;     // return parameter
  int x = 0;                  // step counter
 
  digitalWrite (ledpin,LOW);  // show initialisation ongoing on Arduino board
 
  // move  turntable into start / reset position

  stepper1.setMaxSpeed(500.0);
  stepper1.setAcceleration(500.0);
  stepper1.setSpeed(500);
  // start with a move counterclockwise in case just beyond sensor...
  x = initMove; 

  // now keep turning the table slowly until start point sensed
  do {
    stepper1.runToNewPosition(x);
    x++;
  } while ( (digitalRead (startPin) == HIGH) && (x<700) ); //run until sensor active, max 700 positions (error)

  if (x < 700) { // start position sensed. Intialise stepper position
    stepper1.setCurrentPosition(startcorr);
    digitalWrite (ledpin,HIGH);  // end of initialisation
  } else {   //initialisation error
    succesfull = false;
  }
  stepper1.disableOutputs();  // Turn off stepper motor power
  return succesfull;


// ---- read button sensor ----
// function to get button from analog pin
// returns button 0-3 pressed.
// returns -1 if no button pressed
int getButtonPressed () {
  int r = analogRead (buttonsPin);
  int b = -1;
  if (r < 900) {            // a button was pressed
    b = 3 ;
    if ( r < 750) {
      b = 2;
    }
    if (r < 600) {
      b = 1;
    }
    if (r < 300) {
      b = 0;
    }
  }
  return b;
}

// ---- turntable movement calculation ----
// function to calculate new position for turntable to move to
// input: new track number
// output: new stepper position with corrections mechanical inaccuracies
int calcNewPosition (int trk) {
  int pos = 0;
  // consider slack when change in direction
  if ( newTrack > currentTrack ) {
    prevTurnDirection = -1;
  } else {
    prevTurnDirection = 1;
  }

  currentTrack = newTrack;
  newTrack = trk; 

  // Init new move
  // check direction for additional slack movement.
  //calculate new stepper position
  if ( newTrack > currentTrack ) {
    curTurnDirection = -1;   //clockwise
  } else {
    curTurnDirection = 1;    //counter clockwise
  }
  // calculate position to move to     
  pos = track[newTrack];     //bare track position
  pos = pos + (- slack * (prevTurnDirection - curTurnDirection));  // slack correction in case direction changes
  if (abs(abs(newTrack) - abs(currentTrack)) == 1  && (prevTurnDirection == curTurnDirection) ) {  // adjecent tracks and same direction
    pos = pos + (curTurnDirection*18); 
  }
  return pos;
}

// led on / of / blink function
// input: led number
//        func: 0 = off, 1=blink, 2 = on

void setLed (int led, int func) {
  if (func == 0) {
    digitalWrite(ledPins[led], LOW);
  }
  if (func == 2) {
    digitalWrite(ledPins[led], HIGH);
  }
  if (func == 1) {
    curms = millis();
    if (curms - prevms >= blnkint) {
      prevms = curms;
      if (blnk == HIGH) {
        blnk = LOW;
      } else {
        blnk = HIGH;
      }
      digitalWrite(ledPins[led], blnk);
    }
  }
}

/****** SETUP: RUNS ONCE ******/
void setup() 
{
  bool init = false;  // turntable intialisation status
  int x = 0;
  // set the digital led pins as output and initialise values
  while (x<4) {
    pinMode(ledPins[ x ], OUTPUT);
    analogWrite (ledPins[ x ], 255);
    digitalWrite (ledPins[ x ], HIGH); // show: initializing: all track leds on
    x++;
  }
  pinMode (ledpin, OUTPUT);
  digitalWrite (startPin,HIGH);     // initialise startpin high
  digitalWrite (buttonsPin,HIGH);   // initialise button read
  // turntable initialisation
  init = initTurntable() ;          // initialise turntable.
  while (not init) {                // Blink led indefenitely if initialisation returns an error
    digitalWrite(ledpin,HIGH);
    delay(100);
    digitalWrite(ledpin,LOW);
    delay(100);
  }
  x=0;
  while (x<4) {  // switch of track leds
    digitalWrite (ledPins[ x ], LOW);
    x++;
  }
  // Setings for speed and accelaration during normal operation
  stepper1.setMaxSpeed(65.0);
  stepper1.setAcceleration(100.0);
  stepper1.setSpeed(20);

  // move to initial track
  stepper1.moveTo(track[newTrack] - 2* slack);
  stepper1.runSpeed();
 
}//--(end setup )---


/****** LOOP: RUNS CONSTANTLY ******/
void loop()   
{
  stepper1.run();  // operate the stepper motor
 
  if (stepper1.distanceToGo() == 0) {  // turntable at desired position
    stepper1.disableOutputs();         // turn stepper motor off (all pins low)
    setLed (newTrack,2);               //turn on led for track positioned to/

    button = getButtonPressed ();      // check if a button was pressed
    if (button > -1 && button != newTrack) {     // button pressed for another track than positioned on
      setLed (newTrack,0); //turn off led for this track, we're moving away from it.
      stepper1.moveTo(calcNewPosition(button));  // ca;culate new stepper position and move to it.
    }
  }
  else { // turntable turning (moving to desired position)
    setLed (newTrack,1) ;              // blink the led for the track where is moving to
  }

}//--(end main loop )---


//*********( THE END )***********

--- Einde van code ---



groeten,
Rob

Navigatie

[0] Berichtenindex

[#] Volgende pagina

Naar de volledige versie