Debug Ausgaben zur Laufzeit ein/ausschalten?

Ich habe einen Sketch bei dem ich die Serial produktiv sowie für Debug Ausgaben verwende.

Zunächst habe ich eine Reference auf die HardwareSerial gemacht

HardwareSerial & Debug = Serial;

und dann meine Debug Ausgaben mittels
Debug.print(F("D: Old size="));

definiert.

Vor dem Kompilieren kann ich die Debug Ausgaben mit Änderung der Reference auf die Serial1 verbiegen (ich bin am ESP)
HardwareSerial & Debug = Serial1;

Damit stören mich die Debug Ausgaben auf Serial nicht mehr. So weit so gut.

Nur wie könnte ich es schaffen die Reference so zu verbiegen, dass es zu keiner Ausgabe mehr kommt.
Jetzt musste ich lernen dass "A reference cannot be changed to refer to another object after initialization."
Schlecht für mich.

Welchen einfachen weg gäbe es Debug Ausgaben ein/auszuschalten ohne jede Ausgabe in ein if zu packen oder alle meine Debug.print in eine eigene Funktion packen zu müssen?
Evtl. eine eigene Klasse mit den zwei Methoden println und print die gegebenenfalls einfach nichts mit meinen Ausgaben machen? Oder geht das einfacher?

Aus meiner Wühlkiste, leicht für deine Anforderung umgebaut:

struct:Print{virtual size_t write(uint8_t){return 1;}}dummy;

Print *debug = &Serial;

void setup() 
{
  Serial.begin(9600);      
  Serial.println("Start");

  debug->println("Debug 1");

  debug = &dummy;
  debug->println("Debug 2");

  debug = &Serial;
  debug->println("Debug 3");
}

void loop() 
{
}

noiasca:
...in eine eigene Funktion packen...

Hallo,

Genau, Du packst diese debug Ausgaben in eine Funktion.

bool debug = true;
void setup() {
  Serial.begin(9600);
}
void dmsg(String msg) {
  if (debug) Serial.print(msg);
}
void dmsgln(String msg) {
  if (debug) Serial.println(msg);
}
void loop() {
  dmsgln(F("Das ist ein Test"));
  delay(250);
}

edit: Hab den Code kurz überarbeitet.
Also so ungefähr könnte das ausschauen.

Beste Grüße,
Donny

combie hättest du bitte noch kurz Zeit mir zu erklären was da wirklich passiert?

eine virtuelle Methode mit einem overload des write?

warum reicht die Definition eines write(uint8_t) und ich kann dann trotzdem alle andere Ausprägungen übergeben?

und kann ich etwas gegen dieses Warning machen:

C:\daten\Arduino\Forum\sketch_oct22a\sketch_oct22a.ino: In member function 'virtual size_t Dummy::write(uint8_t)':

C:\daten\Arduino\Forum\sketch_oct22a\sketch_oct22a.ino:4:33: warning: no return statement in function returning non-void [-Wreturn-type]

   virtual size_t write(uint8_t){}

schaut sonst schon sehr gut aus :wink:

struct Dummy: Print
{
  virtual size_t write(uint8_t) {}
};


Dummy dummy;

Print * debug = nullptr;

void setup()
{
  Serial.begin(9600);
  Serial.println("Start");

  debug = &Serial;
  debug->println("Debug 1 ist ein");

  debug = &dummy;
  debug->println("Debug 2 ist aus");

  debug = &Serial;
  debug->println("Debug 3 ist wieder ein");

  debug = &dummy;
  debug->println(F("Debug 4 ist aus"));

  debug = &Serial;
  debug->println(F("Debug 5 ist wieder ein"));

  float afloat = 123.45;
  debug->println(afloat);

  char achararray [] = {"bla bla\0"};
  debug->println(achararray);

  String anArduinoStringObject = "bla blub";
  debug->println(anArduinoStringObject);


}

void loop()
{

}

Schau dir an wie die Print Klasse funktioniert und wie andere Klasse von ihr erben (z.B. eine LCD Bibiliothek)

Jetzt musste ich lernen dass "A reference cannot be changed to refer to another object after initialization."

Klar. Das ist der Haupt-Unterschied zwischen Referenzen und Zeigern

noiasca:
aaah der combie returnt jetzt ...

Ja, war mir auch aufgefallen...
Habe wohl damals ohne aktivierte Warnings kompiliert.

Und jetzt auch eine anonyme Struktur verwendet.
Denn sie braucht keinen Namen.

Tipp (an mich selber):
Erst testen, dann posten.

warum reicht die Definition eines write(uint8_t)

Das reicht um das Print Interface zu implementieren.
Write braucht keinen benannten Parameter, weil der Wert sowieso nicht genutzt wird.
Er darf also auch anonym bleiben.
Wäre er benannt, würde es ein "unused Variable" Warning geben, den man auf anderem Wege unterdrücken oder eben erdulden müsste.

Danke.
Karma verteilt
(auch an Donny für den guten Willen, aber Funktion wollte ich eigentlich nicht und dass man in ein char nicht einen ganzen Text reinbekommt fällt dir sicher auch auf ...).

noiasca:
Danke.
Karma verteilt

Schön, dass es dir gefällt!

Und Karmas nehme ich auch gerne...
Ist es doch ein Zeichen dafür, dass ich nicht nur verbohrt und böse bin.
Meinen Dank dafür!

noiasca:
Danke.
Karma verteilt
(auch an Donny für den guten Willen, aber Funktion wollte ich eigentlich nicht und dass man in ein char nicht einen ganzen Text reinbekommt fällt dir sicher auch auf ...).

Danke, eine Art Willkommensgeschenk, da ich seit langer Zeit nicht mehr Online war. Es wird wieder Zeit hier öfters mal vorbeizuschauen. :slight_smile:

Ja, char ist hier die falsche Wahl.

Grüße,
Donny

noch mal einen Schritte zurück gegangen:

Wenn ich auf die Referenz verzichte und mich auf Serial fixiere, dann bleibt eigentlich nur mehr eine Klasse über und ich bräuchte meine bestehenden prints nicht angreifen.

so viele Möglichkeiten und so wenig Ahnung, ein Drama...

class debugPrint : public Print {
    uint8_t _debugLevel = 1;

  public:
    void setDebugLevel(byte newLevel) {
      _debugLevel = newLevel;
    }

    size_t write (uint8_t value)
    {
      if (_debugLevel)
      {
        Serial.write(value);
      }
      return 1;
    }
} Debug;


void setup() {
  Serial.begin(115200);
  Serial.println(F("Debug Print Test"));

  Debug.println("Debug 1 ist ein");

  Debug.setDebugLevel(0);
  Debug.println("Debug 2 ist aus");

  Debug.setDebugLevel(1);
  Debug.println("Debug 3 ist wieder ein");

  Debug.setDebugLevel(0);
  Debug.println(F("Debug 4 ist aus"));

  Debug.setDebugLevel(1);
  Debug.println(F("Debug 5 ist wieder ein"));

  float afloat = 123.45;
  Debug.println(afloat);

  char achararray [] = {"bla bla\0"};
  Debug.println(achararray);

  String anArduinoStringObject = "bla blub";
  Debug.println(anArduinoStringObject);

}

void loop() {
  // put your main code here, to run repeatedly:

}

Auch eine interessante Variante!

:grin:

Auch eine interessante Variante!

Ja.
Ob man mehr Level außer 0 und 1 braucht, sei mal so stehengelassen.
Auch reicht es oft, den Level nur einmal (z.B. in setup) zu setzen. Hauptsache, nicht mehrfach kompilieren und hochladen, finde ich.

Ist allerdings schade, dass hier Debug so eng mit Serial verkuppelt ist.

Meine Idee dazu:

void setup() {
  pinMode(7, INPUT_PULLUP);
  if ( digitalRead(7) == LOW ) Debug.begin (Serial, 9600);  // Debug Modus: Taster beim Reset gedrückt
  ...
}

Ungetestet, und vermutlich nicht mal zu Ende gedacht