mirror of
				https://github.com/KevinMidboe/TinyGSM.git
				synced 2025-10-29 18:00:18 +00:00 
			
		
		
		
	Add source and examples
This commit is contained in:
		
							
								
								
									
										438
									
								
								TinyGsmClient.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										438
									
								
								TinyGsmClient.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,438 @@ | ||||
| /** | ||||
|  * @file       TinyGsmClient.h | ||||
|  * @author     Volodymyr Shymanskyy | ||||
|  * @license    LGPL-3.0 | ||||
|  * @copyright  Copyright (c) 2016 Volodymyr Shymanskyy | ||||
|  * @date       Nov 2016 | ||||
|  */ | ||||
|  | ||||
| #ifndef TinyGsmClient_h | ||||
| #define TinyGsmClient_h | ||||
|  | ||||
| #if defined(SPARK) || defined(PARTICLE) | ||||
|     #include "Particle.h" | ||||
| #elif defined(ARDUINO) | ||||
|     #if ARDUINO >= 100 | ||||
|         #include "Arduino.h" | ||||
|     #else | ||||
|         #include "WProgram.h" | ||||
|     #endif | ||||
| #endif | ||||
|  | ||||
| #include <Client.h> | ||||
| #include <TinyGsmFifo.h> | ||||
|  | ||||
| #if defined(__AVR__) | ||||
|   #define GSM_PROGMEM PROGMEM | ||||
|   typedef const __FlashStringHelper* GsmConstStr; | ||||
|   #define FP(x) (reinterpret_cast<GsmConstStr>(x)) | ||||
| #else | ||||
|   #define GSM_PROGMEM | ||||
|   typedef const char* GsmConstStr; | ||||
|   #define FP(x) x | ||||
|   #undef F | ||||
|   #define F(x) x | ||||
| #endif | ||||
|  | ||||
| //#define GSM_USE_HEX | ||||
| #define GSM_RX_BUFFER 64 | ||||
|  | ||||
| #define GSM_NL "\r\n" | ||||
| static constexpr char GSM_OK[] GSM_PROGMEM = "OK" GSM_NL; | ||||
| static constexpr char GSM_ERROR[] GSM_PROGMEM = "ERROR" GSM_NL; | ||||
|  | ||||
| class TinyGsmClient | ||||
|     : public Client | ||||
| { | ||||
|   typedef TinyGsmFifo<uint8_t, GSM_RX_BUFFER> RxFifo; | ||||
|  | ||||
| #ifdef GSM_DEBUG | ||||
|   template<typename T> | ||||
|   void DBG(T last) { | ||||
|     GSM_DEBUG.println(last); | ||||
|   } | ||||
|  | ||||
|   template<typename T, typename... Args> | ||||
|   void DBG(T head, Args... tail) { | ||||
|     GSM_DEBUG.print(head); | ||||
|     GSM_DEBUG.print(' '); | ||||
|     DBG(tail...); | ||||
|   } | ||||
| #else | ||||
|   #define DBG(...) | ||||
| #endif | ||||
|  | ||||
| public: | ||||
|   TinyGsmClient(Stream& stream, uint8_t mux = 1) | ||||
|     : stream(stream) | ||||
|     , mux(mux) | ||||
|     , sock_available(0) | ||||
|     , sock_connected(false) | ||||
|   {} | ||||
|  | ||||
| public: | ||||
|  | ||||
|   virtual int connect(const char *host, uint16_t port) { | ||||
|     return modemConnect(host, port); | ||||
|   } | ||||
|  | ||||
|   virtual int connect(IPAddress ip, uint16_t port) { | ||||
|     String host; host.reserve(16); | ||||
|     host += ip[0]; | ||||
|     host += "."; | ||||
|     host += ip[1]; | ||||
|     host += "."; | ||||
|     host += ip[2]; | ||||
|     host += "."; | ||||
|     host += ip[3]; | ||||
|     return modemConnect(host.c_str(), port); | ||||
|   } | ||||
|  | ||||
|   virtual void stop() { | ||||
|     sendAT(F("+CIPCLOSE="), mux); | ||||
|     sock_connected = false; | ||||
|     waitResponse(); | ||||
|   } | ||||
|  | ||||
|   virtual size_t write(const uint8_t *buf, size_t size) { | ||||
|     maintain(); | ||||
|     return modemSend(buf, size); | ||||
|   } | ||||
|  | ||||
|   virtual size_t write(uint8_t c) { | ||||
|     return write(&c, 1); | ||||
|   } | ||||
|  | ||||
|   virtual int available() { | ||||
|     maintain(); | ||||
|     size_t res = rx.size(); | ||||
|     if (res > 0) { | ||||
|       return res; | ||||
|     } | ||||
|     return sock_available; | ||||
|   } | ||||
|  | ||||
|   virtual int read(uint8_t *buf, size_t size) { | ||||
|     maintain(); | ||||
|     size_t cnt = 0; | ||||
|     while (cnt < size) { | ||||
|       size_t chunk = min(size-cnt, rx.size()); | ||||
|       if (chunk > 0) { | ||||
|         rx.get(buf, chunk); | ||||
|         buf += chunk; | ||||
|         cnt += chunk; | ||||
|       } else { | ||||
|         modemRead(rx.free()); //TODO: min(rx.free(), sock_available) | ||||
|       } | ||||
|     } | ||||
|     return cnt; | ||||
|   } | ||||
|  | ||||
|   virtual int read() { | ||||
|     uint8_t c; | ||||
|     if (read(&c, 1) == 1) { | ||||
|       return c; | ||||
|     } | ||||
|     return -1; | ||||
|   } | ||||
|  | ||||
|   virtual int peek() { return -1; } //TODO | ||||
|   virtual void flush() { stream.flush(); } | ||||
|  | ||||
|   virtual uint8_t connected() { | ||||
|     maintain(); | ||||
|     return sock_connected; | ||||
|   } | ||||
|   virtual operator bool() { return connected(); } | ||||
|  | ||||
| public: | ||||
|   bool factoryDefault() { | ||||
|     if (!autoBaud()) { | ||||
|       return false; | ||||
|     } | ||||
|     sendAT(F("&FZE0&W"));  // Factory + Reset + Echo Off + Write | ||||
|     waitResponse(); | ||||
|     sendAT(F("+IPR=0"));   // Auto-baud | ||||
|     waitResponse(); | ||||
|     sendAT(F("+IFC=0,0")); // No Flow Control | ||||
|     waitResponse(); | ||||
|     sendAT(F("+ICF=3,3")); // 8 data 0 parity 1 stop | ||||
|     waitResponse(); | ||||
|     sendAT(F("+CSCLK=0")); // Disable Slow Clock | ||||
|     waitResponse(); | ||||
|     sendAT(F("&W"));       // Write configuration | ||||
|     return waitResponse() == 1; | ||||
|   } | ||||
|  | ||||
|   bool restart() { | ||||
|     autoBaud(); | ||||
|     sendAT(F("+CFUN=0")); | ||||
|     if (waitResponse(10000L) != 1) { | ||||
|       return false; | ||||
|     } | ||||
|     sendAT(F("+CFUN=1,1")); | ||||
|     if (waitResponse(10000L) != 1) { | ||||
|       return false; | ||||
|     } | ||||
|     delay(3000); | ||||
|     autoBaud(); | ||||
|  | ||||
|     sendAT(F("E0")); | ||||
|     if (waitResponse() != 1) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     return 1 == waitResponse(60000, F("Ready")); | ||||
|   } | ||||
|  | ||||
|   bool networkConnect(const char* apn, const char* user, const char* pwd) { | ||||
|     autoBaud(); | ||||
|  | ||||
|     // AT+CPIN=pin-code | ||||
|     // AT+CREG? | ||||
|  | ||||
|     networkDisconnect(); | ||||
|  | ||||
|     // AT+CGATT? | ||||
|     // AT+CGATT=1 | ||||
|  | ||||
|     sendAT(F("+CIPMUX=1")); | ||||
|     if (waitResponse() != 1) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     sendAT(F("+CIPQSEND=1")); | ||||
|     if (waitResponse() != 1) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     sendAT(F("+CIPRXGET=1")); | ||||
|     if (waitResponse() != 1) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     sendAT(F("+CSTT=\""), apn, F("\",\""), user, F("\",\""), pwd, F("\"")); | ||||
|     if (waitResponse(60000L) != 1) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     sendAT(F("+CIICR")); | ||||
|     if (waitResponse(60000L) != 1) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     sendAT(F("+CIFSR;E0")); | ||||
|     String data; | ||||
|     if (waitResponse(10000L, data) != 1) { | ||||
|       data.replace(GSM_NL, ""); | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     sendAT(F("+CDNSCFG=\"8.8.8.8\",\"8.8.4.4\"")); | ||||
|     if (waitResponse() != 1) { | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     // AT+CIPSTATUS | ||||
|  | ||||
|     return true; | ||||
|   } | ||||
|  | ||||
|   bool networkDisconnect() { | ||||
|     sendAT(F("+CIPSHUT")); | ||||
|     return waitResponse(60000L) == 1; | ||||
|   } | ||||
|  | ||||
|   bool autoBaud(unsigned long timeout = 10000L) { | ||||
|     for (unsigned long start = millis(); millis() - start < timeout; ) { | ||||
|       sendAT(""); | ||||
|       if (waitResponse() == 1) { | ||||
|           delay(100); | ||||
|           return true; | ||||
|       } | ||||
|       delay(100); | ||||
|     } | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   void maintain() { | ||||
|     while (stream.available()) { | ||||
|       waitResponse(10); | ||||
|     } | ||||
|   } | ||||
|  | ||||
| private: | ||||
|   int modemConnect(const char* host, uint16_t port) { | ||||
|     sendAT(F("+CIPSTART="), mux, ',', F("\"TCP"), F("\",\""), host, F("\","), port); | ||||
|     sock_connected = (1 == waitResponse(75000L, F("CONNECT OK" GSM_NL), F("CONNECT FAIL" GSM_NL), F("ALREADY CONNECT" GSM_NL))); | ||||
|     return sock_connected; | ||||
|   } | ||||
|  | ||||
|   int modemSend(const void* buff, size_t len) { | ||||
|     sendAT(F("+CIPSEND="), mux, ',', len); | ||||
|     if (waitResponse(F(">")) != 1) { | ||||
|       return -1; | ||||
|     } | ||||
|     stream.write((uint8_t*)buff, len); | ||||
|     if (waitResponse(F(GSM_NL "DATA ACCEPT:")) != 1) { | ||||
|       return -1; | ||||
|     } | ||||
|     stream.readStringUntil(','); | ||||
|     String data = stream.readStringUntil('\n'); | ||||
|     return data.toInt(); | ||||
|   } | ||||
|  | ||||
|   size_t modemRead(size_t size) { | ||||
| #ifdef GSM_USE_HEX | ||||
|     sendAT(F("+CIPRXGET=3,"), mux, ',', size); | ||||
|     if (waitResponse(F("+CIPRXGET: 3,")) != 1) { | ||||
|       return 0; | ||||
|     } | ||||
| #else | ||||
|     sendAT(F("+CIPRXGET=2,"), mux, ',', size); | ||||
|     if (waitResponse(F("+CIPRXGET: 2,")) != 1) { | ||||
|       return 0; | ||||
|     } | ||||
| #endif | ||||
|     stream.readStringUntil(','); // Skip mux | ||||
|     size_t len = stream.readStringUntil(',').toInt(); | ||||
|     sock_available = stream.readStringUntil('\n').toInt(); | ||||
|  | ||||
|     for (size_t i=0; i<len; i++) { | ||||
| #ifdef GSM_USE_HEX | ||||
|       while (stream.available() < 2) { delay(1); } | ||||
|       char buf[4] = { 0, }; | ||||
|       buf[0] = stream.read(); | ||||
|       buf[1] = stream.read(); | ||||
|       char c = strtol(buf, NULL, 16); | ||||
| #else | ||||
|       while (stream.available() < 1) { delay(1); } | ||||
|       char c = stream.read(); | ||||
| #endif | ||||
|       rx.put(c); | ||||
|     } | ||||
|     waitResponse(); | ||||
|     return len; | ||||
|   } | ||||
|  | ||||
|   size_t modemGetAvailable() { | ||||
|     sendAT(F("+CIPRXGET=4,"), mux); | ||||
|     size_t result = 0; | ||||
|     for (byte i = 0; i < 2; i++) { | ||||
|       int res = waitResponse(F("+CIPRXGET: 4"), FP(GSM_OK), FP(GSM_ERROR)); | ||||
|       if (res == 1) { | ||||
|         stream.readStringUntil(','); | ||||
|         stream.readStringUntil(','); | ||||
|         result = stream.readStringUntil('\n').toInt(); | ||||
|       } else if (res == 2) { | ||||
|       } else { | ||||
|         return result; | ||||
|       } | ||||
|     } | ||||
|     if (!result) { | ||||
|       sock_connected = modemGetConnected(); | ||||
|     } | ||||
|     return result; | ||||
|   } | ||||
|  | ||||
|   bool modemGetConnected() { | ||||
|     sendAT(F("+CIPSTATUS="), mux); | ||||
|     int res = waitResponse(F(",\"CONNECTED\""), F(",\"CLOSED\""), F(",\"CLOSING\""), F(",\"INITIAL\"")); | ||||
|     waitResponse(); | ||||
|     return 1 == res; | ||||
|   } | ||||
|  | ||||
|   /* Utilities */ | ||||
|   template<typename T> | ||||
|   void streamWrite(T last) { | ||||
|     stream.print(last); | ||||
|   } | ||||
|  | ||||
|   template<typename T, typename... Args> | ||||
|   void streamWrite(T head, Args... tail) { | ||||
|     stream.print(head); | ||||
|     streamWrite(tail...); | ||||
|   } | ||||
|  | ||||
|   int streamRead() { return stream.read(); } | ||||
|   void streamReadAll() { while(stream.available()) { stream.read(); } } | ||||
|  | ||||
|   template<typename... Args> | ||||
|   void sendAT(Args... cmd) { | ||||
|     streamWrite("AT", cmd..., GSM_NL); | ||||
|   } | ||||
|  | ||||
|   // TODO: Optimize this! | ||||
|   uint8_t waitResponse(uint32_t timeout, String& data, | ||||
|                        GsmConstStr r1=FP(GSM_OK), GsmConstStr r2=FP(GSM_ERROR), | ||||
|                        GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL) | ||||
|   { | ||||
|     data.reserve(64); | ||||
|     bool gotNewData = false; | ||||
|     int index = 0; | ||||
|     for (unsigned long start = millis(); millis() - start < timeout; ) { | ||||
|       while (stream.available() > 0) { | ||||
|         int a = streamRead(); | ||||
|         if (a < 0) continue; //? | ||||
|         data += (char)a; | ||||
|         if (data.indexOf(r1) >= 0) { | ||||
|           index = 1; | ||||
|           goto finish; | ||||
|         } else if (r2 && data.indexOf(r2) >= 0) { | ||||
|           index = 2; | ||||
|           goto finish; | ||||
|         } else if (r3 && data.indexOf(r3) >= 0) { | ||||
|           index = 3; | ||||
|           goto finish; | ||||
|         } else if (r4 && data.indexOf(r4) >= 0) { | ||||
|           index = 4; | ||||
|           goto finish; | ||||
|         } else if (r5 && data.indexOf(r5) >= 0) { | ||||
|           index = 5; | ||||
|           goto finish; | ||||
|         } else if (data.indexOf(F(GSM_NL "+CIPRXGET: 1,1" GSM_NL)) >= 0) { //TODO: use mux | ||||
|           gotNewData = true; | ||||
|           data = ""; | ||||
|         } else if (data.indexOf(F(GSM_NL "1, CLOSED" GSM_NL)) >= 0) { //TODO: use mux | ||||
|           sock_connected = false; | ||||
|           data = ""; | ||||
|         } | ||||
|       } | ||||
|     } | ||||
| finish: | ||||
|     if (!index) { | ||||
|       if (data.length()) { | ||||
|         DBG("### Unhandled:", data); | ||||
|       } | ||||
|       data = ""; | ||||
|     } | ||||
|     if (gotNewData) { | ||||
|       sock_available = modemGetAvailable(); | ||||
|     } | ||||
|     return index; | ||||
|   } | ||||
|  | ||||
|   uint8_t waitResponse(uint32_t timeout, | ||||
|                        GsmConstStr r1=FP(GSM_OK), GsmConstStr r2=FP(GSM_ERROR), | ||||
|                        GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL) | ||||
|   { | ||||
|     String data; | ||||
|     return waitResponse(timeout, data, r1, r2, r3, r4, r5); | ||||
|   } | ||||
|  | ||||
|   uint8_t waitResponse(GsmConstStr r1=FP(GSM_OK), GsmConstStr r2=FP(GSM_ERROR), | ||||
|                        GsmConstStr r3=NULL, GsmConstStr r4=NULL, GsmConstStr r5=NULL) | ||||
|   { | ||||
|     return waitResponse(1000, r1, r2, r3, r4, r5); | ||||
|   } | ||||
|  | ||||
| private: | ||||
|   Stream&       stream; | ||||
|   const uint8_t mux; | ||||
|  | ||||
|   RxFifo        rx; | ||||
|   uint16_t      sock_available; | ||||
|   bool          sock_connected; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										136
									
								
								TinyGsmFifo.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								TinyGsmFifo.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| #ifndef TinyGsmFifo_h | ||||
| #define TinyGsmFifo_h | ||||
|  | ||||
| template <class T, unsigned N> | ||||
| class TinyGsmFifo | ||||
| { | ||||
| public: | ||||
|     TinyGsmFifo() | ||||
|     { | ||||
|         clear(); | ||||
|     } | ||||
|  | ||||
|     void clear() | ||||
|     { | ||||
|         _r = 0; | ||||
|         _w = 0; | ||||
|     } | ||||
|  | ||||
|     // writing thread/context API | ||||
|     //------------------------------------------------------------- | ||||
|  | ||||
|     bool writeable(void) | ||||
|     { | ||||
|         return free() > 0; | ||||
|     } | ||||
|  | ||||
|     int free(void) | ||||
|     { | ||||
|         int s = _r - _w; | ||||
|         if (s <= 0) | ||||
|             s += N; | ||||
|         return s - 1; | ||||
|     } | ||||
|  | ||||
|     T put(const T& c) | ||||
|     { | ||||
|         int i = _w; | ||||
|         int j = i; | ||||
|         i = _inc(i); | ||||
|         while (i == _r) // = !writeable() | ||||
|             /* nothing / just wait */; | ||||
|         _b[j] = c; | ||||
|         _w = i; | ||||
|         return c; | ||||
|     } | ||||
|  | ||||
|     int put(const T* p, int n, bool t = false) | ||||
|     { | ||||
|         int c = n; | ||||
|         while (c) | ||||
|         { | ||||
|             int f; | ||||
|             while ((f = free()) == 0) // wait for space | ||||
|             { | ||||
|                 if (!t) return n - c; // no more space and not blocking | ||||
|                 /* nothing / just wait */; | ||||
|             } | ||||
|             // check free space | ||||
|             if (c < f) f = c; | ||||
|             int w = _w; | ||||
|             int m = N - w; | ||||
|             // check wrap | ||||
|             if (f > m) f = m; | ||||
|             memcpy(&_b[w], p, f); | ||||
|             _w = _inc(w, f); | ||||
|             c -= f; | ||||
|             p += f; | ||||
|         } | ||||
|         return n - c; | ||||
|     } | ||||
|  | ||||
|     // reading thread/context API | ||||
|     // -------------------------------------------------------- | ||||
|  | ||||
|     bool readable(void) | ||||
|     { | ||||
|         return (_r != _w); | ||||
|     } | ||||
|  | ||||
|     size_t size(void) | ||||
|     { | ||||
|         int s = _w - _r; | ||||
|         if (s < 0) | ||||
|             s += N; | ||||
|         return s; | ||||
|     } | ||||
|  | ||||
|     T get(void) | ||||
|     { | ||||
|         int r = _r; | ||||
|         while (r == _w) // = !readable() | ||||
|             /* nothing / just wait */; | ||||
|         T t = _b[r]; | ||||
|         _r = _inc(r); | ||||
|         return t; | ||||
|     } | ||||
|  | ||||
|     int get(T* p, int n, bool t = false) | ||||
|     { | ||||
|         int c = n; | ||||
|         while (c) | ||||
|         { | ||||
|             int f; | ||||
|             for (;;) // wait for data | ||||
|             { | ||||
|                 f = size(); | ||||
|                 if (f)  break;        // free space | ||||
|                 if (!t) return n - c; // no space and not blocking | ||||
|                 /* nothing / just wait */; | ||||
|             } | ||||
|             // check available data | ||||
|             if (c < f) f = c; | ||||
|             int r = _r; | ||||
|             int m = N - r; | ||||
|             // check wrap | ||||
|             if (f > m) f = m; | ||||
|             memcpy(p, &_b[r], f); | ||||
|             _r = _inc(r, f); | ||||
|             c -= f; | ||||
|             p += f; | ||||
|         } | ||||
|         return n - c; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     int _inc(int i, int n = 1) | ||||
|     { | ||||
|         return (i + n) % N; | ||||
|     } | ||||
|  | ||||
|     T    _b[N]; | ||||
|     int  _w; | ||||
|     int  _r; | ||||
| }; | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										75
									
								
								examples/BlynkClient/BlynkClient.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								examples/BlynkClient/BlynkClient.ino
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,75 @@ | ||||
| /************************************************************** | ||||
|  * | ||||
|  * For this example, you need to install Blynk library: | ||||
|  *   https://github.com/blynkkk/blynk-library/releases/latest | ||||
|  * | ||||
|  * TinyGSM Getting Started guide: | ||||
|  *   http://tiny.cc/tiny-gsm-readme | ||||
|  * | ||||
|  ************************************************************** | ||||
|  * | ||||
|  * Blynk is a platform with iOS and Android apps to control | ||||
|  * Arduino, Raspberry Pi and the likes over the Internet. | ||||
|  * You can easily build graphic interfaces for all your | ||||
|  * projects by simply dragging and dropping widgets. | ||||
|  * | ||||
|  * Blynk supports many development boards with WiFi, Ethernet, | ||||
|  * GSM, Bluetooth, BLE, USB/Serial connection methods. | ||||
|  * See more in Blynk library examples and community forum. | ||||
|  * | ||||
|  *                http://www.blynk.io/ | ||||
|  * | ||||
|  * Change GPRS apm, user, pass, and Blynk auth token to run :) | ||||
|  **************************************************************/ | ||||
|  | ||||
| #define BLYNK_PRINT Serial    // Comment this out to disable prints and save space | ||||
|  | ||||
| // Default heartbeat interval for GSM is 60 | ||||
| // If you want override this value, uncomment and set this option: | ||||
| //#define BLYNK_HEARTBEAT 30 | ||||
|  | ||||
| #include <TinyGsmClient.h> | ||||
| #include <BlynkSimpleSIM800.h> | ||||
|  | ||||
| // You should get Auth Token in the Blynk App. | ||||
| // Go to the Project Settings (nut icon). | ||||
| char auth[] = "YourAuthToken"; | ||||
|  | ||||
| // Your GPRS credentials | ||||
| // Leave empty, if missing user or pass | ||||
| char apn[]  = "YourAPN"; | ||||
| char user[] = ""; | ||||
| char pass[] = ""; | ||||
|  | ||||
| // Hardware Serial on Mega, Leonardo, Micro | ||||
| #define GsmSerial Serial1 | ||||
|  | ||||
| // or Software Serial on Uno, Nano | ||||
| //#include <SoftwareSerial.h> | ||||
| //SoftwareSerial GsmSerial(2, 3); // RX, TX | ||||
|  | ||||
| TinyGsmClient gsm(GsmSerial); | ||||
|  | ||||
| void setup() | ||||
| { | ||||
|   // Set console baud rate | ||||
|   Serial.begin(115200); | ||||
|   delay(10); | ||||
|  | ||||
|   // Set GSM module baud rate | ||||
|   GsmSerial.begin(115200); | ||||
|   delay(3000); | ||||
|  | ||||
|   // Restart takes quite some time | ||||
|   // You can skip it in many cases | ||||
|   Serial.println("Restarting modem..."); | ||||
|   gsm.restart(); | ||||
|  | ||||
|   Blynk.begin(auth, gsm, apn, user, pass); | ||||
| } | ||||
|  | ||||
| void loop() | ||||
| { | ||||
|   Blynk.run(); | ||||
| } | ||||
|  | ||||
							
								
								
									
										153
									
								
								examples/FileDownload/FileDownload.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								examples/FileDownload/FileDownload.ino
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | ||||
| /************************************************************** | ||||
|  * | ||||
|  * For this example, you need to install CRC32 library: | ||||
|  *   https://github.com/vshymanskyy/CRC32.git | ||||
|  * | ||||
|  * TinyGSM Getting Started guide: | ||||
|  *   http://tiny.cc/tiny-gsm-readme | ||||
|  * | ||||
|  **************************************************************/ | ||||
|  | ||||
| #include <TinyGsmClient.h> | ||||
| #include <CRC32.h> | ||||
|  | ||||
| // Your GPRS credentials | ||||
| // Leave empty, if missing user or pass | ||||
| char apn[]  = "YourAPN"; | ||||
| char user[] = ""; | ||||
| char pass[] = ""; | ||||
|  | ||||
| // Use Hardware Serial on Mega, Leonardo, Micro | ||||
| #define GsmSerial Serial1 | ||||
|  | ||||
| // or Software Serial on Uno, Nano | ||||
| //#include <SoftwareSerial.h> | ||||
| //SoftwareSerial GsmSerial(2, 3); // RX, TX | ||||
|  | ||||
| TinyGsmClient client(GsmSerial); | ||||
|  | ||||
| char server[] = "cdn.rawgit.com"; | ||||
| char resource[] = "/vshymanskyy/tinygsm/master/extras/test_10k.hex"; | ||||
| uint32_t knownCRC32 = 0x54b3dcbf; | ||||
| uint32_t knownFileSize = 10240;   // In case server does not send it | ||||
|  | ||||
| void setup() { | ||||
|   // Set console baud rate | ||||
|   Serial.begin(115200); | ||||
|   delay(10); | ||||
|  | ||||
|   // Set GSM module baud rate | ||||
|   GsmSerial.begin(115200); | ||||
|   delay(3000); | ||||
|  | ||||
|   // Restart takes quite some time | ||||
|   // You can skip it in many cases | ||||
|   Serial.println("Restarting modem..."); | ||||
|   client.restart(); | ||||
| } | ||||
|  | ||||
| void printPercent(uint32_t readLength, uint32_t contentLength) { | ||||
|   // If we know the total length | ||||
|   if (contentLength != -1) { | ||||
|     Serial.print(String("\r ") + ((100.0 * readLength) / contentLength) + "%"); | ||||
|   } else { | ||||
|     Serial.println(readLength); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void loop() { | ||||
|   Serial.print("Connecting to "); | ||||
|   Serial.print(apn); | ||||
|   if (!client.networkConnect(apn, user, pass)) { | ||||
|     Serial.println(" failed"); | ||||
|     delay(10000); | ||||
|     return; | ||||
|   } | ||||
|   Serial.println(" OK"); | ||||
|  | ||||
|   Serial.print("Connecting to "); | ||||
|   Serial.print(server); | ||||
|  | ||||
|   // if you get a connection, report back via serial: | ||||
|   if (!client.connect(server, 80)) { | ||||
|     Serial.println(" failed"); | ||||
|     delay(10000); | ||||
|     return; | ||||
|   } | ||||
|   Serial.println(" OK"); | ||||
|   // Make a HTTP request: | ||||
|   client.print(String("GET ") + resource + " HTTP/1.0\r\n"); | ||||
|   client.print(String("Host: ") + server + "\r\n"); | ||||
|   client.print("Connection: close\r\n\r\n"); | ||||
|  | ||||
|   long timeout = millis(); | ||||
|   while (client.available() == 0) { | ||||
|     if (millis() - timeout > 5000L) { | ||||
|       Serial.println(">>> Client Timeout !"); | ||||
|       client.stop(); | ||||
|       delay(10000L); | ||||
|       return; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Serial.println("Reading response header"); | ||||
|   uint32_t contentLength = knownFileSize; | ||||
|  | ||||
|   while (client.available()) { | ||||
|     String line = client.readStringUntil('\n'); | ||||
|     line.trim(); | ||||
|     //Serial.println(line);    // Uncomment this to show response header | ||||
|     line.toLowerCase(); | ||||
|     if (line.startsWith("content-length:")) { | ||||
|       contentLength = line.substring(line.lastIndexOf(':') + 1).toInt();   | ||||
|     } else if (line.length() == 0) { | ||||
|       break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Serial.println("Reading response data"); | ||||
|   timeout = millis(); | ||||
|   uint32_t readLength = 0; | ||||
|   CRC32 crc; | ||||
|  | ||||
|   unsigned long timeElapsed = millis(); | ||||
|   printPercent(readLength, contentLength); | ||||
|   while (readLength < contentLength && client.connected() && millis() - timeout < 10000L) { | ||||
|     while (client.available()) { | ||||
|       uint8_t c = client.read(); | ||||
|       //Serial.print((char)c);       // Uncomment this to show data | ||||
|       crc.update(c); | ||||
|       readLength++; | ||||
|       if (readLength % (contentLength / 13) == 0) { | ||||
|         printPercent(readLength, contentLength); | ||||
|       } | ||||
|       timeout = millis(); | ||||
|     } | ||||
|   } | ||||
|   printPercent(readLength, contentLength); | ||||
|   timeElapsed = millis() - timeElapsed; | ||||
|   Serial.println(); | ||||
|  | ||||
|   client.stop(); | ||||
|   Serial.println("Server disconnected"); | ||||
|  | ||||
|   client.networkDisconnect(); | ||||
|   Serial.println("GPRS disconnected"); | ||||
|   Serial.println(); | ||||
|  | ||||
|   float timeSpent = float(timeElapsed) / 1000; | ||||
|   float theorLimit = ((8.0 * readLength) / 85.6) / 1000; | ||||
|  | ||||
|   Serial.print("Content-Length: ");   Serial.println(contentLength); | ||||
|   Serial.print("Actually read:  ");   Serial.println(readLength); | ||||
|   Serial.print("Calc. CRC32:    0x"); Serial.println(crc.finalize(), HEX); | ||||
|   Serial.print("Known CRC32:    0x"); Serial.println(knownCRC32, HEX); | ||||
|   Serial.print("Time spent:     ");   Serial.print(timeSpent); Serial.println("s"); | ||||
|   Serial.print("85.6kBps limit: ");   Serial.print(theorLimit); Serial.println("s"); | ||||
|  | ||||
|   // Do nothing forevermore | ||||
|   while (true) { | ||||
|     delay(1000); | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										130
									
								
								examples/MqttClient/MqttClient.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								examples/MqttClient/MqttClient.ino
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,130 @@ | ||||
| /************************************************************** | ||||
|  * | ||||
|  * For this example, you need to install PubSubClient library: | ||||
|  *   https://github.com/knolleary/pubsubclient/releases/latest | ||||
|  * | ||||
|  * TinyGSM Getting Started guide: | ||||
|  *   http://tiny.cc/tiny-gsm-readme | ||||
|  * | ||||
|  ************************************************************** | ||||
|  * Use Mosquitto client tools to work with MQTT | ||||
|  *   Ubuntu/Linux: sudo apt-get install mosquitto-clients | ||||
|  *   Windows:      https://mosquitto.org/download/ | ||||
|  * | ||||
|  * Subscribe for messages: | ||||
|  *   mosquitto_sub -h test.mosquitto.org -t GsmClientTest/init -t GsmClientTest/ledStatus -q 1 | ||||
|  * Toggle led: | ||||
|  *   mosquitto_pub -h test.mosquitto.org -t GsmClientTest/led -q 1 -m "toggle" | ||||
|  * | ||||
|  * You can use Node-RED for wiring together MQTT-enabled devices | ||||
|  *   https://nodered.org/ | ||||
|  * Also, take a look at these additional Node-RED modules: | ||||
|  *   node-red-contrib-blynk-websockets | ||||
|  *   node-red-dashboard | ||||
|  * | ||||
|  **************************************************************/ | ||||
|  | ||||
| #include <TinyGsmClient.h> | ||||
| #include <PubSubClient.h> | ||||
|  | ||||
| // Your GPRS credentials | ||||
| // Leave empty, if missing user or pass | ||||
| char apn[]  = "YourAPN"; | ||||
| char user[] = ""; | ||||
| char pass[] = ""; | ||||
|  | ||||
| // Use Hardware Serial on Mega, Leonardo, Micro | ||||
| #define GsmSerial Serial1 | ||||
|  | ||||
| // or Software Serial on Uno, Nano | ||||
| //#include <SoftwareSerial.h> | ||||
| //SoftwareSerial GsmSerial(2, 3); // RX, TX | ||||
|  | ||||
| TinyGsmClient gsm(GsmSerial); | ||||
| PubSubClient mqtt(gsm); | ||||
|  | ||||
| const char* broker = "test.mosquitto.org"; | ||||
|  | ||||
| const char* topicLed = "GsmClientTest/led"; | ||||
| const char* topicInit = "GsmClientTest/init"; | ||||
| const char* topicLedStatus = "GsmClientTest/ledStatus"; | ||||
|  | ||||
| #define LED_PIN 13 | ||||
| int ledStatus = LOW; | ||||
|  | ||||
| long lastReconnectAttempt = 0; | ||||
|  | ||||
| void setup() { | ||||
|   pinMode(LED_PIN, OUTPUT); | ||||
|  | ||||
|   // Set console baud rate | ||||
|   Serial.begin(115200); | ||||
|   delay(10); | ||||
|  | ||||
|   // Set GSM module baud rate | ||||
|   GsmSerial.begin(115200); | ||||
|   delay(3000); | ||||
|  | ||||
|   // Restart takes quite some time | ||||
|   // You can skip it in many cases | ||||
|   Serial.println("Restarting modem..."); | ||||
|   gsm.restart(); | ||||
|  | ||||
|   Serial.print("Connecting to "); | ||||
|   Serial.print(apn); | ||||
|   if (!gsm.networkConnect(apn, user, pass)) { | ||||
|     Serial.println(" failed"); | ||||
|     while (true); | ||||
|   } | ||||
|   Serial.println(" OK"); | ||||
|  | ||||
|   // MQTT Broker setup | ||||
|   mqtt.setServer(broker, 1883); | ||||
|   mqtt.setCallback(mqttCallback); | ||||
| } | ||||
|  | ||||
| boolean mqttConnect() { | ||||
|   Serial.print("Connecting to "); | ||||
|   Serial.print(broker); | ||||
|   if (!mqtt.connect("GsmClientTest")) { | ||||
|     Serial.println(" failed"); | ||||
|     return false; | ||||
|   } | ||||
|   Serial.println(" OK"); | ||||
|   mqtt.publish(topicInit, "GsmClientTest started"); | ||||
|   mqtt.subscribe(topicLed); | ||||
|   return mqtt.connected(); | ||||
| } | ||||
|  | ||||
| void loop() { | ||||
|  | ||||
|   if (mqtt.connected()) { | ||||
|     mqtt.loop(); | ||||
|   } else { | ||||
|     // Reconnect every 10 seconds | ||||
|     unsigned long t = millis(); | ||||
|     if (t - lastReconnectAttempt > 10000L) { | ||||
|       lastReconnectAttempt = t; | ||||
|       if (mqttConnect()) { | ||||
|         lastReconnectAttempt = 0; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
| void mqttCallback(char* topic, byte* payload, unsigned int len) { | ||||
|   Serial.print("Message arrived ["); | ||||
|   Serial.print(topic); | ||||
|   Serial.print("]: "); | ||||
|   Serial.write(payload, len); | ||||
|   Serial.println(); | ||||
|  | ||||
|   // Only proceed if incoming message's topic matches | ||||
|   if (String(topic) == topicLed) { | ||||
|     ledStatus = !ledStatus; | ||||
|     digitalWrite(LED_PIN, ledStatus); | ||||
|     mqtt.publish(topicLedStatus, ledStatus ? "1" : "0"); | ||||
|   } | ||||
| } | ||||
|  | ||||
							
								
								
									
										92
									
								
								examples/WebClient/WebClient.ino
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								examples/WebClient/WebClient.ino
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| /************************************************************** | ||||
|  * | ||||
|  * This sketch connects to a website and downloads a page. | ||||
|  * It can be used to perform HTTP/RESTful API calls. | ||||
|  * | ||||
|  * TinyGSM Getting Started guide: | ||||
|  *   http://tiny.cc/tiny-gsm-readme | ||||
|  * | ||||
|  **************************************************************/ | ||||
|  | ||||
| #include <TinyGsmClient.h> | ||||
|  | ||||
| // Your GPRS credentials | ||||
| // Leave empty, if missing user or pass | ||||
| char apn[]  = "YourAPN"; | ||||
| char user[] = ""; | ||||
| char pass[] = ""; | ||||
|  | ||||
| // Use Hardware Serial on Mega, Leonardo, Micro | ||||
| #define GsmSerial Serial1 | ||||
|  | ||||
| // or Software Serial on Uno, Nano | ||||
| //#include <SoftwareSerial.h> | ||||
| //SoftwareSerial GsmSerial(2, 3); // RX, TX | ||||
|  | ||||
| TinyGsmClient client(GsmSerial); | ||||
|  | ||||
| char server[] = "cdn.rawgit.com"; | ||||
| char resource[] = "/vshymanskyy/tinygsm/master/extras/logo.txt"; | ||||
|  | ||||
| void setup() { | ||||
|   // Set console baud rate | ||||
|   Serial.begin(115200); | ||||
|   delay(10); | ||||
|  | ||||
|   // Set GSM module baud rate | ||||
|   GsmSerial.begin(115200); | ||||
|   delay(3000); | ||||
|  | ||||
|   // Restart takes quite some time | ||||
|   // You can skip it in many cases | ||||
|   Serial.println("Restarting modem..."); | ||||
|   client.restart(); | ||||
| } | ||||
|  | ||||
| void loop() { | ||||
|   Serial.print("Connecting to "); | ||||
|   Serial.print(apn); | ||||
|   if (!client.networkConnect(apn, user, pass)) { | ||||
|     Serial.println(" failed"); | ||||
|     delay(10000); | ||||
|     return; | ||||
|   } | ||||
|   Serial.println(" OK"); | ||||
|  | ||||
|   Serial.print("Connecting to "); | ||||
|   Serial.print(server); | ||||
|   if (!client.connect(server, 80)) { | ||||
|     Serial.println(" failed"); | ||||
|     delay(10000); | ||||
|     return; | ||||
|   } | ||||
|   Serial.println(" OK"); | ||||
|  | ||||
|   // Make a HTTP GET request: | ||||
|   client.print(String("GET ") + resource + " HTTP/1.0\r\n"); | ||||
|   client.print(String("Host: ") + server + "\r\n"); | ||||
|   client.print("Connection: close\r\n\r\n"); | ||||
|  | ||||
|   unsigned long timeout = millis(); | ||||
|   while (client.connected() && millis() - timeout < 10000L) { | ||||
|     // Print available data | ||||
|     while (client.available()) { | ||||
|       char c = client.read(); | ||||
|       Serial.print(c); | ||||
|       timeout = millis(); | ||||
|     } | ||||
|   } | ||||
|   Serial.println(); | ||||
|  | ||||
|   client.stop(); | ||||
|   Serial.println("Server disconnected"); | ||||
|  | ||||
|   client.networkDisconnect(); | ||||
|   Serial.println("GPRS disconnected"); | ||||
|  | ||||
|   // Do nothing forevermore | ||||
|   while (true) { | ||||
|     delay(1000); | ||||
|   } | ||||
| } | ||||
|  | ||||
		Reference in New Issue
	
	Block a user