Skip to content

BRobin55/sim7080g_showcase

Repository files navigation

SIM7080G Pico Library

A C++17 library for the Raspberry Pi Pico that drives a SIMCom SIM7080G LTE Cat-M / NB-IoT modem over UART via AT commands.

Built from a real GPS/LTE car-tracker project. The library covers the full connectivity lifecycle: modem startup, network attachment, PDP context activation, MQTT publish/subscribe, and TLS certificate upload to modem flash.


Features

  • Interrupt-driven UART receive buffer with unsolicited result code (URC) dispatch
  • AT command helper that waits for final results (OK, ERROR, +CME, +CMS) instead of returning on partial response substrings
  • Prompt/payload command helper for MQTT, HTTP body upload, SMS, TCP sends and modem file uploads
  • Basic modem identity commands (ATI, CGMI, CGMM, CGMR, CGSN, GCAP)
  • SIM identity/status helpers (CPIN, CIMI, CCID, optional PIN unlock)
  • LTE Cat-M / NB-IoT mode selection and full network attachment sequence (SIM PIN check, signal quality, GPRS attachment polling, APN, PDP context)
  • 3GPP PDP helpers (CGATT, CGDCONT, CGACT, CGPADDR, CGAUTH)
  • App Network helpers (CNCFG, CNACT, typed CNACT? state)
  • MQTT configure, connect (with retry), publish, subscribe, unsubscribe, state and disconnect
  • HTTP(S) command wrappers (SHCONF, SHSSL, SHCONN, SHBOD, SHREQ, length-based SHREAD)
  • TLS file upload and SSL context configuration (CFS*, CSSLCFG)
  • GNSS power/start/info parsing and wait-for-fix helper (CGNS*)
  • SMS text-mode send/list/read/delete helpers
  • Thin TCP/UDP wrappers for the CA* command family
  • Power, reboot, slow-clock, PSM and eDRX wrappers
  • Battery status reading (charge state, level %, voltage)
  • Comprehensive AT+CPSI? response parser — handles GSM and LTE variants, missing fields represented via std::optional
  • Modular CMake build: three static libraries (at_commandssim7080g → app)

Hardware

Pin Defaults

Signal GPIO Note
Modem UART TX GP0 Pico → modem RXD
Modem UART RX GP1 Modem TXD → Pico
Modem power key GP14 2.5 s active-high pulse to boot module
Debug stdio TX GP4 UART1 — connect to your debug probe/USB
Debug stdio RX GP5 UART1
LED GP25 Onboard Pico LED

All modem pins are configurable through SIM7080GConfig before calling sim7080g_init(config).

Wiring

Pico                    SIM7080G breakout
────────────────        ──────────────────
GP0  (UART0 TX) ──────► RXD
GP1  (UART0 RX) ◄────── TXD
GP14 (GPIO OUT) ──────► PWRKEY
3V3             ──────► VCC    (verify your breakout — some require 4.2 V / 5 V)
GND             ──────  GND

Dependencies

Dependency Version How
Raspberry Pi Pico SDK ≥ 2.1.0 Set PICO_SDK_PATH or use the VS Code extension
nlohmann/json 3.x Single-header bundled in json/json.hpp

Build

git clone https://github.com/BRobin55/sim7080g_showcase
cd sim7080g_showcase

cmake -S . -B build -DPICO_BOARD=pico
cmake --build build --parallel

Flash build/sim7080g_showcase.uf2 to your Pico (hold BOOTSEL while connecting USB).

If the Pico SDK is not on PATH, pass -DPICO_SDK_PATH=/path/to/pico-sdk to the first cmake command or set the environment variable PICO_SDK_PATH.


Repository Layout

sim7080g_showcase/
├── sim7080g/                   # Modem library  (libsim7080g.a)
│   ├── SIM7080G.h/.cpp         #   UART init, IRQ buffer, URC dispatch
│   ├── AT.h/.cpp               #   AT command send/receive with timeout
│   ├── Network.h/.cpp          #   High-level network lifecycle
│   ├── MQTT.h/.cpp             #   MQTT helpers (config, connect, pub, sub)
│   ├── FileSystem.h/.cpp       #   TLS credential file upload
│   └── at_commands/            # Low-level AT wrappers  (libat_commands.a)
│       ├── basic.h/.cpp        #   AT / ATE / ATI / CGMI / CGSN / GCAP
│       ├── battery.h/.cpp      #   AT+CBC  — battery status
│       ├── file_system.h/.cpp  #   AT+CFSTERM / CFSINIT / CFSWFILE
│       ├── gnss.h/.cpp         #   AT+CGNSPWR / CGNSINF / starts / waitForFix
│       ├── http.h/.cpp         #   AT+SHCONF / SHBOD / SHREQ / SHREAD / SHDISC
│       ├── mqtt.h/.cpp         #   AT+SMCONF / SMSSL / SMCONN / SMPUB / SMSUB / SMDISC
│       ├── network.h/.cpp      #   AT+CFUN / CNMP / CMNB / CPIN / CGATT / CPSI / CNACT / CNCFG
│       ├── parser.h/.cpp       #   quoted CSV and response-line helpers
│       ├── pdp.h/.cpp          #   AT+CGATT / CGDCONT / CGACT / CGPADDR / CGAUTH
│       ├── power.h/.cpp        #   boot probe, power cycle, PSM/eDRX, reboot
│       ├── sim.h/.cpp          #   CPIN / CIMI / CCID / CNUM
│       ├── sms.h/.cpp          #   CMGF / CMGS / CMGL / CMGR / CMGD
│       ├── ssl.h/.cpp          #   CSSLCFG generic SSL context helpers
│       └── tcp_udp.h/.cpp      #   CA* thin TCP/UDP wrappers
├── json/                       # JSON payload helper  (libjson.a)
│   ├── json.hpp                #   nlohmann/json (bundled single-header)
│   ├── j.h                     #   createMqttPayload declaration
│   └── json.cpp                #   Payload builder
├── sim7080g_showcase.cpp        # Example application
└── CMakeLists.txt

Dependency order: at_commandssim7080g ← application


Quick Start

1 — Initialize the modem

#include "SIM7080G.h"
#include "power.h"

// Default config: UART0, GP0/GP1, power key GP14, 115200 baud
sim7080g_init();

// Register a handler for unsolicited result codes (e.g. MQTT messages)
sim7080g_set_urc_handler([](const std::string &line) {
    if (line.find("+SMSUB:") != std::string::npos)
        printf("MQTT message: %s\n", line.c_str());
});

check_start(); // probe, power-cycle if needed, retry up to 10×

2 — Attach to LTE Cat-M

#include "Network.h"

set_network(LTE_ONLY, CAT_M);   // AT+CNMP / AT+CMNB
check_network();                 // SIM PIN, signal, GPRS, APN, PDP activate

3 — Connect and publish via MQTT

#include "MQTT.h"
#include "json/j.h"

MqttConnectionConfig cfg;
cfg.host      = "your-broker.example.com";
cfg.port      = "1883";
cfg.client_id = "pico-001";
cfg.use_tls   = false;

mqttSetUpAndConnect(cfg);   // configure + connect, up to 10 retries

std::string payload = createMqttPayload(STATE, "online", cfg.client_id);
// → {"type":"state","data":"online","device_id":"pico-001"}

mqttPublishMessage("device/pico-001/state", payload);
mqttSubscribeToTopic("device/pico-001/cmd");

4 — Drive the URC loop

while (true) {
    process_uart_messages(); // dispatch any buffered URC lines
    sleep_ms(100);
}

TLS / mTLS

The SIM7080G stores TLS material in its own flash. The library uploads it over AT commands using AT+CFSWFILE.

Credential headers are excluded from version control by .gitignore. Use sim7080g/ssl_files/credentials.example.h as the template:

// credentials.h  (never commit this file)
static const unsigned char root_ca[]    = { /* DER bytes */ };
static const size_t        root_ca_len  = sizeof(root_ca);

static const unsigned char client_cert[]    = { /* DER bytes */ };
static const size_t        client_cert_len  = sizeof(client_cert);

static const unsigned char private_key[]    = { /* DER bytes */ };
static const size_t        private_key_len  = sizeof(private_key);

Then pass them to loadSSLFiles():

#include "FileSystem.h"
#include "ssl_files/credentials.h"

SIM7080GTlsCredentials creds;
creds.root_ca          = root_ca;
creds.root_ca_size     = root_ca_len;
creds.client_cert      = client_cert;
creds.client_cert_size = client_cert_len;
creds.private_key      = private_key;
creds.private_key_size = private_key_len;

loadSSLFiles(creds);

Set kUseTls = true and point MqttConnectionConfig::port at 8883 (or your broker's TLS port).


Showcase Application

sim7080g_showcase.cpp walks through the complete workflow end-to-end. Edit the constants at the top before flashing:

constexpr char kMqttHost[]       = "broker.example.com"; // ← your broker
constexpr char kMqttPort[]       = "1883";
constexpr char kMqttClientId[]   = "pico-sim7080g-demo";
constexpr char kPublishTopic[]   = "sim7080g/demo/state";
constexpr char kSubscribeTopic[] = "sim7080g/demo/config";
constexpr bool kUseTls           = false;

Flow:

  1. stdio_init_all() — debug output on UART1 (GP4/GP5)
  2. LED blink — visible boot indicator
  3. sim7080g_init() + check_start() — probe modem, power-cycle if silent
  4. get_battery_status() — log charge state and voltage
  5. Safety gate: exits early if kMqttHost still contains example.com
  6. set_network(LTE_ONLY, CAT_M) — configure radio
  7. check_network() — wait for attachment and activate PDP
  8. mqttSetUpAndConnect() — connect to broker
  9. Publish {"type":"state","data":"online",...}
  10. mqttSubscribeToTopic() — listen for inbound commands
  11. Main loop: process_uart_messages() every 3 s dispatches URC lines

Expected serial output (115200 baud on GP4/GP5):

Start
Charge Status: 0
Battery Level: 87%
Voltage: 4102 mV
AT+CNMP=38 -> OK
AT+CMNB=1 -> OK
...
AT+SMCONN -> OK
AT+SMPUB="sim7080g/demo/state",... -> OK
AT+SMSUB="sim7080g/demo/config",0 -> OK

SIM7080G Configuration Reference

Key AT commands used by this library:

AT command Purpose
AT+CFUN Phone functionality (min / full / reset)
AT+CNMP Preferred network mode (GSM / LTE / Auto)
AT+CMNB Cat-M / NB-IoT selection
AT+CPIN SIM PIN status / unlock
AT+CSQ Signal quality report (RSSI / BER)
AT+CGATT GPRS attachment status
AT+CGDCONT 3GPP PDP context configuration
AT+CGACT 3GPP PDP context activation
AT+CGPADDR Read PDP address
AT+CPSI UE system information (operator, band, RSRP)
AT+CGNAPN Read network-provided APN
AT+CNCFG PDP context configuration
AT+CNACT Application network activation
AT+SHCONF HTTP parameter configuration
AT+SHBOD HTTP request body upload
AT+SHREQ HTTP request
AT+SHREAD HTTP response read
AT+SMCONF MQTT parameter configuration
AT+SMCONN MQTT connect
AT+SMPUB MQTT publish
AT+SMSUB MQTT subscribe
AT+SMDISC MQTT disconnect
AT+CSSLCFG SSL/TLS parameter configuration
AT+SMSSL Bind SSL context to MQTT
AT+CFSINIT Initialize modem file system buffer
AT+CFSWFILE Write file to modem flash
AT+CGNSPWR GNSS power
AT+CGNSINF GNSS fix/status information
AT+CMGF SMS format
AT+CMGS SMS text send
AT+CAOPEN TCP/UDP open
AT+CASEND TCP/UDP send
AT+CBC Battery and charge status
AT+CPOWD Power down modem
AT+CREBOOT Reboot modem
AT+CSCLK Slow clock / sleep configuration
AT+CPSMS 3GPP Power Saving Mode
AT+CEDRXS eDRX configuration

Full AT command reference: SIM7080G AT Command Manual


What Is Not Included

  • Unit tests with a mocked UART transport
  • Production reconnect / exponential-backoff state machine
  • Watchdog / health-monitor integration
  • Complete voice, FTP, CoAP, SIM Toolkit or vendor-special command coverage

License

MIT — see LICENSE.

About

Raspberry Pi Pico SIM7080G LTE/GNSS AT command library

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages