Arduino Uno + Schrittmotor ULN2003

Hallo,
folgende Programmierung soll durchgeführt werden, aber ich habe mit der Umsetzung leider Probleme, mir buggt immer wieder etwas dazwischen und letztendlich steh ich voll auf dem Schlauch, weil ich nicht weiß wo das Problem ist.
Need help...

Ausser die Aussage "vor dem Monitor" fällt mir ohne irgendwas zum nachsehen nicht ein.
Was hast Du, was nicht funktioniert?

Ich hätte bei dieser Aufgabenstellung auch ein paar Fragen, aber die behindern die Lösung nicht, außer bei der Umrechnung von Schritten in Winkel, die vermutlich irgendwo anders erklärt ist.

Kannst du deinen Sketch bitte hier richtig einstellen.
Das mit den Fotos ist größer Mist.
In der IDE mit rechter Maustaste auf "für Forum kopieren" und dann hier einfügen.
Dann können alle den Sketch besser lesen.
Und die Bilder löschen.

Und beschreibe, was funktioniert und was nicht.

Thx für den Hinweis.
Also der Schrittmotor läuft manchmal gar nicht erst an oder erst nach einer kurzen Ruckelphase.
Oder aber der Schrittmotor läuft problemlos die 180 ° rechts rum, dann die 90° links und dann wieder die 180° rechts rum, und nachdem dies dann 4-5 mal wiederholt wurde, steht der Motor ohne ersichtlichen Grund.
Liegt das Ruckeln, bzw diese Anlaufschwierigkeiten am Vollschrittbetrieb? Und wieso stoppt der Motor?

char schritt = B00000001;
int Wartezeit, Drehung;
float Endwert1, Endwert2;

// PORTB = Pin 8 bis 11
// PORTB = B00000001      schaltet PIN8
// PORTB = B00000010      schaltet PIN9
// PORTB = B00000100      schaltet PIN10
// PORTB = B00001000      schaltet PIN11
// Vollschrittbetrieb

void setup()
{
  Serial.begin(9600);                                                                   // Aufbau einer seriellen Verbindung

  DDRB = B00001111;
  PORTB = B00000001;
  Wartezeit = 2000;                                                                     // Wartezeit von 2 sec
  Endwert1 = 1024;
  Endwert2 = 512;
  Drehung = 0;
}

void loop ()
{
  while(Drehung<=(int)Endwert1)
  {
    schritt_rechts();
    Drehung=Drehung+1;
  }
  Drehung=0;
  
  while(Drehung<=Endwert2)
  {
    schritt_links();
    Drehung=Drehung+1;
  }
  Drehung=0;
  
  while(Drehung<=(int)Endwert1)
  {
    schritt_rechts();
    Drehung=Drehung+1;
  }
  Drehung=0;
  
  delay(Wartezeit);                                                                     // Wartezeit von 2 sec, siehe oben
}


void schritt_rechts()                                                                   // void schritt_rechts 
{
  PORTB = schritt;
  delay(2);

  if(schritt == B00001000)
  {
    schritt = B00000001;
  }

  else
  {
    schritt = schritt << 1;
  }
}


void schritt_links()                                                                    // void schritt_links
{
  PORTB = schritt;
  delay(2);

  if(schritt == B00000001)
  {
    schritt = B00010000;
  }

  else
  {
    schritt = schritt >> 1;
  }
}

Warum verwendest du while-Schleifen für deine Abfrage ? Du hast doch schon eine Schleife, die loop(). Da wäre eine if Abfrage in dem Fall besser.
Und warum definierst du Entwert1 als float und machst in der Abfrage ein Int draus ?
Deine Werte sind aber int.

Was ist das denn für ein Schrittmotor und wie hast Du ihn angeschlossen? Dein Schrittfolge entspricht eigentlich nicht einem typischen Fullstep. Das ist ein Beispiel für einen über den ULN2003 angeschlossenen Schrittmotor:

grafik

Du machst nur die Schritte 1,3,5 und 7. Da hat der Motor sicher nur wenig Kraft, und wenn die Spulen evtl. noch falsch angeschlossen sind ...

Besserer Vollschrittbetrieb wären die Schritte 2,4,6 und 8 mit jeweils 2 aktivierten Spulen. Das könnte man auch durch Schieben (+ Korrektur) realisieren.

Schrittmotor 28BYJ-48-5V mit Treiber ULN2003A; beides miteinander kompatibel und am Arduino an die PINS 8 bis 11 angeschlossen.
Verschaltung bzw. Laufrichtung (im rechtslauf, uhrzeigersinn) A-> B -> C-> D (LED Ausgabe auf Treiberplatine)
Und ja es soll sich hier der Vollschrittbetrieb abspielen.
Der Halbschrittbetrieb muss aber auch noch realsiert werden.

Meine while soll dafür sorgen, dass er die Schitte bis 512 (90° Drehung) ausführt, ohne while würde er die zwar immer wieder durchlaufen, aber nicht bis zum Endwert.
Mein Endwert ist ein float, das ist korrekt, aber ich habs einfach ausprobiert und mit dem int läuft der Schrittmotor irwie flüssiger.

Wie würdet Ihr denn die Programmierung sonst realisieren?

Das geht aber nicht mit dem Schieben wie es da vorgeschrieben wird. Elegant kann man sowas mit Tabellen lösen

Jedes while kann durch ein passender if in loop ersetzt werden. Wenn man nur eine Sache macht ist nicht unbedingt wichtig. Aber wenn man noch andere Dinge nebenbei erledigen möchte, schafft man sich mit den meisten while-Schleifen nur Probleme

Verstehen was gemacht wird ist wichtiger als einfach willkürlich Dinge auszuprobieren. Klar geht das vielleicht. Aber sinnvoll ist es nicht

Verzählt?

ich glaube ich sehe das Problem nicht, bin Programmblind geworden

Sowas passiert :slightly_smiling_face: - bei dem Sonnenwetter ganz leicht.
Zähl mal die Nullen hinter der eins:

schritt = B00010000;

Kommt drauf an, ob vorher oder nachher geschoben wird.

Problem vorerst gesolvt! Thx!

Neues Problem: ich soll das ganze nun im Halbschrittbetrieb ausführen:

a) Schreibe eine Programm, bei dem sich der Schrittmotor zunächst permanent im Halbschrittbetrieb in eine Drehrichtung dreht.

  • meine vorgegebene Drehrichtung: Uhrzeigersinn

b) Erstelle ein C-Programm (wie in Aufgabenstellung oben) zur Durchführung von jeweils 1 Schritt rechts und links im Halbschrittbetrieb.

Frage: muss ich dann nicht einfach nur die Anzahl der Schritte verändern und den Endwert1 bzw. Endwert2?

28BYJ-48 hat...
...2048 bei 1 Umdrehung =360° im Vollschrittbetrieb
...4096 bei 1 Umdrehung =360° im Halbschrittbetrieb

char schritt = B00000001;
int Wartezeit;
int Drehung;
int Endwert1;
int Endwert2;

// PORTB = Pin 8 bis 11
// PORTB = B00000001      schaltet PIN8
// PORTB = B00000010      schaltet PIN9
// PORTB = B00000100      schaltet PIN10
// PORTB = B00001000      schaltet PIN11

// Halbschrittbetrieb

void setup()
{
Serial.begin(9600);                                                                   
  
DDRB = B00001111;
PORTB = B00000001;
Wartezeit = 2000;                                                                     
Endwert1 = 1024;
Endwert2 = 512;
Drehung = 0;
}

void loop ()                                                                          // void loop: Vorgabe Schrittabfolgt mit Aufruf der schritt_rechts/links
{
while(Drehung<=Endwert1)
{
schritt_rechts();
Drehung=Drehung+1;
}
Drehung=0;
  
while(Drehung<=Endwert2)
{
schritt_links();
Drehung=Drehung+1;
}
Drehung=0;
  
while(Drehung<=Endwert1)
{
schritt_rechts();
Drehung=Drehung+1;
}
Drehung=0;
  
delay(Wartezeit);                                                                     
}


void schritt_rechts()                                                                   // void schritt_rechts 
{
PORTB = schritt;
delay(2);

if(schritt == B00001000)
{
schritt = B00000001;
}

else
{
schritt = schritt << 1;
}
}


void schritt_links()                                                                    // void schritt_links
{
PORTB = schritt;
delay(2);

if(schritt == B00000001)
{
schritt = B00001000;
}

else
{
schritt = schritt >> 1;
}
}

Siehe Post #9 vom @MicroBahner, da steht die Halbschritt-Ansteuerung.

Nein, Anzahl der Schritte ändern reicht nicht.

Halbschritt hat eine andere Schrittfolge. Das geht nicht mehr einfach durch Schieben. Dafür zählt man am Besten die 8 verschiedenen Schritte hoch und runter. Und je nach Wert holt man sich den Zustand der Pins aus einer Tabelle, z.B. switch/case oder ein Array

Na hab ich doch gesagt...

Also mal ehrlich.
Die Aufgabe war doch schon bei #1 bekannt.
Und jetzt ist dann aber auch Schluß mit Hausaufgabenlösungen vorlesen lassen.

Ich versteh das nicht.
Diejenigen, die lernen sollen regen sich darüber auf, das sie nur zuHause rumsitzen und nichts bei rumkommt.

Jetzt, wo das Schuljahr zu Ende geht und die Inhalte, die (als was auch immer) vorgelegt/vermittelt wurden, abgefragt werden kommt es zum persönlichen Gau.

Eigentlich schade.