Anfänger ist am verzweifeln - Menü Taster und Schrittmotor Ansteuerung

Hallo erst mal an alle,

ich heiße Jürgen bin 50 Jahre und purer Anfänger in der ArduinoWelt :wink:

Warum ich Hilfe brauche... ich bastle gerade an einem Turntable für die 360° Fotografie und der Arduino Uno macht nicht was ich will :confused: :slight_smile:

Ich möchte ein Menü am LCD ausgeben, wo ich wählen kann wie viele Photos ich schießen möchte... 8/12/24/32 etc. Der Schrittmotor fährt mir dann die Schritte/Positionen an.. klappt ohne Menü bereits bestens.

Soooo... ich hab da jetzt 4 Taster... UP/DOWN/SELECT und den einen Taster(für weiteres Photo) für den nächsten Schritt an zu fahren.

Heißt, ich wähle im Menü "Programm 24"... also 24 Photos... dann schieße ich das erste Photo... drücke dann den Taster um das zweite Photo zu schießen usw. (am Ende sollte er dann wieder ins Menü zurück)

Ich weis nicht wie, ich das anpacken soll?? Vielleicht hat jemand nur eine Ansatz für mich :slight_smile:

Hier mal der Versuch Sketch:

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

LiquidCrystal_I2C lcd(0x27, 20, 4);

// Menueführung
int upButton = 7;
int downButton = 6;
int selectButton = 4;
int menu = 1;
int LEDblau = 13; // CNC Shield Spin Dir nur zum testen

// Stepper und Pins
int ENA = 8; // EnabelPin
int STP = 2; // StepPin
int DIR = 5; // DIR Uhrzeigersinn
int stepCounter;
int steps;

// Taster für Start der Umdrehungen/Schritte / am Shield GND = GND rechts unten
int TasterStart = 3; // Pin am CNC Shield Y-Achse STP
int ZaehlerStart = 0; // Zahler für TasterStart
int set = 0; // Merker

////////////////////////////////////////////////////////////

void setup() {
// Stepper Pins setzen 
pinMode(ENA, OUTPUT); // Enable ENA
pinMode(STP, OUTPUT); // Step STP
pinMode(DIR, OUTPUT); // Richtung DIR
digitalWrite(ENA,LOW);

// Led und Taster für WeiterSchritt 
pinMode(LEDblau, OUTPUT); // Led
pinMode(TasterStart, INPUT); // Taster der die Schritte am Stepper auslöst
digitalWrite(TasterStart, HIGH); // Taste geöffneter

// LCD und Menütasten 
 lcd.init();
 lcd.backlight();
 pinMode(upButton, INPUT_PULLUP);
 pinMode(downButton, INPUT_PULLUP);
 pinMode(selectButton, INPUT_PULLUP);
 updateMenu();
}

void loop() {
 if (!digitalRead(downButton)){
   menu++;
   updateMenu();
   delay(100);
   while (!digitalRead(downButton));
 }
 if (!digitalRead(upButton)){
   menu--;
   updateMenu();
   delay(100);
   while(!digitalRead(upButton));
 }
 if (!digitalRead(selectButton)){
   executeAction();
   updateMenu();
   delay(100);
   while (!digitalRead(selectButton));
 }

}

void updateMenu() {
 switch (menu) {
   case 0:
     menu = 1;
     break;
   case 1:
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(">Programm 8  Photos");
     lcd.setCursor(0, 1);
     lcd.print(" Programm 12 Photos");
     lcd.setCursor(0, 2);
     lcd.print(" Programm 24 Photos");
     lcd.setCursor(0, 3);
     lcd.print(" Programm 32 Photos");
     break;
   case 2:
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(" Programm 8  Photos");
     lcd.setCursor(0, 1);
     lcd.print(">Programm 12 Photos");
     lcd.setCursor(0, 2);
     lcd.print(" Programm 24 Photos");
     lcd.setCursor(0, 3);
     lcd.print(" Programm 32 Photos");
     break;
   case 3:
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(" Programm 8  Photos");
     lcd.setCursor(0, 1);
     lcd.print(" Programm 12 Photos");
     lcd.setCursor(0, 2);
     lcd.print(">Programm 24 Photos");
     lcd.setCursor(0, 3);
     lcd.print(" Programm 32 Photos");
     break;
   case 4:
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(" Programm 8  Photos");
     lcd.setCursor(0, 1);
     lcd.print(" Programm 12 Photos");
     lcd.setCursor(0, 2);
     lcd.print(" Programm 24 Photos");
     lcd.setCursor(0, 3);
     lcd.print(">Programm 32 Photos");
     break;
   case 5:
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(">Programm 64  Photos");
     lcd.setCursor(0, 1);
     lcd.print(" Programm 94  Photos");
     lcd.setCursor(0, 2);
     lcd.print(" Programm 193 Photos");
     lcd.setCursor(0, 3);
     lcd.print(" Programm 360 Grad");
     break;
   case 6:
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(" Programm 64  Photos");
     lcd.setCursor(0, 1);
     lcd.print(">Programm 94  Photos");
     lcd.setCursor(0, 2);
     lcd.print(" Programm 193 Photos");
     lcd.setCursor(0, 3);
     lcd.print(" Programm 360 Grad");
     break;
   case 7:
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(" Programm 64  Photos");
     lcd.setCursor(0, 1);
     lcd.print(" Programm 94  Photos");
     lcd.setCursor(0, 2);
     lcd.print(">Programm 193 Photos");
     lcd.setCursor(0, 3);
     lcd.print(" Programm 360 Grad");
     break;
   case 8:
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(" Programm 64  Photos");
     lcd.setCursor(0, 1);
     lcd.print(" Programm 94  Photos");
     lcd.setCursor(0, 2);
     lcd.print(" Programm 193 Photos");
     lcd.setCursor(0, 3);
     lcd.print(">Programm 360 Grad");
     break;
   case 9:
     menu = 8;
     break;
 }
}

void executeAction() {
 switch (menu) {
   case 1:
     action1();
     break;
   case 2:
     action2();
     break;
   case 3:
     action3();
     break;
   case 4:
     action4();
     break;
   case 5:
     action5();
     break;
   case 6:
     break;
   case 7:
     action7();
     break;
   case 8:
     action8();
     break;
 }
}
//// void actionX()
///////////////// 8 Photos /////////////////
void action1() {
 steps = 80;
 lcd.clear();
 lcd.setCursor(0,0);
 lcd.print(">Executing #8");
 lcd.setCursor(0, 1);
 lcd.print(steps);
 
if (!digitalRead(TasterStart) == LOW && set == 0) {
   ZaehlerStart++;
   lcd.setCursor(6,3);
   lcd.print( ZaehlerStart );
   set=1; 
 } 
 
 if (!digitalRead(TasterStart) == HIGH && set == 1) {
   delay(500);
   set=0; 
 }

for(stepCounter = 0; stepCounter < steps; stepCounter++)
{
// LED blinkt
digitalWrite(LEDblau, HIGH);
delay(500);
digitalWrite(LEDblau, LOW);
delay(500);
// Stepper
digitalWrite(STP,HIGH);
delayMicroseconds(500);
digitalWrite(STP,LOW);
delayMicroseconds(500);
}
}
///////////////// 12 Photos /////////////////
void action2() {
 steps = 12;
 lcd.clear();
 lcd.print(">Executing #12");
 lcd.setCursor(0, 1);
 lcd.print(steps);
 delay(1500);
}

void action3() {
 steps = 24;
 lcd.clear();
 lcd.print(">Executing #24");
 lcd.setCursor(0, 1);
 lcd.print(steps);
 delay(1500);
}
void action4() {
 lcd.clear();
 lcd.print(">Executing #32");
 delay(1500);
}
void action5() {
 lcd.clear();
 lcd.print(">Executing #64");
 delay(1500);
}
void action6() {
 lcd.clear();
 lcd.print(">Executing #94");
 delay(1500);
}
void action7() {
 lcd.clear();
 lcd.print(">Executing #193");
 delay(1500);
}
void action8() {
 lcd.clear();
 lcd.print(">Executing #360 Grad");
 delay(1500);
}

Ich weis, könnte sicher besser programmiert sein, aber ich bin ja erst noch am START :slight_smile:
Bitte, nehmt mich nicht zu sehr in die Mangel :confused: :slight_smile:

Vielen Dank für die Tips.

Gruß
Jugii

Den Code bitte in Codetags posten. Das geht im erweiterten Editor "Preview" mit </>

Sorry... erledigt :slight_smile:

Jugii:
Sorry... erledigt :slight_smile:

Kein Grund sich zu entschuldigen. Die Foresoftware ist unter aller Sau.

Hallo,

ich hab mir jetzt Dein Program nicht genau angesehen, aber hab ich das richtig verstanden. Du hast :

2 Taster auf/ ab -> Auswahl des Programes
1 Taster start -> das mit auf / ab ausgewählte Program wird gestartet 1. Position anfahren, 1. Foto machen.
1 Taster weiter nexter schritt.-> nexte Position anfahren für nextes Foto

Willst Du zwischendurch abbrechen (reset) können oder willst Du erst erneut in den Modus auf ab wenn alle Positionen abgefahren sind. Eigendlich die perfekte Aufgabe für eine Schrittkette, eventuell mit einem Rückwärtszähler und 2-3 status Variablen.

schau dir mal die lib oneButon an , damit kann man mehrere Funktionen auf einen Taster legen.

kurz, doppel, lang

Heinz

Hi

Was mir 'verbesserungswürdig' an dem Sketch auffällt:

  • Pin-Nummern sind als int, sollten const byte sein - oder erwartest Du negative Pin-Nummern?
  • Zähler ist int, sollte unsigned int oder byte sein - je nach Anzahl der benötigten Schritte - wir erwarten hier keine negativen Schritte (signed unnötig, der halbe Zahlenraum dadurch verschenkt)
  • delay(100); ... während delay() macht der Arduino nicht viel - zumindest schafft Er nicht am Programm - siehe Dir 'blink_without_delay' aus der IDE an, hier im Forum gibt's die von combie eine Liste zum Thema State-Maschine
  • Deine Menü's sind 'Alles das Gleiche' - Du kannst auch menu*4 +1,+2,+3 anzeigen und brauchst Damit nur EINE Ausgabe. Die Werte variieren ggf. bei Dir, dann muß Es eben x12 oder so werden.
    Die 193 erschließen sich mir nicht :wink:
  • der Stepper und die Blinke-LED per delay() - dazu hast Du ja schon Was gelesen :wink:
  • nur action1() enthält sinnvollen Code, oder? Da Das Alles immer das Gleiche ist (nur mit anderen Schrittzahlen o.Ä.), lässt Sich Das in eine eigene Funktion auslagern und Du kommst mit EINER Funktion und der übergebenen Anzahl an Schritten/whatever aus.

Ist Alles Nichts, was einen Weltuntergang herauf beschwört, geht aber halt schöner.

MfG

Hey hey postmaster-ino,

erst mal Danke für deinen Post :slight_smile:

Ich bin purer Anfänger... ich hab das Sketch zusammen gestöpselt aus TUT's.

Weis, dass es besser geht... und vor allem seeehr kürzer. :wink:
Nur WIE? :o :cold_sweat:

Int... const byte... ich glaub muss mich da noch mal hinsetzten und lernen!!

Heinz hat es schon fast richtig erkannt mit den Tastern.

  • 2 Taster um das Menü zu bedienen rauf/runter
  • 1 Taster um es auszuwählen und zu bestätigen, dann...
  • Programm wird gestartet( z.B 24 Fotos) und wartet bis ich Taster 4 bediene um die ersten z.B. 15° Grad anzufahren
  • Ich drücke wieder Taster 4... um die nächsten/weiteren 15° anzufahren
    usw.
  • Am Ende dann zurück ins Menü
  • Option im Programm ist.. es abbrechen zu können (steht erst mal auf der Warteliste :wink: )

Zu 193 Fotos... das ergibt sich durch die Schritte des Steppers(1600) und Verhältnis bzw. Übersetzung des Getriebes(Stirnrad 12 Zähne und Zahndrehkranz 139 Zähne) Übersetzung 1:11,58.33333 :wink:

Also für eine ganze Umdrehung 360° werden für den Stepper 18528 Steps benötigt.
Teilbare Summen ergibt: 1,2,3,4,6,8,12,16,24,32,48,96,193 :roll_eyes: ;D
Darum die 193 :wink: Bin ja noch am testen ;D

Ich bin für jede Hilfe dankbar.

Gruß
Jugii

Hi

char -127...128
byte 0...255
unsigned int 0...65535
int -32768...32767
Die andere Darstellung uint8_t besagt
-u unsigned (weglassen für signed)
-int integer - also GANZ-Zahlen, nix mit Komma
-8 die Bitbreite (hier also 256, 2^8 wäre der komplette Zahlenvorrat, bei SIGNED ist die Hälfte davon aber Negativ)
_t ... jo, gute Frage - nimm's so hin :wink:

const sagt dem Kompiler, daß dieser Wert FEST ist, sich NIE ändern wird.
So kann Er diesen Wert auch fest im Code einbetten - Das kann man mit Allem machen, was sich NIE ändern wird - Nie im Sinne von 'in der Laufzeit' - wenn man neu kompiliert darf hier auch eine andere Pin-Nummer stehen :wink:
Feste Nummern können direkt im Maschinencode eingearbeitet werden, macht die Befehle kürzer und den ganzen Kram schneller (kein Zugriff auf Speicher nötig - der Wert könnte ja sonst 'jetzt' anders sein).

Deine Erklärung zur 193 gefällt mir :slight_smile:

Du hast hier eigentlich eine schöne State-Maschine beschrieben - mache 'das und das, wenn das und das' - oder 'wenn das und das, wechsle in State x'.
Dazu sind die 'combie-Links' recht brauchbar.

Wenn Dein Programm läuft und in den Käfer rein passt (... sonst würde Es ja auch nicht laufen ...) ist Alles ok, ein funktionierendes Programm ist ein gutes Programm - bei Anpassungen oder einem neuen Programm sollte man aber das neue Wissen einfließen lassen.

Ob Deine ganze Knöpfchen-Drückerei nötig ist, wirst Du besser beantworten können - meinem Empfinden nach sollte der Stepper nach der Ansteuerung der x Schritte damit auch fertig sein und somit kann ich das Foto eigentlich direkt auslösen - ohne weiteren Knopf-Druck.
Das hast Du aber, als Praktiker, wohl besser auf dem Schirm - ich kenne Dein Problem nur von Außen und kann - nach Herzenslust :wink: - kritisieren - bitte nicht persönlich nehmen.

MfG

Edit
@Tommy56
Danke für die Korrektur - hab's angepasst (... dürfte eigentlich nicht passieren ... sorry)

postmaster-ino:
unsigned int -32768...32767
int 0...65535

Da hast Du was verwechselt.

Gruß Tommy

Hey Hey postmaster-ino,

Duuu sollst kritisieren... BITTE ;D

Alsoooo im Moment hab ich noch gaaaaar nix am Schirm ::slight_smile:
Hoffe, bald mal ein kleines Pixel am Schirm zu haben... und es mehr und mehr werden... und auch heller dann für mich wird ;D

Hab jetzt mal den KOPFTEIL des Sketch geändert / Zuordnung PIN's etc.

Schnipp...

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

LiquidCrystal_I2C lcd(0x27, 20, 4);

// Menueführung
const int upButton = 7;
const int downButton = 6;
const int selectButton = 4;
byte menu = 1;
const int LEDblau = 13; // CNC Shield Spin Dir nur zum testen

// Stepper und Pins
const int ENA = 8; // EnabelPin
const int STP = 2; // StepPin
const int DIR = 5; // DIR Uhrzeigersinn
unsigned int stepCounter;
unsigned int steps;

// Taster für Start der Umdrehungen/Schritte
const int TasterStart = 3; // Pin am CNC Shield Y-Achse STP
byte ZaehlerStart = 0; // Zahler für TasterStart
byte set = 0; // Merker

////////////////////////////////////////////////////////////

void setup() {
// Stepper Pins setzen 
pinMode(ENA, OUTPUT); // Enable ENA
pinMode(STP, OUTPUT); // Step STP
pinMode(DIR, OUTPUT); // Richtung DIR
digitalWrite(ENA,LOW);
...

Schapp...

Ob das jetzt sooo richtig ist???????

Zu "Du hast hier eigentlich eine schöne State-Maschine beschrieben" Dank dir recht herzlich dafür. Ich weiß, was es machen soll das Dingen's :wink:

Diiiiie "Knöpfchen-Drückerei" bzgl. für weiteren Schritt(z.B nächsten 15° anfahren) ist sosso... sollte ich mal kurz um die Ecke gehen müssen... oder weist was Jugii , drink mal ein kleines Bierchen zwischen durch.. bei fotografieren... ist das Problem ;D ;D ;D

Der Arduino würde alle 8/12/24/32... kontinuierlich anfahren... und es würde dann kein Foto geben :stuck_out_tongue:
Darum, hab Zeit für's nächstes Foto... und drück dann den Taster, wenn ich wieder Zeit hab um ein weiters Foto zu schießen.

Hoffe, finde Zeit am WE mich ein bisschen weiter ein zu arbeiten...

Und ich freue mich sehr über weitere Tips. Danke euch allen :wink:

LG
Jugii

Soweit ich es sehe, müßte executeAction() häufiger aufgerufen werden. Da könnte ein Merker helfen:

 if (!digitalRead(selectButton)){
   merker = true;
   updateMenu();
   delay(100);
   while (!digitalRead(selectButton));
 }
 if(merker) executeAction();

Nach Abschluß der Drehung muß noch merker=false; ausgeführt werden.

Hallo,

ich hab mal etwas mit Deiner Aufgabenstellung beschäftigt. Was mich etwas an Deinem Ansatz etwas stört ist das Du eigendlich sehr viel Gleiches programiert hast , da könnte man einigens durch geeignete Variablentypen vereinfachen. Eventuell hast Du dich noch nicht mit Arrays beschäftigt. Die Verwendung von Arrays oder auch Strukturen bietete sich hier jedoch stark an , um die Daten deiner Auswahl zu verarbeiten.

Ich hab jetzt mal einen bewust kleinen Ansatz gewählt und in einem Array die Anzahl der zu machenden Fotos untergebracht. Der Verstellwinkel ergibt sich aus der Anzahl der zu machenden Fotos. Bei 4 Fotos also 0,90,180,270 damit sind 4 Fotos gemacht. In einen zusätzlichen Schritt wird dann auf 360 gefahren damit die Anfangsposition wieder erreicht ist.

Die Ausgaben gehen auf die Serielle Schnittstelle, das must Du dann noch ändern. Ebenfalls hab ich die Taster lediglich mit delay entprellt und eigendlich gehört da auch noch eine Flankenerkennung fur jeden Taster rein, desshalb ist das delay auch ziemlich lang. Aber es laüft so , und mit ging es darum Dir zu zeigen was man mit Array´s machen kann.

Heinz

/* Hardware UNO 
 *  Anschluss 4 Taster gegen 0 Volt
 *  Steppermotor 28BY J-48
 * 
 */
#include <Stepper.h>
const int stepsPerRev = 2038; // Motor Schritte / Umdrehung

int program;// Programmnummer
byte maxprog = 5;
int anzfotos[8] = {4, 8,12, 16, 32, 64};// Anzahl Fotos je Programe

// Variable
byte count;
float Position; // hier float wegen wiederholter Rungungsfehler 
float stepToGo;

// Taster zur Menue Bedienug
byte btn_up = 2;    // Programm auf
byte btn_down = 3;  // Program ab
byte btn_sel = 4;   // Programm auswählen
byte btn_next = 5;  // Next Step

// Status Variable
bool stat_ausw;
bool stat_sel;
bool stat_next;

Stepper myStepper(stepsPerRev, 8, 10, 9, 11);


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  myStepper.setSpeed(10);
  pinMode(btn_up, INPUT_PULLUP);
  pinMode(btn_down, INPUT_PULLUP);
  pinMode(btn_sel, INPUT_PULLUP);
  pinMode(btn_next, INPUT_PULLUP);

  stat_ausw = true;
  stat_sel = false;
  stat_next = false;

  // Startanzeige
  Serial.print("Vorwahl Program "); Serial.println(program);
  Serial.print("Anzahl Fotos "); Serial.println(anzfotos[program]);

}

void loop() {
  // put your main code here, to run repeatedly:

  // ----------Auswahl aktiv
  if (stat_ausw) {
    if (digitalRead(btn_up ) == 0) {
      program ++;
      if (program > maxprog)program = 0;
      Serial.print("Vorwahl Program "); Serial.println(program);
      Serial.print("Anzahl Fotos "); Serial.println(anzfotos[program]);
      delay(200);// entprellen und doppel vermeiden
    }
    if (digitalRead(btn_down) == 0) {
      program --;
      if (program < 0 )program = maxprog;
      Serial.print("Vorwahl Program"); Serial.println(program);
      Serial.print("Anzahl Fotos "); Serial.println(anzfotos[program]);
      delay(200);
    }
  }
  // ---------Program ist ausgewählt
  if (digitalRead(btn_sel) == 0 && stat_ausw == true) {
    delay(200);
    stat_ausw = false;
    stat_sel = true;
    Position = 0;
    stepToGo = 360.0 / anzfotos[program];
    Serial.print("Gestartet anzahl Fotos");
    Serial.println(anzfotos[program]);
    Serial.print("Schrittweite"); Serial.println(stepToGo);
    Serial.print("aktuelle Position"); Serial.println(Position);
    Serial.println("jetzt erstes Foto machen, danach next Buton");
    count = anzfotos[program];

    stat_next = true;
    stat_sel = false;

  }
  // --------Next Buton aktiv
  if (digitalRead(btn_next) == 0 && stat_next == true) {
    delay(200);

    if ( count > 0) {
      Position = Position + stepToGo;
      Serial.print("aktuelle Position"); Serial.println(Position);
      move_stepper();
      if (count > 1)Serial.println("jetzt Foto machen");
      count --;
    }
    if (count == 1) {
      Serial.println("jetzt Letzes Foto machen, danach nochmals Next Buton");
    }

    if (count == 0) {
      Serial.println("Vorgang beendet , Auswahlmodus");
      stat_next = false;
      stat_ausw = true;
    }
  }


}
//-------Ansteuerung des Steppermotors

void move_stepper() {
  int steps;
  steps = stepToGo * stepsPerRev / 360;
  myStepper.step(steps);
}

Hey hey,

Heinz... wooooow... SPITZE... merciii Dir für den Ansatz :wink:

Jaa, das ist genau das, dass ich brauche.

Hab mich jetzt damit etwas gespielt und komme ganz gut klar.

Jap, ich hab etwas Ahnung vom programmieren... nur ich programmiere in perl und php...
Und hier ist es doch ein bisschen anders...

array... weis wie sie funktioniert z.B. in perl so...
schnipp...

my @photos = ("1 Photo", "2 Photos", "3 Photos");
foreach my $view (@photos) {
  out $view;
}

schnapp... :wink: 8)

Sooo, nun zu meiner Hardware:
Arduino Uno, CNC Shield V3.0, StepperDriver A4988, Stepper Nema17 und LCD 20x4 mit I2C Interface

Die #include <Stepper.h> ist für den Steppermotor 28BY J-48 ausgelegt hab ich gesehen.
Ich weis jetzt nicht, ob man diese auch für den StepperDriver A4988 verwenden kann???

Die Variable:
Stepper myStepper(stepsPerRev, 8, 10, 9, 11);
macht mir bisschen Kopfzerbrechen... :fearful:

Bei mir sind die Pins soo angelegt (CNC Shield V3.0 - verwende die X-Achse)
// Stepper und Pins
int ENA = 8; // EnabelPin
int STP = 2; // StepPin
int DIR = 5; // DIR Richtung Uhrzeigersinn

Bisschen Angst hab ich bei schon... weil ich jaaaa bereits einen Arduino UNO und einen StepperDriver A4988 GEGRILLT hab :roll_eyes: :stuck_out_tongue_closed_eyes:

Hab gelesen, ist ganz normal... jeder muss sein Leeehrgeld zahlen ;D

Bin für jede weitere Hilfe dankbar... merciii :wink:

LG
Jugii

Hi

Die Stepper.h ist blockierend - habe jetzt nicht drauf geachtet, ob Du diese Blockade brauchst!
Du kannst einen 28BYJ-48 mit den Bitmustern der Stepper-Bibliothek verwenden, wenn Du die mittleren zwei Pins vertauscht - dann kommt ein 'wanderndes' Bitfeld heraus - Das braucht der 28BYJ-48 bzw. Dessen Ansteuerung mittels ULN.
(Siehe "Es geht doch, Stepper 28BYJ-48 mit Stepper-Lib")

Die AccelStepper-Library blockiert nicht, kann sowohl direkte Bitmuster ausgeben (4-Wire), oder Dir+Step (2-Wire) in Halb und Vollschritt.
(neben 3-Wire für BLDC wie HDD-Motore)
Hier ist es aber zwingend, daß die loop() keine Zeit benötigt, also auch kein delay() zum Tasten Entprellen.
Das obige Beispiel lässt sich ganz einfach auf die AccelStepper umstricken!

Von dem A4988 auf den 28BYJ-48 halte ich aber für einen Rückschritt - oder Du musst den Stepper hacken (den roten Draht weg, die Verbindung der zwei Mittelanzapfungen trennen - ist unter dem blauen Plastik beim Anschluss) - dann hast Du den Motor auf Bi-Polar umgebaut, soll mehr Kraft bringen - ich hätte zwar schon einen dieser Stepper umgebaut, aber noch nicht getestet ... kann dazu also nicht wirklich was sinniges zu sagen.

MfG

Hallo,
Was Du für einen Steppermotor mit welchem Treiber nimmt ist ja ein anderes Thema. Ich hab halt nur den einen zum probieren. Deshalb hab ich das auch gleich in eine eigenen Function gepackt damit Du das leichter ersetzen kannst. Klar die delay sollten dann noch aus dem loop raus, aber auch das ist eine schöne Übung für Dich, ich hatte es ja bereits erwähnt. :slight_smile:

Tip dazu pack auch das in eine Function "taster_Flanke_entprellt" der Du die Parameter übergibst und parameter zurück lieferst die Du als Hilfsvariabel global verwendest. intern arbeitest Du mit millis(). Alternativ dazu kannst Du auch eine fertige lib nehmen, aber der Spass Effekt ist kleiner. :slight_smile: . Wenn es dich dann so richtig erwischt hat machst du aus der Function dann eine eigene Lib.

Schön das Dir der Ansatz passt und ich Dir helfen konnte.

Heinz

Hey hey,

erst mal riiiießen Dank für die Hilfestellungen :wink:

Sooo, hab jetzt mal den Code soo angepasst wie es laufen soll.

/* Hardware UNO 
 *  Anschluss 4 Taster gegen 0 Volt
 *  Steppermotor 28BY J-48
 * 
 */
#include <Stepper.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27, 20, 4);

const int stepsPerRev = 18528; // Motor Schritte / Umdrehung

int program;// Programmnummer
byte maxprog = 6;
int anzfotos[7] = {12,16,24,32,48,96,193};// Anzahl Fotos je Programe

// Variable
byte count;
float Position; // hier float wegen wiederholter Rungungsfehler 
float NextPosition; // hier float wegen wiederholter Rungungsfehler 
byte PhotoCount;
float stepToGo;

// Taster zur Menue Bedienug
byte btn_up = 7;    // Programm auf
byte btn_down = 6;  // Program ab
byte btn_sel = 4;   // Programm auswählen
byte btn_next = 3;  // Next Step

// Status Variable
bool stat_ausw;
bool stat_sel;
bool stat_next;

Stepper myStepper(stepsPerRev, 8, 10, 9, 11);

void setup() {
// LCD und Menütasten 
  lcd.init();
  lcd.backlight();
   
  // put your setup code here, to run once:
  myStepper.setSpeed(10);
  pinMode(btn_up, INPUT_PULLUP);
  pinMode(btn_down, INPUT_PULLUP);
  pinMode(btn_sel, INPUT_PULLUP);
  pinMode(btn_next, INPUT_PULLUP);

  stat_ausw = true;
  stat_sel = false;
  stat_next = false;

  // Startanzeige
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(" TurntablePro  360\337");
  lcd.setCursor(0, 1);
  lcd.print("Bitte w\xE1hlen...");
  lcd.setCursor(0, 2);
  lcd.print("Programm "); lcd.print(anzfotos[program]); lcd.print(" Photos");
}

void loop() {
  // put your main code here, to run repeatedly:

  // ----------Auswahl aktiv
  if (stat_ausw) {
    if (digitalRead(btn_up ) == 0) {
      program ++;
      if (program > maxprog)program = maxprog;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(" TurntablePro  360\337");
      lcd.setCursor(0, 1);
      lcd.print("Bitte w\xE1hlen...");
      lcd.setCursor(0, 2);
      lcd.print("Programm "); lcd.print(anzfotos[program]); lcd.print(" Photos");
      delay(200);// entprellen und doppel vermeiden
      while (!digitalRead(btn_up));
    }
    if (digitalRead(btn_down) == 0) {
      program --;
      if (program < 0)program = 0;
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(" TurntablePro  360\337");
      lcd.setCursor(0, 1);
      lcd.print("Bitte w\xE1hlen...");
      lcd.setCursor(0, 2);
      lcd.print("Programm "); lcd.print(anzfotos[program]); lcd.print(" Photos");
      delay(200);
      while (!digitalRead(btn_down));
    }
  }
  // ---------Program ist ausgewählt
  if (digitalRead(btn_sel) == 0 && stat_ausw == true) {
    delay(200);
    stat_ausw = false;
    stat_sel = true;
    Position = 0;
    stepToGo = 360.0 / anzfotos[program];
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Photos gesamt:");lcd.print(anzfotos[program]);
    lcd.setCursor(0, 1);
    lcd.print("Position now: "); lcd.print(Position);lcd.print("\337");
    lcd.setCursor(0, 2);
    lcd.print("Next: "); lcd.print(stepToGo);lcd.print("\337");
    lcd.setCursor(0, 3);
    lcd.print("Photo ");lcd.print("1"); lcd.print(" von ");lcd.print(anzfotos[program]);
    count = anzfotos[program];
    
    stat_next = true;
    stat_sel = false;

// Programm Abbruch!!
    if (digitalRead(btn_down) == 1){
    delay(200);
    stat_ausw = true;

    }
  }
  // --------Next Buton aktiv
  if (digitalRead(btn_next) == 0 && stat_next == true) {
    delay(200);

    if ( count > 0) {
      Position = Position + stepToGo;
      NextPosition = Position + stepToGo; 
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Position Turntable");
      lcd.setCursor(0, 1);
      lcd.print("Now: "); lcd.print(Position);lcd.print("\337");
      move_stepper();
      lcd.setCursor(0, 2);
      lcd.print("Next: "); lcd.print(NextPosition );lcd.print("\337");
      count --;
      PhotoCount = anzfotos[program] - count+1;
      lcd.setCursor(0, 3);
      if (count > 1)lcd.print("Photo ");lcd.print(PhotoCount); lcd.print(" von ");lcd.print(anzfotos[program]);
    }
    if (count == 1) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(" TurntablePro  360\337");
      lcd.setCursor(0, 1);
      lcd.print("Photo ");lcd.print(PhotoCount); lcd.print(" von ");lcd.print(anzfotos[program]);
      lcd.setCursor(0, 2);
      lcd.print("letzes Photo =");
      lcd.setCursor(0, 3);
      lcd.print("erstes Photo next...");
    }

    if (count == 0) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(" TurntablePro  360\337");
      lcd.setCursor(0, 1);
      lcd.print("Alle Photos fertig!");
      lcd.setCursor(0, 2);
      lcd.print("Select = Wiederholen");
      lcd.setCursor(0, 3);
      lcd.print("Up/Down = Menuwahl");
      stat_next = false;
      stat_ausw = true;
    }

    // Programm Abbruch!!
    if (digitalRead(btn_down) == 1){
    delay(200);
    stat_ausw = true;
    }
  }
}
//-------Ansteuerung des Steppermotors

void move_stepper() {
  int steps;
  steps = stepToGo * stepsPerRev / 360;
  myStepper.step(steps);
}

Wie ich das jetzt auf meine Arduino UNO steckendes CNC Shield V3.0 und Nema17 umbasteln muss, weis ich noch nich??? :o :stuck_out_tongue_closed_eyes:

Hab mal ein paar Fotos hochgeladen, was ich da eigentlich mache :wink:

Für weitere Hilfe bin ich sehr dankbar...
Und vielen Dank für die informativen Tip's bis jetzt :wink:

LG
Jugii

Hi

Schöne Plaxi-Teile - selbst erstellt?
Aktuell spielst Du mit einem 28BYJ-48 rum und schickst Diesem die Bitmuster.
Die myStepper.h müsste ich mir Mal anschauen, meine, 'Meine' hieß nur Stepper.h - Die konnte ich aber gegen die AccelStepper austauschen, Die unterstützt auch '2-wire', also DIR+PULS.
Dort klemmst Du den Treiber für Deinen Nema17-Stepper an (Nema17 ist nur der Flansch), stellst den Strom ein und klemmst den Stepper an.
Das soll's gewesen sein.

MfG

Hey hey postmaster-ino,

jooo... ich bastle alles selber :wink:

Bin ja eigentlich Schreiner bzw. Holztechniker und auf Abwegen :stuck_out_tongue_closed_eyes:

Ich verwende schon die #include <Stepper.h>
Hmmm...

Ich glaub, ich muss noch sehr viel lernen... :roll_eyes: :stuck_out_tongue_closed_eyes:

Verwende derzeit die X-Achse am Shield:
// Stepper und Pins
int ENA = 8; // EnabelPin
int STP = 2; // StepPin
int DIR = 5; // Richtung Uhrzeigersinn

und ich kann auch damit die Schritte anfahren :wink:
Mit einem kleinen Sketch das ich geschrieben hab.
Nur mich nervt, dass ich immer den Arduino updaten müsste, wenn ich 8/12/24 usw. Fotos schießen möchte.

Wird schon werden bis 2025 8) :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes: :stuck_out_tongue_closed_eyes:

Für weitere Hilfe... sehr gerne :wink:

LG
Jugii

Hallo,

Na der Drehkranz sieht super aus, toll gemacht. Da wirst Du den Rest auch noch hinbekommen.

@postmaster es handelt sich in dem Beispiel von mir um die standard Stepper.h lib . Lediglich das Stepper Object hat den namen mystepper :slight_smile:

ich denke aber mal die AccelStepper.h kann ebenfalls dein CNC Shield V3.0 ansteuern. ich hab gesehen das auf dem Video dein Motor dreht, wie steuerst Du den jetzt an. wie sagst Du Ihm wieviele Schritte er fahren soll. ? ich vermute dazu hast Du einen Beispiel Sketch verwendet.

Stell doch einfach mal den sketch hier rein , dann bekommst Du sicher noch ein paar tipps wie Du das zusammen bekommst.

Heinz

Hi

Wenn ich Dich in ein anderes Forum entführen darf - Deine Plexi-Arbeiten könnten in der Zerspanerbude durchaus Neider finden - wobei dort auch Volk mit T-T-T (Tausend Tonnen Technik) vertreten ist, Welches über die Hobbyisten manches Mal doch die Nase rümpft. Bin dort aber (seit ich hier bin) nur noch sehr selten gewesen - CNC ist ja auch ein schönes Hobby.

@Rentner (Heinz)
Wenn's die Standard-Stepper.h ist, lässt sich Diese 1:1 durch die AccelStepper austauschen - man bekommt Rampen und kann mehrere Stepper gleichzeitig verfahren.
... wenn ich nicht so viel hier Tippen würde, käme ich auch zum Fräsen, um die Aufhängung meiner 28BYT-48-Aqua-Beads Sortiermaschine 'auszustanzen'.

@Juggi
Naja, gibt schon schlimmeres als Schreiner :wink:
Einem bekannten Schreiner konnte ich Seine ~1,5m x ~2,5m Portal-Fräse wieder zum Leben erwecken - wobei Der dort auch viel mit Holz spielt.
Das ist dann schon ein Unterschied zu meiner Din-A-4 Chinesin.

Jesses, eigentlich fast nur OT geworden - 'tschuldigung'

MfG