{"id":25811073,"url":"https://github.com/tabahi/statefulgsmlib","last_synced_at":"2026-05-06T14:38:57.038Z","repository":{"id":279610684,"uuid":"939167849","full_name":"tabahi/StatefulGSMLib","owner":"tabahi","description":"ESP32/arduino library for SIM800l GSM module. ","archived":false,"fork":false,"pushed_at":"2025-02-26T13:42:54.000Z","size":1,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-26T13:43:00.986Z","etag":null,"topics":["arduino","arduino-library","cellular","esp32","gprs","gsm","gsm-module","sim800","sim800l"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tabahi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-02-26T05:19:34.000Z","updated_at":"2025-02-26T12:51:14.000Z","dependencies_parsed_at":"2025-02-26T13:53:08.076Z","dependency_job_id":null,"html_url":"https://github.com/tabahi/StatefulGSMLib","commit_stats":null,"previous_names":["tabahi/esp32-sim800-gsm"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/tabahi/StatefulGSMLib","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tabahi%2FStatefulGSMLib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tabahi%2FStatefulGSMLib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tabahi%2FStatefulGSMLib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tabahi%2FStatefulGSMLib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tabahi","download_url":"https://codeload.github.com/tabahi/StatefulGSMLib/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tabahi%2FStatefulGSMLib/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32698855,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-06T08:33:17.875Z","status":"ssl_error","status_checked_at":"2026-05-06T08:33:17.221Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arduino","arduino-library","cellular","esp32","gprs","gsm","gsm-module","sim800","sim800l"],"created_at":"2025-02-28T00:34:30.541Z","updated_at":"2026-05-06T14:38:57.020Z","avatar_url":"https://github.com/tabahi.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# StatefulGSMLib (2025)\n\nThis library provides a clean, well-structured interface for controlling a SIM800L GSM/GPRS module with an ESP32. It implements a state machine to handle the various states of modem operation, including initialization, network registration, and SMS handling.\n\n## Features\n\n- Robust state machine for handling various modem states\n- SMS sending and receiving capabilities\n- Network status monitoring\n- Signal strength monitoring\n- TCP/UDP communication support\n- HTTP data fetching\n\n## Hardware Requirements\n\n- ESP32 development board.\n- Can work with other boards. The only dependency here is the Hardware Serial instance.\n- SIM800L GSM/GPRS module. Should work with other similar modules. Scraped modules from aliexpress don't work.\n- SIM card with 2G capability. Tested in the UK (Vodafone and EE works as of 2025).\n- Power supply capable of providing sufficient current for the SIM800L module.\n\n\n## Configuration\n\nAll pin assignments and timing parameters can be configured in `configSIM800L.h` in examples or `StatefulGSMLibconfig.h` for defaults. Update the `TARGET_PHONE` define to set the authorized phone number for SMS commands.\n\n## Usage\n\n\n### Getting started - Checking new SMS\n```cpp\n// Include necessary headers\n#include \"configSIM800L.h\"\n#include \"StatefulGSMLib.h\"\n\n// Hardware configuration\n#define MODEM_RX_PIN         26  // ESP32 pin connected to SIM800L TX, must connect\n#define MODEM_TX_PIN         27  // ESP32 pin connected to SIM800L RX, must connect\n#define MODEM_RST_PIN        5   // Reset pin, set to -1 to ignore\n#define MODEM_PWRKEY_PIN     4   // Power key pin, must connect\n#define MODEM_PWR_EXT_PIN    23  // External power control, set to -1 to ignore\n#define MODEM_BAUD_RATE      9600\n\n\n// Create a hardware serial for the modem\nHardwareSerial HSerial1(1);\n\n// Create SIM800L instance\nSIM800L sim800(HSerial1);\n\nvoid setup() {\n  // Initialize serial for debugging\n  Serial.begin(9600);\n  \n  // Initialize SIM800L module with your pin configuration\n  sim800.begin(MODEM_BAUD_RATE, MODEM_RX_PIN, MODEM_TX_PIN, MODEM_PWRKEY_PIN, MODEM_RST_PIN, MODEM_PWR_EXT_PIN);\n}\n\nvoid loop() {\n  // Run the SIM800L state machine\n  sim800.loop();\n  \n  // Process any received SMS messages\n  if (sim800.sms_available) {\n    // Handle the received message\n    String sender = sim800.receivedNumber;\n    String message = sim800.receivedMessage;\n    \n    Serial.println(\"SMS from: \" + sender);\n    Serial.println(\"Message: \" + message);\n    \n    // Clear the flag to avoid processing the same message repeatedly\n    sim800.sms_available = false;\n  }\n}\n```\n\n### Sending an SMS\n```cpp\n// Assuming you have already initialized the modem as shown above\n\n// Send an SMS to a specific number\nvoid sendStatusMessage(String phoneNumber) {\n  String statusMessage = \"Device status: Signal strength = \" + \n                         String(sim800.getSignalStrength()) + \n                         \", All systems operational.\";\n  \n  // Queue the message for sending (the state machine will handle the actual sending)\n  sim800.sendSMS(phoneNumber, statusMessage);\n}\n\n// Example usage in your code\nif (buttonPressed) {\n  sendStatusMessage(TARGET_PHONE);\n}\n```\n\n### TCP connect and request\n```cpp\n// Assuming you have already initialized the modem as shown above\n\n// Connect to a server and send a TCP request\nbool sendDataToServer(String host, int port, String data) {\n  // Initialize TCP connection\n  if (sim800.initTCP(host, port)) {\n    Serial.println(\"Connected to server\");\n    \n    // Send data\n    if (sim800.sendData(data)) {\n      Serial.println(\"Data sent successfully\");\n      \n      // Wait for response (10 second timeout)\n      String response = sim800.receiveData(10000);\n      Serial.println(\"Server response: \" + response);\n      \n      // Close the connection\n      sim800.closeConnection();\n      return true;\n    } else {\n      Serial.println(\"Failed to send data\");\n    }\n    \n    // Ensure connection is closed\n    sim800.closeConnection();\n  } else {\n    Serial.println(\"Failed to connect to server\");\n  }\n  \n  return false;\n}\n\n// Example usage\nif (sim800.state() == STATE_READY) {\n  sendDataToServer(\"example.com\", 80, \"Hello Server!\");\n}\n```\n\n### UDP connect and send\n```cpp\n// Assuming you have already initialized the modem as shown above\n\n// Connect to a server and send a UDP datagram\nbool sendUDPData(String host, int port, String data) {\n  // Initialize UDP connection\n  if (sim800.initUDP(host, port)) {\n    Serial.println(\"UDP connection established\");\n    \n    // Send data\n    if (sim800.sendData(data)) {\n      Serial.println(\"UDP data sent successfully\");\n      \n      // For UDP, you might want to receive a response\n      String response = sim800.receiveData(5000);\n      if (response.length() \u003e 0) {\n        Serial.println(\"Received UDP response: \" + response);\n      }\n      \n      // Close the connection\n      sim800.closeConnection();\n      return true;\n    } else {\n      Serial.println(\"Failed to send UDP data\");\n    }\n    \n    // Ensure connection is closed\n    sim800.closeConnection();\n  } else {\n    Serial.println(\"Failed to establish UDP connection\");\n  }\n  \n  return false;\n}\n\n// Example usage in your code\nif (sim800.state() == STATE_READY \u0026\u0026 dataNeedsToSend) {\n  sendUDPData(\"udpserver.com\", 8080, \"Status update: \" + getSensorData());\n}\n```\n\n### HTTP Request Example\n```cpp\n// Connect to a server and perform an HTTP GET request\nbool performHTTPGet(String host, int port, String path) {\n  // Initialize TCP connection\n  if (sim800.initTCP(host, port)) {\n    Serial.println(\"Connected to HTTP server\");\n    \n    // Construct HTTP GET request\n    String httpRequest = \n      \"GET \" + path + \" HTTP/1.1\\r\\n\" +\n      \"Host: \" + host + \"\\r\\n\" +\n      \"Connection: close\\r\\n\\r\\n\";\n    \n    // Send the HTTP request\n    if (sim800.sendData(httpRequest)) {\n      Serial.println(\"HTTP request sent\");\n      \n      // Receive the HTTP response (with 15-second timeout)\n      String httpResponse = sim800.receiveData(15000);\n      \n      // Process the response\n      if (httpResponse.length() \u003e 0) {\n        Serial.println(\"HTTP Response received: \");\n        Serial.println(httpResponse);\n      } else {\n        Serial.println(\"No response or timeout\");\n      }\n      \n      // Close the connection\n      sim800.closeConnection();\n      return true;\n    }\n    \n    // Ensure connection is closed\n    sim800.closeConnection();\n  }\n  \n  return false;\n}\n\n// Example usage\nif (sim800.state() == STATE_READY) {\n  performHTTPGet(\"example.com\", 80, \"/api/data\");\n}\n```\n\n## State Machine\n\nThe SIM800L state machine goes through the following states:\n\n1. **RESET**: Resets the modem hardware\n2. **POST_RESET**: Waits after reset\n3. **CHECK_AT**: Verifies AT command interface is working\n4. **CHECK_SIM**: Checks if SIM card is available\n5. **CHECK_NETWORK**: Checks for cellular network registration\n6. **INITIALIZE**: Configures SMS settings\n7. **READY**: Normal operation, handles SMS and maintains network connection\n\n\n![State Diagram](state_diagram.png)\n\n\n## Error Recovery\n\nThe library includes automatic error recovery:\n\n- Automatically resets the modem if it becomes unresponsive\n- Attempts to re-register to the network if connection is lost\n- Monitors signal strength and network health\n- Implements retry mechanisms for failed operations\n\n\n## Wiring\nThe library instance is initialized as following:\n```cpp\n\nsim800.begin(MODEM_BAUD_RATE, MODEM_RX_PIN, MODEM_TX_PIN, MODEM_PWRKEY_PIN, MODEM_RST_PIN, MODEM_PWR_EXT_PIN);\n```\nThe `MODEM_RST_PIN` and `MODEM_PWR_EXT_PIN` are optional and can be set to -1 to opt-out. It is recommened to connect the `MODEM_RST_PIN` to ensure smooth resetting. It will help to have an external MOSFET to switch On and Off the SIM800 module, in that case `MODEM_PWR_EXT_PIN` can be used to control the MOSFET.\n\nThis module has been tested with [LilyGo-T-Call-SIM800](https://github.com/Xinyuan-LilyGO/LilyGo-T-Call-SIM800) that has an ESP32-Wrover connected to these pins:\n\n\n| ESP32 Pin | SIM800L Pin |\n|-----------|-------------|\n| GPIO 27   | RX          |\n| GPIO 26   | TX          |\n| GPIO 5    | RST         |\n| GPIO 4    | PWRKEY      |\n| GPIO 23   | VDD         |\n| GND       | GND         |\n\n## Handling Communication Errors\n\nThe library handles common communication errors with SIM800L modules:\n\n- Automatically retries failed SMS transmissions with exponential backoff\n- Monitors network registration status and re-registers when needed\n- Verifies successful message sending with multiple confirmation methods\n- Stores last error message for debugging (`sim800.lastErrorMessage`)\n\n## Power Management\n\nFor reliable operation of the SIM800L module, keep in mind:\n\n- The module requires a stable power supply capable of handling current spikes up to 2A\n- Use appropriate capacitors (recommended 100μF) between VCC and GND\n- Consider using a dedicated power regulator for the SIM800L module\n\n## License\n\nThe Unlicense","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftabahi%2Fstatefulgsmlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftabahi%2Fstatefulgsmlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftabahi%2Fstatefulgsmlib/lists"}