SIM800L Modul

Über den Beitrag

Das SIM800L Modul ermöglicht es euch im Prinzip ein Mobiltelefon zu bauen, das ihr mit eurem Mikrocontroller steuern könnt. Der Funktionsumfang ist riesig. Die meisten von euch sind sicherlich vorrangig an SMS und Telefonie interessiert, um beispielsweise Daten in WLAN-freien Zonen zu übertragen. Es gibt aber noch vieles darüber hinaus, wie z.B. FTP, TCP/IP und HTTP Anwendungen, E-Mail, oder MMS. Man könnte ein ganzes Buch über das SIM800L Modul schreiben.

Da ich mich hier etwas beschränken muss, konzentriere ich mich auf die folgenden Themen:

Technische Eigenschaften

Das SIM800L ist ein Quadband GSM / GRPS Modul. Es deckt die Frequenzbänder GSM850, EGSM900, DCS1800 und PCS1900 ab. Um das SIM800L nutzen zu können, benötigt ihr eine 2G SIM-Karte im Mikroformat. Die Kommunikation eures Mikrocontrollers mit dem SIM800L erfolgt seriell über RX / TX und AT-Befehle.

Der Bereich für die Spannungsversorgung beträgt ungewöhnliche 3.4 bis 4.4 Volt. Deshalb, und aufgrund von Stromspitzen bis zu 2 Ampere, ist eine Spannungsversorgung über den Mikrocontroller nicht möglich. Geeignet sind Lithium-Ionen-Akkus, oder ihr setzt Schaltregler wie den LM2596 ein. Für Schaltregler braucht ihr dann aber auch ein Netzteil, das ausreichend Strom liefert.

Pinout des SIM800L Moduls
Pinout des SIM800L Moduls

Das SIM800L Modul hat die folgenden Anschlüsse:

  • Antennenanschluss (IPX U.FL, oben links / unbeschriftet).
  • NET: Antennenanschluss für Spiralantennen.
  • VCC: Spannungsversorgung (3.4 – 4.4 Volt).
  • RESET: LOW-aktiv, könnt ihr auch unverbunden lassen.
  • RX/TX: serielle Anschlüsse, Baudrate: 1200 – 115200 bps.
  • GND: zu verbinden mit GND der Spannungsversorgung und GND des Mikrocontrollers.
  • RING: standardmäßig HIGH, geht kurz auf LOW bei Eingang eines Anrufes oder einer SMS; nützlich für Interruptprogrammierung.
  • DTR: darüber steuert ihr Schlafmodi.
  • MIC+/MIC-: Mikrofonanschluss.
  • Speaker+/-: hier könnt ihr direkt 8-Ohm-Lautsprecher anschließen und erhaltet „satte“ 1.08 Watt.

RX / TX Spannungslevel

Über das zulässige Spannungslevel der seriellen Anschlüsse des SIM800L liest man Widersprüchliches. Einige bescheinigen 5V Toleranz, einige andere sehen die Grenze bei 3.3 Volt. Laut Datenblatt liegt das Maximum hingegen bei 2.8 Volt. Dort ist auch beschrieben, wie man 3.3 Volt und 5 Volt Mikrocontroller idealerweise verbinden sollte (ab Seite 31). Ich habe lediglich einen Spannungsteiler vor RX des Moduls gesetzt und bin damit gut gefahren.

Antennen für das SIM800L Modul

Antennen und  Antennenadapter für das SIM800L Modul
Antennen und Antennenadapter für das SIM800L Modul
SIM800L Modul mit Spiralantenne

Das SIM800L Modul wird meistens mit einer oder mit mehreren Antennen angeboten. In vielen Fällen werdet ihr mit der einfachen Spiralantenne auskommen. In Gebieten mit schlechter Abdeckung, bei Störsignalen oder in abgeschirmten Gebäuden benötigt ihr unter Umständen eine größere Antenne.

Man könnte auch auf den Gedanken kommen, zwei Antennen anzuschließen. Das ist jedoch kontraproduktiv, da sie sich gegenseitig stören.

Wenn ihr euch eine Antenne mit SMA Anschluss besorgt (das ist der mit dem Schraubgewinde), dann benötigt ihr noch einen IPX UF.L auf SMA Adapter.

Stromverbrauch

Typische Verbrauchswerte sind:

  • Power Down Mode: 60 µA
  • Sleep Mode: 0.7 – 1.0 mA
  • Normal Mode: (Warten auf SMS oder Call): ca. 15 mA

Wie viel das SIM800L Modul während eines Telefonates oder bei der Datenübertragung per GRPS verbraucht, ist nicht so leicht zu beantworten, da sich kein konstanter Wert einstellt. Ich habe hier ziemlich konkrete Angaben gefunden (131 – 216 mA, je nach Frequenzband), konnte sie aber in eigenen Messungen nicht nachvollziehen. Bei mir lagen die Werte eher bei 70 mA, allerdings mit Spitzen.

Zu Beginn einer Verbindung können, wie oben schon erwähnt, Spitzen von bis zu 2 Ampere auftreten.

Anmerkungen zur SIM-Karte

How to put the SIM card into the SIM800L

Die SIM-Karte wird, wie rechts abgebildet, in den Kartenhalter gesteckt.

Ich kann euch nicht sagen, welches die ideale SIM-Karte für euch ist. Das hängt zu sehr von eurer Anwendung ab, also hauptsächlich von der zu erwartenden Frequenz an SMS oder Anrufen.

Aber ich möchte eine Erfahrung mit euch teilen. Und zwar hatte ich mir eine „IoT und M2M Prepaid“ Karte besorgt, weil das so schön passend klang. Nur leider hatte die Karte eine „+882“ Vorwahl, was für „Internationale Netzwerke“ steht. Diese Nummer ist von vielen Mobilfunkanbietern gesperrt, weil darüber auch Betrugsanrufe laufen. Außerdem kann eine Verbindung mit dieser Vorwahl hohe Kosten erzeugen. Telefonieren ging also nicht ohne Weiteres und SMS konnte ich nur vom, aber nicht zum Modul versenden. Ich habe mir dann eine andere SIM-Karte von der guten, alten Telekom besorgt. Schaut also genau hin.

Und seid vorsichtig, wenn ihr Programme zum Versenden von SMS erstellt, dass ihr nicht aus Versehen Massen davon verschickt. Bestenfalls habt ihr eine Prepaid Karte, die dann auf null gezogen ist.

Schaltung für das SIM800L Modul

So sah die von mir verwendete Basisschaltung aus:

SIM800L am Arduino Nano
SIM800L am Arduino Nano

Beachtet, dass RX des Moduls mit TX des Mikrocontrollers und TX des Moduls mit RX des Microcontrollers verbunden wird.

Für die obige Schaltung ist die Spannung an RX des Moduls:

V_{RX}=\frac{5.6}{5.6+4.7}\cdot 5.0\;=\;\sim 2.72\;[\text{V}]

Kommunikation über AT-Befehle

Der eine oder andere von euch kennt AT-Befehle vielleicht schon von den HC05 / HC06 Bluetooth Modulen oder anderen seriell gesteuerten Bauteilen. Die meisten AT-Befehle haben die Struktur (Ausnahmen bestätigen die Regel!):

  • AT+xxxx: Funktionsaufruf oder Abfrage ohne Parameter
  • AT+xxxx=yyyy: Zuweisung des Wertes yyyy zur Eigenschaft / Funktion xxxx
  • AT+xxxx?: Abfrage des Wertes xxxx
  • AT+xxxx=? Abfrage der Optionen

Eine Liste mit den vielen AT-Befehlen des SIM800L Moduls bekommt ihr hier. Es gibt alleine in diesem Dokument über 300 davon.

Zum ersten „Herumspielen“ sendet ihr die AT-Befehle am einfachsten über den seriellen Monitor der Arduino IDE. Ihr könnt aber auch genauso gut Terminalprogramme wie PuTTY oder HTerm verwenden, braucht dann aber einen USB-zu-TTL Adapter.

SoftwareSerial Sketch

Ladet den folgenden SoftwareSerial Sketch auf euer Arduino Board, um über den seriellen Monitor kommunizieren zu können:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);

void setup() {
  Serial.begin(9600);
  Serial.println("Software Serial Sketch");
  mySerial.begin(9600);
}

void loop() { // run over and over
  while(mySerial.available()) {
    Serial.write(mySerial.read());
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Nach meiner Erfahrung kann man mit einer Baudrate von 9600 bps zuverlässig arbeiten. Bei 115200 bps gingen mir Teile von SMS verloren. Im seriellen Monitor stellt ihr dieselbe Baudrate ein und wählt „Zeilenumbruch (CR)“.

Erste Schritte

Habt ihr alles verkabelt, die SIM-Karte eingelegt und das SIM800L Modul mit Strom versorgt, kann es jetzt losgehen. Die LED auf dem SIM800L Modul sollte nach Anlegen der Stromversorgung zunächst mit einer Frequenz von ca. 0.8 Sekunden aufleuchten.

Als ersten Test gebt ihr einfach nur AT ein und bestätigt mit Enter oder klickt auf „Senden“. Das Modul sollte mit OK antworten. Tut es das nicht, dann überprüft noch einmal die Verkabelung und die Einstellungen des seriellen Monitors.

Wenn alles OK ist, könnt ihr jetzt Informationen über das Modul abfragen:

ATI → Antwort: SIM800 R14.18

Eventuell ist eure SIM-Karte durch eine PIN geschützt. Gebt Folgendes ein:

AT+CPIN? →  bei Antwort:  +CPIN: READY ist keine PIN notwendig; bei Antwort: +CPIN: SIM PIN müsst ihr die PIN einschließlich der Anführungszeichen eingeben:

AT+CPIN="xxxx" → Antwort: OK; bei falschem PIN oder wenn die PIN schon eingegeben wurde: ERROR.

Spätestens nach der Eingabe des korrekten Pins sollte sich das Modul mit dem Netz verbinden und die LED im 3-Sekunden-Takt blinken.

Eine sehr nützliche Funktion ist die Abfrage des Akkustatus:

AT+CBC → Antwort: +CBC: 0,75,4005

Das bedeutet: „0“ – Akku lädt nicht („1“ hieße der Akku lädt). „75“ heißt, der Akku hat noch 75 % Kapazität. „4005“ steht für 4005 mV Spannung.

Die Signalstärke eures Netzes erfahrt ihr so:

AT+CSQ → Antwort: +CSQ: 20,0

Dabei bedeutet die erste Zahl: 

  • 0„:  -115 dBm oder weniger
  • 1„:  -111 dBm
  • 2 … 30″: -110 … -54 dBm
  • 31„:  -52 dBm oder größer
  • 99„:  unbekannt oder nicht messbar

In welchem Netz ihr seid, fragt ihr folgendermaßen ab:

AT+COPS? → Antwort: +COPS: 0,0,"D1"

Die wesentliche Information steht hinter dem zweiten Komma. Hier ist es also das D1-Netz. Die anderen Zahlen codieren Modus und Format. Schaut in die AT-Befehlsliste, wenn ihr näheres dazu wissen möchtet. 

Nützlich ist auch diese Abfrage:

AT+CREG? → Antwort: +CREG: 0,1

Die zweite Zahl bedeutet: „1“ Registered, home network; „5“ Registered: Roaming. Erhaltet ihr eine 2, 3 oder 4, seid ihr nicht im Netz registriert.

Euren Service Provider (gem. SIM-Karte) erfahrt ihr durch:

AT+CSPN? → Antwort: +CSPN: "Telekom.de",0

Sleep und Power Down Modi

Den Power-Down Modus aktiviert ihr mit:

AT+CPOWD=1 → Antwort: NORMAL POWER DOWN

Mit dem Parameter 0 geht das SIM800L Modul sofort und ohne Rückmeldung aus. Leider scheint der Power-Down Modus aber nicht stabil zu sein. Nach einiger Zeit schaltet sich mein Modul immer wieder von allein an. Ich konnte bisher nicht klären, warum das so ist.

Besser funktioniert der Schlafmodus (Slow Clock). Und so wird der Schlafmodus gestartet:

AT+CSCLK=x → Antwort: +CSCLK: x mit x = 0, 1, 2:

  • 0: normaler (Wach-)Modus.
  • 1: Slow Clock Modus 1; um zwischenzeitlich aus diesem Slow Clock Modus zu gehen, zieht ihr DTR auf GND. Das ist sehr praktisch. Wenn DTR wieder HIGH ist, geht das Modul zurück in den Schlafmodus. Im Normalzustand ist DTR durch einen internen Pull-Up Widerstand auf HIGH gezogen.
  • 2: Slow Clock Modus 2; zum Aufwecken sendet ihr zweimal kurz hintereinander AT+CSCLK=0.

Im Sleep Modus ist das SIM800L Modul für SMS und Anrufe erreichbar.

SMS senden

Um eine SMS zu versenden, müsst ihr ggf. eure PIN eingeben und das Modul mit AT+CMGF=1 in den SMS Textmodus bringen. Evtl. müsst ihr noch ein delay einbauen, um dem Modul Zeit zu geben, sich zu verbinden.

Das eigentliche Versenden der SMS leitet ihr mit der Eingabe der Telefonnummer des Empfängers ein:

AT+CMGS="+491738xxxxxx"

Daraufhin erhaltet ihr ein Promptzeichen (>). Ihr gebt den SMS Text ein und schließt die Eingabe mit Strg+Z (ASCII-Code Nr. 26) und dann Enter ab. So die Theorie. Praktisch habe ich es nicht hinbekommen, ein Strg+Z über den seriellen Monitor zu senden, da dieser nur sichtbare Zeichen verarbeitet. Mittels eines Sketches (s.u.) ist das aber kein Problem. Ein Strg+Z erzeugt ihr über Serial.write(26)

Alle anderen Befehle übermittelt ihr mit Serial.println(). Anführungszeichen müsst ihr ein Backslash voranstellen, damit sie nicht als Ende der println-Anweisung interpretiert werden.

Die SoftwareSerial Abfrage habe ich als separate Funktion (updateSerial) ausgelagert. Da die Reaktion auf einen AT Befehl ein wenig dauern kann,  habe ich eine Wartezeit (wt_ms = 100 ms) eingefügt. Eventuell müsst ihr den Wert bei euch anpassen.

In der Hauptschleife (loop) könnt ihr weitere Befehle über den seriellen Monitor eingeben. Hier braucht ihr keine Wartezeit, da ihr permanent abfragt.

So sieht der vollständige Sketch aus:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);
const unsigned int wt_ms = 100; // wait ms

void setup() {
  Serial.begin(9600);
  Serial.println("Send SMS Sketch");
  mySerial.begin(9600);
  delay(1000);
  updateSerial(wt_ms);
  mySerial.println("AT"); // to check if the module is connected
  updateSerial(wt_ms);
  mySerial.println("AT+CPIN=\"xxxx\""); // if Pin is needed
  updateSerial(wt_ms);
//  delay(8000); // maybe needed to setup connection to the network
//  mySerial.println("AT+CCID"); // optional check
//  updateSerial(wt_ms);
//  mySerial.println("AT+CBC"); // optional check
//  updateSerial(wt_ms);
//  mySerial.println("AT+COPS?"); // optional check
//  updateSerial(wt_ms);
//  mySerial.println("AT+CSQ"); // optional check
//  updateSerial(wt_ms);
//  mySerial.println("AT+CREG?"); // optional check
//  updateSerial(wt_ms);
  mySerial.println("AT+CMGF=1"); // SMS text mode
  updateSerial(wt_ms);
  mySerial.println("AT+CMGS=\"+491738xxxxxx\"");
  updateSerial(wt_ms);
  mySerial.print("Hi Wolle, this is a message from your SIM800L Module."); 
  updateSerial(wt_ms);
  mySerial.write(26);
  mySerial.println("");
  updateSerial(wt_ms);
}

void loop() { 
  updateSerial(0);
}
  
void updateSerial(unsigned int wait_ms){
  String dataString = "";
  delay(wait_ms);
  if(mySerial.available()) {
    dataString = mySerial.readString();
    Serial.println(dataString);
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Vielleicht ist euch aufgefallen, dass die Antworten des SIM800L Moduls in diesem Sketch mit mySerial.readString() ausgelesen und in einer Variable gespeichert werden. Das hat den Vorteil, dass man die Antwort des Moduls bearbeiten oder auswerten kann.

Ausgabe auf seriellem Monitor und Smartphone

So sahen die Ausgaben aus:

Ausgabe von send_sms_from_sim800l.ino
Ausgabe von send_sms_from_sim800l.ino
SMS auf dem Smartphone
SMS auf dem Smartphone

Auswerten von Strings

Zum Auswerten und Bearbeiten von Strings gibt es drei sehr nützliche Funktionen:

  • indexOf() / lastIndexOf(): liefert die nächste oder letzte Position der übergebenen Zeichenkette im String. Wird die Zeichenkette nicht gefunden, dann geben die Funktionen -1 zurück.
  • parseInt(): sucht nach der nächsten Zahlenfolge in einem String und liefert sie als Integerwert.
  • substring(x,y): schneidet eine Zeichenfolge aus einem String (Position x bis y-1).

Als ein kleines Beispiel für die substring() Funktion zeige ich, wie ihr aus der Modulantwort auf eine „COPS“-Abfrage gezielt den Namen des Netzes herausschneidet. In meinem Fall also das „D1″ aus +COPS: 0,0,“D1“.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);
const int wt_ms = 100; // wait ms
String moduleAnswer = "";

void setup() {
  String irg = "AT+COPS";
  Serial.begin(9600);
  Serial.println("Evaluate Answer");
  mySerial.begin(9600);
  delay(1000);
  
  mySerial.println("AT+COPS?");
  updateSerial(wt_ms);
  
  moduleAnswer = moduleAnswer.substring(1);   // does not work without, don't know why!
  int pos1 = moduleAnswer.indexOf("\"");      // first position of " 
  int pos2 = moduleAnswer.lastIndexOf("\"");  // last position of "
  moduleAnswer = moduleAnswer.substring(pos1+1,pos2);
  Serial.print("The module is connected to ");
  Serial.println(moduleAnswer);
}

void loop(){
}
  
void updateSerial(unsigned int wait_ms){
  delay(wait_ms);
  if(mySerial.available()) {
    moduleAnswer = mySerial.readString();
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Warum ich die Zeile:

moduleAnswer = moduleAnswer.substring(1);

einfügen musste, weiß ich nicht. Ohne das ging es nicht.

Ausgabe von evaluate_module_answer.ino
Ausgabe von evaluate_module_answer.ino

SMS empfangen

Um SMS zu empfangen, müsst ihr zunächst wieder mit dem Netz verbunden sein und den SMS Textmodus aktivieren. Zusätzlich definiert ihr, wie eingehende SMS zu behandeln sind:

AT+CNMI=1,2.

Die hier verwendeten Parameter sorgen dafür, dass der SMS-Text direkt auf dem seriellen Monitor erscheint.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);
const int wt_ms = 100; // wait ms

void setup() {
  Serial.begin(9600);
  Serial.println("Receive SMS Sketch");
  mySerial.begin(9600);
  delay(1000);
  updateSerial(wt_ms);
  mySerial.println("AT+CPIN=\"xxxx\""); // in your SIM card has a PIN
  updateSerial(wt_ms);
  mySerial.println("AT+CREG?"); // optional check
  updateSerial(wt_ms);
  mySerial.println("AT+CMGF=1"); 
  updateSerial(wt_ms);
  mySerial.println("AT+CNMI=1,2"); // defines how incoming SMS are handled
  updateSerial(wt_ms);
}

void loop() { 
  updateSerial(0);
}
  
void updateSerial(unsigned int wait_ms){
  String bufString = "";
  delay(wait_ms);
  if(mySerial.available()) {
    bufString = mySerial.readString();
  }
  if(bufString != ""){
    Serial.println(bufString);
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Und so sieht es auf dem seriellen Monitor aus, wenn eine SMS eintrifft:

Empfangene SMS
Empfangene SMS

Ein alternativer Modus zum Verarbeiten von SMS ist: AT+CNMI=2,1 (anstelle „1,2“). Damit wird die SMS gespeichert. Ihr bekommt auf dem seriellen Monitor lediglich eine Meldung wie z.B.:

+CMTI: "ME",21

Das bedeutet, dass die SMS Nr. 21 im Telefonspeicher („ME“ = Mobile Equipment) gespeichert wurde. Ihr könnt die gespeicherten SMS mit AT+CMGL="ALL" auflisten:

Anstelle von „ALL“ könnt ihr auch „REC UNREAD“ (received unread) oder „REC READ“ (received read) als Parameter verwenden.

Mit AT+CMGD=21 löscht ihr die SMS Nr 21. Ihr könnt auch alle SMS auf einmal löschen. Dazu verwendet ihr die Anweisung AT+CMGDA="DEL ALL".

Den Mikrocontroller per SMS steuern

Ihr könnt euren Mikrocontroller per SMS steuern. Das möchte ich hier am Beispiel von zwei LEDs, die ich an die Pins 9 und 10 angeschlossen habe, demonstrieren.

Variante 1: mit indexOf()

Die beiden LEDs habe ich led1 und led2 genannt. Wenn eine SMS eingeht, sucht der Sketch mithilfe der Funktion indexOf, ob led1 oder led2 im Text enthalten ist. Dann sucht er, ob das Schlüsselwort „on“ enthalten ist. Ist das der Fall, wird led1 bzw. led2 eingeschaltet. Wenn kein „on“ enthalten ist, wird die led1 bzw. led2 ausgeschaltet. Beispiele:

  • led1on: led1 wird angeschaltet
  • blablaled2blablaonblabla: led2 wird angeschaltet
  • led1: led1 wird ausgeschaltet.
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);
const int led1_pin = 9;
const int led2_pin = 10;
const int wt_ms = 100; // wait ms

void setup() {
  String moduleAnswer = "";
  Serial.begin(9600);
  Serial.println("Control LED Sketch");
  mySerial.begin(9600);
  pinMode(led1_pin, OUTPUT);
  pinMode(led2_pin, OUTPUT);
  
  delay(1000);
  updateSerial(wt_ms, moduleAnswer);
  mySerial.println("AT+CPIN=\"xxxx\"");
  updateSerial(wt_ms, moduleAnswer);
  mySerial.println("AT+CREG?"); 
  updateSerial(wt_ms, moduleAnswer);
  mySerial.println("AT+CMGF=1"); 
  updateSerial(wt_ms, moduleAnswer);
  mySerial.println("AT+CNMI=1,2");
  updateSerial(wt_ms, moduleAnswer);
}

void loop() { 
  String smsText = "";
  updateSerial(0, smsText);
    
  if(smsText != ""){
    smsText = smsText.substring(1);
    Serial.print("Text: ");
    Serial.println(smsText);
    if(smsText.indexOf("led1")>0){
      
      if(smsText.indexOf("on")>0){
        digitalWrite(led1_pin, HIGH);
      }
      else{
        digitalWrite(led1_pin, LOW);
      }
    }
    
    if(smsText.indexOf("led2")>0){
      if(smsText.indexOf("on")>0){
        digitalWrite(led2_pin, HIGH);
      }
      else{
        digitalWrite(led2_pin, LOW);
      }  
    }  
  }
}
  
void updateSerial(unsigned int wait_ms, String &bufString){
  bufString = "";
  delay(wait_ms);
  if(mySerial.available()) {
    bufString = mySerial.readString();
  }
  if(bufString != ""){
    Serial.println(bufString);
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Das Strings recht viel Speicher kosten, übergebe ich „moduleAnswer“ und „smsText“ als Referenz (&bufString). Das bedeutet, dass in der Funktion mit dem Original gearbeitet wird. Entsprechend gibt es keinen Rückgabewert.

Variante 2: mit parseInt()

Bei dieser Variante steht die Pinnummer und der gewünschte Pinzustand (0 oder 1) direkt im SMS Text. Beispiele:

  • *10*1*: Pin 10 geht HIGH
  • *9*0*: Pin 9 geht LOW
#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);
const int led1_pin = 9;
const int led2_pin = 10;
const int wt_ms = 100; // wait ms

void setup() {
  Serial.begin(9600);
  Serial.println("Control LED Sketch");
  mySerial.begin(9600);
  pinMode(led1_pin, OUTPUT);
  pinMode(led2_pin, OUTPUT);
  
  delay(1000);
  updateSerial(wt_ms);
  mySerial.println("AT+CPIN=\"xxxx\"");
  updateSerial(wt_ms);
  mySerial.println("AT+CREG?"); 
  updateSerial(wt_ms);
  mySerial.println("AT+CMGF=1"); 
  updateSerial(wt_ms);
  mySerial.println("AT+CNMI=1,2");
  updateSerial(wt_ms);
}

void loop() { 
  waitForSMS();
}
  
void waitForSMS(){
  int led = 0;
  bool state = false;
  if(mySerial.available()){
    while(((char)mySerial.read())!= '\n'){}
    led = mySerial.parseInt();
    state = mySerial.parseInt();
    digitalWrite(led, state);
  }
}


void updateSerial(unsigned int wait_ms){
  String bufString = "";
  delay(wait_ms);
  if(mySerial.available()) {
    bufString = mySerial.readString();
  }
  if(bufString != ""){
    Serial.println(bufString);
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Telefonieren

Telefonieren mit dem SIM800L ist noch einfacher als SMS zu versenden. Eigentlich müsst ihr nur dafür sorgen, dass euer SIM800L Modul mit dem Netz verbunden ist und Serial/SoftwareSerial wie bei den anderen Sketchen einrichten:

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);
const int wt_ms = 100; // wait ms 

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  Serial.println("Call or wait for a call");
  delay(1000);
  mySerial.println("AT");  // optional check
  updateSerial(wt_ms);
  mySerial.println("AT+CPIN=\"++++\"");
  updateSerial(wt_ms);
  mySerial.println("AT+CREG?"); // optional check
  updateSerial(wt_ms);
}
void loop() { 
  updateSerial(0);
}
  
void updateSerial(unsigned int wait_ms){
  String dataString = "";
  delay(wait_ms);
  if(mySerial.available()) {
    dataString = mySerial.readString();
    if(dataString != ""){
      Serial.println(dataString);
    }
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Ausgehender Anruf

Einen Anruf startet ihr mit dem folgenden AT-Befehl:

ATD+ +xxxxxxxxxxxx;

Ersetzt xxxxxxxxxxxx durch die zu wählende Nummer, beginnend mit dem Ländercode. Mit ATH beendet ihr das Gespräch. Vergesst nicht das Semikolon am Ende (kein Schreibfehler!).

Eingehender Anruf

Verwendet denselben Sketch, wenn ihr euer SIM800L Modul anrufen wollt. Der Anruf macht sich akustisch bemerkbar, durch „RING“ im seriellen Monitor und durch ein kurzes LOW Signal am RING-Pin. Letzteres Signal könntet ihr nutzen, um euren Mikrocontroller aus einem Sleep Modus zu wecken. So lassen sich stromsparende Projekte umsetzen.

Mit ATA nehmt ihr den Anruf an, mit ATH lehnt ihr den Anruf ab.

Eingehender Anruf auf dem seriellen Monitor
Eingehender Anruf auf dem seriellen Monitor

Telefonie-Einstellungen

Hier noch ein paar nützliche Einstellungen. Die Gesprächslautstärke fragt ihr folgendermaßen ab:

AT+CLVL? → Antwort: +CLVL: 33

Und so stellt ihr sie ein:

AT+CLVL=x mit x = 0 – 100

Die Klingeltonlautstärke ist davon unabhängig (auch 0-100):

AT+CRSL? (Abfrage) / AT+CRSL=x (Einstellung)

Es gibt 20 Klingelsounds, die ihr so einstellt:

AT+CALS=x mit x = 0 – 19

Den Mikrocontroller per Anruf steuern

Ich habe mir dann noch überlegt, wie man den Mikrocontroller per Anruf steuern kann. Eine LED anzuschalten, ist über das „RING“ sehr einfach. Genauso einfach ist es, die LED mit einem weiteren Anruf wieder auszuschalten. Allerdings kommt man dabei auch leicht durcheinander. Schön wäre es, eine Rückmeldung zu erhalten, ob die LED an oder aus ist.

Das habe ich mit dem folgenden Sketch realisiert. Wenn ein Anruf eingeht, dann prüft der Sketch den Status der LED. Sollte sie angeschaltet sein, wird der Anruf sofort abgelehnt. Ist sie hingegen aus, passiert erst einmal nichts. In beiden Fällen wird 10 Sekunden gewartet und die weiteren eingehenden „Rings“ gezählt. War die LED ausgeschaltet, wird der Anruf jetzt abgelehnt. Dadurch zählt der Sketch je nach LED Zustand eine unterschiedliche Anzahl von „Rings“. Entsprechend wird die LED an- oder ausgeschaltet. Und der Anrufer weiß, dass bei sofortiger Ablehnung des Anrufes die LED aus war und jetzt angeschaltet ist.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);
const int ledPin = 9;
const int wt_ms = 100; // wait ms

void setup() {
  String moduleAnswer = "";
  Serial.begin(9600);
  Serial.println("Control LED by Call");
  mySerial.begin(9600);
  pinMode(ledPin, OUTPUT);
  delay(1000);
  updateSerial(wt_ms, moduleAnswer); 
  mySerial.println("AT+CPIN=\"xxxx\""); // in case a PIN is required
  updateSerial(wt_ms, moduleAnswer); 
  mySerial.println("AT+CREG?"); // optional check
  updateSerial(wt_ms, moduleAnswer);
}

void loop() { 
  String ring = "";
  int noOfRings = 0;
  unsigned long callTime = 0;
  const unsigned long threshold = 10000; 
  
  updateSerial(0, ring); 
  
  if(ring != ""){
    if(ring.indexOf("RING")>0){
      noOfRings++;
      callTime = millis();
      ring = "";
      if(digitalRead(ledPin)){
        mySerial.println("ATH");
      }
      
      while((millis()-callTime)<threshold){
        updateSerial(0, ring); 
        if(ring != ""){
          if(ring.indexOf("RING")>0){
            noOfRings++;
            ring = "";
          }
        }
      }
      if(noOfRings == 1){
        digitalWrite(ledPin, LOW);
      }
      else{
        digitalWrite(ledPin, HIGH);
        mySerial.println("ATH");
      }
    }
  }
}
  
void updateSerial(unsigned int wait_ms, String &bufString){
  bufString = "";
  delay(wait_ms);
  if(mySerial.available()) {
    bufString = mySerial.readString();
  }
  if(bufString != ""){
    Serial.println(bufString);
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Achtung: Ein abgelehnter Anruf ist nicht unbedingt kostenfrei! Ggf. müsst ihr unter anderem die Einstellung, dass bei „Besetzt“ der SMS Benachrichtigungsservice angeboten wird, abstellen. Prüft das lieber bevor eure Telefonrechnung explodiert!

Den Zugriff beschränken – Whitelist

Die SMS- und die Anrufmethode bergen grundsätzlich die Gefahr, dass irgendjemand, aus Versehen oder mit böser Absicht, unbefugt euer Gerät steuert. Um das zu verhindern, könnt ihr eine Whitelist einrichten. Damit stellt ihr ein, für welche Telefonnummern euer SIM800L erreichbar sein soll. Anrufe von Geräten mit anderen Telefonnummern lehnt das SIM800L ab. Der Anrufer erhält ein Besetztzeichen.

Und so geht’s:

AT+CWHITELIST=mode,index,phone_number

Der Modus (mode) legt fest, ob die Whitelist für Anrufe, SMS oder beides wirksam ist:

  • 0: Whitelist deaktiviert
  • 1: Anruf Whitelist
  • 2: SMS Whitelist
  • 3: Anruf und SMS Whitelist

Der Modus gilt immer für die gesamte Whitelist. Das bedeutet, dass unterschiedliche Einstellungen für unterschiedliche Nummern nicht möglich sind.

Index ist die Nummer des Eintrages (1-30). Die phone_number ist die Telefonnummer mit Ländervorwahl, aber ohne „+“ – wie ich nach mehrstündigem Herumprobieren und Recherchieren herausbekam.

AT+CWHITELIST? fragt die Whitelist ab und AT+CWHITELIST=0 deaktiviert die gesamte Liste.

Hier ein Beispiel:

Einsatz der Whitelist für das SIM800L Modul
Einsatz der Whitelist

Zeit abfragen

Ihr könnt das SIM800L Modul auch als RTC (Real Time Clock) nutzen. Mit AT+CCLK? fragt ihr die Uhrzeit ab.

+CCLK: "04/01/01,00:01:31+00"

Das Format ist:  „YY/MM/DD,hh:mm:ss±tz“, also „Jahr/Monat/Tag,Stunden:Minuten:Sekunden+tz“, wobei tz die Abweichung von GMT in Viertelstunden ist. Das Modul startet nach Trennung von der Spannungsversorgung immer wieder um 0 Uhr am 01.01.2004. Ihr müsst die Uhrzeit also stellen. Dafür gibt es drei Möglichkeiten:

  1. Manuell stellen
  2. Über die Systemzeit des Computers
  3. Abfrage über einen NTP Server

Manuelles Einstellen der Zeit

Ich denke, die folgenden Ein-/Ausgaben auf dem seriellen Monitor sind selbsterklärend:

Zeiteinstellung mit CCLK
Zeiteinstellung mit CCLK

Einstellen nach der Systemzeit

Bei dieser Methode wird die Zeit mithilfe der Systemzeit des Computers gestellt. Dazu müsst ihr erst einmal dem Mikrocontroller die Zeit „beibringen“. Dazu ist die Soft-RTC Variante der RTCLib gut geeignet. Dann überträgt der Mikrocontroller die Zeit auf das SIM800L Modul. Ich möchte nicht zu weit ins Detail gehen. Wie ihr mit DateTime und RTC_Millis Objekten arbeitet, habe ich in meinem Beitrag zum RTC Modul DS3231 erklärt.

Ich bringe die Methode nur der Vollständigkeit halber. Besser ist die dritte Methode, mit der ihr die Zeit immer wieder nachstellen könnt.

#include "RTClib.h"
#include <SoftwareSerial.h>
RTC_Millis rtc;
SoftwareSerial mySerial(7,8);
const int wt_ms = 100; // wait ms 

void setup () {
  Serial.begin(9600); 
  mySerial.begin(9600);
  Serial.println("Set time and date by system time");
  delay(1000);
  Serial.println("Time before setting: ");
  mySerial.println("AT+CCLK?");
  updateSerial(wt_ms);
  Serial.println("Time after setting: ");
  rtc.begin(DateTime(F(__DATE__), F(__TIME__))); // sets soft-RTC time by system time
  setTimeBySystemTime();
}

void loop () {
  mySerial.println("AT+CCLK?");
  updateSerial(wt_ms);
  delay(3000);
}

void setTimeBySystemTime(){
  DateTime now = rtc.now();
  String dateTimeString = String(now.year()-2000);
  dateTimeString += "/";
  dateTimeString += byteToStringAndFormat(now.month());
  dateTimeString += "/";
  dateTimeString += byteToStringAndFormat(now.day());
  dateTimeString += ",";
  dateTimeString += byteToStringAndFormat(now.hour());
  dateTimeString += ":";
  dateTimeString += byteToStringAndFormat(now.minute());
  dateTimeString += ":";
  dateTimeString += byteToStringAndFormat(now.second());
  dateTimeString += "+08"; // change according to your time zone 
  mySerial.print("AT+CCLK=\"");
  mySerial.print(dateTimeString);
  mySerial.println("\"");
  updateSerial(wt_ms);
}

String byteToStringAndFormat(byte b){
  String str = "";
  str = String(b);
  if(b<10){
    str = "0" + str;
  }
  return str;    
}

void updateSerial(unsigned int wait_ms){
  String dataString = "";
  delay(wait_ms);
  if(mySerial.available()) {
    dataString = mySerial.readString();
    if(dataString != ""){
      Serial.println(dataString);
    }
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

So sieht dann die Ausgabe aus:

Zeiteinstellung über die Systemzeit
Zeiteinstellung über die Systemzeit

Einstellen der Zeit über NTP Server

Ihr könnt die Uhrzeit des SIM800L auch mit einem NTP (Network Time Protocoll) Server synchronisieren. Das ist eine GPRS Anwendung, für die ihr eine Reihe von „SAPBR“ Befehlen ausführen müsst. Im Sketch habe ich einige Kommentare eingefügt. Ansonsten schaut bitte in die AT-Befehlsliste. Die „CNTP“ Befehle für den NTP Server findet ihr in einem separaten Dokument, der NTP Application Note.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);
const int wt_ms = 100; // wait ms

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  Serial.println("Get Time");
  delay(1000);
  mySerial.println("AT");  // optional check
  updateSerial(wt_ms);
  mySerial.println("AT+CPIN=\"xxxx\""); // if PIN is required
  updateSerial(wt_ms);
  mySerial.println("AT+CREG?"); // optional check
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""); // set GPRS connection
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=3,1,\"APN\",\"internet\""); // set APN name
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=3,1,\"USER\",\"\""); // username empty
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=3,1,\"PWD\",\"\"");  // password empty
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=1,1"); // set rate
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=2,1");  // connect
  updateSerial(wt_ms);
  mySerial.println("AT+CNTPCID=1"); // set GPRS Bearer Profile’s ID
  updateSerial(wt_ms);
  int timeZone = 2; // local time = UTC + timeZone
  int timeVal = timeZone*4;
  mySerial.print("AT+CNTP=\"0.de.pool.ntp.org\","); // replace by your country ntp server
  mySerial.println(timeVal);
  updateSerial(wt_ms);
  mySerial.println("AT+CNTP"); // synchronize time
  updateSerial(wt_ms);

  mySerial.println("AT+CCLK?"); // query local (module) time
  updateSerial(wt_ms);
  
  // close connection:
  mySerial.println("AT+SAPBR=0,1");
} 
  
void loop() { 
  updateSerial(0);
}
  
void updateSerial(unsigned int wait_ms){
  String dataString = "";
  delay(wait_ms);
  if(mySerial.available()) {
    dataString = mySerial.readString();
    if(dataString != ""){
      Serial.println(dataString);
    }
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

Noch eine Bemerkung zur timeZone: Einige Zeitzonen haben keine ganzstündigen Verschiebungen. Deswegen wird Server die Verschiebung in Viertelstunden übergeben.

SIM800L Modul mit Bibliothek steuern

Ich habe mir verschiedene Bibliotheken angeschaut und halte GSMSim von Erdem Arslan am besten. Ihr könnt sie über den Library Manager installieren oder hier direkt von GitHub herunterladen. Allerdings funktionieren die Beispielsketche nicht ohne Weiteres auf einem Arduino UNO. Unten findet ihr den angepassten Beispielsketch zum Versenden von SMS.

#include <GSMSimSMS.h>
#include <SoftwareSerial.h>
#define RESET_PIN 10 // you can use any pin.

SoftwareSerial Serial1(6,7);
GSMSimSMS sms(Serial1, RESET_PIN); // GSMSimSMS inherit from GSMSim. You can use GSMSim methods with it.

void setup() {
  Serial1.begin(9600); // If you don't change module baudrate, it comes with auto baudrate.
  Serial.begin(9600); // Serial for debug...

  // Init module...
  sms.init(); // use for init module. Use it if you don't have any valid reason.

  Serial.print("Set Phone Function... ");
  Serial.println(sms.setPhoneFunc(1));
  delay(1000);

  //Serial.println("Enter Pin Code:...");
  //Serial.println(sms.enterPinCode("xxxx"));
  //delay(3000);

  Serial.print("is Module Registered to Network?... ");
  Serial.println(sms.isRegistered());
  delay(1000);

  Serial.print("Signal Quality... ");
  Serial.println(sms.signalQuality());
  delay(1000);

  Serial.print("Operator Name... ");
  Serial.println(sms.operatorNameFromSim());
  delay(1000);

  Serial.print("Init SMS... ");
  Serial.println(sms.initSMS()); // Its optional but highly recommended. Some function work with this function.
  delay(1000);

  Serial.print("List Unread SMS... ");
  Serial.println(sms.list(true)); // Its optional but highly recommended. Some function work with this function.
  delay(1000);

  Serial.print("SMS to any number... ");
  Serial.println(sms.send("+49173xxxxxxx", "SMS test message")); // only use ascii chars please
  delay(1000);
}

void loop() { 
}

Alles in allem würde ich aber raten, ohne Bibliothek zu arbeiten. Ihr seid einfach flexibler.

Anhang – Versuche zur Ortsbestimmung

Theoretisch lässt sich der Standort des SIM800L bestimmen. Um es vorwegzunehmen, ich erhalte dabei „Location Error“. Es könnte sein, dass das mit meinem Standort zusammenhängt und es anderswo funktioniert. Normalerweise veröffentliche ich nichts, was vielleicht funktionieren könnte. Da ich jedoch viele Stunden in das Problem investiert habe und einige Teilprobleme, mit denen andere Probleme hatten, lösen könnte, möchte ich meine Erfahrungen teilen.

CIPGSMLOC funktioniert nicht mehr

Mithilfe des AT-Befehls AT+CIPGSMLOC=1,1 und einigen vorbereitenden Einstellungen konnte man bis vor einiger Zeit den Standort in Längen- und Breitengrad bestimmen. Die Methode basiert aber auf einem Dienst, der leider abgeschaltet worden ist. Dieser Weg ist also verbaut.

Alternativ gibt es die „CLBS“ AT-Befehle, die in der Location_Application_Note beschrieben werden. Allerdings ist dazu ein Update der Firmware des SIM800L erforderlich.

Update der Firmware auf Version 1418B05SIM800L24

Vorbereitungen

Hardwareseitig braucht Ihr einen USB-zu-TTL Adapter, den ihr für wenige Euro bei Amazon und Co bekommt. Dann benötigt ihr die Firmware Version 1418B05SIM800L24. Die gibt es zum Beispiel hier auf Github. Ladet die ZIP-Datei herunter und entpackt sie irgendwo. Des Weiteren braucht ihr das Programm SIM800_Series_download_Tools_Customer_v1.19 zum Upload der Firmware. Das bekommt ihr z.B. hier. Ladet die rar-Datei herunter und entpackt sie. Der Ort ist nicht wichtig. Im entpackten Ordner findet ihr das Programm Flash_tool.exe.

Verkabelt alles folgendermaßen:

Schaltung zum Upload neuer Firmware für das SIM800L Modul
Schaltung zum Upload neuer Firmware

Der Spannungsteiler (5.6 kΩ / 4.7 kΩ) bezieht sich auf einen 5V Adapter. Wie weiter oben erwähnt, gibt es Stimmen, die sagen, die SIM800L Pins seien 5V tolerant. Ihr müsst selbst entscheiden, wie vorsichtig ihr sein wollt.

Aufspielen der Firmware

Nun startet Flash_tool.exe. Klickt auf „Image Folder“ und wählt die zuvor heruntergeladene und entpackte Firmware Datei. Stellt SIM800L, UART und Baudrate 115200 ein.  Als „Com“ wählt ihr den Port eures Adapters. „Erase Type“ ist „Erase Source Code And User Data“:

Firmware Upload auf das SIM800L Modul mit Flash_tool.exe
Firmware Upload auf das SIM800L Modul mit Flash_tool.exe

Klickt auf „Start Download“. Dann nehmt ihr das SIM800L kurz vom Strom und verbindet es wieder. Der Upload (hier Download genannt) sollte nun in ca. 10 Sekunden beginnen.

Nach ein paar Minuten ist die Firmware auf dem Modul. Trennt es wieder kurzfristig vom Strom, um es neu zu starten.

Versuch der Ortsbestimmung

Mit dem folgenden Sketch scheint alles zu funktionieren, bis zur eigentlichen Ortsbestimmung mit AT+CLBS=1,1. Die Antwort lautet +CLBS: 1. Das ist laut Fehlerliste „Location Failed“. Vielleicht muss noch irgendetwas anders eingestellt werden, vielleicht hängt es aber auch mit der Funkabdeckung meines Wohnortes zusammen. Oder wurde der Dienst wieder eingestellt? Ich habe das Ganze erst einmal in meinem Akte X Ordner geparkt.

#include <SoftwareSerial.h>
SoftwareSerial mySerial(7,8);
const int wt_ms = 100; // wait ms

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  Serial.println("Get Location");
  delay(1000);
  mySerial.println("AT");  // optional check
  updateSerial(wt_ms);
  mySerial.println("AT+CPIN=\"xxxx\""); // if PIN is required
  updateSerial(wt_ms);
  mySerial.println("AT+CREG?"); // optional check
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\""); // set GPRS connection
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=3,1,\"APN\",\"internet\""); // set APN name
//  updateSerial(wt_ms);
//  mySerial.println("AT+SAPBR=3,1,\"USER\",\"\""); // username empty
//  updateSerial(wt_ms);
//  mySerial.println("AT+SAPBR=3,1,\"PWD\",\"\"");  // password empty
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=1,1"); // set rate
  updateSerial(wt_ms);
  mySerial.println("AT+SAPBR=2,1");  // connect
  updateSerial(500);
  mySerial.println("AT+CLBSCFG=0,1"); 
  updateSerial(500);
  mySerial.println("AT+CLBSCFG=0,2"); 
  updateSerial(wt_ms);
  mySerial.println("AT+CLBSCFG=0,3"); 
  updateSerial(wt_ms);
  mySerial.println("AT+CLBSCFG=1,3,\"lbs-simcom.com:3002\"");
  updateSerial(500);
  mySerial.println("AT+CLBS=1,1");
  updateSerial(500);
  delay(10000);
  
  //close connection:
  mySerial.println("AT+SAPBR=0,1");
} 
  
void loop() { 
  updateSerial(0);
}
  
void updateSerial(unsigned int wait_ms){
  String dataString = "";
  delay(wait_ms);
  if(mySerial.available()) {
    dataString = mySerial.readString();
    if(dataString != ""){
      Serial.println(dataString);
    }
  }
  while(Serial.available()) {
    mySerial.write(Serial.read());
  }
}

 

Danksagung

Wieder habe ich einige Bilder von Pixabay für mein Beitragsbild verwendet. Besten Dank an die Erschaffer:

Das SIM800L habe ich von Andrey Fedorov auf GitHub.

56 thoughts on “SIM800L Modul

  1. Hallo Wolfgang,
    für Deine stets hervorragend aufbereiteten Artikel vielen Dank.
    Jetzt aber eine Bitte zum Thema: Mikrocontroller mit SMS steuern. Das Programm funktioniert wie erwartet. Ich habe es jedoch nicht geschafft, das Programm so zu erweitern, dass der Status der einzelnen LED´s abgefragt werden kann. Oder noch besser: Ein Befehl wird erteilt und als Rückmeldung kommt sofort eine SMS.
    Bitte hilf mir mit einem getesteten Code. Vielen Dank.
    Unabhängig davon möchte ich ein 4G-LTE-Modul kaufen, damit ich mit meinem kleinen Projekt – was passiert zu Hause während des Asien-Urlaubs – auch aus dem 4G-Netz auf den Philippinen zugreifen kann. Wo kaufst Du Deine Module?

    1. Hallo Hubert,
      einen ganzen Sketch kann ich dir nicht schreiben, dafür fehlt mir die Zeit. Aber wenn das Hauptproblem die Abfrage ist, dann hilft der folgende kleine Sketch vielleicht weiter. Hier wird der Status von fünf Pins (4, 8, 9, 11 und 13) abgefragt.

      int ledArray[5] = {4, 8, 9, 11, 13};
      String statusString = "";
      
      void setup(){
        Serial.begin(9600);
        for(int i=0; i< 5; i++){
          pinMode(ledArray[i], OUTPUT);
        }
        digitalWrite(ledArray[0], HIGH); // 4 ist HIGH
        digitalWrite(ledArray[2], HIGH); // 9 ist HIGH
      
        // Abfrage:
        for(int i=0; i<5; i++){
          statusString += String(ledArray[i]) + ": ";
          if(digitalRead(ledArray[i])){
            statusString += "ON";
          }
          else{
            statusString += "OFF";
          }
          if(i != 4){
            statusString += ", ";
          }
        }
        Serial.println(statusString);
      }
      
      void loop(){}
      

      Die Ausgabe des Sketches ist wie erwartet:
      4: ON, 8: OFF, 9: ON, 11: OFF, 13: OFF

      Jetzt musst du nur noch den String per SMS versenden. Um die Abfrage per SMS zu starten, könntest du einfach eine SMS mit dem Inhalt "Abfrage" versenden. Wenn eine SMS mit diesem Inhalt eingeht, dann führst du die Abfrage aus. Du könntest dann auch die LEDs schalten, indem du beispielsweise einen String sendest:
      "Schalte 0,0,1,1,1", um die LEDs 4 und 8 aus- und 9, 11 und 13 einzuschalten. Du überprüfst, ob die ersten 7 Buchstaben "Schalte" sind und nimmst dann den Rest der SMS mit parseInt auseinander.
      Hoffe, das hilft.

      Wenn ich irgendetwas an Modulen brauche, dann ist normalerweise Amazon meine erste Adresse, da ich mir meistens über Prime die Liefergebühren sparen kann. Bei den Anbietern auf Amazon habe ich keine besonderen Präferenzen. Wenn es nicht eilt, dann kaufe ich auch gerne bei AliExpress.

      VG, Wolfgang

      1. Hallo Wolfgang,
        vielen Dank für Deine umfangreiche Antwort. Ich werde weiter experimentieren (learning by doing 🙂 ).
        Deine Beiträge sind allesamt sehr lehrreich!!
        Mit besten Grüßen, Hubert

  2. Hallo Wolle,
    Dein Beitrag über den SIM800L ist ganz toll!! Ich hab das Teil auch zum Laufen gebracht, aber es funktioniert nur in Verbindung mit einem Arduino! Ich brauche also zwei Stromversorgungen. Ist es möglich, nach der Programmierung den SIM800 im Standalone zu betreiben??? Er soll als Alarmanlage arbeiten und nur eine SMS beim Einschalten versenden.
    Da gibts noch den SIM800L EVB (blaue Platine), kann der das??? Wird der auch über den Arduino betrieben???
    Vielen Dank, Andreas

    1. Hallo Andreas,
      nein, allein kann das Modul so ziemlich nichts. Was es machen soll, muss man ihm durch die AT-Kommandos mitteilen. Man könnte höchstens einen ganz kleinen Mikrocontroller nehmen, z.B. einen ATtiny85 oder, wenn du die „nackten“ Mikrocontroller scheust, einen Digispark oder einen ESP8266.
      Mit dem SIM800L EVB habe ich keine Erfahrung, aber nach einer kleinen Recherche komme ich zu dem Schluss, dass er sich nicht grundlegend vom SIM800L unterscheidet.
      VG, Wolfgang

  3. Hallo!
    Ihr schriebt: „RING: standardmäßig HIGH, geht kurz auf LOW bei Anruf (auch für SMS einstellbar); „.
    Ich würde gerne wissen, welchen AT-command verwendet werden muss, damit sich der Pegel auf dem RING-Pin nur bei Anrufen ändert, damit er nicht auf sms reagiert. Sicher kennen Sie die Antwort 🙂 Vielen Dank !

    1. Hallo, es scheint, dass ich damit falsche Hoffnungen geweckt habe. Einen solchen AT-Befehl habe ich nicht gefunden und habe die Stelle in meinem Beitrag umformuliert. Tut mir leid!
      VG, Wolfgang

      1. Moin,

        man kann aber indirekt ermitteln, ob es eine SMS oder ein Anruf war, der das RING-Pin auf Low gezogen hat:
        Wenn RING-Pin auf Low, dann Daten von serielle Schnittstelle einlesen. Wenn RING im String enthalten ist, dann Anruf; wenn +CMTI: „ME“, enthalten, dann SMS. Je nach dem, kann dann entschieden werden, ob weitere Aktionen ausgeführt werden sollen.

    1. Hallo Jörg, vielen Dank. Sieht interessant aus- ich verspreche aber lieber nichts!
      VG, Wolle

  4. Hi.
    Erstmal danke für die tollen Infos!
    Kann man das Modul eigentlich auch ohne einen angeschlossenen Mikrocontroller benutzen, um hardwaremäßig getriggert Anrufe zu tätigen und ggf. etwas zu schalten?
    Habe eine Siedle Türsprechstation HTA 711-01, die ich gerne auf ein Handy weiterleiten würde.
    Wenn jemand klingelt ein digitales Pulssignal zu erzeugen würde einigermaßen einfach gehen.
    Wäre nice, wenn man dieses an das Modul anlegen könnte, und das dann eine eingespeicherte Nummer anwählt.
    Miktofon und Lautsprecher der Siedle würde ich dann gekreuzt an Lautsprecher- und Mikrofonanschluss des Moduls klemmen, ggf. mit Kondensator getrennt und den Pegel mittels Spannungsteiler angepasst.
    Und dann wäre es nice, den Türöffner zu betätigen (im Prinzip könnte man das mit dem Klingel-Signal machen, dann müsste man halt am Handy erst auflegen und dann das Modul anrufen)…

    1. Hallo Erwin, ich wüsste nicht, wie man das Modul ohne Mikrocontroller steuern könnte. Man muss dem guten Stück über RX/TX mitteilen, was es tun soll und da wüsste ich keine Alternative. Man könnte allerdings einen kleinen Mikrocontroller nehmen, wie einen ATtiny85.
      VG, Wolfgang

      1. Hallo Wolfgang,

        der Platz in dem Türsprechgehäuse ist halt auch recht begrenzt.
        Dachte, man könnte vielleicht direkt in das SIM800L Modul was reinprogrammieren.
        Z.B. das es, wenn es aus dem Schlaf geholt wird, automatisch die letzte verwendete Nummer anruft.
        Gruß
        Erwin

  5. Vielen Dank Wolfgang, das habe ich wohl überlesen. Eine kurze Frage noch : das Modul soll ja mit RX TX an den Arduino angeschlossen werden, aber es werden die pins 7 und 8 verwendet. Ich dachte sie müssen auch an TX und RX angeschlossen werden. Warum ist das so? Entschuldige bitte, ich bin noch Anfänger. Wünsche frohe Weihnachten und ein guten Rutsch ins neue Jahr 🙋🏻‍♂️🍀

    1. Hallo Lukas,
      bei mir darf man alle Frage stellen. Die Pins 7 und 8 sind als TX/RX ausreichend. Sie tun praktisch so als wären sie eine Serial-Schnittstelle. Das wird über SoftwareSerial mySerial(7,8) erreicht. In den meisten Fällen ist es besser, SoftwareSerial zu verwenden, da über die Hardware Serial Pins 0 und 1 auch der Programmupload und die Kommunikation mit dem seriellen Monitor läuft. Diese Vorgänge können sich mit den angeschlossenen Geräten stören.
      Dir auch ein frohes Fest und einen guten Rutsch!
      VG, Wolfgang

  6. Hallo Wofgang

    Bin auf der suche nach sim800l auf deine Seite gestoßen. Tolle Seite – Super Arbeit – Gratulation

    Kurze Frage – Wie Stabil ist das „Rote“ Modul?
    Verwende das Modul mit 5V. Ab und zu verliert es beim senden oder empfangen das Netz und
    verbindet sich nicht mehr

    lg Bruno

    1. Hallo Bruno,
      ich hatte ab und zu Probleme mit dem Verbindungsaufbau, aber nach gelungener Einwahl lief es eigentlich stabil. Ich habe es aber auch nie über längere Zeit laufen lassen. Vielleicht googelst du mal nach „sim800 verbindungsprobleme“. Hab gesehen, da gibt es ein paar Treffer, aber nicht weiter geschaut.
      VG, Wolfgang

      1. Danke für die Antwort

        Habe natürlich im Netz gesucht. Modul lief bei mir ca 5 Jahre ok. (Modul SIM800L EVB 5V Platine)
        Habe ein Update der Firmware durchgeführt. Jetzt Wählt es sich auch wieder ohne Probleme
        ein. Man merkt eine stärkere Sendeleistung.(nähe vom Lautsprecher mehr Verbindungsgeräusche) . ps der große Kondensator war bei mir bei drei Modulen zu schwach. Habe einen Elko 470u umgelötet.
        Müsste das Rote Modul besorgen und Testen.

        lg Bruno

  7. Hallo Wolle.
    Interessantes Projekt, danke, sehr ausführlich erklärt.
    Eine Frage hätte ich, welche Library wäre geeignet für das sm800l Modul

    Liebe Grüße Lukas

      1. Vielen Dank Wolfgang, das habe ich wohl überlesen. Eine kurze Frage noch : das Modul soll ja mit RX TX an den Arduino angeschlossen werden, aber es werden die pins 7 und 8 verwendet. Ich dachte sie müssen auch an TX und RX angeschlossen werden. Warum ist das so? Entschuldige bitte, ich bin noch Anfänger. Wünsche frohe Weihnachten und ein guten Rutsch ins neue Jahr 🙋🏻‍♂️🍀

  8. Hallo Wolfgang,
    Ich wollte auf meinem Schreibtisch im Geschäft endlich ein vernünftiges Telefon haben und hatte mich entschlossen, ein W48 dazu umzurüsten. Dann las ich Deinen Beitrag an. Super! Alle Teile gekauft, Telefon aufgebaut, jetzt funktioniert es endlich. Naja, ich musste dann schon die Datasheets vom Simcom gründlich lesen, um die ganze Sache stabil zu bekommen. Gestern entdeckte ich Deinen Beitrag nochmal, weil ich nach Erfahrungen mit dem W48 gesucht habe. Hauptproblem ist bei mir, daß die Kohle-Sprechkapsel beim Empfänger starkes Rauschen und Brummen verursacht. Ein Elektret-Mikro passt in den Hörer nicht richtig rein und es gibt auch keine Möglichkeit, dieses ordentlich störsicher aufzubauen, wegen dem langen Kabel. Folglich, es brummt noch mehr. Verwendet habe ich einen Atmega32U4. Der hat eine USB-Buchse und eine serielle Schnittstelle und kann im Ruhezustand fast komplett abgeschaltet werden, sodaß eine 18650-Batterie eigentlich einen ganzen Monat reichen sollte. Stromaufnahme im Sleep-Modus ca. 3mA incl. SIM800L. Beim Telefonieren ca.50mA. Bitte stelle mir den Kontakt zu Thorsten Hartwig her, eventuell können wir uns zusammentun. Vielen Dank 🙂 Norbert

    1. Hallo Norbert, dann darf ich ihm deine E-mail Adresse weiterleiten, richtig? Das ist eigentlich offensichtlich, aber ich frage bei diesem sensiblen Thema lieber nach.
      VG, Wolfgang

  9. Hallo Wolfgang,
    jetzt komme ich nochmals. Ich habe auch mal etwas mit SMS machen wollen, es klappt auch enigermaßen, z.B mit deinem obigen Sketch „SMS empfangen“ und auch meinem eigenen (der ja dann auch mit diesen Befehlen arbeitet). Aber- es gehen keine Umlaute, da kommen nur nicht darstellbare Zeichen. Hast du da deine Idee wie man das lösen könnte?
    Viele Grüße
    73 Uwe

      1. Hallo Wolfgang,
        danke für die Antwort. Ich habe es jetzt geschafft, mit
        AT+CSCS=\“HEX\“ die Antwort 48616C6C6F207C7B7E5C5B5E1E
        auf meine SMS Hallo öäüÖÄÜß
        in einen String zu bekommen. Aber ich schaffe es nicht das wieder in den Originaltext zurückzuwandeln. Hättest du da noch einen Tipp?
        Viele Grüße Uwe

        1. @ Wolfgang: Falls ich Dein Forum zumülle, wir können das auch über E-Mail direkt machen und dann eine Zusammenfassung hier im Forum als Kommentar schreiben.

          Hallo Uwe,

          ich bin hier im Forum auch neugierig geworden. Dann hat mich die Antwort auf Deine Frage gereizt… Habe mal was ausprobiert. Ich habe ein SMS auf das SIM800L senden lassen. „ä Ä ö Ö ü Ü ß“. Im normalen Modus des SIM800L kommen die Umlaute als Unicode oberhalb des 0x7F an. Weder der Seielle Monitor der Aduino-IDE noch der Arduino-Scetch können diese Zeichen darstellen. Ein Grund ist, daß der Variablentyp „char“ wie „int8_t“ behandelt wird, also ab 0x80 ein negatives Ergebnis liefert. Mit welchem Display möchtest Du die SMS anzeigen? Hat das überhaupt die Möglichkeit, Umlaute anzuzeigen?
          Wenn ich folgendes mache:
          char c = 0;
          while (Serial1.available()) {
          c = Serial1.read();
          if ((c == 10) || (c == 13)) {
          Commands.toUpperCase();
          letzteMeldung = milli;
          if (Commands.length() > 1) {
          Meldung(Commands + ‚\n‘);
          complete = true; }
          else Commands = „“;
          break;
          } // if ((c == 10) || (c == 13))
          else { complete = false;
          if (uint8_t(c) > 127) Commands += String(uint8_t(c),HEX);
          else Commands += String(c);
          } }
          „Commands“ ist der String, der dann ausgewertet wird für z.B „RING“ oder eben auf einem Display ausgegeben werden kann. Serial1 ist die Schnittstelle vom Atmega32U4 (Leonardo, Micro…) zum SIM800L.

          Die Umlaute bekommen dann die Zahl des Unicodes: ä Ä ö Ö ü Ü ß werden zu E4 C4 F6 D6 FC DC DF.

          LG Norbert

          1. Ja, besser ihr tauscht euch über andere Wege aus. Dann könnt ihr auch besser Code austauschen. Die Kommentarfelder interpretieren alles als HTML, d.h. Einrückungen sind weg und alles in eckigen Klammern, wie z.B. bei #include wir versuch als HTML Anweisung zu lesen.
            Die E-Mail an Thorsten ist raus – jetzt liegt es an ihm.

  10. Sehr informativ und übersichtlich geschrieben! Großes Lob an Dich.
    Ich habe dieses Modul mir auch geholt und mit Hilfe deine Anleitung rumprobiert.
    Was mich jetzt wundert ist, dass das Modul sich plötzlich nicht mehr mit dem Netz registieren möchte.
    Ich betreibe es an einen ESP32 die Stromquelle ist wie bei dir ein Lipo. Es kann aber nicht sein, dass das Modul defekt ist, da die AT Befehle funktionieren. Finde ich ein wenig komisch 🙁

    1. In der Tat komisch, wenn es vorher funktioniert hat. Ein LiPo sollte eigentlich genug Strom liefern um den Peak beim Verbindungsaufbau zu bewältigen. Vielleicht hilft trotzdem noch ein fetter Kondensator? Schwer, das aus der Ferne zu lösen. Wenn mir noch etwas einfällt, dann melde ich mich noch.

      1. Ja, das ist sehr komisch. Ich werde einen 3,3k uF Kondensator an den Tantalelko am Board + an den LiPo machen. Ich melde mich nochmal.

        1. Unglaublich! Es liegt am Empfang…. Ich habe das Modul mal aufm Balkon getestet und plötzlich geht es wieder… Komisch, weil es ja gestern ja auch im Raum funktioniert hatte… Dachte der Mobilfunk ist konstant. Trotzdem danke für deine Hilfe. Viele Grüße

  11. Hallo, erst einmal vielen Dank für den Beitrag. Mich würde interessieren, was das genau für eine Telekom-SIM Karte ist, bzw. wie der Tarif heißt. Denn wenn ich das richtig verstehe funktioniert das SIM800L-Modul nur mit einer 2G-SIM-Karte, aber nicht mit einer 3G/4G/LTE-Karte, wie sie in den üblichen Handys verwendet wird.

    1. Hallo, mein Vertrag nennt sich
      „Smart Connect S eco 1M“. Die Sim Karte heißt TD Triple Sim Standard. Ich könnte sie wohl auch in einem Smartphone nutzen. 2G ist damit abgedeckt. VG, Wolfgang

  12. Hallo Wolle,
    ich bin immer wiede begeistert, wie gut Arduino-Projekte hier erklärt werden!! Deswegen versuche ich mal, mein Anliegen zu plzieren, in der Hofnung, dass Sie es ebenso interessant finden 😉

    Mich würde folgendes interessieren: Haben Sie eine Lösung, wie der Arduino die Nummer des Absenders einer SMS im EEPROM ablegen könnte und diese dann für zukünftige SMS/Anrufe abrufen?

    Ich würde gerne per SMS Rufnummern für verschiedene Szenarien programmieren (Wenn der Taster an D2 gedrückt wird, ruf Bertie an, wenn Taster an D3 gedrückt wird, schreibe Oma, dass wir auf dem Weg sind).
    Und da Bertie und Oma nicht programmieren können, sollen sie ihre Nummer per SMS „programmieren“ können (z.B. mit einer SMS „KontaktOma +4917xxxxxx“).

    Leider finde ich immer nur Beipiele für einzelne Teile meines Plans (bei Ihnen zum Beispiel „Fernsteuern per SMS“, auf anderen Seiten „Auf SMS antowrten“) aber dann sind die Codes mit verschiedenen Bibliotheken und mein Wissen reicht nicht, die Codes dann sinnvoll zu kombinieren, zumal die Kommentierung meist dürftig ist 🙁

    Herzliche Grüße!
    Marie

    1. Hallo, meine erste Antwort an dieser Stelle war viel zu kompliziert. Ich habe deinen Kommentar zum Anlass genommen, einen Beitrag über EEPROMs zu machen. In ein paar Wochen kommt er raus. Ich kann die Vorgehensweise hier nur skizzieren. Du nimmst jeweils eine Telefonnummer und die Nachricht und speicherst sie durch Komma getrennt in einem String. Den String speicherst du Zeichen für Zeichen auf dem EEPROM und schließt ihn mit einem ‚\0‘ (Nullstring) ab. Das wiederholst du mit den anderen Einträgen. Du musst die lediglich die Reihenfolge merken. Wenn du dann z.B. den dritten Eintrag aufrufen willst, dann liest du den EEPROM zeichenweise von der Adresse 0 bis zu der Stelle, an der du das zweite Mal auf ‚\0‘ stößt. Ab da liest du zeichenweise weiter, bis du auf das nächste ‚\0‘ stößt. Die Zeichen fügst du zum String zusammen. Über die substring(), indexOf() und length() kannst du den Eintrag dann in Telefonnummer und Nachricht trennen und die Nachricht verschicken.
      Ich kann dir die Sketche schon mal zusenden.
      VG, Wolfgang

      1. Hallo Wolfgang, Ich danke dir für beide Einträge sehr!! Mittlerweile habe ich es geschafft, den Inhalt von SMS abhängig von bestimmten Triggerzeichen im Text in verschiedene char zu speichern – so weit zur Vorbereitung. An EEPROM hab ich mich bisher nicht getraut, wird aber der nächste Schritt sein. Einer der Links in deiner ersten Antwort hat mir da schon ein bisschen geholfen und in Kombination mit deiner zweiten Antwort, werde ich es hoffentlich bald schaffen. Ich sage Bescheid, wenn ich es hinbekommen hab.

  13. Hallo,
    ich habe gerade den Abschnitt „Versuch der Ortsbestimmung“ gelesen.
    Bei mir hat das auch plötzlich nicht mehr funktioniert. Ich habe dann etwas rumgesucht und dabei gefunden, dass nach einem Firmwareupdate der Befehl AT+CLBS=4,1 funktioniert.
    Firmware ist (AT+CGMR) Revision:1418B04SIM800L24.
    Der von SIM800 gelieferte Standort ist recht ungenau aber besser als nichts ;-).
    Bei Interesse kann ich mal den Sketch raussuchen….

  14. Hallo, ich habe versucht ein Projekt mit dem Sim 800l umzusetzen. Leider funktioniert es nicht. Können sie mir helfen. Es soll ein Weihnachtsgeschenk für meine Freundin werden.
    Zu meinem Projekt:
    Ich möchte eine LED mit einem Arduino UNO und dem SIM800l Modus verbinden. Durch SMS soll es möglich sein die LED anzumachen und eine Bestätigung, dass Licht angemacht wurde soll vom SIm800l zurück gesendet werden.

    Ich habe den Code soweit implementiert und alles verkabelt.

    Verkabelung: Stromversorgung für den Sim: 3,7V 1800 mAh Lipo Batterie ( in etwa wie auf dieser Internetseite https://elektro.turanis.de/html/prj237/index.html) nur das LED noch von Arduino weggeht.
    Code : ich würde ihnen den Code unten eingefügt. Bei Creq kommt immer 0,2.
    Sim Karte: Congstar Prepaid Karte: https://www.amazon.de/gp/product/B001ASIKDU/ref=ppx_yo_dt_b_asin_title_o00_s00?ie=UTF8&psc=1

    Das ganze funktioniert nicht wirklich. Es hat mal funktioniert aber nachdem ich es einen Tag später nochmal versucht habe hat es nicht mehr geklappt. es gibt mir immer komische Ausgaben für die AT Befehle. Die Led am Sim blinkt im Sekundentakt
    was darauf schließt das er sich nicht mit dem Netz verbindet aber er gibt mir eine gute Signalqualität und CPIn Ready wieder ( manchmal auch nicht aber es funktioniert so oder so nicht).

    Können sie mir helfen was ich falsch mache oder was das Problem ist ?

    Mit freundlichen Grüßen
    Michael März

    #include

    //Create software serial object to communicate with SIM800L
    SoftwareSerial mySerial(3, 2);

    boolean timersetted = false;
    String message;
    #define lampe 4
    const long interval = 7200; // in sekunden = 2stunden
    unsigned long previousMillis = 0;
    void setup()
    {

    pinMode(lampe, OUTPUT);
    //Begin serial communication with Arduino and Arduino IDE (Serial Monitor)
    Serial.begin(9600);

    //Begin serial communication with Arduino and SIM800L
    mySerial.begin(9600);

    Serial.println(„Initializing…“);
    delay(1000);
    mySerial.println(„AT“);
    updateSerial();
    mySerial.println(„AT+CSQ“);
    updateSerial();
    mySerial.println(„AT+CFUN=1“);
    updateSerial();
    //mySerial.println(„AT+CPIN=\“PIN\““);
    //updateSerial();
    mySerial.println(„AT+CPIN?“);
    updateSerial();
    mySerial.println(„AT+CREG?“);
    updateSerial();
    mySerial.println(„AT+CMGF=1“);
    updateSerial();
    mySerial.println(„AT+CNMI=1,2,0,0,0“);
    updateSerial();
    mySerial.println(„AT+CMGS=\“+Hier steht nummer\““);
    updateSerial();
    // zum testen ob funktioniert
    mySerial.print(„Lampe initialisiert „); //text content
    updateSerial();
    mySerial.write(26);

    }

    void loop()
    {

    unsigned long currentMillis = millis();
    if(timersetted == true){
    if ((currentMillis – previousMillis)/1000 >= interval) {
    previousMillis = currentMillis;
    digitalWrite(lampe,LOW);
    mySerial.println(„AT+CMGS=\“hier Nummer\““);//change ZZ with country code and xxxxxxxxxxx with phone number to sms
    updateSerial();
    mySerial.print(„Licht wurde ausgemacht, Schoenen Tag noch 🙂 „); //text content
    updateSerial();
    mySerial.write(26);
    timersetted =false;
    }
    }

    message=mySerial.readString();
    if(message != „“){
    Serial.println(message);
    }
    if (message.indexOf(„#on“)>=0){
    previousMillis = currentMillis;
    timersetted = true;
    digitalWrite(lampe,HIGH);
    mySerial.println(„AT+CMGS=\“+hier nummer\““);//change ZZ with country code and xxxxxxxxxxx with phone number to sms
    updateSerial();
    mySerial.print(„Licht wurde angemacht. In 2 Stunden schalte ich es automatisch aus und benachrichtige Sie. Oder sie schreiben #off. Schoenen Tag noch 🙂 „); //text content
    updateSerial();
    mySerial.write(26);
    }

    if (message.indexOf(„#off“)>=0){
    digitalWrite(lampe,LOW);
    mySerial.println(„AT+CMGS=\“+hier nummer\““);//change ZZ with country code and xxxxxxxxxxx with phone number to sms
    updateSerial();
    mySerial.print(„Licht wurde ausgemacht, Schoenen Tag noch 🙂 „); //text content
    updateSerial();
    mySerial.write(26);
    previousMillis = currentMillis;
    timersetted=false;
    }

    }

    void updateSerial()
    {
    delay(5000);
    while (Serial.available())
    {
    mySerial.write(Serial.read());//Forward what Serial received to Software Serial Port
    }
    while(mySerial.available())
    {
    Serial.write(mySerial.read());//Forward what Software Serial received to Serial Port
    }
    }

    1. Hallo Michael,

      Weihnachtsgeschenk für die Freundin – das ist natürlich eine kritische Situation!

      Wenn die LED im Sekundentakt blinkt, dann hast du keine Netzverbindung. Bei mir hat es manchmal auch etwas gedauert, bis ich Netzverbindung hatte und ich weiß nicht genau wieso. Ich habe zunächst die Rückmeldung bekommen „+CPIN: READY“ und die LED stockte kurz, aber dann ging sie wieder im Sekundentakt. Für einen weiteren Versuch musst du die Pin erneut senden. Wenn ich aber drin war, bin ich auch immer drin geblieben. Vielleicht probierst du mal in einer Schleife im setup die Pin 10 oder 20 mal zu übermitteln. Zwischen den einzelnen Versuchen müssen ein paar Sekunden liegen.

      Was mir auffällt, ist das lange delay in der Update seriell Funktion. 5 Sekunden ist sehr lang. Der Rest des Sketches ist erstmal ziemlich unerheblich. Wenn du keine Verbindung hast, dann liegt das Problem ganz am Anfang.

      Evtl. hilft auch eine bessere Antenne, dagegen spricht natürlich, dass dir das Modul sagt, die Netzqualität sei OK. Bei mir ist die Netzqualität angeblich auch gut, trotzdem hatte ich tendentiell weniger Fehlversuche mit einer guten Antenne. Oder wenn du mal rausgeht, ist es dann vielleicht besser?

      Was meinst du mit „komischen Zeichen“ auf die AT Befehle? Das klingt so als hättest du eine falsch Baudrate eingestellt. Wenn es im Sketch 9600 sind, dann müssen auch 9600 im seriellen Monitor eingestellt werden. Du kannst mir auch mal einen Screenshot schicken (Wolfgang.Ewald@wolles-elektronikkiste.de).

      Dann ist noch wichtig, dass die Batterie und der Arduino ihre GNDs verbunden haben.

      Deine Batterie sollte funktionieren. So etwas benutze ich auch. Ebenso glaube ich nicht, dass es ein Problem mit der Simkarte gibt.

      Mehr fällt mir erst einmal nicht ein.

      VG, Wolfgang

  15. Hallo Wolfgang, als Arduino- und Elektronik-Neuling freue ich mich außerordentlich über deine sorgfältigen, gut verständlichen und gründlichen Anleitungen. Das ist für mich eine tolle Hilfe, und ich kann ganz gut ermessen, wieviel Arbeit da von deiner Seite aus drinsteckt. Vielen Dank!

    Zum SoftwareSerial Sketch habe ich jetzt nur eine harmlose Frage: In der Breadboard-Schaltung sind RX und TX mit den Pins D7 und D8 verbunden. Müsste es in SoftwareSerial.ino dann nicht heißen:

    SoftwareSerial mySerial(7, 8);
    ?

    1. Hallo Thomas,

      trotz x-maligen Durchlesens gehen immer noch Fehler durch – vielen Dank! Da bin ich in der Schaltung um einen Pin verrutscht.

      Ich muss mal schauen, ob ich die Schaltung oder die Sketche anpasse.

      VG, Wolfgang

  16. Meine Erfahrung mit dem Modul ist auch gut. Ich kann noch empfehlen einen 1000uF direkt an VCC+GND am Modul anzulöten, wenn man nicht mit LiPo Akkus arbeitet, die schnell viel Strom abgeben können.
    Das Modul hatte sich bei mir sonst manchmal resettet wenn spontan ein hoher Strom gezogen wurde (Stichwort „burst“)

  17. Hallo Wolfgang,

    wieder einmal ein sehr ausführlicher und schöner Beitrag von dir!
    Herzlichen Dank!

    Ich hätte da mal eine andere Frage, hast du Erfahrungen mit der TR-064 SOAP Library? Hier kämpfe ich gerade. Immer wenn ich diese Bibliothek in meinen Arduino Sketch einbaue, gibt es einen Compiler Fehler, egal, welches Board ich auswähle.

    exit status 1
    Fehler beim Kompilieren für das Board NodeMCU 0.9 (ESP-12 Module)

    Schöne Grüße von der Nordseeküste aus Wilhelmshaven
    Enno Jürgens

    1. Hallo Enno, diese Bibliothek ist mir noch nicht über den Weg gelaufen, sieht aber sehr interessant aus. Ich schaue sie mir sicherlich mal an, aber ich glaube „für mal eben auf die Schnelle“ ist das wahrscheinlich nichts. Bleibt wohl nur der Weg über Foren oder du meldest die Fehler direkt als Issue auf GitHub. VG, Wolfgang

  18. Danke wieder einmal für den, wie immer, äußerst lehrreichen Beitrag. Irgendwann wirst du ein Buch daraus binden müssen.
    Das SIM800L hatte ich schon vor einiger Zeit entdeckt. Was ich daraus gemacht habe:
    Die FeTap612 der Bundespost von 1973 sowie die W48 von 1955 zu einem Retro-Handy umgebaut. Muss noch etwas an der Software drehen, dann hat es Serienreife, dann gibt es auch Pläne auf Github.
    https://makeprojects.com/project/retro-handy-fetap-gsm

    1. Falls es jemanden interessiert oder jemand sehen möchte, wie man das SIM800L im Real Life benutzen kann:
      Die Pläne für die zum Mobiltelefon umfunktionierten Telefone „FeTap-612“ (Bundespost-Telefon der 70er) und das „W48-GSM“ (Bundespost-Telefon aus Bakelit der 50er und 50er) sind veröffentlicht. Schaltplan, Platine, Software , Bedienungsanleitung. Software wird irgendwann noch auf Stromsparen optimiert, sobald das „Power Profiler Kit II“ mal lieferbar ist. Ansonsten ist alles stabil.
      Here we go:
      https://github.com/Pontifex42/W48-GSM
      https://github.com/Pontifex42/FeTap-GSM

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert