Diverse Stepper mit Tastenfeld ansteuern

Hallo zusammen,

ich versuche momentan für ein Modellbauprojekt
mehrere Step-Motoren mit den 4x4 Tastenfeld zu kombinieren
kapiere aber nicht wie ich das anstellen soll.

Mein Vorhaben:
Ich drücke Taste 1 -> Motor 1 dreht von Pos. 0 zu Pos 1
Ich drücke Taste 1 nochmal -> Motor 1 dreht von Pos. 1 zurück zu Pos. 0
Ich drücke Taste 2 -> Motor 2 dreht von Pos. 0 zu Pos 1
Ich drücke Taste 2 nochmal -> Motor 2 dreht von Pos. 1 zurück zu Pos. 0

Sprich ich möchte Garagentore auf- und zufahren.
Das drehen eines Steppers klappt einwandfrei,
aber das kombinieren mit dem Tastendruck bekomme ich nicht gebacken...

Könntet Ihr mir vielleicht (möglichst anhand eines Beispieles) weiterhelfen?
Danke vielmals und guten Wochenstart!

Gruß
Chris

Edit:
Momentan steuere ich einen Servomotor!!! mit der IR Fernbedienung und je eine Taste für auf und eine für zu...

Du möchtest einen endlichen Automaten mit mehreren Zustände programmieren.

Hi

Und Du möchtest uns an Deinem Code Teil haben lassen!!!1Elf1!!! (Satzzeichen sind KEINE Rudeltiere)

MfG

Suche nach einem Beispiel für 4x4 tasten Matrix und ein Beisiel für switch toggle
Grüße Uwe

Hallo zusammen,

also ich habe es zumindest schonmal so weit hin bekommen,
dass mein Motor sich dreht wenn ich eine Taste des Tastenfeldes drücke.

Hier mal der Code:

#include <Keypad.h>
#include <Stepper.h> // Hinzufügen der Programmbibliothek.
int SPU = 2048; // Schritte pro Umdrehung.
Stepper Motor(SPU, 10,12,11,13); // Der Schrittmotor erhält die Bezeichnung "Motor" und es wird angegeben an welchen Pins der Motor angeschlossen ist.

  
const byte ROWS = 4; //four rows
 
const byte COLS = 4; //four columns
 
char keys[ROWS][COLS] = {
 
  {'1','2','3','A'},
 
  {'4','5','6','B'},
 
  {'7','8','9','C'},
 
  {'*','0','#','D'}   
 
};
 
byte rowPins[ROWS] = {13, 12, 11, 10}; //connect to the row pinouts of the keypad
 
byte colPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad
 
 
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
 
 
void setup(){
     Motor.setSpeed(6); // Angabe der Geschwindigkeit in Umdrehungen pro Minute.
 
     Serial.begin(9600);
  
}
  
void loop(){

Motor.step(512); 
Serial.print("Motor dreht");
 
delay(1000);

  }

Jetzt fehlt mir nur noch, dass er auf einer spezifischen Taste (Bsp. 1) dreht und nach den 512 Steps stehen bleibt.
Und dann bei einem zweiten Druck auf (1) sich in die andere Richtung dreht.
Wenn es was für die späteren (mehreren) Motoren hilft:
Ich habe noch ein CNC Shield für 4 Stepper Motoren liegen.

Danke und Gruß,
Chris

Wenn Du noch quote = Zitat und code = Quelltext bei den Tags auseinander halten lernst, kann das noch was werden.

Gruß Tommy

Danke für den Hinweis,
aber ist das für die Ergebnisfindung so wichtig? :wink:

Habe noch einen Code gefunden und modifiziert.
Jetzt klappt es aber im Grunde auch wieder nur mit zwei unterschiedlichen Tasten.
Durch die Sache mit dem Switch (Toggle) steige ich ehrlich gesagt nicht ganz so durch.
Irgendwie komme ich nicht darauf, wie ich die Beispiele der LED-Ansteuerung umarbeite zu dem
Motor bzw. Tastendruck.

Hier mal der Code der akutell mit zwei Tasten läuft:

/*  Keypadtest.pde
 *
 *  Demonstrate the simplest use of the  keypad library.
 *
 *  The first step is to connect your keypad to the
 *  Arduino  using the pin numbers listed below in
 *  rowPins[] and colPins[]. If you want to use different
 *  pins then  you  can  change  the  numbers below to
 *  match your setup.
 *
 */
#include <Keypad.h>
#include <Stepper.h> // Hinzufügen der Programmbibliothek.
int SPU = 2048; // Schritte pro Umdrehung.
Stepper Motor(SPU, 10,12,11,13); // Der Schrittmotor erhält die Bezeichnung "Motor" und es wird angegeben an welchen Pins der Motor angeschlossen ist.

const byte ROWS = 4; // Four rows
const byte COLS = 4; // Four columns
// Define the Keymap
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 2, 3, 4, 5};
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 6, 7, 8, 9}; 

// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

#define ledpin 13

void setup()
{
  Motor.setSpeed(6); // Angabe der Geschwindigkeit in Umdrehungen pro Minute.
  pinMode(ledpin,OUTPUT);
  digitalWrite(ledpin, HIGH);
  Serial.begin(9600);
}

void loop()
{
  char key = kpd.getKey();
  if(key)  // Check for a valid key.
  {
    switch (key)
    {
      case '*':
        Motor.step(512);
        Serial.println(key);
        break;
      case '#':
        Motor.step(-512); 
        
        break;
      default:
      Serial.println(key);
    }
  }
}

Mir würde auch eine Zwei-Tasten-Lösung reichen.
Z.B. Taste 1 + * für die eine Richtung und Taste 1 + # für die andere.
Weiß nur nicht, ob das so realisierbar ist.

Hi

Da '1' eine Taste ist und '*' eine Taste ist, bist Du schon bei 2 Tasten.
Natürlich kannst Du die Tastenmatrix abfragen und auch erkennen, wenn mehrere Tasten gleichzeitig gedrückt sind.
Nur bieten Das die Beispiele nicht - Da muß man schon selber ran.
(oder sich überlegen, was man WIRKLICH will und den Kram Mal aufschreiben)

  • Motor drehte noch nicht, DU drückst '1' -> Motor soll 512 Schritte nach + laufen
    (Darf die Drehung unterbrochen werden, was soll passieren, wenn ich auf der 1 drauf bleibe, soll der Motor mit Drehen beginnen, wenn ich die Taste drücke, oder erst, wenn ich Diese löse? Endprellen wird Dich auch noch interessieren)
  • Motor hat die 512 Schritte gelaufen, Du drückst '2', was soll hier passieren?
    Was, wenn Du erneut die '1' drückst?
    Wieder: Beim Drücken, oder Lösen?
    Was, wenn die Taste gedrückt beleibt?

Du siehst: Alles nicht so einfach, Du musst Dir genau überlegen, WAS Du WANN willst - und Das in die Logik Deines Sketch 'gießen'.

.pde lässt erahnen, daß der Sketch etwas (viel) älter ist - könnte sein, daß Du mit aktuelleren Beispielen weniger Probleme bekommst!

MfG

postmaster-ino:
Hi

Da '1' eine Taste ist und '*' eine Taste ist, bist Du schon bei 2 Tasten.
Natürlich kannst Du die Tastenmatrix abfragen und auch erkennen, wenn mehrere Tasten gleichzeitig gedrückt sind.

Normale Tastaturmatrix können nicht sicher 2 Tasten gleichzeitig detektieren. Dazu braucht es je eine Diode in serie zum Taster in der Tastenmatrix.

https://www-user.tu-chemnitz.de/~heha/Mikrocontroller/Tastenmatrix.htm

Grüße Uwe

@uwefed
Danke, die Möglichkeit habe ich schon wieder verworfen.
Halte ich selbst nicht für praktikabel, bzw. ist genau genommen zu umständlich.

@postmaster-ino
Dank Dir für den Tip.
Ich habe mir jetzt nochmal alles durchgedacht und verglichen.
Da ich in der Vergangenheit Servomotoren im Einsatz hatte/habe und für meinen
Zweck die Mirco-Baugröße der Servos auch ausreicht,
bin ich wieder zurück auf diese geswitched.
Vor allem auch, weil ich da auf meinen bisherigen Code zurückgreifen kann :wink:

Trotzdem benötige ich da nochmal Eure Hilfe:
Der Servo fährt korrekt von seiner 0 Position (20) auf seine Endposition (92) nach einem Druck auf die
Taste (1).
Ich habe versucht eine if/else Variante einzubauen, aber das klappt nicht.
Beim zweiten Druck auf die Taste (1) springt der Servo auf Pos (20) zurück und fährt dann wieder hoch
auf Pos (92).
Ich nehme an, dass ich irgendwas falsch deklariert habe.

Unterbrechungen oder "was-wäre-wenn" ich nochmal während des laufens auf die Taste drück,
lasse ich mal aussen vor, da im Regelfall diese Möglichkeit normalerweise ausgeschlossen ist.
Und der Servo eh bei erneutem Druck auf die Taste während des Drehvorganges nicht reagiert.

Hier mal der Code:

#include <Servo.h>
#include <Keypad.h>

const byte ROWS = 4;          // Four rows
const byte COLS = 4;          // Four columns
char keys[ROWS][COLS] = {     // Define the Keymap
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
// Connect keypad ROW0, ROW1, ROW2 and ROW3 to these Arduino pins.
byte rowPins[ROWS] = { 2, 3, 4, 5};
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { 6, 7, 8, 9}; 

Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

    int led1 = 2;
    int itsONled[] = {0,0,0,0};
    int pos = 20;
Servo servogarage;

#define pos_ini 20 // Ausgangsposition
#define ledpin 13  //Externe LED


void setup()
{ 
  Serial.begin(9600); 
  servogarage.attach(12);
  servogarage.write(pos_ini);
//  pinMode(led1, OUTPUT);
}

void loop()
{
   char key = kpd.getKey();
if(key)

  {
   switch(key)

    {

      case '1': // DOWN button pressed
                      Serial.println(key);
                      Serial.println(pos);
                      if (pos = 20)
                      for (pos = 20; pos <= 92; pos += 2) // alt 14.9 92 1
                         {
                      servogarage.write(pos); //Dreht nach links
                      delay(80);
                      Serial.println(pos);

                         }
                    //  digitalWrite(led1, LOW);   // turn it off when button is pressed

                      else
                      if (pos = 92)
                      for (pos = 92; pos >= 20; pos -= 2)
                      servogarage.write(pos); //Dreht nach links

                      break;
    }
  }  
}/* --end main loop -- */

Die LED Geschichte darin bitte ignorieren.

Ich hoffe, damit komme ich mit Eurer Hilfe weiter.
Danke einstweilen und schönen Tag,
Chris

Erst mal die Fehler ausputzen:

                      if (pos = 20)
                     for (pos = 20; pos <= 92; pos += 2) // alt 14.9 92 1

if (pos=20) ist immer True (nicht 0), weil das eine Zuweisung ist die pos auf 20 setzt. Immer.
Dafür kannst Du Dir das pos=20 im for() sparen.
Ob das else immer richtig sitzt, wird sich noch herausstellen. Spätestens wenn Du das digitalWrite() davor ausführen läßt :-]

Dann kannst Du Dir noch überlegen, was wann passieren soll. Für eine einfache Wechselschaltung reicht es, die Position zu prüfen. Wenn sie <= 20 ist, das Tor öffnen, sonst schließen. Und das natürlich nur, wenn ein Knopf gedrückt wurde, und auch dann nur einmal.

Du solltest Dich in der Benutzung der geschwungenen Klammern üben.
Grüße Uwe

DrDiettrich:
Erst mal die Fehler ausputzen:

                      if (pos = 20)

for (pos = 20; pos <= 92; pos += 2) // alt 14.9 92 1



if (pos=20) ist immer True (nicht 0), weil das eine Zuweisung ist die pos auf 20 setzt. Immer.
Dafür kannst Du Dir das pos=20 im for() sparen.
Ob das else immer richtig sitzt, wird sich noch herausstellen. Spätestens wenn Du das digitalWrite() davor ausführen läßt :-]

Dann kannst Du Dir noch überlegen, was wann passieren soll. Für eine einfache Wechselschaltung reicht es, die Position zu prüfen. Wenn sie <= 20 ist, das Tor öffnen, sonst schließen. Und das natürlich nur, wenn ein Knopf gedrückt wurde, und auch dann nur einmal.

Dank Dir,
ich habe jetzt mal das pos=20 aus dem for() rausgelassen, dafür möchte er ein ; haben.
Wenn ich das vor der ) einsetze, also so for (pos <=92; pos +=2;)
dann überdreht der Motor.
Irgendwie komme ich nicht drauf, wie ich den Code dafür generiere, dass der Motor einfach wieder nach
unten dreht, wenn die "offene" Position (92) eingestellt ist.
Ich dache das geht vielleicht mir dem else , aber da rührt sich nichts.

@uwefed:

Meinst Du damit, den if/else code nochmal separieren also in {} setzen?

Im for() sollst Du nur pos=20 löschen, nicht den ; danach.
Hast Du auch das if() korrigiert?

DrDiettrich:
Im for() sollst Du nur pos=20 löschen, nicht den ; danach.
Hast Du auch das if() korrigiert?

Ah okay, das klappt dann.
Er fährt korrekt hoch.
Allerdings rührt sich jetzt beim zweiten Tastendruck nichts mehr.

{
   switch(key)

    {

      case '1': // 1 button pressed
                      Serial.println(key);
                      Serial.println(pos);
                      {                     
                      if (pos)
                      for (; pos <= 92; pos += 5)
                         {
                      servogarage.write(pos); //Dreht nach links
                      delay(80);
                      Serial.println(pos);

                         }
                    //  digitalWrite(led1, LOW);   // turn it off when button is pressed

                      else
                      
                      if (pos)
                      for (; pos >= 20; pos -= 5)
                      servogarage.write(pos); //Dreht nach links


    }
    
   
  }  }

Die Klammergeschichte durchsteig ich nicht.

Du solltest dich etwas mehr mit den Grundlagen der Programmierung befassen. Wenn in jeder neuen Version mehr Fehler drin sind als in der alten, dann wird das nichts.