Hilfe bei Adafruit Motor Shield v2.3

Hallo alle zusammen,

ich habe einen Arduino uno R3 mit dem Adafruit Motor Shield v2.3 gekauft. Ich möchte einen Schrittmotor in möglichst kleinen Schritten, flüssig 90° vorwärts drehen lassen und wieder 90°zurück.
Das ganze sollte mit einem Schalter eingeschalten werden. Mein Problem ist, dass ich es nicht hinbekomme einen Schalter mit in die Programmierung einzubinden.

Ich habe Unten mal mein Programm eingefügt, wie weit ich es bis jetzt habe.
Mein Problem ist ich weiß nicht wie ich einen Schalter in das Programm bekomme.
Kann mir jemand weiter Helfen? Wäre Super

Gruß MArtin

Stepper_Drehtisch.ino (1.25 KB)

Mein Problem ist ich weiß nicht wie ich einen Schalter in das Programm bekomme

Das nicht ganz so triviale bei Schaltern ist

  • der elektrische Anschluss ( pulldown oder pullup Widerstand (pullup geht extern oder intern))
  • das Entprellen ( kompliziert per debounce oder einfach per delay(5) oder nichts, weil es manchmal egal ist. )

Für das gibt es eingebaute Beispielsketche, die du einfach mal ausprobieren solltest (Basics und Digital sind Stichworte).

Wenn deine Frage ist, wie man generell Arduino programmiert und z.B. Beispiele erweitert/ändert oder zwei Beispiele kombiniert, solltest du kleiner anfangen, ohne mehrere gefundene Fremd-Bibliotheken.

(Meine Meinung, ich weiß dass auch Leute mit gefundener Software blind Erfolg haben können)

Ich hab den Code der Übersichtlichkeit mal in Code Tags gepackt

// Pins definieren
#define BLUE 3
#define GREEN 5
#define RED 6
int ledPin = 13;
int myArray[ ]={300,300,300,600,600,600,300,300,300} ;
int buttonLED = 10;
int tasterAN = 9;
int tasterAUS = 8;

byte leds = 0;

void setup()
{

pinMode(RED, OUTPUT);
pinMode(GREEN, OUTPUT);
pinMode(BLUE, OUTPUT);
digitalWrite(RED, HIGH);
digitalWrite(GREEN, LOW);
digitalWrite(BLUE, LOW);

pinMode(ledPin, OUTPUT);

pinMode(buttonLED, OUTPUT);
pinMode(tasterAN, INPUT_PULLUP);  
pinMode(tasterAUS, INPUT_PULLUP);

}

int redValue;
int greenValue;
int blueValue;

void loop()
{

if (digitalRead(tasterAN) == LOW)
  {
    digitalWrite(buttonLED, HIGH);
  }
  if (digitalRead(tasterAUS) == LOW)
  {
    digitalWrite(buttonLED, LOW);
  }
for (int i=0; i<9; i++)    {

  digitalWrite(ledPin, HIGH);   
  delay(myArray[i]);                       
  digitalWrite(ledPin, LOW);    
  delay(300);        
}        

delay(1000);


#define delayTime 10 

redValue = 255; // Wählen Sie einen Wert zwischen 1 und 255, um die Farbe zu ändern.
greenValue = 0;
blueValue = 0;


for(int i = 0; i < 255; i += 1) // fängt mit rot an und wird grün wenn i=255 ist
{
redValue -= 1;
greenValue += 1;
// The following was reversed, counting in the wrong directions
// analogWrite(RED, 255 - redValue);
// analogWrite(GREEN, 255 - greenValue);
analogWrite(RED, redValue);
analogWrite(GREEN, greenValue);
delay(delayTime);
}

redValue = 0;
greenValue = 255;
blueValue = 0;

for(int i = 0; i < 255; i += 1) // fängt mit grün an und wird blau bei i=255
{
greenValue -= 1;
blueValue += 1;
// The following was reversed, counting in the wrong directions
// analogWrite(GREEN, 255 - greenValue);
// analogWrite(BLUE, 255 - blueValue);
analogWrite(GREEN, greenValue);
analogWrite(BLUE, blueValue);
delay(delayTime);
}

redValue = 0;
greenValue = 0;
blueValue = 255;

for(int i = 0; i < 255; i += 1) // fängt mit blau an und wird rot bei i=255
{
// Der folgende Code wurde umgeordnet, um den anderen zwei ähnlichen Abschnitten zu entsprechen
blueValue -= 1;
redValue += 1;
// The following was reversed, counting in the wrong directions
// analogWrite(BLUE, 255 - blueValue);
// analogWrite(RED, 255 - redValue);
analogWrite(BLUE, blueValue);
analogWrite(RED, redValue);
delay(delayTime);
}

}

Hier ist nirgends eine Adafruit Lib eingebunden, eigentlich gehts in den Sketch nur um LEDs dimmen.
Ist das überhaupt der richtige Code? :confused:

Hast du einen Schaltplan? Ist der Stepper mit dem MotorShield richtig verbunden?

lg dony

Ok, war also der falsche Code :wink:
Also nochmal in Code Tags verpackt

/* 
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
It won't work with v1.x motor shields! Only for the v2's with built in PWM
control

For use with the Adafruit Motor Shield v2 
---->	http://www.adafruit.com/products/1438
*/


#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); 

// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);


void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Stepper test!");

  //AFMS.begin();  // create with the default frequency 1.6KHz
  AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  
  myMotor->setSpeed(5);  // 10 rpm   
}

void loop() 
{
  // ----- Hier die Taster Abfrage rein
  
  // ----- Und hier eine if Funktion rein ob der Taster gedrückt wurde. lg dony
  
  for (int i=0; i<=51; i ++)
   {
      if (i<51)
      {
      myMotor->step(1, FORWARD, INTERLEAVE); 
       delay(100);
      }
     else 
     {
      myMotor->step(50, BACKWARD, INTERLEAVE);
     } 
   }
}

und 2 Kommentare eingefügt die dir weiterhelfen sollten (am anfang der loop).
In den zuerst von dir geposteten Code ist eh eine Taster Abfrage drinnen, naja eber ohne Debouncer.
Ein Taster muss entprellt werden, da bei einem Tastendruck mehrere Signal an den Arduino geschickt werden.

lg dony

Er möchte statt Taster einen Schalter, hat vermutlich keinen Pulldown-Widerstand zur Hand, ausserdem ist es bei Motoren generell nicht schlecht, wenn man diese bei Richtungswechsel erstmal stoppt. (Soviel delay ist bei Schalterbetätigung durchaus ok, und das erledigt die Frage nach Entprellen/Debounce gleich mit)

Dass man bei einem Schrittmotor nach dem Start nicht weiss, wo der steht, und also seine +- 90° Anforderung ziemlich sinnlos ist, wird demnächst auch noch aufkommen, denke ich mal.

( Ganz nebenbei: +- 90° riecht eigentlich eher nach einer Servo-Anwendung statt nach Schrittmotor ? )

Schon mal Vielen dank.
Aber ich möchte einfach das das Programm anfängt abzulaufen wenn ich einen Taster/Schalter Drücke und nicht wie bis jetzt dass es anfängt wenn ich alles mit Strom versorge. Der Schrittmotor macht schon die Richtigen schritte Vorwärts und dann wieder Rückwärts. Das sollte für den anfang reichen. Denn wenn ich ja mittendrin aufhöre, müsste man ja die Schritte Vorwärts Zähelen damit er die gleichen wieder Rückwärts macht.

Hallo,

Er möchte statt Taster einen Schalter, hat vermutlich keinen Pulldown-Widerstand zur Hand, ausserdem ist es bei Motoren generell nicht schlecht, wenn man diese bei Richtungswechsel erstmal stoppt

Also bei einem Schalter würde ich in der for Schleife eine Pegelabfrage durchführen damit ich einen ausstieg hab.
Wir sollen ja nicht das Rad neu erfinden sondern den TO mit seinem code helfen.

michael_x:
Dass man bei einem Schrittmotor nach dem Start nicht weiss, wo der steht, und also seine +- 90° Anforderung ziemlich sinnlos ist, wird demnächst auch noch aufkommen, denke ich mal.

Also ich würde sagen, Schritt für Schritt, zuviel aufeinmal ist manchmal zuviel. imho

Der +-90° Winkel hört sich doch sehr nach einen Servo an. Handelt es sich um einen Servomotor?
Wegen dem Schalter hab ich etwas in deinem Code verändert, natürlich läßt sich das noch optimieren. (Ich habe ja auch noch eigene Projekte)

void loop() 
{
  // ----- Hier die Schalter Abfrage rein
  
  // ----- Und hier eine if Funktion rein ob der Schalter gedrückt wurde. lg dony
  
  for (int i=0; i<=51; i ++)
   {

    if(Schalter == AUS) {  // Ausgang aus der for Schleife
      i = 51;
    }          

      if (i<51)
      {
      myMotor->step(1, FORWARD, INTERLEAVE); 
       delay(100); // <- das sollte raus (muss es aber nicht)
      }
     else 
     {
      myMotor->step(50, BACKWARD, INTERLEAVE);
     }
  }
}

lg dony

Hallo nochmal,

Also ich habe dieses Shield auch und bin von der Hardware positiv überrascht, hingegen die Lib ist eher... naja. Das liegt vielleicht auch daran das ich nur DC-Motoren damit betreibe. Ich hab natürlich auch schon mal nen Schrittmotor darauf angeschlossen.

Dein Code schaut mir sehr nach einem veränderten Beispiel Code aus.
Wenn du einen Taster verwenden willst, musst du regelmäßige Abfragen des Tasters durchführen und sicherstellen dass, nach einem Tastendruck Dein Stepper Code durchläuft.

Am besten du erstellst ein Funktion und gibst dort den ganzen code aus der loop hinein:

void runStepper() {
  // hier das Stepper zeug rein
}

und in der loop die Tasterabfrage:

if(digitalRead(buttonPin) == HIGH) { runStepper(); } // führt die Funktion aus, ein ; vergessen.

Aber lese auch die Kommentare die ich in deinen Code geschrieben habe, und schau dir die Basics an denn Du sollst ja auch was lernen. zB: Taster einlesen und entprellen

lg dony

Aber ich möchte einfach das das Programm anfängt abzulaufen wenn ich einen Taster/Schalter Drücke und nicht wie bis jetzt dass es anfängt wenn ich alles mit Strom versorge

Das wäre was anderes. (Ich dachte, der Schalter sollte dazu dienen den Motor in der einen Stellung 90° vorwärts, und in der anderen Stellung wieder zurück fahren zu lassen.

Niemand zwingt dich setup() sofort zu beenden.
Kannst dort auch solange auf den Schalter warten, bis er erstmalig betätigt wird.

void setup() {
  ... ( wie gehabt )
  pinMode(SHALTER_PIN, INPUT_PULLUP); // SCHALTER_PIN via Schalter an GND  
  while (digitalRead(SCHALTER_PIN) == HIGH ) {} // warten auf Start
}

Das hat den Nachteil, dass nach dem ersten Start der Schalter völlig sinnlos ist.
Ist zwar so nicht geforert, aber da ist donys Interpretation schon sinnvoller:
Wenn der Schalter EIN ist, macht der Motor seine "Hin und Zurück" Bewegung.
Wenn der Schalter AUS ist, hört er nach dem "Zurück" auf. (Wie ein Scheibenwischer am Auto)

Wenn man den Arduino und das Motorshield nur ausschaltet, wenn alles in Grundstellung ist, gibt es auch das Problem nicht, dass ein Schrittmotor beim Start "irgendwo" steht.

Hey also ich brauche eine Schrittmotor weil der Motor soll sich wenn ich einen Taster drücke um einen Schritt bewegen dann 2 sek verweilen und sich dann weiterdrehen bis sich den Taster loslasse. Wenn ich den Taster Loslasse soll der Motor 10 sek verweilen und sich dann in seine ausgangsposition zurückdrehen. Aber das ganz soll maxiaml 90° sein also 50 Schritte.

/* 
This is a test sketch for the Adafruit assembled Motor Shield for Arduino v2
It won't work with v1.x motor shields! Only for the v2's with built in PWM
control

For use with the Adafruit Motor Shield v2 
---->	http://www.adafruit.com/products/1438
*/


#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include "utility/Adafruit_MS_PWMServoDriver.h"

// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield(); 
// Or, create it with a different I2C address (say for stacking)
// Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); 

// Connect a stepper motor with 200 steps per revolution (1.8 degree)
// to motor port #2 (M3 and M4)
Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 2);

const int buttonPin = 7;


void setup()
{
  Serial.begin(9600);  // set up Serial library at 9600 bps
  Serial.println("Stepper test!");

  //AFMS.begin();  // create with the default frequency 1.6KHz
  AFMS.begin(1000);  // OR with a different frequency, say 1KHz
  
  myMotor->setSpeed(5);  // 5 rpm

  pinMode(buttonPin, INPUT);
}

void loop() 
{2
 if (digitalRead(buttonPin)== HIGH)
   {
    runStepper;
   } 
}
    void runStepper()
{
     for (int i=0; i<=51; i ++)
   {
     if (i<51)
     {
      myMotor->step(1, FORWARD, INTERLEAVE); 
       delay(2000);
     }
       else 
      {
        myMotor->step(50, BACKWARD, INTERLEAVE);
      } 
   }

}
[CODE]

Aso wenn ich das Programm auf den Arduino lade passiert nichts :o

Hi, der 2er nach loop { gehört da nicht hin. Und der Funktionsaufruf ist falsch funktion() statt funktion.
Wenn das nicht geht versuch die funktion in die setup() ohne der if abfrage zu schreiben, dann sollte sie ausgeführt werden.
lg dony

mafri99:
Aso wenn ich das Programm auf den Arduino lade passiert nichts :o

Auch wenn ich heute gut gelaunt bin, werd ich nicht weiter try and error spielen.

dann 2 sek verweilen und sich dann weiterdrehen bis sich den Taster loslasse

Das mit Taster drücken und gedrückt halten... machbar is es aber vielleicht ist da ein Schalter doch besser.
Schau dir mal BlinkWithoutDelay an.
Hoffentlich hast Du die Adafruit Anleitung zum MotorShield vollständig gelesen.

lg dony

Aso wenn ich das Programm auf den Arduino lade passiert nichts :o

Und wenn du die Original Demo-Version wieder lädst, geht sie wieder?
Also direkt nach Reset / Spannungswiederkehr / Hochladen bewegt sich der Motor hin (langsam) und zurück (schnell) Ja?
Und die Version mit Schalter reagiert auch so wie sie soll: Nach Reset... passiert nichts?
Das ist doch schonmal was. 8)

Meine Glaskugel schimmert grinsend: Hast du wohl den Schalter falsch angeschlossen :wink:

Schreib doch mal einen Sketch, wo du mit dem Schalter die LED an Pin13 zum Leuchten bringst.
(Da gibts ein fertiges Beispiel, falls du lieber suchst statt zu programmieren)

Dann, wie deinen Motor, nur mit langsameren Pulsen, 10 mal schnell scnell blinken, dann 10 mal langsam Blinken und das ewig wiederholen, aber nur solange der Schalter gedrückt ist.

Oder denk dir eine andere Variante aus, wo du mehr erkannen kannst ausser "geht nicht".