Debug mit Taster aktivieren

Hi,

Ich wollte für ein Programm einen Debugger haben, wo der Arduino bzw. NodeMCU prüft ob beim Starten ein Taster gedrückt ist und dann der das Debugg Programm startet

so hab ich das versucht

boolean Taster = true;

#ifdef Taster == true
#define DEBUG_PRINT(x) Serial.print(x)
#define DEBUG_PRINTLN(x) Serial.println(x)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTLN(x)
#endif

#ifdef macht was anderes als du wohl denkst.

Insbesondere reagiert es nicht auf Variablendefinitionen, sondern auf Präprozessor #define

Wenn du den Debug-Modus per Taster nach Reset umschalten willst, was eine gute Idee ist, kannst du das in setup() machen. Aber mit ganz normaler Programmierung
if (digitalRead(pin))

#ifdef Taster == true

Da bist du auf einem falschen Dampfer!
Denn #define wird zur Kompilezeit ausgewertet.

Wenn zur Laufzeit, dann musst du das wohl anders angehen.

Hier ein Fragment aus meiner Wühlkiste:
(vielleicht kannst da ja was mit anfangen...)

class Debug: public Print
{
  private:
   Print *printer;

  public:
   Debug(Print *printer=nullptr):printer(printer){}
   
   void setPrinter(Print *printer=nullptr)
   {
    this->printer=printer;
   }
   
   virtual size_t write(uint8_t value)
   {
     if(printer) return printer->write(value);
     return 1;
   }
};

Debug debug;
//Debug debug(&Serial);


void setup() 
{
  Serial.begin(9600);
  debug.println("Start1"); // evtl. nirvana


  debug.setPrinter(&Serial); 
  debug.println("Start2");  // zu sehen


  debug.setPrinter(nullptr); 
  debug.println("Start3"); // nirvana

  
}

void loop() 
{
}

Alle Kontrollstrukturen, die mit # anfangen werden vor der Kompilierung abgeabeitet und gelangen nicht in den übertragenen Kode. Der Kode kann verschieden sein wenn zB für den UNO oder DUE kompiliert wird. Das kann man mit #ifdef machen.

Wenn die Funktionalität des Kodes je nach Eingabesignal (Gedrückter oder nicht gedrückter Taster/Schalter) verschieden sein soll, dann mußt du das mit normalen if im Sketch machen. im Setup() liest Du den Eingang ein, setzt eine Statusvariable und führst im loop() einen oder den anderen Programmteil aus.

Grüße Uwe

letztes Jahr haben wir so etwas bereits diskutiert:

https://forum.arduino.cc/index.php?topic=575044.0

imho könntest du meinen Beitrag #10 gut reusen und beim auslesen des Taster im Setup entsprechend

Debug.setDebugLevel(0); oder Debug.setDebugLevel(1); setzen.

letztes Jahr haben wir so etwas bereits diskutiert:

Ja, daher die Wühlkistendebugklasse, die hier ich Beitrag #2 gezeigt habe, sie ist eine direkte Überarbeitung/Weiterentwicklung aus den Ansätzen des von dir verlinken Threads.

Der Glanzpunkt der Weiterentwicklung ist einfach nur die Settermethode.
Austauschen des Printers zu Laufzeit.
Ob per Knopfdruck, oder seriellem Kommando, ist dabei egal.

Durch den Setter kann das Debuggen jederzeit ein und ausgeschaltet werden.
Es kann jede Instanz als Ziel verwendet werden, welche Print implementiert.
Also auch z.B. Files auf SD Karten
Alle Serial Implementierungen, auch Software- und AltSerial
Selbst I2C
LC Displays
Über Funk
usw... halt alles was ein Print oder auch Stream ist.
(in meiner Wühlkiste schlummert noch eine EEPROM Erweiterung um dieses als Stream zu nutzen)

Hi

sorry für die späte Antwort komme gerade von einer Geschäftsreise.

Danke für die Aufklärung.

combie:

class Debug: public Print

{
  private:
  Print *printer;

public:
  Debug(Print *printer=nullptr):printer(printer){}
 
  void setPrinter(Print *printer=nullptr)
  {
    this->printer=printer;
  }
 
  virtual size_t write(uint8_t value)
  {
    if(printer) return printer->write(value);
    return 1;
  }
};

Debug debug;
//Debug debug(&Serial);

void setup()
{
  Serial.begin(9600);
  debug.println("Start1"); // evtl. nirvana

debug.setPrinter(&Serial);
  debug.println("Start2");  // zu sehen

debug.setPrinter(nullptr);
  debug.println("Start3"); // nirvana

}

void loop()
{
}

würdest du mir eventuell erklären was da passiert?

Mfg

würdest du mir eventuell erklären was da passiert?

Gerne!
Was möchtest du denn "konkret" wissen?

Allgemein:
Debug implementiert Print
Debug erbt so alle Print Methoden

Der Setter setPrinter() setzt den konkreten Printer.
Alternativ, setzt es den Printer auf nullptr, dann landen alle Ausgaben im Nirvana.

combie:
Gerne!
Was möchtest du denn "konkret" wissen?

ehrlich gesagt versteh ich da nichts. Hätte man eventuell erwähnen sollen dass ich Anfänger (zwar nicht ganz aber dein code sieht echt komplex aus deswegen bin ich es jetzt) bin.

class und public habe ich mal in Zusammenhang von eigenen Bibliotheken schreiben gelesen.

Wenns keine Umstände macht könntest du eventuell das ganze kommentieren.

ist nirvana ein Arduino begriff?

Danke für die hilfe
Mfg

was verstehst du nicht?

du kannst mit debug.setPrinter ein und ausschalten.
Und wie combie schon schrieb, theoretisch auch die Ausgaben woanders hin schicken.
Das ist aber aktuell nicht deine Anforderung.

Einschalten
Ausschalten

Beides geht mit Combies Variante:

 debug.setPrinter(&Serial); // --> das aktiviert die Serial Ausgabe
  debug.println("Start2");  // zu sehen  

  debug.setPrinter(nullptr); // --> das deaktiviert die Serial Ausgabe, schaltet sie aus, sorgt dafür, das nichts angezeigt wird ... es geht in das NIRVANA.
  debug.println("Start3"); // nirvana

Nirvana ist kein Arduino Begriff.
suche hier weiter

class und public habe ich mal in Zusammenhang von eigenen Bibliotheken schreiben gelesen.

Das ist die Objekt orientierte Programmierung.
Ich empfehle dir eins der schönen dicken, über 1000 Seitigen, C++ Bücher.
Achte darauf, dass darin C++17 abgehandelt wird.
Arduino ist jetzt auf C++11, aber C++17 ist mit der Arduino IDE 1.9.0-Beta aktivierbar/nutzbar.

evtl. findest du hier ja schon etwas Hintergrundwissen.

if(printer) return printer->write(value);

Hier wird abgefragt ob printer NULL ist oder nicht. Wenn es auf nullptr steht wird also nichts getan

Ich suche schon lange ein gutes C++ Buch oder Internetseite. Habt ihr eine Empfehlung für mich?

okay gut habs nicht getestet würde das dann so funktionieren?

void setup()
{
  Serial.begin(9600);
  debug.println("Start1"); // evtl. nirvana


  if (digitalRead(TASTER) == HIGH)
  {
    while (digitalRead(TASTER) == HIGH);

    debug.setPrinter(&Serial);
    debug.println("Start2");  // zu sehen

  }else{
  
  debug.setPrinter(nullptr);
  debug.println("Start3"); // nirvana
  }

}

nein wird so nicht funktionieren.

du musst die Klasse auch mit übernehmen!(!!!)

noch mal von ganz vorne.

Bring erst mal den Sketch von Combi (oder den von mir verlinkten auf),

funktioniert?
ja.
DANN erweiterst du was du brauchst.

noiasca:
Bring erst mal den Sketch von Combi (oder den von mir verlinkten auf),

hab ich.

noiasca:
DANN erweiterst du was du brauchst.

kann ich nicht wenn ich den Sketch nicht verstehe.

class Debug: public Print // Denke mal Debug wird definiert und Print ist öffentlich
{
  private: // nicht öffentlich
   Print *printer; // Keine Ahung Stern heißt zeiger weiß ich

  public:
   Debug(Print *printer=nullptr):printer(printer){} // Keine Ahnung
   
   void setPrinter(Print *printer=nullptr) // ebenfalls
   {
    this->printer=printer; // und nochmal
   }
   
   virtual size_t write(uint8_t value) // goto keine Ahnung. Sieht aber echt sehr interessant aus
   {
     if(printer) return printer->write(value); // wurde mir schon erklärt
     return 1; 
   }
};

Debug debug;
//Debug debug(&Serial);


void setup() 
{
  Serial.begin(9600);
  debug.println("Start1"); // evtl. nirvana


  debug.setPrinter(&Serial); 
  debug.println("Start2");  // zu sehen


  debug.setPrinter(nullptr); 
  debug.println("Start3"); // nirvana

  
}

void loop() 
{
}

habe jetzt im loop meinen anfangscode eingebunden. Läuft auch soweit würde aber dennoch gerne den Code von Combie verstehen

Mfg

Topsi:
..... würde aber dennoch gerne den Code von Combie verstehen

Nicht nur du. :confused:

class Debug: public Print // Denke mal Debug wird definiert und Print ist öffentlich

Ja!
Print ist eine vorgefertigte Klasse, welche auf deinem Rechner liegt.
Gehört zur Arduino Standardausstattung.
Debug erbt alles von Print

Print *printer; // Keine Ahung Stern heißt zeiger weiß ich

Die private Instanzeigenschaft printer wird definiert.
printer ist ein Zeiger auf eine Print Instanz

Debug(Print *printer=nullptr):printer(printer){} // Keine Ahnung

Ein Konstruktor mit Initialisierungsliste und default Parameter

void setPrinter(Print *printer=nullptr) // ebenfalls

Eine Setter Methode, mit default Parameter, um die Instanzeigenschaft printer zu setzen.

Wenn ich in Rente bin, kauf ich mir dann auch endlich das oft genannte 1000 Seiten Buch. Vielleicht komm ich dann sogar dazu, es zu lesen.

Habe ich mal wieder übertrieben?

Nö, finde ich nicht. Ein paar Kenntnisse muss man manches Mal voraussetzen. Wir hatten hier im Forum ja bereits einen langen Thread zu den Grundlagen der OOP. Den kann man ja dazu nutzen.

Gruß Tommy