Browse Source

Merge pull request #98 from EnviroDIY/master

XBee updates, other tweeks
v_master
Volodymyr Shymanskyy 7 years ago
committed by GitHub
parent
commit
11d068d529
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 962 additions and 834 deletions
  1. BIN
      extras/doc/Digi XBee LTEC1 Users Guide - 90001525.pdf
  2. BIN
      extras/doc/Digi XBee S6B Users Guide - 90002180.pdf
  3. BIN
      extras/doc/ESP8266 - AT Instruction Set v2.1.0.pdf
  4. BIN
      extras/doc/ESP8266 - AT Instruction Set.pdf
  5. BIN
      extras/doc/ESP8266 - Datasheet v4.3.pdf
  6. BIN
      extras/doc/ESP8266 - Low Power Solutions.pdf
  7. BIN
      extras/doc/SIM800 - AT Commands v1.10.pdf
  8. BIN
      extras/doc/SIM900 AT Commands v1.11.pdf
  9. BIN
      extras/doc/Telit_LE866_AT_Commands_Reference_Guide_r5.pdf
  10. BIN
      extras/doc/UBlox SARA-R4 AT Commands Manual (UBX-17003787).pdf
  11. BIN
      extras/doc/WNC M14A2A AT&T Commands Guide v1.7.pdf
  12. BIN
      extras/doc/u-blox-CEL_ATCommands_(UBX-13002752).pdf
  13. +1
    -1
      library.json
  14. +0
    -0
      src/TinyGsmClient.h
  15. +756
    -756
      src/TinyGsmClientA6.h
  16. +54
    -28
      src/TinyGsmClientESP8266.h
  17. +3
    -3
      src/TinyGsmClientM590.h
  18. +21
    -10
      src/TinyGsmClientSIM800.h
  19. +0
    -0
      src/TinyGsmClientSIM808.h
  20. +1
    -1
      src/TinyGsmClientU201.h
  21. +81
    -35
      src/TinyGsmClientXBee.h
  22. +0
    -0
      src/TinyGsmCommon.h
  23. +0
    -0
      src/TinyGsmFifo.h
  24. +45
    -0
      tools/AT_Spy/AT_Spy.ino

BIN
extras/doc/Digi XBee LTEC1 Users Guide - 90001525.pdf View File


BIN
extras/doc/Digi XBee S6B Users Guide - 90002180.pdf View File


BIN
extras/doc/ESP8266 - AT Instruction Set v2.1.0.pdf View File


BIN
extras/doc/ESP8266 - AT Instruction Set.pdf View File


BIN
extras/doc/ESP8266 - Datasheet v4.3.pdf View File


BIN
extras/doc/ESP8266 - Low Power Solutions.pdf View File


BIN
extras/doc/SIM800 - AT Commands v1.10.pdf View File


BIN
extras/doc/SIM900 AT Commands v1.11.pdf View File


BIN
extras/doc/Telit_LE866_AT_Commands_Reference_Guide_r5.pdf View File


BIN
extras/doc/UBlox SARA-R4 AT Commands Manual (UBX-17003787).pdf View File


BIN
extras/doc/WNC M14A2A AT&T Commands Guide v1.7.pdf View File


BIN
extras/doc/u-blox-CEL_ATCommands_(UBX-13002752).pdf View File


+ 1
- 1
library.json View File

@ -16,7 +16,7 @@
},
"homepage": "https://github.com/vshymanskyy/TinyGSM",
"export": {
"exclude": [ "extras", "tools" ]
"exclude": [ "extras/*", "tools/*" ]
},
"frameworks": [ "arduino", "energia", "wiringpi" ],
"platforms": "*",


TinyGsmClient.h → src/TinyGsmClient.h View File


src/TinyGsmClientA6.h
File diff suppressed because it is too large
View File


TinyGsmClientESP8266.h → src/TinyGsmClientESP8266.h View File

@ -12,7 +12,7 @@
//#define TINY_GSM_DEBUG Serial
#if !defined(TINY_GSM_RX_BUFFER)
#define TINY_GSM_RX_BUFFER 256
#define TINY_GSM_RX_BUFFER 512
#endif
#define TINY_GSM_MUX_COUNT 5
@ -108,7 +108,7 @@ public:
continue;
}
// TODO: Read directly into user buffer?
if (!rx.size()) {
if (!rx.size() && sock_connected) {
at->maintain();
//break;
}
@ -185,7 +185,7 @@ public:
if (!testAT()) {
return false;
}
sendAT(GF("E0"));
sendAT(GF("E0")); // Echo Off
if (waitResponse() != 1) {
return false;
}
@ -209,9 +209,7 @@ public:
}
void maintain() {
//while (stream.available()) {
waitResponse(10, NULL, NULL);
//}
}
bool factoryDefault() {
@ -270,13 +268,25 @@ public:
streamSkipUntil(','); // Skip BSSID/MAC address
streamSkipUntil(','); // Skip Chanel number
int res2 = stream.parseInt(); // Read RSSI
DBG(res2);
waitResponse();
waitResponse(); // Returns an OK after the value
return res2;
}
bool isNetworkConnected() {
return true; // TODO
sendAT(GF("+CIPSTATUS"));
int res1 = waitResponse(3000, GF("STATUS:"));
int res2 = 0;
if (res1 == 1) {
res2 = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5"));
}
// <stat> status of ESP8266 station interface
// 2 : ESP8266 station connected to an AP and has obtained IP
// 3 : ESP8266 station created a TCP or UDP transmission
// 4 : the TCP or UDP transmission of ESP8266 station disconnected (but AP is connected)
// 5 : ESP8266 station did NOT connect to an AP
waitResponse(); // Returns an OK after the status
if (res2 == 2 || res2 == 3 || res2 == 4) return true;
else return false;
}
bool waitForNetwork(unsigned long timeout = 60000L) {
@ -285,14 +295,12 @@ public:
int res1 = waitResponse(3000, GF("busy p..."), GF("STATUS:"));
if (res1 == 2) {
int res2 = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5"));
if (res2 == 2 || res2 == 3 || res2 == 4) return true;
}
// <stat> status of ESP8266 station interface
// 2 : ESP8266 station connected to an AP and has obtained IP
// 3 : ESP8266 station created a TCP or UDP transmission
// 4 : the TCP or UDP transmission of ESP8266 station disconnected (but AP is connected)
// 5 : ESP8266 station did NOT connect to an AP
delay(1000);
if (res2 == 2 || res2 == 3 || res2 == 4) {
waitResponse();
return true;
}
}
delay(250);
}
return false;
}
@ -322,7 +330,9 @@ public:
bool networkDisconnect() {
sendAT(GF("+CWQAP"));
return waitResponse(10000L) == 1;
bool retVal = waitResponse(10000L) == 1;
waitResponse(GF("WIFI DISCONNECT"));
return retVal;
}
String getLocalIP() {
@ -332,7 +342,6 @@ public:
return "";
}
String res2 = stream.readStringUntil('"');
DBG(res2);
waitResponse();
return res2;
}
@ -349,11 +358,12 @@ protected:
waitResponse();
}
sendAT(GF("+CIPSTART="), mux, ',', ssl ? GF("\"SSL") : GF("\"TCP"), GF("\",\""), host, GF("\","), port, GF(","), TINY_GSM_TCP_KEEP_ALIVE);
// TODO: Check mux
int rsp = waitResponse(75000L,
GFP(GSM_OK),
GFP(GSM_ERROR),
GF(GSM_NL "ALREADY CONNECT" GSM_NL));
waitResponse(100, GF("1,CONNECT")); // TODO
GF("ALREADY CONNECT"));
// if (rsp == 3) waitResponse(); // May return "ERROR" after the "ALREADY CONNECT"
return (1 == rsp);
}
@ -364,7 +374,7 @@ protected:
}
stream.write((uint8_t*)buff, len);
stream.flush();
if (waitResponse(GF(GSM_NL "SEND OK" GSM_NL)) != 1) {
if (waitResponse(10000L, GF(GSM_NL "SEND OK" GSM_NL)) != 1) {
return -1;
}
return len;
@ -372,9 +382,19 @@ protected:
bool modemGetConnected(uint8_t mux) {
sendAT(GF("+CIPSTATUS="), mux);
int res = waitResponse(GF(",\"CONNECTED\""), GF(",\"CLOSED\""), GF(",\"CLOSING\""), GF(",\"INITIAL\""));
waitResponse();
return 1 == res;
int res1 = waitResponse(3000, GF("STATUS:"));
int res2;
if (res1 == 1) {
res2 = waitResponse(GFP(GSM_ERROR), GF("2"), GF("3"), GF("4"), GF("5"));
}
// <stat> status of ESP8266 station interface
// 2 : ESP8266 station connected to an AP and has obtained IP
// 3 : ESP8266 station created a TCP or UDP transmission
// 4 : the TCP or UDP transmission of ESP8266 station disconnected (but AP is connected)
// 5 : ESP8266 station did NOT connect to an AP
waitResponse(); // Returns an OK after the status
if (res2 == 2 || res2 == 3 || res2 == 4) return true;
else return false;
}
public:
@ -458,12 +478,18 @@ public:
sockets[mux]->rx.put(stream.read());
}
if (len_orig > sockets[mux]->available()) { // TODO
DBG(GSM_NL, "### Fewer characters received than expected: ", sockets[mux]->available(), " vs ", len_orig);
DBG("### Fewer characters received than expected: ", sockets[mux]->available(), " vs ", len_orig);
}
data = "";
} else if (data.endsWith(GF("CLOSED"))) {
int muxStart = max(0,data.lastIndexOf(GSM_NL, data.length()-8));
int coma = data.indexOf(',', muxStart);
int mux = data.substring(muxStart, coma).toInt();
if (mux >= 0 && mux < TINY_GSM_MUX_COUNT && sockets[mux]) {
sockets[mux]->sock_connected = false;
}
data = "";
return index;
} else if (data.endsWith(GF(GSM_NL "1,CLOSED" GSM_NL))) { //TODO: use mux
sockets[1]->sock_connected = false;
DBG("### Closed: ", mux);
}
}
} while (millis() - startMillis < timeout);

TinyGsmClientM590.h → src/TinyGsmClientM590.h View File

@ -123,7 +123,7 @@ public:
continue;
}
// TODO: Read directly into user buffer?
if (!rx.size()) {
if (!rx.size() && sock_connected) {
at->maintain();
//break;
}
@ -367,7 +367,7 @@ public:
if (isNetworkConnected()) {
return true;
}
delay(500);
delay(250);
}
return false;
}
@ -655,7 +655,7 @@ public:
sockets[mux]->rx.put(stream.read());
}
if (len_orig > sockets[mux]->available()) { // TODO
DBG(GSM_NL, "### Fewer characters received than expected: ", sockets[mux]->available(), " vs ", len_orig);
DBG("### Fewer characters received than expected: ", sockets[mux]->available(), " vs ", len_orig);
}
data = "";
} else if (data.endsWith(GF("+TCPCLOSE:"))) {

TinyGsmClientSIM800.h → src/TinyGsmClientSIM800.h View File

@ -126,7 +126,7 @@ public:
TINY_GSM_YIELD();
at->maintain();
size_t cnt = 0;
while (cnt < size) {
while (cnt < size && sock_connected) {
size_t chunk = TinyGsmMin(size-cnt, rx.size());
if (chunk > 0) {
rx.get(buf, chunk);
@ -432,7 +432,7 @@ public:
if (isNetworkConnected()) {
return true;
}
delay(500);
delay(250);
}
return false;
}
@ -443,71 +443,82 @@ public:
bool gprsConnect(const char* apn, const char* user, const char* pwd) {
gprsDisconnect();
sendAT(GF("+SAPBR=3,1,\"Contype\",\"GPRS\""));
// Set the Bearer for the IP
sendAT(GF("+SAPBR=3,1,\"Contype\",\"GPRS\"")); // Set the connection type to GPRS
waitResponse();
sendAT(GF("+SAPBR=3,1,\"APN\",\""), apn, '"');
sendAT(GF("+SAPBR=3,1,\"APN\",\""), apn, '"'); // Set the APN
waitResponse();
if (user && strlen(user) > 0) {
sendAT(GF("+SAPBR=3,1,\"USER\",\""), user, '"');
sendAT(GF("+SAPBR=3,1,\"USER\",\""), user, '"'); // Set the user name
waitResponse();
}
if (pwd && strlen(pwd) > 0) {
sendAT(GF("+SAPBR=3,1,\"PWD\",\""), pwd, '"');
sendAT(GF("+SAPBR=3,1,\"PWD\",\""), pwd, '"'); // Set the password
waitResponse();
}
// Define the PDP context
sendAT(GF("+CGDCONT=1,\"IP\",\""), apn, '"');
waitResponse();
// Activate the PDP context
sendAT(GF("+CGACT=1,1"));
waitResponse(60000L);
// Open a GPRS context
// Open the definied GPRS bearer context
sendAT(GF("+SAPBR=1,1"));
waitResponse(85000L);
// Query the GPRS context
// Query the GPRS bearer context status
sendAT(GF("+SAPBR=2,1"));
if (waitResponse(30000L) != 1)
return false;
// Attach to GPRS
sendAT(GF("+CGATT=1"));
if (waitResponse(60000L) != 1)
return false;
// TODO: wait AT+CGATT?
// Set to multi-IP
sendAT(GF("+CIPMUX=1"));
if (waitResponse() != 1) {
return false;
}
// Put in "quick send" mode (thus no extra "Send OK")
sendAT(GF("+CIPQSEND=1"));
if (waitResponse() != 1) {
return false;
}
// Set to get data manually
sendAT(GF("+CIPRXGET=1"));
if (waitResponse() != 1) {
return false;
}
// Start Task and Set APN, USER NAME, PASSWORD
sendAT(GF("+CSTT=\""), apn, GF("\",\""), user, GF("\",\""), pwd, GF("\""));
if (waitResponse(60000L) != 1) {
return false;
}
// Bring Up Wireless Connection with GPRS or CSD
sendAT(GF("+CIICR"));
if (waitResponse(60000L) != 1) {
return false;
}
// Get Local IP Address, only assigned after connection
sendAT(GF("+CIFSR;E0"));
if (waitResponse(10000L) != 1) {
return false;
}
// Configure Domain Name Server (DNS)
sendAT(GF("+CDNSCFG=\"8.8.8.8\",\"8.8.4.4\""));
if (waitResponse() != 1) {
return false;
@ -517,11 +528,11 @@ public:
}
bool gprsDisconnect() {
sendAT(GF("+CIPSHUT"));
sendAT(GF("+CIPSHUT")); // Shut the TCP/IP connection
if (waitResponse(60000L) != 1)
return false;
sendAT(GF("+CGATT=0"));
sendAT(GF("+CGATT=0")); // Deactivate the bearer context
if (waitResponse(60000L) != 1)
return false;

TinyGsmClientSIM808.h → src/TinyGsmClientSIM808.h View File


TinyGsmClientU201.h → src/TinyGsmClientU201.h View File

@ -372,7 +372,7 @@ public:
if (isNetworkConnected()) {
return true;
}
delay(500);
delay(250);
}
return false;
}

TinyGsmClientXBee.h → src/TinyGsmClientXBee.h View File

@ -31,7 +31,7 @@ enum SimStatus {
enum XBeeType {
S6B = 0,
LTEC1 = 1,
LTEC1 = 1,
};
enum RegStatus {
@ -74,7 +74,7 @@ public:
virtual int connect(const char *host, uint16_t port) {
at->streamClear(); // Empty anything remaining in the buffer;
at->commandMode();
sock_connected = at->modemConnect(host, port, mux);
sock_connected = at->modemConnect(host, port, mux, false);
at->writeChanges();
at->exitCommand();
return sock_connected;
@ -83,7 +83,7 @@ public:
virtual int connect(IPAddress ip, uint16_t port) {
at->streamClear(); // Empty anything remaining in the buffer;
at->commandMode();
sock_connected = at->modemConnect(ip, port, mux);
sock_connected = at->modemConnect(ip, port, mux, false);
at->writeChanges();
at->exitCommand();
return sock_connected;
@ -92,13 +92,13 @@ public:
// This is a hack to shut the socket by setting the timeout to zero and
// then sending an empty line to the server.
virtual void stop() {
at->streamClear(); // Empty anything remaining in the buffer;
at->commandMode();
at->sendAT(GF("TM0")); // Set socket timeout to 0;
at->waitResponse();
at->writeChanges();
at->exitCommand();
at->modemSend("", 1, mux);
at->streamClear(); // Empty anything remaining in the buffer;
at->commandMode();
at->sendAT(GF("TM64")); // Set socket timeout back to 10seconds;
at->waitResponse();
@ -124,7 +124,8 @@ public:
}
virtual int read(uint8_t *buf, size_t size) {
return available();
TINY_GSM_YIELD();
return at->stream.readBytes(buf, size);
}
virtual int read() {
@ -155,6 +156,35 @@ private:
bool sock_connected;
};
class GsmClientSecure : public GsmClient
{
public:
GsmClientSecure() {}
GsmClientSecure(TinyGsm& modem, uint8_t mux = 1)
: GsmClient(modem, mux)
{}
public:
virtual int connect(const char *host, uint16_t port) {
at->streamClear(); // Empty anything remaining in the buffer;
at->commandMode();
sock_connected = at->modemConnect(host, port, mux, true);
at->writeChanges();
at->exitCommand();
return sock_connected;
}
virtual int connect(IPAddress ip, uint16_t port) {
at->streamClear(); // Empty anything remaining in the buffer;
at->commandMode();
sock_connected = at->modemConnect(ip, port, mux, true);
at->writeChanges();
at->exitCommand();
return sock_connected;
}
};
public:
TinyGsm(Stream& stream)
@ -190,7 +220,18 @@ public:
return true;
}
bool testAT(unsigned long timeout = 10000L) { // not supported
bool testAT(unsigned long timeout = 10000L) {
for (unsigned long start = millis(); millis() - start < timeout; ) {
if (commandMode())
{
sendAT();
if (waitResponse(200) == 1) {
return true;
}
exitCommand();
}
delay(100);
}
return false;
}
@ -205,6 +246,11 @@ public:
return ret_val;
}
bool hasSSL() {
if (beeType == S6B) return false;
else return true;
}
/*
* Power functions
*/
@ -230,8 +276,10 @@ public:
commandMode();
sendAT(GF("SM"),1);
waitResponse();
sendAT(GF("SO"),200);
waitResponse();
if (beeType == S6B) {
sendAT(GF("SO"),200);
waitResponse();
}
writeChanges();
exitCommand();
}
@ -272,8 +320,7 @@ public:
RegStatus getRegistrationStatus() {
commandMode();
if (beeType == S6B) sendAT(GF("AI"));
else sendAT(GF("CI"));
sendAT(GF("AI"));
// wait for the response
unsigned long startMillis = millis();
while (!stream.available() && millis() - startMillis < 1000) {};
@ -290,7 +337,7 @@ public:
res == GF("40") || res == GF("41") || res == GF("42"))
return REG_SEARCHING;
else if(res == GF("24"))
else if(res == GF("24") || res == GF("25") || res == GF("27"))
return REG_DENIED;
else return REG_UNKNOWN;
@ -314,34 +361,31 @@ public:
int getSignalQuality() {
commandMode();
if (beeType == S6B) sendAT(GF("LM")); // ask for the "link margin" - the dB above sensitivity
else sendAT(GF("DB")); // ask for the cell strenght in dBm
else sendAT(GF("DB")); // ask for the cell strength in dBm
// wait for the response
unsigned long startMillis = millis();
while (!stream.available() && millis() - startMillis < 1000) {};
char buf[2] = {0}; // Set up buffer for response
buf[0] = streamRead();
buf[1] = streamRead();
DBG(buf[0], buf[1], "\n");
// DBG(buf[0], buf[1], "\n");
exitCommand();
int intr = strtol(buf, 0, 16);
if (beeType == S6B) return -93 + intr; // the maximum sensitivity is -93dBm
else return -1*intr; // need to convert to negative number
}
bool isNetworkConnected() {
RegStatus s = getRegistrationStatus();
return (s == REG_OK_HOME || s == REG_OK_ROAMING);
}
bool waitForNetwork(unsigned long timeout = 60000L) {
for (unsigned long start = millis(); millis() - start < timeout; ) {
commandMode();
if (beeType == S6B) sendAT(GF("AI"));
else sendAT(GF("CI"));
// wait for the response
unsigned long startMillis = millis();
while (!stream.available() && millis() - startMillis < 1000) {};
String res = streamReadUntil('\r'); // Does not send an OK, just the result
exitCommand();
if (res == GF("0")) {
if (isNetworkConnected()) {
return true;
}
delay(1000);
delay(250);
}
return false;
}
@ -439,7 +483,7 @@ fail:
private:
int modemConnect(const char* host, uint16_t port, uint8_t mux = 0) {
int modemConnect(const char* host, uint16_t port, uint8_t mux = 0, bool ssl = false) {
sendAT(GF("LA"), host);
String strIP; strIP.reserve(16);
// wait for the response
@ -447,10 +491,10 @@ private:
while (stream.available() < 8 && millis() - startMillis < 30000) {};
strIP = streamReadUntil('\r'); // read result
IPAddress ip = TinyGsmIpFromString(strIP);
return modemConnect(ip, port);
return modemConnect(ip, port, mux, ssl);
}
int modemConnect(IPAddress ip, uint16_t port, uint8_t mux = 0) {
int modemConnect(IPAddress ip, uint16_t port, uint8_t mux = 0, bool ssl = false) {
String host; host.reserve(16);
host += ip[0];
host += ".";
@ -459,8 +503,13 @@ private:
host += ip[2];
host += ".";
host += ip[3];
sendAT(GF("IP"), 1); // Put in TCP mode
waitResponse();
if (ssl) {
sendAT(GF("IP"), 4); // Put in TCP mode
waitResponse();
} else {
sendAT(GF("IP"), 1); // Put in TCP mode
waitResponse();
}
sendAT(GF("DL"), host); // Set the "Destination Address Low"
waitResponse();
sendAT(GF("DE"), String(port, HEX)); // Set the destination port
@ -476,8 +525,7 @@ private:
bool modemGetConnected(uint8_t mux = 0) {
commandMode();
if (beeType == S6B) sendAT(GF("AI"));
else sendAT(GF("CI"));
sendAT(GF("AI"));
int res = waitResponse(GF("0"));
exitCommand();
return 1 == res;
@ -504,9 +552,7 @@ public:
TINY_GSM_YIELD();
String return_string = stream.readStringUntil(c);
return_string.trim();
if (String(c) == GSM_NL) {
DBG(return_string, "\r\n");
} else DBG(return_string, c);
// DBG(return_string, c);
return return_string;
}
@ -517,7 +563,7 @@ public:
bool commandMode(void) {
delay(guardTime); // cannot send anything for 1 second before entering command mode
streamWrite(GF("+++")); // enter command mode
DBG("\r\n+++\r\n");
// DBG("\r\n+++\r\n");
return 1 == waitResponse(guardTime*2);
}
@ -594,7 +640,7 @@ finish:
data.replace(GSM_NL GSM_NL, GSM_NL);
data.replace(GSM_NL, "\r\n ");
if (data.length()) {
DBG("<<< ", data, "\r\n");
// DBG("<<< ", data);
}
}
return index;

TinyGsmCommon.h → src/TinyGsmCommon.h View File


TinyGsmFifo.h → src/TinyGsmFifo.h View File


+ 45
- 0
tools/AT_Spy/AT_Spy.ino View File

@ -0,0 +1,45 @@
/**************************************************************
*
* This script just listens in on the communication between an Arduino and the
* modem.
*
* TinyGSM Getting Started guide:
* http://tiny.cc/tiny-gsm-readme
*
**************************************************************/
// Set the baud rate between the modem and the board
#define BAUD_RATE 9600
// Set serial printing out the communication
#define SPY Serial
// Set serial for input from modem
#define MODEM_TX Serial1
// Set serial for AT commands (to the module)
// Use Hardware Serial on Mega, Leonardo, Micro
// #define BOARD_TX Serial1
// or AltSoftware
#include <AltSoftSerial.h>
AltSoftSerial BOARD_TX;
void setup() {
// Set console baud rate
SPY.begin(57600);
MODEM_TX.begin(BAUD_RATE);
BOARD_TX.begin(BAUD_RATE);
delay(5000);
}
void loop()
{
while (MODEM_TX.available()) {
SPY.write(MODEM_TX.read());
}
while (BOARD_TX.available()) {
SPY.write(BOARD_TX.read());
}
}

Loading…
Cancel
Save