A SIM800L lets a NodeMCU send SMS alerts and make missed calls when Wi-Fi is down — handy for power-cut alarms and farm pump controllers. It is also the module that most often “doesn’t work”, almost always because of power.
This guide gets the basics right: a separate 4.0 V, 2 A supply, a common ground, and the module’s serial lines on D5/D6 with SoftwareSerial, so the USB Serial Monitor stays free for testing. The sketch checks the SIM and network, then lets you type AT commands.
Wiring
| NodeMCU ESP8266 | SIM800L GSM/GPRS module (2G) | Wire | Notes |
|---|---|---|---|
| — | NET | — | To GSM antenna (helical spring or IPEX) (not drawn) |
| LM2596 buck set to 4.0 V (2 A+) · + | VCC | red | 4.0 V with 2 A peaks. Add a 1000 µF capacitor right at the module’s VCC/GND. |
| LM2596 buck set to 4.0 V (2 A+) · - | GND | black | |
| GND | GND | black | Common ground — the serial lines don’t work without it. |
| D5 | TXD | green | SIM800L TXD → D5 (GPIO14), the SoftwareSerial RX. |
| D6 | RXD | yellow | D6 (GPIO12) → SIM800L RXD. 3.3 V logic is accepted by the ~2.8 V input. |
3.4–4.4 V, peaks up to 2 A part, 3.3 V board. The SIM800L’s serial pins work at about 2.8 V. Its TXD is read fine by 3.3 V and 5 V boards; its RXD must be protected from a 5 V Arduino TX with a divider (10 kΩ / 20 kΩ). ESP32 and Pico can connect directly.
Board quirks
- Power is everything. The SIM800L pulls up to 2 A in bursts when it transmits. The NodeMCU’s 3V3 regulator can’t supply that and its VIN (USB 5 V) is too high for the module (3.4–4.4 V). Use a buck converter set to 4.0 V, or a single Li-ion cell, with a big capacitor at the module.
- The ESP8266’s only full hardware UART is the USB serial on TX/RX. This guide uses SoftwareSerial (EspSoftwareSerial, bundled with core 3.1.2 — no install needed) on D5/D6. Keep it at 9600 baud: Wi-Fi interrupts can corrupt bytes at higher software-serial speeds.
- Alternative for a finished build:
Serial.swap()moves the hardware UART to D7 (RX) / D8 (TX). It is rock-solid, but you lose the USB Serial Monitor, and the module’s TXD must not hold D8 high at boot — that is why this guide doesn’t start there. - Avoid D3/D4/D8 for the module’s TXD: it idles HIGH, which would hold D8 (GPIO15) high and stop the board booting.
- India: the SIM800L is 2G-only. Jio is 4G-only, so Jio SIMs never register. Airtel, Vi and BSNL still run 2G in many areas, but check coverage first; for new designs consider a 4G module (A7670, SIM7600).
- Waits for module replies use
yield()— on the ESP8266 a long wait without it can end in a soft WDT reset.
Code
// SIM800L GSM module on a NodeMCU (ESP8266) — checks the module and network, then bridges
// the Serial Monitor to the SIM800L so you can type AT commands.
// SIM800L VCC/GND → its own 4.0 V 2 A supply; that supply's − also → NodeMCU GND.
// TXD → D5 (GPIO14, SoftwareSerial RX), RXD → D6 (GPIO12, SoftwareSerial TX).
#include <SoftwareSerial.h> // EspSoftwareSerial, bundled with the ESP8266 core
SoftwareSerial sim(D5, D6); // RX, TX
void at(const char* cmd, unsigned long waitMs = 1000) {
sim.println(cmd);
unsigned long t = millis();
while (millis() - t < waitMs) {
while (sim.available()) Serial.write(sim.read());
yield(); // let Wi-Fi and the watchdog run
}
}
void setup() {
Serial.begin(115200);
sim.begin(9600); // SIM800L auto-bauds; 9600 is reliable for SoftwareSerial on the ESP8266
Serial.println();
Serial.println("SIM800L check - set the Serial Monitor to 'Both NL & CR'");
delay(3000); // give the module time to start after power-up
at("AT"); // expect OK
at("AT+CPIN?"); // SIM inserted? expect +CPIN: READY
at("AT+CSQ"); // signal 0-31 (99 = none)
at("AT+CREG?"); // 0,1 = home network, 0,5 = roaming
at("AT+COPS?"); // operator name
Serial.println("Type AT commands now");
}
void loop() {
while (Serial.available()) sim.write(Serial.read());
while (sim.available()) Serial.write(sim.read());
}// SIM800L GSM module on a NodeMCU (ESP8266) — checks the module and network, then bridges
// the Serial Monitor to the SIM800L so you can type AT commands.
// SIM800L VCC/GND → its own 4.0 V 2 A supply; that supply's − also → NodeMCU GND.
// TXD → D5 (GPIO14, SoftwareSerial RX), RXD → D6 (GPIO12, SoftwareSerial TX).
#include <SoftwareSerial.h> // EspSoftwareSerial, bundled with the ESP8266 core
SoftwareSerial sim(D5, D6); // RX, TX
void at(const char* cmd, unsigned long waitMs = 1000) {
sim.println(cmd);
unsigned long t = millis();
while (millis() - t < waitMs) {
while (sim.available()) Serial.write(sim.read());
yield(); // let Wi-Fi and the watchdog run
}
}
void setup() {
Serial.begin(115200);
sim.begin(9600); // SIM800L auto-bauds; 9600 is reliable for SoftwareSerial on the ESP8266
Serial.println();
Serial.println("SIM800L check - set the Serial Monitor to 'Both NL & CR'");
delay(3000); // give the module time to start after power-up
at("AT"); // expect OK
at("AT+CPIN?"); // SIM inserted? expect +CPIN: READY
at("AT+CSQ"); // signal 0-31 (99 = none)
at("AT+CREG?"); // 0,1 = home network, 0,5 = roaming
at("AT+COPS?"); // operator name
Serial.println("Type AT commands now");
}
void loop() {
while (Serial.available()) sim.write(Serial.read());
while (sim.available()) Serial.write(sim.read());
}Library: TinyGSM (Volodymyr Shymanskyy).
Expected serial output
SIM800L check - set the Serial Monitor to 'Both NL & CR'
AT
OK
AT+CPIN?
+CPIN: READY
OK
AT+CSQ
+CSQ: 18,0
OK
AT+CREG?
+CREG: 0,1
OK
AT+COPS?
+COPS: 0,0,"airtel"
OK
Type AT commands nowSIM800L check - set the Serial Monitor to 'Both NL & CR' AT OK AT+CPIN? +CPIN: READY OK AT+CSQ +CSQ: 18,0 OK AT+CREG? +CREG: 0,1 OK AT+COPS? +COPS: 0,0,"airtel" OK Type AT commands now
Common errors
Module keeps restarting, NET LED blinks then goes off
Supply too weak or wires too thin. Use 4.0 V at 2 A with a 1000 µF capacitor. See SIM800L keeps restarting.
No reply to AT at all
TXD/RXD swapped (module TXD goes to D5), no common GND, or the module is still starting — wait a few seconds after power-up.
+CREG: 0,2 or 0,0 for ever
Not registering: a Jio SIM, no 2G in your area, or no antenna. Try an Airtel or BSNL SIM and fit the antenna.