Arduino UNO - Roboclaw 2X30A - 2 Bürstenlose DC Antriebe Probleme bei Programmierung Sketch

Ich danke Dir vielmals für Deine Unterstützung. Wünsche Dir ein schönes Wochenende...

Muss gleich los...

Gruß

Ben

Ich habs.
Erstens das geht nicht:

Pin 0 und PIN 1 gehören zur Seriellen Schnittstelle.
Du legts Dir damit ein Ei...

Und dann im Case 2 das - in (digitalRead(tasterPin[status - 1]) == LOW)) gegen ein + tauschen.
Dann bist Du zum überspringen mit der nächsten Taste dran, aber vermutlich wird da noch Ladung auf dem Eingang sein, sodas Du sofort rausfliegst, weil Du ja noch auf der Taste aus dem case 1 stehts.

Ich checke das am Montag nochmal alles und gebe Dir Bescheid.

Vielen Dank...

Gruß

Mal sehen, ich hab am WE nen Controller, dann teste ich das mal aus.
man liest sich

Danke für alles :+1:

//Buffered Drive M1 with signed Speed, Accel, Deccel and Position

//Includes required to use Roboclaw library
#include <SoftwareSerial.h>
#include "RoboClaw.h"

//See limitations of Arduino SoftwareSerial
SoftwareSerial serial(10, 11);
RoboClaw roboclaw(&serial, 10000);

#define address 0x80

const byte kreise = 6;
const byte tasterPin[kreise] = {2, 4, 7, 13, 12, 12}; // S1=2 lila / S2=4 rot / S3=7 gelb / S4=12 rot / S5=13 blau /
const byte ledPin[kreise] = {8, 8, 8, 8, 8, 0}; // S1 8 /
byte status = 0;


void setup()
{
  //Open Serial and roboclaw at 38400bps
  Serial.begin(57600);
  roboclaw.begin(38400);
  Serial.println("Starting...");
  for (byte b = 0; b < kreise; b++)
  {
    pinMode( tasterPin[b], INPUT_PULLUP);  // wir definieren den tasterPin als Eingang mit Pull Up
    digitalWrite(ledPin[b], LOW);
    pinMode( ledPin[b], OUTPUT);           // wir definieren den ledPin als Ausgang
  }
}

void loop()
{
  actor();
}
//
void actor()
{
  static bool tasteGedrueckt = false;
  static byte zaehler = 0;
  unsigned long lastmillis = 0;
  const unsigned long bounceTime = 50;
  static unsigned long schwenkPositionM1 = 11000;
  const unsigned int addSchwenk = 100;
  switch (status)
  {
    case 0:
      if (digitalRead(tasterPin[status]) == LOW)
      {
        Serial.println(F("Panorama Display fährt in Schwenk-Position"));
        setLed(status);
        //Von Startposition 0 auf Schwenkposition 1 - volle Geschwindigkeit
        roboclaw.SpeedAccelDeccelPositionM1(address, 200, 1685, 200, schwenkPositionM1 + zaehler * addSchwenk, 1);
        zaehler = 0;
        tasteGedrueckt = false;
        status = 1;
      }
      break;
    case 1:
      if (digitalRead(tasterPin[status]) == LOW)
      {
        setLed(status);
        if (tasteGedrueckt == false)
        {
          Serial.println(F("Panorama Diplay nach oben schwenken"));
          tasteGedrueckt = true;
          lastmillis = millis();
          zaehler++;
          Serial.print(F("Zaehler: ")); Serial.println(zaehler);
          Serial.print(F("SchwenkPosition: "));
          Serial.print(schwenkPositionM1); Serial.print(' ');
          //Schwenkposition 1 Display schwenken - halbe Geschwindigkeit + 500 Inkremente
          schwenkPositionM1 += addSchwenk;
          roboclaw.SpeedAccelDeccelPositionM1(address, 200, 842, 200, schwenkPositionM1 + zaehler * addSchwenk, 0);
          Serial.println(schwenkPositionM1);
        }
      }
      else if (millis() - lastmillis >= bounceTime)
      { tasteGedrueckt = false; }
      if ((zaehler == 5) || (digitalRead(tasterPin[status + 1]) == LOW))
      {
        zaehler = 0;
        tasteGedrueckt = false;
        status = 2;
      }
      break;
    case 2:
    
      if (digitalRead(tasterPin[status]) == LOW)
      {
        setLed(status);
        if (tasteGedrueckt == false)
        {
          Serial.println(F("Panorama Diplay nach unten schwenken"));
          tasteGedrueckt = true;
          lastmillis = millis();
          zaehler++;
          Serial.print(F("Zaehler: ")); Serial.println(zaehler);
          Serial.print(F("SchwenkPosition: "));
          Serial.print(schwenkPositionM1); Serial.print(' ');
          //Schwenkposition 1 Display schwenken - halbe Geschwindigkeit - 500 Inkremente
          schwenkPositionM1 >= addSchwenk ? schwenkPositionM1 -= addSchwenk : schwenkPositionM1 = 0;
          roboclaw.SpeedAccelDeccelPositionM1(address, 200, 421, 200, schwenkPositionM1, 0);
          Serial.println(schwenkPositionM1);
        }
      }
      else if (millis() - lastmillis >= bounceTime)
      { tasteGedrueckt = false; }
      if ((zaehler == 3) || (digitalRead(tasterPin[status + 1]) == LOW))
      {
        zaehler = 0;
        tasteGedrueckt = false;
        schwenkPositionM1 = 0;
        status = 3;
      }
      break;
    case 3:
      if (digitalRead(tasterPin[status]) == LOW)
      {
        Serial.println(F("Panorama Display fährt in Kino-Position"));
        setLed(status);
        //Schwenkposition 1 Display auf Kino Position - halbe Geschwindigkeit
        roboclaw.SpeedAccelDeccelPositionM1(address, 200, 842, 200, 20000, 0);
        //roboclaw.SpeedAccelDeccelPositionM2(address, 200, 50, 200, schwenkPositionM2, 0);
        status = 4;
      }
      break;
   case 4:
      if (digitalRead(tasterPin[status]) == LOW)
      {  
        setLed(status);
        if (tasteGedrueckt == false)
        {tasteGedrueckt = true;
        lastmillis = millis();
        
        Serial.println(F("Panorama Display fährt in Start-Position"));
      
        // Von  Kino Position 3 auf Startposition 0 - halbe Geschwindigleit Motor 1
        // Dispaly Schwenkposition auf 0 1/20 Geschwindigleit Motor 2
        roboclaw.SpeedAccelDeccelPositionM1(address, 200, 842, 200, 0, 0);
        //roboclaw.SpeedAccelDeccelPositionM2(address, 200, 210, 200, 0, 0);
        status = 5;
      }
     }
      break;
    case 5:
      if (digitalRead(tasterPin[status]) == LOW)
      {
       
        setLed(status);
        status = 0;
      }
      break;
  }
}
//
void setLed(const byte led)
{
  for (byte b = 0; b < kreise; b++)
  { digitalWrite(ledPin[b], LOW); }
  digitalWrite(ledPin[led], HIGH);
}

//Display Encoder and Speed for Motor 1
void displayspeed(void)
{
  uint8_t status1,status2,status3,status4;
  bool valid1,valid2,valid3,valid4;
  
  int32_t enc1= roboclaw.ReadEncM1(address, &status1, &valid1);
  int32_t enc2 = roboclaw.ReadEncM2(address, &status2, &valid2);
  int32_t speed1 = roboclaw.ReadSpeedM1(address, &status3, &valid3);
  int32_t speed2 = roboclaw.ReadSpeedM2(address, &status4, &valid4);
  
  Serial.print("Encoder1:");
  if(valid1){
    Serial.print(enc1,DEC);
    Serial.print(" ");
    Serial.print(status1,HEX);
    Serial.print(" ");
  }
  else{
  Serial.print("failed ");
  }
  Serial.print("Encoder2:");
  if(valid2){
    Serial.print(enc2,DEC);
    Serial.print(" ");
    Serial.print(status2,HEX);
    Serial.print(" ");
  }
  else{
  Serial.print("failed ");
  }
  Serial.print("Speed1:");
  if(valid3){
    Serial.print(speed1,DEC);
    Serial.print(" ");
  }
  else{
  Serial.print("failed ");
  }
  Serial.print("Speed2:");
  if(valid4){
    Serial.print(speed2,DEC);
    Serial.print(" ");
  }
  else{
  Serial.print("failed ");
  }
  Serial.println();
  exit(0);
}

Guten Morgen mein bester, ich habe die letzte Woche komplett flach gelegen, sonst hätte ich mich schon eher gemeldet.

Soweit funktioniert alles, danke Dir.

Ich hätte noch eine Frage an Dich :slight_smile:

Wenn ich im Case 1 bin , hätte ich gerne noch zwei weitere Optionen:

  1. Display schwenken +- (Taster 2 und Taster 3) das funktioniert super.
  2. Wenn ich nicht schwenken will, drücke Taster 5 und fahre wieder in Position 0
  3. Oder ich drücke Taster 4 und fahre direkt in Kino Position.

Ich weiß momentan nicht, wie im Case 1 die Taster 4 oder Taster 5 einbinden kann, da Sie in der Reihenfolge der Cases abgearbeitet werden.

Noch was weiteres, jetzt nur wieder mit einem Motor.

Wenn ich im Case 3 bin "Kinoposition" :

  1. Hätte ich gerne die Möglichkeit, Taste 1 zu drücken und das Display nochmal in Schwenk Position zu fahren und nach zu justieren (Schwenken) und dann wieder mit Taste 4 in Kinoposition fahren.

Wäre Dir für Deine Unterstützung sehr dankbar. Wünsche Dir einen schönen Tag.

Gruß Ben

Ich hab sowas schon fast gedacht...
Dann mal umschreiben.
Alles in einzelne Funktionen packen und für die Taster eine zentrale Abfrage.
Dann kannst Du in jedem Case alle 5 Taster abfragen.
Aber ich hab grad gesehen, das Du die Led's rausgeworfen hast -Absicht? Und was ist das für ein ominöser 6ter Eintrag bei Tastr und Led?

Sage mal... Der Zähler ist doch da mit 0 gefüllt, wenn der roboclaw aufgerufen wird, oder irre ich mich?
Und da ich mit der LED auch nicht wirklich was anfangen konnte, mal was zum probieren. Es geht Fehler- und Warnungsfrei durch.
Wozu brauchst Du das exit(0)?

//Buffered Drive M1 with signed Speed, Accel, Deccel and Position

//Includes required to use Roboclaw library
#include <SoftwareSerial.h>
#include "RoboClaw.h"

//See limitations of Arduino SoftwareSerial
SoftwareSerial serial(10, 11);
RoboClaw roboclaw(&serial, 10000);

#define address 0x80

const byte kreise = 6;
const byte tasterPin[kreise] = {2, 4, 7, 13, 12, 12}; // S1=2 lila / S2=4 rot / S3=7 gelb / S4=12 rot / S5=13 blau /
const byte ledPin[kreise] = {8, 8, 8, 8, 8, 0}; // S1 8 /
byte status = 0;
unsigned long schwenkPositionM1 = 11000;
const unsigned int addSchwenk = 100;


void setup()
{
  //Open Serial and roboclaw at 38400bps
  Serial.begin(57600);
  roboclaw.begin(38400);
  Serial.println(F("Starting..."));
  for (byte b = 0; b < kreise; b++)
  {
    pinMode( tasterPin[b], INPUT_PULLUP);  // wir definieren den tasterPin als Eingang mit Pull Up
    digitalWrite(ledPin[b], LOW);
    pinMode( ledPin[b], OUTPUT);           // wir definieren den ledPin als Ausgang
  }
  startPosition();
}

void loop()
{
  actor();
}
//
void actor()
{
  static byte zaehler = 0;
  setLed(status);
  switch (status)
  {
    case 0:
      if (tasterAbfrage() == 0)
      {
        zaehler = 0;
        schwenk(zaehler);
        status = 1;
      }
      break;
    case 1:
      switch (tasterAbfrage())
      {
        case 0:                        // 1. Taster hat Nr. 0!
          break;
        case 1:                        // 2. Taster
          {
            zaehler++;
            schwenkUp(zaehler);
            if (zaehler == 5)
            {
              zaehler = 0;
              status = 2;
            }
          }
          break;
        case 2:                       // 3. Taster
          status = 2;
          break;
        case 3:                       // 4. Taster
          status = 4;
          break;
        case 4:                       // 5. Taster
          status = 0;
          break;
      }
      break;
    case 2:
      if (tasterAbfrage() == 2)
      {
        zaehler++;
        schwenkDown(zaehler);
      }
      if ((tasterAbfrage() == 3) || (zaehler == 3))
      {
        zaehler = 0;
        schwenkPositionM1 = 0;
        status = 3;
      }
      break;
    case 3:
      if (tasterAbfrage() == 3)
      {
        kinoPosition();
        status = 4;
      }
      break;
    case 4:
      if (tasterAbfrage() == 4)
      {
        startPosition();
        status = 5;
      }
      break;
    case 5:
      if (tasterAbfrage() == 5)
      {
        status = 0;
      }
      break;
  }
}

byte tasterAbfrage()
{
  const uint32_t bounceTime = 50;
  static uint32_t lastMillis[kreise] = {0};
  static bool gedrueckt[kreise] = {false};
  byte auswahlTaste = 255;
  for (byte b = 0; b < kreise; b++)   // Alle Tasten abfragen
  {
    if (!digitalRead(tasterPin[b]))   // gedrückt?
    {
      if (!gedrueckt[b])              // Taste nicht aktiv?
      {
        gedrueckt[b] = true;          // merken
        lastMillis[b] = millis();
        auswahlTaste = b;             // Taste zurück geben, gedrueckt
      }
    }
    // Taste losgelassen, BounceTime um und vorher Taste gedrückt?
    else if (millis() - lastMillis[b] > bounceTime && gedrueckt[b])
    {
      gedrueckt[b] = false;          // löschen
      // auswahlTaste = b;              // Taste zurück geben, wenn losgelassen
    }
  }
  return auswahlTaste;
}
//
void schwenk(const byte zaehler)
{
  Serial.println(F("Panorama Display fährt in Schwenk-Position"));
  //Von Startposition 0 auf Schwenkposition 1 - volle Geschwindigkeit
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 1685, 200, schwenkPositionM1 + zaehler * addSchwenk, 1);
}
//
void schwenkUp(const byte zaehler)
{
  Serial.println(F("Panorama Diplay nach oben schwenken"));
  Serial.print(F("Zaehler: ")); Serial.println(zaehler);
  Serial.print(F("SchwenkPosition: "));
  Serial.print(schwenkPositionM1); Serial.print(' ');
  //Schwenkposition 1 Display schwenken - halbe Geschwindigkeit + 500 Inkremente
  schwenkPositionM1 += addSchwenk;
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 842, 200, schwenkPositionM1 + zaehler * addSchwenk, 0);
  Serial.println(schwenkPositionM1);
}
//
void schwenkDown(const byte zaehler)
{
  Serial.println(F("Panorama Diplay nach unten schwenken"));
  Serial.print(F("Zaehler: ")); Serial.println(zaehler);
  Serial.print(F("SchwenkPosition: "));
  Serial.print(schwenkPositionM1); Serial.print(' ');
  //Schwenkposition 1 Display schwenken - halbe Geschwindigkeit - 500 Inkremente
  schwenkPositionM1 >= addSchwenk ? schwenkPositionM1 -= addSchwenk : schwenkPositionM1 = 0;
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 421, 200, schwenkPositionM1, 0);
  Serial.println(schwenkPositionM1);
}
//
void startPosition()
{
  Serial.println(F("Panorama Display fährt in Start-Position"));
  // Von  Kino Position 3 auf Startposition 0 - halbe Geschwindigleit Motor 1
  // Dispaly Schwenkposition auf 0 1/20 Geschwindigleit Motor 2
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 842, 200, 0, 0);
  //roboclaw.SpeedAccelDeccelPositionM2(address, 200, 210, 200, 0, 0);
}
//
void kinoPosition()
{
  Serial.println(F("Panorama Display fährt in Kino-Position"));
  //Schwenkposition 1 Display auf Kino Position - halbe Geschwindigkeit
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 842, 200, 20000, 0);
  //roboclaw.SpeedAccelDeccelPositionM2(address, 200, 50, 200, schwenkPositionM2, 0);
}
//
void setLed(const byte led)
{
  for (byte b = 0; b < kreise; b++)
  { digitalWrite(ledPin[b], LOW); }
  digitalWrite(ledPin[led], HIGH);
}
//Display Encoder and Speed for Motor 1
void displayspeed(void)
{
  uint8_t status1, status2, status3, status4;
  bool valid1, valid2, valid3, valid4;
  int32_t enc1 = roboclaw.ReadEncM1(address, &status1, &valid1);
  int32_t enc2 = roboclaw.ReadEncM2(address, &status2, &valid2);
  int32_t speed1 = roboclaw.ReadSpeedM1(address, &status3, &valid3);
  int32_t speed2 = roboclaw.ReadSpeedM2(address, &status4, &valid4);
  Serial.print("Encoder1:");
  if (valid1)
  {
    Serial.print(enc1, DEC);
    Serial.print(" ");
    Serial.print(status1, HEX);
    Serial.print(" ");
  }
  else
  {
    Serial.print("failed ");
  }
  Serial.print("Encoder2:");
  if (valid2)
  {
    Serial.print(enc2, DEC);
    Serial.print(" ");
    Serial.print(status2, HEX);
    Serial.print(" ");
  }
  else
  {
    Serial.print("failed ");
  }
  Serial.print("Speed1:");
  if (valid3)
  {
    Serial.print(speed1, DEC);
    Serial.print(" ");
  }
  else
  {
    Serial.print("failed ");
  }
  Serial.print("Speed2:");
  if (valid4)
  {
    Serial.print(speed2, DEC);
    Serial.print(" ");
  }
  else
  {
    Serial.print("failed ");
  }
  Serial.println();
  exit(0);
}

Moin :slight_smile:
Danke für Deine Rückmeldung.
Hoffe Dir geht es gut?

Ja, mir sind die Digital Input ausgegangen, deshalb habe ich nur noch eine LED.
Mit dem 6. Eintrag habe ich gespielt, weil der Sketch nur einmal durchgeführt worden ist und ich für einen "Neuen Durchlauf", den Reset Taster betätigen musste.

Dann kannst Du das array auflösen.
Aus ledPin[kreise] wird nur noch ledPin.
setLed() kann dann weg, dafür kommt überall ein digitalWrite(ledPin, HIGH) rein.
Wann Du den Low stellst, musst dann noch rausfinden...

Da hast Du ja einen rausgehauen, muss das erstmal verstehen :slight_smile: Danke dafür...

Klar, den array werde ich später auflösen.

Habe mal ein paar Tests gemacht:
Taster 1 auf Schwenk-Position ( :+1:)
Taster 2 schwenkUp ( :+1:)
Taster 3 Schwenkdown -> geht erst wenn Schwenkup auf Zähler = 5 ist und dann sehr stark verzögert, erst nach mehrfachen drücken....
Taster 4 auf Kino ( :+1:)
Taster 5 auf Start ( :+1:)


Taster 1 auf Schwenk ( :+1:)
Taster 5 auf Start ( :+1:)


Taster 1 auf Schwenk ( :+1:)
Taster 4 auf Kino - geht leider nicht, verstehe aktuell nicht warum, sollte eigentlich


Taster 1 auf Schwenk ( :+1:)
Taster 2 Schwenkup ( :+1:)
Taster 3 Schwenkdown ( :+1:) -> geht erst wenn Schwenkup auf Zähler = 5 ist und dann sehr stark verzögert, erst nach mehrfachen drücken....
Taster 4 auf Kino ( :+1:)
Taster 1 wieder auf Schwenk - geht leider nicht....

Ich muss den Sketch immer resetten um einen erneuten durchlauf zu machen.

Vielen Dank für Deine Zeit, weiß gar nicht wie ich mich erkenntlich zeigen kann?

Gruß Ben

Hab das mal auf status 3 gesetzt, oder?

Jo.

Ich hab nur versucht, die Logik dahinter zu verstehen.
Dann wars ganz einfach...

Muss ich mal sehen...

Da gehört noch was rein, wenn mich nicht alles täuscht.
Ich hol mir mal den Code - mal sehen...

Ich als Anfänger :slight_smile: , wie lange programmierst Du schon?

zu kurz. :wink:
Ich mach viel mit Logik und weniger mit Code.
Oftmals muss ich mir auch zusammenlesen, wie was funktioniert.
Das Manko fehlendem English löst deepl.
Und ansonsten sind es immer wieder die gleichen Grundfunktionen, die verwendet werden.

Man muss sich nur angewöhnen einen Stil durchgehend beizubehalten. Und mir hilft viel die Formatierung des Codes...

Sage mal...
Du hast 5 Positionen, die mit 5 Taster angefahren werden.
Die angefahrene Position bleibt doch erhalten, wenn Sie angefahren ist.

Dann kann man das doch vereinfachen.
Ich hab das mal versucht nach folgender Logik:
Nach dem Start, fährt der in Grundstellung "start" Und danach geht es weiter mit Tasten:
start -> 1 -> schwenk -> 2 -> up (max 5) -> schwenk
start -> 1 -> schwenk -> 2 -> up -> 4 -> Kino -> 5 -> start
start -> 1 -> schwenk -> 3 -> down (max 3) -> schwenk
start -> 1 -> schwenk -> 3 -> down -> 4 -> Kino -> 5 -> start
start -> 1 -> schwenk -> 4 -> Kino -> 5 - start
start -> 1 -> schwenk -> 5 -> start
Wenn ich mich jetzt nicht verhauen habe...
Bitte meinen Kommentar zu schwenkpositionM1 beachten

//Buffered Drive M1 with signed Speed, Accel, Deccel and Position

//Includes required to use Roboclaw library
#include <SoftwareSerial.h>
#include "RoboClaw.h"

//See limitations of Arduino SoftwareSerial
SoftwareSerial serial(10, 11);
RoboClaw roboclaw(&serial, 10000);

#define address 0x80

const byte kreise = 5;
const byte tasterPin[kreise] = {2, 4, 7, 13, 12}; // S1=2 lila / S2=4 rot / S3=7 gelb / S4=12 rot / S5=13 blau /
const byte ledPin = 8; //

unsigned long schwenkPositionM1 = 11000;
const unsigned int addSchwenk = 100;

enum {tSchwenk, tSchwenkUp, tSchwenkDown, tKino, tStart}; // Auslöser Tasten
enum {pSchwenk, pSchwenkUp, pSchwenkDown, pKino, pStart}; // Positionen
byte status = pStart;

void setup()
{
  //Open Serial and roboclaw at 38400bps
  Serial.begin(57600);
  roboclaw.begin(38400);
  Serial.println(F("Starting..."));
  for (byte b = 0; b < kreise; b++)
  {
    pinMode( tasterPin[b], INPUT_PULLUP);  // wir definieren den tasterPin als Eingang mit Pull Up
  }
  digitalWrite(ledPin, LOW);
  pinMode( ledPin, OUTPUT);           // wir definieren den ledPin als Ausgang
}

void loop()
{
  actor();
}
//
void actor()
{
  static byte zaehler = 0;
  switch (status)
  {
    case pStart:
      startPosition();
      switch (tasterAbfrage())
      {
        case tSchwenk:                // 1. Taster
          zaehler = 0;
          schwenk(zaehler);
          serialSchwenk();
          status = pSchwenk;
          break;
      }
      break;
    case pSchwenk:
      switch (tasterAbfrage())
      {
        case tSchwenkUp:               // 2. Taster
          status = pSchwenkUp;
          break;
        case tSchwenkDown:             // 3. Taster
          status = pSchwenkDown;
          break;
        case tKino:                    // 4. Taster
          serialKino();
          status = pKino;
          break;
        case tStart:                   // 5. Taster
          serialStart();
          status = pStart;
          break;
      }
      break;
    case pSchwenkUp:
      switch (tasterAbfrage())
      {
        case tSchwenkUp:
          zaehler++;
          serialSchwenkUp(zaehler);
          schwenkUp(zaehler);
          serialSchwenkM1();
          if (zaehler == 5)
          {
            zaehler = 0;
            status = pSchwenk;
          }
          break;
        case tKino:
          serialKino();
          status = pKino;
          break;
      }
      break;
    case pSchwenkDown:
      switch (tasterAbfrage())
      {
        case tSchwenkDown:
          zaehler++;
          serialSchwenkDown(zaehler);
          schwenkDown();
          serialSchwenkM1();
          if (zaehler == 3)
          {
            zaehler = 0;
            schwenkPositionM1 = 0;    // Warum setzt Du den auf 0?
          }
          break;
        case tKino:
          serialKino();
          status = pKino;
          break;
      }
      break;
    case pKino:
      kinoPosition();
      switch (tasterAbfrage())
      {
        case tStart:
          serialStart();
          status = pStart;
          break;
      }
      break;
  }
}
void serialSchwenk()
{
  Serial.println(F("Panorama Display fährt in Schwenk-Position"));
}
void serialSchwenkUp(const byte &zaehler)
{
  Serial.println(F("Panorama Diplay nach oben schwenken"));
  Serial.print(F("Zaehler: ")); Serial.println(zaehler);
  Serial.print(F("SchwenkPosition: "));
  Serial.print(schwenkPositionM1); Serial.print(' ');
}
void serialSchwenkDown(const byte &zaehler)
{
  Serial.println(F("Panorama Diplay nach unten schwenken"));
  Serial.print(F("Zaehler: ")); Serial.println(zaehler);
  Serial.print(F("SchwenkPosition: "));
  Serial.print(schwenkPositionM1); Serial.print(' ');
}
void serialSchwenkM1()
{
  Serial.println(schwenkPositionM1);
}
void serialKino()
{
  Serial.println(F("Panorama Display fährt in Kino-Position"));
}
void serialStart()
{
  Serial.println(F("Panorama Display fährt in Start-Position"));
}

byte tasterAbfrage()
{
  const uint32_t bounceTime = 50;
  static uint32_t lastMillis[kreise] = {0};
  static bool gedrueckt[kreise] = {false};
  byte auswahlTaste = 255;
  for (byte b = 0; b < kreise; b++)   // Alle Tasten abfragen
  {
    if (!digitalRead(tasterPin[b]))   // gedrückt?
    {
      if (!gedrueckt[b])              // Taste nicht aktiv?
      {
        gedrueckt[b] = true;          // merken
        lastMillis[b] = millis();
        auswahlTaste = b;             // Taste zurück geben, gedrueckt
        digitalWrite(ledPin, HIGH);
      }
    }
    // Taste losgelassen, BounceTime um und vorher Taste gedrückt?
    else if (millis() - lastMillis[b] > bounceTime && gedrueckt[b])
    {
      gedrueckt[b] = false;          // löschen
      // auswahlTaste = b;              // Taste zurück geben, wenn losgelassen
      digitalWrite(ledPin, LOW);
    }
  }
  return auswahlTaste;
}
//
void startPosition()
{
  // Von  Kino Position 3 auf Startposition 0 - halbe Geschwindigleit Motor 1
  // Dispaly Schwenkposition auf 0 1/20 Geschwindigleit Motor 2
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 842, 200, 0, 0);
  //roboclaw.SpeedAccelDeccelPositionM2(address, 200, 210, 200, 0, 0);
}
//
void schwenk(const byte &zaehler)
{
  //Von Startposition 0 auf Schwenkposition 1 - volle Geschwindigkeit
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 1685, 200, schwenkPositionM1 + zaehler * addSchwenk, 1);
}
//
void schwenkUp(const byte &zaehler)
{
  //Schwenkposition 1 Display schwenken - halbe Geschwindigkeit + 500 Inkremente
  schwenkPositionM1 += addSchwenk;
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 842, 200, schwenkPositionM1 + zaehler * addSchwenk, 0);
}
//
void schwenkDown()
{
  //Schwenkposition 1 Display schwenken - halbe Geschwindigkeit - 500 Inkremente
  schwenkPositionM1 >= addSchwenk ? schwenkPositionM1 -= addSchwenk : schwenkPositionM1 = 0;
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 421, 200, schwenkPositionM1, 0);
}
//
void kinoPosition()
{
  //Schwenkposition 1 Display auf Kino Position - halbe Geschwindigkeit
  roboclaw.SpeedAccelDeccelPositionM1(address, 200, 842, 200, 20000, 0);
  //roboclaw.SpeedAccelDeccelPositionM2(address, 200, 50, 200, schwenkPositionM2, 0);
}
//
//Display Encoder and Speed for Motor 1
void displayspeed(void)
{
  uint8_t status1, status2, status3, status4;
  bool valid1, valid2, valid3, valid4;
  int32_t enc1 = roboclaw.ReadEncM1(address, &status1, &valid1);
  int32_t enc2 = roboclaw.ReadEncM2(address, &status2, &valid2);
  int32_t speed1 = roboclaw.ReadSpeedM1(address, &status3, &valid3);
  int32_t speed2 = roboclaw.ReadSpeedM2(address, &status4, &valid4);
  Serial.print("Encoder1:");
  if (valid1)
  {
    Serial.print(enc1, DEC);
    Serial.print(" ");
    Serial.print(status1, HEX);
    Serial.print(" ");
  }
  else
  {
    Serial.print("failed ");
  }
  Serial.print("Encoder2:");
  if (valid2)
  {
    Serial.print(enc2, DEC);
    Serial.print(" ");
    Serial.print(status2, HEX);
    Serial.print(" ");
  }
  else
  {
    Serial.print("failed ");
  }
  Serial.print("Speed1:");
  if (valid3)
  {
    Serial.print(speed1, DEC);
    Serial.print(" ");
  }
  else
  {
    Serial.print("failed ");
  }
  Serial.print("Speed2:");
  if (valid4)
  {
    Serial.print(speed2, DEC);
    Serial.print(" ");
  }
  else
  {
    Serial.print("failed ");
  }
  Serial.println();
}

Moin Moin,

mit deepl arbeite ich auch teilweise. Sehr guter Übersetzer.

Habe früher sehr viel SPS programmiert, arbeite auch lieber mit der Logik aber wenn du die Befehle (wie bei C++) nicht wirklich kennst, tut man sich schwer...

Das fuktioniert schon mal sehr gut, danke dafür. Ich versuche noch die Möglichkeit einzubinden, wenn man in pKino ist wieder zu pSchwenk zu fahren.

Viele Grüße

ein zusätzliches

case tSchwenk:
status=pSchwenk;
break;

wäre ein erster Ansatz :slight_smile:

Guten Morgen :slight_smile:

Soweit funktioniert alles sehr gut, danke für Deine Unterstützung.

Was ich gerne noch ändern würde, wäre die Taster für Schwenkup und Schwenkdown zu ändern, das mit den Zählern war für den Anfang gut aber um die Endanschläge "manuell" anfahren zu können würde ich es gerne anders machen.

Ich habe gestern schon etwas geändert, was nicht zum Erfolg geführt hat. Alle Taster werden mit der "Entprell Funktion" abgefragt, das bereitet mir ein wenig Probleme.

Taster 1 Schwenkup und Taster 2 Schwenkdown sollen nicht über einen Zähler abgefragt (positionsgesteuert) werden sondern so lange ich den Taster drücke, fährt der Motor. (Die Geschwindigkeit und rechts/links Lauf weiß ich, wie man es programmieren muss).

Vielleicht hast Du eine Idee?
Besten Dank und einen schönen Tag.

Gruß

Ben