Go Down

Topic: Arduino Nano SIm800L Modul String setzen und vergleichen. (Read 574 times) previous topic - next topic

GastAnfaenger0815

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.


 
Code: [Select]
#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");
  }
}

Tommy56

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
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

GastAnfaenger0815

#2
Jul 16, 2019, 07:24 pm Last Edit: Jul 16, 2019, 08:12 pm by GastAnfaenger0815
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.

Code: [Select]
AT+CMGR=1

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

OK




Im Internet fand ich dann noch folgendes:

Code: [Select]

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?

Tommy56

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:
Code: [Select]

+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.
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

GastAnfaenger0815

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.   

Tommy56

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
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

GastAnfaenger0815

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.

GastAnfaenger0815

#7
Jul 18, 2019, 05:55 pm Last Edit: Jul 18, 2019, 06:09 pm by GastAnfaenger0815
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.

Code: [Select]
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.

Code: [Select]
//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.

Tommy56

"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

GastAnfaenger0815

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.

Code: [Select]
  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.

Serenifly

Code: [Select]

char Temp = "a";

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

GastAnfaenger0815

#11
Jul 20, 2019, 08:51 pm Last Edit: Jul 20, 2019, 08:55 pm by GastAnfaenger0815
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.
Code: [Select]
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:


Code: [Select]
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:


Code: [Select]
//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());
  }
}

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

GastAnfaenger0815

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?

Tommy56

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
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Go Up