Arduino Nano SIm800L Modul String setzen und vergleichen.

Hallo liebe Gemeinde,
das ist meine erste Spielerei mit dem Arduino, und zwar folgends.

Ich habe das Sim800L Modul und möchte damit, wenn ich einen bestimmten Text bekomme, eine SMS an mich senden. Die Library benutze ich. Die Beispiel sketche funktionieren ohne Probleme. Das Lesen und das Schreiben von SMS'se kriege ich hin. Nun möchte ich aber den Inhalt der SMS die ich lese mit einem Text z.b. "Temp" vergleichen um dann zum testen eine Temperatur an mich zu senden. Die zu sendende Temperatur simuliere ich zunächst nur mit einem Text der mir gesendet wird sobald ich eine SMS mit dem Inhalt "Temp" an das Modul sende. Leider weiß ich allerdings nicht, wie ich Strings mit anderen Variablen oder Inhalten vergleichen kann. Über Hilfe wäre ich sehr dankbar.

Hier noch mein Aktueller Code, so wie ich es da versucht habe, wird mir nie eine SMS gesendet. Ich denke mal das ich da was grundlegendes falsch verstehe.
Wenn noch weitere Informationen benötigt werden, werde ich diese selbst verständlich noch zu Verfügung stellen. Solltet ihr Librarys kenne, mit dem mein Vorhaben leichter zu realisieren ist, kann ich mir auch vorstellen umzusteigen.

#include <Sim800l.h>
#include <SoftwareSerial.h> //is necesary for the library!!

Sim800l Sim800l;  //to declare the library
String text;     // to storage the text of the sms
uint8_t index;   // to indicate the message to read.
char Temp = "a";

void setup(){
	Serial.begin(9600); // only for debug the results . 
	Sim800l.begin(); // initializate the library. 
	index=1; // first position in the prefered memory storage. 
	text=Sim800l.readSms(index);   	
	Serial.println(text);
  Sim800l.delAllSms();
}

void loop(){
  text=Sim800l.readSms(index);    
  Serial.println(text);
  Sim800l.delAllSms();
  if (text == "a"){
    Serial.println("Hallo");
    Sim800l.sendSms("Meine Nummer xxxxxxxxxxxxxx","the text go here");
  }
}

Auf dem Aeduino Nano/MEGA/UNO solltest Du Dir Gebrauch der Klasse String abgewöhnen, wenn Du länger Gefallen daran haben willst. Verwende stattdessen char-Arrays. Infos dazu gibt es hier.

Zum Vergleich nutze strcmp oder strncmp.

Gruß Tommy

Vielen Dank für deine Antwort, ich werde mir das mal genauer angucken.
Ich habe grade noch festgestellt, wenn ich eine SMS an das Modul sende, dann wird wohl nicht nur der Text den ich gesendet habe an den String übergeben. Sonder noch weitere Daten.
Hier die Serielle Ausgabe nach dem Senden einer sms Empfangen einer SMS am Sim800L Modul.

AT+CMGR=1

+CMGR: "REC UNREAD","+49176xxxxxxxx","","19/07/16,19:22:38+08"
temp

OK

Im Internet fand ich dann noch folgendes:

at+cmgr=x Auslesen der mit x angegebenen Kurznachricht aus dem mit +CPMS eingestellten 
                        Speicherbereich. Die Nachrichten werden im folgenden Format ausgegeben:
                        +CMGL: index, status, length
                        .......PDU.......
at+cmgr=? Zeigt an, welcher Bereich für x im gewählten Speicher unterstützt wird

Was wäre da der einfachste Weg, den von mir gesendeten von dem Rest der Daten zu trennen?

Das wirst Du doch wohl auf dem Empfangsgerät tun müssen.
Wie sieht die SMS denn da aus?

Welche SMS meinst Du denn nun? Die, Die Du auf dem SIM800 empfängst oder die, die Du sendest?
Mit den AT-Befehlen habe ich mich noch nicht beschäftigt, Deine Serielle Ausgabe passt aber nicht zu Deiner gefundenen Beschreibung.

Gruß Tommy

Edit:
Ich würde vermuten, Der Aufbau bedeutet:

+CMGR: "REC UNREAD" --> Kommandoantwort + Zustand (unread)
"+49176xxxxxxxx" --> Absendernummer
"" --> Inhalt (leer)
"19/07/16,19:22:38+08" --> Datum/Uhrzeit und Zeitzone

Das könnte man über strtok aufspalten und weiterverarbeiten. Da wäre aber ein Empfang mit Inhalt sinnvoll.

Sorry, hatte mich da wohl missverständlich ausgedrückt, das was ich in Code Tags gesetzt hatte, war die Ausgabe von "text" nach dem das sms Modul eine SMS von mir mit dem Inhalt "temp" empfangen hat. Leider kenne ich mich mit dem SMS Modul nicht so gut aus, aber ich habe noch das gefunden

At Befehl für Textmode.
Da ist noch eine andere Verarbeitung des Sendens beschrieben. Ich weiß allerdings nicht, ob das auch das Empfangen von SMS beeinflusst.

Wenn ich die Lib die ich benutze richtig interpretiere unterstützt diese allerdings kein Textmode. Werde es aber jetzt erstmal gucken ob ich das ausprobieren kann. Hatte mir auch schon überlegt eigene Funktionen für die AT Kommandos zu schreiben um unabhängig von der Lib zu werden. Werde mich dafür aber erstmal ein wenig mehr in die Materie einarbeiten müssen.

Der Inhalt "temp" ist aber in der Ausgabe nicht sichtbar. Da musst Du erst mal checken, was da noch nicht passt. Bei der SMS-Problematik kann ich Dir nicht helfen, bei der Aufbereitung des Char-Arrays dann wieder.

Gruß Tommy

Ich dachte das wäre so richtig, da das "temp" kommt sobald ich eine SMS an das Modul sende. Was mich verwirrt hatte, waren die Infos dazu. Aber deine Aufdröselung der Daten klingt schlüssig. Dann mache ich mich jetzt erstmal daran mich mehr in das Modul und in der Kommunikation zwischen dem Modul und dem Arduino rein zu arbeiten. Vielen Dank erstmal.

Ich bin aus kosmetischen Gründen jetzt auf dem TC35 von Siemens umgestiegen. Und habe versucht alles in Char Variablen um zu ändern. Und meine eigenen Funktionen für die Kommunikation zwischen Modul und Arduino zu gestalten. Wenn ich meine Nummer nun versuche in ein char array zu packen kommt folgendes.

TC35_Test1:38:32: error: invalid operands of types 'const char [10]' and 'char [15]' to binary 'operator+'

   tcSerial.print("At+CMGS=\""+ nummer +"\"\r");

                                ^

exit status 1
invalid operands of types 'const char [10]' and 'char [15]' to binary 'operator+'

Mein Code sieht bis jetzt wie folgt aus.

//TC35 Siemens SMS Modul, erstes Testptrogramm.

#include <SoftwareSerial.h>
#define rxPin 9
#define txPin 8
SoftwareSerial tcSerial = SoftwareSerial(rxPin, txPin);
char text[] = "Test Test Test";
char nummer[] = "+4912345678910"; // Ziffern stimmen mit Anzahl der Zielnummer überein. 


void setup()
{
pinMode(10,OUTPUT);  
Serial.begin(9600);  
while (!Serial){}  
tcSerial.begin(9600); 
digitalWrite(10,0);
delay(1000); 
digitalWrite(10,1);
Serial.println("Ready"); 
}

void loop() {
  SendeNachricht();
  ShowSerialData();
  delay(500000);
}
void LeseNachricht()
{
  
  
}
void SendeNachricht() 
{
  Serial.println("Sende Nachricht...");
  tcSerial.println("AT+CMGF=1\r");
  delay(500);
  tcSerial.print("At+CMGS=\""+ nummer +"\"\r");
  delay(500);
  tcSerial.print(text);
  delay(500);
  tcSerial.println((char)26);
  delay(500);
}


void ShowSerialData() {
  while (tcSerial.available() > 0) {
    Serial.write(tcSerial.read());
  }
}

Wenn ich die Nummer wieder in ein String packe, dann funktioniert es. Und ich kriege die SMS geschickt, die in char text[] steckt. Jedoch möchte ich das mit den Char Arrays richtig verstehen.

Dann schaue mal hier rein.

Gruß Tommy

Hmm, war mein Fehler das mit dem Char Array war richtig, ich bin wohl nur zu blöd die Serielle Kommunikation zu benutzen. Wenn ich das wie folgt gestalte funktioniert es auch mit dem Char Array.

  tcSerial.print("AT+CMGS=\"");
  tcSerial.print(nummer);
  tcSerial.print("\"\r");

Dann versuche ich mich jetzt mal daran, die SMS die das Modul von mir bekommt zu lesen und zu verarbeiten.

Vielen Dank soweit.

char Temp = "a";

'a' ist ein Zeichen. "a" ist ein String. Das ist ein riesiger Unterschied

Guten Abend, erst einmal vielen Dank für die Hilfe bis jetzt.
Da das auslesen einer Nachricht vom Modul in der Seriellenausgebe so aussieht:

+CMGR: "SMS Status","Nummer",,"RTC"
Text

Dachte ich mir, ich könnte die " zählen, bis der Text kommt. das wären 6 Stück.
Desweiteren hatte ich mir gedacht eine SMS immer mit einem Punkt zu beenden.
Und das zählen der Zeichen für c damit zu beenden.

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
      }
      if (c == '"') fuesseCount++;  // Zählt ["]
      if (c == '.') punktCount++;   // Zählt [.]
      Serial.print(c);
      count++; // Erhöhe die Variable count um 1
    }
  }

Mein Problem ist jetzt, ich kriege im Serielmonitur das ausgegeben für das Array char inhalt[160] = "";

Hallo.

Wenn ich das aber nun mit dem Array char text1[] = "Hallo.";

vergleichen möchte, dann habe ich absolut keine Ahnung wie das funktioniert. mit der If abfrage:

if (inhalt == text1)
  {
    Serial.println("Sende diesen Text.");
  }

geht es nicht. Könnte mir diesbezüglich noch mal Jemand den ein oder anderen Tipp geben?

Mein ganzer code sieht so aus:

//TC35 Siemens SMS Modul, erstes Testptrogramm.

#include <SoftwareSerial.h>
#define rxPin 9
#define txPin 8
SoftwareSerial tcSerial = SoftwareSerial(rxPin, txPin);
char text[] = "Test Test Test";
char nummer[] = "+4912345678910";
char inhalt[160] = "";
char c;
int fuesseCount = 0;
int punktCount = 0;
int charCounter = 0;
int count = 0;
char text1[] = "Hallo.";
//------------------------------------------------
void setup()
{
  pinMode(10, OUTPUT);
  tcSerial.begin(9600);
  Serial.begin(9600);
  //while (!Serial){}
  //tcSerial.begin(9600);
  digitalWrite(10, 0);
  delay(1000);
  digitalWrite(10, 1);
  Serial.println("Bereit");
}
//------------------------------------------------
void loop()
{
  //SendeNachricht();
  //NachrichtenLoeschen();
  LeseNachricht();
  if (inhalt == text1)
  {
    Serial.println("Sende diesen Text.");
  }
  
  //ZeigeAusgabeModul();
  delay(5000);
}
//------------------------------------------------
void LeseNachricht()
{
  tcSerial.println("AT+CMGF=1"); // Setze Teextmode 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.
  {
    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
      }
      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(charCounter);
  count = 0;
}
//------------------------------------------------
void NachrichtenLoeschen()
{
  tcSerial.print("AT+CMGD=4\r"); // CMGD Löscht nachrichten.
  delay(500);

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

Du kannst char Arrays nicht mit == vergleichen. Char Arrays zerfallen zu Zeigern auf das erste Element. Damit vergleicht du nur Zeiger, was immer schief läuft

Dafür gibt es strcmp() (string compare):
http://www.cplusplus.com/reference/cstring/strcmp/

Außerdem darfst du beim Einlesen nicht die Null-Terminierung vergessen. C Strings müssen am Ende ein NULL/0/'\0' haben damit die Verarbeitung korrekt funktioniert. Das geht zufällig weil globale Variablen mit 0 initialisiert werden. Aber auch nur bis mal ein kürzerer String kommt

Serenifly:
Du kannst char Arrays nicht mit == vergleichen. Char Arrays zerfallen zu Zeigern auf das erste Element. Damit vergleicht du nur Zeiger, was immer schief läuft

Dafür gibt es strcmp() (string compare):
http://www.cplusplus.com/reference/cstring/strcmp/

Außerdem darfst du beim Einlesen nicht die Null-Terminierung vergessen. C Strings müssen am Ende ein NULL/0/'\0' haben damit die Verarbeitung korrekt funktioniert. Das geht zufällig weil globale Variablen mit 0 initialisiert werden. Aber auch nur bis mal ein kürzerer String kommt

Vielen Dank.
Ich hatte vorher das hier gefunden daraus wurde ich aber nicht wirklich schlau. Bei deinem Link ist es viel besser erklärt. Was du mit Null-Terminierung meinst kann ich mir nicht wirklich vorstellen grade. Ich dachte wenn ich das Array mit char variable[] = "Text"; initialisieren lasse, dass die Null-Terminierung am Ende automatisch kommt. Oder meinst du in dem Moment wo ich mir den Inhalt für das Array char beispiel[] = ""; selbst irngedwo her hole?

Wenn Du char variable[] = "Text"; benutzt, wird die '\0' automatsch angehängt.
Wenn Du es Zeichenweise einliest, must Du es selbst anhängen, wenn Du das Ende der Übertrsagung erkannt hast.
Das kann z.B. ein NewLine sein.

Gruß Tommy

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)
  {


  }
}