Schleife

Hallo zusammen,

ich bin seit kurzem dabei mit dem Arduino (MEGA) bestimmte Sensoren auszuwerten.

Nun bin ich dabei ein Interface für den Nutzer zu gestalten alles soweit gut, bis auf dass folgende Problem.

Es gibt ein Untermenü "XY" hier sollen von einem GYRO, Beschleunigungsmesser die Messwerte in Echtzeit angezeigt werden.
Wenn ich die folgenden Programmzeilen in den loop() {} packe funktioniert es einwandfrei, jedoch soll dies nun unter einem Menüpunkt gesetzt werden. So dass der Benutzer diesen auswählen kann und erst dann die Daten angezeigt werden.

Mein Problem:
Die Werte werden einmalig zu dem Zeitpunkt angezeigt in dem ich diesen Menüpunkt auswähle danach bleiben diese Daten. --> Also eine Schleife die solange durchlaufen soll bis ich die Taste "X" betätige, dies habe ich mit einer do …. while - Schleife versucht jedoch erfolglos, die Daten bleiben die selben.

Wenn ich dies mit einer for - Schleife schreibe funktioniert es aber auch nur solange bis der Zähler eben eine vorher bestimmten Wert einnimmt.

Ich hänge hier mal den CODE mit an.

Ich hoffe Ihr könnt mir helfen.
LG ghahn11

    do {
          u8x8.clear();
    IMU.readSensor();
    u8x8.print(IMU.getAccelX_mss(), 1);
    u8x8.print("\t");
    u8x8.print(IMU.getAccelY_mss(), 1);
    u8x8.print("\t");
    u8x8.print(IMU.getAccelZ_mss(), 1);
    u8x8.println("\n");
    u8x8.print(IMU.getGyroX_rads(), 1);
    u8x8.print("\t");
    u8x8.print(IMU.getGyroY_rads(), 1);
    u8x8.print("\t");
    u8x8.print(IMU.getGyroZ_rads(), 1);
    u8x8.println("\n");
    u8x8.print(IMU.getMagX_uT(), 1);
    u8x8.print("\t");
    u8x8.print(IMU.getMagY_uT(), 1);
    u8x8.print("\t");
    u8x8.print(IMU.getMagZ_uT(), 1);
    u8x8.println("\n");
    u8x8.println(IMU.getTemperature_C(), 3);
    delay(200);
   } while (!digitalRead(zuruck));

Bitte den gesamten Sketch
Uwe

Wenn ich fragen darf weshalb den gesamten Code ?

ghahn11:
Wenn ich fragen darf weshalb den gesamten Code ?

Meist zeigen Leute (also evtl. auch du) den Code, den sie schon 1000 mal geprüft haben.
Und der Code, wo sie noch nicht intensiv hingeschaut haben, wird vor uns geheim gehalten.
Aber genau da steckt der Fehler. Oft.
Der Fehler steckt dort, wo du ihn nicht vermutest.
Denn wenn er nicht dort wäre, dann hättest du ihn doch schon gefunden.
Oder?
Zeigst aber die Stelle, wo du ihn vermutest.

Merksatz:
Der Fehler ist IMMER dort, wo man ihn zuletzt sucht.

Hier:
Da while Schleifen perfekt funktionieren, immer, hast du ein Problem mit der Taste, oder ähnlich.
Aber die funktionierende For Schleife muss ja geheim bleiben, genauso wie die Tasteninitialisierung/Schaltplan.

Also ....

Weil 20 Zeilen aus dem Kontext (Sketch) gerissen gleichgut völlig richtig wie grottenfalsch im Bezug zum restlichen Sketch sein können.
Bist Du 100% sicher daß die Schleife mehr als einmal durchlaufen wird?
Ah, einen Schaltplan bräuchten wir auch. Zum Schluß fehlt nur der Pullupwiderstand.
Grüße Uwe

Ich bin gegen den "gesamten Code"

Ich bevorzuge stattdessen "Kompletten Code, der das Problem zeigt, aber gern ohne alles Unnötige"

Das ist zwar für dich mehr Arbeit, hilft dir selbst aber enorm, wenn du beim Versuch, ein minimales Fehlerbeispiel zusammenzustellen, merkst, dass der Fehler gar nicht da ist, wo du ihn vermutest.

michael_x:
Ich bevorzuge stattdessen "Kompletten Code, der das Problem zeigt, aber gern ohne alles Unnötige"

Das ist zwar für dich mehr Arbeit, hilft dir selbst aber enorm, wenn du beim Versuch, ein minimales Fehlerbeispiel zusammenzustellen, merkst, dass der Fehler gar nicht da ist, wo du ihn vermutest.

Dem kann ich in allen Punkten, voll und ganz, zustimmen.

Hallo,

noch ein Tipp:
Warum baust du nicht einfach ein paar serial.print() in Deinen Code ein damit Du den Fehler leichter finden kannst.

ghahn11:
Ich hoffe Ihr könnt mir helfen.

Nein, da du ja die notwendigen Informationen verweigerst.

Ich setze mal eine abgewandelte Version davon rein, wo der selbe Fehler wieder entsteht.

#include "MPU9250.h"
MPU9250 IMU(Wire, 0x68);
int status;
#include <U8g2lib.h>
#include <U8x8lib.h>
#include <Arduino.h>
#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE);
#define U8LOG_WIDTH 16
#define U8LOG_HEIGHT 8
uint8_t u8log_buffer[U8LOG_WIDTH * U8LOG_HEIGHT];
U8X8LOG u8x8log;

int hoch = 4;
int runter = 5;
int ok = 6;
int zuruck = 7;
int i=0;

int zustand = 1;


void setup()
{
  Serial.begin(9600);
  while (!Serial) {}

  status = IMU.begin();
  if (status < 0) 
  {
    Serial.println("IMU Initialisierung fehlgeschlagen");
    Serial.println("Verkabelung prüfen ggf. Neustarten");
    Serial.print("Status: ");
    Serial.println(status);
    while (1) {}
  }
    IMU.setAccelRange(MPU9250::ACCEL_RANGE_2G);
    IMU.setGyroRange(MPU9250::GYRO_RANGE_500DPS);
    IMU.setDlpfBandwidth(MPU9250::DLPF_BANDWIDTH_20HZ);
    IMU.setSrd(19);
    IMU.calibrateGyro();

    u8x8.begin();
    u8x8.setFont(u8x8_font_chroma48medium8_r);
    u8x8log.begin(u8x8, U8LOG_WIDTH, U8LOG_HEIGHT, u8log_buffer);
    u8x8log.setRedrawMode(1);

    pinMode(hoch, INPUT_PULLUP);
    pinMode(runter, INPUT_PULLUP);
    pinMode(ok, INPUT_PULLUP);
    pinMode(zuruck, INPUT_PULLUP);
    updateMenu(); 
}

   void gyro()
    {
      do {
        u8x8.clear();
        IMU.readSensor();
        u8x8.print(IMU.getAccelX_mss(), 1);
        u8x8.print("\t");
        u8x8.print(IMU.getAccelY_mss(), 1);
        u8x8.print("\t");
        u8x8.print(IMU.getAccelZ_mss(), 1);
        u8x8.println("\n");
        u8x8.print(IMU.getGyroX_rads(), 1);
        u8x8.print("\t");
        u8x8.print(IMU.getGyroY_rads(), 1);
        u8x8.print("\t");
        u8x8.print(IMU.getGyroZ_rads(), 1);
        u8x8.println("\n");
        u8x8.print(IMU.getMagX_uT(), 1);
        u8x8.print("\t");
        u8x8.print(IMU.getMagY_uT(), 1);
        u8x8.print("\t");
        u8x8.print(IMU.getMagZ_uT(), 1);
        u8x8.println("\n");
        u8x8.println(IMU.getTemperature_C(), 3);
        delay(200);
      } while (!digitalRead(zuruck));    
    }

    void action5()//GYRO-Set
      {
        gyro();
      }

      
     void execute()
    {
      switch (zustand)
      {
        case 1:
         // action1();
          break;

        case 2:
          //action2();
          break;

        case 3:
          //action3();
          break;

        case 4:
          //action4();
          break;
        case 5:
          action5();
          break;
      }
    }
    
  void loop()
  {
    if (!digitalRead(runter))
    {
      zustand++;
      updateMenu();
      delay(10);
      while (!digitalRead(runter));
    }

    if (!digitalRead(hoch))
    {
      zustand--;
      updateMenu();
      delay(10);
      while (!digitalRead(hoch));
    }

    if (!digitalRead(ok))
    {
      execute();
      delay(10);
      while (!digitalRead(ok));
    }

    if (!digitalRead(zuruck))
    {
      u8x8.clear();
      updateMenu();
      delay(10);
      while (!digitalRead(zuruck));
    }

  }

  void updateMenu()
  {
    switch (zustand)
    {
      case 0:
        zustand = 1;
        break;
      case 1:
        u8x8.clear();
        u8x8.print(">1");
        u8x8.setCursor(0, 1);
        u8x8.print("2");
        u8x8.setCursor(0, 2);
        u8x8.print("3");
        u8x8.setCursor(0, 3);
        u8x8.print("4");
        u8x8.setCursor(0, 4);
        u8x8.print("5");
        break;
      case 2:
        u8x8.clear();
        u8x8.print("1");
        u8x8.setCursor(0, 1);
        u8x8.print(">2");
        u8x8.setCursor(0, 2);
        u8x8.print("3");
        u8x8.setCursor(0, 3);
        u8x8.print("4");
        u8x8.setCursor(0, 4);
        u8x8.print("5");
        break;
      case 3:
        u8x8.clear();
        u8x8.print("1");
        u8x8.setCursor(0, 1);
        u8x8.print("2");
        u8x8.setCursor(0, 2);
        u8x8.print(">3");
        u8x8.setCursor(0, 3);
        u8x8.print("4");
        u8x8.setCursor(0, 4);
        u8x8.print("5");
        break;
      case 4:
        u8x8.clear();
        u8x8.print("1");
        u8x8.setCursor(0, 1);
        u8x8.print("2");
        u8x8.setCursor(0, 2);
        u8x8.print("3");
        u8x8.setCursor(0, 3);
        u8x8.print(">4");
        u8x8.setCursor(0, 4);
        u8x8.print("5");
        break;
      case 5:
        u8x8.clear();
        u8x8.print("1");
        u8x8.setCursor(0, 1);
        u8x8.print("2");
        u8x8.setCursor(0, 2);
        u8x8.print("3");
        u8x8.setCursor(0, 3);
        u8x8.print("4");
        u8x8.setCursor(0, 4);
        u8x8.print(">5");
        break;
      case 6:
        zustand = 4;
        break;
    }
  }

Halo,

ich kann das leider nicht laufen lassen , Harware fehlt mir.

ich vermute du kommst aus der aus der function schon raus , aber gleich wieder rein weil zustand immer noch 5 ist und nicht geändert wurde.

Bau dir sein serial.print hinter die Abbruchbedingung und setze "zustand" auf einen anderen wert.

Heinz

Hallo,

habs eingekürzt, jetzt schaust du erstmal zu wie das Programm auf deine Tastendrücke reagiert.

Was macht i ?

Globale zustand Variable für mehrere switch case ist gefährlich. Sollte hier auch unsigned sein, meistens reicht byte.
case default ist hier auch wichtig, weil dein zustandszähler wild geändert wird per Tastendruck.
Wenn der ins negative zählt bzw. außerhalb deiner case Nummern ist, kann dein Programm nichts machen bzw. wird nicht sauber ausgeführt. Könntest über eine Zählumfangsbegrenzung nachdenken.

const byte hoch = 4;
const byte runter = 5;
const byte ok = 6;
const byte zuruck = 7;
int i = 0;

int zustand = 1;


void setup()
{
  Serial.begin(9600);

  pinMode(hoch, INPUT_PULLUP);
  pinMode(runter, INPUT_PULLUP);
  pinMode(ok, INPUT_PULLUP);
  pinMode(zuruck, INPUT_PULLUP);
  updateMenu();
}



void loop()
{
  if (!digitalRead(runter))
  {
    zustand++;
    updateMenu();
    delay(10);
    while (!digitalRead(runter));
  }

  if (!digitalRead(hoch))
  {
    zustand--;
    updateMenu();
    delay(10);
    while (!digitalRead(hoch));
  }

  if (!digitalRead(ok))
  {
    execute();
    delay(10);
    while (!digitalRead(ok));
  }

  if (!digitalRead(zuruck))
  {
    updateMenu();
    delay(10);
    while (!digitalRead(zuruck));
  }

}

void updateMenu()
{
  Serial.print("Menu zustand: "); 
  Serial.print(zustand);
  switch (zustand)
  {
    case 0:
      Serial.print(" im case: "); Serial.println(zustand);
      zustand = 1;
      break;
    case 1:
      Serial.print(" im case: "); Serial.println(zustand);
      break;
    case 2:
      Serial.print(" im case: "); Serial.println(zustand);
      break;
    case 3:
      Serial.print(" im case: "); Serial.println(zustand);
      break;
    case 4:
      Serial.print(" im case: "); Serial.println(zustand);
      break;
    case 5:
      Serial.print(" im case: "); Serial.println(zustand);
      break;
    case 6:
      Serial.print(" im case: "); Serial.println(zustand);
      zustand = 4;
      break;
    default: Serial.println(" Menu default");
             break;
  }
}

void gyro()
{
  do {
    Serial.println("bin in gyro() Funktion");
    delay(200);
  } while (!digitalRead(zuruck));
}

void action5()  //GYRO-Set
{
  gyro();
}


void execute()
{
  Serial.print("execute zustand: ");
  Serial.print(zustand);
  switch (zustand)
  {
    case 1:
      Serial.print(" im case: "); Serial.println(zustand);
      // action1();
      break;

    case 2:
      Serial.print(" im case: "); Serial.println(zustand);
      //action2();
      break;

    case 3:
      Serial.print(" im case: "); Serial.println(zustand);
      //action3();
      break;

    case 4:
      Serial.print(" im case: "); Serial.println(zustand);
      //action4();
      break;
    case 5:
      Serial.print(" im case: "); Serial.println(zustand);
      action5();
      break;
    default: Serial.println(" execute default");
             break;
  }
}

@Doc_Arduino

Das "i=0" war für die for-Schleife.

Für den Zustandszähler wird eine Abbruchbedingung eingesetzt, so dass wenn er über 5 geht auf 1 gesetzt wird.
Danke für die Idee.

Aber leider funktioniert die do-while-Schleife immer noch nicht.

LG

ghahn11:
Also eine Schleife die solange durchlaufen soll bis ich die Taste "X" betätige, dies habe ich mit einer do …. while - Schleife versucht jedoch erfolglos, die Daten bleiben die selben.

Zum Einen: gewöhne dir bitte von Anfang an an, deine Programme vernünftig zu kommentieren. Ich finde es - gelinde gesagt - eine Zumutung, uns hier vollkommen unkommentierten Code vorzusetzen, durch den wir uns durchbeissen sollen. Insbesondere, da durch den fehlenden Kommentar nicht klar, ist was passieren SOLL. So kann man dann auch nicht feststellen, ob der Code das tut, was er tun soll.
Außerdem wirst Du dich selbst über jeden Kommentar freuen, wenn Du dir dein eigenes Programm nach längerer Zeit mal wieder vornimmst.

Zum Anderen: Da Du die Tasterinputs mit INPUT_PULLUP initiierst, gehe ich davon aus, dass deine Taster LOW-aktiv sind. D.h. im Ruhezustand ist der Input HIGH. Wenn Du dann in deiner while-Schleife auf LOW abfragst:

      } while (!digitalRead(zuruck));

bedeutet dass, das die Schleife sofort beendet wird, denn bei nicht gedrücktem Taster ist dieser Ausdruck false. Wenn ich dich richtig verstehe, willst Du aber, dass die Schleife läuft bis der Taster gedrückt wird. Der Ausdruck muss als 'true' sein, wenn der Taster nicht gedrückt ist:

      } while (digitalRead(zuruck));

P.S. ein gutes Programmkonzept ist das m.M. nach nicht. Während der Anzeige kann ringsrum die Welt zusammenbrechen - der Arduino merkt es nicht, denn er kann auf nichts anderes reagieren, als auf deinen 'zuruck' Taster.

ghahn11:
Aber leider funktioniert die do-while-Schleife immer noch nicht.

Hallo,

mein Ziel war es nicht deinen Sketch zu reparieren. Im dem Zustand ist das schlecht möglich. Mein Ziel war es dir Debugausgaben in die Hand zugeben damit DU siehst was dein Sketch macht und eben nicht macht. Die Schlussfolgerungen daraus solltest du dann ziehen.