Mehrere serielle Terminal-Programme verwenden gleichzeitig gleiche Hardware

Die Terminal-Programme haben ein Delay, bis ein neuer Befehl ausgegeben wird. Das Delay hat eine Spanne von 500ms, andere Terminal-Programme können mehrere sekunden warten. Das sind sog. Pollings.

Sehe ich nicht so krumm.
Die Terminals senden die 5 bytes enBlock - da passt das schon.

Ich teil das lesen mal auf in lesen und senden.
Dann muss ich sehen, was ich mit dem lesen mache um daraus etwas sinnvolles als Antwort auszugeben.

Na das sind ja Welten :slight_smile: passt! Du hast drei Serielle - 500ms / 3 = 160 + x ms...

Ja genau, alle drei vom Arduino Mega,

Serial, Terminal-Programm 0
Serial1, Terminal-Programm 1
Serial2, Terminal-Programm 2

Serial 3, Hardware

Bei Arduino Serial (Null) verwende ich einen Schalter für das Hochladen des arduino-Programms.

Mir fällt noch ein, die Terminal-Programme schalten die Anzeigen nach längerer Zeit aus. Jedes Terminal-Programm mit seiner eigenen Zeit. Sobald die Funktionalität wieder besteht, legen sie automatisch wieder los.

Ich kann per Datenleitung abfragen, ob gewünschtes Terminal-Programm aktiv ist. Das funktioniert bei allen Terminals glücklicherweise.

Sorry, ich musste mal schnell was anderes machen.
ungetestet, aber kompiliert.
Mich würde interessieren, ob das geht....

char inByte;
char stringPort[4][6] = {'\0'};      // Zeichenkette für jeden SerialPort
uint8_t portPosition[4] = {0};       // Position des Zeichens in der Zeichenkette
bool portIsFull[4] = {false};
uint32_t receivedTimeOut = 80000;    // Zeit in ms.
void setup()
{
  // initialize serial ports:
  //Serial.begin(4800);
  Serial.begin(4800, SERIAL_8N2);   // Baud, Config
  Serial1.begin(4800, SERIAL_8N2);  // Baud, Config
  Serial2.begin(4800, SERIAL_8N2);  // Baud, Config
  Serial3.begin(4800, SERIAL_8N2);  // Baud, Config
}

void loop()
{
  readSerial();
  readSerial1();
  readSerial2();
  sendSerial();
}

void readSerial()
{
  // read from Serial 0, send to Serial 3:
  if (Serial.available())                       // wenn ein Zeichen vorhanden ...
  {
    inByte = Serial.read();                     // ... einlesen ...
    stringPort[0][portPosition[0]] = inByte;    // ... in Zeichenkette aufnehmen ...
    portPosition[0]++;                          // ... nächste Position berechnen
  }
  if (portPosition[0] >= 5)                     // Wenn Ende der Zeichenkette erreicht ...
    portIsFull[0] = true;                       // ... merke das
}

void readSerial1()
{
  // read from Serial 1, send to Serial 3:
  if (Serial1.available())
  {
    inByte = Serial1.read();
    stringPort[1][portPosition[1]] = inByte;
    portPosition[1]++;
  }
  if (portPosition[1] >= 5)
    portIsFull[1] = true;
}
void readSerial2()
{
  // read from Serial 2, send to Serial 3:
  if (Serial2.available())
  {
    inByte = Serial2.read();
    stringPort[2][portPosition[2]] = inByte;
    portPosition[2]++;
  }
  if (portPosition[2] >= 5)
    portIsFull[2] = true;
}

void sendSerial()
{
  static uint8_t lastSend[4] = {0};            // Merker, wann letzte Sendung - für jeden Port
  static byte schritt = 0;                     // Zähler
  static uint8_t port = 0;                     // serials 3 ^ Ports 0,1,2
  if (port > 2) port = 0;                      // Wenn drüber gezählt, fang an von vorn
  if (portIsFull[port] == false) port++;       // Wenn nichts vorhanden nächster Port ...
  else
  {
    switch (schritt)                           // Auswahl
    {
      case 0:                                  // Erste Sendung - Es wird aktuell nur einmal gesendet
        Serial3.println(stringPort[port]);     // ... gebe aus was da ist ...
        lastSend[port] = millis();             // ... Zeit merken ...
        schritt++;                             // ... nächste Auswahl ...
        break;
      case 1:
        readSerial3();                         // ... lese Antwort ...
        if (portPosition[3] >= 5)              // ... warte auf Vollständigkeit
        {
          Serial.println(stringPort[3]);       // ... gebe aus
          schritt++;                           // nächster Schritt
        }
        else if (millis() - lastSend[port] > 100) // Nicht vollständig und Zeit abgelaufen
        {
          schritt++;                           // nächster Schritt
        }
        break;
      case 2:
        memset(stringPort[port], '\0', sizeof(stringPort[port])); // ... lösche Inhalte ...
        memset(stringPort[3], '\0', sizeof(stringPort[port]));
        portPosition[port] = 0  ;                                 // ... und setze Positionen zurück
        portPosition[3] = 0;
        schritt = 0;                                              // und fange an von vorn
        break;
      default:
        schritt = 0;
        break;
    }
  }
}

void readSerial3()
{
  // read from Serial 3
  if (Serial3.available())
  {
    inByte = Serial3.read();
    stringPort[3][portPosition[3]] = inByte;
    portPosition[3]++;
  }
}

Wenn der macht, dann erklär ich über die Kommentare hinaus, was da passiert. (Momentan nur gestrickt mit heisser Nadel... :wink: )

Danke, danke, alles vollkommen in Ordnung. Ich teste das Programm... DANKE!

Serial1 empfängt korrekt die Daten, die Hardware reagiert nicht. Ich konnte bei den Case keine Daten lesen. Ich gehe nochmals die Schritte durch... Irgend etwas müsste auf Serial3 passieren...

Hier ist mir ein Fehler unterlaufen?
Das case 1:

case 1:
        readSerial3();                         // ... lese Antwort ...
        if (portPosition[3] >= 5)              // ... warte auf Vollständigkeit
        {
Hier müsste doch IMHO der richtige Port rein... auf dem ausgegeben wird???
          Serial.println(stringPort[3]);       // ... gebe aus

          schritt++;                           // nächster Schritt
        }
        else if (millis() - lastSend[port] > receivedTimeOut) // Nicht vollständig und Zeit abgelaufen
        {
          schritt++;                           // nächster Schritt
        }
        break;

HINWEIS:
Bitte immer auf einen Beitrag von mir antworten - wenn Du unten auf das Antworten im Thread klickst, sehe ich das nicht - Danke.

Entschuldigung, habe ich nicht aufgepasst, OK, ich ändere das... gut, gut

Ich hab mal das sendSerial umgebaut:

void sendSerial()
{
  static uint8_t lastSend[4] = {0};            // Merker, wann letzte Sendung - für jeden Port
  static byte schritt = 0;                     // Zähler
  static uint8_t port = 0;                     // serials 3 ^ Ports 0,1,2
  if (port > 2) port = 0;                      // Wenn drüber gezählt, fang an von vorn
  if (portIsFull[port] == false) port++;       // Wenn nichts vorhanden nächster Port ...
  else
  {
    switch (schritt)                           // Auswahl
    {
      case 0:                                  // Erste Sendung - Es wird aktuell nur einmal gesendet
        Serial3.println(stringPort[port]);     // ... gebe aus was da ist ...
        lastSend[port] = millis();             // ... Zeit merken ...
        schritt++;                             // ... nächste Auswahl ...
        break;
      case 1:
        readSerial3();                         // ... lese Antwort ...
        if (portPosition[3] >= 5)              // ... warte auf Vollständigkeit
        {
          switch (port)
          {
            case 0:
              Serial.println(stringPort[3]);       // ... gebe aus
              break;
            case 1:
              Serial1.println(stringPort[3]);       // ... gebe aus
              break;
            case 2:
              Serial2.println(stringPort[3]);       // ... gebe aus
              break;
          }
          schritt++;                           // nächster Schritt
        }
        else if (millis() - lastSend[port] > receivedTimeOut) // Nicht vollständig und Zeit abgelaufen
        {
          schritt++;                           // nächster Schritt
        }
        break;
      case 2:
        memset(stringPort[port], '\0', sizeof(stringPort[port])); // ... lösche Inhalte ...
        memset(stringPort[3], '\0', sizeof(stringPort[port]));
        portPosition[port] = 0  ;                                 // ... und setze Positionen zurück
        portPosition[3] = 0;
        schritt = 0;                                              // und fange an von vorn
        break;
      default:
        schritt = 0;
        break;
    }
  }
}

der schickt jetzt auf den Serialport, der ausgewählt ist...
Wenns nicht geht, brauch ich etwas länger...

Die Ausgabe ist bei void readSerial3()

000000000
00000
00000
00000
00000
00000
usw.

Ok, ich brauch da mal etwas länger.
Aber es ist wieder Samstag - da hör ich Fritz! :slight_smile:

Lieben Dank aber für die tolle Unterstützung! Dann viel Freude bei Fritz!!!

Man tut, ich mach das nur um mich wenigstens noch logisch fit zu halten.
Und da ist auch mein Ansatz!
Ich habe zumindest vergessen den Merker zurückzusetzen.
Vielleicht findest es ja, wo es hin gehört.

      case 2:
        memset(stringPort[port], '\0', sizeof(stringPort[port])); // ... lösche Inhalte ...
        memset(stringPort[3], '\0', sizeof(stringPort[port]));
        portPosition[port] = 0  ;                                 // ... und setze Positionen zurück
        portPosition[3] = 0;
        schritt = 0;                                              // und fange an von vorn
        portIsFull[port]=false; // <= Der muss neu rein, sonst wird der immer wieder ausgeführt
        break;

Zwischenzeitlich schau ich mal, ob ich noch Schnitzer habe.

Danke, danke, ich schaue danach...

Ich würde gerne, das Du den Serial Port fürs debuggen lässt und nur Serial1,2,3 benutzt.
Dabei bleiben wie gehabt 1 und 2 die Geber und 3 der Empfänger, der bestätigt.

Dazu gibt es folgenden Code. Da die Übergaben offensichtlich ohne Steuerzeichen laufen, habe ich das einfach mal aufs wesentliche runter gebrochen.

Du musst jetzt nur dafür sorgen, das Serial(0) dem USB vorbehalten bleibt und nicht dazwischen manscht. Beachte, das die Geschwindigkeit schneller ist, sonst macht das keinen Sinn...

char inByte;
char stringPort[4][6] = {'\0'};      // Zeichenkette für jeden SerialPort
uint8_t portPosition[4] = {0};       // Position des Zeichens in der Zeichenkette
bool portIsFull[4] = {false};
uint32_t receivedTimeOut = 130;    // Zeit in ms.
void setup()
{
  // initialize serial ports:
  Serial.begin(115200);
  //  Serial.begin(4800, SERIAL_8N2);   // Baud, Config
  Serial1.begin(4800, SERIAL_8N2);  // Baud, Config
  Serial2.begin(4800, SERIAL_8N2);  // Baud, Config
  Serial3.begin(4800, SERIAL_8N2);  // Baud, Config
}

void loop()
{
  //  readSerial();
  readSerial1();
  readSerial2();
  sendSerial();
}

void readSerial()
{
  // read from Serial 0, send to Serial 3:
  if (Serial.available())                       // wenn ein Zeichen vorhanden ...
  {
    inByte = Serial.read();                     // ... einlesen ...
    stringPort[0][portPosition[0]] = inByte;    // ... in Zeichenkette aufnehmen ...
    portPosition[0]++;                          // ... nächste Position berechnen
  }
  if (portPosition[0] >= 5)                     // Wenn Ende der Zeichenkette erreicht ...
    portIsFull[0] = true;                       // ... merke das
}

void readSerial1()
{
  // read from Serial 1, send to Serial 3:
  if (Serial1.available())
  {
    inByte = Serial1.read();
    stringPort[1][portPosition[1]] = inByte;
    portPosition[1]++;
  }
  if (portPosition[1] >= 5)
  {
    portIsFull[1] = true;
    Serial.print(F("ser1 full! "));
    Serial.println(stringPort[1]);
  }
}
void readSerial2()
{
  // read from Serial 2, send to Serial 3:
  if (Serial2.available())
  {
    inByte = Serial2.read();
    stringPort[2][portPosition[2]] = inByte;
    portPosition[2]++;
  }
  if (portPosition[2] >= 5)
  {
    portIsFull[2] = true;
    Serial.print(F("ser2 full! "));
    Serial.println(stringPort[1]);
  }
}

void sendSerial()
{
  static uint8_t lastSend[4] = {0};            // Merker, wann letzte Sendung - für jeden Port
  static byte schritt = 0;                     // Zähler
  static uint8_t port = 0;                     // serials 3 ^ Ports 0,1,2
  if (port > 2) port = 0;                      // Wenn drüber gezählt, fang an von vorn
  if (portIsFull[port] == false) port++;       // Wenn nichts vorhanden nächster Port ...
  else
  {
    switch (schritt)                           // Auswahl
    {
      case 0:                                  // Erste Sendung - Es wird aktuell nur einmal gesendet
        Serial.println(F("sendSerial 0"));
        while (Serial3.available())     // Das ist evtl. nicht der Weisheit letzter Schluss zum Leeren des Puffer
          Serial3.read();               // aber wenn da nicht dauerhaft gesendet wird, sollte es gehen
        Serial3.println(stringPort[port]);     // ... gebe aus was da ist ...
        lastSend[port] = millis();             // ... Zeit merken ...
        schritt++;                             // ... nächste Auswahl ...
        break;
      case 1:
        readSerial3();                         // ... lese Antwort ...
        if (portPosition[3] >= 5)              // ... warte auf Vollständigkeit
        {
          Serial.print(F("sendSerial 1 - Antwort: "));
          Serial.println(stringPort[3]);
          switch (port)
          {
            case 0:
              Serial.println(stringPort[3]);   // ... gebe aus
              break;
            case 1:
              Serial1.println(stringPort[3]);  // ... gebe aus
              Serial.println(F("Ausgabe auf Ser 1"));
              break;
            case 2:
              Serial2.println(stringPort[3]);  // ... gebe aus
              Serial.println(F("Ausgabe auf Ser 2"));
              break;
          }
          schritt++;                           // nächster Schritt
        }
        else if (millis() - lastSend[port] > receivedTimeOut) // Nicht vollständig und Zeit abgelaufen
        {
          schritt++;                           // nächster Schritt
          Serial.println(F("Timeout beim lesen!"));
        }
        break;
      case 2:
        memset(stringPort[port], '\0', sizeof(stringPort[port])); // ... lösche Inhalte ...
        memset(stringPort[3], '\0', sizeof(stringPort[port]));
        portPosition[port] = 0  ;                                 // ... und setze Positionen zurück ...
        portPosition[3] = 0;
        portIsFull[port] = false;                                 // ... Merker löschen ...
        schritt = 0;                                              // ... und fange an von vorn
        Serial.println(F("Rest Parameter"));
        break;
      default:
        schritt = 0;
        break;
    }
  }
}

void readSerial3()
{
  // read from Serial 3
  if (Serial3.available())
  {
    inByte = Serial3.read();
    stringPort[3][portPosition[3]] = inByte;
    portPosition[3]++;
  }
}

Ja vielen Dank, den Serial (Null) verwende bei den Tests nie, erst gegen Ende. Ich muss die Baude-Rate ohnehin anpassen. Nicht alle können 115200, aber einige. Mit dem Hauttest-Terminal-Programm verwende ich 115200. Die Hardware kann nur 4800.

Na dann ist das ja ok so.
Fürs debuggen müssen die Ausgaben nur schneller raus, um wenigstens ansatzweise keine zeichen zu verlieren.