summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libraries/SIM800/SIM800.cpp294
-rw-r--r--libraries/SIM800/SIM800.h55
-rw-r--r--libraries/SIM800/examples/GPRSTest/GPRSTest.ino126
3 files changed, 475 insertions, 0 deletions
diff --git a/libraries/SIM800/SIM800.cpp b/libraries/SIM800/SIM800.cpp
new file mode 100644
index 0000000..7a63482
--- /dev/null
+++ b/libraries/SIM800/SIM800.cpp
@@ -0,0 +1,294 @@
+/*************************************************************************
+* Test sketch for SIM800 library
+* Distributed under GPL v2.0
+* Written by Stanley Huang <stanleyhuangyc@gmail.com>
+* For more information, please visit http://arduinodev.com
+*************************************************************************/
+
+#include "SIM800.h"
+
+bool CGPRS_SIM800::init()
+{
+ simser.begin(115200);
+ pinMode(SIM800_RESET_PIN, OUTPUT);
+ digitalWrite(SIM800_RESET_PIN, HIGH);
+ delay(10);
+ digitalWrite(SIM800_RESET_PIN, LOW);
+ delay(100);
+ // generate turn on pulse
+ digitalWrite(SIM800_RESET_PIN, HIGH);
+ delay(3000);
+ if (sendCommand("AT")) {
+ sendCommand("AT+IPR=115200");
+ sendCommand("ATE0");
+ return true;
+ }
+ return false;
+}
+byte CGPRS_SIM800::setup(const char* apn)
+{
+ bool success = false;
+ for (byte n = 0; n < 30; n++) {
+ if (sendCommand("AT+CREG?", 2000)) {
+ char *p = strstr(buffer, "0,");
+ if (p) {
+ char mode = *(p + 2);
+#if DEBUG
+ con.print("Mode:");
+ con.println(mode);
+#endif
+ if (mode == '1' || mode == '5') {
+ success = true;
+ break;
+ }
+ }
+ }
+ delay(1000);
+ }
+
+ if (!success)
+ return 1;
+
+ if (!sendCommand("AT+CGATT?"))
+ return 2;
+
+ if (!sendCommand("AT+SAPBR=3,1,\"Contype\",\"GPRS\""))
+ return 3;
+
+ simser.print("AT+SAPBR=3,1,\"APN\",\"");
+ simser.print(apn);
+ simser.println('\"');
+ if (!sendCommand(0))
+ return 4;
+
+ for (byte n = 0; n < 10 && !(success = (sendCommand("AT+SAPBR=1,1") != 0)); n++)
+ delay(500);
+
+ if (!success)
+ return 5;
+
+ return 0;
+}
+bool CGPRS_SIM800::getOperatorName()
+{
+ // display operator name
+ if (sendCommand("AT+COPS?", "OK\r", "ERROR\r") == 1) {
+ char *p = strstr(buffer, ",\"");
+ if (p) {
+ p += 2;
+ char *s = strchr(p, '\"');
+ if (s) *s = 0;
+ strcpy(buffer, p);
+ return true;
+ }
+ }
+ return false;
+}
+bool CGPRS_SIM800::checkSMS()
+{
+ if (sendCommand("AT+CMGR=1", "+CMGR:", "ERROR") == 1) {
+ // reads the data of the SMS
+ sendCommand(0, 100, "\r\n");
+ if (sendCommand(0)) {
+ // remove the SMS
+ sendCommand("AT+CMGD=1");
+ return true;
+ }
+ }
+ return false;
+}
+int CGPRS_SIM800::getSignalQuality()
+{
+ sendCommand("AT+CSQ");
+ char *p = strstr(buffer, "CSQ: ");
+ if (p) {
+ int n = atoi(p + 2);
+ if (n == 99 || n == -1) return 0;
+ return n * 2 - 114;
+ } else {
+ return 0;
+ }
+}
+void CGPRS_SIM800::httpUninit()
+{
+ sendCommand("AT+HTTPTERM");
+}
+
+bool CGPRS_SIM800::httpInit()
+{
+ if (!sendCommand("AT+HTTPINIT", 10000) || !sendCommand("AT+HTTPPARA=\"CID\",1", 5000)) {
+ httpState = HTTP_DISABLED;
+ return false;
+ }
+ httpState = HTTP_READY;
+ return true;
+}
+bool CGPRS_SIM800::httpConnect(const char* url, const char* args)
+{
+ // Sets url
+ simser.print("AT+HTTPPARA=\"URL\",\"");
+ simser.print(url);
+ if (args) {
+ simser.print('?');
+ simser.print(args);
+ }
+
+ simser.println('\"');
+ if (sendCommand(0))
+ {
+ // Starts GET action
+ simser.println("AT+HTTPACTION=0");
+ httpState = HTTP_CONNECTING;
+ bytesRecv = 0;
+ checkTimer = millis();
+ } else {
+ httpState = HTTP_ERROR;
+ }
+ return false;
+}
+// check if HTTP connection is established
+// return 0 for in progress, 1 for success, 2 for error
+byte CGPRS_SIM800::httpIsConnected()
+{
+ byte ret = checkbuffer("0,200", "0,60", 10000);
+ if (ret >= 2) {
+ httpState = HTTP_ERROR;
+ return -1;
+ }
+ return ret;
+}
+void CGPRS_SIM800::httpRead()
+{
+ simser.println("AT+HTTPREAD");
+ httpState = HTTP_READING;
+ bytesRecv = 0;
+ checkTimer = millis();
+}
+// check if HTTP connection is established
+// return 0 for in progress, -1 for error, number of http payload bytes on success
+int CGPRS_SIM800::httpIsRead()
+{
+ byte ret = checkbuffer("+HTTPREAD: ", "Error", 10000) == 1;
+ if (ret == 1) {
+ bytesRecv = 0;
+ // read the rest data
+ sendCommand(0, 100, "\r\n");
+ int bytes = atoi(buffer);
+ sendCommand(0);
+ bytes = min(bytes, sizeof(buffer) - 1);
+ buffer[bytes] = 0;
+ return bytes;
+ } else if (ret >= 2) {
+ httpState = HTTP_ERROR;
+ return -1;
+ }
+ return 0;
+}
+byte CGPRS_SIM800::sendCommand(const char* cmd, unsigned int timeout, const char* expected)
+{
+ if (cmd) {
+ purgeSerial();
+#if DEBUG
+ con.print('>');
+ con.println(cmd);
+#endif
+ simser.println(cmd);
+ }
+ uint32_t t = millis();
+ byte n = 0;
+ do {
+ if (simser.available()) {
+ char c = simser.read();
+ if (n >= sizeof(buffer) - 1) {
+ // buffer full, discard first half
+ n = sizeof(buffer) / 2 - 1;
+ memcpy(buffer, buffer + sizeof(buffer) / 2, n);
+ }
+ buffer[n++] = c;
+ buffer[n] = 0;
+ if (strstr(buffer, expected ? expected : "OK\r")) {
+#if DEBUG
+ con.print("[1]");
+ con.println(buffer);
+#endif
+ return n;
+ }
+ }
+ } while (millis() - t < timeout);
+#if DEBUG
+ con.print("[0]");
+ con.println(buffer);
+#endif
+ return 0;
+}
+byte CGPRS_SIM800::sendCommand(const char* cmd, const char* expected1, const char* expected2, unsigned int timeout)
+{
+ if (cmd) {
+ purgeSerial();
+#if DEBUG
+ con.print('>');
+ con.println(cmd);
+#endif
+ simser.println(cmd);
+ }
+ uint32_t t = millis();
+ byte n = 0;
+ do {
+ if (simser.available()) {
+ char c = simser.read();
+ if (n >= sizeof(buffer) - 1) {
+ // buffer full, discard first half
+ n = sizeof(buffer) / 2 - 1;
+ memcpy(buffer, buffer + sizeof(buffer) / 2, n);
+ }
+ buffer[n++] = c;
+ buffer[n] = 0;
+ if (strstr(buffer, expected1)) {
+#if DEBUG
+ con.print("[1]");
+ con.println(buffer);
+#endif
+ return 1;
+ }
+ if (strstr(buffer, expected2)) {
+#if DEBUG
+ con.print("[2]");
+ con.println(buffer);
+#endif
+ return 2;
+ }
+ }
+ } while (millis() - t < timeout);
+#if DEBUG
+ con.print("[0]");
+ con.println(buffer);
+#endif
+ return 0;
+}
+
+byte CGPRS_SIM800::checkbuffer(const char* expected1, const char* expected2, unsigned int timeout)
+{
+ while (simser.available()) {
+ char c = simser.read();
+ if (bytesRecv >= sizeof(buffer) - 1) {
+ // buffer full, discard first half
+ bytesRecv = sizeof(buffer) / 2 - 1;
+ memcpy(buffer, buffer + sizeof(buffer) / 2, bytesRecv);
+ }
+ buffer[bytesRecv++] = c;
+ buffer[bytesRecv] = 0;
+ if (strstr(buffer, expected1)) {
+ return 1;
+ }
+ if (expected2 && strstr(buffer, expected2)) {
+ return 2;
+ }
+ }
+ return (millis() - checkTimer < timeout) ? 0 : 3;
+}
+
+void CGPRS_SIM800::purgeSerial()
+{
+ while (simser.available()) simser.read();
+}
+
diff --git a/libraries/SIM800/SIM800.h b/libraries/SIM800/SIM800.h
new file mode 100644
index 0000000..ca3104f
--- /dev/null
+++ b/libraries/SIM800/SIM800.h
@@ -0,0 +1,55 @@
+/*************************************************************************
+* Test sketch for SIM800 library
+* Distributed under GPL v2.0
+* Written by Stanley Huang <stanleyhuangyc@gmail.com>
+* For more information, please visit http://arduinodev.com
+*************************************************************************/
+
+#include <Arduino.h>
+
+#define SIM800_RESET_PIN 7
+#define simser Serial1
+#define con Serial
+#define DEBUG 0
+
+typedef enum {
+ HTTP_DISABLED = 0,
+ HTTP_READY,
+ HTTP_CONNECTING,
+ HTTP_READING,
+ HTTP_ERROR,
+} HTTP_STATES;
+
+class CGPRS_SIM800 {
+public:
+ CGPRS_SIM800():httpState(HTTP_DISABLED) {}
+ bool init();
+ byte setup(const char* apn);
+ bool getOperatorName();
+ bool checkSMS();
+ int getSignalQuality();
+ void httpUninit();
+ bool httpInit();
+ bool httpConnect(const char* url, const char* args = 0);
+ // check if HTTP connection is established
+ // return 0 for in progress, 1 for success, 2 for error
+ byte httpIsConnected();
+ void httpRead();
+ // check if HTTP connection is established
+ // return 0 for in progress, -1 for error, number of http payload bytes on success
+ int httpIsRead();
+ byte sendCommand(const char* cmd, unsigned int timeout = 2000, const char* expected = 0);
+ byte sendCommand(const char* cmd, const char* expected1, const char* expected2, unsigned int timeout = 2000);
+ bool available()
+ {
+ return simser.available();
+ }
+ char buffer[256];
+ byte httpState;
+private:
+ byte checkbuffer(const char* expected1, const char* expected2 = 0, unsigned int timeout = 2000);
+ void purgeSerial();
+ byte bytesRecv;
+ uint32_t checkTimer;
+};
+
diff --git a/libraries/SIM800/examples/GPRSTest/GPRSTest.ino b/libraries/SIM800/examples/GPRSTest/GPRSTest.ino
new file mode 100644
index 0000000..e752166
--- /dev/null
+++ b/libraries/SIM800/examples/GPRSTest/GPRSTest.ino
@@ -0,0 +1,126 @@
+/*************************************************************************
+* Test sketch for SIM800 library
+* Distributed under GPL v2.0
+* Written by Stanley Huang <stanleyhuangyc@gmail.com>
+* For more information, please visit http://arduinodev.com
+*************************************************************************/
+
+#include "SIM800.h"
+
+#define APN "connect"
+static const char* url = "http://arduinodev.com/datetime.php";
+
+
+CGPRS_SIM800 gprs;
+uint32_t count = 0;
+uint32_t errors = 0;
+
+void setup()
+{
+ con.begin(9600);
+ while (!con);
+
+ con.println("SIM800 TEST");
+
+ for (;;) {
+ con.print("Resetting...");
+ while (!gprs.init()) {
+ con.write('.');
+ }
+ con.println("OK");
+
+ con.print("Setting up network...");
+ byte ret = gprs.setup(APN);
+ if (ret == 0)
+ break;
+ con.print("Error code:");
+ con.println(ret);
+ con.println(gprs.buffer);
+ }
+ con.println("OK");
+ delay(3000);
+
+ if (gprs.getOperatorName()) {
+ con.print("Operator:");
+ con.println(gprs.buffer);
+ }
+ int ret = gprs.getSignalQuality();
+ if (ret) {
+ con.print("Signal:");
+ con.print(ret);
+ con.println("dB");
+ }
+
+#if 0
+ sendCommand("AT+CSQ");
+ lcd.println("Dialing...");
+ if (sendCommand("ATD + +61402533012;", 10000)) {
+ lcd.println(buffer);
+ }
+ if (sendCommand("ATH"))
+ lcd.println(buffer);
+ delay(1000);
+#endif
+
+ gprs.sendCommand("AT+CMGF=1"); // sets the SMS mode to text
+ gprs.sendCommand("AT+CPMS=\"SM\",\"SM\",\"SM\""); // selects the memory
+
+ for (;;) {
+ if (gprs.httpInit()) break;
+ con.println(gprs.buffer);
+ gprs.httpUninit();
+ delay(1000);
+ }
+ delay(3000);
+}
+
+void loop()
+{
+ count++;
+
+ char mydata[16];
+ sprintf(mydata, "t=%lu", millis());
+ con.print("Requesting ");
+ con.print(url);
+ con.print('?');
+ con.println(mydata);
+ gprs.httpConnect(url, mydata);
+ while (gprs.httpIsConnected() == 0) {
+ // can do something here while waiting
+ con.write('.');
+ for (byte n = 0; n < 25 && !gprs.available(); n++) {
+ delay(10);
+ }
+ }
+ if (gprs.httpState == HTTP_ERROR) {
+ con.println("error");
+ errors++;
+ delay(3000);
+ return;
+ }
+ gprs.httpRead();
+ int ret;
+ while ((ret = gprs.httpIsRead()) == 0) {
+ // can do something here while waiting
+ }
+ if (gprs.httpState == HTTP_ERROR) {
+ con.println("error");
+ errors++;
+ delay(3000);
+ return;
+ }
+
+ // now we have received payload
+ con.print("\n[Payload]");
+ con.println(gprs.buffer);
+
+ // show stats
+ con.print("Total Requests:");
+ con.print(count);
+ if (errors) {
+ con.print(" Errors:");
+ con.print(errors);
+ }
+ con.println();
+}
+