Bauteile · 16 Min. Lesezeit

SIM800L mit Arduino: SMS senden, Relais schalten und anrufen

SIM800L GSM-Modul am Arduino: Stromversorgung mit 4 V und 2 A, LED-Blinkcodes, AT-Befehle, SMS senden, Relais per SMS schalten, Anrufe, Code für ESP32 und Pico.

Das SIM800L GSM-Modul ist ein winziges, sehr günstiges 2G-Modem in Briefmarkengröße, das deinem Arduino-Projekt eine eigene Telefonleitung gibt. Mit einer eingelegten Micro-SIM-Karte kannst du SMS senden und empfangen, Anrufe tätigen und über GPRS kleine Datenmengen ins Internet schicken. Wo WLAN und Bluetooth nicht hinreichen, etwa im Gartenhaus, Gewächshaus, Lager oder Fahrzeug, ist ein SIM800L am Arduino der einfachste Weg, ein Gerät von überall mit Mobilfunkempfang fernzusteuern. Das Modul spricht über eine zweiadrige serielle Verbindung (UART) mit dem Arduino und wird mit kurzen Textbefehlen gesteuert, den sogenannten AT-Befehlen.

Allerdings gehört der SIM800L zu den Modulen, die Einsteigern den meisten Ärger machen, und fast alle Probleme haben zwei Ursachen: eine unzureichende Stromversorgung und fehlende 2G-Abdeckung. In dieser Anleitung lernst du, das Modul passend zu seinem Bereich von 3,4–4,4 V und 2 A Spitzenstrom zu versorgen, was dir die Blinkfrequenz der LED auf der Platine verrät, wie du es Schritt für Schritt mit AT-Befehlen testest, wie du mit einem Arduino Uno eine SMS sendest, ein Relais per SMS ein- und ausschaltest und eine Schaltung baust, die dich bei Alarm anruft. Danach machst du dasselbe mit dem ESP32, dem fertigen TTGO-T-Call-Board und dem Raspberry Pi Pico, und am Ende findest du die Lösungen für Probleme bei der Netzanmeldung in einer Tabelle.

SIM800L GSM/GPRS-Modul mit Spiralantenne
SIM800L-Platine: oben die Spiralantenne, daneben ein Stützkondensator und zwei Stiftleisten; auf der Rückseite der Platine (unten) sitzt der Micro-SIM-Halter.

Was ist der SIM800L und wie funktioniert er?

Der SIM800L ist ein GSM/GPRS-Modul von SIMCom und misst nur 17,8 × 15,8 mm. Die rote Platine, die du kaufst, ist ein kleines Breakout-Board, das um das Modul herum einen SIM-Halter, einen Antennenanschluss, eine Status-LED und Stiftleisten ergänzt. Das Modul durchsucht automatisch alle vier GSM-Bänder (850, 900, 1800 und 1900 MHz), meldet sich wie ein Handy im Netz an und führt dann die Befehle aus, die über die serielle Schnittstelle kommen: „Schick diese Nachricht an diese Nummer“, „Ruf diese Nummer an“, „Gib eingehende Nachrichten an mich weiter“ und so weiter. Stell es dir als Handy ohne Display und Tastatur vor; beides übernimmt der Arduino. Schließt du ein Mikrofon und einen Lautsprecher an die Pins MIC und SPK an, kannst du sogar richtig telefonieren.

MerkmalWert
ModulSIMCom SIM800L, 2G GSM/GPRS
FrequenzbänderQuad-Band: GSM 850, EGSM 900, DCS 1800, PCS 1900 MHz
Versorgungsspannung3,4–4,4 V (empfohlen 4,0 V)
SpitzenstromBis zu 2 A (kurze Impulse beim Senden)
Mittlerer StromAusgeschaltet ~0,1 mA, Schlaf ~1–2 mA, Leerlauf ~15 mA, Sprachanruf 130–220 mA, GPRS 150–450 mA (je nach Band und Datenblattversion)
Sendeleistung2 W (850/900 MHz), 1 W (1800/1900 MHz)
SchnittstelleUART und AT-Befehle; Autobauding 1200–115200
LogikpegelAusgang 2,8 V; RXD-Eingang max. 3,1 V
SIM-KarteMicro-SIM (1,8-V- und 3-V-Karten)
GPRS-GeschwindigkeitBis zu 85,6 kbit/s
Betriebstemperatur-40 bis +85 °C

SIM800L-Pinbelegung

PinFunktionHinweis
NETAntennenanschlussHier wird die Spiralantenne angelötet; gibt es eine u.FL-Buchse (IPEX), kommt dort eine externe Antenne dran
VCCVersorgung (+)3,4–4,4 V; niemals an den 5V- oder 3.3V-Pin des Arduino
RSTHardware-ResetMindestens 105 ms auf LOW gezogen, startet das Modul neu; kann offen bleiben
RXDSerieller Eingang des ModulsZum TX-Pin des Boards; max. 3,1 V
TXDSerieller Ausgang des ModulsZum RX-Pin des Boards; 2,8-V-Pegel
GNDMasseMit der Stromquelle und dem Arduino verbinden (gemeinsame Masse)
RINGAnruf-/SMS-SignalGeht bei eingehendem Anruf auf LOW und gibt bei einer SMS einen 120-ms-LOW-Impuls aus
DTRSchlafsteuerungMit AT+CSCLK=1 schläft das Modul, solange DTR HIGH ist, und wacht bei LOW auf
MIC+ / MIC−MikrofoneingangFür ein Elektretmikrofon
SPK+ / SPK−LautsprecherausgangEin kleiner 8-Ω-Lautsprecher kann angeschlossen werden

Die beiliegende Spiralantenne wird an das Loch NET in der Ecke der Platine gelötet; manche Platinen haben zusätzlich eine kleine u.FL-Buchse (IPEX) für eine externe Antenne. Ohne Antenne findet das Modul kein Netz und die Signalstärke liegt nahe null; ist der Empfang im Haus schwach, bringt eine Klebeantenne mit Kabel gegenüber der Spirale einen deutlichen Unterschied. Die Micro-SIM kommt in den Halter auf der Rückseite, mit der abgeschrägten Ecke passend zur Zeichnung auf dem Halter. Bevor du die Karte einlegst, deaktiviere die PIN-Abfrage in einem Handy und stell sicher, dass die Karte SMS senden und telefonieren kann und genug Guthaben hat.

Stromversorgung: 3,4–4,4 V und 2 A Spitzenstrom

Die Stromversorgung ist der kritischste Punkt beim SIM800L und der, bei dem am häufigsten Fehler passieren. GSM arbeitet im Zeitmultiplex: Innerhalb jedes 4,615 ms langen Rahmens sendet das Modul nur in seinem eigenen 577 µs langen Zeitschlitz. In diesen kurzen Momenten zieht es bis zu 2 A, gleich danach fällt der Strom wieder auf einige zehn Milliampere. Kann die Quelle diesen plötzlichen Strom nicht liefern, bricht die Spannung ein. Laut SIMCom-Datenblatt meldet das Modul bei 3,5 V über die serielle Schnittstelle UNDER-VOLTAGE WARNNING, unter 3,4 V schreibt es UNDER-VOLTAGE POWER DOWN und schaltet sich ab (der Tippfehler in WARNNING stammt aus der Firmware des Herstellers). Nach oben hin kommt bei 4,3 V die Warnung OVER-VOLTAGE WARNNING, über 4,4 V schaltet das Modul ebenfalls ab. Bei manchen Firmware-Versionen ist diese automatische Abschaltung ab Werk deaktiviert und wird mit AT+CBATCHK=1 eingeschaltet; aber auch dann arbeitet das Modul außerhalb dieser Grenzen instabil und startet immer wieder neu. Deshalb ist der 5V-Pin des Arduino zu hoch für den SIM800L. Der 3.3V-Pin liegt unter dem Minimum und ist offiziell nur mit 50 mA belastbar; außerdem liefert ein USB-Port am Computer höchstens 500 mA.

VersorgungGeeignet?Erläuterung
Einzelliger 3,7-V-LiPo- oder 18650-Li-Ionen-AkkuJa, am einfachstenVoll geladen 4,2 V; läuft problemlos, bis die Zelle auf 3,6–3,7 V sinkt, darunter kann es bei Sendeimpulsen abschalten. Wähle mindestens 1000 mAh mit 2 A Belastbarkeit und lade mit einem TP4056
LM2596-Step-down-Modul (Buck)Ja, für Projekte mit NetzteilAus einem 7–12-V-Netzteil auf 4,0–4,1 V einstellen; liefert bis zu 3 A
SIM800L-Platinen mit 5-V-Eingang (z. B. „SIM800L V2“)Ja, nach Anleitung der PlatineDie Schaltung auf der Platine senkt die Spannung; du brauchst trotzdem ein 5-V-Netzteil, das 2 A liefert
5V-Pin des ArduinoNeinÜberschreitet die 4,4-V-Grenze, das Modul schaltet ab oder nimmt Schaden; USB liefert keine 2 A
3.3V-Pin des ArduinoNeinUnter 3,4 V und viel zu wenig Strom; das Modul startet nicht oder startet ständig neu
3,3-V-Regler wie der AMS1117Nein3,3 V liegen unter dem Minimum des Moduls
LM2596
LM2596
18650 Li-Ion
18650 Li-Ion
TP4056
TP4056
Wenn du einen LM2596 verwendest, stell seinen Ausgang am Trimmer auf 4,0–4,1 V ein und miss dabei mit dem Multimeter, bevor du den SIM800L anschließt. Ab Werk kann der Regler auf einen beliebigen Wert eingestellt sein; eine Ausgangsspannung nahe den 12 V am Eingang zerstört den SIM800L in der ersten Sekunde. Bei Akkubetrieb lädst du die Zelle mit einem TP4056-Lademodul und achtest darauf, sie nicht verpolt anzuschließen; die SIM800L-Platine hat keinen Verpolungsschutz.
Setze einen 470–1000 µF Low-ESR-Elektrolytkondensator und einen 100-nF-Keramikkondensator zwischen VCC und GND, so nah wie möglich an die Pins des Moduls; SIMCom empfiehlt im eigenen Referenzdesign mindestens 100 µF mit niedrigem ESR. Der Kondensator liefert die 2-A-Impulse anstelle der Stromquelle und verhindert, dass die Spannung einbricht; wie er funktioniert, erklären wir in Was ist ein Kondensator?. Halte die Versorgungsleitungen kurz und dick, leite keine 2 A über die Federkontakte eines Steckbretts und verbinde GND des Moduls unbedingt mit GND des Arduino.

Was sagt dir die LED? Die Blinkcodes erklärt

LED-VerhaltenBedeutungWas tun?
AusDas Modul läuft nichtVersorgung und Polung von VCC–GND prüfen, Spannung messen
Etwa einmal pro Sekunde (64 ms an, 800 ms aus)Läuft, aber nicht im Netz angemeldetIn den ersten 10–60 Sekunden normal; dauert es länger, SIM, PIN, Antenne und 2G-Abdeckung prüfen
Etwa alle 3 Sekunden (64 ms an, 3000 ms aus)Im Netz angemeldetBereit für SMS und Anrufe
Sehr schnell, etwa 3-mal pro Sekunde (64 ms an, 300 ms aus)GPRS-Datenverbindung aktivEine Internetverbindung steht
Blinkt ein paarmal, geht aus und startet neuDie Spannung bricht ein, das Modul schaltet abStärkere Quelle, großer Kondensator, kurze und dicke Kabel

Gewöhne dir an, die LED als Diagnosewerkzeug zu nutzen: Siehst du schon vor dem Programmieren, dass das Modul auf Blinken alle 3 Sekunden wechselt, ist die Hälfte der möglichen Fehler ausgeschlossen. Blinkt das Modul minutenlang einmal pro Sekunde, bringt Herumprobieren an der Software nichts; schau dir zuerst den Abschnitt zur Netzanmeldung weiter unten an. Die größten Stromimpulse treten genau bei der Anmeldung auf, wenn das Modul zum ersten Mal mit der Basisstation spricht; ist die Versorgung schwach, schaltet das Modul genau dann ab und alles beginnt von vorn.

SIM800L am Arduino anschließen: Verkabelung und Pegelanpassung

Der SIM800L kommuniziert per UART mit dem Arduino, und die Datenleitungen werden gekreuzt: Der TXD-Pin des Moduls geht an den RX-Pin des Boards, der RXD-Pin des Moduls an den TX-Pin des Boards. Die einzige Hardware-Schnittstelle des Arduino Uno (D0 und D1) wird für den Upload per USB und den seriellen Monitor gebraucht, deshalb schließen wir das Modul mit SoftwareSerial an D2 und D3 an; SoftwareSerial arbeitet bei 9600 Baud zuverlässig. Beim ESP32 und Pico brauchst du keine Software-Schnittstelle, dort kommen Hardware-UARTs zum Einsatz. Die Grundlagen der seriellen Kommunikation findest du in unserem Beitrag zur seriellen UART-Kommunikation.

SIM800L-PinArduino UnoESP32Raspberry Pi Pico
VCCExterne 4,0 V (+)Externe 4,0 V (+)Externe 4,0 V (+)
GNDGND + Minus der QuelleGND + Minus der QuelleGND + Minus der Quelle
TXDD2 (SoftwareSerial RX)GPIO 16 (RX2)GP1 (UART0 RX)
RXDD3, über Spannungsteiler 10 kΩ + 15 kΩGPIO 17 (TX2), über Spannungsteiler 1 kΩ + 5,6 kΩGP0 (UART0 TX), über Spannungsteiler 1 kΩ + 5,6 kΩ
RSTKann offen bleibenKann offen bleibenKann offen bleiben
NETAntenneAntenneAntenne
Laut Datenblatt verträgt der RXD-Eingang des SIM800L höchstens 3,1 V. Der D3-Pin des Uno liefert 5 V, also gehört ein Spannungsteiler dazwischen: D3 → 10 kΩ → RXD und RXD → 15 kΩ → GND ergibt etwa 3,0 V. Der im Netz oft gezeigte Teiler aus 10 kΩ + 20 kΩ liefert 3,3 V; das funktioniert meistens, liegt aber leicht über der Herstellergrenze. Für den 3,3-V-Ausgang von ESP32 und Pico ergeben die von SIMCom empfohlenen Widerstände, 1 kΩ in Reihe + 5,6 kΩ nach GND, etwa 2,8 V. In der Gegenrichtung liest der Uno das 2,8-V-Signal von TXD meist richtig, sein Datenblatt verlangt bei 5 V aber 3,0 V für HIGH; in einem dauerhaften Aufbau ist ein bidirektionaler Pegelwandler die sauberste Lösung.

Erster Test mit AT-Befehlen

  1. Schließ das Modul wie in der Tabelle an, befestige die Antenne und lege eine Micro-SIM mit deaktivierter PIN-Abfrage ein.
  2. Schalte die Versorgung ein und beobachte die LED: Nach einigen Sekunden Blinken im Sekundentakt sollte sie auf Blinken alle 3 Sekunden wechseln.
  3. Lade den Brücken-Sketch unten auf den Arduino; SoftwareSerial gehört zur Arduino IDE, eine zusätzliche Bibliothek ist nicht nötig.
  4. Öffne den seriellen Monitor, stell 9600 Baud und als Zeilenende Both NL & CR ein (in der deutschen IDE „Sowohl NL als auch CR“).
  5. Tippe AT und drück Enter. Das Modul passt sich per Autobauding deiner Geschwindigkeit an; die ersten Versuche bleiben eventuell ohne Antwort, wiederhole, bis OK erscheint.
  6. Prüfe dann mit den Befehlen aus der Tabelle unten nacheinander SIM-Karte, Signalstärke und Netzanmeldung.
Arduino (C++)
1#include <SoftwareSerial.h>
2
3SoftwareSerial sim800(2, 3);        // RX = D2 (SIM800L TXD), TX = D3 (SIM800L RXD, bölücüyle / via divider)
4
5void setup() {
6  Serial.begin(9600);               // Seri Monitör hızı / Serial Monitor speed
7  sim800.begin(9600);               // SIM800L bu hıza kendini ayarlar / SIM800L autobauds to this rate
8  Serial.println(F("AT yaz ve Enter'a bas / Type AT and press Enter"));
9}
10
11void loop() {
12  if (Serial.available()) sim800.write(Serial.read());   // bilgisayar → modül / PC → module
13  if (sim800.available()) Serial.write(sim800.read());   // modül → bilgisayar / module → PC
14}
BefehlBeispielantwortBedeutung
ATOKDas Modul läuft und die Baudrate passt
AT+CPIN?+CPIN: READYSIM ist bereit; bei SIM PIN die PIN deaktivieren oder AT+CPIN="1234" senden
AT+CSQ+CSQ: 18,0Signalstärke von 0 bis 31 (99 = unbekannt); ab 10 reicht es
AT+CREG?+CREG: 0,11 = angemeldet, 5 = angemeldet (Roaming), 2 = sucht, 3 = abgelehnt
AT+COPS?+COPS: 0,0,"NETZBETREIBER"Name des Netzbetreibers
AT+CBC+CBC: 0,82,4012Versorgungsspannung in Millivolt (hier 4,012 V)
AT+GSN15-stellige ZahlIMEI des Moduls
AT+CCID19- bis 20-stellige ZahlSeriennummer der SIM-Karte (ICCID); zeigt, dass die Karte gelesen wird
AT+CMGF=1OKTextmodus für SMS
AT+CMGS="+905551112233">Wartet auf den Nachrichtentext; Senden mit Strg+Z (26)
AT+CNMI=1,2,0,0,0OKGibt eingehende SMS direkt seriell aus, ohne sie zu speichern
ATD+905551112233;OKStartet einen Sprachanruf (das ; am Ende ist Pflicht)
ATA / ATHOKNimmt einen Anruf an / legt auf
AT+CLIP=1OKZeigt bei eingehenden Anrufen die Nummer in einer +CLIP-Zeile
AT+IPR=9600OKLegt die Geschwindigkeit fest auf 9600 Baud statt Autobauding; mit anschließendem AT&W bleibt sie dauerhaft
AT+CMEE=2OKGibt Fehler als Klartext statt als Zahl aus

Aus der ersten Zahl der Antwort auf AT+CSQ kannst du die Signalstärke in dBm berechnen: dBm ≈ −113 + 2 × Wert. 18 entspricht zum Beispiel etwa −77 dBm und ist recht gut; unter 10 ist schwach, und unter 5 kommt selbst eine SMS kaum noch durch. Die Antwort 99 bedeutet, dass das Modul noch nicht messen konnte. Der Befehl AT+CBC eignet sich perfekt, um Versorgungsprobleme aufzuspüren: Zeigt er im Leerlauf etwa 4,0 V, das Modul schaltet aber beim Senden einer SMS oder beim Anrufen ab, liegt das Problem eindeutig an der Strombelastbarkeit deiner Quelle. Im voreingestellten Autobaud-Modus gibt das Modul beim Start nichts aus; legst du die Geschwindigkeit mit AT+IPR=9600 fest und speicherst sie mit AT&W, bleibt die Einstellung dauerhaft erhalten und das Modul meldet sich bei jedem Start mit RDY, +CFUN: 1 und +CPIN: READY betriebsbereit.

Keine Netzanmeldung? 2G-Abdeckung, SIM und IMEI

Der SIM800L nutzt ausschließlich das 2G-Netz (GSM/GPRS); 3G, 4G oder 5G kennt er nicht. In Deutschland betreiben die Netzbetreiber 2G noch, die Telekom plant die Abschaltung jedoch zum 30. Juni 2028, und auch bei den anderen Anbietern ist das Ende absehbar. In der Schweiz ist 2G seit Anfang 2023 komplett abgeschaltet, in Frankreich verschwindet es bis Ende 2026, in den USA ging das letzte 2G-Netz im August 2026 vom Netz und in Australien schon vor Jahren. Wo es kein 2G gibt, kann sich der SIM800L nicht anmelden, egal wie gut er versorgt ist; dort brauchst du ein 4G-LTE-Modul wie den SIM7600 oder A7670 bzw. ein LTE-M/NB-IoT-Modul wie den SIM7080G. Für ein Projekt, das viele Jahre laufen soll, ist das auch in Deutschland schon heute die zukunftssichere Wahl. Bei Anmeldeproblemen gehst du in dieser Reihenfolge vor:

  • Gibt es bei dir 2G? Stell in den Mobilfunkeinstellungen deines Handys den bevorzugten Netztyp auf „nur 2G“ und versuch, mit derselben SIM-Karte zu telefonieren. Findet das Handy im 2G-Modus kein Netz, findet es der SIM800L auch nicht.
  • Wird die SIM-Karte gelesen? AT+CCID sollte eine Nummer liefern und AT+CPIN? mit +CPIN: READY antworten. Bei einem Fehler legst du die Karte richtig herum neu ein; verwendest du eine Nano-SIM im Adapter, achte darauf, dass der Adapter nicht ungleichmäßig auf die Kontakte drückt.
  • Reicht das Signal? AT+CSQ sollte mindestens 10 ergeben. Löte die Antenne an oder schließe eine externe an und stell das Modul ans Fenster.
  • Wird die Anmeldung abgelehnt? Antwortet AT+CREG? mit 0,3, weist das Netz das Modul ab: Die Karte kann gesperrt oder die IMEI des Geräts blockiert sein.
  • IMEI-Registrierung: Manche Länder sperren Geräte, deren IMEI nicht registriert ist; in der Türkei etwa werden unregistriert eingeführte Geräte nach einer Übergangsfrist abgeschaltet. Lies die IMEI des Moduls mit AT+GSN aus und kaufe in solchen Ländern bei einem lokalen Händler, der Module mit registrierter IMEI anbietet.
  • Reicht die Versorgung? Startet das Modul genau bei der Anmeldung neu, liegt das Problem nicht am Netz, sondern an der Stromversorgung; geh zurück zum Abschnitt Stromversorgung.

SMS mit dem Arduino senden

Um eine SMS zu senden, schaltest du zuerst mit AT+CMGF=1 in den Textmodus. Danach folgt AT+CMGS="+905551112233"; am sichersten schreibst du die Nummer mit Ländervorwahl (+90 im Beispiel ist die Türkei, für Deutschland nimmst du +49, für Österreich +43, für die Schweiz +41). Das Modul antwortet mit dem Prompt > und wartet auf den Text. Nach dem Text sendest du statt Enter das Zeichen Strg+Z (ASCII 26, 0x1A); sobald das Netz die Nachricht angenommen hat, liefert das Modul eine Referenznummer wie +CMGS: 12 und danach OK. Diese Bestätigung kann ein paar Sekunden, bei schwachem Signal bis zu 60 Sekunden dauern. Der Sketch unten synchronisiert sich mit dem Modul, wartet auf die Netzanmeldung und sendet eine einzige SMS; trag in der Zeile PHONE deine eigene Nummer ein:

Arduino (C++)
1#include <SoftwareSerial.h>
2
3SoftwareSerial sim800(2, 3);                // RX = D2 ← SIM TXD, TX = D3 → SIM RXD
4const char PHONE[] = "+905551112233";      // kendi numaran, uluslararası biçimde / your number, international format
5
6// ok gelirse 1, ERROR gelirse -1, süre dolarsa 0 / 1 on ok, -1 on ERROR, 0 on timeout
7int waitReply(const char *ok, unsigned long timeoutMs) {
8  const char *err = "ERROR";
9  byte m1 = 0, m2 = 0;
10  unsigned long start = millis();
11  while (millis() - start < timeoutMs) {
12    if (!sim800.available()) continue;
13    char c = sim800.read();
14    Serial.write(c);                        // modülün cevabını göster / show the module's reply
15    m1 = (c == ok[m1]) ? m1 + 1 : (c == ok[0] ? 1 : 0);
16    if (ok[m1] == '\0') return 1;
17    m2 = (c == err[m2]) ? m2 + 1 : (c == err[0] ? 1 : 0);
18    if (err[m2] == '\0') return -1;
19  }
20  return 0;
21}
22
23// Şebeke kaydını bekle: +CREG: 0,1 (ev ağı) ya da 0,5 (dolaşım) / wait for registration: home or roaming
24bool waitForNetwork(unsigned long timeoutMs) {
25  unsigned long start = millis();
26  while (millis() - start < timeoutMs) {
27    sim800.println("AT+CREG?");
28    String reply = "";
29    unsigned long t = millis();
30    while (millis() - t < 1000) {
31      while (sim800.available()) reply += (char)sim800.read();
32    }
33    Serial.print(reply);
34    if (reply.indexOf("+CREG: 0,1") >= 0 || reply.indexOf("+CREG: 0,5") >= 0) return true;
35    delay(2000);
36  }
37  return false;
38}
39
40bool sendSms(const char *number, const char *text) {
41  sim800.print("AT+CMGS=\"");
42  sim800.print(number);
43  sim800.print("\"\r");
44  if (waitReply(">", 5000) != 1) return false;   // metin istemi gelmedi / no text prompt
45  sim800.print(text);
46  sim800.write(26);                               // Ctrl+Z (0x1A): mesajı gönder / send the message
47  return waitReply("+CMGS:", 60000) == 1;         // ağ onayı 60 sn sürebilir / network ack may take 60 s
48}
49
50void setup() {
51  Serial.begin(9600);
52  sim800.begin(9600);
53  delay(3000);                                    // modül açılsın / let the module boot
54
55  bool alive = false;
56  for (byte i = 0; i < 10 && !alive; i++) {       // otomatik baud için birkaç kez AT / several ATs for autobaud
57    sim800.println("AT");
58    alive = (waitReply("OK", 1000) == 1);
59  }
60  if (!alive) {
61    Serial.println(F("\nModul cevap vermiyor / Module not responding"));
62    return;
63  }
64
65  sim800.println("AT+CMGF=1");                    // SMS metin modu / SMS text mode
66  waitReply("OK", 1000);
67
68  Serial.println(F("\nSebeke bekleniyor / Waiting for network"));
69  if (!waitForNetwork(60000)) {
70    Serial.println(F("Sebekeye kayit olunamadi / Not registered"));
71    return;
72  }
73
74  if (sendSms(PHONE, "BlueGrays: SIM800L calisiyor!")) Serial.println(F("\nSMS gonderildi / SMS sent"));
75  else Serial.println(F("\nSMS gonderilemedi / SMS failed"));
76}
77
78void loop() {
79  if (sim800.available()) Serial.write(sim800.read());   // sonraki mesajları göster / show later messages
80}

Im Sketch gibt die Funktion waitReply() jedes Zeichen vom Modul im seriellen Monitor aus und sucht dabei nach der erwarteten Antwort (OK, > oder +CMGS:) und dem Wort ERROR; so siehst du das Ergebnis jedes Befehls. waitForNetwork() wartet, bis die +CREG-Antwort 0,1 (Heimnetz) oder 0,5 (Roaming) zeigt, denn eine SMS vor der Anmeldung schlägt fehl. Im Textmodus darf eine SMS höchstens 160 Zeichen lang sein. Umlaute gehören zwar zum GSM-Alphabet, aus dem Sketch kommen sie aber als UTF-8 und werden verstümmelt dargestellt; schreib deshalb ae, oe, ue und ss, wie im Beispiel ohne Sonderzeichen.

Jede SMS kostet Geld. Schreib SMS-Code niemals ohne Bedingung in loop(): Ein Fehler, der jede Sekunde auslöst, bedeutet in wenigen Minuten Hunderte Nachrichten und eine hohe Rechnung. Bei wiederkehrenden Ereignissen wie Alarmen legst du mit millis() eine Wartezeit zwischen zwei Nachrichten fest; wie das geht, steht in unserem Beitrag millis() und delay().

Relais per SMS schalten und per Anruf umschalten

Zum Lesen eingehender Nachrichten verwenden wir AT+CNMI=1,2,0,0,0: Damit speichert das Modul neue SMS nicht auf der SIM-Karte, sondern gibt sie direkt als zwei Zeilen seriell aus. Die erste Zeile, etwa +CMT: "+905551112233","","26/10/30,14:05:12+12", enthält Absendernummer und Zeit (das +12 am Ende ist die Zeitzone in Viertelstunden, hier UTC+3), die zweite Zeile die Nachricht selbst. Der Sketch unten steuert ein Relaismodul an D7 mit den Nachrichten „ROLE AC“ (Relais an), „ROLE KAPA“ (Relais aus) und „DURUM“ (Status), schickt nach jedem Befehl eine Antwort-SMS und akzeptiert nur Nachrichten von deiner eigenen Nummer; die Befehle kannst du im Code natürlich in EIN, AUS und STATUS umbenennen. Dank AT+CLIP=1 wird außerdem dein Anruf beim Modul abgewiesen, ohne angenommen zu werden, und das Relais schaltet um; da ein nicht angenommener Anruf nichts kostet, ist das der günstigste Fernschalter überhaupt. Manche Netze übermitteln die Absendernummer im nationalen Format (mit führender 0) statt international; werden Befehle ignoriert, schau dir die +CMT-Zeile im seriellen Monitor an und trag OWNER im selben Format ein.

Arduino (C++)
1#include <SoftwareSerial.h>
2
3SoftwareSerial sim800(2, 3);                 // RX = D2 ← SIM TXD, TX = D3 → SIM RXD
4const byte RELAY_PIN = 7;                    // röle modülü IN / relay module IN
5const bool RELAY_ON = HIGH;                  // düşük seviyeli modülde LOW yap / set LOW for active-low modules
6const char OWNER[] = "+905551112233";        // komut kabul edilen tek numara / the only accepted number
7
8char line[100];                              // gelen satır tamponu / incoming line buffer
9byte lineLen = 0;
10bool bodyNext = false;                       // sonraki satır SMS metni mi? / is the next line the SMS text?
11bool fromOwner = false;
12bool relayState = false;
13
14int waitReply(const char *ok, unsigned long timeoutMs) {
15  const char *err = "ERROR";
16  byte m1 = 0, m2 = 0;
17  unsigned long start = millis();
18  while (millis() - start < timeoutMs) {
19    if (!sim800.available()) continue;
20    char c = sim800.read();
21    Serial.write(c);
22    m1 = (c == ok[m1]) ? m1 + 1 : (c == ok[0] ? 1 : 0);
23    if (ok[m1] == '\0') return 1;
24    m2 = (c == err[m2]) ? m2 + 1 : (c == err[0] ? 1 : 0);
25    if (err[m2] == '\0') return -1;
26  }
27  return 0;
28}
29
30bool sendSms(const char *number, const char *text) {
31  sim800.print("AT+CMGS=\"");
32  sim800.print(number);
33  sim800.print("\"\r");
34  if (waitReply(">", 5000) != 1) return false;
35  sim800.print(text);
36  sim800.write(26);                          // Ctrl+Z: gönder / send
37  return waitReply("+CMGS:", 60000) == 1;
38}
39
40void setRelay(bool on) {
41  relayState = on;
42  digitalWrite(RELAY_PIN, on ? RELAY_ON : !RELAY_ON);
43}
44
45void handleCommand(char *text) {
46  for (char *p = text; *p; p++) *p = toupper(*p);       // büyük harfe çevir / convert to upper case
47  if (strstr(text, "ROLE AC")) {
48    setRelay(true);
49    sendSms(OWNER, "Role ACILDI / Relay ON");
50  } else if (strstr(text, "ROLE KAPA")) {
51    setRelay(false);
52    sendSms(OWNER, "Role KAPANDI / Relay OFF");
53  } else if (strstr(text, "DURUM")) {
54    sendSms(OWNER, relayState ? "Role ACIK / Relay ON" : "Role KAPALI / Relay OFF");
55  }
56}
57
58void handleLine() {
59  Serial.println(line);
60  if (bodyNext) {                            // +CMT satırından sonraki satır SMS metnidir / the line after +CMT is the SMS text
61    bodyNext = false;
62    if (fromOwner) handleCommand(line);
63  } else if (strncmp(line, "+CMT:", 5) == 0) {
64    fromOwner = (strstr(line, OWNER) != NULL);           // gönderen kontrolü / sender check
65    bodyNext = true;
66  } else if (strncmp(line, "+CLIP:", 6) == 0 && strstr(line, OWNER) != NULL) {
67    sim800.println("ATH");                   // aramayı reddet, ücret yazılmaz / reject the call, nothing is charged
68    setRelay(!relayState);                   // her çağrıda aç-kapa / toggle on every call
69  }
70}
71
72void setup() {
73  pinMode(RELAY_PIN, OUTPUT);
74  setRelay(false);
75  Serial.begin(9600);
76  sim800.begin(9600);
77  delay(3000);
78  for (byte i = 0; i < 10; i++) {            // otomatik baud eşleşmesi / autobaud sync
79    sim800.println("AT");
80    if (waitReply("OK", 1000) == 1) break;
81  }
82  const char *initCmds[] = {"ATE0", "AT+CMGF=1", "AT+CNMI=1,2,0,0,0", "AT+CLIP=1"};
83  for (byte i = 0; i < 4; i++) {
84    sim800.println(initCmds[i]);             // yankı kapalı, metin modu, SMS'i ilet, arayanı göster / echo off, text mode, push SMS, caller ID
85    waitReply("OK", 1000);
86  }
87  Serial.println(F("\nHazir / Ready"));
88}
89
90void loop() {
91  while (sim800.available()) {
92    char c = sim800.read();
93    if (c == '\r') continue;
94    if (c == '\n') {                         // satır tamamlandı / line complete
95      line[lineLen] = '\0';
96      if (lineLen > 0) handleLine();
97      lineLen = 0;
98    } else if (lineLen < sizeof(line) - 1) {
99      line[lineLen++] = c;
100    }
101  }
102}
Code-ElementWas es macht
ATE0Schaltet das Echo ab, das Modul wiederholt gesendete Befehle nicht mehr; die eingehenden Zeilen werden übersichtlicher
AT+CNMI=1,2,0,0,0Gibt eine neue SMS als +CMT-Zeile mit direkt folgendem Nachrichtentext seriell aus
AT+CLIP=1Meldet bei einem Anruf nach RING die Nummer des Anrufers in einer +CLIP-Zeile
strstr(line, OWNER)Prüft, ob die berechtigte Nummer in der Zeile steht; Befehle anderer Nummern werden ignoriert
toupper()Wandelt den Text in Großbuchstaben um, damit „role ac“ und „ROLE AC“ gleich behandelt werden
ATHBeendet den eingehenden Anruf, ohne ihn anzunehmen
RELAY_ONFür Relaismodule, die bei LOW schalten (active-low), auf LOW setzen
Schaltest du mit dem Relais 230 V Netzspannung, verdrahte nur bei gezogenem Netzstecker und berühre niemals die Hochspannungsseite; ohne Erfahrung probierst du es zuerst mit einer LED oder einer 12-V-Last. Bedenke außerdem, dass die in einer SMS angezeigte Absendernummer gefälscht werden kann. Steuerst du etwas Wichtiges wie ein Türschloss oder eine Heizung, hänge an den Befehl ein Passwort an, das nur du kennst (zum Beispiel „ROLE AC 4827“), und prüfe es im Code mit.

Mit dem SIM800L anrufen: Bei Alarm ruft er dich an

Für einen Anruf schreibst du nach dem Befehl ATD die Nummer und ein Semikolon: ATD+905551112233;. Das Semikolon am Ende kennzeichnet einen Sprachanruf; vergisst du es, startet das Modul einen Datenanruf und es kommt kein Sprachanruf zustande. Lehnt die Gegenseite ab oder endet das Gespräch, meldet das Modul NO CARRIER oder BUSY, nimmt niemand ab, NO ANSWER, und ohne Netz NO DIALTONE. ATH beendet den Anruf jederzeit. Ein klingelndes Handy erregt bei einem Alarm viel mehr Aufmerksamkeit als eine SMS. Der Sketch unten sendet eine SMS, sobald ein PIR-Bewegungsmelder an D4 auslöst, lässt dann dein Handy bis zu 20 Sekunden klingeln und wartet zwischen zwei Alarmen 2 Minuten:

Arduino (C++)
1#include <SoftwareSerial.h>
2
3SoftwareSerial sim800(2, 3);                 // RX = D2 ← SIM TXD, TX = D3 → SIM RXD
4const byte SENSOR_PIN = 4;                   // PIR çıkışı / PIR output
5const char OWNER[] = "+905551112233";        // aranacak numara / number to call
6const unsigned long RING_MS = 20000;         // en fazla 20 sn çaldır / ring for at most 20 s
7const unsigned long COOLDOWN_MS = 120000;    // iki alarm arası 2 dk; açılışta da 2 dk bekler / 2 min between alarms, also after power-up
8unsigned long lastAlarm = 0;
9
10int waitReply(const char *ok, unsigned long timeoutMs) {
11  const char *err = "ERROR";
12  byte m1 = 0, m2 = 0;
13  unsigned long start = millis();
14  while (millis() - start < timeoutMs) {
15    if (!sim800.available()) continue;
16    char c = sim800.read();
17    Serial.write(c);
18    m1 = (c == ok[m1]) ? m1 + 1 : (c == ok[0] ? 1 : 0);
19    if (ok[m1] == '\0') return 1;
20    m2 = (c == err[m2]) ? m2 + 1 : (c == err[0] ? 1 : 0);
21    if (err[m2] == '\0') return -1;
22  }
23  return 0;
24}
25
26bool sendSms(const char *number, const char *text) {
27  sim800.print("AT+CMGS=\"");
28  sim800.print(number);
29  sim800.print("\"\r");
30  if (waitReply(">", 5000) != 1) return false;
31  sim800.print(text);
32  sim800.write(26);                          // Ctrl+Z: gönder / send
33  return waitReply("+CMGS:", 60000) == 1;
34}
35
36void callOwner() {
37  sim800.print("ATD");
38  sim800.print(OWNER);
39  sim800.println(";");                       // sondaki ; sesli arama demektir / the trailing ; means a voice call
40  waitReply("NO CARRIER", RING_MS);          // açıp kapatırsan erken biter / ends early if you answer and hang up
41  sim800.println("ATH");                     // aramayı sonlandır / hang up
42  waitReply("OK", 2000);
43}
44
45void setup() {
46  pinMode(SENSOR_PIN, INPUT);
47  Serial.begin(9600);
48  sim800.begin(9600);
49  delay(3000);
50  for (byte i = 0; i < 10; i++) {            // otomatik baud eşleşmesi / autobaud sync
51    sim800.println("AT");
52    if (waitReply("OK", 1000) == 1) break;
53  }
54  sim800.println("AT+CMGF=1");               // SMS metin modu / SMS text mode
55  waitReply("OK", 1000);
56}
57
58void loop() {
59  if (digitalRead(SENSOR_PIN) == HIGH && millis() - lastAlarm > COOLDOWN_MS) {
60    lastAlarm = millis();
61    Serial.println(F("Hareket! / Motion!"));
62    sendSms(OWNER, "ALARM: Hareket algilandi / Motion detected");
63    callOwner();
64  }
65  while (sim800.available()) Serial.write(sim800.read());
66}

Auch in den ersten 2 Minuten nach dem Einschalten bleibt der Sketch still; das gibt dem PIR-Sensor Zeit zum Aufwärmen und dir Zeit, das Haus zu verlassen. Nimmst du den Anruf an, wird die Verbindung hergestellt; mit einem Elektretmikrofon und einem kleinen 8-Ω-Lautsprecher an MIC und SPK des SIM800L kannst du über das Gerät sprechen. Um eingehende Anrufe automatisch anzunehmen, sendest du einfach ATA, sobald die Zeile RING erscheint. Während eines Anrufs zieht das Modul im Mittel 130–220 mA und in Spitzen weiterhin 2 A; reicht deine Versorgung für SMS, schaltet das Modul aber beim Telefonieren ab, nimm einen größeren Kondensator oder eine stärkere Quelle.

SIM800L mit dem ESP32 und dem TTGO-T-Call-Board

Beim ESP32 brauchst du kein SoftwareSerial; einer seiner drei Hardware-UARTs lässt sich beliebigen Pins zuweisen. Um die Uno-Sketches oben auf einem ESP32 laufen zu lassen, löschst du die SoftwareSerial-Zeilen, schreibst stattdessen HardwareSerial sim800(2); und verwendest in setup() sim800.begin(9600, SERIAL_8N1, 16, 17);; der Rest des Codes läuft unverändert. Da der ESP32 mit 3,3 V arbeitet, genügt ein Teiler aus 1 kΩ + 5,6 kΩ in der TX-Leitung. Versorgst du den SIM800L aus derselben schwachen Quelle wie den ESP32, ziehen die 2-A-Impulse auch dessen Spannung herunter und das Board startet mit dem Fehler „Brownout detector was triggered“ neu; versorge beide Boards getrennt und verbinde nur die GNDs. Diesen Fehler erklären wir ausführlich in unserem Beitrag zum ESP32-Brownout.

Wenn du dir die Verkabelung sparen willst, vereint das LilyGO TTGO T-Call einen ESP32 und ein SIM800-Modem auf einer Platine. Darauf sitzen ein ESP32-WROVER-B-Modul, ein SIM800L (bei manchen Chargen der SIM800H aus derselben Familie), ein SIM-Kartenhalter, ein LiPo-Akkuanschluss und der Power-Management-Chip IP5306, der den Akku lädt und den nötigen Strom für das Modem bereitstellt. Das Modem wird nicht über externe Pins, sondern über bestimmte GPIOs des ESP32 ein- und ausgeschaltet, deshalb laufen gewöhnliche SIM800L-Sketches auf dem T-Call nicht ohne Weiteres.

LilyGO TTGO T-Call ESP32 SIM800 Board
TTGO T-Call: vorne das ESP32-WROVER-B und das SIM800-Modem, hinten der SIM-Kartenhalter und der LiPo-Akkuanschluss.
T-Call-DefinitionGPIOFunktion
MODEM_PWRKEY4Schaltet das Modem mit einem 1-Sekunden-LOW-Impuls ein
MODEM_RST5Modem-Reset; bleibt auf HIGH
MODEM_POWER_ON23Schaltet bei HIGH die Versorgung des Modems ein
MODEM_TX27Vom ESP32 zum RXD-Eingang des Modems
MODEM_RX26Vom TXD-Ausgang des Modems zum ESP32
I2C SDA / SCL21 / 22Power-Chip IP5306 (Adresse 0x75)
LED13Benutzer-LED auf der Platine
Arduino (C++)
1#include <Wire.h>
2
3// LilyGO TTGO T-Call SIM800L (IP5306'lı sürüm) pinleri / pins of the IP5306 version
4#define MODEM_PWRKEY     4
5#define MODEM_RST        5
6#define MODEM_POWER_ON  23
7#define MODEM_TX        27      // ESP32 TX → modem RX
8#define MODEM_RX        26      // ESP32 RX ← modem TX
9#define I2C_SDA         21
10#define I2C_SCL         22
11#define IP5306_ADDR   0x75      // güç yönetim yongası / power management chip
12
13HardwareSerial &modem = Serial1;
14const char OWNER[] = "+905551112233";
15
16// Pille çalışırken IP5306 kendini kapatmasın / keep the IP5306 boost on when running from battery
17bool setPowerBoostKeepOn() {
18  Wire.beginTransmission(IP5306_ADDR);
19  Wire.write(0x00);             // SYS_CTL0 yazmacı / SYS_CTL0 register
20  Wire.write(0x37);             // boost keep-on biti açık / boost keep-on bit set
21  return Wire.endTransmission() == 0;
22}
23
24// token gelirse true; ERROR ya da süre dolarsa false / true on token, false on ERROR or timeout
25bool waitFor(const char *token, unsigned long timeoutMs) {
26  String reply = "";
27  unsigned long start = millis();
28  while (millis() - start < timeoutMs) {
29    while (modem.available()) reply += (char)modem.read();
30    if (reply.indexOf(token) >= 0) break;
31    if (reply.indexOf("ERROR") >= 0) break;
32  }
33  Serial.print(reply);
34  return reply.indexOf(token) >= 0;
35}
36
37bool at(const char *cmd) {
38  modem.println(cmd);
39  return waitFor("OK", 2000);
40}
41
42bool registered() {
43  modem.println("AT+CREG?");
44  return waitFor("+CREG: 0,1", 1000);       // ev şebekesine kayıtlı / registered on the home network
45}
46
47bool sendSms(const char *number, const char *text) {
48  modem.printf("AT+CMGS=\"%s\"\r", number);
49  if (!waitFor(">", 5000)) return false;
50  modem.print(text);
51  modem.write(26);                           // Ctrl+Z: gönder / send
52  return waitFor("+CMGS:", 60000);
53}
54
55void setup() {
56  Serial.begin(115200);
57  Wire.begin(I2C_SDA, I2C_SCL);
58  Serial.println(setPowerBoostKeepOn() ? "IP5306 OK" : "IP5306 yok / not found");
59
60  pinMode(MODEM_RST, OUTPUT);
61  pinMode(MODEM_PWRKEY, OUTPUT);
62  pinMode(MODEM_POWER_ON, OUTPUT);
63  digitalWrite(MODEM_RST, HIGH);             // reset bırakılmış / reset released
64  digitalWrite(MODEM_POWER_ON, HIGH);        // modemin beslemesini aç / switch on the modem supply
65  digitalWrite(MODEM_PWRKEY, HIGH);
66  delay(100);
67  digitalWrite(MODEM_PWRKEY, LOW);           // PWRKEY 1 sn düşük: modem açılır / PWRKEY low for 1 s: modem starts
68  delay(1000);
69  digitalWrite(MODEM_PWRKEY, HIGH);
70
71  modem.begin(115200, SERIAL_8N1, MODEM_RX, MODEM_TX);
72  delay(3000);
73
74  for (int i = 0; i < 10 && !at("AT"); i++) delay(500);   // otomatik baud / autobaud
75  at("AT+CMGF=1");                           // SMS metin modu / SMS text mode
76  at("AT+CNMI=1,2,0,0,0");                   // gelen SMS'i seri porta ver / push incoming SMS to the UART
77
78  unsigned long start = millis();
79  while (!registered() && millis() - start < 60000) delay(2000);
80
81  if (sendSms(OWNER, "TTGO T-Call hazir / ready")) Serial.println("\nSMS gonderildi / sent");
82}
83
84void loop() {
85  while (modem.available()) Serial.write(modem.read());   // gelen SMS ve aramalar / incoming SMS and calls
86  while (Serial.available()) modem.write(Serial.read());  // Seri Monitör'den AT komutu / AT commands from the monitor
87}

Diese Pins gelten für die T-Call-SIM800L-Versionen von LilyGO mit IP5306. Bei der Version mit dem Power-Chip AXP192 wird dieser mit anderem Code eingerichtet, und bei der SIM800C-Version liegt der Versorgungspin des Modems auf GPIO 25; schau auf das Versionsdatum auf deiner Platine und in die Pintabelle des Herstellers. Die Funktion setPowerBoostKeepOn() schreibt 0x37 in Register 0x00 des IP5306 und verhindert so, dass sich der Chip im Akkubetrieb bei geringer Last selbst abschaltet. Schaltet das Modem bei der Anmeldung ab, wenn das Board nur am USB-Port des Computers hängt, steck zusätzlich den LiPo-Akku an; er fängt die 2-A-Impulse ab. Beim ESP32-WROVER sind GPIO 16 und 17 für das interne PSRAM reserviert, deshalb hängt das Modem an 26 und 27. Für GPRS-Aufgaben wie HTTP-Anfragen oder MQTT unterstützt die Bibliothek TinyGSM dieses Board mit der Definition TINY_GSM_MODEM_SIM800.

SIM800L mit dem Raspberry Pi Pico und MicroPython

Am Raspberry Pi Pico schließen wir das Modul an UART0 an: TXD des SIM800L geht an GP1, RXD über einen Teiler aus 1 kΩ + 5,6 kΩ an GP0, und die GNDs werden verbunden. Die Pins VBUS und 3V3 des Pico können den SIM800L nicht versorgen, also kommt auch hier eine externe 4-V-Quelle zum Einsatz. Der MicroPython-Code unten erledigt dasselbe wie das Relais-Beispiel für den Arduino: Er schaltet das Relais an GP15 per SMS ein und aus und sendet eine Antwort. Die Funktion to_text() verwirft durch Störungen verfälschte Bytes und behält nur ASCII-Zeichen, sodass ein Dekodierfehler das Programm nicht anhält. Eine zusätzliche Bibliothek ist nicht nötig; wenn du nicht weißt, wie man den Code mit Thonny ausführt, lies zuerst unseren Beitrag zu den MicroPython-Grundlagen.

MicroPython
1from machine import UART, Pin
2import time
3
4# GP0 (TX) → SIM RXD (1k + 5,6k bölücü / divider), GP1 (RX) ← SIM TXD
5sim = UART(0, baudrate=9600, tx=Pin(0), rx=Pin(1), timeout=100, timeout_char=50)
6relay = Pin(15, Pin.OUT, value=0)              # röle modülü IN / relay module IN
7OWNER = "+905551112233"                        # yetkili numara / authorised number
8
9def to_text(raw):
10    # yalnız ASCII karakterleri al / keep ASCII characters only
11    return "".join(chr(b) for b in raw if 9 < b < 128)
12
13def wait_for(token, timeout_ms):
14    # token ya da ERROR gelene kadar oku / read until token or ERROR
15    buf = ""
16    t0 = time.ticks_ms()
17    while time.ticks_diff(time.ticks_ms(), t0) < timeout_ms:
18        if sim.any():
19            buf += to_text(sim.read())
20            if token in buf:
21                return True
22            if "ERROR" in buf:
23                return False
24    return False
25
26def at(cmd, timeout_ms=2000):
27    sim.write(cmd + "\r\n")
28    return wait_for("OK", timeout_ms)
29
30def send_sms(number, msg):
31    sim.write('AT+CMGS="{}"\r'.format(number))
32    if not wait_for(">", 5000):
33        return False
34    sim.write(msg)
35    sim.write(b"\x1a")                         # Ctrl+Z: gönder / send
36    return wait_for("+CMGS:", 60000)
37
38for _ in range(10):                            # otomatik baud eşleşmesi / autobaud sync
39    if at("AT", 1000):
40        break
41at("ATE0")                                     # yankıyı kapat / echo off
42at("AT+CMGF=1")                                # SMS metin modu / SMS text mode
43at("AT+CNMI=1,2,0,0,0")                        # gelen SMS'i UART'a ver / push incoming SMS to the UART
44print("Hazir / Ready")
45
46body_next = False
47from_owner = False
48while True:
49    raw = sim.readline()
50    if not raw:
51        continue
52    line = to_text(raw).strip()
53    if not line:
54        continue
55    print(line)
56    if body_next:                              # +CMT'den sonraki satır SMS metni / line after +CMT is the text
57        body_next = False
58        cmd = line.upper()
59        if not from_owner:
60            continue
61        if "ROLE AC" in cmd:
62            relay.value(1)
63            send_sms(OWNER, "Role ACILDI / Relay ON")
64        elif "ROLE KAPA" in cmd:
65            relay.value(0)
66            send_sms(OWNER, "Role KAPANDI / Relay OFF")
67        elif "DURUM" in cmd:
68            send_sms(OWNER, "Role ACIK / ON" if relay.value() else "Role KAPALI / OFF")
69    elif line.startswith("+CMT:"):             # yeni SMS başlığı / new SMS header
70        from_owner = OWNER in line
71        body_next = True

Projektideen mit dem SIM800L

  • Einbruchalarm mit SMS: Ein System, das bei Bewegung an einem PIR- oder Türsensor eine SMS sendet und dich danach anruft; Details findest du in unserem Beitrag zur Arduino-Alarmanlage.
  • Gaswarnung: Eine SMS aufs Handy, sobald der MQ-2-Gassensor seinen Schwellwert überschreitet, auch wenn niemand zu Hause ist.
  • GPS-Tracker mit SMS-Antwort: Mit einem NEO-6M-GPS-Modul ein Auto- oder Fahrradtracker, der auf die Nachricht „POSITION“ mit einem Google-Maps-Link antwortet.
  • Fernbewässerung: Ein System für Garten oder Schrebergarten, das den Wert des Bodenfeuchtesensors per SMS meldet und auf „GIESSEN“ die Pumpe startet.
  • Temperaturwächter: Eine DS18B20-Schaltung, die warnt, wenn Gewächshaus, Hühnerstall oder Gefriertruhe den Sollbereich verlassen.
  • Garagentor per Anruf: Eine kostenlose Fernbedienung, die das Relais nur bei Anrufen von registrierten Nummern für eine Sekunde anziehen lässt.
  • Stromausfallmelder: Eine kleine Schaltung, die bei Netzausfall am Akku weiterläuft und eine SMS „Stromausfall“ verschickt.

Keine Netzverbindung, SMS geht nicht raus: häufige Fehler und Lösungen

SymptomMögliche UrsacheLösung
Keine Antwort auf ATTXD und RXD vertauscht, keine gemeinsame Masse, falsches Zeilenende oder Autobauding nicht synchronisiertTXD an D2, GNDs verbinden, Both NL & CR wählen, AT mehrmals senden
ZeichensalatBaudrate passt nicht oder Pegel grenzwertigSeriellen Monitor und Sketch auf 9600 stellen, Pegelwandler verwenden
LED blinkt ein paarmal und geht aus, Modul startet neuSpannung fällt bei der Anmeldung unter 3,4 VQuelle mit 2 A, 1000-µF-Kondensator, kurze und dicke Kabel
UNDER-VOLTAGE POWER DOWN im seriellen MonitorVersorgung unter 3,4 V gefallenAkku laden oder Buck-Ausgang auf 4,0–4,1 V stellen
OVER-VOLTAGE WARNNING oder OVER-VOLTAGE POWER DOWNSpannung über 4,3–4,4 VAusgang auf 4,0 V senken; das Modul nie an 5 V anschließen
LED blinkt dauerhaft im SekundentaktKeine Antenne, SIM nicht gelesen, PIN aktiv oder kein 2G vor OrtAntenne anbringen, mit AT+CPIN? und AT+CSQ prüfen, 2G-Abdeckung mit dem Handy testen
Antwort +CREG: 0,3Netzanmeldung abgelehntPrüfen, ob die Karte aktiv und die IMEI nicht gesperrt ist
SMS schlägt mit +CMS ERROR fehlKein Guthaben, falsches Nummernformat oder fehlende SMS-ZentraleGuthaben prüfen, Nummer mit Ländervorwahl schreiben, SMS-Zentrale mit AT+CSCA? prüfen
Arduino startet beim SMS-Versand neuSIM800L und Arduino hängen an derselben schwachen QuelleVersorgungen trennen, nur die GNDs verbinden
Eingehende SMS erscheinen nichtAT+CNMI nicht gesetzt oder nach einem Neustart des Moduls verlorenIm Setup AT+CMGF=1 und AT+CNMI=1,2,0,0,0 senden
Am schnellsten findest du heraus, ob das Problem im Code oder in der Hardware steckt, wenn du das Modul mit einem 3,3-V-USB-TTL-Wandler direkt an den Computer anschließt und die AT-Befehle von Hand eintippst. Sende bei der Fehlersuche AT+CMEE=2: Dann zeigt das Modul lesbare Fehlermeldungen wie „+CME ERROR: SIM not inserted“ statt „+CME ERROR: 10“.

Richtig versorgt und dort eingesetzt, wo es 2G gibt, ist der SIM800L der günstigste Weg, deine Arduino-Projekte aus beliebiger Entfernung zu erreichen: Eine stabile 4-V-Quelle, ein großer Kondensator und eine Handvoll AT-Befehle genügen. Wenn du die anderen Funkoptionen vergleichen willst, wirf einen Blick in unseren Beitrag zu Funkmodulen für den Arduino. In der BlueGrays-App findest du Projekte, die du leicht um einen SIM800L erweitern kannst, etwa einen Alarm mit Bewegungsmelder, einen Gas- und Flammenalarm, die Steuerung einer 230-V-Lampe, eine smarte Bewässerung und einen ESP32-Alarm mit Telegram-Benachrichtigung, jeweils mit Schaltplan und Schritt-für-Schritt-Code.

Häufige Fragen

Welche Spannung braucht der SIM800L, darf er an 5V?

Der SIM800L arbeitet mit 3,4–4,4 V, empfohlen sind 4,0 V. Am 5V-Pin des Arduino schaltet das Modul wegen Überspannung ab oder wird beschädigt. Nutze einen einzelligen LiPo- oder 18650-Akku oder einen auf 4,0 V eingestellten LM2596; die Quelle muss außerdem kurze Impulse von 2 A liefern können.

Funktioniert der SIM800L noch in Deutschland?

Ja, derzeit noch, denn die deutschen Netzbetreiber betreiben ihr 2G-Netz weiter. Die Telekom plant die Abschaltung aber zum 30. Juni 2028, und die anderen Anbieter werden folgen. Für Projekte, die länger laufen sollen, ist ein 4G-LTE-Modul die sicherere Wahl; in der Schweiz funktioniert der SIM800L schon heute nicht mehr.

Warum meldet sich mein SIM800L nicht im Netz an?

Die häufigsten Ursachen sind eine unzureichende Versorgung, eine fehlende Antenne, eine SIM-Karte mit aktiver PIN und fehlendes 2G am Standort. Prüfe das Signal mit AT+CSQ, die SIM mit AT+CPIN? und den Anmeldestatus mit AT+CREG?. Startet das Modul bei der Anmeldung neu, liegt es eindeutig an der Stromversorgung.

Was bedeuten die Blinkcodes der SIM800L-LED?

Blinken im Sekundentakt bedeutet, dass das Modul läuft, aber nicht im Netz angemeldet ist; Blinken alle 3 Sekunden heißt, es ist angemeldet und bereit für SMS und Anrufe. Sehr schnelles Blinken zeigt eine aktive GPRS-Datenverbindung. Blinkt die LED ein paarmal und geht dann aus, startet das Modul wegen eines Spannungseinbruchs neu.

Kann der SIM800L ins Internet?

Ja, über GPRS sendet und empfängt er Daten mit bis zu 85,6 kbit/s; das reicht, um Sensordaten an einen Server zu schicken, HTTP-Anfragen zu stellen oder MQTT zu nutzen. Du musst die APN-Daten deines Anbieters eintragen, und die Bibliothek TinyGSM erleichtert die Arbeit. Für Bilder oder große Dateien ist er aber viel zu langsam.

Welches Modul kann ich statt des SIM800L verwenden?

In Ländern, in denen 2G abgeschaltet ist oder wird, nimmst du ein 4G-LTE-Modul wie den SIM7600 oder A7670 oder ein LTE-M/NB-IoT-Modul wie den SIM7080G. Die meisten AT-Befehle sind ähnlich, sodass sich SMS- und Anrufcode mit kleinen Änderungen übertragen lässt. Der SIM800C und der ältere SIM900 aus derselben Familie nutzen ähnliche Befehle, funken aber ebenfalls nur in 2G.

Alle Projekte ansehen
Temperatur und Luftfeuchtigkeit mit DHT11
#55Mittel

Temperatur und Luftfeuchtigkeit mit DHT11

Wie warm ist dein Zimmer, und ist die Luft feucht oder trocken? Der DHT11-Sensor misst Temperatur und Luftfeuchtigkeit, und der Arduino schreibt die Werte auf ein zweizeiliges LCD und aktualisiert sie

4.7(47)
64
ESP32 Bewegungsalarmsystem (PIR + Buzzer + LED + Telegram)
#145Fortgeschritten
Premium

ESP32 Bewegungsalarmsystem (PIR + Buzzer + LED + Telegram)

Ein intelligentes Sicherheitsalarmsystem, das Buzzer und LED aktiviert, sobald der PIR-Sensor Bewegung erkennt, und gleichzeitig eine sofortige Benachrichtigung per Telegram an den Besitzer sendet. Ein 30-sekündiger Cooldown begrenzt die Häufigkeit wiederholter Alarme; dieser Mechanismus überprüft weder die Gültigkeit der PIR-Erkennungen noch verhindert er Fehlauslösungen. Geeignet für Heimsicherheit, Garagenüberwachung, Lagerräume oder Arbeitszimmer. Mit ESP32-CAM sind Foto-Benachrichtigungen m

0.0(0)
8
Bewegungsmelder mit Bewegungssensor
#24Anfänger
Premium

Bewegungsmelder mit Bewegungssensor

Ein einfacher Wächter, der Bescheid gibt, wenn jemand den Raum betritt. Der Bewegungsmelder spürt die Wärme, die der menschliche Körper abgibt; der Arduino lässt die LED leuchten, solange sich etwas b

4.6(47)
67
ESP32-Bewegungsalarm
#140Mittel
Premium

ESP32-Bewegungsalarm

In diesem Projekt, das mit einem ESP32 und einem PIR-Sensor realisiert wurde, wird bei Bewegungserkennung ein Summer aktiviert, der einen akustischen Alarm auslöst. Es handelt sich um eine einfache und kostengünstige Sicherheitssystem-Anwendung. (Die Abbildungen dienen nur zur Veranschaulichung; bitte ordnen Sie sie den Texten zu.)

4.4(10)
15
Flammen- und Gassensor-Alarm
#52Fortgeschritten
Premium

Flammen- und Gassensor-Alarm

Ein kleiner Wächter, der dich sofort warnt, wenn Gas austritt oder irgendwo eine Flamme auftaucht. Der Gassensor überwacht die Luft, der Flammensensor achtet auf das Licht eines Feuers; solange alles

4.8(52)
67
220V Glühbirne mit Druckknopf (Push)
#19Fortgeschritten
Premium

220V Glühbirne mit Druckknopf (Push)

Solange du den Knopf gedrückt hältst, leuchtet eine echte 220-Volt-Glühbirne, und sobald du loslässt, geht sie aus. Das schwache Signal des Arduino kann die Birne nicht direkt einschalten, deshalb sit

4.4(30)
38
220-V-Glühbirne mit Fernbedienung schalten
#21Fortgeschritten
Premium

220-V-Glühbirne mit Fernbedienung schalten

Schalte eine echte Glühbirne in deiner Wohnung mit einer Fernbedienung ein und aus, ohne vom Sofa aufzustehen. Der Arduino liest das unsichtbare Lichtsignal der Fernbedienung; die Einschalttaste lässt

4.4(22)
30
Intelligente Bewässerungsstation
#83Fortgeschritten
Premium

Intelligente Bewässerungsstation

Ein Gärtner, der deine Pflanzen von selbst gießt, damit sie im Urlaub nicht vertrocknen. Ein Bodenfeuchtesensor misst, wie nass die Erde ist; wird sie trocken, lässt der Arduino die Wasserpumpe ein pa

5.0(42)
57