Einem Objekt einen seriellen Ausgang zuweisen

Hallo,

ich bin dabei ein Objekt (Instanz einer Klasse) zu erstellen, welches von Zeit zu Zeit serielle Befehle an einem bestimmten seriellen Port ausgeben soll.

Dem Objekt soll von außerhalb per Setter-Methode mitgeteilt werden, dass es von nun an auf einem bestimmten Ausgang senden soll.

Es geht mir nun darum, wie ich innerhalb des Objekts die Stellen an denen diese seriellen Befehle gesendet werden sollen umschreiben muss, damit diese an den von außerhalb u.U. neu definierten Ausgang gesendet werden.

Geht das überhaupt und falls ja, wie?

Gruß Chris

Gehen tut vieles....

class testprint
{
  public:
  HardwareSerial *serial = 0;
  void log()
  {
    if(serial) serial->println("Hi!");
  }
  void setSerial(HardwareSerial *port)
  {
    serial = port;
  }
};

testprint logger;

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

void loop() 
{
  
 logger.setSerial(&Serial);
 logger.log();
 logger.setSerial(&Serial1);
 logger.log();
 logger.setSerial(0); // logging abschalten
 logger.log(); // geht ins leere
 delay(500);

}

ungetestet

HardwareSerial geht nicht. Da kommt folgender Fehler: "error: invalid conversion from 'Print*' to 'HardwareSerial*' [-fpermissive]" Die Klasse die willst ist Print. HardwareSerial ist von Print abgleitet:

void setSerial(Print* serial)
{
   _serial = serial;
}

Zugriff sollte man dann vielleicht sicherheitshalber über eine Methode machen, die auf NULL testet:

void printSerial(const char* str)
{
   if (_serial != NULL)
     _serial->println(str);
}

Das bedeutet übrigens auch dass du der Methode andere Klassen übergeben kannst die von Print abgeleitet sind. Da sieht man wie schön Polymorphie ist, da der Code sehr flexibel wird :)

HardwareSerial geht nicht. Da kommt folgender Fehler:

Ausgeführt habe ich es nicht, aber bei mir kompiliert es. IDE 1.6

Ach, ich Idiot :) Ich hatte versucht einen Zeiger auf Print auf einen Zeiger auf HardwareSerial zuzuweisen, weil ich vergessen hatte den Parameter zu ändern :(

Wenn es nur Serial sein soll, kann man dann HardwareSerial nehmen. Print hat den Vorteil, dass die Methode alles schluckt was von Print, bzw. Stream abgeleitet ist, also z.B. auch Wire oder SoftwareSerial

Wenn es nur Serial sein soll, kann man dann HardwareSerial nehmen. Print hat den Vorteil, dass die Methode alles schluckt was von Print, bzw. Stream abgeleitet ist, also z.B. auch Wire oder SoftwareSerial

Eine schöne Sache. Das werde ich beizeiten mal ausgiebig testen!

Serenifly: ..die von Print abgeleitet sind.

Was bedeutet das?

Serielle Befehle habe ich bisher so ausgegeben:

Serial.print(); Serial.println(); Serial.write();

Gruß Chris

Vererbung.

HardwareSerial ist eine Unterklasse von Stream, welche wiederum eine Unterklasse von Print ist: Print ^ Stream ^ HardwareSerial

Daher kann man Serial, sowohl als HardwareSerial*, Stream* oder Print* ansprechen. Mit dem Unterschied dass man als HardwareSerial* Zugriff auch die Methoden von Print und Stream hat (d.h. alle Methoden der Oberklassen), aber als Print nicht Zugriff auf die Stream Methoden, da die einer Klasse darunter sind.

Wieso das Ganze?

Du hast sicher inzwischen gemerkt dass sehr viele Klassen print()/println() unterstützen. Es wäre da Irrsinn diese Funktionalität vollständig in jeder Klasse neu zu implementieren. Die eigentliche Logik steckt daher in Print. Der Kern der Sache ist die Version von write() die ein einzelnes Zeichen schreibt. Diese Methode ist virtuell (genauer rein virtuell, d.h. sie muss implementiert werden). Wenn man also in einer Klasse die Print Funktionalität will, leitet man die Klasse von Print ab und implementiert lediglich diese eine write() Methode wie man sie für die jeweilige Hardware braucht.

Wenn du dann das machst: .println("text");

wird erst mal die println(const char*) Methode in Print aufgerufen. Diese ist für jede Hardware gleich. Und von da die lokale write(char) Methode für jedes Zeichen, die hardware-spezifisch ist.

Also nur eine einfache Methode schreiben und man kann die ganzen Format und Ausgabe Optionen von Print verwenden.

Wonach muss ich googlen um verstehen zu können, was das hier bedeutet?

_serial->println(str);

Es geht mir hauptsächlich um den Pfeil in der Mitte.

Danke.

Gruß Chris

"Pfeil Operator" http://www.namespace-cpp.de/std/doku.php/kennen/klassen

Ist tatsächlich wenig beschrieben, aber nicht C++ spezifisch:

http://openbook.rheinwerk-verlag.de/c_von_a_bis_z/021_c_dyn_datenstrukturen_001.htm#mja75ba2f4ab8f95e9e321d195c1e26d76

struct S { int i; long l; };  // eine struct 

struct S s;    // eine Variable vom Datentyp struct S
struct S * sp = &s;  // sp ist ein Zeiger auf s

s.i = 1;
Serial.println( (*sp).i ) ; // Zugriff auf s.i
Serial.println( sp->i );  // vereinfachte Schreibweise

Aus der Arduino Reference:

Pointers are one of the more complicated subjects for beginners in learning C, and it is possible to write the vast majority of Arduino sketches without ever encountering pointers. However for manipulating certain data structures, the use of pointers can simplify the code, and and knowledge of manipulating pointers is handy to have in one's toolkit.

Das sollte Ansporn sein, Freunde, nicht Abschreckung.

Hallo,

was bedeutet denn eigentlich das hier?

combie:

HardwareSerial *serial = 0;

Ein Zeiger mit Datentyp HardwareSerial? HardwareSerial ist doch kein Datentyp. Das verstehe ich nicht. :blush:

Ein kleiner Link, wo ich ansetzen könnte zu suchen, wäre super.

Gruß Chris

Doch, HardwareSerial ist ein Datentyp

Serial ist vom Datentyp HardwareSerial. Solltest du jedenfalls versuchen, so zu sehen ;)

Ich glaube dir dass das für dich ungewöhnlich ist. Datentypen kann man schon in c definieren -> typedef , -> struct in c++ gibts als Erweiterung des struct Konzepts -> class

\hardware\arduino\avr\cores\arduino\HardwareSerial.h definiert class HardwareSerial Solltest natürlich eine Idee von class haben, bevor du dich in die Details dort vertiefst

Ein Zeiger auf einen Datentyp ist auch ein Datentyp. Jedenfalls was anderes als ein Zeiger auf einen anderen Datentyp. Das ist dann kein Problem für dich, erstmal ?

Werd mir die HardwareSerial class mal genauer anschauen.

Vielen Dank!

Gruß Chris