Nerf flywheel Einzelfeuer & Feuerstoss brauche Hilfe

Moin zusammen,
Ich hab wohl ein Denkfehler und bekomme es nicht hin. Hab schon mehrere Varianten probiert und jedes mal bin ich gescheitert.

Folgendes sollte passieren:
Wenn buttonFlywheel = 0 soll sich Flywheel drehen...
wenn bottonAbzug & buttonEinzelfeuer = 0 soll ein mal geschossen werden ABER Flywheel soll weiter drehen

oder wenn buttonAbzug & buttonFeuerstoss = 0 soll drei mal geschossen werden ABER Flywheel soll immer noch so lage drehen bis buttonFlywheel =1

Ich habe bestimmt nur ein Gedankenfehler und wäre für jeden Hinweis dankbar.

Aktuell ist es so, dass das Flywheel sich dreht wird buttonFlywheel gedrückt, wird der Abzug bei FS o. EF betätigt hört auch das Flywheel auf sich zu drehen wenn geschossen wurde.


#include <Servo.h>
const int button_abzug = 2;
const int button_feuerstoss = 4;
const int button_einzelfeuer = 6;
const int button_flywheel = 8;
Servo flywheel;
Servo pusher;
int buttonAbzug = 1;
int buttonFeuerstoss = 1;
int buttonEinzelfeuer = 1;
int buttonFlywheel = 1;
boolean grundstellung = false;



void setup() {
  Serial.begin(9600);
    pinMode(button_abzug, INPUT_PULLUP);
  pinMode(button_feuerstoss, INPUT_PULLUP);
  pinMode(button_einzelfeuer, INPUT_PULLUP);
  pinMode(button_flywheel, INPUT_PULLUP);

  pusher.attach(9);  
  pusher.write(140); //Pusher auf Null
  delay(100);

    flywheel.writeMicroseconds(1000);

  flywheel.attach(11, 1000, 2000);
  delay(5000);
}
void loop() {
  buttonAbzug = digitalRead(button_abzug);
  buttonFeuerstoss = digitalRead(button_feuerstoss);
  buttonEinzelfeuer = digitalRead(button_einzelfeuer);
  buttonFlywheel = digitalRead(button_flywheel);

  if ((buttonFlywheel == LOW) )
  {
    delay(30);
    flywheel.write(92);
    delay(30);

 if ((buttonAbzug == LOW) && (buttonEinzelfeuer == LOW) && grundstellung == false)
  
   { 
    delay(30);
    pusher.write(40); 
    delay(300);
    pusher.write(140);
    delay(300);
    grundstellung=true;         
  } 
  if ( (buttonAbzug == LOW)&&(buttonFeuerstoss == LOW)&& grundstellung == false)
   { 
    delay(30);
    pusher.write(40); 
    delay(300);
    pusher.write(140);
    delay(300);
    pusher.write(40); 
    delay(300);
    pusher.write(140);
    delay(300);
    pusher.write(40); 
    delay(300);
    pusher.write(140);
    delay(300);
    grundstellung=true;
               
  } 
       } else {
      flywheel.write(0);
      delay(30);
    }
} 

Hier mein erster Ansatz etwas mehr Abfragen aber selbes Ergebnis

Lösung ist bestimmt denkbar einfach, ich komme aber einfach nicht drauf.


#include <Servo.h>
const int button_abzug = 2;
const int button_feuerstoss = 4;
const int button_einzelfeuer = 6;
const int button_flywheel = 8;
Servo flywheel;
Servo pusher;
int buttonAbzug = 1;
int buttonFeuerstoss = 1;
int buttonEinzelfeuer = 1;
int buttonFlywheel = 1;
boolean grundstellung = false;



void setup() {
  Serial.begin(9600);
    pinMode(button_abzug, INPUT_PULLUP);
  pinMode(button_feuerstoss, INPUT_PULLUP);
  pinMode(button_einzelfeuer, INPUT_PULLUP);
  pinMode(button_flywheel, INPUT_PULLUP);

  pusher.attach(9);  
  pusher.write(140); //Pusher auf Null
  delay(100);

    flywheel.writeMicroseconds(1000);

  flywheel.attach(11, 1000, 2000);
  delay(5000);



}

void loop() {
  buttonAbzug = digitalRead(button_abzug);
  buttonFeuerstoss = digitalRead(button_feuerstoss);
  buttonEinzelfeuer = digitalRead(button_einzelfeuer);
  buttonFlywheel = digitalRead(button_flywheel);

  if ((buttonFlywheel == LOW) && (buttonFeuerstoss == LOW || buttonEinzelfeuer == LOW))
  {
    delay(30);
    flywheel.write(92);
    delay(30);
    } else {
      flywheel.write(0);
      delay(30);
    }
 if ((buttonAbzug))grundstellung=false;
  if ((buttonFlywheel == LOW) && (buttonAbzug == LOW)&&(buttonEinzelfeuer == LOW)&&(!grundstellung))
   { 
    delay(30);
    pusher.write(40); 
    delay(300);
    pusher.write(140);
    delay(300);
    grundstellung=true;         
  } 
  if ((buttonFlywheel == LOW) && (buttonAbzug == LOW)&&(buttonFeuerstoss == LOW)&&(!grundstellung))
   { 
    delay(30);
    pusher.write(40); 
    delay(300);
    pusher.write(140);
    delay(300);
    pusher.write(40); 
    delay(300);
    pusher.write(140);
    delay(300);
    pusher.write(40); 
    delay(300);
    pusher.write(140);
    delay(300);
    grundstellung=true;
               
  } 
   
} 

Deine delay stehen Dir im Weg. Du hast ja schon 1.8 Sekunden drin, in denen gewartet wird.
Schau Dir das Beispiel BlinkWithoutDelay in der IDE an und verstehe es oder arbeite Dich in die Timer der MoBaTools ein.

Gruß Tommy

Ich klabüster mal auseinander:
a)
Flywheel soll sich solange drehen, wie buttonFlywheel gedrückt ist.
Wenn der button losgelassen wird, bleibt das ding stehen.

b) wenn buttonAbzug gedrückt ist, gibt es drei Möglichkieten.
b.1) Kein weiterer Button gedrückt -> Es passiert nix
b.2) buttonEinzelfeuer gedrückt -> 1x auslösen dann sperren
b.2.1. Erneutes auslösen erst, wenn der button zwischendurch losgelassen wurde
b.2.2. Gleichzeitiges auslösen von buttonDauerfeuer ist gesperrt

b.3) buttonDauerfeuer gedrückt -> dauerhaft auslösen
b.3.1. Wenn Taste losgelassen wird sofort aufgehört
b.3.2. Gleichzeitiges auslösen von buttonEinzelfeuer ist gesperrt.

JA?

Danke für deine schnelle Antwort.
Ich verstehe die millis etwas. Habs auch Anfänglich damit versucht. Da kam aber nur Grütze bei raus weil die Zeiten durcheinander liefen. (da habe ich aber noch versucht schon im setup mit milis zu arbeiten werde das mal mit delay und millis probieren.

Aber vielleicht hat ja jemand doch ne delay Lösung, dass flywheel dreht sich bis vermutlich grundstellung = true je Sequenz.
Ich male es mir morgen noch mal auf mit millis...

Nein.
Es steht Dir im Weg.
War doch deutlich.

oh mein Gott das ist gut, warum hab ich das nicht so geschrieben.
grundsätzlich Feuerstoß und Einzelfeuer ist ein Wahlschalter somit gleichzeitig ausgeschlossen.

a) Wenn buttonFlywheel gedrückt ist Flywheel drehen (flywheel.write(92)

b) wenn buttonAbzug gedrückt ist, gibt es drei Möglichkieten. JA (nix // einzelfeuer // feuerstoss)

b1) Kein weiterer Button gedrückt -> Es passiert nix. JA

b.2) buttonEinzelfeuer gedrückt -> 1x auslösen dann Grundstellung

b.2.1. Erneutes auslösen erst, wenn der button zwischendurch losgelassen wurde JA

b.3) buttonFeuerstoss gedrückt -> 3x auslösen dann Grundstellung

b.3.1. Erneut auslösen erst wenn der button zwischendurch losgelassen wurde

ich weiss. :smiling_face_with_halo:

weiss ich nicht :rolling_on_the_floor_laughing:

Ok, ich versuch mal was logisches.


ich kann nur Praktisch geht´s auch mit nem Hammer? :rolling_on_the_floor_laughing:

man man man seit ihr flott hier. Ich denke mal son billo kram schreibt ihr in unter ner Minute.... ich hab dafür Tage gebraucht um alleine die Richtigen billig Fahrregler an Start zu bekommen. 2 Arduinos haben bisschen gequalmt weil ein Schalter hin war. Hut ab, hab den größten Respekt vor euch. Hab hier auch viel im Forum gestöbert und rausgezogen.

1 Like

Naja - ganz so schnell gehts bei mir auch nicht.
Ich schreib das alles mit der Hand und bau das ohne vorgefertigte Scripte.
Nur reine Logik.

Sag mal, Du wartest zu Anfang immer 30ms - Bist Du Dir sicher, dass das gewollt ist?

geht bestimmt auch ohne die 30ms
hatte es zur Sicherheit mit eingebaut.

die 300ms sind ein Weg vom pusher, sprich er brauch 300ms für ganz vor und 300 für ganz zurück. Es irritiert mich das immer eine ganze Sequenz durchläuft und das FW dann stehen bleibt.

Ich muss mal schaun, was da alles zusammengehört. Hatte bis eben noch 2 andere Hochzeiten :slight_smile:

Mooment.
Das FW läuft nur auf Position 92 - dann ist Schluss.
Erst wenn der FW-button losgelassen geht der wieder auf Position 0.

Was soll das Ding machen? zwischen 92 und 0 ständig hin und her solange der button gedrückt ist?
Das mit den Feuertasten hab ich logisch begriffen. Aber das wird nicht in 10 Zeilen stehen :slight_smile:

Ganz in ruhe, und NEIN hab keine vorgefertigten Skripte gezogen, lediglich den Weg hab ich mir angeschaut und alles dann per Hand geschrieben. Nur so versteht man auch halbwegs was man macht.

Jetzt qualmt nicht nur der UNO sondern auch mein Kopf.
92 ist GAS und 0 ist STOP.
Solange der Button gedrückt ist 92 wenn Button nicht gedrückt 0

Ah ok - dann hab ichs.
Zu morgen früh - ich werd heute nicht mehr alt.

Wenns nicht passt, kannste ja mal versuchen ob es mit Hammer besser wird.
kompiliert - aber ich hab keine ahnung, was ich da gemacht habe.

#include <Servo.h>

constexpr uint8_t pusherPin {9};
constexpr uint8_t wheelPin {11};

constexpr uint8_t puNullPos {140};
constexpr uint8_t puFirePos {40};

constexpr uint8_t fwNullPos {0};
constexpr uint8_t fwActivPos {92};

Servo pusher;
Servo flywheel;


constexpr uint8_t btnAbzug {2};
// es wird nur ein Button gebraucht! Im Code wird btnFeuerstoss nicht verwendet
constexpr uint8_t btnFeuerstoss {4};
constexpr uint8_t btnEinzelfeuer {6};
constexpr uint8_t btnWheel {8};

constexpr uint8_t btnSize {4};
constexpr uint8_t allBtn[btnSize] {btnAbzug, btnFeuerstoss, btnEinzelfeuer, btnWheel};

constexpr bool isPressed {LOW};

constexpr uint8_t oneShot {1};
constexpr uint8_t threeShot {3};
constexpr uint32_t shotTime {300};

uint8_t shot;
bool shotActive = false;



void setup()
{
  Serial.begin(9600);
  Serial.println(F("Start..."));
  for (byte b = 0; b < btnSize; b++)
  { pinMode(allBtn[b], INPUT_PULLUP); }
  pusher.attach(pusherPin);
  pusher.write(puNullPos); //Pusher auf Null
  flywheel.writeMicroseconds(1000);
  flywheel.attach(wheelPin, 1000, 2000);
  flywheel.write(fwNullPos);
  while ((digitalRead(btnAbzug) == isPressed) ||
         (digitalRead(btnWheel) == isPressed))
  {
    Serial.println(F("Auslöser blockiert!"));
    delay(500);
  }
}

void loop()
{
  checkWheel();
  checkFireButton();
}

void fire()
{
  static byte shotStep = 0;
  static uint32_t myMillis = 0;
  switch (shotStep)
  {
    case 0:
      if (shot)
      {
        if (pusher.read() == puNullPos)   // Schuss nicht ausgelöst
        { pusher.write(puFirePos); }      //
        else                              // Schuss ausgelöst
        {
          pusher.write(puNullPos);
          shot--;                          // Schuss löschen
          if (shotActive == false)         // greift bei Dauerfeuer und gelöster Taste
          { shot = 0; }
        }
      }
      if (shot) // Prüfung ob noch ein Schuss aktiv ist
      {
        myMillis = millis();
        shotStep = 1;
      }
      break;
    case 1:
      if (millis() - myMillis > shotTime)
      { shotStep = 0; }
      break;
  }
}
//
void checkFireButton()
{
  if (digitalRead(btnAbzug) == isPressed)
  {
    if ((shotActive == false) &&
        (shot == 0))
    {
      shotActive = true;
      shot = digitalRead(btnEinzelfeuer) == isPressed ? oneShot : threeShot;
    }
  }
  else
  { shotActive = false; }
  fire();
}
//
void checkWheel()
{
  flywheel.write(digitalRead(btnWheel) == isPressed ? fwActivPos : fwNullPos);
}

Nicht schlecht so auf die schnelle. Vielen Dank
Leider geht das so nicht.

  1. Die Start Sequenz im Setup darf nicht verändert werden da die Regler sonst nicht oder anders Laufen.
    flywheel.writeMicroseconds(1000);
 flywheel.attach(11, 1000, 2000);
  delay(5000);

DAS delay ist sehr sehr wichtig und bei allen Reglern unterschiedlich. Die Start Abläufe sind bei den Reglern unterschiedlich. Machen reicht einfach nur LOW für 2600ms

  1. Dein Code (danke noch mal für die Arbeit) lässt das FW zwar laufen für die button pressed Zeit ohne Unterbrechung, passt soweit.
  2. auf EF geht der pusher beim drücken vor und zurück und beim Loslassen nochmal schnell vor und zurück
  3. auf FS geht der pusher langsam vor und dann zu schnell zurück-vor-zurück vor-zurück und beim loslassen des Abzugs wieder vor und zurück.
  4. jetzt muss ich erstmal nen paar Stunden deinen code studieren

Noch mal danke!!!! bitte Erstmal keine Hilfe mehr. Ich schreibe heute noch mal jeden code einzeln raus und teste die, ich meine mich zu erinnern das die einzeln funktioniert haben. (also nur EF oder nur FS)