Re-aligned with vshymanskyy-master
This commit is contained in:
61
README.md
61
README.md
@@ -14,9 +14,12 @@ If you like **TinyGSM** - give it a star, or fork it and contribute!
|
|||||||
[](https://github.com/vshymanskyy/TinyGSM/stargazers)
|
[](https://github.com/vshymanskyy/TinyGSM/stargazers)
|
||||||
[](https://github.com/vshymanskyy/TinyGSM/network)
|
[](https://github.com/vshymanskyy/TinyGSM/network)
|
||||||
|
|
||||||
|
You can also join our chat:
|
||||||
|
[](https://gitter.im/tinygsm)
|
||||||
|
|
||||||
### Arduino Client interface support
|
### Arduino Client interface support
|
||||||
This library is easy to integrate with lots of sketches, which use Ethernet or WiFi.
|
This library is easy to integrate with lots of sketches, which use Ethernet or WiFi.
|
||||||
Examples for **PubSubClient ([MQTT](http://mqtt.org/))**, **[Blynk](http://blynk.cc)**, **Web Client** and **File Download** are provided.
|
**PubSubClient ([MQTT](http://mqtt.org/))**, **[Blynk](http://blynk.cc)**, **HTTP Client** and **File Download** examples are provided.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -30,7 +33,38 @@ Arduino GSM library uses 15868 bytes (49%) of Flash and 1113 bytes (54%) of RAM
|
|||||||
TinyGSM also pulls data gently from the modem (whenever possible), so it can operate on very little RAM.
|
TinyGSM also pulls data gently from the modem (whenever possible), so it can operate on very little RAM.
|
||||||
**Now, you have more space for your experiments.**
|
**Now, you have more space for your experiments.**
|
||||||
|
|
||||||
### Supported modem models
|
## Features
|
||||||
|
|
||||||
|
Feature \ Modem | SIM800 | SIM8x8 | A6/A7/A20 | M590 | ESP8266
|
||||||
|
--- | --- | --- | --- | --- | ---
|
||||||
|
**Data connections**
|
||||||
|
TCP (HTTP, MQTT, Blynk, ...) | ✔ | ✔ | ✔ | ✔ | ✔
|
||||||
|
UDP | | | | |
|
||||||
|
SSL/TLS (HTTPS) | ✔¹ | ✔¹ | 🅧 | 🅧 | ◌
|
||||||
|
**USSD**
|
||||||
|
Sending USSD requests | ✔ | ✔ | ✔ | ✔ |
|
||||||
|
Decoding 7,8,16-bit response | ✔ | ✔ | ✔ | ✔ |
|
||||||
|
**SMS**
|
||||||
|
Sending | ✔ | ✔ | ✔ | ✔ |
|
||||||
|
Sending Unicode | ✔ | ✔ | ◌ | 🅧 |
|
||||||
|
Reading | | | | |
|
||||||
|
Incoming message event | | | | ? |
|
||||||
|
**Calls**
|
||||||
|
Dial, hangup | ✔ | ✔ | ✔ | 🅧 |
|
||||||
|
Receiving calls | ✔ | ✔ | ✔ | 🅧 |
|
||||||
|
Incoming event (RING) | ◌ | ◌ | ◌ | 🅧 |
|
||||||
|
DTMF sending | ◌ | ◌ | ◌ | 🅧 |
|
||||||
|
DTMF decoding | ◌ | ◌ | 🅧 | 🅧 |
|
||||||
|
**Location**
|
||||||
|
GSM location service | ✔ | ✔ | 🅧 | 🅧 |
|
||||||
|
GPS/GNSS | 🅧 | ✔² | ◌¹ | 🅧 |
|
||||||
|
|
||||||
|
✔ - implemented ◌ - planned 🅧 - not available for this modem
|
||||||
|
¹ - only some device models or firmware revisions have this feature
|
||||||
|
² - current implementation only supports SIM808 V2 GPS
|
||||||
|
|
||||||
|
## Supported modems
|
||||||
|
|
||||||
- [x] SIMCom SIM800 series (SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868)
|
- [x] SIMCom SIM800 series (SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868)
|
||||||
- [x] SIMCom SIM900 series (SIM900A, SIM900D, SIM908, SIM968)
|
- [x] SIMCom SIM900 series (SIM900A, SIM900D, SIM908, SIM968)
|
||||||
- [x] AI-Thinker A6, A6C, A7
|
- [x] AI-Thinker A6, A6C, A7
|
||||||
@@ -53,6 +87,19 @@ More modems may be supported later:
|
|||||||
|
|
||||||
Watch this repo for new updates! And of course, contributions are welcome ;)
|
Watch this repo for new updates! And of course, contributions are welcome ;)
|
||||||
|
|
||||||
|
## Donation
|
||||||
|
|
||||||
|
[](https://salt.bountysource.com/checkout/amount?team=tinygsm-dev)
|
||||||
|
[](http://tny.im/aen)
|
||||||
|
|
||||||
|
If you have found TinyGSM to be useful in your work, research or company, please consider making a donation to the project commensurate with your resources. Any amount helps!
|
||||||
|
**All donations will be used strictly to fund the development of TinyGSM:**
|
||||||
|
- Covering cellular network expences
|
||||||
|
- Buying new hardware and modems for integration
|
||||||
|
- Bounty Budget (to reward other developers for their contributions)
|
||||||
|
- Implementing new features
|
||||||
|
- Quality Assurance
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
|
|
||||||
1. Using your phone:
|
1. Using your phone:
|
||||||
@@ -65,6 +112,16 @@ Watch this repo for new updates! And of course, contributions are welcome ;)
|
|||||||
Send an ```AT``` command using [this sketch](tools/AT_Debug/AT_Debug.ino)
|
Send an ```AT``` command using [this sketch](tools/AT_Debug/AT_Debug.ino)
|
||||||
5. Check if GSM antenna is attached
|
5. Check if GSM antenna is attached
|
||||||
|
|
||||||
|
## How does it work?
|
||||||
|
|
||||||
|
Many GSM modems, WiFi and radio modules can be controlled by sending AT commands over Serial.
|
||||||
|
TinyGSM knows which commands to send, and how to handle AT responses, and wraps that into standard Arduino Client interface.
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
For GPRS data streams, this library provides the standard [Arduino Client](https://www.arduino.cc/en/Reference/ClientConstructor) interface.
|
||||||
|
For additional functions, please refer to [this example sketch](examples/AllFunctions/AllFunctions.ino)
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
### SoftwareSerial problems
|
### SoftwareSerial problems
|
||||||
|
@@ -11,14 +11,32 @@
|
|||||||
|
|
||||||
#if defined(TINY_GSM_MODEM_SIM800) || defined(TINY_GSM_MODEM_SIM900)
|
#if defined(TINY_GSM_MODEM_SIM800) || defined(TINY_GSM_MODEM_SIM900)
|
||||||
#include <TinyGsmClientSIM800.h>
|
#include <TinyGsmClientSIM800.h>
|
||||||
|
typedef TinyGsmSim800 TinyGsm;
|
||||||
|
typedef TinyGsmSim800::GsmClient TinyGsmClient;
|
||||||
|
typedef TinyGsmSim800::GsmClientSecure TinyGsmClientSecure;
|
||||||
|
|
||||||
|
#elif defined(TINY_GSM_MODEM_SIM808) || defined(TINY_GSM_MODEM_SIM868)
|
||||||
|
#include <TinyGsmClientSIM808.h>
|
||||||
|
typedef TinyGsmSim808 TinyGsm;
|
||||||
|
typedef TinyGsmSim808::GsmClient TinyGsmClient;
|
||||||
|
typedef TinyGsmSim808::GsmClientSecure TinyGsmClientSecure;
|
||||||
|
|
||||||
#elif defined(TINY_GSM_MODEM_A6) || defined(TINY_GSM_MODEM_A7)
|
#elif defined(TINY_GSM_MODEM_A6) || defined(TINY_GSM_MODEM_A7)
|
||||||
#include <TinyGsmClientA6.h>
|
#include <TinyGsmClientA6.h>
|
||||||
|
typedef TinyGsm::GsmClient TinyGsmClient;
|
||||||
|
|
||||||
#elif defined(TINY_GSM_MODEM_M590)
|
#elif defined(TINY_GSM_MODEM_M590)
|
||||||
#include <TinyGsmClientM590.h>
|
#include <TinyGsmClientM590.h>
|
||||||
|
typedef TinyGsm::GsmClient TinyGsmClient;
|
||||||
|
|
||||||
#elif defined(TINY_GSM_MODEM_ESP8266)
|
#elif defined(TINY_GSM_MODEM_ESP8266)
|
||||||
#include <TinyGsmClientESP8266.h>
|
#include <TinyGsmClientESP8266.h>
|
||||||
|
typedef TinyGsm::GsmClient TinyGsmClient;
|
||||||
|
|
||||||
#elif defined(TINY_GSM_MODEM_XBEE)
|
#elif defined(TINY_GSM_MODEM_XBEE)
|
||||||
#include <TinyGsmClientXBee.h>
|
#include <TinyGsmClientXBee.h>
|
||||||
|
typedef TinyGsm::GsmClient TinyGsmClient;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#error "Please define GSM modem model"
|
#error "Please define GSM modem model"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
#define TINY_GSM_RX_BUFFER 256
|
#define TINY_GSM_RX_BUFFER 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TINY_GSM_MUX_COUNT 8
|
||||||
|
|
||||||
#include <TinyGsmCommon.h>
|
#include <TinyGsmCommon.h>
|
||||||
|
|
||||||
#define GSM_NL "\r\n"
|
#define GSM_NL "\r\n"
|
||||||
@@ -40,11 +42,6 @@ enum RegStatus {
|
|||||||
class TinyGsm
|
class TinyGsm
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
|
||||||
TinyGsm(Stream& stream)
|
|
||||||
: stream(stream)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class GsmClient : public Client
|
class GsmClient : public Client
|
||||||
@@ -111,7 +108,7 @@ public:
|
|||||||
|
|
||||||
virtual int available() {
|
virtual int available() {
|
||||||
TINY_GSM_YIELD();
|
TINY_GSM_YIELD();
|
||||||
if (!rx.size()) {
|
if (!rx.size() && sock_connected) {
|
||||||
at->maintain();
|
at->maintain();
|
||||||
}
|
}
|
||||||
return rx.size();
|
return rx.size();
|
||||||
@@ -155,6 +152,13 @@ public:
|
|||||||
return sock_connected;
|
return sock_connected;
|
||||||
}
|
}
|
||||||
virtual operator bool() { return connected(); }
|
virtual operator bool() { return connected(); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended API
|
||||||
|
*/
|
||||||
|
|
||||||
|
String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TinyGsm* at;
|
TinyGsm* at;
|
||||||
uint8_t mux;
|
uint8_t mux;
|
||||||
@@ -164,6 +168,12 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
TinyGsm(Stream& stream)
|
||||||
|
: stream(stream)
|
||||||
|
{
|
||||||
|
memset(sockets, 0, sizeof(sockets));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basic functions
|
* Basic functions
|
||||||
*/
|
*/
|
||||||
@@ -211,6 +221,18 @@ public:
|
|||||||
return waitResponse() == 1;
|
return waitResponse() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getModemInfo() {
|
||||||
|
sendAT(GF("I"));
|
||||||
|
String res;
|
||||||
|
if (waitResponse(1000L, res) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
res.replace(GSM_NL "OK" GSM_NL, "");
|
||||||
|
res.replace(GSM_NL, " ");
|
||||||
|
res.trim();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Power functions
|
* Power functions
|
||||||
*/
|
*/
|
||||||
@@ -224,6 +246,11 @@ public:
|
|||||||
return init();
|
return init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool poweroff() {
|
||||||
|
sendAT(GF("+CPOF"));
|
||||||
|
return waitResponse() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SIM card functions
|
* SIM card functions
|
||||||
*/
|
*/
|
||||||
@@ -235,7 +262,7 @@ public:
|
|||||||
|
|
||||||
String getSimCCID() {
|
String getSimCCID() {
|
||||||
sendAT(GF("+CCID"));
|
sendAT(GF("+CCID"));
|
||||||
if (waitResponse(GF(GSM_NL "+ICCID:")) != 1) {
|
if (waitResponse(GF(GSM_NL "+SCID: SIM Card ID:")) != 1) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
String res = streamReadUntil('\n');
|
String res = streamReadUntil('\n');
|
||||||
@@ -303,7 +330,7 @@ public:
|
|||||||
if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
|
if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
|
||||||
return 99;
|
return 99;
|
||||||
}
|
}
|
||||||
int res = streamReadUntil(',').toInt();
|
int res = stream.readStringUntil(',').toInt();
|
||||||
waitResponse();
|
waitResponse();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -336,9 +363,17 @@ public:
|
|||||||
bool gprsConnect(const char* apn, const char* user, const char* pwd) {
|
bool gprsConnect(const char* apn, const char* user, const char* pwd) {
|
||||||
gprsDisconnect();
|
gprsDisconnect();
|
||||||
|
|
||||||
|
sendAT(GF("+CGATT=1"));
|
||||||
|
if (waitResponse(60000L) != 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// TODO: wait AT+CGATT?
|
||||||
|
|
||||||
sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"');
|
sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"');
|
||||||
waitResponse();
|
waitResponse();
|
||||||
|
|
||||||
|
if (!user) user = "";
|
||||||
|
if (!pwd) pwd = "";
|
||||||
sendAT(GF("+CSTT=\""), apn, GF("\",\""), user, GF("\",\""), pwd, GF("\""));
|
sendAT(GF("+CSTT=\""), apn, GF("\",\""), user, GF("\",\""), pwd, GF("\""));
|
||||||
if (waitResponse(60000L) != 1) {
|
if (waitResponse(60000L) != 1) {
|
||||||
return false;
|
return false;
|
||||||
@@ -347,24 +382,11 @@ public:
|
|||||||
sendAT(GF("+CGACT=1,1"));
|
sendAT(GF("+CGACT=1,1"));
|
||||||
waitResponse(60000L);
|
waitResponse(60000L);
|
||||||
|
|
||||||
sendAT(GF("+CGATT=1"));
|
|
||||||
if (waitResponse(60000L) != 1)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// TODO: wait AT+CGATT?
|
|
||||||
|
|
||||||
sendAT(GF("+CIPMUX=1"));
|
sendAT(GF("+CIPMUX=1"));
|
||||||
if (waitResponse() != 1) {
|
if (waitResponse() != 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*sendAT(GF("+CIFSR"));
|
|
||||||
String data;
|
|
||||||
if (waitResponse(10000L, data) != 1) {
|
|
||||||
data.replace(GSM_NL, "");
|
|
||||||
return false;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,22 +395,58 @@ public:
|
|||||||
return waitResponse(60000L) == 1;
|
return waitResponse(60000L) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getLocalIP() {
|
||||||
|
sendAT(GF("+CIFSR"));
|
||||||
|
String res;
|
||||||
|
if (waitResponse(10000L, res) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
res.trim();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress localIP() {
|
||||||
|
IPAddress res;
|
||||||
|
res.fromString(getLocalIP());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Phone Call functions
|
* Phone Call functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
|
|
||||||
bool callAnswer() {
|
bool callAnswer() {
|
||||||
sendAT(GF("A"));
|
sendAT(GF("A"));
|
||||||
return waitResponse() == 1;
|
return waitResponse() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true on pick-up, false on error/busy
|
||||||
bool callNumber(const String& number) {
|
bool callNumber(const String& number) {
|
||||||
sendAT(GF("D"), number);
|
sendAT(GF("D\""), number, "\";");
|
||||||
return waitResponse() == 1;
|
if (waitResponse() != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (waitResponse(60000L, GF(GSM_NL "+CIEV: \"CALL\",1"), GF(GSM_NL "+CIEV: \"CALL\",0")) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rsp = waitResponse(60000L, GF(GSM_NL "+CIEV: \"SOUNDER\",0"), GF(GSM_NL "+CIEV: \"CALL\",0"));
|
||||||
|
|
||||||
|
int rsp2 = waitResponse(300L, GF(GSM_NL "BUSY" GSM_NL), GF(GSM_NL "NO ANSWER" GSM_NL));
|
||||||
|
|
||||||
|
return rsp == 1 && rsp2 == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool callHangup(const String& number) {
|
//bool callRedial() {
|
||||||
sendAT(GF("H"), number);
|
// sendAT(GF("DLST"));
|
||||||
|
// return waitResponse() == 1;
|
||||||
|
//}
|
||||||
|
|
||||||
|
bool callHangup() {
|
||||||
|
sendAT(GF("H"));
|
||||||
return waitResponse() == 1;
|
return waitResponse() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -396,6 +454,32 @@ public:
|
|||||||
* Messaging functions
|
* Messaging functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
String sendUSSD(const String& code) {
|
||||||
|
sendAT(GF("+CMGF=1"));
|
||||||
|
waitResponse();
|
||||||
|
sendAT(GF("+CSCS=\"HEX\""));
|
||||||
|
waitResponse();
|
||||||
|
sendAT(GF("+CUSD=1,\""), code, GF("\",15"));
|
||||||
|
if (waitResponse(10000L) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (waitResponse(GF(GSM_NL "+CUSD:")) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
stream.readStringUntil('"');
|
||||||
|
String hex = stream.readStringUntil('"');
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
int dcs = stream.readStringUntil('\n').toInt();
|
||||||
|
|
||||||
|
if (dcs == 15) {
|
||||||
|
return decodeHex7bit(hex);
|
||||||
|
} else if (dcs == 72) {
|
||||||
|
return decodeHex16bit(hex);
|
||||||
|
} else {
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool sendSMS(const String& number, const String& text) {
|
bool sendSMS(const String& number, const String& text) {
|
||||||
sendAT(GF("+CMGF=1"));
|
sendAT(GF("+CMGF=1"));
|
||||||
waitResponse();
|
waitResponse();
|
||||||
@@ -405,24 +489,41 @@ public:
|
|||||||
}
|
}
|
||||||
stream.print(text);
|
stream.print(text);
|
||||||
stream.write((char)0x1A);
|
stream.write((char)0x1A);
|
||||||
|
stream.flush();
|
||||||
return waitResponse(60000L) == 1;
|
return waitResponse(60000L) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Location functions
|
* Location functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Battery functions
|
* Battery functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
int getBattPercent() {
|
||||||
|
sendAT(GF("+CBC?"));
|
||||||
|
if (waitResponse(GF(GSM_NL "+CBC:")) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
int res = stream.readStringUntil('\n').toInt();
|
||||||
|
waitResponse();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int modemConnect(const char* host, uint16_t port, uint8_t* mux) {
|
|
||||||
|
bool modemConnect(const char* host, uint16_t port, uint8_t* mux) {
|
||||||
sendAT(GF("+CIPSTART="), GF("\"TCP"), GF("\",\""), host, GF("\","), port);
|
sendAT(GF("+CIPSTART="), GF("\"TCP"), GF("\",\""), host, GF("\","), port);
|
||||||
|
|
||||||
if (waitResponse(75000L, GF(GSM_NL "+CIPNUM:")) != 1) {
|
if (waitResponse(75000L, GF(GSM_NL "+CIPNUM:")) != 1) {
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
int newMux = streamReadUntil('\n').toInt();
|
int newMux = streamReadUntil('\n').toInt();
|
||||||
|
|
||||||
@@ -431,7 +532,7 @@ private:
|
|||||||
GF("CONNECT FAIL" GSM_NL),
|
GF("CONNECT FAIL" GSM_NL),
|
||||||
GF("ALREADY CONNECT" GSM_NL));
|
GF("ALREADY CONNECT" GSM_NL));
|
||||||
if (waitResponse() != 1) {
|
if (waitResponse() != 1) {
|
||||||
return -1;
|
return false;
|
||||||
}
|
}
|
||||||
*mux = newMux;
|
*mux = newMux;
|
||||||
|
|
||||||
@@ -440,7 +541,7 @@ private:
|
|||||||
|
|
||||||
int modemSend(const void* buff, size_t len, uint8_t mux) {
|
int modemSend(const void* buff, size_t len, uint8_t mux) {
|
||||||
sendAT(GF("+CIPSEND="), mux, ',', len);
|
sendAT(GF("+CIPSEND="), mux, ',', len);
|
||||||
if (waitResponse(10000L, GF(GSM_NL ">")) != 1) {
|
if (waitResponse(2000L, GF(GSM_NL ">")) != 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
stream.write((uint8_t*)buff, len);
|
stream.write((uint8_t*)buff, len);
|
||||||
@@ -451,14 +552,61 @@ private:
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool modemGetConnected(uint8_t mux) { //TODO mux?
|
bool modemGetConnected(uint8_t mux) {
|
||||||
sendAT(GF("+CIPSTATUS"));
|
sendAT(GF("+CIPSTATUS")); //TODO mux?
|
||||||
int res = waitResponse(GF(",\"CONNECTED\""), GF(",\"CLOSED\""), GF(",\"CLOSING\""), GF(",\"INITIAL\""));
|
int res = waitResponse(GF(",\"CONNECTED\""), GF(",\"CLOSED\""), GF(",\"CLOSING\""), GF(",\"INITIAL\""));
|
||||||
waitResponse();
|
waitResponse();
|
||||||
return 1 == res;
|
return 1 == res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private Utilities */
|
static String decodeHex7bit(String &instr) {
|
||||||
|
String result;
|
||||||
|
byte reminder = 0;
|
||||||
|
int bitstate = 7;
|
||||||
|
for (unsigned i=0; i<instr.length(); i+=2) {
|
||||||
|
char buf[4] = { 0, };
|
||||||
|
buf[0] = instr[i];
|
||||||
|
buf[1] = instr[i+1];
|
||||||
|
byte b = strtol(buf, NULL, 16);
|
||||||
|
|
||||||
|
byte bb = b << (7 - bitstate);
|
||||||
|
char c = (bb + reminder) & 0x7F;
|
||||||
|
result += c;
|
||||||
|
reminder = b >> bitstate;
|
||||||
|
bitstate--;
|
||||||
|
if (bitstate == 0) {
|
||||||
|
char c = reminder;
|
||||||
|
result += c;
|
||||||
|
reminder = 0;
|
||||||
|
bitstate = 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String decodeHex16bit(String &instr) {
|
||||||
|
String result;
|
||||||
|
for (unsigned i=0; i<instr.length(); i+=4) {
|
||||||
|
char buf[4] = { 0, };
|
||||||
|
buf[0] = instr[i];
|
||||||
|
buf[1] = instr[i+1];
|
||||||
|
char b = strtol(buf, NULL, 16);
|
||||||
|
if (b) { // If high byte is non-zero, we can't handle it ;(
|
||||||
|
b = '?';
|
||||||
|
} else {
|
||||||
|
buf[0] = instr[i+2];
|
||||||
|
buf[1] = instr[i+3];
|
||||||
|
b = strtol(buf, NULL, 16);
|
||||||
|
}
|
||||||
|
result += b;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* Utilities */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void streamWrite(T last) {
|
void streamWrite(T last) {
|
||||||
stream.print(last);
|
stream.print(last);
|
||||||
@@ -470,17 +618,6 @@ private:
|
|||||||
streamWrite(tail...);
|
streamWrite(tail...);
|
||||||
}
|
}
|
||||||
|
|
||||||
int streamRead() { return stream.read(); }
|
|
||||||
|
|
||||||
String streamReadUntil(char c) {
|
|
||||||
String return_string = stream.readStringUntil(c);
|
|
||||||
return_string.trim();
|
|
||||||
if (String(c) == GSM_NL || String(c) == "\n"){
|
|
||||||
DBG(return_string, c, " ");
|
|
||||||
} else DBG(return_string, c);
|
|
||||||
return return_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool streamSkipUntil(char c) {
|
bool streamSkipUntil(char c) {
|
||||||
String skipped = stream.readStringUntil(c);
|
String skipped = stream.readStringUntil(c);
|
||||||
skipped.trim();
|
skipped.trim();
|
||||||
@@ -520,7 +657,7 @@ private:
|
|||||||
do {
|
do {
|
||||||
TINY_GSM_YIELD();
|
TINY_GSM_YIELD();
|
||||||
while (stream.available() > 0) {
|
while (stream.available() > 0) {
|
||||||
int a = streamRead();
|
int a = stream.read();
|
||||||
if (a <= 0) continue; // Skip 0x00 bytes, just in case
|
if (a <= 0) continue; // Skip 0x00 bytes, just in case
|
||||||
data += (char)a;
|
data += (char)a;
|
||||||
if (r1 && data.endsWith(r1)) {
|
if (r1 && data.endsWith(r1)) {
|
||||||
@@ -539,24 +676,25 @@ private:
|
|||||||
index = 5;
|
index = 5;
|
||||||
goto finish;
|
goto finish;
|
||||||
} else if (data.endsWith(GF("+CIPRCV:"))) {
|
} else if (data.endsWith(GF("+CIPRCV:"))) {
|
||||||
mux = stream.readStringUntil(',').toInt();
|
int mux = stream.readStringUntil(',').toInt();
|
||||||
data += mux;
|
int len = stream.readStringUntil(',').toInt();
|
||||||
data += (',');
|
if (len > sockets[mux]->rx.free()) {
|
||||||
len = stream.readStringUntil(',').toInt();
|
DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free());
|
||||||
data += len;
|
} else {
|
||||||
data += (',');
|
DBG("### Got: ", len, "->", sockets[mux]->rx.free());
|
||||||
gotData = true;
|
}
|
||||||
index = 6;
|
while (len--) {
|
||||||
goto finish;
|
while (!stream.available()) { TINY_GSM_YIELD(); }
|
||||||
|
sockets[mux]->rx.put(stream.read());
|
||||||
|
}
|
||||||
|
data = "";
|
||||||
} else if (data.endsWith(GF("+TCPCLOSED:"))) {
|
} else if (data.endsWith(GF("+TCPCLOSED:"))) {
|
||||||
mux = stream.readStringUntil(',').toInt();
|
int mux = stream.readStringUntil('\n').toInt();
|
||||||
data += mux;
|
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) {
|
||||||
data += (',');
|
sockets[mux]->sock_connected = false;
|
||||||
String concl = stream.readStringUntil('\n');
|
}
|
||||||
data += concl;
|
data = "";
|
||||||
sockets[mux]->sock_connected = false;
|
DBG("### Closed: ", mux);
|
||||||
index = 7;
|
|
||||||
goto finish;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (millis() - startMillis < timeout);
|
} while (millis() - startMillis < timeout);
|
||||||
@@ -611,9 +749,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Stream& stream;
|
Stream& stream;
|
||||||
GsmClient* sockets[8];
|
GsmClient* sockets[TINY_GSM_MUX_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TinyGsm::GsmClient TinyGsmClient;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* @file TinyWiFiClientESP8266.h
|
* @file TinyGsmClientESP8266.h
|
||||||
* @author Volodymyr Shymanskyy
|
* @author Volodymyr Shymanskyy
|
||||||
* @license LGPL-3.0
|
* @license LGPL-3.0
|
||||||
* @copyright Copyright (c) 2016 Volodymyr Shymanskyy
|
* @copyright Copyright (c) 2016 Volodymyr Shymanskyy
|
||||||
* @date Nov 2016
|
* @date Nov 2016
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TinyWiFiClientESP8266_h
|
#ifndef TinyGsmClientESP8266_h
|
||||||
#define TinyWiFiClientESP8266_h
|
#define TinyGsmClientESP8266_h
|
||||||
|
|
||||||
//#define TINY_GSM_DEBUG Serial
|
//#define TINY_GSM_DEBUG Serial
|
||||||
|
|
||||||
@@ -15,21 +15,18 @@
|
|||||||
#define TINY_GSM_RX_BUFFER 256
|
#define TINY_GSM_RX_BUFFER 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TINY_GSM_MUX_COUNT 5
|
||||||
|
|
||||||
#include <TinyGsmCommon.h>
|
#include <TinyGsmCommon.h>
|
||||||
|
|
||||||
#define GSM_NL "\r\n"
|
#define GSM_NL "\r\n"
|
||||||
static const char GSM_OK[] TINY_GSM_PROGMEM = "OK" GSM_NL;
|
static const char GSM_OK[] TINY_GSM_PROGMEM = "OK" GSM_NL;
|
||||||
static const char GSM_ERROR[] TINY_GSM_PROGMEM = "ERROR" GSM_NL;
|
static const char GSM_ERROR[] TINY_GSM_PROGMEM = "ERROR" GSM_NL;
|
||||||
static unsigned int TCP_KEEP_ALIVE = 120;
|
static unsigned TINY_GSM_TCP_KEEP_ALIVE = 120;
|
||||||
|
|
||||||
class TinyGsm
|
class TinyGsm
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
|
||||||
TinyGsm(Stream& stream)
|
|
||||||
: stream(stream)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class GsmClient : public Client
|
class GsmClient : public Client
|
||||||
@@ -94,7 +91,7 @@ public:
|
|||||||
|
|
||||||
virtual int available() {
|
virtual int available() {
|
||||||
TINY_GSM_YIELD();
|
TINY_GSM_YIELD();
|
||||||
if (!rx.size()) {
|
if (!rx.size() && sock_connected) {
|
||||||
at->maintain();
|
at->maintain();
|
||||||
}
|
}
|
||||||
return rx.size();
|
return rx.size();
|
||||||
@@ -138,6 +135,13 @@ public:
|
|||||||
return sock_connected;
|
return sock_connected;
|
||||||
}
|
}
|
||||||
virtual operator bool() { return connected(); }
|
virtual operator bool() { return connected(); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended API
|
||||||
|
*/
|
||||||
|
|
||||||
|
String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TinyGsm* at;
|
TinyGsm* at;
|
||||||
uint8_t mux;
|
uint8_t mux;
|
||||||
@@ -147,6 +151,12 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
TinyGsm(Stream& stream)
|
||||||
|
: stream(stream)
|
||||||
|
{
|
||||||
|
memset(sockets, 0, sizeof(sockets));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basic functions
|
* Basic functions
|
||||||
*/
|
*/
|
||||||
@@ -273,20 +283,21 @@ public:
|
|||||||
return waitResponse(10000L) == 1;
|
return waitResponse(10000L) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getLocalIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
|
IPAddress localIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GPRS functions
|
* GPRS functions
|
||||||
*/
|
*/
|
||||||
bool gprsConnect(const char* apn, const char* user, const char* pwd) {
|
bool gprsConnect(const char* apn, const char* user, const char* pwd) TINY_GSM_ATTR_NOT_IMPLEMENTED;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gprsDisconnect() {
|
bool gprsDisconnect() TINY_GSM_ATTR_NOT_IMPLEMENTED;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int modemConnect(const char* host, uint16_t port, uint8_t mux) {
|
int modemConnect(const char* host, uint16_t port, uint8_t mux) {
|
||||||
sendAT(GF("+CIPSTART="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port, GF(","), TCP_KEEP_ALIVE);
|
sendAT(GF("+CIPSTART="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port, GF(","), TINY_GSM_TCP_KEEP_ALIVE);
|
||||||
int rsp = waitResponse(75000L,
|
int rsp = waitResponse(75000L,
|
||||||
GFP(GSM_OK),
|
GFP(GSM_OK),
|
||||||
GFP(GSM_ERROR),
|
GFP(GSM_ERROR),
|
||||||
@@ -301,6 +312,7 @@ private:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
stream.write((uint8_t*)buff, len);
|
stream.write((uint8_t*)buff, len);
|
||||||
|
stream.flush();
|
||||||
if (waitResponse(GF(GSM_NL "SEND OK" GSM_NL)) != 1) {
|
if (waitResponse(GF(GSM_NL "SEND OK" GSM_NL)) != 1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -314,7 +326,10 @@ private:
|
|||||||
return 1 == res;
|
return 1 == res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private Utilities */
|
public:
|
||||||
|
|
||||||
|
/* Utilities */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void streamWrite(T last) {
|
void streamWrite(T last) {
|
||||||
stream.print(last);
|
stream.print(last);
|
||||||
@@ -326,7 +341,14 @@ private:
|
|||||||
streamWrite(tail...);
|
streamWrite(tail...);
|
||||||
}
|
}
|
||||||
|
|
||||||
int streamRead() { return stream.read(); }
|
bool streamSkipUntil(char c) { //TODO: timeout
|
||||||
|
while (true) {
|
||||||
|
while (!stream.available()) { TINY_GSM_YIELD(); }
|
||||||
|
if (stream.read() == c)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
String streamReadUntil(char c) {
|
String streamReadUntil(char c) {
|
||||||
String return_string = stream.readStringUntil(c);
|
String return_string = stream.readStringUntil(c);
|
||||||
@@ -376,7 +398,7 @@ private:
|
|||||||
do {
|
do {
|
||||||
TINY_GSM_YIELD();
|
TINY_GSM_YIELD();
|
||||||
while (stream.available() > 0) {
|
while (stream.available() > 0) {
|
||||||
int a = streamRead();
|
int a = stream.read();
|
||||||
if (a <= 0) continue; // Skip 0x00 bytes, just in case
|
if (a <= 0) continue; // Skip 0x00 bytes, just in case
|
||||||
data += (char)a;
|
data += (char)a;
|
||||||
if (r1 && data.endsWith(r1)) {
|
if (r1 && data.endsWith(r1)) {
|
||||||
@@ -395,16 +417,20 @@ private:
|
|||||||
index = 5;
|
index = 5;
|
||||||
goto finish;
|
goto finish;
|
||||||
} else if (data.endsWith(GF(GSM_NL "+IPD,"))) {
|
} else if (data.endsWith(GF(GSM_NL "+IPD,"))) {
|
||||||
mux = stream.readStringUntil(',').toInt();
|
int mux = stream.readStringUntil(',').toInt();
|
||||||
data += mux;
|
int len = stream.readStringUntil(':').toInt();
|
||||||
data += (',');
|
if (len > sockets[mux]->rx.free()) {
|
||||||
len = stream.readStringUntil(':').toInt();
|
DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free());
|
||||||
data += len;
|
} else {
|
||||||
data += (':');
|
DBG("### Got: ", len, "->", sockets[mux]->rx.free());
|
||||||
gotData = true;
|
}
|
||||||
index = 6;
|
while (len--) {
|
||||||
goto finish;
|
while (!stream.available()) { TINY_GSM_YIELD(); }
|
||||||
} else if (data.endsWith(GF("1,CLOSED" GSM_NL))) { //TODO: use mux
|
sockets[mux]->rx.put(stream.read());
|
||||||
|
}
|
||||||
|
data = "";
|
||||||
|
return index;
|
||||||
|
} else if (data.endsWith(GF(GSM_NL "1,CLOSED" GSM_NL))) { //TODO: use mux
|
||||||
sockets[1]->sock_connected = false;
|
sockets[1]->sock_connected = false;
|
||||||
index = 7;
|
index = 7;
|
||||||
goto finish;
|
goto finish;
|
||||||
@@ -462,9 +488,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Stream& stream;
|
Stream& stream;
|
||||||
GsmClient* sockets[5];
|
GsmClient* sockets[TINY_GSM_MUX_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TinyGsm::GsmClient TinyGsmClient;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -15,6 +15,8 @@
|
|||||||
#define TINY_GSM_RX_BUFFER 256
|
#define TINY_GSM_RX_BUFFER 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TINY_GSM_MUX_COUNT 2
|
||||||
|
|
||||||
#include <TinyGsmCommon.h>
|
#include <TinyGsmCommon.h>
|
||||||
|
|
||||||
#define GSM_NL "\r\n"
|
#define GSM_NL "\r\n"
|
||||||
@@ -40,11 +42,6 @@ enum RegStatus {
|
|||||||
class TinyGsm
|
class TinyGsm
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
|
||||||
TinyGsm(Stream& stream)
|
|
||||||
: stream(stream)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class GsmClient : public Client
|
class GsmClient : public Client
|
||||||
@@ -108,7 +105,7 @@ public:
|
|||||||
|
|
||||||
virtual int available() {
|
virtual int available() {
|
||||||
TINY_GSM_YIELD();
|
TINY_GSM_YIELD();
|
||||||
if (!rx.size()) {
|
if (!rx.size() && sock_connected) {
|
||||||
at->maintain();
|
at->maintain();
|
||||||
}
|
}
|
||||||
return rx.size();
|
return rx.size();
|
||||||
@@ -152,6 +149,13 @@ public:
|
|||||||
return sock_connected;
|
return sock_connected;
|
||||||
}
|
}
|
||||||
virtual operator bool() { return connected(); }
|
virtual operator bool() { return connected(); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended API
|
||||||
|
*/
|
||||||
|
|
||||||
|
String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TinyGsm* at;
|
TinyGsm* at;
|
||||||
uint8_t mux;
|
uint8_t mux;
|
||||||
@@ -161,6 +165,12 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
TinyGsm(Stream& stream)
|
||||||
|
: stream(stream)
|
||||||
|
{
|
||||||
|
memset(sockets, 0, sizeof(sockets));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basic functions
|
* Basic functions
|
||||||
*/
|
*/
|
||||||
@@ -216,6 +226,18 @@ public:
|
|||||||
return waitResponse() == 1;
|
return waitResponse() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getModemInfo() {
|
||||||
|
sendAT(GF("I"));
|
||||||
|
String res;
|
||||||
|
if (waitResponse(1000L, res) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
res.replace(GSM_NL "OK" GSM_NL, "");
|
||||||
|
res.replace(GSM_NL, " ");
|
||||||
|
res.trim();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Power functions
|
* Power functions
|
||||||
*/
|
*/
|
||||||
@@ -233,6 +255,11 @@ public:
|
|||||||
return init();
|
return init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool poweroff() {
|
||||||
|
sendAT(GF("+CPWROFF"));
|
||||||
|
return waitResponse(3000L) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SIM card functions
|
* SIM card functions
|
||||||
*/
|
*/
|
||||||
@@ -303,16 +330,16 @@ public:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic network functions
|
* Generic network functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int getSignalQuality() {
|
int getSignalQuality() {
|
||||||
sendAT(GF("+CSQ"));
|
sendAT(GF("+CSQ"));
|
||||||
if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
|
if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
|
||||||
return 99;
|
return 99;
|
||||||
}
|
}
|
||||||
int res = streamReadUntil(',').toInt();
|
int res = stream.readStringUntil(',').toInt();
|
||||||
waitResponse();
|
waitResponse();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -364,13 +391,15 @@ public:
|
|||||||
sendAT(GF("+XIIC?"));
|
sendAT(GF("+XIIC?"));
|
||||||
waitResponse();
|
waitResponse();
|
||||||
|
|
||||||
/*sendAT(GF("+DNSSERVER=1,8.8.8.8"));
|
/*
|
||||||
|
sendAT(GF("+DNSSERVER=1,8.8.8.8"));
|
||||||
waitResponse();
|
waitResponse();
|
||||||
|
|
||||||
sendAT(GF("+DNSSERVER=2,8.8.4.4"));
|
sendAT(GF("+DNSSERVER=2,8.8.4.4"));
|
||||||
if (waitResponse() != 1) {
|
if (waitResponse() != 1) {
|
||||||
return false;
|
return false;
|
||||||
}*/
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -380,30 +409,72 @@ public:
|
|||||||
return waitResponse(60000L) == 1;
|
return waitResponse(60000L) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getLocalIP() {
|
||||||
|
sendAT(GF("+XIIC?"));
|
||||||
|
if (waitResponse(GF(GSM_NL "+XIIC:")) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
String res = stream.readStringUntil('\n');
|
||||||
|
waitResponse();
|
||||||
|
res.trim();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress localIP() {
|
||||||
|
IPAddress res;
|
||||||
|
res.fromString(getLocalIP());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Phone Call functions
|
* Phone Call functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool callAnswer() {
|
bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
sendAT(GF("A"));
|
|
||||||
return waitResponse() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool callNumber(const String& number) {
|
bool callAnswer() TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
sendAT(GF("D"), number);
|
|
||||||
return waitResponse() == 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool callHangup(const String& number) {
|
bool callNumber(const String& number) TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
sendAT(GF("H"), number);
|
|
||||||
return waitResponse() == 1;
|
bool callRedial() TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
}
|
|
||||||
|
bool callHangup() TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Messaging functions
|
* Messaging functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
String sendUSSD(const String& code) {
|
||||||
|
sendAT(GF("+CMGF=1"));
|
||||||
|
waitResponse();
|
||||||
|
sendAT(GF("+CSCS=\"HEX\""));
|
||||||
|
waitResponse();
|
||||||
|
sendAT(GF("D"), code);
|
||||||
|
if (waitResponse(10000L, GF(GSM_NL "+CUSD:")) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
stream.readStringUntil('"');
|
||||||
|
String hex = stream.readStringUntil('"');
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
int dcs = stream.readStringUntil('\n').toInt();
|
||||||
|
|
||||||
|
if (waitResponse() != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dcs == 15) {
|
||||||
|
return decodeHex8bit(hex);
|
||||||
|
} else if (dcs == 72) {
|
||||||
|
return decodeHex16bit(hex);
|
||||||
|
} else {
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool sendSMS(const String& number, const String& text) {
|
bool sendSMS(const String& number, const String& text) {
|
||||||
|
sendAT(GF("+CSCS=\"GSM\""));
|
||||||
|
waitResponse();
|
||||||
sendAT(GF("+CMGF=1"));
|
sendAT(GF("+CMGF=1"));
|
||||||
waitResponse();
|
waitResponse();
|
||||||
sendAT(GF("+CMGS=\""), number, GF("\""));
|
sendAT(GF("+CMGS=\""), number, GF("\""));
|
||||||
@@ -412,31 +483,31 @@ public:
|
|||||||
}
|
}
|
||||||
stream.print(text);
|
stream.print(text);
|
||||||
stream.write((char)0x1A);
|
stream.write((char)0x1A);
|
||||||
|
stream.flush();
|
||||||
return waitResponse(60000L) == 1;
|
return waitResponse(60000L) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool sendSMS_UTF16(const String& number, const void* text, size_t len)
|
||||||
|
TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Location functions
|
* Location functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Battery functions
|
* Battery functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private:
|
uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
String dnsIpQuery(const char* host) {
|
|
||||||
sendAT(GF("+DNS=\""), host, GF("\""));
|
|
||||||
if (waitResponse(10000L, GF(GSM_NL "+DNS:")) != 1) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
String res = streamReadUntil('\n');
|
|
||||||
waitResponse(GF("+DNS:OK" GSM_NL));
|
|
||||||
res.trim();
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
int modemConnect(const char* host, uint16_t port, uint8_t mux) {
|
int getBattPercent() TINY_GSM_ATTR_NOT_AVAILABLE;
|
||||||
for (int i=0; i<3; i++) {
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool modemConnect(const char* host, uint16_t port, uint8_t mux) {
|
||||||
|
for (int i=0; i<3; i++) { // TODO: no need for loop?
|
||||||
String ip = dnsIpQuery(host);
|
String ip = dnsIpQuery(host);
|
||||||
|
|
||||||
sendAT(GF("+TCPSETUP="), mux, GF(","), ip, GF(","), port);
|
sendAT(GF("+TCPSETUP="), mux, GF(","), ip, GF(","), port);
|
||||||
@@ -462,7 +533,7 @@ private:
|
|||||||
}
|
}
|
||||||
stream.write((uint8_t*)buff, len);
|
stream.write((uint8_t*)buff, len);
|
||||||
stream.write((char)0x0D);
|
stream.write((char)0x0D);
|
||||||
|
stream.flush();
|
||||||
if (waitResponse(30000L, GF(GSM_NL "+TCPSEND:")) != 1) {
|
if (waitResponse(30000L, GF(GSM_NL "+TCPSEND:")) != 1) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -477,7 +548,52 @@ private:
|
|||||||
return 1 == res;
|
return 1 == res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private Utilities */
|
String dnsIpQuery(const char* host) {
|
||||||
|
sendAT(GF("+DNS=\""), host, GF("\""));
|
||||||
|
if (waitResponse(10000L, GF(GSM_NL "+DNS:")) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String res = stream.readStringUntil('\n');
|
||||||
|
waitResponse(GF("+DNS:OK" GSM_NL));
|
||||||
|
res.trim();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String decodeHex8bit(String &instr) {
|
||||||
|
String result;
|
||||||
|
for (unsigned i=0; i<instr.length(); i+=2) {
|
||||||
|
char buf[4] = { 0, };
|
||||||
|
buf[0] = instr[i];
|
||||||
|
buf[1] = instr[i+1];
|
||||||
|
char b = strtol(buf, NULL, 16);
|
||||||
|
result += b;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String decodeHex16bit(String &instr) {
|
||||||
|
String result;
|
||||||
|
for (unsigned i=0; i<instr.length(); i+=4) {
|
||||||
|
char buf[4] = { 0, };
|
||||||
|
buf[0] = instr[i];
|
||||||
|
buf[1] = instr[i+1];
|
||||||
|
char b = strtol(buf, NULL, 16);
|
||||||
|
if (b) { // If high byte is non-zero, we can't handle it ;(
|
||||||
|
b = '?';
|
||||||
|
} else {
|
||||||
|
buf[0] = instr[i+2];
|
||||||
|
buf[1] = instr[i+3];
|
||||||
|
b = strtol(buf, NULL, 16);
|
||||||
|
}
|
||||||
|
result += b;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* Utilities */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void streamWrite(T last) {
|
void streamWrite(T last) {
|
||||||
stream.print(last);
|
stream.print(last);
|
||||||
@@ -489,26 +605,13 @@ private:
|
|||||||
streamWrite(tail...);
|
streamWrite(tail...);
|
||||||
}
|
}
|
||||||
|
|
||||||
int streamRead() { return stream.read(); }
|
bool streamSkipUntil(char c) { //TODO: timeout
|
||||||
|
while (true) {
|
||||||
String streamReadUntil(char c) {
|
while (!stream.available()) { TINY_GSM_YIELD(); }
|
||||||
String return_string = stream.readStringUntil(c);
|
if (stream.read() == c)
|
||||||
return_string.trim();
|
return true;
|
||||||
if (String(c) == GSM_NL || String(c) == "\n"){
|
}
|
||||||
DBG(return_string, c, " ");
|
return false;
|
||||||
} else DBG(return_string, c);
|
|
||||||
return return_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool streamSkipUntil(char c) {
|
|
||||||
String skipped = stream.readStringUntil(c);
|
|
||||||
skipped.trim();
|
|
||||||
if (skipped.length()) {
|
|
||||||
if (String(c) == GSM_NL || String(c) == "\n"){
|
|
||||||
DBG(skipped, c, " ");
|
|
||||||
} else DBG(skipped, c);
|
|
||||||
return true;
|
|
||||||
} else return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
@@ -539,7 +642,7 @@ private:
|
|||||||
do {
|
do {
|
||||||
TINY_GSM_YIELD();
|
TINY_GSM_YIELD();
|
||||||
while (stream.available() > 0) {
|
while (stream.available() > 0) {
|
||||||
int a = streamRead();
|
int a = stream.read();
|
||||||
if (a <= 0) continue; // Skip 0x00 bytes, just in case
|
if (a <= 0) continue; // Skip 0x00 bytes, just in case
|
||||||
data += (char)a;
|
data += (char)a;
|
||||||
if (r1 && data.endsWith(r1)) {
|
if (r1 && data.endsWith(r1)) {
|
||||||
@@ -558,24 +661,26 @@ private:
|
|||||||
index = 5;
|
index = 5;
|
||||||
goto finish;
|
goto finish;
|
||||||
} else if (data.endsWith(GF("+TCPRECV:"))) {
|
} else if (data.endsWith(GF("+TCPRECV:"))) {
|
||||||
mux = stream.readStringUntil(',').toInt();
|
int mux = stream.readStringUntil(',').toInt();
|
||||||
data += mux;
|
int len = stream.readStringUntil(',').toInt();
|
||||||
data += (',');
|
if (len > sockets[mux]->rx.free()) {
|
||||||
len = stream.readStringUntil(',').toInt();
|
DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free());
|
||||||
data += len;
|
} else {
|
||||||
data += (',');
|
DBG("### Got: ", len, "->", sockets[mux]->rx.free());
|
||||||
gotData = true;
|
}
|
||||||
index = 6;
|
while (len--) {
|
||||||
goto finish;
|
while (!stream.available()) { TINY_GSM_YIELD(); }
|
||||||
|
sockets[mux]->rx.put(stream.read());
|
||||||
|
}
|
||||||
|
data = "";
|
||||||
} else if (data.endsWith(GF("+TCPCLOSE:"))) {
|
} else if (data.endsWith(GF("+TCPCLOSE:"))) {
|
||||||
mux = stream.readStringUntil(',').toInt();
|
int mux = stream.readStringUntil(',').toInt();
|
||||||
data += mux;
|
stream.readStringUntil('\n');
|
||||||
data += (',');
|
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) {
|
||||||
String concl = stream.readStringUntil('\n');
|
sockets[mux]->sock_connected = false;
|
||||||
data += concl;
|
}
|
||||||
sockets[mux]->sock_connected = false;
|
data = "";
|
||||||
index = 7;
|
DBG("### Closed: ", mux);
|
||||||
goto finish;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (millis() - startMillis < timeout);
|
} while (millis() - startMillis < timeout);
|
||||||
@@ -630,9 +735,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Stream& stream;
|
Stream& stream;
|
||||||
GsmClient* sockets[2];
|
GsmClient* sockets[TINY_GSM_MUX_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TinyGsm::GsmClient TinyGsmClient;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
#define TINY_GSM_RX_BUFFER 64
|
#define TINY_GSM_RX_BUFFER 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TINY_GSM_MUX_COUNT 5
|
||||||
|
|
||||||
#include <TinyGsmCommon.h>
|
#include <TinyGsmCommon.h>
|
||||||
|
|
||||||
#define GSM_NL "\r\n"
|
#define GSM_NL "\r\n"
|
||||||
@@ -38,33 +40,30 @@ enum RegStatus {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class TinyGsm
|
class TinyGsmSim800
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
|
||||||
TinyGsm(Stream& stream)
|
|
||||||
: stream(stream)
|
|
||||||
{}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
class GsmClient : public Client
|
class GsmClient : public Client
|
||||||
{
|
{
|
||||||
friend class TinyGsm;
|
friend class TinyGsmSim800;
|
||||||
typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
|
typedef TinyGsmFifo<uint8_t, TINY_GSM_RX_BUFFER> RxFifo;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GsmClient() {}
|
GsmClient() {}
|
||||||
|
|
||||||
GsmClient(TinyGsm& modem, uint8_t mux = 1) {
|
GsmClient(TinyGsmSim800& modem, uint8_t mux = 1) {
|
||||||
init(&modem, mux);
|
init(&modem, mux);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool init(TinyGsm* modem, uint8_t mux = 1) {
|
bool init(TinyGsmSim800* modem, uint8_t mux = 1) {
|
||||||
this->at = modem;
|
this->at = modem;
|
||||||
this->mux = mux;
|
this->mux = mux;
|
||||||
sock_available = 0;
|
sock_available = 0;
|
||||||
|
prev_check = 0;
|
||||||
sock_connected = false;
|
sock_connected = false;
|
||||||
|
got_data = false;
|
||||||
|
|
||||||
at->sockets[mux] = this;
|
at->sockets[mux] = this;
|
||||||
|
|
||||||
@@ -110,7 +109,14 @@ public:
|
|||||||
|
|
||||||
virtual int available() {
|
virtual int available() {
|
||||||
TINY_GSM_YIELD();
|
TINY_GSM_YIELD();
|
||||||
if (!rx.size()) {
|
if (!rx.size() && sock_connected) {
|
||||||
|
// Workaround: sometimes SIM800 forgets to notify about data arrival.
|
||||||
|
// TODO: Currently we ping the module periodically,
|
||||||
|
// but maybe there's a better indicator that we need to poll
|
||||||
|
if (millis() - prev_check > 500) {
|
||||||
|
got_data = true;
|
||||||
|
prev_check = millis();
|
||||||
|
}
|
||||||
at->maintain();
|
at->maintain();
|
||||||
}
|
}
|
||||||
return rx.size() + sock_available;
|
return rx.size() + sock_available;
|
||||||
@@ -157,15 +163,48 @@ public:
|
|||||||
return sock_connected;
|
return sock_connected;
|
||||||
}
|
}
|
||||||
virtual operator bool() { return connected(); }
|
virtual operator bool() { return connected(); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extended API
|
||||||
|
*/
|
||||||
|
|
||||||
|
String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TinyGsm* at;
|
TinyGsmSim800* at;
|
||||||
uint8_t mux;
|
uint8_t mux;
|
||||||
uint16_t sock_available;
|
uint16_t sock_available;
|
||||||
|
uint32_t prev_check;
|
||||||
bool sock_connected;
|
bool sock_connected;
|
||||||
|
bool got_data;
|
||||||
RxFifo rx;
|
RxFifo rx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GsmClientSecure : public GsmClient
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
GsmClientSecure() {}
|
||||||
|
|
||||||
|
GsmClientSecure(TinyGsmSim800& modem, uint8_t mux = 1)
|
||||||
|
: GsmClient(modem, mux)
|
||||||
|
{}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual int connect(const char *host, uint16_t port) {
|
||||||
|
TINY_GSM_YIELD();
|
||||||
|
rx.clear();
|
||||||
|
sock_connected = at->modemConnect(host, port, mux, true);
|
||||||
|
return sock_connected;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TinyGsmSim800(Stream& stream)
|
||||||
|
: stream(stream)
|
||||||
|
{
|
||||||
|
memset(sockets, 0, sizeof(sockets));
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Basic functions
|
* Basic functions
|
||||||
@@ -178,7 +217,9 @@ public:
|
|||||||
if (!autoBaud()) {
|
if (!autoBaud()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
sendAT(GF("&FZE0")); // Factory + Reset + Echo Off
|
sendAT(GF("&FZ")); // Factory + Reset
|
||||||
|
waitResponse();
|
||||||
|
sendAT(GF("E0")); // Echo Off
|
||||||
if (waitResponse() != 1) {
|
if (waitResponse() != 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -187,7 +228,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool autoBaud(unsigned long timeout = 10000L) {
|
bool autoBaud(unsigned long timeout = 10000L) {
|
||||||
streamWrite(GF("AAAAAAAAAAAAA")); // extra A's to help detect the baud rate
|
//streamWrite(GF("AAAAA" GSM_NL)); // TODO: extra A's to help detect the baud rate
|
||||||
for (unsigned long start = millis(); millis() - start < timeout; ) {
|
for (unsigned long start = millis(); millis() - start < timeout; ) {
|
||||||
sendAT(GF(""));
|
sendAT(GF(""));
|
||||||
if (waitResponse(200) == 1) {
|
if (waitResponse(200) == 1) {
|
||||||
@@ -200,6 +241,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void maintain() {
|
void maintain() {
|
||||||
|
for (int mux = 0; mux < TINY_GSM_MUX_COUNT; mux++) {
|
||||||
|
GsmClient* sock = sockets[mux];
|
||||||
|
if (sock && sock->got_data) {
|
||||||
|
sock->got_data = false;
|
||||||
|
sock->sock_available = modemGetAvailable(mux);
|
||||||
|
}
|
||||||
|
}
|
||||||
while (stream.available()) {
|
while (stream.available()) {
|
||||||
waitResponse(10, NULL, NULL);
|
waitResponse(10, NULL, NULL);
|
||||||
}
|
}
|
||||||
@@ -220,6 +268,26 @@ public:
|
|||||||
return waitResponse() == 1;
|
return waitResponse() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getModemInfo() {
|
||||||
|
sendAT(GF("I"));
|
||||||
|
String res;
|
||||||
|
if (waitResponse(1000L, res) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
res.replace(GSM_NL "OK" GSM_NL, "");
|
||||||
|
res.replace(GSM_NL, " ");
|
||||||
|
res.trim();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool hasSSL() {
|
||||||
|
sendAT(GF("+CIPSSL=?"));
|
||||||
|
if (waitResponse(GF(GSM_NL "+CIPSSL:")) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return waitResponse() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Power functions
|
* Power functions
|
||||||
*/
|
*/
|
||||||
@@ -240,6 +308,23 @@ public:
|
|||||||
return init();
|
return init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool poweroff() {
|
||||||
|
sendAT(GF("+CPOWD=1"));
|
||||||
|
return waitResponse(GF("NORMAL POWER DOWN")) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool radioOff() {
|
||||||
|
if (!autoBaud()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sendAT(GF("+CFUN=0"));
|
||||||
|
if (waitResponse(10000L) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
delay(3000);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SIM card functions
|
* SIM card functions
|
||||||
*/
|
*/
|
||||||
@@ -310,16 +395,16 @@ public:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Generic network functions
|
* Generic network functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int getSignalQuality() {
|
int getSignalQuality() {
|
||||||
sendAT(GF("+CSQ"));
|
sendAT(GF("+CSQ"));
|
||||||
if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
|
if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) {
|
||||||
return 99;
|
return 99;
|
||||||
}
|
}
|
||||||
int res = streamReadUntil(',').toInt();
|
int res = stream.readStringUntil(',').toInt();
|
||||||
waitResponse();
|
waitResponse();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -413,9 +498,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
sendAT(GF("+CIFSR;E0"));
|
sendAT(GF("+CIFSR;E0"));
|
||||||
String data;
|
if (waitResponse(10000L) != 1) {
|
||||||
if (waitResponse(10000L, data) != 1) {
|
|
||||||
data.replace(GSM_NL, "");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,6 +515,22 @@ public:
|
|||||||
return waitResponse(60000L) == 1;
|
return waitResponse(60000L) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String getLocalIP() {
|
||||||
|
sendAT(GF("+CIFSR;E0"));
|
||||||
|
String res;
|
||||||
|
if (waitResponse(10000L, res) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
res.trim();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
IPAddress localIP() {
|
||||||
|
IPAddress res;
|
||||||
|
res.fromString(getLocalIP());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Phone Call functions
|
* Phone Call functions
|
||||||
*/
|
*/
|
||||||
@@ -446,13 +545,25 @@ public:
|
|||||||
return waitResponse() == 1;
|
return waitResponse() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true on pick-up, false on error/busy
|
||||||
bool callNumber(const String& number) {
|
bool callNumber(const String& number) {
|
||||||
sendAT(GF("D"), number);
|
sendAT(GF("D"), number, ";");
|
||||||
return waitResponse() == 1;
|
int status = waitResponse(60000L, GF("OK"), GF("BUSY"), GF("NO ANSWER"), GF("NO CARRIER"));
|
||||||
|
switch (status) {
|
||||||
|
case 1: return true;
|
||||||
|
case 2:
|
||||||
|
case 3: return false;
|
||||||
|
default: return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool callHangup(const String& number) {
|
//bool callRedial() {
|
||||||
sendAT(GF("H"), number);
|
// sendAT(GF("DL"));
|
||||||
|
// return waitResponse() == 1;
|
||||||
|
//}
|
||||||
|
|
||||||
|
bool callHangup() {
|
||||||
|
sendAT(GF("H"));
|
||||||
return waitResponse() == 1;
|
return waitResponse() == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -460,6 +571,32 @@ public:
|
|||||||
* Messaging functions
|
* Messaging functions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
String sendUSSD(const String& code) {
|
||||||
|
sendAT(GF("+CMGF=1"));
|
||||||
|
waitResponse();
|
||||||
|
sendAT(GF("+CSCS=\"HEX\""));
|
||||||
|
waitResponse();
|
||||||
|
sendAT(GF("+CUSD=1,\""), code, GF("\""));
|
||||||
|
if (waitResponse() != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
if (waitResponse(10000L, GF(GSM_NL "+CUSD:")) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
stream.readStringUntil('"');
|
||||||
|
String hex = stream.readStringUntil('"');
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
int dcs = stream.readStringUntil('\n').toInt();
|
||||||
|
|
||||||
|
if (dcs == 15) {
|
||||||
|
return decodeHex8bit(hex);
|
||||||
|
} else if (dcs == 72) {
|
||||||
|
return decodeHex16bit(hex);
|
||||||
|
} else {
|
||||||
|
return hex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool sendSMS(const String& number, const String& text) {
|
bool sendSMS(const String& number, const String& text) {
|
||||||
sendAT(GF("+CMGF=1"));
|
sendAT(GF("+CMGF=1"));
|
||||||
waitResponse();
|
waitResponse();
|
||||||
@@ -469,6 +606,7 @@ public:
|
|||||||
}
|
}
|
||||||
stream.print(text);
|
stream.print(text);
|
||||||
stream.write((char)0x1A);
|
stream.write((char)0x1A);
|
||||||
|
stream.flush();
|
||||||
return waitResponse(60000L) == 1;
|
return waitResponse(60000L) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,6 +633,7 @@ public:
|
|||||||
stream.print(c, HEX);
|
stream.print(c, HEX);
|
||||||
}
|
}
|
||||||
stream.write((char)0x1A);
|
stream.write((char)0x1A);
|
||||||
|
stream.flush();
|
||||||
return waitResponse(60000L) == 1;
|
return waitResponse(60000L) == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,11 +644,12 @@ public:
|
|||||||
|
|
||||||
String getGsmLocation() {
|
String getGsmLocation() {
|
||||||
sendAT(GF("+CIPGSMLOC=1,1"));
|
sendAT(GF("+CIPGSMLOC=1,1"));
|
||||||
if (waitResponse(GF(GSM_NL "+CIPGSMLOC:")) != 1) {
|
if (waitResponse(10000L, GF(GSM_NL "+CIPGSMLOC:")) != 1) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
String res = streamReadUntil('\n');
|
String res = stream.readStringUntil('\n');
|
||||||
waitResponse();
|
waitResponse();
|
||||||
|
res.trim();
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,13 +670,30 @@ public:
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
int getBattPercent() {
|
||||||
int modemConnect(const char* host, uint16_t port, uint8_t mux) {
|
sendAT(GF("+CBC"));
|
||||||
|
if (waitResponse(GF(GSM_NL "+CBC:")) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
int res = stream.readStringUntil(',').toInt();
|
||||||
|
waitResponse();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool modemConnect(const char* host, uint16_t port, uint8_t mux, bool ssl = false) {
|
||||||
|
sendAT(GF("+CIPSSL="), ssl);
|
||||||
|
int rsp = waitResponse();
|
||||||
|
if (ssl && rsp != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
sendAT(GF("+CIPSTART="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port);
|
sendAT(GF("+CIPSTART="), mux, ',', GF("\"TCP"), GF("\",\""), host, GF("\","), port);
|
||||||
int rsp = waitResponse(75000L,
|
rsp = waitResponse(75000L,
|
||||||
GF("CONNECT OK" GSM_NL),
|
GF("CONNECT OK" GSM_NL),
|
||||||
GF("CONNECT FAIL" GSM_NL),
|
GF("CONNECT FAIL" GSM_NL),
|
||||||
GF("ALREADY CONNECT" GSM_NL));
|
GF("ALREADY CONNECT" GSM_NL));
|
||||||
return (1 == rsp);
|
return (1 == rsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -573,16 +730,15 @@ private:
|
|||||||
|
|
||||||
for (size_t i=0; i<len; i++) {
|
for (size_t i=0; i<len; i++) {
|
||||||
#ifdef TINY_GSM_USE_HEX
|
#ifdef TINY_GSM_USE_HEX
|
||||||
while (stream.available() < 2) {}
|
while (stream.available() < 2) { TINY_GSM_YIELD(); }
|
||||||
char buf[4] = { 0, };
|
char buf[4] = { 0, };
|
||||||
buf[0] = streamRead();
|
buf[0] = streamRead();
|
||||||
buf[1] = streamRead();
|
buf[1] = streamRead();
|
||||||
char c = strtol(buf, NULL, 16);
|
char c = strtol(buf, NULL, 16);
|
||||||
DBG(c);
|
DBG(c);
|
||||||
#else
|
#else
|
||||||
while (!stream.available()) {}
|
while (!stream.available()) { TINY_GSM_YIELD(); }
|
||||||
char c = streamRead();
|
char c = stream.read();
|
||||||
DBG(c);
|
|
||||||
#endif
|
#endif
|
||||||
sockets[mux]->rx.put(c);
|
sockets[mux]->rx.put(c);
|
||||||
}
|
}
|
||||||
@@ -612,7 +768,41 @@ private:
|
|||||||
return 1 == res;
|
return 1 == res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private Utilities */
|
static String decodeHex8bit(String &instr) {
|
||||||
|
String result;
|
||||||
|
for (unsigned i=0; i<instr.length(); i+=2) {
|
||||||
|
char buf[4] = { 0, };
|
||||||
|
buf[0] = instr[i];
|
||||||
|
buf[1] = instr[i+1];
|
||||||
|
char b = strtol(buf, NULL, 16);
|
||||||
|
result += b;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static String decodeHex16bit(String &instr) {
|
||||||
|
String result;
|
||||||
|
for (unsigned i=0; i<instr.length(); i+=4) {
|
||||||
|
char buf[4] = { 0, };
|
||||||
|
buf[0] = instr[i];
|
||||||
|
buf[1] = instr[i+1];
|
||||||
|
char b = strtol(buf, NULL, 16);
|
||||||
|
if (b) { // If high byte is non-zero, we can't handle it ;(
|
||||||
|
b = '?';
|
||||||
|
} else {
|
||||||
|
buf[0] = instr[i+2];
|
||||||
|
buf[1] = instr[i+3];
|
||||||
|
b = strtol(buf, NULL, 16);
|
||||||
|
}
|
||||||
|
result += b;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/* Utilities */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void streamWrite(T last) {
|
void streamWrite(T last) {
|
||||||
stream.print(last);
|
stream.print(last);
|
||||||
@@ -624,26 +814,13 @@ private:
|
|||||||
streamWrite(tail...);
|
streamWrite(tail...);
|
||||||
}
|
}
|
||||||
|
|
||||||
int streamRead() { return stream.read(); }
|
bool streamSkipUntil(char c) { //TODO: timeout
|
||||||
|
while (true) {
|
||||||
String streamReadUntil(char c) {
|
while (!stream.available()) { TINY_GSM_YIELD(); }
|
||||||
String return_string = stream.readStringUntil(c);
|
if (stream.read() == c)
|
||||||
return_string.trim();
|
return true;
|
||||||
if (String(c) == GSM_NL || String(c) == "\n"){
|
}
|
||||||
DBG(return_string, c, " ");
|
return false;
|
||||||
} else DBG(return_string, c);
|
|
||||||
return return_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool streamSkipUntil(char c) {
|
|
||||||
String skipped = stream.readStringUntil(c);
|
|
||||||
skipped.trim();
|
|
||||||
if (skipped.length()) {
|
|
||||||
if (String(c) == GSM_NL || String(c) == "\n"){
|
|
||||||
DBG(skipped, c, " ");
|
|
||||||
} else DBG(skipped, c);
|
|
||||||
return true;
|
|
||||||
} else return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
@@ -666,14 +843,12 @@ private:
|
|||||||
String r5s(r5); r5s.trim();
|
String r5s(r5); r5s.trim();
|
||||||
DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s);*/
|
DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s);*/
|
||||||
data.reserve(64);
|
data.reserve(64);
|
||||||
bool gotData = false;
|
|
||||||
int mux = -1;
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
unsigned long startMillis = millis();
|
unsigned long startMillis = millis();
|
||||||
do {
|
do {
|
||||||
TINY_GSM_YIELD();
|
TINY_GSM_YIELD();
|
||||||
while (stream.available() > 0) {
|
while (stream.available() > 0) {
|
||||||
int a = streamRead();
|
int a = stream.read();
|
||||||
if (a <= 0) continue; // Skip 0x00 bytes, just in case
|
if (a <= 0) continue; // Skip 0x00 bytes, just in case
|
||||||
data += (char)a;
|
data += (char)a;
|
||||||
if (r1 && data.endsWith(r1)) {
|
if (r1 && data.endsWith(r1)) {
|
||||||
@@ -695,8 +870,11 @@ private:
|
|||||||
index = 6;
|
index = 6;
|
||||||
String mode = streamReadUntil(',');
|
String mode = streamReadUntil(',');
|
||||||
if (mode.toInt() == 1) {
|
if (mode.toInt() == 1) {
|
||||||
mux = streamReadUntil('\n').toInt();
|
int mux = stream.readStringUntil('\n').toInt();
|
||||||
gotData = true;
|
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) {
|
||||||
|
sockets[mux]->got_data = true;
|
||||||
|
}
|
||||||
|
data = "";
|
||||||
} else {
|
} else {
|
||||||
data += mode;
|
data += mode;
|
||||||
}
|
}
|
||||||
@@ -704,10 +882,12 @@ private:
|
|||||||
index = 7;
|
index = 7;
|
||||||
int nl = data.lastIndexOf(GSM_NL, data.length()-8);
|
int nl = data.lastIndexOf(GSM_NL, data.length()-8);
|
||||||
int coma = data.indexOf(',', nl+2);
|
int coma = data.indexOf(',', nl+2);
|
||||||
mux = data.substring(nl+2, coma).toInt();
|
int mux = data.substring(nl+2, coma).toInt();
|
||||||
if (mux) {
|
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) {
|
||||||
sockets[mux]->sock_connected = false;
|
sockets[mux]->sock_connected = false;
|
||||||
}
|
}
|
||||||
|
data = "";
|
||||||
|
DBG("### Closed: ", mux);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (millis() - startMillis < timeout);
|
} while (millis() - startMillis < timeout);
|
||||||
@@ -718,17 +898,6 @@ private:
|
|||||||
DBG(GSM_NL, "### Unhandled:", data);
|
DBG(GSM_NL, "### Unhandled:", data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
data.trim();
|
|
||||||
data.replace(GSM_NL GSM_NL, GSM_NL);
|
|
||||||
data.replace(GSM_NL, GSM_NL " ");
|
|
||||||
if (data.length()) {
|
|
||||||
DBG(GSM_NL, "<<< ", data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (gotData) {
|
|
||||||
sockets[mux]->sock_available = modemGetAvailable(mux);
|
|
||||||
}
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -746,11 +915,9 @@ private:
|
|||||||
return waitResponse(1000, r1, r2, r3, r4, r5);
|
return waitResponse(1000, r1, r2, r3, r4, r5);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
Stream& stream;
|
Stream& stream;
|
||||||
GsmClient* sockets[5];
|
GsmClient* sockets[TINY_GSM_MUX_COUNT];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef TinyGsm::GsmClient TinyGsmClient;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
148
TinyGsmClientSIM808.h
Normal file
148
TinyGsmClientSIM808.h
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/**
|
||||||
|
* @file TinyGsmClientSIM808.h
|
||||||
|
* @author Volodymyr Shymanskyy
|
||||||
|
* @license LGPL-3.0
|
||||||
|
* @copyright Copyright (c) 2016 Volodymyr Shymanskyy
|
||||||
|
* @date Nov 2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TinyGsmClientSIM808_h
|
||||||
|
#define TinyGsmClientSIM808_h
|
||||||
|
|
||||||
|
#include <TinyGsmClientSIM800.h>
|
||||||
|
|
||||||
|
class TinyGsmSim808: public TinyGsmSim800
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
TinyGsmSim808(Stream& stream)
|
||||||
|
: TinyGsmSim800(stream)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPS location functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
// enable GPS
|
||||||
|
bool enableGPS() {
|
||||||
|
uint16_t state;
|
||||||
|
|
||||||
|
sendAT(GF("+CGNSPWR=1"));
|
||||||
|
if (waitResponse() != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool disableGPS() {
|
||||||
|
uint16_t state;
|
||||||
|
|
||||||
|
sendAT(GF("+CGNSPWR=0"));
|
||||||
|
if (waitResponse() != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the RAW GPS output
|
||||||
|
// works only with ans SIM808 V2
|
||||||
|
String getGPSraw() {
|
||||||
|
sendAT(GF("+CGNSINF"));
|
||||||
|
if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
String res = stream.readStringUntil('\n');
|
||||||
|
waitResponse();
|
||||||
|
res.trim();
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get GPS informations
|
||||||
|
// works only with ans SIM808 V2
|
||||||
|
bool getGPS(float *lat, float *lon, float *speed=0, int *alt=0, int *vsat=0, int *usat=0) {
|
||||||
|
//String buffer = "";
|
||||||
|
char chr_buffer[12];
|
||||||
|
bool fix = false;
|
||||||
|
|
||||||
|
sendAT(GF("+CGNSINF"));
|
||||||
|
if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
stream.readStringUntil(','); // mode
|
||||||
|
if ( stream.readStringUntil(',').toInt() == 1 ) fix = true;
|
||||||
|
stream.readStringUntil(','); //utctime
|
||||||
|
*lat = stream.readStringUntil(',').toFloat(); //lat
|
||||||
|
*lon = stream.readStringUntil(',').toFloat(); //lon
|
||||||
|
if (alt != NULL) *alt = stream.readStringUntil(',').toFloat(); //lon
|
||||||
|
if (speed != NULL) *speed = stream.readStringUntil(',').toFloat(); //speed
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
stream.readStringUntil(',');
|
||||||
|
if (vsat != NULL) *vsat = stream.readStringUntil(',').toInt(); //viewed satelites
|
||||||
|
if (usat != NULL) *usat = stream.readStringUntil(',').toInt(); //used satelites
|
||||||
|
stream.readStringUntil('\n');
|
||||||
|
|
||||||
|
waitResponse();
|
||||||
|
|
||||||
|
return fix;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get GPS time
|
||||||
|
// works only with SIM808 V2
|
||||||
|
bool getGPSTime(int *year, int *month, int *day, int *hour, int *minute, int *second) {
|
||||||
|
bool fix = false;
|
||||||
|
char chr_buffer[12];
|
||||||
|
sendAT(GF("+CGNSINF"));
|
||||||
|
if (waitResponse(GF(GSM_NL "+CGNSINF:")) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
String buffer = stream.readStringUntil(',');
|
||||||
|
buffer.toCharArray(chr_buffer, sizeof(chr_buffer));
|
||||||
|
switch (i) {
|
||||||
|
case 0:
|
||||||
|
//mode
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
//fixstatus
|
||||||
|
if ( buffer.toInt() == 1 ) {
|
||||||
|
fix = buffer.toInt();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*year = buffer.substring(0,4).toInt();
|
||||||
|
*month = buffer.substring(4,6).toInt();
|
||||||
|
*day = buffer.substring(6,8).toInt();
|
||||||
|
*hour = buffer.substring(8,10).toInt();
|
||||||
|
*minute = buffer.substring(10,12).toInt();
|
||||||
|
*second = buffer.substring(12,14).toInt();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// if nothing else matches, do the default
|
||||||
|
// default is optional
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String res = stream.readStringUntil('\n');
|
||||||
|
waitResponse();
|
||||||
|
|
||||||
|
if (fix) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@@ -26,6 +26,9 @@
|
|||||||
#define TINY_GSM_YIELD() { delay(0); }
|
#define TINY_GSM_YIELD() { delay(0); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TINY_GSM_ATTR_NOT_AVAILABLE __attribute__((error("Not available on this modem type")))
|
||||||
|
#define TINY_GSM_ATTR_NOT_IMPLEMENTED __attribute__((error("Not implemented")))
|
||||||
|
|
||||||
#if defined(__AVR__)
|
#if defined(__AVR__)
|
||||||
#define TINY_GSM_PROGMEM PROGMEM
|
#define TINY_GSM_PROGMEM PROGMEM
|
||||||
typedef const __FlashStringHelper* GsmConstStr;
|
typedef const __FlashStringHelper* GsmConstStr;
|
||||||
@@ -69,4 +72,26 @@ const T& TinyGsmMax(const T& a, const T& b)
|
|||||||
return (b < a) ? a : b;
|
return (b < a) ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
uint32_t TinyGsmAutoBaud(T& SerialAT)
|
||||||
|
{
|
||||||
|
static uint32_t rates[] = { 115200, 57600, 38400, 19200, 9600, 74400, 74880, 230400, 460800, 2400, 4800, 14400, 28800 };
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < sizeof(rates)/sizeof(rates[0]); i++) {
|
||||||
|
uint32_t rate = rates[i];
|
||||||
|
DBG("Trying baud rate", rate, "...");
|
||||||
|
SerialAT.begin(rate);
|
||||||
|
delay(10);
|
||||||
|
for (int i=0; i<3; i++) {
|
||||||
|
SerialAT.print("AT\r\n");
|
||||||
|
String input = SerialAT.readString();
|
||||||
|
if (input.indexOf("OK") >= 0) {
|
||||||
|
DBG("Modem responded at rate", rate);
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
172
examples/AllFunctions/AllFunctions.ino
Normal file
172
examples/AllFunctions/AllFunctions.ino
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
/**************************************************************
|
||||||
|
*
|
||||||
|
* TinyGSM Getting Started guide:
|
||||||
|
* http://tiny.cc/tiny-gsm-readme
|
||||||
|
*
|
||||||
|
* NOTE:
|
||||||
|
* Some of the functions may be unavailable for your modem.
|
||||||
|
* Just comment them out.
|
||||||
|
*
|
||||||
|
**************************************************************/
|
||||||
|
|
||||||
|
// Select your modem:
|
||||||
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
// #define TINY_GSM_MODEM_SIM808
|
||||||
|
// #define TINY_GSM_MODEM_SIM900
|
||||||
|
// #define TINY_GSM_MODEM_A6
|
||||||
|
// #define TINY_GSM_MODEM_A7
|
||||||
|
// #define TINY_GSM_MODEM_M590
|
||||||
|
|
||||||
|
// Set serial for debug console (to the Serial Monitor, speed 115200)
|
||||||
|
#define SerialMon Serial
|
||||||
|
|
||||||
|
// Set serial for AT commands (to the module)
|
||||||
|
// Use Hardware Serial on Mega, Leonardo, Micro
|
||||||
|
#define SerialAT Serial1
|
||||||
|
|
||||||
|
// or Software Serial on Uno, Nano
|
||||||
|
//#include <SoftwareSerial.h>
|
||||||
|
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
||||||
|
|
||||||
|
|
||||||
|
//#define DUMP_AT_COMMANDS
|
||||||
|
#define TINY_GSM_DEBUG SerialMon
|
||||||
|
|
||||||
|
// Set phone numbers, if you want to test SMS and Calls
|
||||||
|
//#define SMS_TARGET "+380xxxxxxxxx"
|
||||||
|
//#define CALL_TARGET "+380xxxxxxxxx"
|
||||||
|
|
||||||
|
// Your GPRS credentials
|
||||||
|
// Leave empty, if missing user or pass
|
||||||
|
const char apn[] = "YourAPN";
|
||||||
|
const char user[] = "";
|
||||||
|
const char pass[] = "";
|
||||||
|
|
||||||
|
#include <TinyGsmClient.h>
|
||||||
|
|
||||||
|
#ifdef DUMP_AT_COMMANDS
|
||||||
|
#include <StreamDebugger.h>
|
||||||
|
StreamDebugger debugger(SerialAT, SerialMon);
|
||||||
|
TinyGsm modem(debugger);
|
||||||
|
#else
|
||||||
|
TinyGsm modem(SerialAT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// Set console baud rate
|
||||||
|
SerialMon.begin(115200);
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
// Set GSM module baud rate
|
||||||
|
TinyGsmAutoBaud(SerialAT);
|
||||||
|
delay(3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
// Restart takes quite some time
|
||||||
|
// To skip it, call init() instead of restart()
|
||||||
|
DBG("Initializing modem...");
|
||||||
|
if (!modem.restart()) {
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String modemInfo = modem.getModemInfo();
|
||||||
|
DBG("Modem:", modemInfo);
|
||||||
|
|
||||||
|
// Unlock your SIM card with a PIN
|
||||||
|
//modem.simUnlock("1234");
|
||||||
|
|
||||||
|
DBG("Waiting for network...");
|
||||||
|
if (!modem.waitForNetwork()) {
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG("Connecting to", apn);
|
||||||
|
if (!modem.gprsConnect(apn, user, pass)) {
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool res;
|
||||||
|
|
||||||
|
String ccid = modem.getSimCCID();
|
||||||
|
DBG("CCID:", ccid);
|
||||||
|
|
||||||
|
String imei = modem.getIMEI();
|
||||||
|
DBG("IMEI:", imei);
|
||||||
|
|
||||||
|
String cop = modem.getOperator();
|
||||||
|
DBG("Operator:", cop);
|
||||||
|
|
||||||
|
IPAddress local = modem.localIP();
|
||||||
|
DBG("Local IP:", local);
|
||||||
|
|
||||||
|
int csq = modem.getSignalQuality();
|
||||||
|
DBG("Signal quality:", csq);
|
||||||
|
|
||||||
|
// This is NOT supported on M590
|
||||||
|
int battLevel = modem.getBattPercent();
|
||||||
|
DBG("Battery lavel:", battLevel);
|
||||||
|
|
||||||
|
// This is only supported on SIMxxx series
|
||||||
|
float battVoltage = modem.getBattVoltage() / 1000.0F;
|
||||||
|
DBG("Battery voltage:", battVoltage);
|
||||||
|
|
||||||
|
// This is only supported on SIMxxx series
|
||||||
|
String gsmLoc = modem.getGsmLocation();
|
||||||
|
DBG("GSM location:", gsmLoc);
|
||||||
|
|
||||||
|
String ussd_balance = modem.sendUSSD("*111#");
|
||||||
|
DBG("Balance (USSD):", ussd_balance);
|
||||||
|
|
||||||
|
String ussd_phone_num = modem.sendUSSD("*161#");
|
||||||
|
DBG("Phone number (USSD):", ussd_phone_num);
|
||||||
|
|
||||||
|
#if defined(TINY_GSM_MODEM_SIM808)
|
||||||
|
modem.enableGPS();
|
||||||
|
String gps_raw = modem.getGPSraw();
|
||||||
|
modem.disableGPS();
|
||||||
|
DBG("GPS raw data:", gps_raw);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(SMS_TARGET)
|
||||||
|
res = modem.sendSMS(SMS_TARGET, String("Hello from ") + imei);
|
||||||
|
DBG("SMS:", res ? "OK" : "fail");
|
||||||
|
|
||||||
|
// This is only supported on SIMxxx series
|
||||||
|
res = modem.sendSMS_UTF16(SMS_TARGET, u"Привіііт!", 9);
|
||||||
|
DBG("UTF16 SMS:", res ? "OK" : "fail");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CALL_TARGET)
|
||||||
|
DBG("Calling:", CALL_TARGET);
|
||||||
|
|
||||||
|
// This is NOT supported on M590
|
||||||
|
res = modem.callNumber(CALL_TARGET);
|
||||||
|
DBG("Call:", res ? "OK" : "fail");
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
delay(5000L);
|
||||||
|
|
||||||
|
res = modem.callHangup();
|
||||||
|
DBG("Hang up:", res ? "OK" : "fail");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
modem.gprsDisconnect();
|
||||||
|
DBG("GPRS disconnected");
|
||||||
|
|
||||||
|
// Try to power-off (modem may decide to restart automatically)
|
||||||
|
// To turn off modem completely, please use Reset/Enable pins
|
||||||
|
modem.poweroff();
|
||||||
|
DBG("Poweroff.");
|
||||||
|
|
||||||
|
// Do nothing forevermore
|
||||||
|
while (true) {
|
||||||
|
modem.maintain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
// Select your modem:
|
// Select your modem:
|
||||||
#define TINY_GSM_MODEM_SIM800
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
// #define TINY_GSM_MODEM_SIM808
|
||||||
// #define TINY_GSM_MODEM_SIM900
|
// #define TINY_GSM_MODEM_SIM900
|
||||||
// #define TINY_GSM_MODEM_A6
|
// #define TINY_GSM_MODEM_A6
|
||||||
// #define TINY_GSM_MODEM_A7
|
// #define TINY_GSM_MODEM_A7
|
||||||
@@ -74,6 +75,10 @@ void setup()
|
|||||||
Serial.println("Initializing modem...");
|
Serial.println("Initializing modem...");
|
||||||
modem.restart();
|
modem.restart();
|
||||||
|
|
||||||
|
String modemInfo = modem.getModemInfo();
|
||||||
|
Serial.print("Modem: ");
|
||||||
|
Serial.println(modemInfo);
|
||||||
|
|
||||||
// Unlock your SIM card with a PIN
|
// Unlock your SIM card with a PIN
|
||||||
//modem.simUnlock("1234");
|
//modem.simUnlock("1234");
|
||||||
|
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
/**************************************************************
|
/**************************************************************
|
||||||
*
|
*
|
||||||
* For this example, you need to install CRC32 library:
|
* For this example, you need to install CRC32 library:
|
||||||
* https://github.com/vshymanskyy/CRC32.git
|
* https://github.com/bakercp/CRC32
|
||||||
* or from http://librarymanager/all#CRC32+checksum
|
* or from http://librarymanager/all#CRC32+checksum
|
||||||
*
|
*
|
||||||
* TinyGSM Getting Started guide:
|
* TinyGSM Getting Started guide:
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
// Select your modem:
|
// Select your modem:
|
||||||
#define TINY_GSM_MODEM_SIM800
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
// #define TINY_GSM_MODEM_SIM808
|
||||||
// #define TINY_GSM_MODEM_SIM900
|
// #define TINY_GSM_MODEM_SIM900
|
||||||
// #define TINY_GSM_MODEM_A6
|
// #define TINY_GSM_MODEM_A6
|
||||||
// #define TINY_GSM_MODEM_A7
|
// #define TINY_GSM_MODEM_A7
|
||||||
@@ -24,8 +25,8 @@
|
|||||||
// Increase RX buffer
|
// Increase RX buffer
|
||||||
#define TINY_GSM_RX_BUFFER 1030
|
#define TINY_GSM_RX_BUFFER 1030
|
||||||
|
|
||||||
#include <TinyGsmClient.h>
|
//#define DUMP_AT_COMMANDS
|
||||||
#include <CRC32.h>
|
//#define TINY_GSM_DEBUG Serial
|
||||||
|
|
||||||
// Your GPRS credentials
|
// Your GPRS credentials
|
||||||
// Leave empty, if missing user or pass
|
// Leave empty, if missing user or pass
|
||||||
@@ -40,12 +41,23 @@ const char pass[] = "";
|
|||||||
//#include <SoftwareSerial.h>
|
//#include <SoftwareSerial.h>
|
||||||
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
||||||
|
|
||||||
TinyGsm modem(SerialAT);
|
#include <TinyGsmClient.h>
|
||||||
|
#include <CRC32.h>
|
||||||
|
|
||||||
|
#ifdef DUMP_AT_COMMANDS
|
||||||
|
#include <StreamDebugger.h>
|
||||||
|
StreamDebugger debugger(SerialAT, Serial);
|
||||||
|
TinyGsm modem(debugger);
|
||||||
|
#else
|
||||||
|
TinyGsm modem(SerialAT);
|
||||||
|
#endif
|
||||||
TinyGsmClient client(modem);
|
TinyGsmClient client(modem);
|
||||||
|
|
||||||
const char server[] = "cdn.rawgit.com";
|
const char server[] = "cdn.rawgit.com";
|
||||||
const char resource[] = "/vshymanskyy/tinygsm/master/extras/test_1k.bin";
|
const int port = 80;
|
||||||
uint32_t knownCRC32 = 0x6f50d767;
|
|
||||||
|
const char resource[] = "/vshymanskyy/tinygsm/master/extras/test_1k.bin";
|
||||||
|
uint32_t knownCRC32 = 0x6f50d767;
|
||||||
uint32_t knownFileSize = 1024; // In case server does not send it
|
uint32_t knownFileSize = 1024; // In case server does not send it
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
@@ -62,6 +74,10 @@ void setup() {
|
|||||||
Serial.println("Initializing modem...");
|
Serial.println("Initializing modem...");
|
||||||
modem.restart();
|
modem.restart();
|
||||||
|
|
||||||
|
String modemInfo = modem.getModemInfo();
|
||||||
|
Serial.print("Modem: ");
|
||||||
|
Serial.println(modemInfo);
|
||||||
|
|
||||||
// Unlock your SIM card with a PIN
|
// Unlock your SIM card with a PIN
|
||||||
//modem.simUnlock("1234");
|
//modem.simUnlock("1234");
|
||||||
}
|
}
|
||||||
@@ -99,7 +115,7 @@ void loop() {
|
|||||||
Serial.print(server);
|
Serial.print(server);
|
||||||
|
|
||||||
// if you get a connection, report back via serial:
|
// if you get a connection, report back via serial:
|
||||||
if (!client.connect(server, 80)) {
|
if (!client.connect(server, port)) {
|
||||||
Serial.println(" fail");
|
Serial.println(" fail");
|
||||||
delay(10000);
|
delay(10000);
|
||||||
return;
|
return;
|
||||||
|
152
examples/HttpClient/HttpClient.ino
Normal file
152
examples/HttpClient/HttpClient.ino
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
/**************************************************************
|
||||||
|
*
|
||||||
|
* This sketch connects to a website and downloads a page.
|
||||||
|
* It can be used to perform HTTP/RESTful API calls.
|
||||||
|
*
|
||||||
|
* For this example, you need to install ArduinoHttpClient library:
|
||||||
|
* https://github.com/arduino-libraries/ArduinoHttpClient
|
||||||
|
* or from http://librarymanager/all#ArduinoHttpClient
|
||||||
|
*
|
||||||
|
* TinyGSM Getting Started guide:
|
||||||
|
* http://tiny.cc/tiny-gsm-readme
|
||||||
|
*
|
||||||
|
**************************************************************/
|
||||||
|
|
||||||
|
// Select your modem:
|
||||||
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
// #define TINY_GSM_MODEM_SIM808
|
||||||
|
// #define TINY_GSM_MODEM_SIM900
|
||||||
|
// #define TINY_GSM_MODEM_A6
|
||||||
|
// #define TINY_GSM_MODEM_A7
|
||||||
|
// #define TINY_GSM_MODEM_M590
|
||||||
|
// #define TINY_GSM_MODEM_ESP8266
|
||||||
|
|
||||||
|
// Increase RX buffer
|
||||||
|
#define TINY_GSM_RX_BUFFER 512
|
||||||
|
|
||||||
|
// Use Hardware Serial on Mega, Leonardo, Micro
|
||||||
|
#define SerialAT Serial1
|
||||||
|
|
||||||
|
// or Software Serial on Uno, Nano
|
||||||
|
//#include <SoftwareSerial.h>
|
||||||
|
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
||||||
|
|
||||||
|
//#define DUMP_AT_COMMANDS
|
||||||
|
//#define TINY_GSM_DEBUG Serial
|
||||||
|
|
||||||
|
|
||||||
|
// Your GPRS credentials
|
||||||
|
// Leave empty, if missing user or pass
|
||||||
|
const char apn[] = "YourAPN";
|
||||||
|
const char user[] = "";
|
||||||
|
const char pass[] = "";
|
||||||
|
|
||||||
|
// Name of the server we want to connect to
|
||||||
|
const char server[] = "cdn.rawgit.com";
|
||||||
|
const int port = 443;
|
||||||
|
// Path to download (this is the bit after the hostname in the URL)
|
||||||
|
const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
|
||||||
|
|
||||||
|
#include <TinyGsmClient.h>
|
||||||
|
#include <ArduinoHttpClient.h>
|
||||||
|
|
||||||
|
#ifdef DUMP_AT_COMMANDS
|
||||||
|
#include <StreamDebugger.h>
|
||||||
|
StreamDebugger debugger(SerialAT, Serial);
|
||||||
|
TinyGsm modem(debugger);
|
||||||
|
#else
|
||||||
|
TinyGsm modem(SerialAT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TinyGsmClient client(modem);
|
||||||
|
HttpClient http(client, server, port);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// Set console baud rate
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
// Set GSM module baud rate
|
||||||
|
SerialAT.begin(115200);
|
||||||
|
delay(3000);
|
||||||
|
|
||||||
|
// Restart takes quite some time
|
||||||
|
// To skip it, call init() instead of restart()
|
||||||
|
Serial.println("Initializing modem...");
|
||||||
|
modem.restart();
|
||||||
|
|
||||||
|
String modemInfo = modem.getModemInfo();
|
||||||
|
Serial.print("Modem: ");
|
||||||
|
Serial.println(modemInfo);
|
||||||
|
|
||||||
|
// Unlock your SIM card with a PIN
|
||||||
|
//modem.simUnlock("1234");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
Serial.print(F("Waiting for network..."));
|
||||||
|
if (!modem.waitForNetwork()) {
|
||||||
|
Serial.println(" fail");
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.println(" OK");
|
||||||
|
|
||||||
|
Serial.print(F("Connecting to "));
|
||||||
|
Serial.print(apn);
|
||||||
|
if (!modem.gprsConnect(apn, user, pass)) {
|
||||||
|
Serial.println(" fail");
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.println(" OK");
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Performing HTTP GET request... "));
|
||||||
|
int err = http.get(resource);
|
||||||
|
if (err != 0) {
|
||||||
|
Serial.println("failed to connect");
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int status = http.responseStatusCode();
|
||||||
|
Serial.println(status);
|
||||||
|
if (!status) {
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (http.headerAvailable()) {
|
||||||
|
String headerName = http.readHeaderName();
|
||||||
|
String headerValue = http.readHeaderValue();
|
||||||
|
//Serial.println(headerName + " : " + headerValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = http.contentLength();
|
||||||
|
if (length >= 0) {
|
||||||
|
Serial.println(String("Content length is: ") + length);
|
||||||
|
}
|
||||||
|
if (http.isResponseChunked()) {
|
||||||
|
Serial.println("This response is chunked");
|
||||||
|
}
|
||||||
|
|
||||||
|
String body = http.responseBody();
|
||||||
|
Serial.println("Response:");
|
||||||
|
Serial.println(body);
|
||||||
|
|
||||||
|
Serial.println(String("Body length is: ") + body.length());
|
||||||
|
|
||||||
|
// Shutdown
|
||||||
|
|
||||||
|
http.stop();
|
||||||
|
|
||||||
|
modem.gprsDisconnect();
|
||||||
|
Serial.println("GPRS disconnected");
|
||||||
|
|
||||||
|
// Do nothing forevermore
|
||||||
|
while (true) {
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
155
examples/HttpsClient/HttpsClient.ino
Normal file
155
examples/HttpsClient/HttpsClient.ino
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/**************************************************************
|
||||||
|
*
|
||||||
|
* This sketch connects to a website and downloads a page.
|
||||||
|
* It can be used to perform HTTP/RESTful API calls.
|
||||||
|
*
|
||||||
|
* For this example, you need to install ArduinoHttpClient library:
|
||||||
|
* https://github.com/arduino-libraries/ArduinoHttpClient
|
||||||
|
* or from http://librarymanager/all#ArduinoHttpClient
|
||||||
|
*
|
||||||
|
* TinyGSM Getting Started guide:
|
||||||
|
* http://tiny.cc/tiny-gsm-readme
|
||||||
|
*
|
||||||
|
**************************************************************/
|
||||||
|
|
||||||
|
// Select your modem
|
||||||
|
// SSL/TLS is currently supported only with SIM8xx series
|
||||||
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
#define TINY_GSM_MODEM_SIM808
|
||||||
|
|
||||||
|
// Increase RX buffer
|
||||||
|
#define TINY_GSM_RX_BUFFER 64
|
||||||
|
|
||||||
|
// Use Hardware Serial on Mega, Leonardo, Micro
|
||||||
|
#define SerialAT Serial1
|
||||||
|
|
||||||
|
// or Software Serial on Uno, Nano
|
||||||
|
//#include <SoftwareSerial.h>
|
||||||
|
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
||||||
|
|
||||||
|
//#define DUMP_AT_COMMANDS
|
||||||
|
//#define TINY_GSM_DEBUG Serial
|
||||||
|
|
||||||
|
|
||||||
|
// Your GPRS credentials
|
||||||
|
// Leave empty, if missing user or pass
|
||||||
|
const char apn[] = "YourAPN";
|
||||||
|
const char user[] = "";
|
||||||
|
const char pass[] = "";
|
||||||
|
|
||||||
|
// Name of the server we want to connect to
|
||||||
|
const char server[] = "cdn.rawgit.com";
|
||||||
|
const int port = 443;
|
||||||
|
// Path to download (this is the bit after the hostname in the URL)
|
||||||
|
const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
|
||||||
|
|
||||||
|
#include <TinyGsmClient.h>
|
||||||
|
#include <ArduinoHttpClient.h>
|
||||||
|
|
||||||
|
#ifdef DUMP_AT_COMMANDS
|
||||||
|
#include <StreamDebugger.h>
|
||||||
|
StreamDebugger debugger(SerialAT, Serial);
|
||||||
|
TinyGsm modem(debugger);
|
||||||
|
#else
|
||||||
|
TinyGsm modem(SerialAT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
TinyGsmClientSecure client(modem);
|
||||||
|
HttpClient http(client, server, port);
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
// Set console baud rate
|
||||||
|
Serial.begin(115200);
|
||||||
|
delay(10);
|
||||||
|
|
||||||
|
// Set GSM module baud rate
|
||||||
|
SerialAT.begin(115200);
|
||||||
|
delay(3000);
|
||||||
|
|
||||||
|
// Restart takes quite some time
|
||||||
|
// To skip it, call init() instead of restart()
|
||||||
|
Serial.println("Initializing modem...");
|
||||||
|
modem.restart();
|
||||||
|
|
||||||
|
String modemInfo = modem.getModemInfo();
|
||||||
|
Serial.print("Modem: ");
|
||||||
|
Serial.println(modemInfo);
|
||||||
|
|
||||||
|
// Unlock your SIM card with a PIN
|
||||||
|
//modem.simUnlock("1234");
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
if (!modem.hasSSL()) {
|
||||||
|
Serial.println("SSL is not supported by this modem");
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Serial.print(F("Waiting for network..."));
|
||||||
|
if (!modem.waitForNetwork()) {
|
||||||
|
Serial.println(" fail");
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.println(" OK");
|
||||||
|
|
||||||
|
Serial.print(F("Connecting to "));
|
||||||
|
Serial.print(apn);
|
||||||
|
if (!modem.gprsConnect(apn, user, pass)) {
|
||||||
|
Serial.println(" fail");
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.println(" OK");
|
||||||
|
|
||||||
|
|
||||||
|
Serial.print(F("Performing HTTP GET request... "));
|
||||||
|
http.connectionKeepAlive(); // Currently, this is needed for HTTPS
|
||||||
|
int err = http.get(resource);
|
||||||
|
if (err != 0) {
|
||||||
|
Serial.println("failed to connect");
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int status = http.responseStatusCode();
|
||||||
|
Serial.println(status);
|
||||||
|
if (!status) {
|
||||||
|
delay(10000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (http.headerAvailable()) {
|
||||||
|
String headerName = http.readHeaderName();
|
||||||
|
String headerValue = http.readHeaderValue();
|
||||||
|
//Serial.println(headerName + " : " + headerValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
int length = http.contentLength();
|
||||||
|
if (length >= 0) {
|
||||||
|
Serial.println(String("Content length is: ") + length);
|
||||||
|
}
|
||||||
|
if (http.isResponseChunked()) {
|
||||||
|
Serial.println("This response is chunked");
|
||||||
|
}
|
||||||
|
|
||||||
|
String body = http.responseBody();
|
||||||
|
Serial.println("Response:");
|
||||||
|
Serial.println(body);
|
||||||
|
|
||||||
|
Serial.println(String("Body length is: ") + body.length());
|
||||||
|
|
||||||
|
// Shutdown
|
||||||
|
|
||||||
|
http.stop();
|
||||||
|
|
||||||
|
modem.gprsDisconnect();
|
||||||
|
Serial.println("GPRS disconnected");
|
||||||
|
|
||||||
|
// Do nothing forevermore
|
||||||
|
while (true) {
|
||||||
|
delay(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
// Select your modem:
|
// Select your modem:
|
||||||
#define TINY_GSM_MODEM_SIM800
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
// #define TINY_GSM_MODEM_SIM808
|
||||||
// #define TINY_GSM_MODEM_SIM900
|
// #define TINY_GSM_MODEM_SIM900
|
||||||
// #define TINY_GSM_MODEM_A6
|
// #define TINY_GSM_MODEM_A6
|
||||||
// #define TINY_GSM_MODEM_A7
|
// #define TINY_GSM_MODEM_A7
|
||||||
@@ -81,6 +82,10 @@ void setup() {
|
|||||||
Serial.println("Initializing modem...");
|
Serial.println("Initializing modem...");
|
||||||
modem.restart();
|
modem.restart();
|
||||||
|
|
||||||
|
String modemInfo = modem.getModemInfo();
|
||||||
|
Serial.print("Modem: ");
|
||||||
|
Serial.println(modemInfo);
|
||||||
|
|
||||||
// Unlock your SIM card with a PIN
|
// Unlock your SIM card with a PIN
|
||||||
//modem.simUnlock("1234");
|
//modem.simUnlock("1234");
|
||||||
|
|
||||||
|
@@ -10,12 +10,12 @@
|
|||||||
|
|
||||||
// Select your modem:
|
// Select your modem:
|
||||||
#define TINY_GSM_MODEM_SIM800
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
// #define TINY_GSM_MODEM_SIM808
|
||||||
// #define TINY_GSM_MODEM_SIM900
|
// #define TINY_GSM_MODEM_SIM900
|
||||||
// #define TINY_GSM_MODEM_A6
|
// #define TINY_GSM_MODEM_A6
|
||||||
// #define TINY_GSM_MODEM_A7
|
// #define TINY_GSM_MODEM_A7
|
||||||
// #define TINY_GSM_MODEM_M590
|
// #define TINY_GSM_MODEM_M590
|
||||||
// #define TINY_GSM_MODEM_ESP8266
|
// #define TINY_GSM_MODEM_ESP8266
|
||||||
// #define TINY_GSM_MODEM_XBEE
|
|
||||||
|
|
||||||
#include <TinyGsmClient.h>
|
#include <TinyGsmClient.h>
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ TinyGsmClient client(modem);
|
|||||||
const char server[] = "cdn.rawgit.com";
|
const char server[] = "cdn.rawgit.com";
|
||||||
const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
|
const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
|
||||||
|
|
||||||
int port = 80;
|
const int port = 80;
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// Set console baud rate
|
// Set console baud rate
|
||||||
@@ -54,6 +54,10 @@ void setup() {
|
|||||||
Serial.println(F("Initializing modem..."));
|
Serial.println(F("Initializing modem..."));
|
||||||
modem.restart();
|
modem.restart();
|
||||||
|
|
||||||
|
String modemInfo = modem.getModemInfo();
|
||||||
|
Serial.print("Modem: ");
|
||||||
|
Serial.println(modemInfo);
|
||||||
|
|
||||||
// Unlock your SIM card with a PIN
|
// Unlock your SIM card with a PIN
|
||||||
//modem.simUnlock("1234");
|
//modem.simUnlock("1234");
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
#######################################
|
#######################################
|
||||||
TinyGsm KEYWORD1
|
TinyGsm KEYWORD1
|
||||||
TinyGsmClient KEYWORD1
|
TinyGsmClient KEYWORD1
|
||||||
|
TinyGsmClientSecure KEYWORD1
|
||||||
|
|
||||||
SerialAT KEYWORD1
|
SerialAT KEYWORD1
|
||||||
SerialMon KEYWORD1
|
SerialMon KEYWORD1
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "TinyGSM",
|
"name": "TinyGSM",
|
||||||
"version": "0.1.8",
|
"version": "0.3.1",
|
||||||
"description": "A small Arduino library for GPRS modules, that just works. Includes examples for Blynk, MQTT, File Download, and Web Client. Supports GSM modules with AT command interface: SIM800, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900, SIM900A, SIM900D, SIM908, SIM968",
|
"description": "A small Arduino library for GPRS modules, that just works. Includes examples for Blynk, MQTT, File Download, and Web Client. Supports GSM modules with AT command interface: SIM800, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900, SIM900A, SIM900D, SIM908, SIM968",
|
||||||
"keywords": "GSM, AT commands, AT, SIM800, SIM900, A6, A7, M590, ESP8266, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900A, SIM900D, SIM908, SIM968",
|
"keywords": "GSM, AT commands, AT, SIM800, SIM900, A6, A7, M590, ESP8266, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900A, SIM900D, SIM908, SIM968",
|
||||||
"authors":
|
"authors":
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
name=TinyGSM
|
name=TinyGSM
|
||||||
version=0.1.8
|
version=0.3.1
|
||||||
author=Volodymyr Shymanskyy
|
author=Volodymyr Shymanskyy
|
||||||
maintainer=Volodymyr Shymanskyy
|
maintainer=Volodymyr Shymanskyy
|
||||||
sentence=A small Arduino library for GPRS modules, that just works.
|
sentence=A small Arduino library for GPRS modules, that just works.
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
// Select your modem:
|
// Select your modem:
|
||||||
#define TINY_GSM_MODEM_SIM800
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
// #define TINY_GSM_MODEM_SIM808
|
||||||
// #define TINY_GSM_MODEM_SIM900
|
// #define TINY_GSM_MODEM_SIM900
|
||||||
// #define TINY_GSM_MODEM_A6
|
// #define TINY_GSM_MODEM_A6
|
||||||
// #define TINY_GSM_MODEM_A7
|
// #define TINY_GSM_MODEM_A7
|
||||||
@@ -30,7 +31,9 @@
|
|||||||
//#include <SoftwareSerial.h>
|
//#include <SoftwareSerial.h>
|
||||||
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
||||||
|
|
||||||
TinyGsm modem(SerialAT);
|
#define TINY_GSM_DEBUG SerialMon
|
||||||
|
|
||||||
|
#include <TinyGsmClient.h>
|
||||||
|
|
||||||
// Module baud rate
|
// Module baud rate
|
||||||
uint32_t rate = 0; // Set to 0 for Auto-Detect
|
uint32_t rate = 0; // Set to 0 for Auto-Detect
|
||||||
@@ -44,21 +47,7 @@ void setup() {
|
|||||||
void loop() {
|
void loop() {
|
||||||
|
|
||||||
if (!rate) {
|
if (!rate) {
|
||||||
static uint32_t rates[] = { 115200, 9600, 57600, 19200, 38400, 74400, 74880, 230400, 460800, 2400, 4800, 14400, 28800 };
|
rate = TinyGsmAutoBaud(SerialAT);
|
||||||
|
|
||||||
SerialMon.println("Autodetecting baud rate");
|
|
||||||
for (unsigned i = 0; i < sizeof(rates)/sizeof(rates[0]); i++) {
|
|
||||||
SerialMon.print(String("Trying baud rate ") + rates[i] + "... ");
|
|
||||||
SerialAT.begin(rates[i]);
|
|
||||||
delay(10);
|
|
||||||
if (modem.autoBaud(1000)) {
|
|
||||||
rate = rates[i];
|
|
||||||
SerialMon.println(F("OK"));
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
SerialMon.println(F("fail"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rate) {
|
if (!rate) {
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
// Select your modem:
|
// Select your modem:
|
||||||
#define TINY_GSM_MODEM_SIM800
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
// #define TINY_GSM_MODEM_SIM808
|
||||||
// #define TINY_GSM_MODEM_SIM900
|
// #define TINY_GSM_MODEM_SIM900
|
||||||
// #define TINY_GSM_MODEM_A6
|
// #define TINY_GSM_MODEM_A6
|
||||||
// #define TINY_GSM_MODEM_A7
|
// #define TINY_GSM_MODEM_A7
|
||||||
@@ -18,11 +19,10 @@
|
|||||||
// #define TINY_GSM_MODEM_ESP8266
|
// #define TINY_GSM_MODEM_ESP8266
|
||||||
// #define TINY_GSM_MODEM_XBEE
|
// #define TINY_GSM_MODEM_XBEE
|
||||||
|
|
||||||
// Increase buffer fo see less commands
|
// Increase the buffer
|
||||||
#define TINY_GSM_RX_BUFFER 256
|
#define TINY_GSM_RX_BUFFER 512
|
||||||
|
|
||||||
#include <TinyGsmClient.h>
|
#include <TinyGsmClient.h>
|
||||||
#include <StreamDebugger.h>
|
|
||||||
|
|
||||||
// Your GPRS credentials
|
// Your GPRS credentials
|
||||||
// Leave empty, if missing user or pass
|
// Leave empty, if missing user or pass
|
||||||
@@ -42,12 +42,13 @@ const char pass[] = "";
|
|||||||
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
||||||
|
|
||||||
|
|
||||||
|
#include <StreamDebugger.h>
|
||||||
StreamDebugger debugger(SerialAT, SerialMon);
|
StreamDebugger debugger(SerialAT, SerialMon);
|
||||||
TinyGsm modem(debugger);
|
TinyGsm modem(debugger);
|
||||||
TinyGsmClient client(modem);
|
TinyGsmClient client(modem);
|
||||||
|
|
||||||
const char server[] = "cdn.rawgit.com";
|
const char server[] = "cdn.rawgit.com";
|
||||||
const char resource[] = "/vshymanskyy/tinygsm/master/extras/test_simple.txt";
|
const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt";
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// Set console baud rate
|
// Set console baud rate
|
||||||
@@ -144,9 +145,9 @@ void loop() {
|
|||||||
SerialMon.println("************************");
|
SerialMon.println("************************");
|
||||||
SerialMon.print (" Received: ");
|
SerialMon.print (" Received: ");
|
||||||
SerialMon.print(bytesReceived);
|
SerialMon.print(bytesReceived);
|
||||||
SerialMon.println("bytes");
|
SerialMon.println(" bytes");
|
||||||
SerialMon.print (" Test: ");
|
SerialMon.print (" Test: ");
|
||||||
SerialMon.println((bytesReceived == 1000) ? "PASSED" : "FAIL");
|
SerialMon.println((bytesReceived == 121) ? "PASSED" : "FAILED");
|
||||||
SerialMon.println("************************");
|
SerialMon.println("************************");
|
||||||
|
|
||||||
// Do nothing forevermore
|
// Do nothing forevermore
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
// Select your modem:
|
// Select your modem:
|
||||||
#define TINY_GSM_MODEM_SIM800
|
#define TINY_GSM_MODEM_SIM800
|
||||||
|
// #define TINY_GSM_MODEM_SIM808
|
||||||
// #define TINY_GSM_MODEM_SIM900
|
// #define TINY_GSM_MODEM_SIM900
|
||||||
// #define TINY_GSM_MODEM_A6
|
// #define TINY_GSM_MODEM_A6
|
||||||
// #define TINY_GSM_MODEM_A7
|
// #define TINY_GSM_MODEM_A7
|
||||||
@@ -19,7 +20,6 @@
|
|||||||
// #define TINY_GSM_MODEM_XBEE
|
// #define TINY_GSM_MODEM_XBEE
|
||||||
|
|
||||||
#include <TinyGsmClient.h>
|
#include <TinyGsmClient.h>
|
||||||
#include <StreamDebugger.h>
|
|
||||||
|
|
||||||
// Set serial for debug console (to the Serial Monitor, speed 115200)
|
// Set serial for debug console (to the Serial Monitor, speed 115200)
|
||||||
#define SerialMon Serial
|
#define SerialMon Serial
|
||||||
@@ -32,6 +32,7 @@
|
|||||||
//#include <SoftwareSerial.h>
|
//#include <SoftwareSerial.h>
|
||||||
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
//SoftwareSerial SerialAT(2, 3); // RX, TX
|
||||||
|
|
||||||
|
#include <StreamDebugger.h>
|
||||||
StreamDebugger debugger(SerialAT, SerialMon);
|
StreamDebugger debugger(SerialAT, SerialMon);
|
||||||
TinyGsm modem(debugger);
|
TinyGsm modem(debugger);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user