diff --git a/README.md b/README.md index 382b3a8..5722642 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,12 @@ If you like **TinyGSM** - give it a star, or fork it and contribute! [![GitHub stars](https://img.shields.io/github/stars/vshymanskyy/TinyGSM.svg?style=social&label=Star)](https://github.com/vshymanskyy/TinyGSM/stargazers) [![GitHub forks](https://img.shields.io/github/forks/vshymanskyy/TinyGSM.svg?style=social&label=Fork)](https://github.com/vshymanskyy/TinyGSM/network) +You can also join our chat: +[![Gitter](https://img.shields.io/gitter/room/vshymanskyy/TinyGSM.svg)](https://gitter.im/tinygsm) + ### Arduino Client interface support 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. ![examples](/extras/examples.png) @@ -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. **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 SIM900 series (SIM900A, SIM900D, SIM908, SIM968) - [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 ;) +## Donation + +[![Donate BountySource](https://img.shields.io/badge/Donate-BountySource-149E5E.svg)](https://salt.bountysource.com/checkout/amount?team=tinygsm-dev) +[![Donate Bitcoin](https://img.shields.io/badge/Donate-Bitcoin-orange.svg)](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 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) 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 ### SoftwareSerial problems diff --git a/TinyGsmClient.h b/TinyGsmClient.h index 421914c..07f1126 100644 --- a/TinyGsmClient.h +++ b/TinyGsmClient.h @@ -11,14 +11,32 @@ #if defined(TINY_GSM_MODEM_SIM800) || defined(TINY_GSM_MODEM_SIM900) #include + typedef TinyGsmSim800 TinyGsm; + typedef TinyGsmSim800::GsmClient TinyGsmClient; + typedef TinyGsmSim800::GsmClientSecure TinyGsmClientSecure; + +#elif defined(TINY_GSM_MODEM_SIM808) || defined(TINY_GSM_MODEM_SIM868) + #include + typedef TinyGsmSim808 TinyGsm; + typedef TinyGsmSim808::GsmClient TinyGsmClient; + typedef TinyGsmSim808::GsmClientSecure TinyGsmClientSecure; + #elif defined(TINY_GSM_MODEM_A6) || defined(TINY_GSM_MODEM_A7) #include + typedef TinyGsm::GsmClient TinyGsmClient; + #elif defined(TINY_GSM_MODEM_M590) #include + typedef TinyGsm::GsmClient TinyGsmClient; + #elif defined(TINY_GSM_MODEM_ESP8266) #include + typedef TinyGsm::GsmClient TinyGsmClient; + #elif defined(TINY_GSM_MODEM_XBEE) #include + typedef TinyGsm::GsmClient TinyGsmClient; + #else #error "Please define GSM modem model" #endif diff --git a/TinyGsmClientA6.h b/TinyGsmClientA6.h index 82407c3..1eaf2c4 100644 --- a/TinyGsmClientA6.h +++ b/TinyGsmClientA6.h @@ -15,6 +15,8 @@ #define TINY_GSM_RX_BUFFER 256 #endif +#define TINY_GSM_MUX_COUNT 8 + #include #define GSM_NL "\r\n" @@ -40,11 +42,6 @@ enum RegStatus { class TinyGsm { -public: - TinyGsm(Stream& stream) - : stream(stream) - {} - public: class GsmClient : public Client @@ -111,7 +108,7 @@ public: virtual int available() { TINY_GSM_YIELD(); - if (!rx.size()) { + if (!rx.size() && sock_connected) { at->maintain(); } return rx.size(); @@ -155,6 +152,13 @@ public: return sock_connected; } virtual operator bool() { return connected(); } + + /* + * Extended API + */ + + String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; + private: TinyGsm* at; uint8_t mux; @@ -164,6 +168,12 @@ private: public: + TinyGsm(Stream& stream) + : stream(stream) + { + memset(sockets, 0, sizeof(sockets)); + } + /* * Basic functions */ @@ -211,6 +221,18 @@ public: 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 */ @@ -224,6 +246,11 @@ public: return init(); } + bool poweroff() { + sendAT(GF("+CPOF")); + return waitResponse() == 1; + } + /* * SIM card functions */ @@ -235,7 +262,7 @@ public: String getSimCCID() { sendAT(GF("+CCID")); - if (waitResponse(GF(GSM_NL "+ICCID:")) != 1) { + if (waitResponse(GF(GSM_NL "+SCID: SIM Card ID:")) != 1) { return ""; } String res = streamReadUntil('\n'); @@ -295,7 +322,7 @@ public: } /* - * Generic network functions + * Generic network functions */ int getSignalQuality() { @@ -303,7 +330,7 @@ public: if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) { return 99; } - int res = streamReadUntil(',').toInt(); + int res = stream.readStringUntil(',').toInt(); waitResponse(); return res; } @@ -336,9 +363,17 @@ public: bool gprsConnect(const char* apn, const char* user, const char* pwd) { gprsDisconnect(); + sendAT(GF("+CGATT=1")); + if (waitResponse(60000L) != 1) + return false; + + // TODO: wait AT+CGATT? + sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"'); waitResponse(); + if (!user) user = ""; + if (!pwd) pwd = ""; sendAT(GF("+CSTT=\""), apn, GF("\",\""), user, GF("\",\""), pwd, GF("\"")); if (waitResponse(60000L) != 1) { return false; @@ -347,24 +382,11 @@ public: sendAT(GF("+CGACT=1,1")); waitResponse(60000L); - sendAT(GF("+CGATT=1")); - if (waitResponse(60000L) != 1) - return false; - - // TODO: wait AT+CGATT? - sendAT(GF("+CIPMUX=1")); if (waitResponse() != 1) { return false; } - /*sendAT(GF("+CIFSR")); - String data; - if (waitResponse(10000L, data) != 1) { - data.replace(GSM_NL, ""); - return false; - }*/ - return true; } @@ -373,22 +395,58 @@ public: 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 */ + bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE; + bool callAnswer() { sendAT(GF("A")); return waitResponse() == 1; } + // Returns true on pick-up, false on error/busy bool callNumber(const String& number) { - sendAT(GF("D"), number); - return waitResponse() == 1; + sendAT(GF("D\""), number, "\";"); + 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) { - sendAT(GF("H"), number); + //bool callRedial() { + // sendAT(GF("DLST")); + // return waitResponse() == 1; + //} + + bool callHangup() { + sendAT(GF("H")); return waitResponse() == 1; } @@ -396,6 +454,32 @@ public: * 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) { sendAT(GF("+CMGF=1")); waitResponse(); @@ -405,24 +489,41 @@ public: } stream.print(text); stream.write((char)0x1A); + stream.flush(); return waitResponse(60000L) == 1; } + /* * Location functions */ + String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE; /* * 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: - 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); if (waitResponse(75000L, GF(GSM_NL "+CIPNUM:")) != 1) { - return -1; + return false; } int newMux = streamReadUntil('\n').toInt(); @@ -431,7 +532,7 @@ private: GF("CONNECT FAIL" GSM_NL), GF("ALREADY CONNECT" GSM_NL)); if (waitResponse() != 1) { - return -1; + return false; } *mux = newMux; @@ -440,7 +541,7 @@ private: int modemSend(const void* buff, size_t len, uint8_t mux) { sendAT(GF("+CIPSEND="), mux, ',', len); - if (waitResponse(10000L, GF(GSM_NL ">")) != 1) { + if (waitResponse(2000L, GF(GSM_NL ">")) != 1) { return -1; } stream.write((uint8_t*)buff, len); @@ -451,14 +552,61 @@ private: return len; } - bool modemGetConnected(uint8_t mux) { //TODO mux? - sendAT(GF("+CIPSTATUS")); + bool modemGetConnected(uint8_t mux) { + sendAT(GF("+CIPSTATUS")); //TODO mux? int res = waitResponse(GF(",\"CONNECTED\""), GF(",\"CLOSED\""), GF(",\"CLOSING\""), GF(",\"INITIAL\"")); waitResponse(); return 1 == res; } - /* Private Utilities */ + static String decodeHex7bit(String &instr) { + String result; + byte reminder = 0; + int bitstate = 7; + for (unsigned i=0; i> 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 void streamWrite(T last) { stream.print(last); @@ -470,17 +618,6 @@ private: 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) { String skipped = stream.readStringUntil(c); skipped.trim(); @@ -520,7 +657,7 @@ private: do { TINY_GSM_YIELD(); while (stream.available() > 0) { - int a = streamRead(); + int a = stream.read(); if (a <= 0) continue; // Skip 0x00 bytes, just in case data += (char)a; if (r1 && data.endsWith(r1)) { @@ -539,24 +676,25 @@ private: index = 5; goto finish; } else if (data.endsWith(GF("+CIPRCV:"))) { - mux = stream.readStringUntil(',').toInt(); - data += mux; - data += (','); - len = stream.readStringUntil(',').toInt(); - data += len; - data += (','); - gotData = true; - index = 6; - goto finish; + int mux = stream.readStringUntil(',').toInt(); + int len = stream.readStringUntil(',').toInt(); + if (len > sockets[mux]->rx.free()) { + DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free()); + } else { + DBG("### Got: ", len, "->", sockets[mux]->rx.free()); + } + while (len--) { + while (!stream.available()) { TINY_GSM_YIELD(); } + sockets[mux]->rx.put(stream.read()); + } + data = ""; } else if (data.endsWith(GF("+TCPCLOSED:"))) { - mux = stream.readStringUntil(',').toInt(); - data += mux; - data += (','); - String concl = stream.readStringUntil('\n'); - data += concl; - sockets[mux]->sock_connected = false; - index = 7; - goto finish; + int mux = stream.readStringUntil('\n').toInt(); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) { + sockets[mux]->sock_connected = false; + } + data = ""; + DBG("### Closed: ", mux); } } } while (millis() - startMillis < timeout); @@ -611,9 +749,7 @@ private: private: Stream& stream; - GsmClient* sockets[8]; + GsmClient* sockets[TINY_GSM_MUX_COUNT]; }; -typedef TinyGsm::GsmClient TinyGsmClient; - #endif diff --git a/TinyGsmClientESP8266.h b/TinyGsmClientESP8266.h index 3dfffac..c6c129e 100644 --- a/TinyGsmClientESP8266.h +++ b/TinyGsmClientESP8266.h @@ -1,13 +1,13 @@ /** - * @file TinyWiFiClientESP8266.h + * @file TinyGsmClientESP8266.h * @author Volodymyr Shymanskyy * @license LGPL-3.0 * @copyright Copyright (c) 2016 Volodymyr Shymanskyy * @date Nov 2016 */ -#ifndef TinyWiFiClientESP8266_h -#define TinyWiFiClientESP8266_h +#ifndef TinyGsmClientESP8266_h +#define TinyGsmClientESP8266_h //#define TINY_GSM_DEBUG Serial @@ -15,21 +15,18 @@ #define TINY_GSM_RX_BUFFER 256 #endif +#define TINY_GSM_MUX_COUNT 5 + #include #define GSM_NL "\r\n" static const char GSM_OK[] TINY_GSM_PROGMEM = "OK" 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 { -public: - TinyGsm(Stream& stream) - : stream(stream) - {} - public: class GsmClient : public Client @@ -94,7 +91,7 @@ public: virtual int available() { TINY_GSM_YIELD(); - if (!rx.size()) { + if (!rx.size() && sock_connected) { at->maintain(); } return rx.size(); @@ -138,6 +135,13 @@ public: return sock_connected; } virtual operator bool() { return connected(); } + + /* + * Extended API + */ + + String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; + private: TinyGsm* at; uint8_t mux; @@ -147,6 +151,12 @@ private: public: + TinyGsm(Stream& stream) + : stream(stream) + { + memset(sockets, 0, sizeof(sockets)); + } + /* * Basic functions */ @@ -273,20 +283,21 @@ public: return waitResponse(10000L) == 1; } + String getLocalIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; + + IPAddress localIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; + /* * GPRS functions */ - bool gprsConnect(const char* apn, const char* user, const char* pwd) { - return false; - } + bool gprsConnect(const char* apn, const char* user, const char* pwd) TINY_GSM_ATTR_NOT_IMPLEMENTED; - bool gprsDisconnect() { - return false; - } + bool gprsDisconnect() TINY_GSM_ATTR_NOT_IMPLEMENTED; private: + 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, GFP(GSM_OK), GFP(GSM_ERROR), @@ -301,6 +312,7 @@ private: return -1; } stream.write((uint8_t*)buff, len); + stream.flush(); if (waitResponse(GF(GSM_NL "SEND OK" GSM_NL)) != 1) { return -1; } @@ -314,7 +326,10 @@ private: return 1 == res; } - /* Private Utilities */ +public: + + /* Utilities */ + template void streamWrite(T last) { stream.print(last); @@ -326,7 +341,14 @@ private: 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 return_string = stream.readStringUntil(c); @@ -376,7 +398,7 @@ private: do { TINY_GSM_YIELD(); while (stream.available() > 0) { - int a = streamRead(); + int a = stream.read(); if (a <= 0) continue; // Skip 0x00 bytes, just in case data += (char)a; if (r1 && data.endsWith(r1)) { @@ -395,16 +417,20 @@ private: index = 5; goto finish; } else if (data.endsWith(GF(GSM_NL "+IPD,"))) { - mux = stream.readStringUntil(',').toInt(); - data += mux; - data += (','); - len = stream.readStringUntil(':').toInt(); - data += len; - data += (':'); - gotData = true; - index = 6; - goto finish; - } else if (data.endsWith(GF("1,CLOSED" GSM_NL))) { //TODO: use mux + int mux = stream.readStringUntil(',').toInt(); + int len = stream.readStringUntil(':').toInt(); + if (len > sockets[mux]->rx.free()) { + DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free()); + } else { + DBG("### Got: ", len, "->", sockets[mux]->rx.free()); + } + while (len--) { + while (!stream.available()) { TINY_GSM_YIELD(); } + 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; index = 7; goto finish; @@ -462,9 +488,7 @@ private: private: Stream& stream; - GsmClient* sockets[5]; + GsmClient* sockets[TINY_GSM_MUX_COUNT]; }; -typedef TinyGsm::GsmClient TinyGsmClient; - #endif diff --git a/TinyGsmClientM590.h b/TinyGsmClientM590.h index cab8252..3a07084 100644 --- a/TinyGsmClientM590.h +++ b/TinyGsmClientM590.h @@ -15,6 +15,8 @@ #define TINY_GSM_RX_BUFFER 256 #endif +#define TINY_GSM_MUX_COUNT 2 + #include #define GSM_NL "\r\n" @@ -40,11 +42,6 @@ enum RegStatus { class TinyGsm { -public: - TinyGsm(Stream& stream) - : stream(stream) - {} - public: class GsmClient : public Client @@ -108,7 +105,7 @@ public: virtual int available() { TINY_GSM_YIELD(); - if (!rx.size()) { + if (!rx.size() && sock_connected) { at->maintain(); } return rx.size(); @@ -152,6 +149,13 @@ public: return sock_connected; } virtual operator bool() { return connected(); } + + /* + * Extended API + */ + + String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; + private: TinyGsm* at; uint8_t mux; @@ -161,6 +165,12 @@ private: public: + TinyGsm(Stream& stream) + : stream(stream) + { + memset(sockets, 0, sizeof(sockets)); + } + /* * Basic functions */ @@ -216,6 +226,18 @@ public: 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 */ @@ -233,6 +255,11 @@ public: return init(); } + bool poweroff() { + sendAT(GF("+CPWROFF")); + return waitResponse(3000L) == 1; + } + /* * SIM card functions */ @@ -303,16 +330,16 @@ public: return res; } - /* - * Generic network functions - */ + /* + * Generic network functions + */ int getSignalQuality() { sendAT(GF("+CSQ")); if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) { return 99; } - int res = streamReadUntil(',').toInt(); + int res = stream.readStringUntil(',').toInt(); waitResponse(); return res; } @@ -364,13 +391,15 @@ public: sendAT(GF("+XIIC?")); waitResponse(); - /*sendAT(GF("+DNSSERVER=1,8.8.8.8")); + /* + sendAT(GF("+DNSSERVER=1,8.8.8.8")); waitResponse(); sendAT(GF("+DNSSERVER=2,8.8.4.4")); if (waitResponse() != 1) { return false; - }*/ + } + */ return true; } @@ -380,30 +409,72 @@ public: 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 */ - bool callAnswer() { - sendAT(GF("A")); - return waitResponse() == 1; - } + bool setGsmBusy(bool busy = true) TINY_GSM_ATTR_NOT_AVAILABLE; - bool callNumber(const String& number) { - sendAT(GF("D"), number); - return waitResponse() == 1; - } + bool callAnswer() TINY_GSM_ATTR_NOT_AVAILABLE; - bool callHangup(const String& number) { - sendAT(GF("H"), number); - return waitResponse() == 1; - } + bool callNumber(const String& number) TINY_GSM_ATTR_NOT_AVAILABLE; + + bool callRedial() TINY_GSM_ATTR_NOT_AVAILABLE; + + bool callHangup() TINY_GSM_ATTR_NOT_AVAILABLE; /* * 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) { + sendAT(GF("+CSCS=\"GSM\"")); + waitResponse(); sendAT(GF("+CMGF=1")); waitResponse(); sendAT(GF("+CMGS=\""), number, GF("\"")); @@ -412,31 +483,31 @@ public: } stream.print(text); stream.write((char)0x1A); + stream.flush(); return waitResponse(60000L) == 1; } + bool sendSMS_UTF16(const String& number, const void* text, size_t len) + TINY_GSM_ATTR_NOT_AVAILABLE; + /* * Location functions */ + String getGsmLocation() TINY_GSM_ATTR_NOT_AVAILABLE; + /* * Battery functions */ + uint16_t getBattVoltage() TINY_GSM_ATTR_NOT_AVAILABLE; + + int getBattPercent() TINY_GSM_ATTR_NOT_AVAILABLE; + private: - 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) { - for (int i=0; i<3; i++) { + + 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); sendAT(GF("+TCPSETUP="), mux, GF(","), ip, GF(","), port); @@ -462,7 +533,7 @@ private: } stream.write((uint8_t*)buff, len); stream.write((char)0x0D); - + stream.flush(); if (waitResponse(30000L, GF(GSM_NL "+TCPSEND:")) != 1) { return 0; } @@ -477,7 +548,52 @@ private: 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 void streamWrite(T last) { stream.print(last); @@ -489,26 +605,13 @@ private: 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) { - 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; + bool streamSkipUntil(char c) { //TODO: timeout + while (true) { + while (!stream.available()) { TINY_GSM_YIELD(); } + if (stream.read() == c) + return true; + } + return false; } template @@ -539,7 +642,7 @@ private: do { TINY_GSM_YIELD(); while (stream.available() > 0) { - int a = streamRead(); + int a = stream.read(); if (a <= 0) continue; // Skip 0x00 bytes, just in case data += (char)a; if (r1 && data.endsWith(r1)) { @@ -558,24 +661,26 @@ private: index = 5; goto finish; } else if (data.endsWith(GF("+TCPRECV:"))) { - mux = stream.readStringUntil(',').toInt(); - data += mux; - data += (','); - len = stream.readStringUntil(',').toInt(); - data += len; - data += (','); - gotData = true; - index = 6; - goto finish; + int mux = stream.readStringUntil(',').toInt(); + int len = stream.readStringUntil(',').toInt(); + if (len > sockets[mux]->rx.free()) { + DBG("### Buffer overflow: ", len, "->", sockets[mux]->rx.free()); + } else { + DBG("### Got: ", len, "->", sockets[mux]->rx.free()); + } + while (len--) { + while (!stream.available()) { TINY_GSM_YIELD(); } + sockets[mux]->rx.put(stream.read()); + } + data = ""; } else if (data.endsWith(GF("+TCPCLOSE:"))) { - mux = stream.readStringUntil(',').toInt(); - data += mux; - data += (','); - String concl = stream.readStringUntil('\n'); - data += concl; - sockets[mux]->sock_connected = false; - index = 7; - goto finish; + int mux = stream.readStringUntil(',').toInt(); + stream.readStringUntil('\n'); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) { + sockets[mux]->sock_connected = false; + } + data = ""; + DBG("### Closed: ", mux); } } } while (millis() - startMillis < timeout); @@ -630,9 +735,7 @@ private: private: Stream& stream; - GsmClient* sockets[2]; + GsmClient* sockets[TINY_GSM_MUX_COUNT]; }; -typedef TinyGsm::GsmClient TinyGsmClient; - #endif diff --git a/TinyGsmClientSIM800.h b/TinyGsmClientSIM800.h index 134703a..399f400 100644 --- a/TinyGsmClientSIM800.h +++ b/TinyGsmClientSIM800.h @@ -16,6 +16,8 @@ #define TINY_GSM_RX_BUFFER 64 #endif +#define TINY_GSM_MUX_COUNT 5 + #include #define GSM_NL "\r\n" @@ -38,33 +40,30 @@ enum RegStatus { }; -class TinyGsm +class TinyGsmSim800 { -public: - TinyGsm(Stream& stream) - : stream(stream) - {} - public: class GsmClient : public Client { - friend class TinyGsm; + friend class TinyGsmSim800; typedef TinyGsmFifo RxFifo; public: GsmClient() {} - GsmClient(TinyGsm& modem, uint8_t mux = 1) { + GsmClient(TinyGsmSim800& modem, uint8_t mux = 1) { init(&modem, mux); } - bool init(TinyGsm* modem, uint8_t mux = 1) { + bool init(TinyGsmSim800* modem, uint8_t mux = 1) { this->at = modem; this->mux = mux; sock_available = 0; + prev_check = 0; sock_connected = false; + got_data = false; at->sockets[mux] = this; @@ -110,7 +109,14 @@ public: virtual int available() { 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(); } return rx.size() + sock_available; @@ -157,16 +163,49 @@ public: return sock_connected; } virtual operator bool() { return connected(); } + + /* + * Extended API + */ + + String remoteIP() TINY_GSM_ATTR_NOT_IMPLEMENTED; + private: - TinyGsm* at; + TinyGsmSim800* at; uint8_t mux; uint16_t sock_available; + uint32_t prev_check; bool sock_connected; + bool got_data; RxFifo rx; }; +class GsmClientSecure : public GsmClient +{ +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 */ @@ -178,7 +217,9 @@ public: if (!autoBaud()) { return false; } - sendAT(GF("&FZE0")); // Factory + Reset + Echo Off + sendAT(GF("&FZ")); // Factory + Reset + waitResponse(); + sendAT(GF("E0")); // Echo Off if (waitResponse() != 1) { return false; } @@ -187,7 +228,7 @@ public: } 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; ) { sendAT(GF("")); if (waitResponse(200) == 1) { @@ -200,6 +241,13 @@ public: } 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()) { waitResponse(10, NULL, NULL); } @@ -220,6 +268,26 @@ public: 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 */ @@ -240,6 +308,23 @@ public: 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 */ @@ -310,16 +395,16 @@ public: return res; } - /* - * Generic network functions - */ + /* + * Generic network functions + */ int getSignalQuality() { sendAT(GF("+CSQ")); if (waitResponse(GF(GSM_NL "+CSQ:")) != 1) { return 99; } - int res = streamReadUntil(',').toInt(); + int res = stream.readStringUntil(',').toInt(); waitResponse(); return res; } @@ -413,9 +498,7 @@ public: } sendAT(GF("+CIFSR;E0")); - String data; - if (waitResponse(10000L, data) != 1) { - data.replace(GSM_NL, ""); + if (waitResponse(10000L) != 1) { return false; } @@ -432,6 +515,22 @@ public: 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 */ @@ -446,13 +545,25 @@ public: return waitResponse() == 1; } + // Returns true on pick-up, false on error/busy bool callNumber(const String& number) { - sendAT(GF("D"), number); - return waitResponse() == 1; + sendAT(GF("D"), number, ";"); + 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) { - sendAT(GF("H"), number); + //bool callRedial() { + // sendAT(GF("DL")); + // return waitResponse() == 1; + //} + + bool callHangup() { + sendAT(GF("H")); return waitResponse() == 1; } @@ -460,6 +571,32 @@ public: * 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) { sendAT(GF("+CMGF=1")); waitResponse(); @@ -469,6 +606,7 @@ public: } stream.print(text); stream.write((char)0x1A); + stream.flush(); return waitResponse(60000L) == 1; } @@ -495,6 +633,7 @@ public: stream.print(c, HEX); } stream.write((char)0x1A); + stream.flush(); return waitResponse(60000L) == 1; } @@ -505,11 +644,12 @@ public: String getGsmLocation() { sendAT(GF("+CIPGSMLOC=1,1")); - if (waitResponse(GF(GSM_NL "+CIPGSMLOC:")) != 1) { + if (waitResponse(10000L, GF(GSM_NL "+CIPGSMLOC:")) != 1) { return ""; } - String res = streamReadUntil('\n'); + String res = stream.readStringUntil('\n'); waitResponse(); + res.trim(); return res; } @@ -530,13 +670,30 @@ public: return res; } -private: - int modemConnect(const char* host, uint16_t port, uint8_t mux) { + int getBattPercent() { + 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); - int rsp = waitResponse(75000L, - GF("CONNECT OK" GSM_NL), - GF("CONNECT FAIL" GSM_NL), - GF("ALREADY CONNECT" GSM_NL)); + rsp = waitResponse(75000L, + GF("CONNECT OK" GSM_NL), + GF("CONNECT FAIL" GSM_NL), + GF("ALREADY CONNECT" GSM_NL)); return (1 == rsp); } @@ -573,16 +730,15 @@ private: for (size_t i=0; irx.put(c); } @@ -612,7 +768,41 @@ private: return 1 == res; } - /* Private Utilities */ + static String decodeHex8bit(String &instr) { + String result; + for (unsigned i=0; i void streamWrite(T last) { stream.print(last); @@ -624,26 +814,13 @@ private: 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) { - 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; + bool streamSkipUntil(char c) { //TODO: timeout + while (true) { + while (!stream.available()) { TINY_GSM_YIELD(); } + if (stream.read() == c) + return true; + } + return false; } template @@ -666,14 +843,12 @@ private: String r5s(r5); r5s.trim(); DBG("### ..:", r1s, ",", r2s, ",", r3s, ",", r4s, ",", r5s);*/ data.reserve(64); - bool gotData = false; - int mux = -1; int index = 0; unsigned long startMillis = millis(); do { TINY_GSM_YIELD(); while (stream.available() > 0) { - int a = streamRead(); + int a = stream.read(); if (a <= 0) continue; // Skip 0x00 bytes, just in case data += (char)a; if (r1 && data.endsWith(r1)) { @@ -695,8 +870,11 @@ private: index = 6; String mode = streamReadUntil(','); if (mode.toInt() == 1) { - mux = streamReadUntil('\n').toInt(); - gotData = true; + int mux = stream.readStringUntil('\n').toInt(); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) { + sockets[mux]->got_data = true; + } + data = ""; } else { data += mode; } @@ -704,10 +882,12 @@ private: index = 7; int nl = data.lastIndexOf(GSM_NL, data.length()-8); int coma = data.indexOf(',', nl+2); - mux = data.substring(nl+2, coma).toInt(); - if (mux) { + int mux = data.substring(nl+2, coma).toInt(); + if (mux >= 0 && mux < TINY_GSM_MUX_COUNT) { sockets[mux]->sock_connected = false; } + data = ""; + DBG("### Closed: ", mux); } } } while (millis() - startMillis < timeout); @@ -718,17 +898,6 @@ private: 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; } @@ -746,11 +915,9 @@ private: return waitResponse(1000, r1, r2, r3, r4, r5); } -private: +protected: Stream& stream; - GsmClient* sockets[5]; + GsmClient* sockets[TINY_GSM_MUX_COUNT]; }; -typedef TinyGsm::GsmClient TinyGsmClient; - #endif diff --git a/TinyGsmClientSIM808.h b/TinyGsmClientSIM808.h new file mode 100644 index 0000000..2b9c49a --- /dev/null +++ b/TinyGsmClientSIM808.h @@ -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 + +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 diff --git a/TinyGsmCommon.h b/TinyGsmCommon.h index 29bd967..832b33e 100644 --- a/TinyGsmCommon.h +++ b/TinyGsmCommon.h @@ -26,6 +26,9 @@ #define TINY_GSM_YIELD() { delay(0); } #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__) #define TINY_GSM_PROGMEM PROGMEM typedef const __FlashStringHelper* GsmConstStr; @@ -69,4 +72,26 @@ const T& TinyGsmMax(const T& a, const T& b) return (b < a) ? a : b; } +template +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 diff --git a/examples/AllFunctions/AllFunctions.ino b/examples/AllFunctions/AllFunctions.ino new file mode 100644 index 0000000..1e28bcb --- /dev/null +++ b/examples/AllFunctions/AllFunctions.ino @@ -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 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 + +#ifdef DUMP_AT_COMMANDS + #include + 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(); + } +} + diff --git a/examples/BlynkClient/BlynkClient.ino b/examples/BlynkClient/BlynkClient.ino index 9672edc..c45dda1 100644 --- a/examples/BlynkClient/BlynkClient.ino +++ b/examples/BlynkClient/BlynkClient.ino @@ -30,12 +30,13 @@ // 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 -// #define TINY_GSM_MODEM_XBEE +// #define TINY_GSM_MODEM_XBEE #include #include @@ -74,6 +75,10 @@ void setup() 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"); diff --git a/examples/FileDownload/FileDownload.ino b/examples/FileDownload/FileDownload.ino index 8fbe75c..bb10ac5 100644 --- a/examples/FileDownload/FileDownload.ino +++ b/examples/FileDownload/FileDownload.ino @@ -1,7 +1,7 @@ /************************************************************** * * 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 * * TinyGSM Getting Started guide: @@ -14,18 +14,19 @@ // 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 -// #define TINY_GSM_MODEM_XBEE +// #define TINY_GSM_MODEM_XBEE // Increase RX buffer #define TINY_GSM_RX_BUFFER 1030 -#include -#include +//#define DUMP_AT_COMMANDS +//#define TINY_GSM_DEBUG Serial // Your GPRS credentials // Leave empty, if missing user or pass @@ -40,12 +41,23 @@ const char pass[] = ""; //#include //SoftwareSerial SerialAT(2, 3); // RX, TX -TinyGsm modem(SerialAT); +#include +#include + +#ifdef DUMP_AT_COMMANDS + #include + StreamDebugger debugger(SerialAT, Serial); + TinyGsm modem(debugger); +#else + TinyGsm modem(SerialAT); +#endif TinyGsmClient client(modem); const char server[] = "cdn.rawgit.com"; -const char resource[] = "/vshymanskyy/tinygsm/master/extras/test_1k.bin"; -uint32_t knownCRC32 = 0x6f50d767; +const int port = 80; + +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 void setup() { @@ -62,6 +74,10 @@ void setup() { 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"); } @@ -99,7 +115,7 @@ void loop() { Serial.print(server); // if you get a connection, report back via serial: - if (!client.connect(server, 80)) { + if (!client.connect(server, port)) { Serial.println(" fail"); delay(10000); return; diff --git a/examples/HttpClient/HttpClient.ino b/examples/HttpClient/HttpClient.ino new file mode 100644 index 0000000..a2c1b73 --- /dev/null +++ b/examples/HttpClient/HttpClient.ino @@ -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 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 +#include + +#ifdef DUMP_AT_COMMANDS + #include + 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); + } +} + diff --git a/examples/HttpsClient/HttpsClient.ino b/examples/HttpsClient/HttpsClient.ino new file mode 100644 index 0000000..b0308ff --- /dev/null +++ b/examples/HttpsClient/HttpsClient.ino @@ -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 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 +#include + +#ifdef DUMP_AT_COMMANDS + #include + 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); + } +} + diff --git a/examples/MqttClient/MqttClient.ino b/examples/MqttClient/MqttClient.ino index a44f5a1..3e1c9aa 100644 --- a/examples/MqttClient/MqttClient.ino +++ b/examples/MqttClient/MqttClient.ino @@ -27,12 +27,13 @@ // 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 -// #define TINY_GSM_MODEM_XBEE +// #define TINY_GSM_MODEM_XBEE #include #include @@ -81,6 +82,10 @@ void setup() { 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"); diff --git a/examples/WebClient/WebClient.ino b/examples/WebClient/WebClient.ino index 87f0bed..6f03426 100644 --- a/examples/WebClient/WebClient.ino +++ b/examples/WebClient/WebClient.ino @@ -10,12 +10,12 @@ // 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 -// #define TINY_GSM_MODEM_XBEE #include @@ -38,7 +38,7 @@ TinyGsmClient client(modem); const char server[] = "cdn.rawgit.com"; const char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt"; -int port = 80; +const int port = 80; void setup() { // Set console baud rate @@ -54,6 +54,10 @@ void setup() { Serial.println(F("Initializing modem...")); modem.restart(); + String modemInfo = modem.getModemInfo(); + Serial.print("Modem: "); + Serial.println(modemInfo); + // Unlock your SIM card with a PIN //modem.simUnlock("1234"); } diff --git a/keywords.txt b/keywords.txt index 5c6cd82..fa2df44 100644 --- a/keywords.txt +++ b/keywords.txt @@ -3,6 +3,7 @@ ####################################### TinyGsm KEYWORD1 TinyGsmClient KEYWORD1 +TinyGsmClientSecure KEYWORD1 SerialAT KEYWORD1 SerialMon KEYWORD1 diff --git a/library.json b/library.json index 6d87889..2572e66 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "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", "keywords": "GSM, AT commands, AT, SIM800, SIM900, A6, A7, M590, ESP8266, SIM800A, SIM800C, SIM800L, SIM800H, SIM808, SIM868, SIM900A, SIM900D, SIM908, SIM968", "authors": diff --git a/library.properties b/library.properties index 526c925..e5bac8a 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=TinyGSM -version=0.1.8 +version=0.3.1 author=Volodymyr Shymanskyy maintainer=Volodymyr Shymanskyy sentence=A small Arduino library for GPRS modules, that just works. diff --git a/tools/AT_Debug/AT_Debug.ino b/tools/AT_Debug/AT_Debug.ino index f13976b..d66b632 100644 --- a/tools/AT_Debug/AT_Debug.ino +++ b/tools/AT_Debug/AT_Debug.ino @@ -10,12 +10,13 @@ // 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 -// #define TINY_GSM_MODEM_XBEE +// #define TINY_GSM_MODEM_XBEE #include @@ -30,7 +31,9 @@ //#include //SoftwareSerial SerialAT(2, 3); // RX, TX -TinyGsm modem(SerialAT); +#define TINY_GSM_DEBUG SerialMon + +#include // Module baud rate uint32_t rate = 0; // Set to 0 for Auto-Detect @@ -44,21 +47,7 @@ void setup() { void loop() { if (!rate) { - static uint32_t rates[] = { 115200, 9600, 57600, 19200, 38400, 74400, 74880, 230400, 460800, 2400, 4800, 14400, 28800 }; - - 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")); - } - } + rate = TinyGsmAutoBaud(SerialAT); } if (!rate) { diff --git a/tools/Diagnostics/Diagnostics.ino b/tools/Diagnostics/Diagnostics.ino index 8a05dbd..fe48c23 100644 --- a/tools/Diagnostics/Diagnostics.ino +++ b/tools/Diagnostics/Diagnostics.ino @@ -11,18 +11,18 @@ // 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 -// #define TINY_GSM_MODEM_XBEE +// #define TINY_GSM_MODEM_XBEE -// Increase buffer fo see less commands -#define TINY_GSM_RX_BUFFER 256 +// Increase the buffer +#define TINY_GSM_RX_BUFFER 512 #include -#include // Your GPRS credentials // Leave empty, if missing user or pass @@ -42,12 +42,13 @@ const char pass[] = ""; //SoftwareSerial SerialAT(2, 3); // RX, TX +#include StreamDebugger debugger(SerialAT, SerialMon); TinyGsm modem(debugger); TinyGsmClient client(modem); 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() { // Set console baud rate @@ -144,9 +145,9 @@ void loop() { SerialMon.println("************************"); SerialMon.print (" Received: "); SerialMon.print(bytesReceived); - SerialMon.println("bytes"); + SerialMon.println(" bytes"); SerialMon.print (" Test: "); - SerialMon.println((bytesReceived == 1000) ? "PASSED" : "FAIL"); + SerialMon.println((bytesReceived == 121) ? "PASSED" : "FAILED"); SerialMon.println("************************"); // Do nothing forevermore diff --git a/tools/FactoryReset/FactoryReset.ino b/tools/FactoryReset/FactoryReset.ino index 8996b81..2cba23b 100644 --- a/tools/FactoryReset/FactoryReset.ino +++ b/tools/FactoryReset/FactoryReset.ino @@ -11,15 +11,15 @@ // 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 -// #define TINY_GSM_MODEM_XBEE +// #define TINY_GSM_MODEM_XBEE #include -#include // Set serial for debug console (to the Serial Monitor, speed 115200) #define SerialMon Serial @@ -32,6 +32,7 @@ //#include //SoftwareSerial SerialAT(2, 3); // RX, TX +#include StreamDebugger debugger(SerialAT, SerialMon); TinyGsm modem(debugger);