Zwei serielle Schnittstellen Umschaltung (Gelöst)

Hallo,
ich benutze einen Atrduino Micro, der zwei serielle Schnittstellen hat: Serial() wird auf dem USB-Port emuliert und Serial1() ist als Hardware auf den Pins verfügbar.

Ich möchte nun zwei Betriebsarten realisieren:

  • Programmierung und Evaluierung
  • Steuerung über Serial1()

Beide sollen im Dauerbetrieb das gleiche tun - wozu es sinnvoll wäre, die Schnittstellen umzuschalten, um den gleichen Puffer etc zu verwenden. Dazu brauche ich aber einen pointer, der auf die jeweils aktuelle Serial() zeigt.

Wie deklariere ich nun den pointer?

const &Serial() S0 = &Serial();
const &Serial() S1 = &Serial1();

funktioniert nicht:

const &Serial() S0 = &Serial();

^~

exit status 1
expected initializer before 'S0'

*Serial() S0 = *Serial();
*Serial() S1 = *Serial1();

geht auch nicht:

*Serial() S0 = *Serial();

^~

exit status 1
expected constructor, destructor, or type conversion before 'S0'

&Serial S0 = &Serial;

bringt auch nichts...

Probier mal entweder nach meinem Gefühl

Serial& S1 = &Serial;

oder nach Tutorial

Serial &S1 = Serial;

Mit const S1 gewinnst Du garnichts, dann kannst Du statt S1 oder S2 gleich Serial oder Serial1 hinschreiben.
Sinn macht eine einzige Referenz Serial& S, der dann wahlweise Serial oder Serial1 zugewiesen wird.

Referenzen sind verkleidete Pointer, die bei ihrer Verwendung ohne Pointer-Syntax auskommen, also nur p statt p*.

DrDiettrich:
Probier mal entweder nach meinem Gefühl

Serial& S1 = &Serial;
   S0.begin(SerSpeed);             // Kommunikationsport USB

^~

ST

exit status 1



'Serial' does not name a type

oder nach Tutorial

Serial &S1 = Serial;

Serial ist kein type :((

Ich habe es jetzt selber herausgefunden:

Serial_ S0 = Serial;

HardwareSerial S1 = Serial1;

funktionieren ohne Maulen des Compilers.

Jetzt die Preisfrage:
Wie muss ich den pointer deklarieren, der wahlweise auf S1 oder S2 zeigt?

oder muss ich das vielleciht besser über ein struct machen, in dem ich dann den Zeiger auf das erste oder zweite Element setze?

also

 S0.begin(SerSpeed);             // Kommunikationsport USB
  S1.begin(Ser1Speed);            // Kommunikationsport Fernsteuerung

funktioniert schon mal wie erwartet

allerdings

&Serial S;

bringt wieder das Problem zutage:

&Serial S;

         ^

exit status 1
expected constructor, destructor, or type conversion before 'S'
#define SerSpeed  2000000 // Baudrate Kommunikation IDE 2MBaud
#define Ser1Speed 115000  // Baudrate Fernsteuerung


Serial_ S0 = Serial;
HardwareSerial S1 = Serial1;

void setup() {
  // put your setup code here, to run once:
  S0.begin(SerSpeed);             // Kommunikationsport USB
  S1.begin(Ser1Speed);            // Kommunikationsport Fernsteuerung
}

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

}

ist der Test-Rumpf...

Dazu brauche ich aber einen pointer, der auf die jeweils aktuelle Serial() zeigt.

Wenn Zeiger die Lösung sind…

#include <Streaming.h>
#include <Wire.h>

Stream *stream = &Serial;


void setup() 
{
  Serial.begin(9600);
  Serial1.begin(9600);
  Wire.begin(); 
  
  *stream << "Start: "<< __FILE__ << endl;

  
  stream = &Serial1;
  *stream << "Start: "<< __FILE__ << endl;


  stream = &Wire;
  Wire.beginTransmission(8); // transmit to device #8
 // *stream << 7411;
  (*stream).print(7411);
  Wire.endTransmission();    // stop transmitting

  //stream = &lcd;
  //stream->println(4711);
  //(*stream).println(42);
}

void loop() 
{

}

Wie muss ich den pointer deklarieren, der wahlweise auf S1 oder S2 zeigt?

HardwareSerial* sp;

void setup() { 
   sp = &Serial;  // Zeiger auf ...
   sp->begin(9600);
   sp->println("Hello");
}

Ein Stream* kann zwar print(), und mit der streaming.h Syntax umgehen, aber nicht begin();

michael_x:

HardwareSerial* sp;

void setup() {
  sp = &Serial;  // Zeiger auf ...
  sp->begin(9600);
  sp->println("Hello");
}




Ein `Stream*` kann zwar `print()`, und mit der streaming.h Syntax umgehen, aber nicht `begin()`;

Ok, danke. Aber die Initialisierung kann ja bei Serial/Serial1.begin() bleiben - oder liege ich da falsch?
ich brauche eigentlich nur .begin(), .available(), .readString(), .print() und .println().

#include <Streaming.h> oder #include “Streaming.h” funktionieren bei mir nicht :frowning:

Ulli:
#include <Streaming.h> oder #include “Streaming.h” funktionieren bei mir nicht :frowning:

Das ist ja eine sehr präzise Aussage.

HotSystems:
Das ist ja eine sehr präzise Aussage.

HotSystems:
Das ist ja eine sehr präzise Aussage.

...steht doch da. das include funktioniert nicht. Weil es die .h nicht findet.

Ulli:
......Weil es die .h nicht findet.

Das steht da nicht.
Und wie wäre mit installieren ?

Ulli:
#include <Streaming.h> oder #include “Streaming.h” funktionieren bei mir nicht :frowning:

Kannst du weglassen.

Ist nur wegen den << Ausgabeumlenkungsoperatoren nötig.
Kannst sattdessen ganz normal mit “.available(), .readString(), .print() und .println()” arbeiten.
Findet sich auch in meinem Beispiel.

combie:
Kannst du weglassen.

Ist nur wegen den << Ausgabeumlenkungsoperatoren nötig.
Kannst sattdessen ganz normal mit “.available(), .readString(), .print() und .println()” arbeiten.
Findet sich auch in meinem Beispiel.

Dankeschön!

Meine Lösung:

Stream *S;
bool remote;
byte b;

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

void loop()
{
  remote = Serial1.available();
  if (remote) 
    S = &Serial1;
  else S = &Serial; 
  while ((*S).available()) {
    b = (*S).read();
    // ...
  }
}

Genial!
Danke für die Lösung - ich hab sehr interessiert mitgelesen.
Machst noch'n gelöst in die Betreffzeile im ersten Post?

Ulli:
Meine Lösung:

Stream *S;

bool remote;
byte b;

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

void loop()
{
  remote = Serial1.available();
  if (remote)
    S = &Serial1;
  else S = &Serial;
  while ((*S).available()) {
    b = (*S).read();
    // ...
  }
}

while ((*S).available())

Alte C Programmierer, die damals mangels C++ - Referenz-Datentypen mit Zeigern vertrauter waren, nutzen gern die Schreibweise S->available(). Was zwar nur 2 Zeichen spart, aber --wenn man’s gewohnt ist-- leichter lesbar ist als mit den vielen Klammern.

Danke auch dafür!

Letztendlich geht die Lösung darauf zurück, dass Stream die übergeordnete Klasse beider Schnittstellen ist. So könnte man die Ausgabe auch auf andere von Stream abgeleitete Schnittstellen umleiten - siehe das eine Beispiel oben mit I²C.