Dummy-Frage: Ersetzen von "Serial.xxx" durch Ausgabe in anderen Kanal

Hat nicht direkt mit Arduino zu tun, aber ist für mich ein richtig großer Brocken ... auch wenn andere das wahrscheinlich mit links progammieren könnten.

Idee:
Alle Ausgaben, die ich bis jetzt über "Serial.print" bzw. "Serial.println" gemacht habe sollen auf einen beliebeigen Zeichenorientierten Ausgabekanal umgeleitet werden. Wenn möglich, ohne den restlichen Code anfassen zu müssen.
Ebenso sollten auch die entsprechenden Eingaberoutinen umgeleitet werden.

Konkret soll das per udp und wlan passieren.

Wie muss ich die entsprechenden Routinen definieren, damit die Parameterübergabe funktioniert?

Für solche Probleme bin ich einfach nicht mehr flexibel genug :frowning:

Kann mir jemand helfen?

Keine Ahnung was du meinst.

Ich kann dir nur sagen, dass Arduino das Print und auch das Printable Interface anbietet, welches du in eigenen Anwendungen nutzen/integrieren kannst.
Und sowieso schon vielfältig eingesetzt wird.
Auch für Netzverkehr

Auch könnte das Streaming eine Erleichterung sein.

sollen auf einen beliebeigen Zeichenorientierten Ausgabekanal umgeleitet

Implementiere/Nutze das Stream Interface.
? ! ?

Keine Ahnung was du meinst.

Alles was von Stream abgeleitet ist, kann println() und print() mit allen Typ-Umwandlungen.

Im primitivsten Fall kannst du wahlweise

#define DebugStream Serial

ersetzen durch

#define DebugStream Serial1

Dann geht
DebugStream.println(var); an die jeweilige Schnittstelle

(Die eigentliche Aufgabe wäre dann, etwas zu bauen, das gar nichts macht.)

Statt #define kann man auch selbst Klassen ableiten. Das wäre dann C++ statt C.

Frage ist auch, reicht ein NeuÜbersetzen+Hochladen zum Ändern oder soll das beim Reset geändert werden können. Oder gar im laufenden Betrieb?

(deleted)

Du könntest einen Referenz auf deine Serial machen.

HardwareSerial & Output= Serial;

dann jedes Serial.print / Serial.println auf Output.print/Output.println ändern.

zu diesem Zeitpunkt funktioniert noch alles wie gehabt.

Dann schreibst dir eine Klasse die analog HardwareSerial von print erbt und tauscht halt dann oben in der Referenz Klasse und Objekt-Name aus. Der restliche Code brauchst nicht mehr angreifen.

Soweit die Theorie.
Meinst nicht, dass es einfacher ist, einfach dort UDP zu implementieren wo es nötig ist?

das hört sich nach Pipes an ?

Kann ja sein...
Setzt aber ein Betriebssystem voraus.

Also: Gibbet nicht.

Also kurz zur Absicht:
ich hab schon ein bestehendes Programm, welches Sensoren am ESP8266 aufnimmt und die Ergebnisse über die Serielle Schnittstelle ausgibt. Dies ist mit "Serial.print" bzw. "Serial.println" ausgeführt.
Ebenso werden Kommandos über die Serial... Schnittstelle angenommen und verarbeitet.

Leider ist jetzt für die identische Anwendung keine drahtgebundene Verbindung mehr möglich (Datenaufnahme im Gebälk einer Scheune). Hier gibt's nur ein Sonnenpanel (auf dem Dach), einige LiPos als Stromspeicher für den Betrieb in der Nacht und ein WLAN zur Kommunikation.

Hier wäre es eben am einfachsten, die Serial. - Routinen durch eine eigene Routine zu ersetzen, die per udp (oder telnet o.ä.) über WLAN mit einem Laptop am Boden der Scheune kommunizieren kann. (=zeichenorientierter Kanal für lesen und schreiben)

Meine blauäugige Vision:

  • ersetze alle "Serial.print" durch "eigeneRoutine.out"
  • schreibe entsprechende Routine "eigeneRoutine" ... <--- und genau daran hakt es...

Evtl. könntest Du meine Telnet-Debug-Routinen als Basis nutzen.

Gruß Tommy

noiasca:
Du könntest einen Referenz auf deine Serial machen.

HardwareSerial & Output= Serial;

Oder Stream. Dann geht es auch mit SoftwareSerial, Ethernet, LCDs, SD und andere Dingen die das gleiche Interface verwenden

ok ihr Theoretiker....
Gibt's auch ein Codebeispiel dafür?

P.S.: Ein Kollege hat mal gesagt:
Bist Du Ingenieur oder Informatiker? Du hast die besten Tips in der Theorie, aber praktisch ist dabei noch nix rüber gekommen....

-nix für ungut -

Moin

Wenn man selber keine Ahnung hat, sollte man schon aufpassen, Wem man auf die Füße kotzt :slight_smile:
In diesem Sinne, theoretisch gehe ich gleich den Grill anwerfen - Das klappte auch in einer Scheune anmerk

MfG

hajos118:
ok ihr Theoretiker....
Gibt's auch ein Codebeispiel dafür?

Ich hatte in #7 eins verlinkt. Wer lesen kann, ist klar im Vorteil.
Wenn es bei Dir nur zum Rumpöbeln reicht, dann wirst Du Deine Probleme wohl allein lösen müssen.

Gruß Tommy

Meine blauäugige Vision:

  • ersetze alle "Serial.print" durch "eigeneRoutine.out"
  • schreibe entsprechende Routine "eigeneRoutine" ... <--- und genau daran hakt es...

und was genau "hakt"?
Wenn hier jemand theoretisch bleibt, dann doch am ehesten der TO

Danke michael_x für die konstruktive Antwort. (Alle anderen sind dann wohl die Theoretiker).

Es hakt daran, dass ich leider keine Ahnung habe, wie ich eine Funktion anlegen muss, welche die gleichen Argumente übernehmen / annehmen kann, die auch die Serial.print() Funktion annimmt.

Was mir fehlt, ist der Ansatz dafür.... also die "leere" Funktion, den Inhalt kann ich dann selbst ausprogrammieren.

Beispiel:
Serial.print("String") und Serial.print(Variable) soll ersetzt werden durch
MeineRoutine("String") oder MeineRoutine(Variable).

Wie muss MeineRoutine angelegt werden? (Hier wäre ein funktionierendes Codebeispiel gefragt)

@Postmaster und Tommy: Ich hab keine Ahnung - deshalb frag ich ja. Wenn ich aber keine konstruktive Antwort bekommen kann, dann ist mir recht egal wem ich vor die Füße kotze - von diesen ist offensichtlich keine Antwort zu erwarten. Diese sollten sich vielleicht an Dieter Nuhr halten. Keiner wird hier gezwungen zu antworten... aber an den Antworten werde ich die Verfasser beurteilen.

Und wir Dich an Deinen Reaktionen. Du hast von mir ein Beispiel bekommen, wie man sowas umsetzen kann. Mit einer Funktion ist es nicht getan. Du musst eine Klasse schreiben, die von Print oder Stream erbt.

Wenn das derzeit noch zu komplex für Dich ist, musst Du halt erstmal die Grundlagen dafür lernen.

Gruß Tommy

Eine Funktion zu schreiben, die ein Ziel und den Inhalt als Parameter hat ist nicht so trivial wie es scheint. Das Problem ist da eher der Inhalt, da man für verschiedene Datentypen unterschiedliche Funktionen braucht.
Templates sind eine Option, aber damit bläht man auch leicht den Code auf:

template <typename T>
void print(const Stream& out, T& value)
{
   stream.print(value);
}

Der Compiler erzeugt dann für jede Verwendung eines anderen Typs eine neue Funktion. Und das kostet Flash. Hat aber den Nachteil, dass z.B. die Formatierungs-Optionen bei Float-Ausgaben nicht direkt verwenden kann. Dafür bräuchte man noch eine spezielle Variante

Brauchst du wirklich diese Flexibilität? Wenn nicht reicht auch eine Referenz:

Stream& out = Serial;

...

out.print("blah");

out = Serial1;

out.print("blah");

Wenn man das nicht zur Laufzeit ändern muss, sondern einmal beim Compilieren reichen auch Makros:

#define Ouput Serial

...

Output.println("blah");

Dann ändert man die erste Zeile und der Compiler passt das entsprechend an. Geht halt nur einmal und man nicht während der Laufzeit auf verschiedene Quellen schreiben. Aber ist oft völlig ok

Es hakt daran, dass ich leider keine Ahnung habe, wie ich eine Funktion anlegen muss, welche die gleichen Argumente übernehmen / annehmen kann, die auch die Serial.print() Funktion annimmt.

Nein. Das mit dem Vererben geht genau andersrum. Du erzeugst ein Objekt, das für alle Varianten von print das bereits vorhandene verwendet. Genau genommen gibt es diese Objekte schon: Serial ist nur eins davon. Alle I2C (Wire) Objekte oder auch dein EthernetUDP usw.
Du brauchst nur eine Referenz auf solch ein Objekt, von dem du weißt, dass es der Stream ( und damit auch der Print - ) Basisklasse angehört.

Combie hat ein 1000 Seiten Buch davon, aber man kann auch mit weniger Stoff schonmal anfangen.

Basisklassen, Vererben und Referenz solltest du zumindest eine Ahnung von bekommen.

@Tommy: OK sieht also so aus als ob ich auf meine alten Tage noch mal was Neues lernen muss...
... hab bis jetzt mehr auf ASM und C - Ebene programmiert. C++ und höher hab' ich bis jetzt noch nicht gebraucht. Hab' mir auch deinen link aus #7 angesehen und erstmal nur einen Bahnhof verstanden... auch wenn ich mir versucht habe einiges zusammen zu reimen.

@all:
hat mir jmd einen link/Tutorial für einen schnellen Einstieg in Klassen, Vererbung und das ganze neumodische Zeugs :wink: ?

Für's aktuelle Projekt werde ich wohl das vorhandene Prog umschreiben - aber für die Zukunft dürfte sich hoffentlich dann einiges einfacher gestalten.

Ich kann Dir ein gutes Buch empfehlen: "Der C++-Programmierer"

Gruß Tommy

hajos118:
Ich hab keine Ahnung

Ja, das merkt man!
Aber dafür hast du die Nase weit oben.

Mach du mal...