Schrittmotorsteuerung für Drehscheibe

Fertige Geräte mit Bilden, Schaltungen, Programmen vorstellen.
Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von Admin »

Und ist alles klar gegangen beim Fahrrad Ausflug. Ich hoffe wir haben bald die Temperaturen die ich brauche, dass ich auch ein wenig fahren kann. :()-():

Schönes Restwochenende, servus
Franz

Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von e69-fan »

Hallo Franz,

ich habe mich mal mit einem 0,96" OLED-Display beschäftigt und den Sketch umgebaut:

Code: Alles auswählen

/*  Dateiname:      Drehscheibe_neu_1_6   by e69-fan

    Beispiel: Stepper_03 von den MobaTools / MoToStepper - attaching a bipolar stepper with step/dir and enable

    StepperMotor ACT 17HS4417L20P1X2
    TB6600 Schrittmotor-Treiber-Modul

    16 MicroStep - 3200 Pulse/Rev -       S1 OFF  / S2 OFF  / S3 ON
    Current Control Setting:  1,5 Ampere  S4 ON   / S5 ON   / S6 OFF

    max. Drehwinkel 370 Grad, dann zurück
    Referenzpunkt bei Position "Einfahrt" in Einzelschritten links/rechts setzen, Bestätigung mit LED
    Blinklicht AN während der Bühnendrehung

    optionale Infoausgabe an LCD-Display 20x4   // A4 =SDA; A5 =SCL; 5V Plus; Masse

    Danke an MicroBahner und Franz54  https://www.franzls-technik-forum.de
                                      https://arduino-fan.de/
*/

#define MAX8BUTTONS
#include <MobaTools.h>

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
// A4 = SDA, grün; A5 = SCL, blau; +5V, rot; Ground, schwarz;


//-----  individuelle Definitionen  -------------------------------------------------- //

// -----------Declarationen Blinklicht-----------------
int LED_PIN = 13;               // Blink-LED auf 13
byte LED = LOW;
byte stopp = 4;
byte fahrt = 4;
unsigned long BLINKIO = 0;
const int delayTime = 300;      // HIGH und LOW Zeit dess Blinksignales
unsigned long VorherMilles = 0;
unsigned long AktuellMilles;

// ----------------------------------------------------
//TMC2209 = 5,6,7 - TB6600 = 36,35,34 - DM556 = 32,31,30


const byte dirPin             = 5;      //  orange
const byte stepPin            = 6;      //  lila
const byte enaPin             = 7;      //  grau

const byte LinksPin           = A1;     //  rot  / 4 steps nach links
const byte RechtsPin          = A2;     //  grün / 4 steps nach rechts
const byte RefPin             = A3;     //  grau / RefPunkt setzen - RefLED leuchtet
const byte RefLED             = 13;     //  gelb / leuchtet wenn RefPunkt gesetzt
const byte piezo              = 3;      //       / ?????????????????????????????????

const byte EinfahrtPin        = 8 ;     //  grün   / Einfahrt Gleis1A - Lok steht vorwärts
const byte V_Ausfahrt_1bPin   = 9 ;     //  gelb   / Ausfahrt Gleis1B - Lok steht vorwärts
const byte WendePin           = 10;     //  blau   / Wendung 180 Grad - Lok steht
const byte SchuppenPin        = 11;     //  grau   / Lokschuppen      - Lok steht
const byte R_Ausfahrt_1bPin   = 12;     //  orange / Ausfahrt Gleis1B - Lok steht rückwärts

const byte potPin       = A0;       // Analog Poti Eingang

int Umdrehungen         = 0;
int Umdrehung_Schritte  = 3200;     // Referenz zur Treibereinstellung Schritte je Umdrehung
int Rampe               = 200;


// -----  Stepper einrichten ( 3200 Schritte / Umdrehung - 1/8 Microstep )-------------------------------------------  //
const int STEPS_REVOLUTION = 3200;                   // Schritte Auftrag für TCM2208 nur 1600

MoToStepper myStepper( STEPS_REVOLUTION, STEPDIR );  // Steps bei xxx pro Umdrehung

// -----  Taster einrichten  ----------------------------------------------------------------------------------------//

enum {                      Button1 = 0,  Button2,    Button3,  Button4,      Button5,          Button6,  Button7,     Button8          } ;    // Den Tasternamen die Indizes 0...3 zuordnen
const byte buttonPins[] = { LinksPin,     RechtsPin,  RefPin,   EinfahrtPin,  V_Ausfahrt_1bPin, WendePin, SchuppenPin, R_Ausfahrt_1bPin } ;    // muss als byte definiert sein, damit ein enfaches sizeof funktioniert
MoToButtons button( buttonPins, sizeof(buttonPins), 20, 500 );


//  -----  speedPoti einrichten  --------------------------------------------------------------------------------------//
MoToTimebase speedIntervall;    // Zeitinterval zum Auslesen des Speedpotentiometers
int vspeed = 0;                 // Steppergeschwindigkeit in U/min*10


// ----------------------------------------- S E T U P -----------------
void setup() {
  
// ------------------OLED Display --------------------------------------
  Wire.begin();
  Wire.setClock(400000L);
#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else                                         // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif                                        // RST_PIN >= 0
  oled.setFont(Callibri11);
// ---------------------------------------------------------------------
  pinMode(RefLED, OUTPUT);
  digitalWrite(RefLED, LOW);
  pinMode(LED_PIN, OUTPUT);

  oled.setCursor (0, 0);
  oled.print (F(""));
  
  oled.setCursor (0, 0);
  oled.print (F("Referenzpunkt ??   "));
  
  oled.setCursor (0, 4);
  oled.print (F("Gleis ?            "));
  
  oled.setCursor (50, 6);   // 50er Einzug in Zeile 6
  oled.print (F("-----"));

  //-----  Stepper  -------------------------------------------------------------------- //
  Umdrehungen = STEPS_REVOLUTION / Umdrehung_Schritte;
  myStepper.attach( stepPin, dirPin );
  myStepper.attachEnable( enaPin, 10, LOW );  // Enable Pin aktivieren ( LOW=aktiv )
  myStepper.setSpeed( 200 );                  // 20 Umdrehungen je Minute
  myStepper.setRampLen( Rampe );              // Rampenlänge 300 Steps bei 20U/min
  speedIntervall.setBasetime( 100 );          // 100ms Tickerzeit
}

void loop() {
  BLINKIO = myStepper.stepsToDo();
  AktuellMilles = millis();
  if (AktuellMilles - VorherMilles >= delayTime) {
    VorherMilles = AktuellMilles;
    LED = !LED;
    if (BLINKIO == 0) {
      LED = 0;
      if (stopp < 4)
      {
        
        //oled.setCursor (0, stopp);               // Ausgabe Position für das Wort "Stopp" übergeben
        //oled.print (F("       Stopp       "));   // durch Leerzeichen mittig ausgerichtet
        stopp = 4;
      }
    }
    digitalWrite(LED_PIN, LED);
  }

  button.processButtons();                                  // Taster einlesen und bearbeiten

  if ( speedIntervall.tick() ) {                            // wird alle 100ms aufgerufen ( Tickerzeit = 100ms im setup() )
    // Speed alle 100ms neu einlesen und setzen
    vspeed = map((analogRead(potPin)), 0, 1023, 20, 240);   // Poti mappen auf 2 ... 240 Umdr/Min
    myStepper.setSpeed( vspeed );                           // min speed =2 and max speed =180 rpm
  }

  //  --------------------------- Referenzpunkt setzen ------------------------------------------------  //
  if (button.pressed(Button1) ) {     // Taster Links gedrückt
    digitalWrite(RefLED, LOW);
    myStepper.doSteps( 4 );           // Stepper dreht 1x links
  }
  if ( button.released(Button1) ) {   // Taster links losgelassen
    myStepper.rotate(0);              // Stepper stoppt
  }
  if (button.pressed(Button2) ) {     // Taster Rechts gedrückt
    digitalWrite(RefLED, LOW);
    myStepper.doSteps( -4 );          // Stepper dreht 1x rechts
  }
  if ( button.released(Button2) ) {   // Taster Rechts losgelassen
    myStepper.rotate(0);              // Stepper stoppt
  }
  if (button.pressed(Button3) ) {     // Taster Ref gedrückt
    myStepper.setZero();              // Referenzpunkt gesetzt
    tone(3, 440, 300);               // Bestätigungston piezo an PIN3, Tonhöhe, ? - Dauer
    digitalWrite(RefLED, HIGH);
    oled.setCursor (0, 0);
    oled.print (F("Referenzpunkt   OK  "));
    
  }

  //  --------------------------- Bühnendrehung ------------------------------------------------  //

  if ((button.pressed(Button4)) && (fahrt == 4)) {      // Taster4 gedrückt:
    tone(3, 440, 300);
    oled.setCursor (0, 4);
    oled.print (F("> Einfahrt Gleis 1A "));
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( 0 );                               // dreht zur Einfahrt Gleis1A zurück
                                                        // zur Startposition
  }

  if ((button.pressed(Button5)) && (fahrt == 4)) {      // Taster5 gedrückt
    oled.setCursor (0, 4);
    oled.print (F("> Ausfahrt Gleis 1B "));
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( 50 );                              // dreht  zur Ausfahrt Gleis1B - vorwärts
  }

  if ((button.pressed(Button6)) && (fahrt == 4)) {      // Taster6 gedrückt:
    oled.setCursor (0, 4);
    oled.print (F("< 180 Wendung        "));
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( -180 );                            // wendet die Bühne um 180 Grad
  }

  if ((button.pressed(Button7)) && (fahrt == 4)) {      // Taster7 gedrückt:
    oled.setCursor (0, 4);
    oled.print (F("< Lokschuppen        "));
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( -250 );                            // dreht zur Abfahrt: Lokschuppen
  }

  if ((button.pressed(Button8)) && (fahrt == 4)) {      // Taster8 gedrückt:
    oled.setCursor (0, 4);
    oled.print (F("< Ausfahrt Gleis 1B ")); 
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( -100 );                            // dreht zur Ausfahrt Gleis1B - rückwärts
  }
}

void disp()
{
  //oled.setCursor (0, 6);
  //oled.print (F("                   "));
  //oled.setCursor (0, (fahrt));                           // Position (Zeile) für das Wort "Fahrt"
  //oled.print (F("       Fahrt       "));
  // 1-----------------20
  fahrt = 4;
}
Jetzt stehe ich vor folgendem Problem:

Wie bekomme ich die Befehle in die letzte Zeile ----- :

Code: Alles auswählen

  oled.setCursor (50, 6);   // 50er Einzug in Zeile 6
  oled.print (F("-----"));

Code: Alles auswählen

        //oled.setCursor (0, stopp);               // Ausgabe Position für das Wort "Stopp" übergeben
        //oled.print (F("       Stopp       "));   // durch Leerzeichen mittig ausgerichtet

Code: Alles auswählen

  //oled.setCursor (0, 6);
  //oled.print (F("                   "));
  //oled.setCursor (0, (fahrt));                           // Position (Zeile) für das Wort "Fahrt"
  //oled.print (F("       Fahrt       "));

Wenn ich die Befehle aktiviere, rutscht die Schrift nach oben und beschneidet die anderen Zeilen in der Höhe.
Ich glaube beim OLED-Display braucht man eine exakte Positionsangabe wie z.B.

Code: Alles auswählen

  oled.setCursor (50, 6);   // 50er Einzug in Zeile 6
  oled.print (F("-----"));

da jedoch der Befehl:

Code: Alles auswählen

  //oled.setCursor (0, (fahrt));                           // Position (Zeile) für das Wort "Fahrt"

lautet funktioniert das nicht.


Den "tone" habe drin gelassen - könnte ein Signal beim Drehbeginn werden.
Ich habe eine piezo-buzzer angeschlossen, möchte diesen aber durch einen 8 Ohm-Lautsprecher ersetzen. Da müsste man doch noch tiefere Töne erzeugen können.

Was brauch ich da für eine Schaltung? Vorwiderstand zur Strombegrenzung?

So jetzt wünsche ich Euch einen schönen Abend und tu mal Rasenmähen ( O-Ton Helga: "Robbi kommt mir nicht ins Haus :evil:
Grüße aus der Heimat der E69

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von Admin »

Im moment wird auf "fahrt" die "3" ausgegeben. Wenn du die 6 brauchst müßen wir einiges ändern. Bei Stopp genauso. Ich musste ja zu Beginn in der Zeile 0, 1, 2, 3 Start oder Stopp ausgeben. Und ich habe auch noch eine Kontrolle eingebaut, dass dann, wenn das "Fahrt" oder "Stopp" ausgegeben wurde, nicht dauernd wieder das selbe Wort auf der selben Zeile ausgegeben wird. Dann würde das Display flackern. Daher wird dann, wenn das Wort "Fahrt" ausgegeben wurde, der Zähler "fahrt" auf 4 gesetzt. Mit dieser 4 kommt er nur noch weiter, wenn man einen neuen Taster drückt, der die Bühne wieder in Drehung bringt. Da wird dann "fahrt" im Programm jetzt nur immer auf "3" gesetzt, weil es ja in den anderen Zeilen nicht mehr ausgeben werden muß.

Ich kanns mit dem Oled nicht testen. Aber sag mal, was ist beim Oled die Zeile 1?
"oled.setCursor (0, 1);" ?? oder "oled.setCursor (0, 0);" ??
Und du willst auf Zeile 6 z.B. "Fahrt" ausgeben. ist das dann
oled.setCursor (0, 6);
oled.print (F(" Fahrt "));
oder
oled.setCursor (0, 5);
oled.print (F(" Fahrt "));

Denn die Zeilen werden ja meistens in der ersten Zeile mit "0" begonnen. Also dann hätten wir die Zeile 0, 1, 2, 3, 4, 5.
Wenn die Zeilen mit "1" begonnen werden, dann haben wir die Zeilen 1, 2, 3, 4, 5, 6.
Ich kann es nicht testen, daher muss ich das von dir wissen, bevor ich da eine Anpassung machen kann.

Gute Nacht
Franz

Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von e69-fan »

Code: Alles auswählen

// Dateiname: Test_for_minimum_program_size_1_1.ino
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
//------------------------ setup -----
void setup() {
  Wire.begin();
  Wire.setClock(400000L);
#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else                                         // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif                                        // RST_PIN >= 0
  //oled.setFont(X11fixed7x14);
  //oled.setFont(Arial14);

  oled.setFont(Callibri11);   // ok
  //oled.setFont(Callibri11_bold);

  //oled.setFont(Callibri11_italic);
  //oled.setFont(Callibri15);
  //oled.setFont(Corsiva_12);
  //oled.setFont(fixed_bold10x15);   // 12 Zeichen

  //oled.setFont(font5x7);
  //oled.setFont(font8x8);

  //oled.setFont(Iain5x7);
  //oled.setFont(lcd5x7);
  //oled.setFont(Stang5x7);            //  ok

  //oled.setFont(System5x7);
  //oled.setFont(TimesNewRoman16);
  //oled.setFont(TimesNewRoman16_bold);
  //oled.setFont(TimesNewRoman16_italic);
  //oled.setFont(utf8font10x16);
  //oled.setFont(Verdana12);          // ok
  //oled.setFont(Verdana12_bold);
  //oled.setFont(Verdana12_italic);
  //oled.setFont(X11fixed7x14);
  //oled.setFont(X11fixed7x14B);
  //oled.setFont(ZevvPeep8x16);   // 16 Zeichen
}
//------------------------ loop -----
void loop() {
  oled.set1X();
  /* Der Unterschied zwischen print() und println besteht darin,
     dass println() zusätzlich einen Zeilenumbruch nach der Ausgabe einfügt.
  */
  oled.setCursor [size=150](0, 0);[/size]
  oled.print  ("A---Zeile-1-------------E");  // 25 Zeichen
  //oled.println("Zeile a");

  oled.setCursor (0, 2);
  oled.print  ("A---Zeile-2------E");
  //oled.println("Zeile b");

  oled.setCursor (0, 4);
  oled.print  ("A---Zeile-3------E");
  //oled.println("Zeile c");

  oled.setCursor(0, 6);
  //oled.print  ("A----------------E");
  oled.print  ("A---Zeile-4------E");
  //oled.println("Zeile d");
}
Das ist der Grundsketch:

oled.setCursor (0, 0);
oled.print ("A---Zeile-1-------------E"); // 25 Zeichen

oled.setCursor (0, 2);
oled.print ("A---Zeile-2------E");


oled.setCursor (0, 4);
oled.print ("A---Zeile-3------E");

oled.setCursor(0, 6);
oled.print ("A---Zeile-4------E");

oled.jpg
oled.jpg (75.11 KiB) 837 mal betrachtet
Ich kanns mit dem Oled nicht testen. Aber sag mal, was ist beim Oled die Zeile 1?
"oled.setCursor (0, 1);" ?? oder "oled.setCursor (0, 0);" ??
Müßte oled.setCursor (0,0) sein
Grüße aus der Heimat der E69

Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von e69-fan »

Hallo Franz,

ich habe nochmals alles probiert.

Das Problem ist oled.setCursor (0, (fahrt)); da ist nur eine Position 0 und (fahrt) schreibt doch nur den Wert "Fahrt" oder "STOPP" rein?
Grüße aus der Heimat der E69

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von Admin »

Da muss ich dir nur mal die Zusammenhänge erklären. Wenn man in "fahrt" einfach mal was anderes übergibt, dann funktioniert die Tastenabfrage nicht mehr. Da gibt es ein Zusammenspiel mit dem Wert, der in "fahrt" steht. Wenn man die Zeile ändert, müßen ein paar Dinge angepasst werden.

Hast du das Programm schon auf das Oled Display geändert, so dass es grundsätzlich wieder funktioniert wie vorher mit dem 4x20 Display?

Dann kannst du mir das mal hier ins Forum reinhängen. Ich nehme das dann, und passe den Rest an, dass die Ausgabe mit Fahrt und Stopp auch wieder in den richtigen Zeilen klappt. Dann muss ich dir den Ablauf mal verklickern, dass du weißt was das Problem ist.

Franz

Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von e69-fan »

Servus,
Da muss ich dir nur mal die Zusammenhänge erklären. Wenn man in "fahrt" einfach mal was anderes übergibt, dann funktioniert die Tastenabfrage nicht mehr. Da gibt es ein Zusammenspiel mit dem Wert, der in "fahrt" steht. Wenn man die Zeile ändert, müßen ein paar Dinge angepasst werden.

Hast du das Programm schon auf das Oled Display geändert, so dass es grundsätzlich wieder funktioniert wie vorher mit dem 4x20 Display?

Dann kannst du mir das mal hier ins Forum reinhängen. Ich nehme das dann, und passe den Rest an, dass die Ausgabe mit Fahrt und Stopp auch wieder in den richtigen Zeilen klappt. Dann muss ich dir den Ablauf mal verklickern, dass du weißt was das Problem ist.

der aktuelle sketch wurde am Di 27. Apr 2021, 16:16 hochgeladen. Achtung: Problemzeilen sind auskommentiert.
Das Problem ist oled.setCursor (0, (fahrt)); da ist nur eine Position 0 und (fahrt) schreibt doch nur den Wert "Fahrt" oder "STOPP" rein?

Das mit Tasterabfrage und "FAHRT" habe ich verstanden, das Problem ist die Position !!!

Code: Alles auswählen

/*  Dateiname:      Drehscheibe_neu_1_6   by e69-fan

    Beispiel: Stepper_03 von den MobaTools / MoToStepper - attaching a bipolar stepper with step/dir and enable

    StepperMotor ACT 17HS4417L20P1X2
    TB6600 Schrittmotor-Treiber-Modul

    16 MicroStep - 3200 Pulse/Rev -       S1 OFF  / S2 OFF  / S3 ON
    Current Control Setting:  1,5 Ampere  S4 ON   / S5 ON   / S6 OFF

    max. Drehwinkel 370 Grad, dann zurück
    Referenzpunkt bei Position "Einfahrt" in Einzelschritten links/rechts setzen, Bestätigung mit LED
    Blinklicht AN während der Bühnendrehung

    optionale Infoausgabe an LCD-Display 20x4   // A4 =SDA; A5 =SCL; 5V Plus; Masse

    Danke an MicroBahner und Franz54  https://www.franzls-technik-forum.de
                                      https://arduino-fan.de/
*/

#define MAX8BUTTONS
#include <MobaTools.h>

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
// A4 = SDA, grün; A5 = SCL, blau; +5V, rot; Ground, schwarz;


//-----  individuelle Definitionen  -------------------------------------------------- //

// -----------Declarationen Blinklicht-----------------
int LED_PIN = 13;               // Blink-LED auf 13
byte LED = LOW;
byte stopp = 4;
byte fahrt = 4;
unsigned long BLINKIO = 0;
const int delayTime = 300;      // HIGH und LOW Zeit dess Blinksignales
unsigned long VorherMilles = 0;
unsigned long AktuellMilles;

// ----------------------------------------------------
//TMC2209 = 5,6,7 - TB6600 = 36,35,34 - DM556 = 32,31,30


const byte dirPin             = 5;      //  orange
const byte stepPin            = 6;      //  lila
const byte enaPin             = 7;      //  grau

const byte LinksPin           = A1;     //  rot  / 4 steps nach links
const byte RechtsPin          = A2;     //  grün / 4 steps nach rechts
const byte RefPin             = A3;     //  grau / RefPunkt setzen - RefLED leuchtet
const byte RefLED             = 13;     //  gelb / leuchtet wenn RefPunkt gesetzt
const byte piezo              = 3;      //       / ?????????????????????????????????

const byte EinfahrtPin        = 8 ;     //  grün   / Einfahrt Gleis1A - Lok steht vorwärts
const byte V_Ausfahrt_1bPin   = 9 ;     //  gelb   / Ausfahrt Gleis1B - Lok steht vorwärts
const byte WendePin           = 10;     //  blau   / Wendung 180 Grad - Lok steht
const byte SchuppenPin        = 11;     //  grau   / Lokschuppen      - Lok steht
const byte R_Ausfahrt_1bPin   = 12;     //  orange / Ausfahrt Gleis1B - Lok steht rückwärts

const byte potPin       = A0;       // Analog Poti Eingang

int Umdrehungen         = 0;
int Umdrehung_Schritte  = 3200;     // Referenz zur Treibereinstellung Schritte je Umdrehung
int Rampe               = 200;


// -----  Stepper einrichten ( 3200 Schritte / Umdrehung - 1/8 Microstep )-------------------------------------------  //
const int STEPS_REVOLUTION = 3200;                   // Schritte Auftrag für TCM2208 nur 1600

MoToStepper myStepper( STEPS_REVOLUTION, STEPDIR );  // Steps bei xxx pro Umdrehung

// -----  Taster einrichten  ----------------------------------------------------------------------------------------//

enum {                      Button1 = 0,  Button2,    Button3,  Button4,      Button5,          Button6,  Button7,     Button8          } ;    // Den Tasternamen die Indizes 0...3 zuordnen
const byte buttonPins[] = { LinksPin,     RechtsPin,  RefPin,   EinfahrtPin,  V_Ausfahrt_1bPin, WendePin, SchuppenPin, R_Ausfahrt_1bPin } ;    // muss als byte definiert sein, damit ein enfaches sizeof funktioniert
MoToButtons button( buttonPins, sizeof(buttonPins), 20, 500 );


//  -----  speedPoti einrichten  --------------------------------------------------------------------------------------//
MoToTimebase speedIntervall;    // Zeitinterval zum Auslesen des Speedpotentiometers
int vspeed = 0;                 // Steppergeschwindigkeit in U/min*10


// ----------------------------------------- S E T U P -----------------
void setup() {
  
// ------------------OLED Display --------------------------------------
  Wire.begin();
  Wire.setClock(400000L);
#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else                                         // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif                                        // RST_PIN >= 0
  oled.setFont(Callibri11);
// ---------------------------------------------------------------------
  pinMode(RefLED, OUTPUT);
  digitalWrite(RefLED, LOW);
  pinMode(LED_PIN, OUTPUT);

  oled.setCursor (0, 0);
  oled.print (F(""));
  
  oled.setCursor (0, 0);
  oled.print (F("Referenzpunkt ??   "));
  
  oled.setCursor (0, 4);
  oled.print (F("Gleis ?            "));
  
  oled.setCursor (50, 6);   // 50er Einzug in Zeile 6
  oled.print (F("-----"));

  //-----  Stepper  -------------------------------------------------------------------- //
  Umdrehungen = STEPS_REVOLUTION / Umdrehung_Schritte;
  myStepper.attach( stepPin, dirPin );
  myStepper.attachEnable( enaPin, 10, LOW );  // Enable Pin aktivieren ( LOW=aktiv )
  myStepper.setSpeed( 200 );                  // 20 Umdrehungen je Minute
  myStepper.setRampLen( Rampe );              // Rampenlänge 300 Steps bei 20U/min
  speedIntervall.setBasetime( 100 );          // 100ms Tickerzeit
}

void loop() {
  BLINKIO = myStepper.stepsToDo();
  AktuellMilles = millis();
  if (AktuellMilles - VorherMilles >= delayTime) {
    VorherMilles = AktuellMilles;
    LED = !LED;
    if (BLINKIO == 0) {
      LED = 0;
      if (stopp < 4)
      {
        
        //oled.setCursor (0, stopp);               // Ausgabe Position für das Wort "Stopp" übergeben
        //oled.print (F("       Stopp       "));   // durch Leerzeichen mittig ausgerichtet
        stopp = 4;
      }
    }
    digitalWrite(LED_PIN, LED);
  }

  button.processButtons();                                  // Taster einlesen und bearbeiten

  if ( speedIntervall.tick() ) {                            // wird alle 100ms aufgerufen ( Tickerzeit = 100ms im setup() )
    // Speed alle 100ms neu einlesen und setzen
    vspeed = map((analogRead(potPin)), 0, 1023, 20, 240);   // Poti mappen auf 2 ... 240 Umdr/Min
    myStepper.setSpeed( vspeed );                           // min speed =2 and max speed =180 rpm
  }

  //  --------------------------- Referenzpunkt setzen ------------------------------------------------  //
  if (button.pressed(Button1) ) {     // Taster Links gedrückt
    digitalWrite(RefLED, LOW);
    myStepper.doSteps( 4 );           // Stepper dreht 1x links
  }
  if ( button.released(Button1) ) {   // Taster links losgelassen
    myStepper.rotate(0);              // Stepper stoppt
  }
  if (button.pressed(Button2) ) {     // Taster Rechts gedrückt
    digitalWrite(RefLED, LOW);
    myStepper.doSteps( -4 );          // Stepper dreht 1x rechts
  }
  if ( button.released(Button2) ) {   // Taster Rechts losgelassen
    myStepper.rotate(0);              // Stepper stoppt
  }
  if (button.pressed(Button3) ) {     // Taster Ref gedrückt
    myStepper.setZero();              // Referenzpunkt gesetzt
    tone(3, 440, 300);               // Bestätigungston piezo an PIN3, Tonhöhe, ? - Dauer
    digitalWrite(RefLED, HIGH);
    oled.setCursor (0, 0);
    oled.print (F("Referenzpunkt   OK  "));
    
  }

  //  --------------------------- Bühnendrehung ------------------------------------------------  //

  if ((button.pressed(Button4)) && (fahrt == 4)) {      // Taster4 gedrückt:
    tone(3, 440, 300);
    oled.setCursor (0, 4);
    oled.print (F("> Einfahrt Gleis 1A "));
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( 0 );                               // dreht zur Einfahrt Gleis1A zurück
                                                        // zur Startposition
  }

  if ((button.pressed(Button5)) && (fahrt == 4)) {      // Taster5 gedrückt
    oled.setCursor (0, 4);
    oled.print (F("> Ausfahrt Gleis 1B "));
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( 50 );                              // dreht  zur Ausfahrt Gleis1B - vorwärts
  }

  if ((button.pressed(Button6)) && (fahrt == 4)) {      // Taster6 gedrückt:
    oled.setCursor (0, 4);
    oled.print (F("< 180 Wendung        "));
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( -180 );                            // wendet die Bühne um 180 Grad
  }

  if ((button.pressed(Button7)) && (fahrt == 4)) {      // Taster7 gedrückt:
    oled.setCursor (0, 4);
    oled.print (F("< Lokschuppen        "));
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( -250 );                            // dreht zur Abfahrt: Lokschuppen
  }

  if ((button.pressed(Button8)) && (fahrt == 4)) {      // Taster8 gedrückt:
    oled.setCursor (0, 4);
    oled.print (F("< Ausfahrt Gleis 1B ")); 
    fahrt = 3;
    disp();
    stopp = 3;
    myStepper.write( -100 );                            // dreht zur Ausfahrt Gleis1B - rückwärts
  }
}

void disp()
{
  //oled.setCursor (0, 6);
  //oled.print (F("                   "));
  //oled.setCursor (0, (fahrt));                           // Position (Zeile) für das Wort "Fahrt"
  //oled.print (F("       Fahrt       "));
  // 1-----------------20
  fahrt = 4;
}
Grüße aus der Heimat der E69

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von Admin »

Schau mal was damit geht. Ich kann es bei mir nicht testen weil ich dein Display nicht habe und die anderen Zeichensatztreiber auch nicht.

Code: Alles auswählen

/*  Dateiname:      Drehscheibe_neu_1_6   by e69-fan

    Beispiel: Stepper_03 von den MobaTools / MoToStepper - attaching a bipolar stepper with step/dir and enable

    StepperMotor ACT 17HS4417L20P1X2
    TB6600 Schrittmotor-Treiber-Modul

    16 MicroStep - 3200 Pulse/Rev -       S1 OFF  / S2 OFF  / S3 ON
    Current Control Setting:  1,5 Ampere  S4 ON   / S5 ON   / S6 OFF

    max. Drehwinkel 370 Grad, dann zurück
    Referenzpunkt bei Position "Einfahrt" in Einzelschritten links/rechts setzen, Bestätigung mit LED
    Blinklicht AN während der Bühnendrehung

    optionale Infoausgabe an LCD-Display 20x4   // A4 =SDA; A5 =SCL; 5V Plus; Masse

    Danke an MicroBahner und Franz54  https://www.franzls-technik-forum.de
                                      https://arduino-fan.de/
*/

#define MAX8BUTTONS
#include <MobaTools.h>

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire oled;
// A4 = SDA, grün; A5 = SCL, blau; +5V, rot; Ground, schwarz;


//-----  individuelle Definitionen  -------------------------------------------------- //

// -----------Declarationen Blinklicht-----------------
int LED_PIN = 13;               // Blink-LED auf 13
byte LED = LOW;
byte stopp = 8;
byte fahrt = 8;
unsigned long BLINKIO = 0;
const int delayTime = 300;      // HIGH und LOW Zeit dess Blinksignales
unsigned long VorherMilles = 0;
unsigned long AktuellMilles;

// ----------------------------------------------------
//TMC2209 = 5,6,7 - TB6600 = 36,35,34 - DM556 = 32,31,30


const byte dirPin             = 5;      //  orange
const byte stepPin            = 6;      //  lila
const byte enaPin             = 7;      //  grau

const byte LinksPin           = A1;     //  rot  / 4 steps nach links
const byte RechtsPin          = A2;     //  grün / 4 steps nach rechts
const byte RefPin             = A3;     //  grau / RefPunkt setzen - RefLED leuchtet
const byte RefLED             = 13;     //  gelb / leuchtet wenn RefPunkt gesetzt
const byte piezo              = 3;      //       / ?????????????????????????????????

const byte EinfahrtPin        = 8 ;     //  grün   / Einfahrt Gleis1A - Lok steht vorwärts
const byte V_Ausfahrt_1bPin   = 9 ;     //  gelb   / Ausfahrt Gleis1B - Lok steht vorwärts
const byte WendePin           = 10;     //  blau   / Wendung 180 Grad - Lok steht
const byte SchuppenPin        = 11;     //  grau   / Lokschuppen      - Lok steht
const byte R_Ausfahrt_1bPin   = 12;     //  orange / Ausfahrt Gleis1B - Lok steht rückwärts

const byte potPin       = A0;       // Analog Poti Eingang

int Umdrehungen         = 0;
int Umdrehung_Schritte  = 3200;     // Referenz zur Treibereinstellung Schritte je Umdrehung
int Rampe               = 200;


// -----  Stepper einrichten ( 3200 Schritte / Umdrehung - 1/8 Microstep )-------------------------------------------  //
const int STEPS_REVOLUTION = 3200;                   // Schritte Auftrag für TCM2208 nur 1600

MoToStepper myStepper( STEPS_REVOLUTION, STEPDIR );  // Steps bei xxx pro Umdrehung

// -----  Taster einrichten  ----------------------------------------------------------------------------------------//

enum {                      Button1 = 0,  Button2,    Button3,  Button4,      Button5,          Button6,  Button7,     Button8          } ;    // Den Tasternamen die Indizes 0...3 zuordnen
const byte buttonPins[] = { LinksPin,     RechtsPin,  RefPin,   EinfahrtPin,  V_Ausfahrt_1bPin, WendePin, SchuppenPin, R_Ausfahrt_1bPin } ;    // muss als byte definiert sein, damit ein enfaches sizeof funktioniert
MoToButtons button( buttonPins, sizeof(buttonPins), 20, 500 );


//  -----  speedPoti einrichten  --------------------------------------------------------------------------------------//
MoToTimebase speedIntervall;    // Zeitinterval zum Auslesen des Speedpotentiometers
int vspeed = 0;                 // Steppergeschwindigkeit in U/min*10


// ----------------------------------------- S E T U P -----------------
void setup() {
  
// ------------------OLED Display --------------------------------------
  Wire.begin();
  Wire.setClock(400000L);
#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else                                         // RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif                                        // RST_PIN >= 0
  oled.setFont(Callibri11);
// ---------------------------------------------------------------------
  pinMode(RefLED, OUTPUT);
  digitalWrite(RefLED, LOW);
  pinMode(LED_PIN, OUTPUT);

  oled.setCursor (0, 0);
  oled.print (F("MobaStepper_Oled_V1_"));
  
  oled.setCursor (0, 2);
  oled.print (F("Referenzpunkt ??   "));
  
  oled.setCursor (0, 4);
  oled.print (F("Gleis ?            "));
  
  oled.setCursor (50, 6);   // 50er Einzug in Zeile 6
  oled.print (F("-----"));

  //-----  Stepper  -------------------------------------------------------------------- //
  Umdrehungen = STEPS_REVOLUTION / Umdrehung_Schritte;
  myStepper.attach( stepPin, dirPin );
  myStepper.attachEnable( enaPin, 10, LOW );  // Enable Pin aktivieren ( LOW=aktiv )
  myStepper.setSpeed( 200 );                  // 20 Umdrehungen je Minute
  myStepper.setRampLen( Rampe );              // Rampenlänge 300 Steps bei 20U/min
  speedIntervall.setBasetime( 100 );          // 100ms Tickerzeit
}

void loop() {
  BLINKIO = myStepper.stepsToDo();
  AktuellMilles = millis();
  if (AktuellMilles - VorherMilles >= delayTime) {
    VorherMilles = AktuellMilles;
    LED = !LED;
    if (BLINKIO == 0) {
      LED = 0;
      if (stopp < 8)
      {
        
        //oled.setCursor (0, stopp);               // Ausgabe Position für das Wort "Stopp" übergeben
        //oled.print (F("       Stopp       "));   // durch Leerzeichen mittig ausgerichtet
        stopp = 8;
      }
    }
    digitalWrite(LED_PIN, LED);
  }

  button.processButtons();                                  // Taster einlesen und bearbeiten

  if ( speedIntervall.tick() ) {                            // wird alle 100ms aufgerufen ( Tickerzeit = 100ms im setup() )
    // Speed alle 100ms neu einlesen und setzen
    vspeed = map((analogRead(potPin)), 0, 1023, 20, 240);   // Poti mappen auf 2 ... 240 Umdr/Min
    myStepper.setSpeed( vspeed );                           // min speed =2 and max speed =180 rpm
  }

  //  --------------------------- Referenzpunkt setzen ------------------------------------------------  //
  if (button.pressed(Button1) ) {     // Taster Links gedrückt
    digitalWrite(RefLED, LOW);
    myStepper.doSteps( 4 );           // Stepper dreht 1x links
  }
  if ( button.released(Button1) ) {   // Taster links losgelassen
    myStepper.rotate(0);              // Stepper stoppt
  }
  if (button.pressed(Button2) ) {     // Taster Rechts gedrückt
    digitalWrite(RefLED, LOW);
    myStepper.doSteps( -4 );          // Stepper dreht 1x rechts
  }
  if ( button.released(Button2) ) {   // Taster Rechts losgelassen
    myStepper.rotate(0);              // Stepper stoppt
  }
  if (button.pressed(Button3) ) {     // Taster Ref gedrückt
    myStepper.setZero();              // Referenzpunkt gesetzt
    tone(3, 440, 300);               // Bestätigungston piezo an PIN3, Tonhöhe, ? - Dauer
    digitalWrite(RefLED, HIGH);
    oled.setCursor (0, 0);
    oled.print (F("Referenzpunkt   OK  "));
    
  }

  //  --------------------------- Bühnendrehung ------------------------------------------------  //

  if ((button.pressed(Button4)) && (fahrt == 8)) {      // Taster4 gedrückt:
    tone(3, 440, 300);
    oled.setCursor (0, 4);
    oled.print (F("> Einfahrt Gleis 1A "));
    fahrt = 6;
    disp();
    stopp = 6;
    myStepper.write( 0 );                               // dreht zur Einfahrt Gleis1A zurück
                                                        // zur Startposition
  }

  if ((button.pressed(Button5)) && (fahrt == 8)) {      // Taster5 gedrückt
    oled.setCursor (0, 4);
    oled.print (F("> Ausfahrt Gleis 1B "));
    fahrt = 6;
    disp();
    stopp = 6;
    myStepper.write( 50 );                              // dreht  zur Ausfahrt Gleis1B - vorwärts
  }

  if ((button.pressed(Button6)) && (fahrt == 8)) {      // Taster6 gedrückt:
    oled.setCursor (0, 4);
    oled.print (F("< 180 Wendung        "));
    fahrt = 6;
    disp();
    stopp = 6;
    myStepper.write( -180 );                            // wendet die Bühne um 180 Grad
  }

  if ((button.pressed(Button7)) && (fahrt == 8)) {      // Taster7 gedrückt:
    oled.setCursor (0, 4);
    oled.print (F("< Lokschuppen        "));
    fahrt = 6;
    disp();
    stopp = 6;
    myStepper.write( -250 );                            // dreht zur Abfahrt: Lokschuppen
  }

  if ((button.pressed(Button8)) && (fahrt == 8)) {      // Taster8 gedrückt:
    oled.setCursor (0, 4);
    oled.print (F("< Ausfahrt Gleis 1B ")); 
    fahrt = 6;
    disp();
    stopp = 6;
    myStepper.write( -100 );                            // dreht zur Ausfahrt Gleis1B - rückwärts
  }
}

void disp()
{
  //oled.setCursor (0, (fahrt));
  //oled.print (F("                   "));
  //oled.setCursor (0, (fahrt));                           // Position (Zeile) für das Wort "Fahrt"
  //oled.print (F("       Fahrt       "));
  //
  fahrt = 8;
}

Benutzeravatar
e69-fan
Beiträge: 282
Registriert: Mi 20. Jan 2021, 10:32
Wohnort: Murnau am Staffelsee

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von e69-fan »

Danke Franz,

funktioniert jetzt !!!

:(V):

muss jetzt nur noch alles zusammenbauen.
Grüße aus der Heimat der E69

Benutzeravatar
Admin
Administrator
Beiträge: 760
Registriert: Mo 20. Apr 2020, 09:47
Wohnort: 82441 Ohlstadt
Kontaktdaten:

Re: Schrittmotorsteuerung für Drehscheibe

Beitrag von Admin »

Alles klar. Super :(V):

Mal für dich zur übersicht.
Ich übergebe in der "stopp" und in "fahrt" immer die Zeile in der diese Worte ausgegeben werden müßen. Das war besonders dann gut, wenn man 4 Verschiedene Zeilen im Display für die Ausgabe hat. so wie ich es am Anfang hatte. Aber das ganze hat noch einen anderen, wichtigeren Grund.
Am Anfang hatte ich 4 Zeilen im Display. Die Zeilen 0, 1, 2, 3. Also wurde beim Taster 4 für die erste Zeile die "0" übergeben. Das selbe für 1 , 2, 3. bei Taster 5, 6 ,7.
Wenn das Wort "Fahrt" ist Display geschrieben wurde, wurde in "fahrt" die "4" eingetragen. Es gab keine Zeile "4". Die "4" heißt nur für´s Programm, dass das Wort nicht nochmal und nochmal und nochmal ausgegeben wird. Den dann würde das Display flackern. Also wurde als Quittung für die erfolgte Ausgabe des Wortes "Fahrt" in den Zeilemerker "fahrt" die "4" eingetragen. Das selbe gilt für das Wort "Stopp". Wenn das Wort "Stopp" in der Vorgesehen Zeile ausgegeben wurde, wurde in den Merker "stopp" anstelle der eigentlichen Zeilennummer, die "4" ausgegeben. Das sorgte auf hier dafür, dass das Wort "Stopp" nur einmal im Display ausgegeben wurde. Also wieder nur deshalb, das das Display nicht andauernde erneute Ausgabe des Wortes "Stopp" flackert.
Jetzt haben wir es geändert. Jetzt wird bei jedem Tastendruck die Zeilennummer "6" ausgeben. wenn das Wort "Fahrt" in Display geschrieben wurde, wird in den "fahrt" Merker die "8" eingetragen. Das heißt wieder, das Wort wurde ausgeben und muss nicht nochmal ausgegeben werden. Das selbe beim "stopp" Merker. "6" für die Zeile in der das Wort ausgegeben werden muss, "8" dafür, dass das Wort nicht mehr ausgegeben werden muss.

Drückt man wieder eine neue Gleistaste werden die Merker "fahrt" und "stopp" wieder auf "6" gesetzt, das Wort "Fahrt" wie das Wort "Stopp" wird eimal ausgegeben und die Merker werden sofort nach der Ausgabe des jeweiligen Wortes wieder auf "8" gesetzt, also auf Ausgabe Ende.

Ich habe übrigens gerade noch einen kleinen Fehler bemerkt. Oben in der Deklaration der Merker, wird bei dem Programm für dich noch in "stopp" und in "fahrt" eine "4" übergeben. Daher wird das Wort "Stopp" gleich nach dem Programmstart in die letzte Zeile geschrieben, ohne dass du eine Taste gedrückt hast. Da muss die "8" übergeben werden, nicht die "4". Das ist noch aus dem alten Programm mit meinem VGA Display.

Also diese Deklaration muss so aussehen:

Code: Alles auswählen

// -----------Declarationen Blinklicht-----------------
int LED_PIN = 13;               // Blink-LED auf 13
byte LED = LOW;
byte stopp = 8;
byte fahrt = 8;
unsigned long BLINKIO = 0;
const int delayTime = 300;      // HIGH und LOW Zeit dess Blinksignales
unsigned long VorherMilles = 0;
unsigned long AktuellMilles;

Antworten

Zurück zu „Fertige Projekte Vorstellen“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast