Hab mir eine ESP "AT" Bliothek erstellt, nun wollte ich noch den Serialport im Konstruktor übergeben und sehe da ein Problem beim SoftwareSerial.
Kurz zusammengefasst: Serialport wird mit "Konstruktor(&verwendeterSerial)" übergeben und in der Klasse gibt's dann ein Objekt"Stream *WifiSerial;", welches den Serial übergeben bekommt. Danach sind zwei Funktionen relevant für den Datenaustausch:
void RxRead()
{
while(WifiSerial->available()) //Wenn Nachricht vorhanden, speichere erstmal in einen Pufferspeicher
{
char tmpChr = WifiSerial->read();
Serial.println(tmpChr);
RxMsgBuffer += tmpChr;
}
if(RxMsgBuffer.lastIndexOf("\n") > -1) // Wenn ein Zeilenumbruch vorhanden, dann nehme den Teilstring
{
int cutPos = RxMsgBuffer.indexOf("\n")+1;
String HelpStr;
RxMsg = RxMsgBuffer;
RxMsg.remove(cutPos);
RxMsgBuffer = RxMsgBuffer.substring(cutPos);
}
else // Wenn kein Text, dann leer
{
RxMsg = "";
}
}
Wenn ich einen Hardware-Serial übergebe, kommen die AT-Rückmeldungen des ESP problemlos und ich hab auch eine Wifi-Verbindung für den Datenaustausch.
Aber wenn ich Software-Serial verwende, kommen nur komische Zahlen zurück. Die ersten Zeichen passen noch, aber mit der Länge der Zeichen steigert sich der Unsinn.
Ein Beispiel: "AT+CWMODE=1" gibt als Antwort nicht "AT+CWMODE=1 OK" sondern "AT+CWMODQ⸮j OK"
Muss man bei SoftwareSerial was beachten mit der Übergabe von Zeigern oder harmoniert diese nicht gut mit der String Bibliothek? Auch wenn ich das tmpChr direkt auslese, kommt der gleiche Unsinn raus. (Deshalb die ganzen "Serial.print" Befehle im Code).
Normal nimmt für sowas Referenzen statt Zeiger, aber im Prinzip ist das nicht das Problem
SoftwareSerial ist natürlich generell weniger zuverlässig als eine Hardware-Schnittstelle. Das kann unter gewissen Umständen solche Fehler verursachen
Das ganze Gewurschtel mit der String Klasse ist hier eigentlich überflüssig, aber das ist nicht die Ursache des Problems.
Deine Behandlung des LFs z.B. ist äußerst abstrus. Du speicherst das LF ab und fragst ab ob es vorhanden. Danach wird irgendwas mit Teil-Strings gemacht. Statt einfach abzufragen ob das eingelesene Zeichen ein LF ist
@Tommy56: Ich dachte ich hol mir nur die beiden Funktionen raus, die ich für das Senden bzw. Empfangen der AT-Befehle verwende. Der Rest ist nur zum Senden und Auswerten der Daten.
Hier nochmal der ganze Code, aber der ist halt bereits sehr angewachsen und besteht im Allgemeinen nur im Aufruf und Auswerten der beiden oben genannten Funktionen.
Hier der Code, der ausgeführt wird:
#include "ESP8266s.h"
#include <SoftwareSerial.h>
#define WifiSerial espSerial
SoftwareSerial espSerial = SoftwareSerial(10,11);
ESP8266 ESP(&espSerial);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
WifiSerial.begin(115200);
ESP.ping();
ESP.ConnectToAP("SSID", "Passwort");
ESP.StartServer(8000);
while(ESP.DataExchange())
delay(10);
}
void loop() {
// Loopcode
}
Hier der Code, der ESP Klasse, welche ich als Objekt erzeuge, sofern ich in einem Projekt ein ESP verwende:
Ich muss es leider in zwei Posts aufteilen, da der ganze Code die 9000 Zeichen sprengt.
In einem Array kann ich maximal 10 AT-Befehle eintragen, für jeden AT-Befehl hab ich eine eigene Funktion erstellt. Durch die DataExchange() Funktion kann ich den Puffer entweder in einer while-Schleife abarbeiten (was aber in der Loop alles ausbremst, aber im Setup durchaus akzeptabel ist), oder ich rufe sie in der Loop jedesmal zyklisch auf um den nächsten Befehl zu senden, sofern ich nicht auf eine Antwort warte. Über eine Switch-Case wird der Status der Übertragung geprüft. Das ist bereits ziemlich viel Code, weshalb ich nicht alles posten wollte (der Übersichtlichkeit halber).
@Serenifly: Ich habs zu Begin als Referenz versucht, allerdings hat die "Read()" keine Werte zurück gegeben und ich bin mit Zeigern etwas vertrauter. Da es ein paar wenige Bibliotheken gibt, wo es so übergeben wird, hab ich mich dafür entschieden. Aber das Anpassen ist später das kleinere Problem.
Dieses Gewurschtel ist tatsächlich fast historisch gewachsen, da ich zu Beginn Probleme hatte, den String richtig auszulesen und auszuwerten. Das wird noch vereinfacht, wenns einmal komplett funktioniert.
@HotSystems: Der Standard bei den ESP8266 ist 115200, da hab ich erstmal nichts angepasst. Kann gerne eine geringere Baudrate versuchen.
Analog bei allen anderen Methoden. Objekte übergibt man immer als Referenz um die Kopie zu vermeiden. Sauberer noch eine const-Referenz wenn man den String nicht verändert
Dein ständiges c_str() ist auch überflüssig. Siehe z.B. das:
return AT_addBuffer(tmpStr.c_str());
bool AT_addBuffer(String newAT)
Du übergibst einen C-String (also ein char Array). Aber die Methode macht gleich wieder ein String Objekt daraus
Ich habs heute doch noch gleich getestet (nur Schnelltest) und tatsächlich minimiert sich der Fehler mit niedrigerer Baudrate. Getestet mit 9600 und 19200.
Am Arduino Mega klappts dadurch gut am Testaufbau, beim Nano für die finale Anwendung hakt es irgendwie noch etwas mehr, aber auch hier kommt häufiger was sinnvolles zurück.
Danke erstmal, damit bin ich ein großes Stück weiter.
Du hast am Anfang den ESP erwähnt. Jetzt sagst du aber dass es auf dem Nano laufen soll. Einen AVR Prozessor zum Testen zu verwenden ist ok, aber wenn das am Ende nur auf AVRs laufen soll bist du mit AltSoftSerial besser dran. Das verwendet einen Hardware Timer und ist damit zuverlässiger. Geht allerdings nicht auf ESPs