Gießautomat mit einem Arduino Uno

Hallo,

ich bin komplett neu in der Welt der Arduinos und der Programmierung und wollte mit euch mal meinen ersten Code teilen-

Das letzte mal saß ich vor locker 20 Jahren in der Schule und habe damals noch delphi geschrieben.

Die Sensorik habe ich noch nicht, also existiert bisher nur alles in meinem Kopf.

Über Feedback und Fehler würde ich mich freuen, damit nachher die Wohnung nicht unter Wasser steht.


const uint8_t Pump1 = 2;  // Namen für Digitalpins 1-5
const uint8_t Pump2 = 3;
const uint8_t Pump3 = 4;
const uint8_t Pump4 = 5;

const uint8_t In1 = A0;  // Namen für Analogpins 1-4
const uint8_t In2 = A1;
const uint8_t In3 = A2;
const uint8_t In4 = A3;

int senswert1;  // Name für Sensorwert
int senswert2;
int senswert3;
int senswert4;

const int TROCKEN = 600;
const int FEUCHT = 475;


unsigned long t0,t1,t2,t3,t4;
unsigned long testintervall = 1000;
unsigned long pumpdauer = 3000;
unsigned long pausedauer =  30000;


void setup() {

  Serial.begin(38400);
  Serial.println("LetsGrow"); 
  pinMode(Pump1, OUTPUT);  // Digitale Pins 1-5 werden auf OUTPUT gestellt
  pinMode(Pump2, OUTPUT);
  pinMode(Pump3, OUTPUT);
  pinMode(Pump4, OUTPUT);


  
}

void loop() {


  t0 = millis();

/////////////////////////////////////////////////////
///////////////////BLOCK 1///////////////////////////
/////////////////////////////////////////////////////


  if (t0 - t1> testintervall)   //Testintervall wird abgefragt
  {
    senswert1 = analogRead(In1);
    Serial.print("Sensor 1: ");
    Serial.println(senswert1); //Wert von Sensor wird ausgelesen

    if (senswert1 < TROCKEN) 
    {
     if(t0 > (t1 + pausedauer) )
     {   
      digitalWrite(Pump1, HIGH); //Pumpe wird eingeschaltet
      Serial.println("Pumpe 1 an ");
      t1 = t0;              //Zeitstempel wird gesetzt
     }
    
      if (t1 + pumpdauer < t0) {
        digitalWrite(Pump1, LOW);
        Serial.println("Pumpe 1 aus");  
      }

    }  
    else{
      digitalWrite(Pump1, LOW);
      Serial.println("Pumpe 1 aus");
    }
  }

/////////////////////////////////////////////////////
///////////////////BLOCK 2///////////////////////////
/////////////////////////////////////////////////////

  if (t0 - t2> testintervall)   //Testintervall wird abgefragt
  {
    senswert2 = analogRead(In2);
    Serial.print("Sensor 2: ");
    Serial.println(senswert2); //Wert von Sensor wird ausgelesen

    if (senswert2 < TROCKEN) 
    {
     if(t0 > t2 + pausedauer )
     {   
      digitalWrite(Pump2, HIGH); //Pumpe wird eingeschaltet
      Serial.println("Pumpe 2 an ");
      t2 = t0;              //Zeitstempel wird gesetzt

     }
    
      if (t2 + pumpdauer < t0) {
        digitalWrite(Pump2, LOW);
        Serial.println("Pumpe 2 aus");  
      }

    }  
    else{
      digitalWrite(Pump2, LOW);
      Serial.println("Pumpe 2 aus");
    }
  }

/////////////////////////////////////////////////////
///////////////////BLOCK 3///////////////////////////
/////////////////////////////////////////////////////


  if (t0 - t3> testintervall)   //Testintervall wird abgefragt
  {
    senswert3 = analogRead(In3);
    Serial.print("Sensor 3: ");
    Serial.println(senswert3); //Wert von Sensor wird ausgelesen

    if (senswert3 < TROCKEN) 
    {
     if(t0 > t3 + pausedauer )
     {   
      digitalWrite(Pump3, HIGH); //Pumpe wird eingeschaltet
      Serial.println("Pumpe 3 an ");
      t3 = t0;              //Zeitstempel wird gesetzt
     }
    
      if (t3 + pumpdauer < t0) {
        digitalWrite(Pump3, LOW);
        Serial.println("Pumpe 3 aus");  
      }

    }  
    else{
      digitalWrite(Pump3, LOW);
      Serial.println("Pumpe 3 aus");
    }
  }

/////////////////////////////////////////////////////
///////////////////BLOCK 4///////////////////////////
/////////////////////////////////////////////////////


  if (t0 - t4> testintervall)   //Testintervall wird abgefragt
  {
    senswert4 = analogRead(In4);
    Serial.print("Sensor 4: ");
    Serial.println(senswert4); //Wert von Sensor wird ausgelesen

    if (senswert4 < TROCKEN) 
    {
     if(t0 > t4 + pausedauer )
     {   
      digitalWrite(Pump4, HIGH); //Pumpe wird eingeschaltet
      Serial.println("Pumpe 4 an ");
      t4 = t0;              //Zeitstempel wird gesetzt
     }
    
      if (t4 + pumpdauer < t0) {
        digitalWrite(Pump4, LOW);
        Serial.println("Pumpe 4 aus");  
      }

    }  
    else{
      digitalWrite(Pump4, LOW);
      Serial.println("Pumpe 4 aus");
    }
  }

//////////////////////////////////////////////////////////////////////////////////////////////

    delay(1000); 
}
  
    



 

Nice, you are using millis() to allow concurrent activities. Not so nice: The delay() at the end.

I assume all blocks should do the same.

It might be a good idea to refactor the code a bit. Use a struct to keep all relevant information for one block in the same context. This allows you to write code once and handle many sensors the same way simply by changing a parameter.

struct BlockInfo {
    uint8_t pin_pump;
    uint8_t pin_sensor;
    int value_sensor;
    unsigned long time_lastCheck;
   ...
};

BlockInfo block1;
BlockInfo block2;
BlockInfo block3;
BlockInfo block4;

void updateBlock(BlockInfo *block) {
  auto now = millis();
  if (now - block->time_lastCheck > testintervall){
    <check sensor and control pump>
    ...
    block->time_lastCheck = now;
  }
}

void loop(){
    updateBlock(&block1);
    updateBlock(&block2);
    updateBlock(&block3);
    updateBlock(&block4);
}

This will overflow after 49 days and the delay will not work as desired.

@devicious ,

:warning:
Im englischen Teil des Forum müssen die Beiträge und Diskussionen in englischer Sprache verfasst werden.
Deswegen wurde diese Diskussion in den deutschen Teil des Forums verschoben.
mfg ein Moderator.

Zum Frühstück - ungetestet. Kompiliert.

const int TROCKEN = 600;
const int FEUCHT = 475;

constexpr bool ein {LOW};

enum class GROWSTEP {CHECK, PUMPEN, WARTEN};

//unsigned long testintervall = 1000;
unsigned long pumpdauer = 3000;
unsigned long pausedauer =  30000;


struct WATERGATE
{
  const uint8_t sensorPin;
  const uint8_t pumpePin;
  uint32_t lastCheckTime;
  GROWSTEP step;
};

constexpr uint8_t gates {4};
WATERGATE watergate[]
{
  {A0, 2, 0, GROWSTEP::CHECK,},
  {A1, 3, 0, GROWSTEP::CHECK,},
  {A2, 4, 0, GROWSTEP::CHECK,},
  {A3, 5, 0, GROWSTEP::CHECK,},
};


void setup()
{
  Serial.begin(38400);
  Serial.println(F("LetsGrow"));
  for (byte b = 0; b < gates; b++)
  {
    pinMode(watergate[b].sensorPin, INPUT);
    pinMode(watergate[b].pumpePin, OUTPUT);
    digitalWrite(watergate[b].pumpePin, !ein);
  }
}

void loop()
{
  uint32_t myMillis = millis();
  for (byte b = 0; b < gates; b++)
  {
    switch (watergate[b].step)
    {
      case GROWSTEP::CHECK:
        if (analogRead(watergate[b].sensorPin) < TROCKEN)
        {
          Serial.print(F("Pumpe "));
          Serial.print(b + 1);
          Serial.println(F(" EIN!"));
          digitalWrite(watergate[b].pumpePin, ein);
          watergate[b].lastCheckTime = myMillis;
          watergate[b].step = GROWSTEP::PUMPEN;
        }
        break;
      case GROWSTEP::PUMPEN:
        if ((myMillis - watergate[b].lastCheckTime > pumpdauer) ||
            (analogRead(watergate[b].sensorPin) > FEUCHT))
        {
          Serial.print(F("Pumpe "));
          Serial.print(b + 1);
          Serial.println(F(" AUS!"));
          digitalWrite(watergate[b].pumpePin, !ein);
          watergate[b].lastCheckTime = myMillis;
          watergate[b].step = GROWSTEP::WARTEN;
        }
        break;
      case GROWSTEP::WARTEN:
        if (myMillis - watergate[b].lastCheckTime > pausedauer)
        {
          Serial.print(F("Arbeitskreis "));
          Serial.print(b + 1);
          Serial.println(F(" Pause abgelaufen"));
          watergate[b].step = GROWSTEP::CHECK;
        }
        break;
      default:
        digitalWrite(watergate[b].pumpePin, !ein);
        watergate[b].step = GROWSTEP::CHECK;
        break;
    }
  }
}

Hallo devicious

Willkommen im besten Arduino Forum der Welt :slight_smile:

Es fehlt eine Überwachung des Wassertanks, damit die Pumpen nicht trocken laufen.

Zum Ausprobieren:

Code
#include <Arduino.h>
#include <Streaming.h>
Print& cout {Serial};

using uint = unsigned int;
using ulong = unsigned long;

//////////////////////////////////////////////////
// Global constants
//////////////////////////////////////////////////
namespace gc {
constexpr ulong mainDelay_ms {30000};
constexpr bool isOutPinInverted {false};   // if true then LOW is on and HIGH is off, elsewhere choose "false"
}   // namespace gc

//////////////////////////////////////////////////
// Class and structure definitions
//////////////////////////////////////////////////
class Timer {
public:
  void start() { timeStamp = millis(); }
  bool operator()(const ulong duration) const { return (millis() - timeStamp >= duration) ? true : false; }

private:
  ulong timeStamp {0};
};

namespace MoistureMeter {

class Interface {
public:
  Interface() = default;
  virtual ~Interface() {}
  Interface(const Interface&) = delete;              // prevent copy
  Interface& operator=(const Interface&) = delete;   // prevent assignment

  virtual void begin(bool) = 0;
  virtual uint run() = 0;
  virtual void setThreshold(const uint) = 0;
  virtual void unLock() = 0;
  virtual uint getThreshold() const = 0;
  virtual uint getMinVal() const = 0;
  virtual uint getMaxVal() const = 0;
  virtual uint getAnalogVal() const = 0;
  virtual byte getDeviceId() const = 0;
  virtual bool isActive() const = 0;
  virtual operator bool() const = 0;
  virtual bool operator()() const = 0;
};

template <byte deviceId, byte analogPin, uint minVal, uint maxVal, uint thVal, byte switchPin, ulong delay_ms>
class Device : public Interface {
  static_assert(analogPin >= A0 && analogPin <= A7, "No usable analog analogPin.");
  static_assert(maxVal > minVal, "The upper limit value must be greater than the lower limit value.");
  static_assert(thVal >= minVal && thVal <= maxVal,
                "The threshold value must be between the minimum and maximum value.");

public:
  explicit Device() : threshold {thVal} {};
  ~Device() {}
  Device(const Device&) = delete;              // prevent copy
  Device& operator=(const Device&) = delete;   // prevent assignment

  virtual void begin(bool isInverted = false) {
    on = (byte)!isInverted;
    off = !on;
    digitalWrite(switchPin, off);
    pinMode(switchPin, OUTPUT);
  }

  virtual uint run() override {
    mValue = analogRead(analogPin);
    if (!locked) {
      byte state = digitalRead(switchPin);
      (state == off && mValue <= threshold) && switchOn();
      (state == on && timer(delay_ms)) && switchOff();
    }
    return mValue;
  }

  virtual void setThreshold(const uint threshold) override {
    if (threshold >= minVal && threshold <= maxVal) { this->threshold = threshold; }
  }
  virtual void unLock() { locked = false; }   // Enable switchPins for switching again
  virtual uint getThreshold() const override { return threshold; }
  virtual uint getMinVal() const override { return minVal; }
  virtual uint getMaxVal() const override { return maxVal; }
  virtual uint getAnalogVal() const override { return mValue; }
  virtual byte getDeviceId() const override { return deviceId; }
  virtual bool isActive() const override { return digitalRead(switchPin) ^ (on == LOW); }   // XOR!!
  virtual operator bool() const override { return mValue >= threshold; }
  virtual bool operator()() const override { return operator bool(); }
  bool switchOn();
  bool switchOff();

private:
  uint threshold;
  uint mValue {0};
  Timer timer;
  byte on {HIGH};
  byte off {LOW};
  bool locked {false};
};

template <byte deviceId, byte analogPin, uint minVal, uint maxVal, uint thVal, byte switchPin, ulong delay_ms>
bool Device<deviceId, analogPin, minVal, maxVal, thVal, switchPin, delay_ms>::switchOn() {
  timer.start();
  cout << F("Device ") << deviceId << F(": Switch on watering for ") << delay_ms << F(" ms on pin nr. ") << switchPin
       << "\n";
  digitalWrite(switchPin, on);
  return on;
}

template <byte deviceId, byte analogPin, uint minVal, uint maxVal, uint thVal, byte switchPin, ulong delay_ms>
bool Device<deviceId, analogPin, minVal, maxVal, thVal, switchPin, delay_ms>::switchOff() {
  cout << F("Device ") << deviceId << F(": Switch off watering.\n");
  digitalWrite(switchPin, off);
  locked = true;   // Lock so that the pin does not become active again immediately, even if the soil is still
                   // considered too dry. Unlocking with the unLock() method.
  return off;
}
}   // namespace MoistureMeter

// Helper structure for flow control
struct ProcessFlow {
  const size_t maxIndex;   // Number of soil moisture meters
  uint deviceIndex;        // Index to the device currently being controlled
  uint activityFlags;      // A flag bit indicates whether a switchPin is active for the respective device.
};

//////////////////////////////////////////////////
// Global variables
//////////////////////////////////////////////////

// DeviceNr, Analogpin, Min-MeasureValue, Max-MeasureValue, Threshold(wet/dry), Solenoid Pin, Switching time in ms
MoistureMeter::Interface* mMeters[] {
    new MoistureMeter::Device<1, A0, 400, 800, 550, 3, 2000> {},
    new MoistureMeter::Device<2, A1, 400, 600, 475, 4, 3000> {},
    new MoistureMeter::Device<3, A2, 400, 800, 650, 5, 1500> {},
};

namespace MoistureMeter {
constexpr size_t devices {sizeof(mMeters) / sizeof(mMeters[0])};
constexpr size_t maxIndex {devices - 1};
}   // namespace MoistureMeter

Timer mainTimer;
ProcessFlow processFlow {MoistureMeter::maxIndex, 0, 0};

//////////////////////////////////////////////////
// Functions
//////////////////////////////////////////////////

template <size_t N> void printValues(MoistureMeter::Interface* (&devices)[N]) {
  for (auto& device : devices) {
    cout << F("Device ") << device->getDeviceId() << F(": Analog value: ") << device->getAnalogVal()
         << F(" Threshold: ") << device->getThreshold() << F(" -> Soil ");
    ((*device)() == true) ? cout << F("moisture sufficient") : cout << F("too dry!");
    cout << "\n";
  }
}

template <size_t N> bool checkSoilMoisture(MoistureMeter::Interface* (&devices)[N], ProcessFlow& pcf) {
  if (pcf.deviceIndex > pcf.maxIndex) {
    pcf.deviceIndex = 0;
    return true;   // All moisture meters have been checked.
  }
  devices[pcf.deviceIndex]->run();
  bool isActive = devices[pcf.deviceIndex]->isActive();
  isActive&& bitSet(pcf.activityFlags, pcf.deviceIndex);   // Set a flag for the respective device if a pin is active.
  !isActive&& bitClear(pcf.activityFlags,
                       pcf.deviceIndex);   // Delete the flag bit again when the pin has been set to inactive again.
  ++pcf.deviceIndex;
  return false;
}

template <size_t N> void unlockSwitchPins(MoistureMeter::Interface* (&devices)[N]) {
  for (auto& device : devices) { device->unLock(); }
}

void setup() {
  Serial.begin(115200);
  cout << F("Start...\n");
  for (auto& mMeter : mMeters) { mMeter->begin(gc::isOutPinInverted); }
}

void loop() {
  static bool mustDoCheck {true};
  switch (mustDoCheck) {
    case true:
      if (checkSoilMoisture(mMeters, processFlow) && !processFlow.activityFlags) {
        mainTimer.start();
        printValues(mMeters);        // Just print data
        cout << F("\nWaiting for the next soil moisture meter test...\n");
        unlockSwitchPins(mMeters);   // Unlock so that the switch pins can be switched again during the next test
        mustDoCheck = false;
      }
      break;
    case false:
      if (mainTimer(gc::mainDelay_ms)) { mustDoCheck = true; }   // Waiting for Godot
      break;
  }
}

Am Simulator:

Einfach die Werte an den Potentiometern verstellen (Sind die Bodenfeuchtemesser).

thank you.

Struct is the thing i'd need but its a bit hard for me to understand how i can program it

the delay was just so i can read the output in the monitor better

ich bin die überwachung des Tanks :grinning_face_with_smiling_eyes:

1 Like

So Senores i Senoritas,

ich habe den Code noch einmal überarbeitet und versucht mit einem Struct zu vereinfachen, einfach der Schönheit und Freude wegen.

Ich komme nun aber auf ein Problem, welches ich gerade nicht gelöst bekomme. Vieles habe ich mir schon erklären können, aber das leider nicht.

#include <string.h>
#include <stdio.h>

const int TROCKEN = 600;
const int FEUCHT = 475;
const int Anzahl_Kreise = 6;

unsigned long testintervall = 1000;
unsigned long pumpdauer = 3000;
unsigned long pausedauer = 30000;

struct Giesskreis {
  byte SensorPin;
  byte PumpePin;
  int Sensorwert;
  unsigned long lastcheck;
}  ; 

void setup() {

Serial.begin(38400);
Serial.println("LetsGrow");

  for (byte i=0; i < Anzahl_Kreise; i++) 
  {
    Giesskreis Kreis [Anzahl_Kreise];
    Kreis[i] = { i + 14, i + 2, 0, 0};     
    pinMode(Kreis[i].PumpePin, OUTPUT);
    Kreis[i].Sensorwert = analogRead(Kreis[i].SensorPin);

    Serial.print("Sensor[i]: ");
    Serial.print(Kreis[i].Sensorwert);
    Serial.print("/// Input Pin: ");
    Serial.print(Kreis[i].SensorPin);
    Serial.print("/// Output Pin: ");
    Serial.println(Kreis[i].PumpePin);
  }
}

void loop() {


  unsigned long Programmzeit = millis();

          for (byte i=0; i < 6; i++) {
                                                              //if (Programmzeit - Kreis[i].lastcheck > testintervall)  //Arbeit mit Testintervall //Sinnvoll, Nötig?
              {
                Kreis[i].Sensorwert = analogRead(Kreis[i].SensorPin); //Sensor auslesen
                Serial.print("Sensor 1: ");
                Serial.println(Kreis[i].Sensorwert);  //Wert ausgeben

                if (Kreis[i].Sensorwert < TROCKEN) {
                  if (Programmzeit > (Kreis[i].lastcheck + pausedauer)) {   //Pausedauer einhalten, um übergießen zu vermeiden
                    digitalWrite(Kreis[i].PumpePin, HIGH);  
                    Serial.println("Pumpe [i] an ");
                    Kreis[i].lastcheck = Programmzeit;  
                  }

                  if (Kreis[i].lastcheck + pumpdauer < Programmzeit) {
                    digitalWrite(Kreis[i].PumpePin, LOW);
                    Serial.println("Pumpe [i] aus");
                  }

                } else {
                  digitalWrite(Kreis[i].PumpePin, LOW);
                  Serial.println("Pumpe 1 aus");
                }
              }
            }
}
  


Ich habe die Struct duch eine for-Schleife im Setup erstellen lassen, allerdings kann ich in der Loop danach nicht mehr auf diese zugreifen. Der Fehler tritt das erste mal auf, wenn die Schleife bei

      for (byte i=0; i < 6; i++) {
                                                          //if (Programmzeit - Kreis[i].lastcheck > testintervall)  //Arbeit mit Testintervall //Sinnvoll, Nötig?
          {
            Kreis[i].Sensorwert = analogRead(Kreis[i].SensorPin); //Sensor auslesen
ankommt.

Muss ich die initialisierung des Structs wo anders machen? PLS HELP :joy:

Giessautomat_Struct\Giessautomat_Struct.ino: In function 'void loop()':
Giessautomat_Struct\Giessautomat_Struct.ino:50:17: error: 'Kreis' was not declared in this scope
Kreis[i].Sensorwert = analogRead(Kreis[i].SensorPin); //Sensor auslesen
^~~~~

exit status 1

Compilation error: 'Kreis' was not declared in this scope

Was hat Dir an meinem Code nicht gefallen, dass Du den jetzt nochmal schreibst?

Aber nun.

#include <string.h>
#include <stdio.h>

const int TROCKEN = 600;
const int FEUCHT = 475;
const int Anzahl_Kreise = 6;

unsigned long testintervall = 1000;
unsigned long pumpdauer = 3000;
unsigned long pausedauer = 30000;

struct Giesskreis
{
  byte SensorPin;
  byte PumpePin;
  int Sensorwert;
  unsigned long lastcheck;
};
Giesskreis Kreis [Anzahl_Kreise];

void setup()
{
  Serial.begin(38400);
  Serial.println("LetsGrow");
  for (byte i = 0; i < Anzahl_Kreise; i++)
  {
    Kreis[i] = { i + 14, i + 2, 0, 0};
    pinMode(Kreis[i].PumpePin, OUTPUT);
    Kreis[i].Sensorwert = analogRead(Kreis[i].SensorPin);
    Serial.print("Sensor[i]: ");
    Serial.print(Kreis[i].Sensorwert);
    Serial.print("/// Input Pin: ");
    Serial.print(Kreis[i].SensorPin);
    Serial.print("/// Output Pin: ");
    Serial.println(Kreis[i].PumpePin);
  }
}

void loop()
{
  unsigned long Programmzeit = millis();
  for (byte i = 0; i < 6; i++)
  {
    //if (Programmzeit - Kreis[i].lastcheck > testintervall)  //Arbeit mit Testintervall //Sinnvoll, Nötig?
    {
      Kreis[i].Sensorwert = analogRead(Kreis[i].SensorPin); //Sensor auslesen
      Serial.print("Sensor 1: ");
      Serial.println(Kreis[i].Sensorwert);  //Wert ausgeben
      if (Kreis[i].Sensorwert < TROCKEN)
      {
        if (Programmzeit > (Kreis[i].lastcheck + pausedauer))     //Pausedauer einhalten, um übergießen zu vermeiden
        {
          digitalWrite(Kreis[i].PumpePin, HIGH);
          Serial.println("Pumpe [i] an ");
          Kreis[i].lastcheck = Programmzeit;
        }
        if (Kreis[i].lastcheck + pumpdauer < Programmzeit)
        {
          digitalWrite(Kreis[i].PumpePin, LOW);
          Serial.println("Pumpe [i] aus");
        }
      }
      else
      {
        digitalWrite(Kreis[i].PumpePin, LOW);
        Serial.println("Pumpe 1 aus");
      }
    }
  }
}

Giesskreis ist nur in den Scope in dem es definiert wurde zugreifbar. Außerhalb der For-Loop existiert es nicht mehr. Da du die Giesskreise öfters verwenden willst, würde ich es global definieren.

Ich würde die Pins nicht berechnen. Falls du die Schaltung ändern musst, bricht dir alles.
Ich würde die Pins ausschreiben bei der Initialisierung des Arrays.

struct Giesskreis {
...
}; 

Giesskreis Kreis [Anzahl_Kreise] {
  {14, 2, 0,0},
  {15, 3, 0,0},
...
};

void setup() {
  for (byte i=0; i < Anzahl_Kreise; i++) 
  {
    pinMode(Kreis[i].PumpePin, OUTPUT);
...

Och menno... keine Statemachine mehr für die Pausenzeit?

Da würde ich nochmal einen Schritt zurück gehen und überlegen, was da passieren soll.

Magic value... wofür steht die 6?

Mit gefallen hat das nicht zu tun. Ich möchte einfach gerne lernen und muss dafür Dinge einfach nochmal selber durchmachen. Ich hab so wenig von dem Verstanden, was ihr gepostet habt.

ich weiß wirklich nicht, was das bedeuten soll. Was ist eine Statemachine?

in der Schleife möchte ich gerne dem Struct die Pins zuweisen. Ich versuche den Code gerade so sehr wie möglich zu komprimieren.

ich bin von 4 auf 6 sensoren hoch.
eigentlich muss ich da nur folgende Variable einsetzen:

Habs verstanden. Ich muss den Struct vor dem Setup definieren. Das ist die Lösung, danke.

Auf deutsch auch endlicher Automat genannt. Es geht darum, das du eine Aufgabe in kleine Zustände aufteilst. Damit kannst du dein Programm so schreiben, das es nicht blockiert. Dadurch ist es möglich mehrere Dinge quasi gleichzeitig zu machen.

In deinem Fall könnte der so aussehen:

Die Kringel sind die Zustände und die Pfeile Zustandswechsel. Um einen Pfeil abzulaufen muss eine Bedingung erfüllt sein. Zusätzlich kommt ein Wechsel auch mit einer Aktion die ausgeführt werden muss.

Ich bin ein Fan von Schleifen... aber bei der Definition der Pinkonfiguration halte ich das aber für Kontraproduktiv.

Nutze sie. Wenn du auf 7 Kreise updatest musst du nicht den Code abscannen und überall ändern, sondern nur an einer Stelle.

1 Like

Die Frage war, warum das struct nicht funktioniert.

Er will meinen Cide nicht.
Nicht einmal zum vergleichen.
Mehr noch, es werden die selben Fehler wieder gemacht.

Nu zeig ich nur wo die Definition hin gehört. Auch falsch.

Nicht mein Code.
Nicht die Frage.

Im Übrigen hast auch Du die entscheidenden Fehler drin gelassen.

Da hat du auch wieder Recht.

Ist halt schwer alle Änderungen zu finden nur vom draufschauen und nicht jeder hat ein Tool wie meld installiert.

Oh da mach ich es mir einfach und klau bei dir...

Aber was hast du gesehen?

Und jetzt Frage ich mich, ob Du evtl. genauso resigniert hast ob der Gleichgültigkeit....

Du führst ein Refactoring durch und hast 5 Punkte auf deiner Liste.

Bei Punkt 1 hängst du fest. Machst du dann erst die anderen Punkte als Trockenübung bevor du dir Hilfe holst oder fragst du das Forum genau da wo du gerade stehst?

Ich denke du verwechselt Geduld mit Gleichgültigkeit.

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