SoftwareSerial funktioniert nicht

Ich habe hier ein orginal Arduino Uno R3 Board. Ich habe einen Solarregler, welcher mit 19200 Baudrate (fest!) an RX sendet.

Für den Arduino sollte das kein Problem sein
https://www.arduino.cc/en/Reference/SoftwareSerialBegin

Bisher habe ich das Empfangene auf einen kleinen LCD Display ausgegeben, was auch gut geklappt hat.
Nun möchte ich das ganze auf den PC ausgeben (COM-Port), leider zeigt er mir immer nur den Begrüßungstext an, hat aber keine Daten (auch keine Anzeige auf dem LCD)

Ich nutze hierfür die Software Serial um einen neuen Input Pin festzulegen, da der Uno bekanntlich nur einen Anschluss hat

//define additional serial input
#include <SoftwareSerial.h>
SoftwareSerial SolarInput(2, 3); // RX2, TX2

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

String label;
String val;
int i=0;

void setup() {
  
   //Display setup
  lcd.init();  //initialize the lcd
  lcd.backlight();  //open the backlight

//Serial start
  Serial.begin(19200);
  Serial.print("Test beginnt");
  SolarInput.begin(19200);
}


void loop() {

  if (SolarInput.available()) 
    {
    label = SolarInput.readStringUntil('\t');      
    val = SolarInput.readStringUntil('\r\r\n');
    lcd.print(label);  
    lcd.print(":");
    lcd.print(val);
    Serial.print(label);
    Serial.print(":");
    Serial.print(val);
    }

}

Auch schon mit AltSoftSerial probiert (ersten 2 Zeilen ersetzt)

#include <AltSoftSerial.h>
AltSoftSerial SolarInput(2, 3); // RX2, TX2

und

#include <AltSoftSerial.h>
AltSoftSerial SolarInput // RX2, TX2

Und nochmal der Hinweis: Angeschlossen am “normalen” RX/TX zeigt er mir die Daten auf den LCD an!

#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);

String label;
String val;
int i=0;

void setup() {
  
   //Display setup
  lcd.init();  //initialize the lcd
  lcd.backlight();  //open the backlight

//Serial start
  Serial.begin(19200);
}


void loop() {

  if (Serial.available()) 
    {
    label = Serial.readStringUntil('\t');      
    val = Serial.readStringUntil('\r\r\n');
    lcd.print(label);  
    lcd.print(":");
    lcd.print(val);
    }

}

Somit schließe ich aus, dass es am Solarregler liegt

Jemand eine Idee?

Grüße

Das Alternative Altsoftserial arbeitet mit HardwareTimerUnterstützung und daher festen Pin-Nummern
( Auf dem Uno 8/9 )

SolarInput.readStringUntil('\r\r\n');

Das scheint mir überarbeitungswürdig

Beides beantwortet leider nicht deine eigentliche Frage.

michael_x:
Das Alternative Altsoftserial arbeitet mit HardwareTimerUnterstützung und daher festen Pin-Nummern
( Auf dem Uno 8/9 )

Ja, leider auch schon probiert

michael_x:
Das scheint mir überarbeitungswürdig

Sagt mir die Arduino IDE auch. Copy&Paste von einem Fremdcode. Steht dann als nächstes an :wink:

Habe es auch in der Variante

SoftwareSerial SolarInput =  SoftwareSerial(2,3); // RX2, TX2
pinMode(2, INPUT);

probiert. Ohne Erfolg

Grüße

Hast du mal RX und TX vertauscht ?

Und so wie es in deinem obigen Sketch gezeigt wird, siehst du auch nur ein max. Zeichen.

HotSystems: Hast du mal RX und TX vertauscht ?

Gerade eben versucht mit SoftwareSerial und AltsoftwareSerial

HotSystems: Und so wie es in deinem obigen Sketch gezeigt wird, siehst du auch nur ein max. Zeichen.

Wieso sollte es?

DerPeter: Wieso sollte es?

Ja....weil es so ist. Mit deiner Anweisung liest du nur ein Zeichen aus.

Wenn es mehr sind (bsp. String) musst du die noch zusammen setzen.

Sieh dir dazu mal dies hier an.

HotSystems: Ja....weil es so ist.

Wahnsinns Begründung :D

In deinem Link wird aber Serial.read() benutzt, bei mir Serial.read*String*Until. Ohne irgendwo nachschauen zu müssen, könnte ich wetten, der Befehl liest die einzelne chars aus dem Buffer aus ohne dafür einen loop benötigen zu müssen und setzt sie automatisch zu einem String zusammen

Nebenbei gibt er mir auf den Display den korrekten (ganzen) String aus

Grüße

Nachtrag:

https://www.arduino.cc/reference/de/language/functions/communication/serial/readstringuntil/: ... readStringUntil() liest Zeichen aus dem seriellen Puffer in einen String. ... Rückgabewert

Der gesamte String, der vom seriellen Puffer bis zum Abschlusszeichen gelesen wird.

Ganz ohne "böse" Strings wäre einen Versuch wert:

  if (SolarInput.available()) {
    char label[10];
    SolarInput.readBytesUntil('\t', label,10);     
    char val[10];
    SolarInput.readBytesUntil('\n',val,10);
    lcd.print(label); 
    lcd.print(":");
    lcd.print(val);
    Serial.print(label);
    Serial.print(":");
    Serial.println(val);
  }

Müsste man evtl. noch die hässlichen '\r' Zeichen aus der lcd-Anzeige entfernen. (Und diese jeweils neu positionieren.

val = Serial.readStringUntil('\r\r\n');

Warnungen aktivieren. Dann merkst du dass das nicht geht

Bei CR + LF reicht es auf das LF abzufragen. Das CR kann man abschneiden. Wenn man mit C Strings arbeitet am besten durch NULL oder '\0' ersetzen damit der String auch richtig terminiert ist. Das ist bei readBytesUntil() wahrscheinlich nicht der Fall

Das größte Problem bei diesen fertigen Funktionen ist dass die Timeout-Zeit normal 1 Sekunde ist. Dass kann man aber mit setTimeout() auf einen vernünftigen Wert setzten

DerPeter: ... Nebenbei gibt er mir auf den Display den korrekten (ganzen) String aus ...

Asche auf mein Haupt!

Ok....sorry, ich hatte übersehen, dass du "readStringUntil" im Sketch verwendest. Da sollte das so funktionieren.

HotSystems: Asche auf mein Haupt!

Ich verzeihe dir ;-)

michael_x: Ganz ohne "böse" Strings wäre einen Versuch wert

Ganz ohne es versucht zu haben, kann ich schon sagen, dass es nicht geht, da er zumindest dann die ":" anzeigen würde

[/quote]

Serenifly: Bei CR + LF reicht es auf das LF abzufragen. Das CR kann man abschneiden. Wenn man mit C Strings arbeitet am besten durch NULL oder '\0' ersetzen damit der String auch richtig terminiert ist. Das ist bei readBytesUntil() wahrscheinlich nicht der Fall

Abgeändert zu SolarInput.readStringUntil('\n'); Danke für den Tipp

Grüße

Ganz ohne es versucht zu haben, kann ich schon sagen, dass es nicht geht, da er zumindest dann die “:” anzeigen würde

Gerade wenn der Sketch sich völlig unerklärlich verhält, fällt traditionell der Verdacht immer auf String Objekte. :slight_smile:

Das ist sicher ein altes Vorurteil, und früherTM war auch SoftwareSerial ein genereller Verdächtiger.

michael_x: Gerade wenn der Sketch sich völlig unerklärlich verhält, fällt traditionell der Verdacht immer auf String Objekte. :)

Nur für dich versucht :D ich wünschte es wäre erfolgreich gewesen :(

Grüße

Wenn es denn garnich will, warum nicht mal anders aufbauen.

Bei mir funktioniert das mit SoftwareSerial so problemlos, ähnlich dem Sketch im Link:

 while (mySerial.available() > 0) {
    c_inChar = mySerial.read();             
    s_input.concat(c_inChar);               
    if (c_inChar == '\n') {                 
      Serial.print(": ");                   
      Serial.print(s_input);              
      s_input = "";                         
    }  

//hier dein weiterer Sketch

}

Glaube mich zu erinnern daß die Software-Seriel-Emulation nur bis 9600 Baud stabil läuft.

Könntest mal mit Hardware probieren die mehrere serielle Schnittstellen hat wie zB Arduino Leonardo / MICRO / PRO MICRO oder Arduino MEGa 2560.

Grüße Uwe

uwefed: Glaube mich zu erinnern daß die Software-Seriel-Emulation nur bis 9600 Baud stabil läuft.

Ich kann jetzt nicht für alle Fälle sprechen, aber ich betreibe mein Nextion-Display seit längerem erfolgreich über SoftwareSerial, mit 38400 baud. Ginge bestimmt noch höher, ich hab es aber nur noch nicht ausprobiert. ;)

wapjoe: Ich kann jetzt nicht für alle Fälle sprechen, aber ich betreibe mein Nextion-Display seit längerem erfolgreich über SoftwareSerial, mit 38400 baud. Ginge bestimmt noch höher, ich hab es aber nur noch nicht ausprobiert. ;)

Ja, das kann ich bestätigen. Ich nutze auch 38400 Bd für meine hausinternen Lichtsteuerung, und das funktioniert da sehr stabil.

Mit einer höheren Geschwindigkeit schleichen sich sehr oft Fehler ein.

Bei SoftwareSerial ist read und write ein großer Unterschied. (write ist einfacher, glaube ich) (Und gleichzeitig geht gar nicht, aber das ist hier nicht das Thema)

Dass in der Referenz SoftwareSerial.begin(19200) erlaubt ist und bei weitem nicht das Maximum darstellt, mag zwar richtig sein, würde ich aber nicht als Garantiezusage in allen Fällen nehmen.

Hallo zurück,

habe mir mal einen zweiten Arduino Uno ausgeliehen und den Code oben etwas abgeändert zum Testen

#include <SoftwareSerial.h>

SoftwareSerial mySerial(2, 3); // RX, TX

void setup() {
  // Open serial communications and wait for port to open:
  Serial.begin(57600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // set the data rate for the SoftwareSerial port
  mySerial.begin(4800);
}

void loop() { 
  
  // run over and over
   mySerial.write("Hello, world?");
   
  if (mySerial.available()) {
    Serial.println(mySerial.readStringUntil('\n'));
    delay(400);
  }
}

Der eine Arduino sendet, der andere empfängt. Beide senden und empfangen sehr erfolgreich auf Pin 2 und 3

Danach mit

mySerial.begin(19200);

versucht, hat auch geklappt

Ich habe weiter geforscht zu dem Solarregler und bin auf eine kleine Info gestoßen, die leider der Hersteller nirgendwo preisgibt

In einem Post habe ich zufällig erfahren, dass der Solarregler 3,3V hat und keine 5V wie der Arduino. Ich vermute einfach, dass RX/TX es zwar noch als High erkennt, die Software Serial dies aber einfach nicht hinbekommt.

Vermutlich hätte ich selber darauf kommen können, wenn ich ein Voltmeter drangehalten hätte…

Der Arduino erkennt 3,3V noch als High. Das hat nichts mit der Software zu tun. In die andere Richtung darfst du aber in den aller meisten Fällen keine 5V an eine 3,3V Schaltung anlegen. Nur wenn explizit dabei steht dass es 5V-tolerant ist