Componenti · 18 min di lettura

SIM800L con Arduino: inviare SMS, comandare un relè e chiamare

Come usare il modulo GSM SIM800L con Arduino: alimentazione 4 V e 2 A, LED, comandi AT, invio di SMS, relè via SMS, chiamate, codice per ESP32 e Pico.

Il modulo GSM SIM800L è un modem 2G minuscolo ed economicissimo, grande come un francobollo, che dà al tuo progetto Arduino una propria linea telefonica. Con una micro SIM all'interno puoi inviare e ricevere SMS, fare telefonate e mandare piccole quantità di dati su internet tramite GPRS. Nei posti dove Wi-Fi e Bluetooth non arrivano, come una casa di campagna, una serra, un magazzino o un veicolo, abbinare un SIM800L ad Arduino è il modo più semplice per comandare un dispositivo a distanza da qualsiasi luogo coperto dalla rete mobile. Il modulo comunica con Arduino tramite una connessione seriale a due fili (UART) e si controlla con brevi comandi di testo chiamati comandi AT.

Detto questo, il SIM800L è uno dei moduli che fanno penare di più chi è alle prime armi, e quasi tutti i problemi nascono da due cose: un'alimentazione inadeguata e la copertura 2G. In questa guida imparerai ad alimentare correttamente il modulo rispettando l'intervallo di 3,4–4,4 V e i picchi di 2 A, a capire cosa indica la frequenza di lampeggio del LED sulla scheda, a testarlo passo passo con i comandi AT, a inviare un SMS con Arduino Uno, ad accendere e spegnere un relè via SMS e a costruire un circuito che ti chiama quando scatta un allarme. Poi farai lo stesso con ESP32, la scheda pronta TTGO T-Call e il Raspberry Pi Pico, e alla fine troverai in una tabella le soluzioni ai problemi di registrazione sulla rete.

Modulo GSM/GPRS SIM800L con antenna elicoidale
Scheda SIM800L: in alto l'antenna a spirale, accanto un condensatore di alimentazione e due file di pin; il porta micro SIM si trova sul retro della scheda (in basso).

Cos'è il SIM800L e come funziona?

Il SIM800L è un modulo GSM/GPRS prodotto da SIMCom che misura appena 17,8 × 15,8 mm. La scheda rossa che acquisti è una piccola breakout che aggiunge intorno al modulo un porta SIM, un collegamento per l'antenna, un LED di stato e le file di pin. Il modulo scansiona automaticamente tutte e quattro le bande GSM (850, 900, 1800 e 1900 MHz), si registra sulla rete proprio come un cellulare e poi esegue i comandi che riceve sulla porta seriale: «invia questo messaggio a questo numero», «chiama questo numero», «passami i messaggi in arrivo» e così via. Immaginalo come un telefono senza schermo né tastiera; il lavoro di entrambi lo fa Arduino. Collegando un microfono e un altoparlante ai pin MIC e SPK puoi perfino fare una vera telefonata.

CaratteristicaValore
ModuloSIMCom SIM800L, 2G GSM/GPRS
Bande di frequenzaQuad-band: GSM 850, EGSM 900, DCS 1800, PCS 1900 MHz
Tensione di alimentazione3,4–4,4 V (consigliati 4,0 V)
Corrente di piccoFino a 2 A (brevi impulsi durante la trasmissione)
Corrente mediaSpento ~0,1 mA, sleep ~1–2 mA, a riposo ~15 mA, chiamata vocale 130–220 mA, GPRS 150–450 mA (a seconda della banda e della versione del datasheet)
Potenza di trasmissione2 W (850/900 MHz), 1 W (1800/1900 MHz)
InterfacciaUART e comandi AT; riconoscimento automatico del baud rate 1200–115200
Livello logicoUscita 2,8 V; ingresso RXD max 3,1 V
SIMMicro SIM (schede da 1,8 V e 3 V)
Velocità GPRSFino a 85,6 kbps
Temperatura di esercizioDa -40 a +85 °C

Piedinatura del SIM800L

PinFunzioneNota
NETCollegamento antennaQui si salda l'antenna a spirale; se c'è un connettore u.FL (IPEX) si collega un'antenna esterna
VCCAlimentazione (+)3,4–4,4 V; mai al pin 5V o 3.3V di Arduino
RSTReset hardwarePortato a LOW per almeno 105 ms riavvia il modulo; può restare scollegato
RXDIngresso seriale del moduloVa al pin TX della scheda; max 3,1 V
TXDUscita seriale del moduloVa al pin RX della scheda; livello 2,8 V
GNDMassaSia all'alimentazione sia ad Arduino (massa comune)
RINGSegnale di chiamata / SMSVa a LOW con una chiamata in arrivo e dà un impulso LOW di 120 ms quando arriva un SMS
DTRControllo dello sleepCon AT+CSCLK=1 il modulo dorme finché DTR è HIGH e si sveglia portandolo a LOW
MIC+ / MIC−Ingresso microfonoPer un microfono electret
SPK+ / SPK−Uscita altoparlanteSi può collegare un piccolo altoparlante da 8 Ω

L'antenna a spirale inclusa si salda sul foro NET nell'angolo della scheda; alcune schede hanno anche un piccolo connettore u.FL (IPEX) per un'antenna esterna. Senza antenna il modulo non trova la rete e il segnale risulta quasi a zero; se in casa la ricezione è debole, un'antenna GSM adesiva con cavo fa una netta differenza rispetto alla spirale. La micro SIM va nel porta SIM sul retro, con l'angolo smussato orientato come nel disegno sul supporto. Prima di inserirla, disattiva la richiesta del PIN in un telefono e verifica che la linea possa inviare SMS, telefonare e abbia credito sufficiente.

Alimentazione: 3,4–4,4 V e picchi di 2 A

L'alimentazione è il punto più critico del SIM800L e quello in cui si sbaglia più spesso. Il GSM funziona a divisione di tempo: in ogni trama da 4,615 ms il modulo trasmette solo durante il proprio intervallo di 577 µs. In quegli istanti assorbe fino a 2 A, subito dopo torna a qualche decina di milliampere. Se la sorgente non riesce a fornire questa corrente improvvisa, la tensione crolla. Secondo il datasheet di SIMCom, quando la tensione scende a 3,5 V il modulo scrive UNDER-VOLTAGE WARNNING sulla seriale, sotto 3,4 V scrive UNDER-VOLTAGE POWER DOWN e si spegne (l'errore di battitura in WARNNING viene dal firmware del produttore). Verso l'alto, a 4,3 V compare l'avviso OVER-VOLTAGE WARNNING e sopra 4,4 V il modulo si spegne di nuovo. In alcune versioni del firmware questo spegnimento automatico è disattivato di fabbrica e si attiva con AT+CBATCHK=1; anche in quel caso, fuori da questi limiti il modulo diventa instabile e si riavvia di continuo. Per questo il pin 5V di Arduino è troppo alto per il SIM800L. Il pin 3.3V è sotto il minimo e ufficialmente fornisce solo 50 mA; in più la porta USB di un computer non dà più di 500 mA.

AlimentazioneVa bene?Dettagli
Batteria LiPo a una cella da 3,7 V o Li-ion 18650Sì, la soluzione più facileCarica dà 4,2 V; il modulo funziona bene finché la cella scende a 3,6–3,7 V, sotto può spegnersi durante i picchi di trasmissione. Scegli almeno 1000 mAh in grado di erogare 2 A e ricaricala con un TP4056
Modulo step-down LM2596 (buck)Sì, per progetti con alimentatoreSi regola a 4,0–4,1 V partendo da un alimentatore da 7–12 V; eroga fino a 3 A
Schede SIM800L con ingresso a 5 V (es. «SIM800L V2»)Sì, seguendo le istruzioni della schedaIl circuito sulla scheda abbassa la tensione; serve comunque un alimentatore da 5 V in grado di dare 2 A
Pin 5V di ArduinoNoSupera il limite di 4,4 V, il modulo si spegne o si danneggia; la USB non dà 2 A
Pin 3.3V di ArduinoNoSotto 3,4 V e con pochissima corrente; il modulo non parte o si riavvia di continuo
Regolatori a 3,3 V come l'AMS1117No3,3 V è sotto il minimo del modulo
LM2596
LM2596
18650 Li-Ion
18650 Li-Ion
TP4056
TP4056
Se usi un LM2596, regola la sua uscita a 4,0–4,1 V con il trimmer misurando con il multimetro, prima di collegare il SIM800L. Non si sa con quale regolazione esca dalla fabbrica; un'uscita vicina ai 12 V d'ingresso distrugge il SIM800L nel primo secondo. Se lo alimenti a batteria, ricaricala con un modulo di ricarica TP4056 e fai attenzione a non invertirla: la scheda del SIM800L non ha protezione contro l'inversione di polarità.
Metti un condensatore elettrolitico da 470–1000 µF a bassa ESR e un ceramico da 100 nF tra VCC e GND, il più vicino possibile ai pin del modulo; SIMCom nel proprio progetto di riferimento consiglia almeno 100 µF a bassa ESR. Il condensatore fornisce gli impulsi da 2 A al posto della sorgente ed evita che la tensione crolli; spieghiamo come funziona in Cos'è un condensatore?. Usa cavi di alimentazione corti e spessi, evita di far passare 2 A nei contatti a molla di una breadboard e collega sempre il GND del modulo al GND di Arduino.

Cosa ti dice il LED? Il significato dei lampeggi

Comportamento del LEDSignificatoCosa fare
SpentoIl modulo non funzionaControlla l'alimentazione e la polarità VCC–GND, misura la tensione
Circa una volta al secondo (64 ms acceso, 800 ms spento)Acceso ma non registrato sulla reteNormale nei primi 10–60 secondi; se dura di più, controlla SIM, PIN, antenna e copertura 2G
Circa ogni 3 secondi (64 ms acceso, 3000 ms spento)Registrato sulla retePronto per SMS e chiamate
Molto veloce, circa 3 volte al secondo (64 ms acceso, 300 ms spento)Connessione dati GPRS attivaÈ attiva una connessione a internet
Lampeggia qualche volta, si spegne e riparteLa tensione crolla e il modulo si spegneSorgente più potente, condensatore grande, cavi corti e spessi

Prendi l'abitudine di usare il LED come strumento di diagnosi: vedere il modulo passare al lampeggio ogni 3 secondi prima ancora di scrivere codice elimina in partenza metà dei problemi. Se il modulo continua a lampeggiare una volta al secondo per minuti, è inutile mettere mano al software; guarda prima la sezione sulla registrazione alla rete più avanti. I picchi di corrente più forti arrivano proprio al momento della registrazione, quando il modulo parla per la prima volta con la stazione base; se l'alimentazione è debole, il modulo si spegne esattamente in quel momento e il ciclo ricomincia.

Collegamento del SIM800L ad Arduino e adattamento dei livelli

Il SIM800L comunica con Arduino tramite UART e le linee dati si incrociano: il pin TXD del modulo va al pin RX della scheda e il pin RXD del modulo al pin TX della scheda. L'unica seriale hardware di Arduino Uno (D0 e D1) serve per caricare il codice via USB e per il Monitor seriale, quindi colleghiamo il modulo a D2 e D3 con SoftwareSerial, che a 9600 baud funziona in modo affidabile. Su ESP32 e Pico non serve una seriale software: si usano le UART hardware. Trovi le basi della comunicazione seriale nella nostra guida sulla comunicazione seriale UART.

Pin del SIM800LArduino UnoESP32Raspberry Pi Pico
VCC4,0 V esterni (+)4,0 V esterni (+)4,0 V esterni (+)
GNDGND + negativo dell'alimentazioneGND + negativo dell'alimentazioneGND + negativo dell'alimentazione
TXDD2 (RX di SoftwareSerial)GPIO 16 (RX2)GP1 (UART0 RX)
RXDD3, tramite partitore 10 kΩ + 15 kΩGPIO 17 (TX2), tramite partitore 1 kΩ + 5,6 kΩGP0 (UART0 TX), tramite partitore 1 kΩ + 5,6 kΩ
RSTPuò restare scollegatoPuò restare scollegatoPuò restare scollegato
NETAntennaAntennaAntenna
Secondo il datasheet, l'ingresso RXD del SIM800L accetta al massimo 3,1 V. Il pin D3 di Arduino Uno dà 5 V, quindi inserisci un partitore di tensione: D3 → 10 kΩ → RXD e RXD → 15 kΩ → GND danno circa 3,0 V. Il partitore 10 kΩ + 20 kΩ che si vede spesso online dà 3,3 V; di solito funziona, ma è un po' sopra il limite del produttore. Per l'uscita a 3,3 V di ESP32 e Pico, le resistenze consigliate da SIMCom, 1 kΩ in serie + 5,6 kΩ verso GND, danno circa 2,8 V. Nella direzione opposta, Arduino Uno di solito legge correttamente il segnale TXD a 2,8 V del modulo, ma il suo datasheet richiede 3,0 V per un HIGH a 5 V; in un montaggio definitivo, un convertitore di livello logico bidirezionale è la soluzione più pulita.

Primo test con i comandi AT

  1. Collega il modulo come nella tabella, monta l'antenna e inserisci una micro SIM con la richiesta del PIN disattivata.
  2. Dai alimentazione e osserva il LED: dopo qualche secondo di lampeggio al secondo, dovrebbe passare a lampeggiare ogni 3 secondi.
  3. Carica su Arduino lo sketch ponte qui sotto; SoftwareSerial è incluso nell'IDE di Arduino, non servono librerie aggiuntive.
  4. Apri il Monitor seriale, imposta 9600 baud e come fine riga Both NL & CR («Entrambi NL & CR»).
  5. Scrivi AT e premi Invio. Il modulo si adatta alla tua velocità con il riconoscimento automatico del baud rate; i primi tentativi possono restare senza risposta, ripeti finché non vedi OK.
  6. Poi controlla uno alla volta la SIM, la potenza del segnale e la registrazione alla rete con i comandi della tabella seguente.
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}
ComandoRisposta di esempioSignificato
ATOKIl modulo funziona e la velocità è sincronizzata
AT+CPIN?+CPIN: READYSIM pronta; se vedi SIM PIN, disattiva il PIN o invia AT+CPIN="1234"
AT+CSQ+CSQ: 18,0Potenza del segnale da 0 a 31 (99 = sconosciuta); da 10 in su basta
AT+CREG?+CREG: 0,11 = registrato, 5 = registrato in roaming, 2 = in ricerca, 3 = rifiutato
AT+COPS?+COPS: 0,0,"OPERATORE"Nome dell'operatore
AT+CBC+CBC: 0,82,4012Tensione di alimentazione in millivolt (qui 4,012 V)
AT+GSNNumero di 15 cifreIMEI del modulo
AT+CCIDNumero di 19–20 cifreNumero di serie della SIM (ICCID); indica che la scheda viene letta
AT+CMGF=1OKModalità testo per gli SMS
AT+CMGS="+905551112233">Attende il testo del messaggio; si invia con Ctrl+Z (26)
AT+CNMI=1,2,0,0,0OKScrive gli SMS in arrivo direttamente sulla seriale senza salvarli
ATD+905551112233;OKAvvia una chiamata vocale (il ; finale è obbligatorio)
ATA / ATHOKRisponde a una chiamata in arrivo / riaggancia
AT+CLIP=1OKMostra il numero di chi chiama in una riga +CLIP
AT+IPR=9600OKFissa la velocità a 9600 baud invece del riconoscimento automatico; invia poi AT&W per renderla permanente
AT+CMEE=2OKRiporta gli errori come testo descrittivo invece che come numeri

Dal primo numero della risposta ad AT+CSQ puoi ricavare il segnale in dBm: dBm ≈ −113 + 2 × valore. Per esempio 18 corrisponde a circa −77 dBm, un valore buono; sotto 10 è debole, e sotto 5 perfino un SMS fatica a partire. La risposta 99 indica che il modulo non è ancora riuscito a misurare. Il comando AT+CBC è perfetto per scovare i problemi di alimentazione: se a riposo leggi circa 4,0 V ma il modulo si spegne mentre invia un SMS o chiama, il problema è senza dubbio la corrente che la tua sorgente riesce a erogare. Nella modalità predefinita con riconoscimento automatico del baud rate, all'avvio il modulo non scrive nulla; se fissi la velocità con AT+IPR=9600 e la salvi con AT&W, l'impostazione resta nella memoria permanente e a ogni accensione il modulo segnala di essere pronto con RDY, +CFUN: 1 e +CPIN: READY.

Non si registra sulla rete? Copertura 2G, SIM e IMEI

Il SIM800L usa solo la rete 2G (GSM/GPRS); non conosce 3G, 4G o 5G. In Italia TIM, Vodafone e WindTre hanno già spento il 3G ma mantengono attivo il 2G e al momento non risultano date ufficiali per spegnerlo, quindi il SIM800L funziona ancora. Altrove il quadro è diverso: in Svizzera il 2G è spento dall'inizio del 2023, in Francia gli operatori lo spengono entro la fine del 2026, negli Stati Uniti l'ultima rete 2G si è spenta ad agosto 2026 e in Australia già anni fa. Dove non c'è 2G il SIM800L non può registrarsi, per quanto sia ben alimentato; lì serve un modulo 4G LTE come il SIM7600 o l'A7670, oppure un modulo LTE-M/NB-IoT come il SIM7080G. Per risolvere i problemi di registrazione segui quest'ordine:

  • C'è il 2G dove ti trovi? Nelle impostazioni di rete mobile del telefono scegli «solo 2G» come tipo di rete preferito e prova a chiamare con la stessa SIM. Se il telefono non trova rete in 2G, non la troverà neanche il SIM800L.
  • La SIM viene letta? AT+CCID deve restituire un numero e AT+CPIN? deve rispondere +CPIN: READY. In caso di errore reinserisci la scheda nel verso giusto; se usi una nano SIM con adattatore, assicurati che l'adattatore non prema male sui contatti.
  • Il segnale è sufficiente? AT+CSQ dovrebbe dare almeno 10. Salda l'antenna o collegane una esterna e avvicina il modulo a una finestra.
  • La registrazione viene rifiutata? Se AT+CREG? risponde 0,3, la rete rifiuta il modulo: la linea potrebbe essere disattivata o l'IMEI del dispositivo bloccato.
  • Registrazione dell'IMEI: alcuni paesi bloccano i dispositivi con IMEI non registrato; in Turchia, per esempio, i dispositivi importati senza registrazione vengono disattivati dopo un periodo di tolleranza. Leggi l'IMEI del modulo con AT+GSN e, in quei paesi, acquista da un rivenditore locale che offre moduli con IMEI registrato.
  • L'alimentazione basta? Se il modulo si riavvia proprio durante la registrazione, il problema non è la rete ma l'alimentazione; torna alla sezione sull'alimentazione.

Inviare un SMS con Arduino

Per inviare un SMS si passa prima alla modalità testo con AT+CMGF=1. Poi si invia AT+CMGS="+905551112233"; la cosa più sicura è scrivere il numero con il prefisso internazionale (il +90 dell'esempio è la Turchia; per l'Italia usa +39, per la Svizzera +41). Il modulo risponde con il prompt > per indicare che aspetta il testo. Dopo averlo scritto, invece di Invio si invia il carattere Ctrl+Z (ASCII 26, 0x1A); quando la rete accetta il messaggio, il modulo restituisce un numero di riferimento come +CMGS: 12 seguito da OK. Questa conferma può richiedere qualche secondo, o fino a 60 secondi con segnale debole. Lo sketch qui sotto si sincronizza con il modulo, attende la registrazione alla rete e invia un solo SMS; scrivi il tuo numero nella riga PHONE:

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}

Nello sketch la funzione waitReply() stampa sul Monitor seriale ogni carattere che arriva dal modulo mentre cerca la risposta attesa (OK, > o +CMGS:) e la parola ERROR, così vedi l'esito di ogni comando. waitForNetwork() aspetta finché la risposta +CREG mostra 0,1 (rete di casa) o 0,5 (roaming), perché un SMS inviato prima della registrazione fallisce. In modalità testo un SMS può contenere al massimo 160 caratteri. I caratteri scritti nell'IDE di Arduino sono codificati in UTF-8, quindi le lettere accentate arrivano storpiate; scrivi i messaggi senza accenti, come nell'esempio.

Ogni SMS costa. Non mettere mai il codice che invia SMS dentro loop() senza una condizione: un guasto che scatta ogni secondo significa centinaia di messaggi e una bolletta salata in pochi minuti. Per eventi che si ripetono, come gli allarmi, imposta un tempo di attesa tra due messaggi con millis(); trovi come fare nella nostra guida millis() e delay().

Comandare un relè via SMS e commutarlo con una chiamata

Per leggere i messaggi in arrivo usiamo AT+CNMI=1,2,0,0,0: con questa impostazione il modulo non salva i nuovi SMS sulla SIM ma li scrive direttamente sulla seriale su due righe. La prima, come +CMT: "+905551112233","","26/10/30,14:05:12+12", contiene il numero del mittente e l'ora (il +12 finale è il fuso orario in quarti d'ora, qui UTC+3), la seconda il messaggio vero e proprio. Lo sketch qui sotto comanda un modulo relè su D7 con i messaggi «ROLE AC» (relè acceso), «ROLE KAPA» (relè spento) e «DURUM» (stato), risponde con un SMS dopo ogni comando e accetta solo i messaggi provenienti dal tuo numero; ovviamente nel codice puoi rinominare i comandi in ON, OFF e STATO. Inoltre, grazie ad AT+CLIP=1, quando chiami il modulo dal tuo numero la chiamata viene rifiutata senza risposta e il relè cambia stato; poiché una chiamata senza risposta non si paga, è l'interruttore remoto più economico che esista. Alcune reti inviano il numero del mittente in formato nazionale invece che internazionale; se i comandi vengono ignorati, guarda la riga +CMT nel Monitor seriale e scrivi OWNER nello stesso formato.

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}
Parte del codiceCosa fa
ATE0Disattiva l'eco: il modulo non ripete più i comandi inviati e le righe in arrivo sono più pulite
AT+CNMI=1,2,0,0,0Scrive ogni nuovo SMS sulla seriale come una riga +CMT seguita subito dal testo del messaggio
AT+CLIP=1In una chiamata in arrivo indica il numero di chi chiama in una riga +CLIP dopo RING
strstr(line, OWNER)Controlla se nella riga compare il numero autorizzato; i comandi di altri numeri vengono ignorati
toupper()Converte il testo in maiuscolo così «role ac» e «ROLE AC» vengono trattati allo stesso modo
ATHChiude la chiamata in arrivo senza rispondere
RELAY_ONDa impostare a LOW per i moduli relè attivi a livello basso (active-low)
Se con il relè commuti la tensione di rete a 230 V, fai i collegamenti con l'apparecchio scollegato dalla presa e non toccare mai la parte ad alta tensione; se non hai esperienza, prova prima con un LED o un carico a 12 V. Tieni anche presente che il numero del mittente mostrato in un SMS può essere falsificato. Se comandi qualcosa di importante, come una serratura o una caldaia, aggiungi al comando una password che conosci solo tu (per esempio «ROLE AC 4827») e verificala anche nel codice.

Telefonare con il SIM800L: fatti chiamare quando scatta l'allarme

Per chiamare si scrive il numero seguito da un punto e virgola dopo il comando ATD: ATD+905551112233;. Il punto e virgola finale indica una chiamata vocale; se lo dimentichi, il modulo avvia una chiamata dati e la chiamata vocale non parte. Se l'altra parte rifiuta o la conversazione finisce, il modulo scrive NO CARRIER o BUSY; se nessuno risponde, NO ANSWER; senza rete, NO DIALTONE. ATH chiude la chiamata in qualsiasi momento. Per un allarme, un telefono che squilla attira molta più attenzione di un SMS. Lo sketch qui sotto invia un SMS quando scatta un sensore di movimento PIR collegato a D4, poi fa squillare il tuo telefono per un massimo di 20 secondi e aspetta 2 minuti tra un allarme e l'altro:

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}

Lo sketch resta in silenzio anche nei primi 2 minuti dopo l'accensione; questo dà al sensore PIR il tempo di stabilizzarsi e a te il tempo di uscire di casa. Se rispondi, la chiamata si collega; con un microfono electret e un piccolo altoparlante da 8 Ω sui pin MIC e SPK del SIM800L puoi parlare attraverso il dispositivo. Per rispondere automaticamente alle chiamate in arrivo basta inviare ATA quando compare la riga RING. Durante una chiamata il modulo assorbe in media 130–220 mA, con picchi che restano di 2 A; se l'alimentazione regge gli SMS ma il modulo si spegne durante le chiamate, usa un condensatore più grande o una sorgente più potente.

SIM800L con ESP32 e la scheda TTGO T-Call

Su ESP32 SoftwareSerial non serve: una qualsiasi delle sue tre UART hardware può essere assegnata ai pin che preferisci. Per usare gli sketch per Uno visti sopra su un ESP32, cancella le righe di SoftwareSerial, scrivi al loro posto HardwareSerial sim800(2); e usa sim800.begin(9600, SERIAL_8N1, 16, 17); in setup(); il resto del codice funziona così com'è. Dato che ESP32 lavora a 3,3 V, basta un partitore da 1 kΩ + 5,6 kΩ sulla linea TX. Se alimenti il SIM800L con la stessa sorgente debole dell'ESP32, gli impulsi da 2 A fanno calare anche la tensione dell'ESP32 e la scheda si riavvia con l'errore «Brownout detector was triggered»; alimenta le due schede separatamente e collega solo i GND. Spieghiamo questo errore nel dettaglio nella nostra guida sul brownout di ESP32.

Se preferisci evitare i cablaggi, la scheda LilyGO TTGO T-Call riunisce un ESP32 e un modem SIM800 su un'unica scheda. Monta un modulo ESP32-WROVER-B, un SIM800L (in alcuni lotti il SIM800H della stessa famiglia), un porta SIM, un connettore per batteria LiPo e il chip di gestione dell'energia IP5306, che ricarica la batteria e fornisce la corrente necessaria al modem. Il modem si accende e si spegne tramite GPIO specifici dell'ESP32 e non con pin esterni, per questo i normali sketch per SIM800L non funzionano così come sono sulla T-Call.

Scheda LilyGO TTGO T-Call ESP32 SIM800
TTGO T-Call: sul fronte l'ESP32-WROVER-B e il modem SIM800, sul retro il porta SIM e il connettore della batteria LiPo.
Definizione T-CallGPIOFunzione
MODEM_PWRKEY4Accende il modem con un impulso LOW di 1 secondo
MODEM_RST5Reset del modem; tenuto a HIGH
MODEM_POWER_ON23A HIGH accende l'alimentazione del modem
MODEM_TX27Dall'ESP32 all'ingresso RXD del modem
MODEM_RX26Dall'uscita TXD del modem all'ESP32
I2C SDA / SCL21 / 22Chip di alimentazione IP5306 (indirizzo 0x75)
LED13LED utente sulla scheda
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}

Questi pin valgono per le versioni T-Call SIM800L di LilyGO con IP5306. Nella versione con il chip di alimentazione AXP192 questo si configura con un codice diverso, mentre nella versione con SIM800C il pin di alimentazione del modem è il GPIO 25; guarda la data di versione stampata sulla tua scheda e la tabella dei pin del produttore. La funzione setPowerBoostKeepOn() scrive 0x37 nel registro 0x00 dell'IP5306 e impedisce al chip di spegnersi da solo con carichi bassi quando funziona a batteria. Se il modem si spegne durante la registrazione quando la scheda è alimentata solo dalla USB del computer, collega anche la batteria LiPo: è lei ad assorbire gli impulsi da 2 A. Sull'ESP32-WROVER i GPIO 16 e 17 sono riservati alla PSRAM interna, per questo il modem è collegato a 26 e 27. Per attività GPRS come richieste HTTP o MQTT, la libreria TinyGSM supporta questa scheda con la definizione TINY_GSM_MODEM_SIM800.

SIM800L con Raspberry Pi Pico e MicroPython

Sul Raspberry Pi Pico colleghiamo il modulo alla UART0: il TXD del SIM800L va a GP1, il suo RXD va a GP0 tramite un partitore da 1 kΩ + 5,6 kΩ e i GND vengono uniti. I pin VBUS e 3V3 del Pico non possono alimentare il SIM800L, quindi anche qui usa una sorgente esterna da 4 V. Il codice MicroPython qui sotto fa lo stesso lavoro dell'esempio del relè con Arduino: accende e spegne il relè su GP15 via SMS e invia una risposta. La funzione to_text() scarta i byte corrotti dai disturbi e tiene solo i caratteri ASCII, così un errore di decodifica non blocca il programma. Non servono librerie aggiuntive; se non sai come eseguirlo con Thonny, leggi prima la nostra guida sulle basi di MicroPython.

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

Idee di progetto con il SIM800L

  • Antifurto con SMS: un sistema che invia un SMS e poi ti chiama quando un sensore PIR o un contatto porta rileva movimento; trovi i dettagli nella nostra guida al sistema d'allarme con Arduino.
  • Allarme fuga di gas: ricevi un SMS sul telefono quando il sensore di gas MQ-2 supera la soglia, anche se in casa non c'è nessuno.
  • Localizzatore GPS che risponde via SMS: con un modulo GPS NEO-6M, un localizzatore per auto o bici che risponde al messaggio «POSIZIONE» con un link a Google Maps.
  • Irrigazione a distanza: un sistema per orto o casa di campagna che comunica via SMS il valore del sensore di umidità del terreno e avvia la pompa con il messaggio «INNAFFIA».
  • Sentinella della temperatura: un circuito con DS18B20 che avvisa quando una serra, un pollaio o un congelatore esce dall'intervallo previsto.
  • Cancello del garage con una chiamata: un telecomando gratuito che attiva il relè per un secondo solo quando chiama un numero registrato.
  • Avviso di blackout: un piccolo circuito che continua a funzionare a batteria quando manca la corrente e invia l'SMS «Corrente assente».

Non si collega alla rete, l'SMS non parte: errori comuni e soluzioni

SintomoCausa probabileSoluzione
Nessuna risposta digitando ATTXD e RXD invertiti, nessuna massa comune, fine riga sbagliato o riconoscimento del baud rate non sincronizzatoCollega TXD a D2, unisci i GND, scegli Both NL & CR e invia AT più volte
Caratteri senza sensoBaud rate diverso o livello logico al limiteImposta 9600 nel Monitor seriale e nello sketch, usa un convertitore di livello
Il LED lampeggia qualche volta e si spegne, il modulo si riavviaDurante la registrazione la tensione scende sotto 3,4 VSorgente da 2 A, condensatore da 1000 µF, cavi corti e spessi
Sulla seriale compare UNDER-VOLTAGE POWER DOWNL'alimentazione è scesa sotto 3,4 VRicarica la batteria o regola l'uscita del buck a 4,0–4,1 V
OVER-VOLTAGE WARNNING o OVER-VOLTAGE POWER DOWNLa tensione supera 4,3–4,4 VAbbassa l'uscita a 4,0 V; non collegare mai il modulo a 5 V
Il LED continua a lampeggiare una volta al secondoNiente antenna, SIM non letta, PIN attivo o niente 2G in zonaMonta l'antenna, controlla con AT+CPIN? e AT+CSQ, verifica la copertura 2G con un telefono
Risposta +CREG: 0,3La rete ha rifiutato la registrazioneControlla che la linea sia attiva e che l'IMEI non sia bloccato
L'SMS fallisce con +CMS ERRORCredito esaurito, formato del numero errato o numero del centro messaggi mancanteControlla il credito, scrivi il numero con il prefisso, verifica il centro messaggi con AT+CSCA?
Arduino si riavvia mentre invia un SMSSIM800L e Arduino condividono la stessa sorgente deboleSepara le alimentazioni e collega solo i GND
Gli SMS in arrivo non compaiono sulla serialeAT+CNMI non impostato o perso al riavvio del moduloInvia AT+CMGF=1 e AT+CNMI=1,2,0,0,0 nel setup
Il modo più rapido per capire se il problema è nel codice o nell'hardware è collegare il modulo direttamente al computer con un convertitore USB-TTL a 3,3 V e digitare i comandi AT a mano. Durante la diagnosi invia AT+CMEE=2: il modulo mostrerà messaggi di errore leggibili come «+CME ERROR: SIM not inserted» invece di «+CME ERROR: 10».

Se alimentato bene e usato dove c'è copertura 2G, il SIM800L è il modo più economico per raggiungere i tuoi progetti Arduino da qualsiasi distanza: bastano una sorgente solida da 4 V, un condensatore grande e qualche comando AT. Se vuoi confrontare le altre soluzioni wireless, dai un'occhiata alla nostra guida sui moduli di comunicazione wireless. Nell'app BlueGrays trovi progetti facili da ampliare con un SIM800L, come un allarme con sensore di movimento, un allarme gas e fiamma, il controllo di una lampada a 230 V, un'irrigazione intelligente e un allarme con ESP32 e notifiche Telegram, tutti con schema elettrico e codice passo passo.

Domande frequenti

Che tensione serve al SIM800L, si può collegare a 5V?

Il SIM800L funziona tra 3,4 e 4,4 V, con 4,0 V come valore consigliato. Collegarlo al pin 5V di Arduino lo fa spegnere per sovratensione o lo danneggia. Usa una batteria LiPo a una cella o una 18650, oppure un LM2596 regolato a 4,0 V; la sorgente deve anche reggere brevi picchi da 2 A.

Il SIM800L funziona ancora in Italia?

Sì: gli operatori italiani hanno spento il 3G ma mantengono attiva la rete 2G, e al momento non risultano date ufficiali per spegnerla. Puoi quindi usarlo con una normale SIM, verificando con un telefono impostato su «solo 2G» che ci sia copertura dove installerai il progetto. Per progetti che devono durare molti anni, valuta comunque un modulo 4G LTE.

Perché il mio SIM800L non si collega alla rete?

Le cause più comuni sono un'alimentazione insufficiente, l'antenna mancante, una SIM con PIN attivo e l'assenza di 2G nella zona. Controlla il segnale con AT+CSQ, la SIM con AT+CPIN? e la registrazione con AT+CREG?. Se il modulo si riavvia durante la registrazione, il problema è senza dubbio l'alimentazione.

Cosa significano i lampeggi del LED del SIM800L?

Un lampeggio al secondo indica che il modulo è acceso ma non registrato sulla rete, un lampeggio ogni 3 secondi che è registrato e pronto per SMS e chiamate. Un lampeggio molto veloce significa che è attiva una connessione dati GPRS. Se il LED lampeggia qualche volta e poi si spegne, il modulo si sta riavviando per un calo di tensione.

Il SIM800L può collegarsi a internet?

Sì, tramite GPRS invia e riceve dati fino a 85,6 kbps, abbastanza per mandare i dati dei sensori a un server, fare richieste HTTP o usare MQTT. Devi impostare l'APN del tuo operatore, e la libreria TinyGSM semplifica il lavoro. Per immagini o file grandi, invece, è troppo lento.

Quale modulo posso usare al posto del SIM800L?

Nei paesi in cui il 2G è stato o sta per essere spento si usano moduli 4G LTE come il SIM7600 o l'A7670, oppure moduli LTE-M/NB-IoT come il SIM7080G. La maggior parte dei comandi AT è simile, quindi il codice per SMS e chiamate si adatta con poche modifiche. Il SIM800C e il vecchio SIM900 della stessa famiglia usano comandi simili, ma anche loro funzionano solo in 2G.

Vedi tutti i progetti
Temperatura e umidità con DHT11
#55Intermedio

Temperatura e umidità con DHT11

Quanti gradi ci sono nella tua stanza, e l'aria è umida o secca? Il sensore DHT11 misura temperatura e umidità, e l'Arduino scrive i valori su uno schermo LCD a due righe, aggiornandoli ogni paio di s

4.7(47)
64
Sistema di Allarme Movimento ESP32 (PIR + Buzzer + LED + Telegram)
#145Avanzato
Premium

Sistema di Allarme Movimento ESP32 (PIR + Buzzer + LED + Telegram)

Un sistema di allarme di sicurezza intelligente che attiva buzzer e LED quando il sensore PIR rileva movimento, inviando contemporaneamente una notifica istantanea al proprietario tramite Telegram. Dispone di un tempo di attesa di 30 secondi per limitare la frequenza degli allarmi ripetuti; questo meccanismo non verifica la validità dei rilevamenti del sensore PIR né elimina le false attivazioni. Adatto a sicurezza domestica, monitoraggio di garage, magazzini o studi. Con l'ESP32-CAM è possibile

0.0(0)
8
Rilevatore di movimento con sensore di movimento
#24Principiante
Premium

Rilevatore di movimento con sensore di movimento

Un semplice guardiano che ti avvisa quando qualcuno entra nella stanza. Il sensore di movimento percepisce il calore emesso dal corpo umano, e l'Arduino tiene acceso il LED finché c'è movimento e lo s

4.6(47)
67
Allarme con sensore di movimento ESP32
#140Intermedio
Premium

Allarme con sensore di movimento ESP32

In questo progetto, realizzato utilizzando un ESP32 e un sensore PIR, quando viene rilevato un movimento, il cicalino si attiva emettendo un allarme acustico. Si tratta di un'applicazione semplice ed economica per un sistema di sicurezza. (Le immagini sono puramente illustrative; collegarle in base al testo)

4.4(10)
15
Allarme del sensore di fiamma e gas
#52Avanzato
Premium

Allarme del sensore di fiamma e gas

Un piccolo guardiano che ti avvisa subito se c'è una fuga di gas o compare una fiamma da qualche parte. Il sensore di gas controlla l'aria e il sensore di fiamma cerca la luce del fuoco; finché va tut

4.8(52)
67
Lampadina 220V con pulsante (Push)
#19Avanzato
Premium

Lampadina 220V con pulsante (Push)

Finché tieni premuto il pulsante, una vera lampadina da 220 volt resta accesa, e si spegne appena lo lasci. Il piccolo segnale dell'Arduino non può accendere la lampadina direttamente, quindi in mezzo

4.4(30)
38
Accendere una lampadina 220V con il telecomando
#21Avanzato
Premium

Accendere una lampadina 220V con il telecomando

Accendi e spegni una vera lampadina di casa con un telecomando, senza alzarti dal divano. L'Arduino legge il segnale di luce invisibile del telecomando; il tasto di accensione fa scattare il relè e ac

4.4(22)
30
Stazione di irrigazione intelligente
#83Avanzato
Premium

Stazione di irrigazione intelligente

Un giardiniere che annaffia le tue piante da solo, così non si seccano mentre sei in vacanza. Un sensore di umidità misura quanto è bagnata la terra; quando diventa secca, l'Arduino accende la pompa d

5.0(42)
57