Arduino Nano SIm800L Modul String setzen und vergleichen.

Tommy56:
Das kann z.B. ein NewLine sein.

Ja. Unbedingt das. Die ganzen AT Kommandos werden mit einem CR + LF abgeschlossen. Darauf sollte man abfragen. Das CR kann man ignorieren und das LF als Endzeichen nehmen

Siehe Anleitung:

Commands are usually followed by a response that includes.
"<CR><LF><response><CR><LF>"

Wobei es das CR/LF am Anfang etwas komplizierter macht

Okay, ich komme da noch nicht so ganz hinter.

Wenn ich das Array char inhalt[160] = "";

so bestücke:

  while (count == 0) // Loop bis count nicht mehr gleich 0.
  {
    while (tcSerial.available() > 0)// Wenn dort Daten sind dann lese sie.
    {
      c = (char)tcSerial.read();
      if (fuesseCount >= 6 && punktCount == 0) //Zählt bis anzahl der füße erreicht.
      {
        inhalt[charCounter++] = c; // Schreibt jedes Zeichen einzellnd in das Char Array
      }
      inhalt[charCounter] = '\0';
      if (c == '"') fuesseCount++;  // Zählt ["]
      if (c == '.') punktCount++;   // Zählt [.]
      Serial.print(c);
      count++; // Erhöhe die Variable count um 1
    }
  }

Und mir dann charCounter seriel ausgeben lasse, dann steht da das charCounter auf 8 gesetzt wurde.
Obwohl Hallo1. nur 6 zeichen hat. Ich vermute, dass noch Enter mit in das Array geschrieben werden. Denn wenn ich bei:
inhalt[charCounter] = '0';
charCounter durch die Zahl 5 ersetze, erscheint nur hal, also 3 zeichen + die Null-Terminierung, aber es müssten ja eigentlich 4 zeichen + Null-Terminierung sein. Oder?

in der Seriellenausgabe sieht es wie folgt aus:

Bereit
AT+CMGF=1

OK
AT+CMGR=1

+CMGR: "REC READ","+4912345678910",,"19/07/20,21:41:06+08"
Hallo.

OK  
      
Hallo.     
8
Hallo.

Was willst du eigentlich genau auswerten? Es wird einfacher sein den kompletten String einzulesen und dann zu Parsen. Man kann z.B. mit strtok() an den Kommas teilen und dann mit einem die Teil-Strings weiterarbeiten. Oder mit strchr()/strrchr() nach einzelnen Zeichen suchen

Ich möchte die SMS die ich an das TC35 sende in das Array char inhalt[160] = "";
schreiben und dieses Array anschließend mit anderen Arrays vergleichen.
Wenn char inhalt[160] gleich dem Array char text1[] = "Hallo."; ist. Möchte ich eine Aktion ausführen. Mein Problem ist jetzt, dass das Array char inhalt[160] wohl erst noch mit einem "enter" beschrieben wird. Deswegen kann ich das nicht mit dem Array char text1[] vergleichen.

Im Moment wenn ich das array char inhalt[160] beschreibe schreibe ich da wohl eher
[
Enter
Hallo.
]

rein.

Ich bin jetzt mit dem Auswerten von dem an den Modul gesendeten Nachrichten erst mal so zu frieden, nun würde ich mich daran versuchen den Code nicht blockierend zu schreiben. Wenn ich es richtig verstanden habe, wäre es mit der Funktion Millis(); mach bar. Doch da gestaltet sich für mich folgendes Problem, wenn ich es richtig verstanden habe müsste ich mit millis alles in if funktionen verschachteln. Gibt es da einfachere Möglichkeiten, die ich nicht sehe?

Hier mein code:

//TC35 Siemens SMS Modul, erstes Testptrogramm.

#include <SoftwareSerial.h>
#define rxPin 9
#define txPin 8
SoftwareSerial tcSerial = SoftwareSerial(rxPin, txPin);
char text[] = "Es sind";
char nummer[] = "+4912345678910";
char inhalt[160] = "";
char c;
int fuesseCount = 0;
int punktCount = 0;
int charCounter = 0;
int count = 0;
char text1[] = "Hallo.";
int temperatur = 147;
uint32_t requestMillis = 0;
int16_t ConvWait = 1000;
//------------------------------------------------
void setup()
{
  pinMode(10, OUTPUT);
  tcSerial.begin(9600);
  Serial.begin(9600);
  //while (!Serial){}
  //tcSerial.begin(9600);
  digitalWrite(10, 0);
  delay(1000);
  digitalWrite(10, 1);
  delay(0000);
  Serial.println("Bereit");

}
//------------------------------------------------
void loop()
{
  LeseNachricht();
  if (strcmp(inhalt, text1) == 0)
  {
    Serial.println(inhalt);
    Serial.println("Sende diesen Text.");
    inhalt[charCounter] = '\0';
    NachrichtenLoeschen();
    Serial.println(charCounter);
    inhalt[0] = '\0';
    count = 0;
    SendeNachricht();
  }
  //Serial.println(inhalt);
  //ZeigeAusgabeModul();
  delay(5000);
}
//------------------------------------------------
void LeseNachricht()
{
  tcSerial.println("AT+CMGF=1"); // Setze Textmode auf 1
  delay(500);
  tcSerial.println("AT+CMGR=1"); // Lese erste Nachricht im Speicher SM
  delay(500);

  while (count == 0) // Loop bis count nicht mehr gleich 0.
  {
    charCounter = 0;
    fuesseCount = 0;
    punktCount = 0;
    while (tcSerial.available() > 0)// Wenn dort Daten sind dann lese sie.
    {
      c = (char)tcSerial.read();
      if (fuesseCount >= 6 && punktCount == 1) //Zählt bis anzahl der füße erreicht.
      {
        inhalt[charCounter++] = c; // Schreibt jedes Zeichen einzellnd in das Char Array
      }
      //inhalt[charCounter] = '\0';
      if (c == '"') fuesseCount++;  // Zählt ["]
      if (c == '.') punktCount++;   // Zählt [.]
      Serial.print(c);
      count++; // Erhöhe die Variable count um 1
    }
  }
  Serial.println(inhalt);
  Serial.println("hallo");
  NachrichtenLoeschen();
  //charCounter = 0;
  Serial.println(charCounter);
  count = 0;
}
//------------------------------------------------
void NachrichtenLoeschen()
{
  tcSerial.println("AT+CMGD=1"); // CMGD Löscht nachrichten.
  delay(1000);

}
//------------------------------------------------
void SendeNachricht()
{
  Serial.println("Sende Nachricht...");
  tcSerial.print("AT+CMGF=1\r"); // Setzt Textmode auf 1
  delay(1000);
  tcSerial.print("AT+CMGS=\""); // Setzt Nummer.
  tcSerial.print(nummer);
  tcSerial.print("\"\r");
  delay(1000);
  tcSerial.print(text);
  tcSerial.print(temperatur);
  delay(1000);
  tcSerial.print((char)26); // sendet CTRL+Z
  delay(1000);
}
//------------------------------------------------
void ZeigeAusgabeModul()
{
  while (tcSerial.available() > 0)
  {
    Serial.write(tcSerial.read());
  }
}
//------------------------------------------------
void Zeit()
{
  requestMillis = millis();
  if (millis() - requestMillis >= ConvWait)
  {


  }
}

Auch da gilt: werte das eigentliche Ende der Nachricht aus. Du bekommst am Anfang und am Ende ein CR + LF. Frage auf das LF ab. Nach dem zweiten LF ist Ende. Dann weißt du dass du fertig bist. Da nach dem Senden eine zeitlang zu warten ist völlig unnötig. Außerdem hängt diese Zeit von der Baudrate und der Anzahl der Zeichen ab und ist damit nicht konstant

Dann kann man bei jedem loop() Durchlauf abfragen ob was im seriellen Eingangspuffer ist. Wenn ja liest man das Zeichen aus. Wenn nein macht man nichts oder was anderes.
Hier ist ein einfaches Programm um was vom seriellen Monitor einzulesen bis ein LF kommt:
https://forum.arduino.cc/index.php?topic=622530.msg4217397#msg4217397

readLine() ist das relevante. Was in loop() steht ist größtenteils Auswertung. Da ist bei dir anders.
Und nicht von der while() Schleife verwirren lassen. i.d.R. wenn nichts blockiert wird nur ein Zeichen pro Aufruf ausgelesen. Deshalb muss man die Funktion in loop() ständig aufrufen

Man kann auch noch einen Zustands-Automaten bauen und zwischen Senden und Empfangen umschalten. Und dann nur Abfragen ob was da ist wenn man vorher was gesendet hat

Allgemein:
Verwende globale Variablen nur wenn wirklich nötig. Ansonsten lokale. Außerdem werden globale Variablen automatisch mit 0 initialisiert

Das mit den Globalen und Lokalen Variablen ist mir völlig fremd. Ich weiß, dass ich noch folgendes machen könnte, nur als Beispiel

:

void LeseNachricht(char inhalt[160] = "", char c, int charCounter, int punktCount, int fuesseCount)

{
  tcSerial.println("AT+CMGF=1"); // Setze Textmode auf 1
  delay(500);
  tcSerial.println("AT+CMGR=1"); // Lese erste Nachricht im Speicher SM
  delay(500);

  while (count == 0) // Loop bis count nicht mehr gleich 0.
  {
    
    charCounter = 0;
    fuesseCount = 0;
    punktCount = 0;
    //inhalt[charCounter] = '\0';
    while (tcSerial.available() > 0)// Wenn dort Daten sind dann lese sie.
    {
      c = (char)tcSerial.read();
      if (fuesseCount >= 2 && punktCount == 1) //Zählt bis anzahl der füße erreicht.
      {
        inhalt[charCounter++] = c; // Schreibt jedes Zeichen einzellnd in das Char Array
      }
      inhalt[charCounter] = '\0';
      if (c == '\n') fuesseCount++;  // Zählt ["]
      if (c == '.') punktCount++;   // Zählt [.]
      Serial.print(c);
      count++; // Erhöhe die Variable count um 1
    }
  }
  NachrichtenLoeschen();
  count = 0;

Dann könnte ich auch im loop mit der Methode LeseNachricht:

void loop()
{
 LeseNachricht( hier alle Variablen befüllen.);
}

Aber da bin ich dann mit der Syntac komplett überfordert. Ich beschäftige mich jetzt auch zum ersten mal mit dem Thema Programmierung.

Aber nur Beispiele abzuarbeiten, ist nichts für mich. Ich brauche zum lernen immer ein reales Problem.

Mit dem warten nach dem Senden eines AT befehles an das Modul, hatte ich das eigentlich so verstanden, dass das Modul eine gewisse Zeit braucht um den Befehl zu verarbeiten. Was sich für mich bis jetzt auch so gezeigt hatte, denn wenn ich die Befehle zu schnell sende, dann macht das Modul nichts mehr und in der seriellen Ausgabe kommen nur komische Zeichen. Deswegen denke ich schon, dass ich da was mit Zeiten machen muss.

Mit dem warten nach dem Senden eines AT befehles an das Modul, hatte ich das eigentlich so verstanden, dass das Modul eine gewisse Zeit braucht um den Befehl zu verarbeiten

Ja. Und die Übertragung selbst dauert auch etwas. Du brauchst 1 / Baudrate * 10 Sekunden pro Zeichen. Im Vergleich zur Geschwindigkeit des Prozessors ist das schon eine Ewigkeit. Das ist der Grund weshalb das normal nicht in einer while-Schleife geht. Die würde ein Zeichen einlesen und dann sofort abbrechen weil das nächste noch unterwegs ist.

Das mit dem Delay ist daher nicht grundlegend falsch. Dadurch wartet man einfach und kann so sicher sein dass die komplette Nachricht da ist. Grob geht das. Aber wenn du nicht-blockierend arbeiten willst, muss man es anders machen. Das die Nachrichten mit einem Endzeichen abgeschlossen werden hat schon seinen Grund.
Hier man muss man halt noch beachten dass am Anfang auch CR+LF kommt. Das kann man aber ähnlich wie du es schon gemacht hast mitzählen

Was sich für mich bis jetzt auch so gezeigt hatte, denn wenn ich die Befehle zu schnell sende, dann macht das Modul nichts mehr und in der seriellen Ausgabe kommen nur komische Zeichen.

Auch deshalb die Anmerkung mit dem Zustands-Automaten. So dass man erst das nächste Kommando sendet wenn die Antwort des vorherigen abgearbeitet ist

Insgesamt ist das nicht das einfachste Anfänger-Projekt. Da muss man schon einige Feinheiten beachten. Auch wenn man sich etwas auskennt

Ahh okay, also wenn ich dich richtig verstanden habe, könnte ich einfach die wie du schon sagtest LF mit

if ( c == '\n') LFZaehler++;

zählen und einfach jeden nächsten Schritt mit z.b.

if (LFZaehler == 0)

{
Tu das
}

if (LFZaehler == 1;

{
tu das
}

abarbeiten und den LFZaehler mit dem letzten Schritt wieder auf 0 setzen, oder?

Na, ja. Nicht ganz. Eine Antwort sieht laut Anleitung so aus:
Text

Das solltest du auch im seriellen Monitor sehen. Das CR macht da nichts, aber das LF erzeugt eine Leerzeile.
Du musst also die Linefeeds zählen und beim zweiten hast du das Ende.

Vorausgesetzt ich habe dich jetzt richtig verstanden, habe ich hier jetzt ein kleinen testcode geschrieben.

// Software Serial test Sketch für TC35 SMS Modul.

#include <SoftwareSerial.h>
#define rxPin 9
#define txPin 8
SoftwareSerial tcSerial = SoftwareSerial(rxPin, txPin);

int counter = 0;

void setup()
{
  pinMode(10, OUTPUT);
  Serial.begin(9600);
  tcSerial.begin(9600);
  digitalWrite(10, 0);
  delay(1000);
  digitalWrite(10, 1);
  delay(500);
  tcSerial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.println("Bereit!");
}

void loop()
{
  while (tcSerial.available() > 0)
  {
    Serial.write(tcSerial.read());
    char c;
    c = (char)tcSerial.read();
    if (c == '\n') counter++;
    if (counter == 0)
    {
      tcSerial.println("AT+CMGR=1");
    }

  }
  Serial.println(counter);
  delay(5000);
}

Dazu kommt dann hier die Serielleausgabe am Monitor

3
3
3
3
3
3
3
3
3
3
3Bereit!
A+MF1
ERR
1
A+MR1A+MR1A+MR1
RO
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2
2

Was mich hier jetzt noch mehr verwirrt als die Tatsache dass, das was ich ausprobieren wollte nicht zu funktionieren scheint, ist dass schon vor das verlassen des Setups in dem int counter wohl eine 3 drinne steht. Uns später eine 2 obwohl nirgendwo was subtrahiert wird.

Nun ja ich hatte da gehofft, so lange in der If funktion zu bleiben, bis eine Antwort von dem Modul zurück kommt. Aber es kommen wie davor auch ohne delay komische Zeichen irgendwas muss ich da noch startk missverstehen.

Das obere Phonemen scheint wohl andere Ursachen zu haben, die ich nicht mehr reproduziert bekomme.

Mit dem folgenden Code

// Software Serial test Sketch für TC35 SMS Modul.
#include <SoftwareSerial.h>
#define rxPin 9
#define txPin 8
SoftwareSerial tcSerial = SoftwareSerial(rxPin, txPin);
int Counter = 0;
int testCounter = 0;
void setup()
{
  pinMode(10, OUTPUT);
  Serial.begin(9600);
  tcSerial.begin(9600);
  digitalWrite(10, 0);
  delay(1000);
  digitalWrite(10, 1);
  delay(500);
  //tcSerial.print("AT+CMGF=1\r\n");
  delay(500);
  Serial.println("Bereit!");
  delay(5000);
}
void loop()
{ 
  if (Counter == 0 && testCounter == 0)
  {
    //tcSerial.println("AT+CMGR=1");
    tcSerial.println("AT+CMGF=1");
    //Serial.println("Okay...");
    testCounter++;
  } 
  while (tcSerial.available() > 0)
  {
    Serial.write(tcSerial.read());
    char c;
    c = (char)tcSerial.read();
    if (c == '\n') Counter++;


  }
  Serial.println(Counter);
  delay(5000);
}

Sieht die Serielle Ausgabe nun so aus.

Bereit!
0
A+MF1
O
2
2
2
2
2
2
2
2
2

Wobei es bei dem gesendeten AT - Befehl so aussieht, als würde beim Senden des Befehls nun jedes zweite Zeichen fehlen.
Was auch erstmal egal wäre, da das "O" das Teil vom "OK" sein wird. Also wenn ich das so weiter führe könnte es funktionieren, es wäre allerdings nur nicht so schön. Und so macht es ja auch wenig Sinn für weiterführende Probleme / Anwendungen oder sonstiges, wenn ich nicht feststelle warum es so ist und es gegebenenfalls auch löse.

Hmm, wenn ich die Zeilen:
Serial.println(Counter);
delay(5000);

weg lasse, dann kommt alles normal bei dem Seriellen monitor.

Bereit!
AT+CMGF=1

OK

Kann mir das einer erklären? Ich verstehe nicht warum die Ausgabe im seriellen Monitor von mir außerhalb der Schleifen so eine Wirkung haben sollte.
Oder ist es wirklich weil nahe zu direkt im gleichen Moment wo die If bedingung wahr wird das dann meine Ausgabe dafür sorgt das die Daten ein bisschen zusammen gewürfelt werden?

  Serial.write(tcSerial.read());
    char c;
    c = (char)tcSerial.read();
    if (c == '\n') Counter++;

Das ist Unsinn. Damit liest du zwei Zeichen aus und eines wird zwar ausgegeben aber nicht überprüft

Also meinst du eher so:

Serial.write(tcSerial.read());
    char c;
    c =tcSerial.read();
    if (c == '\n') Counter++;

Also ohne (char) bei c=tcSerial.read(); sonst kann ich dir gar nicht mehr folgen.

Oder meinst du, dass ich mit

If (c =='\n') Counter++;

Den Counter um 2 erhöhen muss weil es im prinzip 2 zeichen sind?

Du machst zweimal read(). Da ist doch klar dass ja jedes zweite Zeichen anders behandelt wird

Danke Serenifly,

war mein Fehler im ursprungscode hatte ich

c = tcSerial.read();

durch

Serial.print(c);

getauscht.

Aber beim schreiben des testscetches nicht mehr daran gedacht.

Wenn ich mein Scetch jetzt auf einem NodeMCU laden möchte,
hatte ich gelesen, dass ich mir eine andere SoftwareSerial Librarie runterladen muss.
Diese hat allerdings den selben Namen wie die originale von Arduino.
Reicht es wenn ich diese nur umbennene oder muss ich da noch andere Sachen beachten?

Hier findet man die besagte SoftwareSerial librarie.

Du hast 2 grundlegende Wege:

  1. die alte Lib löschen/verschieben
  2. für die Arbeit mit dem ESP zusätzlich eine eigene portable Version der IDE benutzen.

Gruß Tommy

Tommy56:
Du hast 2 grundlegende Wege:

  1. die alte Lib löschen/verschieben
  2. für die Arbeit mit dem ESP zusätzlich eine eigene portable Version der IDE benutzen.

Gruß Tommy

Okay, das mit dem verschieben funktioniert schon mal, dann gucke ich morgen mal dabei eine portable Version zu machen, ist glaube für die Zukunft dann einfacherer. Vielen dank.

Weiters könntest du:

  1. die Dateien der weitere Lib lokal im Sketch speichern und lokal einbinden
  2. die weitere Lib runterladen und einen anderen Namen geben

TEIL 1 von 2.

Vielen dank, mit der portablen Version funktioniert es auch.

Da ich jedoch gerne beim Arduino Nano bleiben würde, hätte ich noch eine Frage.

Ich habe jetzt 2 Sketche, einmal diesen hier:

#include <NewPing.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <SoftwareSerial.h>
#define rxPin 9
#define txPin 8
#define ONE_WIRE_BUS 
#define TRIG_PIN 3
#define ECHO_PIN 4
#define MAX_DIST 400
SoftwareSerial tcSerial = SoftwareSerial(rxPin, txPin);
OneWire oneWire(9);
DallasTemperature sensors (&oneWire);
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DIST);
uint32_t requestMillis = 0;
bool requestStarted = false;
uint8_t bitResolution = 12;
int16_t ConvWait = 750;
char fuellstand[15] = "\nFuellstand?";
char tempTemp[15] = "\nTemperatur?";
char nummer[20] = "+49xxxxxxxxx";
char inhalt[160] = "";
char smsErhalten[3] = "";
char c;
float platzhalter = 0;
float temp = 0;
float abstand = 0;
int fuesseCount = 0;
int lnCount = 0;
int charCounter = 0;
int count = 0;
//----------------------------------------------------------------------------------------------------------------------------------------------------------
void setup()
{
  pinMode(10, OUTPUT);
  tcSerial.begin(9600);
  Serial.begin(9600);
  while (!Serial) {}
  digitalWrite(10, 0);
  delay(1000);
  digitalWrite(10, 1);
  delay(3000);
  tcSerial.println(F("AT+CMGF=1")); // Setze Textmode auf 1
  delay(1000);  
  tcSerial.println(F("AT+CMGD=1")); // CMGD Löscht nachrichten.
  delay(5000);
  Serial.println(F("Bereit"));
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------
void loop()
{ 
  abstand = sonar.ping_cm(); 
  if (!requestStarted)
  {
    sensors.requestTemperatures();
    requestStarted = true;
    requestMillis = millis();
  }
  if (millis() - requestMillis >= ConvWait)
  {
    temp = sensors.getTempCByIndex(0);
    requestStarted = false;   
  }
  LeseNachricht();
  if (strcmp(inhalt, fuellstand) == 0) // Wenn inhalt = char Array fuellstand dann mache:
  {
    platzhalter = abstand*25;
    Serial.println(F("Sende Nachricht mit aktuellen Wert des Fuellstandes."));
    NachrichtenLoeschen();
    NachrichtenLoeschen();
    Serial.println(F("Sende Nachricht..."));
    tcSerial.print(F("AT+CMGS=\"")); // AT-Befehl für Nummer.
    tcSerial.print(nummer); // Gibt Nummer weiter an den AT-Befehl.
    tcSerial.print(F("\"\r")); // Sendet ein Enter.
    delay(1000);
    tcSerial.print(F("Der Fuellstand liegt bei")); // Übergibt zu sendenden Text an das Modul.
    tcSerial.print(platzhalter); // Übergibt den Platzhalter an das Modul.
    tcSerial.print(F("Liter"));
    delay(1000);
    tcSerial.print((char)26); // sendet CTRL+Z
    delay(5000); 
  }
  else if (strcmp(inhalt, tempTemp) == 0) // Wenn inhalt = char Array tempTemp dann mache:
  {  
    Serial.println(F("Sende Nachricht mit aktuellen Wert der Temperatur."));
    platzhalter = temp;
    NachrichtenLoeschen();
    NachrichtenLoeschen();
    Serial.println(F("Sende Nachricht..."));
    tcSerial.print(F("AT+CMGS=\"")); // AT-Befehl für Nummer.
    tcSerial.print(nummer); // Gibt Nummer weiter an den AT-Befehl.
    tcSerial.print(F("\"\r")); // Sendet ein Enter.
    delay(1000);
    tcSerial.print(F("Die Temperatur liegt bei:")); // Übergibt zu sendenden Text an das Modul.
    tcSerial.print(platzhalter); // Übergibt den Platzhalter an das Modul.
    tcSerial.print(F("Grad Celsius"));
    delay(1000);
    tcSerial.print((char)26); // sendet CTRL+Z
    delay(5000);
  }
  else if (strcmp(inhalt, smsErhalten) != 0) // Wenn inhalt != smsErhalten dann mache:
  {
    Serial.println(F("Hier ist noch ein Fehler"));
    platzhalter = 0;
    NachrichtenLoeschen();
    NachrichtenLoeschen();
    Serial.println(F("Sende Nachricht..."));
    tcSerial.print(F("AT+CMGS=\"")); // AT-Befehl für Nummer.
    tcSerial.print(nummer); // Gibt Nummer weiter an den AT-Befehl.
    tcSerial.print(F("\"\r")); // Sendet ein Enter.
    delay(1000);
    tcSerial.print(F("Sende Fuellstand? fuer den aktuellen Wert des Fuellstandes, oder Temperatur? fuer den aktuellen Wert der Temperatur.")); // Übergibt zu sendenden Text an das Modul.
    delay(1000);
    tcSerial.print((char)26); // sendet CTRL+Z
    delay(5000);   
  }
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------
void LeseNachricht()
{
  tcSerial.println(F("AT+CMGR=1")); // Lese erste Nachricht im Speicher SM
  delay(750);
  while (count == 0) // Loop bis count nicht mehr gleich 0.
  {
    charCounter = 0;
    fuesseCount = 0;
    lnCount = 0;
    while (tcSerial.available() > 0)// Wenn dort Daten sind dann lese sie.
    {
      c = tcSerial.read();
      if (fuesseCount >= 6) //Zählt bis anzahl der '"' erreicht.
      {
        inhalt[charCounter] = '\0';
        if (c == '\n') lnCount++; // Zählt [\n].
        if (lnCount == 1 && lnCount != 2)
        {
          inhalt[charCounter++] = c; // Schreibt jedes Zeichen einzellnd in das Char Array
        }   
      }
      inhalt[charCounter] = '\0';
      if (c == '"') fuesseCount++;  // Zählt ["]
      Serial.print(c);
      count++; // Erhöhe die Variable count um 1
    }
  }
  Serial.println(inhalt); // 
  Serial.println(charCounter);
  Serial.println(lnCount);
  count = 0;
}
//----------------------------------------------------------------------------------------------------------------------------------------------------------
void NachrichtenLoeschen()
{
  tcSerial.println(F("AT+CMGD=1")); // CMGD Löscht nachrichten.
  delay(1000);
}

Da habe ich nach dem kompilieren noch 487 bytes freien dynamischen Speicher. Dafür wird der Teil
void loop relativ lang und meiner Meinung nach unübersichtlich.