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 Anruf (auch für SMS einstellbar); 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.

 

9 thoughts on “SIM800L Modul

  1. 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

  2. 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“)

  3. 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

  4. 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

Schreibe einen Kommentar

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