Mehrstufige If-Abfrage

Hallo an alle,

ich schaffe es, meinen Motor (VSM0806) laufen zu lassen, wenn er durch meinen Drucksensor (Pololu, Artikeln. 2727) ausgelöst wird.
Nun möchte ich eine verschachtelte If-Abfrage machen - wenn der Sensor gedrückt wurde, soll auf eine Entlastung abgefragt werden und wenn diese erfolgt 1 Minute gewartet werden. Dann wird noch einmal auf Entlastung abgefragt, dann nochmal 1 min gewartet. Wenn dann kein Druck mehr zu delektieren ist, dann wird der Motor ausgelöst. Ich habe schon an switch-cases und an verschachtelten if-Abfragen gearbeitet, aber da funktioniert nichts.

Blöd formuliert so:

if (sensor > 150) {
   unsigned long Millis = millis();

   if (sensor < 150 && Millis > 60000) {
      unsigned long Millis = millis();
      if (sensor < 150 && Millis > 60000) {
          stepper.move(-steps * microsteps);
          delay(1000);
          stepper.move(steps * microsteps);
          delay(1000);
}

Kann mir jemand helfen?

Vielen Dank schonmal!

Du suchst eine klassische Schrittkette.
Kennst Du switch/case?
Ich würde gerne einen vollständigen Sketch sehen. Dann kann man was basteln.

Eher möchtest Du eine Schrittkette. Ganz grob sowas:

void setup()
{
  Serial.begin(9600);
  Serial.println("\nStart");
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  uint32_t jetzt = millis();
  uint32_t intervall = 0;
  static uint32_t vorhin = 0;
  static byte schritt = 0;
  byte sensor = analogRead(A0) / 4;
  Serial.print("sensor: ");
  Serial.println(sensor);

  if (jetzt - vorhin >= intervall)
  {
    switch (schritt)
    {
      case 0:
        if (sensor > 150)
        {
          digitalWrite(LED_BUILTIN, HIGH);
          intervall = 6000;  // abgekürzt
          vorhin = jetzt;
          schritt++;
          Serial.print("schritt: "); Serial.println(schritt);
        }
        break;
      case 1:
        if (sensor < 150)
        {
          intervall = 6000;  // abgekürzt
          vorhin = jetzt;
          schritt++;
          Serial.print("schritt: "); Serial.println(schritt);
        }
        break;
      case 2:
        if (sensor < 150)
        {
          digitalWrite(LED_BUILTIN, LOW);
          schritt = 0;
          Serial.print("schritt: "); Serial.println(schritt);
        }
        break;
    }
  }

  delay(200);  // nur zum Testen
}

Ich auch :slightly_smiling_face:

Ich glaube nicht daß dieser Motor mit einem Microschritttreiber ordentlich angesteuert werden kann.
Grüße Uwe

Der funktioniert damit tatsächlich hervorragend, ist ein kleiner Linear-Schrittmotor.

Ja, das kenn ich, ich bin nur am Rumbasteln gewesen und in meinem Kopf ergibt sich noch keine sinnvolle Lösung. Einen vollständigen Sketch kann ich noch nicht zeigen, ich habe bisher nur mit ganz vielen if's gearbeitet.
Das, was ich oben geschrieben habe, ist eigentlich mein ganzer Loop bisher. Initialisierungen am Anfang sind:

#include <Arduino.h>
#include "BasicStepperDriver.h"
#define sensorPin 2
#define DIR 0
#define STEP 1
#define steps 2000
#define RPM 120

#define microsteps 1

#define sensorPin 2


BasicStepperDriver stepper(steps, DIR, STEP);

void setup() {
  Serial.begin(9600);
  stepper.begin(RPM, microsteps);
}
void loop() {

  int sensor = analogRead(sensorPin); // Auslesen des Sensorwertes (zwischen 0 und 1023)


  Serial.print("Der Druck beträgt: ");
  Serial.println(sensor);
  delay(500);


  if (sensor > 150) {
    unsigned long Millis = millis();
    Serial.println(Millis);
    
    if (sensor < 150 && millis > 1000) {
      stepper.move(-steps * microsteps);
      delay(1000);
      stepper.move(steps * microsteps);
      delay(1000);

    }
  
}

Danke für deinen Vorschlag!! Ich verstehe die switch-cases aber so, dass entweder der eine oder der andere Fall abgearbeitet wird, aber nicht beide hintereinander, oder?

Die Zeile liefert eine Warnung!
Und das mit Recht!

Auch diese Zeile hat ein Problem!

Bitte mit etwas mehr Sorgfalt zu Werke gehen.

Gut, dass ich mal die Chance habe, dir auf einen Kommentar zu antworten- ich find es wirklich schade, dass (und warum??) du auf sämtliche Fragen so schnippisch, zynisch oder böse antwortest. Nicht nur bei mir, auch bei ganz vielen anderen Posts sehe ich das.
Wenn ich es könnte, bzw. besser wüsste, würde ich kaum nach Hilfe fragen.
Warum kannst du nicht einfach freundlich und ernsthaft hilfreich kommentieren, die anderen können das doch auch? Ansonsten überspring doch einfach meine Fragen, danke.

Wieso, er hat doch Recht.

Gruß Tommy

Das mag sein, aber weder ist sein Kommentar hilfreich, noch freundlich.

Ob hilfreich, kannst du offensichtlich gar nicht beurteilen, denn dann wäre dein Reaktion eine andere
Bist du viel zu sehr damit beschäftigt bist, über mich zu urteilen, so dass dir die wirklich wichtigen, fachlichen, Dinge durch die Lappen gehen?.

Und was daran unfreundlich ist, könntest du mir auch mal gerne mitteilen.
Oder ist für dich schon die Tatsache, dass ich fachliche Kritik übe, ein Akt der Unfreundlichkeit?

Mal abgesehen davon, das eine schließende geschweifte Klammer in deinem Schnipsel fehlt.

Die zweite If-Bedingung wird nie wahr, da sie nur erreicht wird wenn sensor einen Wert größer 150 hat.

Die hat (noch) ein anderes Problem:

E:\Programme\arduino\portable\sketchbook\sketch_sep01b\sketch_sep01b.ino:34:32: warning: ISO C++ forbids comparison between pointer and integer [-fpermissive]
   34 |     if (sensor < 150 && millis > 1000) {
      |                         ~~~~~~~^~~~~~

Aber es ist wie im alten Rom....
Da war das töten des Boten, der die schlechten Nachrichten gebracht hat, auch eine Tradition.

Ich hab mal drauf geschaut...
Vermeide soweit es geht, #define zu verwenden.
Du hattest vor dem edit 2x den sensorPin damit gesetzt.
Das geht sogar Fehlerfrei:

#define sensorPin 3
#define sensorPin 2

Der letzte überschreibt den ersten.

millis() und Millis ist fehleranfällig.
Verwende wenn Du kannst "sprechende" Variablen.

Ich komm irgendwie noch nicht mit der Logik klar.
WENN sensor >150 DANN millis merken DANN darauf warten, das Zeit abgelaufen UND sensor < 150 dann einmal steppen und dann wieder von vorn?
Dann wäre es vielleicht...
(Ich würde das delay(500) rausschmeissen, das mit dem SerMon und dem sensorwert lässt sich besser lösen)

#include <Arduino.h>
#include "BasicStepperDriver.h"
const uint16_t DIR = 0;
const uint16_t STEP = 1;
const uint16_t steps = 2000;
const uint16_t RPM = 120;
const uint16_t microsteps = 1;
const byte sensorPin = 2;

BasicStepperDriver stepper(steps, DIR, STEP);

const uint32_t stepTime = 1000;
uint32_t stepStartZeit;
uint32_t ausloeseZeit;
byte status = 0;

void setup()
{
  Serial.begin(9600);
  stepper.begin(RPM, microsteps);
}
void loop()
{
  int sensor = analogRead(sensorPin); // Auslesen des Sensorwertes (zwischen 0 und 1023)
  Serial.print("Der Druck beträgt: ");
  Serial.println(sensor);
  delay(500);
  switch (status)
  {
    case 0:
      if (sensor > 150)
      {
        ausloeseZeit = millis();
        Serial.println(ausloeseZeit);
        status = 1;
      }
      break;
    case 1:
      if (millis() - ausloeseZeit > 60000)
      {
        if (sensor < 150)
        {
          stepper.move(-steps * microsteps);
          stepStartZeit = millis();
          status = 2;
        }
        else if (sensor > 150)
        {
          status = 0;
        }
      }
      break;
    case 2:
      if (millis() - stepStartZeit > stepTime)
      {
        stepper.move(steps * microsteps);
        status = 3;
      }
      break;
    case 3:
      if (millis() - stepStartZeit > stepTime * 2)
      {
        status = 1;
      }
      break;
  }
}

Das war beabsichtigt - es ging nur um die Darstellng der Reihenfolge.

Vielen Dank für deine Antwort!!
Genau- erst soll der Sensor einmal gedrückt werden (>150), dann entlastet. Wenn also die Entlastung bemerkt wurde (<150) soll ein Timer starten (1 min). Nach dem Timer nochmal die Abfrage, ob immer noch <150. Dann nochmal der Timer. Wenn danach der Sensorwert >150 dann soll abgebrochen werden. Wenn er immer noch < 150 ist, dann soll der Motor laufen.

Ok, steht jetzt oben drin:

      if (millis() - ausloeseZeit > 60000)

Der Rest müsste stimmen.
Zum testen würde ich aber nicht auf die Minute warten, 5000 reichen auch :wink:

1 Like

Ja, da ein break jeweils ein case beendet. Erst der eine Schritt, dann der nächste, das ist die Idee.

Du stellst keine Frage an Deine Freunde, sondern in einem öffentlichen Forum, da wirst Du manche nett finden, andere nicht, das mußt Du akzeptieren. Allerdings ist sein Beitrag sowohl sachlich richtig, wie auch hilfreich. Auch empfinde ich ihn keineswegs als unfreundlich.

Inhaltlich ist die Warnung problematisch, da es sich eigentlich um einen Fehler handelt, denn millis wäre eine Variable, Du möchtest aber die Funktion/Methode/Makro millis(), also mit Klammern. Ein blöder Fehler, weil er vom Kompiler nicht als Fehler erkannt wird.

Daher unbedingt merken! Da wir am besten über Emotionen lernen, darfst Du Dich jetzt nochmal ganz doll über @combie ärgern, dann vergißt Du es nicht mehr :rofl:

Inzwischen ist so viel geschrieben worden, da muß ich erstmal nachlesen.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.