This is an Arduino library for communicating with NB-IoT/CAT-M1 modules that using AT command interface, such as such as SIMCOM SIM70XX series, Quectel BG96, uBlox SARA-R410M.
This library is based on the works of TinyGSM which try to be all-things-AT-commands. What make this library different from the TinyGSM is that this library stripped out the supports of all the legacy GSM modules and unrelated WiFi modules, focus only on NB-IoT/CAT-M1 modules to make the library easier to setup, and add new new features and functionalities related to NB-IoT/CAT-M1 technologies to the library.
If you like SimpleNB - give it a star, or fork it and contribute!
With the exception of SIM7000, SIM7070/7080/7090, SIM7020 and BG96, the rest of supported modules are inherited from TinyGSM without further test.
Some of the modules does not support some of the features due to hardware design (e.g. GNSS receiver), some functionality are available but not implemtented (those marked as TBI
), here is a summary of features and functionalities supported by each modules:
Functionality | BG96 | Sara 4 | uBlox | Sequans | SIM7000 | SIM7020 | SIM70x0 | Xbee |
---|---|---|---|---|---|---|---|---|
TCP | x | x | x | x | x | x | x | x |
SSL | x | x | x | x | x | TBI | x | x |
GNSS | x | x | x | x | x | |||
GSM LBS | x | x | x | |||||
SMS | x | x | x | x | x | x | x | x |
Voice Call | x | x | x | |||||
Network Time | x | x | x | x | x | x | x | |
NTP | x | x | x | x | ||||
Battery Status | x | x | x | x | x | x | x | |
Temperature | x | x | x | x | ||||
GPRS | x | x | x | x | x | x | x | x |
Data connections
SMS
Voice Calls
Location
AT
command.Prior using the library, there is some boiler-plat configuration required. The general flow of your code should be:
#define SIMPLE_NB_MODEM_SIM7080
#include <SimpleNBClient.h>
SimpleNB modem(SerialAT);
SimpleNBClient client(modem);
or
SimpleNBClientSecure client(modem);
(on supported modules)SimpleNBClient clientX(modem, 0);
, SimpleNBClient clientY(modem, 1);
, etc
orSimpleNBClientSecure clientX(modem, 0);
, SimpleNBClientSecure clientY(modem, 1);
, etcmodem.init()
ormodem.restart()
, restart generally takes much longer than init but ensures the module doesn't have lingering connectionsmodem.simUnlock(GSM_PIN)
modem.waitForRegistration(600000L)
modem.getSignalQuality()
modem.gprsConnect(apn, gprsUser, gprsPass)
(or simply modem.gprsConnect(apn)
). The same command is used for both GPRS or EPS connectionmodem.activateDataNetwork()
to establish a data connectionclient.connect(server, port)
SimpleNB behind the scene wrap AT commands and parse the feedback fom the AT Commands to get the important parameters, and provide an easy-to-use API. In most of the case, the syntax of the APIs are resemble of typical Arduino Client interface.
This library is "blocking" in all of its communication. Depending on the function, your code may be blocked for a long time waiting for the module responses. Some functions (e.g. modem.waitForRegistration()
, modem.retart()
or modem.getGPS()
) may block your code for several seconds or even 1 to 2 minute, others may need you to loop through until the return value confirms a value indicating a success (e.g. modem.checkSignalQuality()
).
This libary does not support any sort of "hardware" or pin level controls for the modules. If you need to turn your module on or reset it using some sort of High/Low/High pin sequence, you must write those functions yourself.
For TCP data streams, this library follows the standard Arduino Client API interface. The AllFunctions example provides a glance of almost all the function APIs available in the library.
Most modules require as much as 500mA to properly connect to the network, many of the Arduino boards may not able to power those NB-IoT/CAT-M1 modules. Improving the power supply actually solves stability problems in many cases!
Make sure you connect the Serial connection correctly between the host MCU and the NB-IOT/CAT-M1 module
MCU NB-IOT/CAT-M1
Tx ---> Rx
Rx ---> Tx
Most modules support "auto-bauding" feature where the module will attempt to adjust it's baud rate to match what it is receiving. In most of the cases, if HardwareSerial
is used for interfacing with the module, 115200bps would work perfectly, if SoftwareSerial
is used, it is recommended not use data rate higher than 9600bps. In some cases, if you experiences missing data or receiving gabbage from the modules, there is an auto bauding function SimpleNBAutoBaud(SerialAT, ACK_AUTOBAUD_MIN, ACK_AUTOBAUD_MAX);
which allows you to provide a range of baud rate to test the best suitable baud rate that can be used. While very useful when initially connecting to a module and doing tests, these should NOT be used in any sort of production code. Once you've established communication with the module, set the baud rate with SimpleNBBegin(SerialAT, baudRate)
or calling the modem.setBaud(baudRate)
method and stick with that baud rate.
When using SoftwareSerial
(on Uno, Nano, etc), the speed 115200 may not work.
Try selecting 57600, 38400, or even lower - the one that works best for you.
In some cases 9600 is unstable, but using 38400 helps, etc.
Be sure to set correct TX/RX pins in the sketch. Please note that not every Arduino pin can serve as TX or RX pin.
Read more about SoftSerial options and configuration here and here.
When using HardwareSerial
, you may need to specify additional parameters to the .begin()
call depend on your MCU's Arduino Core implementation. When using SAMD21-based boards, you may need to use a sercom uart port instead of Serial1
. Check your MCU's Arduino implementation documentation.
Sometimes (especially if you played with AT commands), your module configuration may become invalid. This may result in problems such as:
To return module to Factory Defaults, use FactoryReset tool to reset it.
In rare cases (for the legacy network (i.e. 2G/3G)), you may need to set an initial APN to connect to the mobile network.
Try using the gprsConnect(APN)
function to set an initial APN if you are unable to register on the network. You may need set the APN again after registering (In most cases, you should set the APN after registration).
The first connection with a new SIM card, a new module, or at a new location/tower may take a LONG time, especially if the signal quality isn't excellent. If it is your first connection, you may need to adjust your wait times (timeout) timing.
If you are able to open a TCP connection but have the connection close before receiving data, try adding a keep-alive header to your request. Some modules (e.g, the SIM7000 in SSL mode) will immediately throw away any un-read data when the remote server closes the connection - sometimes without even giving a notification that data arrived in the first place.
When using MQTT, to keep a continuous connection you may need set the correct keep-alive interval (PINGREQ/PINGRESP).
Use Diagnostics tool to help diagnose SIM Card and Connection issues.
If the diagnostics fail, uncomment this line (or add this line) to output some debugging comments from the library:
#define SIMPLE_NB_DEBUG Serial
If you are unable to see any obvious errors in the library debugging, use StreamDebugger to copy the entire AT command sequence to the main serial port. In the diagnostics example, simply uncomment the line:
#define DUMP_AT_COMMANDS
or add this snippit to your code:
#ifdef DUMP_AT_COMMANDS
#include <StreamDebugger.h>
StreamDebugger debugger(SerialAT, Serial);
SimpleNB modem(debugger);
#else
SimpleNB modem(SerialAT);
#endif
This library opens a TCP (or SSL) connection to a server. In the OSI model, that's layer 4 (or 5 for SSL). HTTP (GET/POST), MQTT, and most of the other functions you probably want to use are implemented at layer 7. This means that you need to either manually code the top layer or use another library (like HTTPClient or PubSubClient) to do it for you.
Tools like PostMan implemented the HTTP/HTTPS and communicate with servers at layer 7. If you are able to successfully send a request to your server using Postman, it means that your server works correctly, and the problem is with your client implementation.
If you are successfully connecting to a server, but getting responses of "bad request" (or no response), the issue is probably your HTTP formatting (such as missing mandated HTTP header(s), incorrect HTTP protocol (HTTP 1.0 versus HTTP1.1), or incorrect HTTP body). Here are some tips for implementing your own HTTP request manually:
httpbin.org
to test your implementation, as it will echo back what you sent so that you could see what's going onclient.print("...")
, or client.write(buf, #)
, or even client.write(String("..."))
, not client.write("...")
to help prevent text being sent out one character at a time (typewriter style)client.print("....\r\n\r\n")
or put in an extra client.println()
There are two versions of the SIM7000 code, one using SIMPLE_NB_MODEM_SIM7000
and another with SIMPLE_NB_MODEM_SIM7000SSL
. The SIMPLE_NB_MODEM_SIM7000
version does not support SSL but supports up to 8 simultaneous connections. The SIMPLE_NB_MODEM_SIM7000SSL
version supports both SSL and unsecured connections with up to 2 simultaneous connections.
So why are there two versions?
The "SSL" version uses the SIM7000's "application" commands while the other uses the "TCP-IP toolkit". Depending on your region/firmware, one or the other may not work for you. Try both and use whichever is more stable. If you do not need SSL, I recommend starting with SIMPLE_NB_MODEM_SIM7000
.
This project is released under The GNU Lesser General Public License (LGPL-3.0)