From d41eb24ec372ff5125b5af565f6648acb9af9fc9 Mon Sep 17 00:00:00 2001 From: Romualdo Dasig Date: Sat, 16 Feb 2019 08:32:14 +0800 Subject: [PATCH] Issue #1: Get temperature data from DHT11 temperature and humidity sensor. --- lib/ITEADLIB_Arduino_SIMCom/GSM.cpp | 739 ++++++++++++ lib/ITEADLIB_Arduino_SIMCom/GSM.h | 271 +++++ lib/ITEADLIB_Arduino_SIMCom/HWSerial.cpp | 346 ++++++ lib/ITEADLIB_Arduino_SIMCom/HWSerial.h | 72 ++ lib/ITEADLIB_Arduino_SIMCom/LICENSE | 339 ++++++ lib/ITEADLIB_Arduino_SIMCom/LOG.cpp | 59 + lib/ITEADLIB_Arduino_SIMCom/LOG.h | 33 + lib/ITEADLIB_Arduino_SIMCom/README | 267 +++++ lib/ITEADLIB_Arduino_SIMCom/README.md | 48 + lib/ITEADLIB_Arduino_SIMCom/SIM900.cpp | 1009 +++++++++++++++++ lib/ITEADLIB_Arduino_SIMCom/SIM900.h | 42 + lib/ITEADLIB_Arduino_SIMCom/Streaming.h | 95 ++ .../WideTextFinder.cpp | 196 ++++ lib/ITEADLIB_Arduino_SIMCom/WideTextFinder.h | 61 + lib/ITEADLIB_Arduino_SIMCom/bluetooth.cpp | 264 +++++ lib/ITEADLIB_Arduino_SIMCom/bluetooth.h | 154 +++ lib/ITEADLIB_Arduino_SIMCom/call.cpp | 334 ++++++ lib/ITEADLIB_Arduino_SIMCom/call.h | 28 + .../doc/Instructions.txt | 87 ++ .../doc/InstructionsBlueTooth.txt | 127 +++ .../doc/InstructionsForGBoardPro800.txt | 35 + lib/ITEADLIB_Arduino_SIMCom/doc/List.txt | 216 ++++ .../GSM_GPRSLibrary_AT/GSM_GPRSLibrary_AT.ino | 77 ++ .../GSM_GPRSLibrary_BlueTooth_Connect.ino | 45 + .../GSM_GPRSLibrary_BlueTooth_SPP.ino | 55 + .../GSM_GPRSLibrary_Call.ino | 60 + .../GSM_GPRSLibrary_Client.ino | 107 ++ .../GSM_GPRSLibrary_DTMF.ino | 63 + .../GSM_GPRSLibrary_GPS.ino | 133 +++ .../GSM_GPRSLibrary_SMS.ino | 56 + .../GSM_GPRSLibrary_Server.ino | 118 ++ lib/ITEADLIB_Arduino_SIMCom/gps.cpp | 203 ++++ lib/ITEADLIB_Arduino_SIMCom/gps.h | 19 + lib/ITEADLIB_Arduino_SIMCom/inetGSM.cpp | 589 ++++++++++ lib/ITEADLIB_Arduino_SIMCom/inetGSM.h | 31 + lib/ITEADLIB_Arduino_SIMCom/sms.cpp | 572 ++++++++++ lib/ITEADLIB_Arduino_SIMCom/sms.h | 22 + src/main.cpp | 260 ++++- 38 files changed, 7228 insertions(+), 4 deletions(-) create mode 100644 lib/ITEADLIB_Arduino_SIMCom/GSM.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/GSM.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/HWSerial.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/HWSerial.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/LICENSE create mode 100644 lib/ITEADLIB_Arduino_SIMCom/LOG.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/LOG.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/README create mode 100644 lib/ITEADLIB_Arduino_SIMCom/README.md create mode 100644 lib/ITEADLIB_Arduino_SIMCom/SIM900.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/SIM900.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/Streaming.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/WideTextFinder.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/WideTextFinder.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/bluetooth.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/bluetooth.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/call.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/call.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/doc/Instructions.txt create mode 100644 lib/ITEADLIB_Arduino_SIMCom/doc/InstructionsBlueTooth.txt create mode 100644 lib/ITEADLIB_Arduino_SIMCom/doc/InstructionsForGBoardPro800.txt create mode 100644 lib/ITEADLIB_Arduino_SIMCom/doc/List.txt create mode 100644 lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_AT/GSM_GPRSLibrary_AT.ino create mode 100644 lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_BlueTooth_Connect/GSM_GPRSLibrary_BlueTooth_Connect.ino create mode 100644 lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_BlueTooth_SPP/GSM_GPRSLibrary_BlueTooth_SPP.ino create mode 100644 lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Call/GSM_GPRSLibrary_Call.ino create mode 100644 lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Client/GSM_GPRSLibrary_Client.ino create mode 100644 lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_DTMF/GSM_GPRSLibrary_DTMF.ino create mode 100644 lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_GPS/GSM_GPRSLibrary_GPS.ino create mode 100644 lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_SMS/GSM_GPRSLibrary_SMS.ino create mode 100644 lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Server/GSM_GPRSLibrary_Server.ino create mode 100644 lib/ITEADLIB_Arduino_SIMCom/gps.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/gps.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/inetGSM.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/inetGSM.h create mode 100644 lib/ITEADLIB_Arduino_SIMCom/sms.cpp create mode 100644 lib/ITEADLIB_Arduino_SIMCom/sms.h diff --git a/lib/ITEADLIB_Arduino_SIMCom/GSM.cpp b/lib/ITEADLIB_Arduino_SIMCom/GSM.cpp new file mode 100644 index 0000000..3f40f25 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/GSM.cpp @@ -0,0 +1,739 @@ +/* +This is a Beta version. +last modified 18/08/2012. + +This library is based on one developed by Arduino Labs +and it is modified to preserve the compability +with the Arduino's product. + +The library is modified to use the GSM Shield, +developed by www.open-electronics.org +(http://www.open-electronics.org/arduino-gsm-shield/) +and based on SIM900 chip, +with the same commands of Arduino Shield, +based on QuectelM10 chip. +*/ + +#include "GSM.h" +#include "WideTextFinder.h" + +//De-comment this two lines below if you have the +//first version of GSM GPRS Shield +//#define _GSM_TXPIN_ 4 +//#define _GSM_RXPIN_ 5 + +//De-comment this two lines below if you have the +//second version og GSM GPRS Shield +#define _GSM_TXPIN_ 2 +#define _GSM_RXPIN_ 3 + +#ifdef UNO +GSM::GSM():_cell(_GSM_TXPIN_,_GSM_RXPIN_),_tf(_cell, 10),_status(IDLE) +{ +}; +#endif +#ifdef MEGA +GSM::GSM() +{ + _cell.begin(9600); +}; +#endif + + +int GSM::begin(long baud_rate) +{ + // Set pin modes + pinMode(GSM_ON,OUTPUT); + pinMode(GSM_RESET,OUTPUT); + +#ifdef UNO + if (baud_rate==115200) { + Serial.println(F("Don't use baudrate 115200 with Software Serial.\nAutomatically changed at 9600.")); + baud_rate=9600; + } +#endif + int response=-1; + int cont=0; + boolean norep=true; + boolean turnedON=false; + SetCommLineStatus(CLS_ATCMD); + _cell.begin(baud_rate); + p_comm_buf = &comm_buf[0]; + setStatus(IDLE); + + // if no-reply we turn to turn on the module + for (cont=0; cont<3; cont++) { + if (AT_RESP_ERR_NO_RESP == SendATCmdWaitResp(str_at, 500, 100, str_ok, 5)&&!turnedON) { //check power + // there is no response => turn on the module +#ifdef DEBUG_ON + Serial.println(F("DB:NO RESP")); +#endif + // generate turn on pulse + digitalWrite(GSM_ON, HIGH); + delay(1200); + digitalWrite(GSM_ON, LOW); + delay(10000); + WaitResp(1000, 1000); + } else { +#ifdef DEBUG_ON + Serial.println(F("DB:ELSE")); +#endif + WaitResp(1000, 1000); + } + } + + + if (AT_RESP_OK == SendATCmdWaitResp(str_at, 500, 100, str_ok, 5)) { +#ifdef DEBUG_ON + Serial.println(F("DB:CORRECT BR")); +#endif + turnedON=true; + norep=false; + } + + + if (AT_RESP_ERR_DIF_RESP == SendATCmdWaitResp(str_at, 500, 100, str_ok, 5)&&!turnedON) { //check OK +#ifdef DEBUG_ON + Serial.println(F("DB:AUTO BAUD RATE")); +#endif + for (int i=0; i<8; i++) { + switch (i) { + case 0: + _cell.begin(1200); + break; + + case 1: + _cell.begin(2400); + break; + + case 2: + _cell.begin(4800); + break; + + case 3: + _cell.begin(9600); + break; + + case 4: + _cell.begin(19200); + break; + + case 5: + _cell.begin(38400); + break; + + case 6: + _cell.begin(57600); + break; + + case 7: + _cell.begin(115200); + break; + + // if nothing else matches, do the default + // default is optional + } + + delay(100); + +#ifdef DEBUG_PRINT + // parameter 0 - because module is off so it is not necessary + // to send finish AT here + DebugPrint(F("DEBUG: Stringa "), 0); + DebugPrint(buff, 0); +#endif + + + if (AT_RESP_OK == SendATCmdWaitResp(str_at, 500, 100, str_ok, 5)) { +#ifdef DEBUG_ON + Serial.println(F("DB:FOUND PREV BR")); +#endif + _cell.print("AT+IPR="); + _cell.print(baud_rate); + _cell.print("\r"); // send + delay(500); + _cell.begin(baud_rate); + delay(100); + if (AT_RESP_OK == SendATCmdWaitResp(str_at, 500, 100, str_ok, 5)) { +#ifdef DEBUG_ON + Serial.println(F("DB:OK BR")); +#endif + } + turnedON=true; + break; + } +#ifdef DEBUG_ON + Serial.println(F("DB:NO BR")); +#endif + } + // communication line is not used yet = free + SetCommLineStatus(CLS_FREE); + // pointer is initialized to the first item of comm. buffer + p_comm_buf = &comm_buf[0]; + } + + if(norep==true&&!turnedON) { + Serial.println(F("Trying to force the baud-rate to 9600\n")); + for (int i=0; i<8; i++) { + switch (i) { + case 0: + _cell.begin(1200); + delay(1000); + Serial.println(F("1200")); + _cell.print(F("AT+IPR=9600\r")); + delay(1000); + _cell.begin(9600); + delay(1000); + SendATCmdWaitResp(str_at, 500, 100, str_ok, 5); + delay(1000); + WaitResp(1000,1000); + break; + + case 1: + _cell.begin(2400); + delay(1000); + Serial.println(F("2400")); + _cell.print(F("AT+IPR=9600\r")); + delay(1000); + _cell.begin(9600); + delay(1000); + SendATCmdWaitResp(str_at, 500, 100, str_ok, 5); + delay(1000); + WaitResp(1000,1000); + break; + + case 2: + _cell.begin(4800); + delay(1000); + Serial.println(F("4800")); + _cell.print(F("AT+IPR=9600\r")); + delay(1000); + _cell.begin(9600); + delay(1000); + SendATCmdWaitResp(str_at, 500, 100, str_ok, 5); + delay(1000); + WaitResp(1000,1000); + break; + + case 3: + _cell.begin(9600); + delay(1000); + Serial.println(F("9600")); + _cell.print(F("AT+IPR=9600\r")); + delay(1000); + _cell.begin(9600); + delay(1000); + SendATCmdWaitResp(str_at, 500, 100, str_ok, 5); + delay(1000); + WaitResp(1000,1000); + break; + + case 4: + _cell.begin(19200); + delay(1000); + Serial.println(F("19200")); + _cell.print(F("AT+IPR=9600\r")); + delay(1000); + _cell.begin(9600); + delay(1000); + SendATCmdWaitResp(str_at, 500, 100, str_ok, 5); + delay(1000); + WaitResp(1000,1000); + break; + + case 5: + _cell.begin(38400); + delay(1000); + Serial.println(F("38400")); + _cell.print(F("AT+IPR=9600\r")); + delay(1000); + _cell.begin(9600); + delay(1000); + SendATCmdWaitResp(str_at, 500, 100, str_ok, 5); + delay(1000); + WaitResp(1000,1000); + break; + + case 6: + _cell.begin(57600); + delay(1000); + Serial.println(F("57600")); + _cell.print(F("AT+IPR=9600\r")); + delay(1000); + _cell.begin(9600); + delay(1000); + SendATCmdWaitResp(str_at, 500, 100, str_ok, 5); + delay(1000); + WaitResp(1000,1000); + break; + + case 7: + _cell.begin(115200); + delay(1000); + Serial.println(F("115200")); + _cell.print(F("AT+IPR=9600\r")); + delay(1000); + _cell.begin(9600); + delay(1000); + SendATCmdWaitResp(str_at, 500, 100, str_ok, 5); + delay(1000); + WaitResp(1000,1000); + break; + } + } + + Serial.println(F("ERROR: SIM900 doesn't answer. Check power and serial pins in GSM.cpp")); + digitalWrite(GSM_ON, HIGH); + delay(1200); + digitalWrite(GSM_ON, LOW); + delay(10000); + return 0; + } + + SetCommLineStatus(CLS_FREE); + + if(turnedON) { + WaitResp(50, 50); + InitParam(PARAM_SET_0); + InitParam(PARAM_SET_1);//configure the module + Echo(0); //enable AT echo + setStatus(READY); + return(1); + + } else { + //just to try to fix some problems with 115200 baudrate + _cell.begin(115200); + delay(1000); + _cell.print("AT+IPR="); + _cell.print(baud_rate); + _cell.print("\r"); // send + return(0); + } +} + + +void GSM::InitParam(byte group) +{ + switch (group) { + case PARAM_SET_0: + // check comm line + //if (CLS_FREE != GetCommLineStatus()) return; + + SetCommLineStatus(CLS_ATCMD); + // Reset to the factory settings + SendATCmdWaitResp(F("AT&F"), 1000, 50, str_ok, 5); + // switch off echo + SendATCmdWaitResp(F("ATE0"), 500, 50, str_ok, 5); + // setup fixed baud rate + //SendATCmdWaitResp("AT+IPR=9600", 500, 50, str_ok, 5); + // setup mode + //SendATCmdWaitResp("AT#SELINT=1", 500, 50, str_ok, 5); + // Switch ON User LED - just as signalization we are here + //SendATCmdWaitResp("AT#GPIO=8,1,1", 500, 50, str_ok, 5); + // Sets GPIO9 as an input = user button + //SendATCmdWaitResp("AT#GPIO=9,0,0", 500, 50, str_ok, 5); + // allow audio amplifier control + //SendATCmdWaitResp("AT#GPIO=5,0,2", 500, 50, str_ok, 5); + // Switch OFF User LED- just as signalization we are finished + //SendATCmdWaitResp("AT#GPIO=8,0,1", 500, 50, str_ok, 5); + SetCommLineStatus(CLS_FREE); + break; + + case PARAM_SET_1: + // check comm line + //if (CLS_FREE != GetCommLineStatus()) return; + SetCommLineStatus(CLS_ATCMD); + // Request calling line identification + SendATCmdWaitResp(F("AT+CLIP=1"), 500, 50, str_ok, 5); + // Mobile Equipment Error Code + SendATCmdWaitResp(F("AT+CMEE=0"), 500, 50, str_ok, 5); + // Echo canceller enabled + //SendATCmdWaitResp("AT#SHFEC=1", 500, 50, str_ok, 5); + // Ringer tone select (0 to 32) + //SendATCmdWaitResp("AT#SRS=26,0", 500, 50, str_ok, 5); + // Microphone gain (0 to 7) - response here sometimes takes + // more than 500msec. so 1000msec. is more safety + //SendATCmdWaitResp("AT#HFMICG=7", 1000, 50, str_ok, 5); + // set the SMS mode to text + SendATCmdWaitResp(F("AT+CMGF=1"), 500, 50, str_ok, 5); + // Auto answer after first ring enabled + // auto answer is not used + //SendATCmdWaitResp("ATS0=1", 500, 50, str_ok, 5); + // select ringer path to handsfree + //SendATCmdWaitResp("AT#SRP=1", 500, 50, str_ok, 5); + // select ringer sound level + //SendATCmdWaitResp("AT+CRSL=2", 500, 50, str_ok, 5); + // we must release comm line because SetSpeakerVolume() + // checks comm line if it is free + SetCommLineStatus(CLS_FREE); + // select speaker volume (0 to 14) + //SetSpeakerVolume(9); + // init SMS storage + InitSMSMemory(); + // select phonebook memory storage + SendATCmdWaitResp(F("AT+CPBS=\"SM\""), 1000, 50, str_ok, 5); + SendATCmdWaitResp(F("AT+CIPSHUT"), 500, 50, "SHUT OK", 5); + break; + } +} + +byte GSM::WaitResp(uint16_t start_comm_tmout, uint16_t max_interchar_tmout, + char const *expected_resp_string) +{ + byte status; + byte ret_val; + + RxInit(start_comm_tmout, max_interchar_tmout); + // wait until response is not finished + do { + status = IsRxFinished(); + } while (status == RX_NOT_FINISHED); + + if (status == RX_FINISHED) { + // something was received but what was received? + // --------------------------------------------- + + if(IsStringReceived(expected_resp_string)) { + // expected string was received + // ---------------------------- + ret_val = RX_FINISHED_STR_RECV; + } else { + ret_val = RX_FINISHED_STR_NOT_RECV; + } + } else { + // nothing was received + // -------------------- + ret_val = RX_TMOUT_ERR; + } + return (ret_val); +} + + +/********************************************************** +Method sends AT command and waits for response + +return: + AT_RESP_ERR_NO_RESP = -1, // no response received + AT_RESP_ERR_DIF_RESP = 0, // response_string is different from the response + AT_RESP_OK = 1, // response_string was included in the response +**********************************************************/ +char GSM::SendATCmdWaitResp(char const *AT_cmd_string, + uint16_t start_comm_tmout, uint16_t max_interchar_tmout, + char const *response_string, + byte no_of_attempts) +{ + byte status; + char ret_val = AT_RESP_ERR_NO_RESP; + byte i; + + for (i = 0; i < no_of_attempts; i++) { + // delay 500 msec. before sending next repeated AT command + // so if we have no_of_attempts=1 tmout will not occurred + if (i > 0) delay(500); + + _cell.println(AT_cmd_string); + status = WaitResp(start_comm_tmout, max_interchar_tmout); + if (status == RX_FINISHED) { + // something was received but what was received? + // --------------------------------------------- + if(IsStringReceived(response_string)) { + ret_val = AT_RESP_OK; + break; // response is OK => finish + } else ret_val = AT_RESP_ERR_DIF_RESP; + } else { + // nothing was received + // -------------------- + ret_val = AT_RESP_ERR_NO_RESP; + } + + } + + WaitResp(1000, 5000); + return (ret_val); +} + + +/********************************************************** +Method sends AT command and waits for response + +return: + AT_RESP_ERR_NO_RESP = -1, // no response received + AT_RESP_ERR_DIF_RESP = 0, // response_string is different from the response + AT_RESP_OK = 1, // response_string was included in the response +**********************************************************/ +char GSM::SendATCmdWaitResp(const __FlashStringHelper *AT_cmd_string, + uint16_t start_comm_tmout, uint16_t max_interchar_tmout, + char const *response_string, + byte no_of_attempts) +{ + byte status; + char ret_val = AT_RESP_ERR_NO_RESP; + byte i; + + for (i = 0; i < no_of_attempts; i++) { + // delay 500 msec. before sending next repeated AT command + // so if we have no_of_attempts=1 tmout will not occurred + if (i > 0) delay(500); + + _cell.println(AT_cmd_string); + status = WaitResp(start_comm_tmout, max_interchar_tmout); + if (status == RX_FINISHED) { + // something was received but what was received? + // --------------------------------------------- + if(IsStringReceived(response_string)) { + ret_val = AT_RESP_OK; + break; // response is OK => finish + } else ret_val = AT_RESP_ERR_DIF_RESP; + } else { + // nothing was received + // -------------------- + ret_val = AT_RESP_ERR_NO_RESP; + } + + } + + return (ret_val); +} + +byte GSM::WaitResp(uint16_t start_comm_tmout, uint16_t max_interchar_tmout) +{ + byte status; + + RxInit(start_comm_tmout, max_interchar_tmout); + // wait until response is not finished + do { + status = IsRxFinished(); + } while (status == RX_NOT_FINISHED); + return (status); +} + +byte GSM::IsRxFinished(void) +{ + byte num_of_bytes; + byte ret_val = RX_NOT_FINISHED; // default not finished + + // Rx state machine + // ---------------- + + if (rx_state == RX_NOT_STARTED) { + // Reception is not started yet - check tmout + if (!_cell.available()) { + // still no character received => check timeout + /* + #ifdef DEBUG_GSMRX + + DebugPrint("\r\nDEBUG: reception timeout", 0); + Serial.print((unsigned long)(millis() - prev_time)); + DebugPrint("\r\nDEBUG: start_reception_tmout\r\n", 0); + Serial.print(start_reception_tmout); + + + #endif + */ + if ((unsigned long)(millis() - prev_time) >= start_reception_tmout) { + // timeout elapsed => GSM module didn't start with response + // so communication is takes as finished + /* + #ifdef DEBUG_GSMRX + DebugPrint("\r\nDEBUG: RECEPTION TIMEOUT", 0); + #endif + */ + comm_buf[comm_buf_len] = 0x00; + ret_val = RX_TMOUT_ERR; + } + } else { + // at least one character received => so init inter-character + // counting process again and go to the next state + prev_time = millis(); // init tmout for inter-character space + rx_state = RX_ALREADY_STARTED; + } + } + + if (rx_state == RX_ALREADY_STARTED) { + // Reception already started + // check new received bytes + // only in case we have place in the buffer + num_of_bytes = _cell.available(); + // if there are some received bytes postpone the timeout + if (num_of_bytes) prev_time = millis(); + + // read all received bytes + while (num_of_bytes) { + num_of_bytes--; + if (comm_buf_len < COMM_BUF_LEN) { + // we have still place in the GSM internal comm. buffer => + // move available bytes from circular buffer + // to the rx buffer + *p_comm_buf = _cell.read(); + + p_comm_buf++; + comm_buf_len++; + comm_buf[comm_buf_len] = 0x00; // and finish currently received characters + // so after each character we have + // valid string finished by the 0x00 + } else { + // comm buffer is full, other incoming characters + // will be discarded + // but despite of we have no place for other characters + // we still must to wait until + // inter-character tmout is reached + + // so just readout character from circular RS232 buffer + // to find out when communication id finished(no more characters + // are received in inter-char timeout) + _cell.read(); + } + } + + // finally check the inter-character timeout + /* + #ifdef DEBUG_GSMRX + + DebugPrint("\r\nDEBUG: intercharacter", 0); + < Serial.print((unsigned long)(millis() - prev_time)); + DebugPrint("\r\nDEBUG: interchar_tmout\r\n", 0); + Serial.print(interchar_tmout); + + + #endif + */ + if ((unsigned long)(millis() - prev_time) >= interchar_tmout) { + // timeout between received character was reached + // reception is finished + // --------------------------------------------- + + /* + #ifdef DEBUG_GSMRX + + DebugPrint("\r\nDEBUG: OVER INTER TIMEOUT", 0); + #endif + */ + comm_buf[comm_buf_len] = 0x00; // for sure finish string again + // but it is not necessary + ret_val = RX_FINISHED; + } + } + + + return (ret_val); +} + +/********************************************************** +Method checks received bytes + +compare_string - pointer to the string which should be find + +return: 0 - string was NOT received + 1 - string was received +**********************************************************/ +byte GSM::IsStringReceived(char const *compare_string) +{ + char *ch; + byte ret_val = 0; + + if(comm_buf_len) { + /* + #ifdef DEBUG_GSMRX + DebugPrint("DEBUG: Compare the string: \r\n", 0); + for (int i=0; i,,,,, + if (AT_RESP_OK == SendATCmdWaitResp(F("AT+CPMS=\"SM\",\"SM\",\"SM\""), 1000, 1000, "+CPMS:", 10)) { + ret_val = 1; + } else ret_val = 0; + + SetCommLineStatus(CLS_FREE); + return (ret_val); +} + +int GSM::isIP(const char* cadena) +{ + int i; + for (i=0; i=48 && cadena[i] <=57))) + return 0; + return 1; +} + + + + + + diff --git a/lib/ITEADLIB_Arduino_SIMCom/GSM.h b/lib/ITEADLIB_Arduino_SIMCom/GSM.h new file mode 100644 index 0000000..f311026 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/GSM.h @@ -0,0 +1,271 @@ +#ifndef GSM_H +#define GSM_H + +#define UNO +//#define MEGA + +#include +#include +#include "WideTextFinder.h" + + +#define ctrlz 26 //Ascii character for ctr+z. End of a SMS. +#define cr 13 //Ascii character for carriage return. +#define lf 10 //Ascii character for line feed. +#define ctrlz 26 //Ascii character for ctr+z. End of a SMS. +#define cr 13 //Ascii character for carriage return. +#define lf 10 //Ascii character for line feed. +#define GSM_LIB_VERSION 308 // library version X.YY (e.g. 1.00) + +#define DEBUG_ON + + +#ifdef MEGA +#include "HWSerial.h" +#endif + +// if defined - debug print is enabled with possibility to print out +// debug texts to the terminal program +//#define DEBUG_PRINT + +// if defined - debug print is enabled with possibility to print out +// the data recived from gsm module +//#define DEBUG_GSMRX + +// if defined - debug LED is enabled, otherwise debug LED is disabled +//#define DEBUG_LED_ENABLED + +// if defined - SMSs are not send(are finished by the character 0x1b +// which causes that SMS are not send) +// by this way it is possible to develop program without paying for the SMSs +//#define DEBUG_SMS_ENABLED + + +// pins definition +#define GSM_ON 8 // connect GSM Module turn ON to pin 77 +#define GSM_RESET 9 // connect GSM Module RESET to pin 35 +//#define DTMF_OUTPUT_ENABLE 71 // connect DTMF Output Enable not used +#define DTMF_DATA_VALID 14 // connect DTMF Data Valid to pin 14 +#define DTMF_DATA0 72 // connect DTMF Data0 to pin 72 +#define DTMF_DATA1 73 // connect DTMF Data1 to pin 73 +#define DTMF_DATA2 74 // connect DTMF Data2 to pin 74 +#define DTMF_DATA3 75 // connect DTMF Data3 to pin 75 + +// length for the internal communication buffer +#define COMM_BUF_LEN 200 + +// some constants for the IsRxFinished() method +#define RX_NOT_STARTED 0 +#define RX_ALREADY_STARTED 1 + +// some constants for the InitParam() method +#define PARAM_SET_0 0 +#define PARAM_SET_1 1 + +// DTMF signal is NOT valid +//#define DTMF_NOT_VALID 0x10 + + +// status bits definition +#define STATUS_NONE 0 +#define STATUS_INITIALIZED 1 +#define STATUS_REGISTERED 2 +#define STATUS_USER_BUTTON_ENABLE 4 + +// GPRS status +#define CHECK_AND_OPEN 0 +#define CLOSE_AND_REOPEN 1 + +// Common string used +#define str_ok "OK" //string to reduce stack usage +#define str_at "AT" //string to reduce stack usage + +// SMS type +// use by method IsSMSPresent() +enum sms_type_enum { + SMS_UNREAD, + SMS_READ, + SMS_ALL, + + SMS_LAST_ITEM +}; + +enum comm_line_status_enum { + // CLS like CommunicationLineStatus + CLS_FREE, // line is free - not used by the communication and can be used + CLS_ATCMD, // line is used by AT commands, includes also time for response + CLS_DATA, // for the future - line is used in the CSD or GPRS communication + CLS_LAST_ITEM +}; + +enum rx_state_enum { + RX_NOT_FINISHED = 0, // not finished yet + RX_FINISHED, // finished, some character was received + RX_FINISHED_STR_RECV, // finished and expected string received + RX_FINISHED_STR_NOT_RECV, // finished, but expected string not received + RX_TMOUT_ERR, // finished, no character received + // initial communication tmout occurred + RX_LAST_ITEM +}; + + +enum at_resp_enum { + AT_RESP_ERR_NO_RESP = -1, // nothing received + AT_RESP_ERR_DIF_RESP = 0, // response_string is different from the response + AT_RESP_OK = 1, // response_string was included in the response + + AT_RESP_LAST_ITEM +}; + +enum registration_ret_val_enum { + REG_NOT_REGISTERED = 0, + REG_REGISTERED, + REG_NO_RESPONSE, + REG_COMM_LINE_BUSY, + + REG_LAST_ITEM +}; + +enum call_ret_val_enum { + CALL_NONE = 0, + CALL_INCOM_VOICE, + CALL_ACTIVE_VOICE, + CALL_INCOM_VOICE_AUTH, + CALL_INCOM_VOICE_NOT_AUTH, + CALL_INCOM_DATA_AUTH, + CALL_INCOM_DATA_NOT_AUTH, + CALL_ACTIVE_DATA, + CALL_OTHERS, + CALL_NO_RESPONSE, + CALL_COMM_LINE_BUSY, + + CALL_LAST_ITEM +}; + + +enum getsms_ret_val_enum { + GETSMS_NO_SMS = 0, + GETSMS_UNREAD_SMS, + GETSMS_READ_SMS, + GETSMS_OTHER_SMS, + + GETSMS_NOT_AUTH_SMS, + GETSMS_AUTH_SMS, + + GETSMS_LAST_ITEM +}; + + +class GSM { +public: + enum GSM_st_e { ERROR, IDLE, READY, ATTACHED, TCPSERVERWAIT, TCPCONNECTEDSERVER, TCPCONNECTEDCLIENT }; + byte comm_buf[COMM_BUF_LEN+1]; // communication buffer +1 for 0x00 termination + void InitParam (byte group); + +private: + int _status; + byte comm_line_status; + + // global status - bits are used for representation of states + byte module_status; + + // variables connected with communication buffer + + byte *p_comm_buf; // pointer to the communication buffer + byte comm_buf_len; // num. of characters in the buffer + byte rx_state; // internal state of rx state machine + uint16_t start_reception_tmout; // max tmout for starting reception + uint16_t interchar_tmout; // previous time in msec. + unsigned long prev_time; // previous time in msec. + + // last value of speaker volume + byte last_speaker_volume; + char InitSMSMemory(void); + +protected: +#ifdef MEGA + HWSerial _cell; +#endif +#ifdef UNO + SoftwareSerial _cell; +#endif + int isIP(const char* cadena); + +public: +#ifdef UNO + WideTextFinder _tf; +#endif + inline void setStatus(GSM_st_e status) { + _status = status; + } + GSM(); + inline int getStatus() { + return _status; + }; + virtual int begin(long baud_rate); + inline void SetCommLineStatus(byte new_status) { + comm_line_status = new_status; + }; + inline byte GetCommLineStatus(void) { + return comm_line_status; + }; + void RxInit(uint16_t start_comm_tmout, uint16_t max_interchar_tmout); + byte IsRxFinished(void); + byte IsStringReceived(char const *compare_string); + byte WaitResp(uint16_t start_comm_tmout, uint16_t max_interchar_tmout); + byte WaitResp(uint16_t start_comm_tmout, uint16_t max_interchar_tmout, + char const *expected_resp_string); + char SendATCmdWaitResp(char const *AT_cmd_string, + uint16_t start_comm_tmout, uint16_t max_interchar_tmout, + char const *response_string, + byte no_of_attempts); + char SendATCmdWaitResp(const __FlashStringHelper *AT_cmd_string, + uint16_t start_comm_tmout, uint16_t max_interchar_tmout, + char const *response_string, + byte no_of_attempts); + void Echo(byte state); + + + //----------------------- + // turns off/on the speaker + void SetSpeaker(byte off_on); + // checks if module is registered in the GSM network + // must be called regularly + byte CheckRegistration(void); + + // User button methods + inline byte IsUserButtonEnable(void) { + return (module_status & STATUS_USER_BUTTON_ENABLE); + }; + inline void DisableUserButton(void) { + module_status &= ~STATUS_USER_BUTTON_ENABLE; + }; + inline void EnableUserButton(void) { + module_status |= STATUS_USER_BUTTON_ENABLE; + }; + byte IsUserButtonPushed(void); + + // Phonebook's methods + char GetPhoneNumber(byte position, char *phone_number); + char WritePhoneNumber(byte position, char *phone_number); + char DelPhoneNumber(byte position); + char ComparePhoneNumber(byte position, char *phone_number); + + // returns registration state + byte IsRegistered(void); + // returns whether complete initialization was made + byte IsInitialized(void); + //----------------------- + + // debug methods +#ifdef DEBUG_LED_ENABLED + void BlinkDebugLED (byte num_of_blink); +#endif + +#ifdef DEBUG_PRINT + void DebugPrint(const char *string_to_print, byte last_debug_print); + void DebugPrint(int number_to_print, byte last_debug_print); +#endif +}; + +#endif diff --git a/lib/ITEADLIB_Arduino_SIMCom/HWSerial.cpp b/lib/ITEADLIB_Arduino_SIMCom/HWSerial.cpp new file mode 100644 index 0000000..0adcb5c --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/HWSerial.cpp @@ -0,0 +1,346 @@ +#include "HWSerial.h" +#ifdef MEGA +HWSerial::HWSerial() +{ + Serial1.begin(9600); + +} +/* +bool HWSerial::listen(){ + return Serial1.listen(); +} +*/ +void HWSerial::end() +{ + Serial1.end(); +} +/* +bool HWSerial::isListening(){ + return Serial1.isListening(); +} + +bool HWSerial::overflow(){ + return Serial1.overflow(); +} +*/ +void HWSerial::begin(long baud_rate) +{ + Serial1.begin(baud_rate); +} + +int HWSerial::peek() +{ + return Serial1.peek(); +} + +size_t HWSerial::write(uint8_t byte) +{ + return Serial1.write(byte); +} + +int HWSerial::read() +{ + return Serial1.read(); +} + +int HWSerial::available() +{ + return Serial1.available(); +} + +void HWSerial::flush() +{ + Serial1.flush(); +} + + +/**************************************/ + + + +size_t HWSerial::print(const __FlashStringHelper *ifsh) +{ + const prog_char *p = (const prog_char *)ifsh; + size_t n = 0; + while (1) { + unsigned char c = pgm_read_byte(p++); + if (c == 0) break; + n += write(c); + } + return n; +} + +size_t HWSerial::print(const String &s) +{ + size_t n = 0; + for (uint16_t i = 0; i < s.length(); i++) { + n += write(s[i]); + } + return n; +} + +size_t HWSerial::print(const char str[]) +{ + return write(str); +} + +size_t HWSerial::print(char c) +{ + return write(c); +} + +size_t HWSerial::print(unsigned char b, int base) +{ + return print((unsigned long) b, base); +} + +size_t HWSerial::print(int n, int base) +{ + return print((long) n, base); +} + +size_t HWSerial::print(unsigned int n, int base) +{ + return print((unsigned long) n, base); +} + +size_t HWSerial::print(long n, int base) +{ + if (base == 0) { + return write(n); + } else if (base == 10) { + if (n < 0) { + int t = print('-'); + n = -n; + return printNumber(n, 10) + t; + } + return printNumber(n, 10); + } else { + return printNumber(n, base); + } +} + +size_t HWSerial::print(unsigned long n, int base) +{ + if (base == 0) return write(n); + else return printNumber(n, base); +} + +size_t HWSerial::print(double n, int digits) +{ + return printFloat(n, digits); +} + +size_t HWSerial::println(const __FlashStringHelper *ifsh) +{ + size_t n = print(ifsh); + n += println(); + return n; +} + + +size_t HWSerial::println(void) +{ + size_t n = print('\r'); + n += print('\n'); + return n; +} + +size_t HWSerial::println(const String &s) +{ + size_t n = print(s); + n += println(); + return n; +} + + +size_t HWSerial::println(const char c[]) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t HWSerial::println(char c) +{ + size_t n = print(c); + n += println(); + return n; +} + +size_t HWSerial::println(unsigned char b, int base) +{ + size_t n = print(b, base); + n += println(); + return n; +} + +size_t HWSerial::println(int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t HWSerial::println(unsigned int num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t HWSerial::println(long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t HWSerial::println(unsigned long num, int base) +{ + size_t n = print(num, base); + n += println(); + return n; +} + +size_t HWSerial::println(double num, int digits) +{ + size_t n = print(num, digits); + n += println(); + return n; +} + + +/******************************/ +size_t HWSerial::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + while (size--) { + n += write(*buffer++); + } + return n; +} + +size_t HWSerial::printNumber(unsigned long n, uint8_t base) +{ + char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte. + char *str = &buf[sizeof(buf) - 1]; + + *str = '\0'; + + // prevent crash if called with base == 1 + if (base < 2) base = 10; + + do { + unsigned long m = n; + n /= base; + char c = m - base * n; + *--str = c < 10 ? c + '0' : c + 'A' - 10; + } while(n); + + return write(str); +} + +size_t HWSerial::printFloat(double number, uint8_t digits) +{ + size_t n = 0; + + // Handle negative numbers + if (number < 0.0) { + n += print('-'); + number = -number; + } + + // Round correctly so that print(1.999, 2) prints as "2.00" + double rounding = 0.5; + for (uint8_t i=0; i 0) { + n += print("."); + } + + // Extract digits from the remainder one at a time + while (digits-- > 0) { + remainder *= 10.0; + int toPrint = int(remainder); + n += print(toPrint); + remainder -= toPrint; + } + + return n; +} + + + +boolean HWSerial::find(char *target) +{ + return findUntil(target, NULL); +} + + +boolean HWSerial::findUntil(char *target, char *terminate) +{ + byte targetLen = strlen(target); + byte index = 0; // maximum target string length is 255 bytes + byte termIndex = 0; + byte termLen = (terminate == NULL ? 0 : strlen(terminate)); + char c; + + if( *target == 0) + return true; // return true if target is a null string + while( (c = read()) != 0) { + if( c == target[index]) { + if(++index >= targetLen) { // return true if all chars in the target match + return true; + } + } else { + index = 0; // reset index if any char does not match + } + if(termLen > 0 && c == terminate[termIndex]) { + if(++termIndex >= termLen) + return false; // return false if terminate string found before target string + } else + termIndex = 0; + } + return false; +} + + + +int HWSerial::getString( char *pre_string, char *post_string, char *buffer, int length) +{ + if( find(pre_string) ) { + int index = 0; + *buffer = 0; + while(index < length-1 ) { + char c = read(); + if( c == 0 ) { + return 0; // timeout returns 0 ! + } else if( c == *post_string ) { + + while (index < length) { + buffer[index] = '\0'; // terminate the string !!!!!!!!!!!IT DOESN'T WORK!!!!!!!!!!!!!!!!! + index++; + } + + //buffer[index]=0; + return index; // data got successfully + } else { + buffer[index++] = c; + } + } + buffer[index] = 0; + return index; // Note: buffer full before the closing post_string encountered + } + return 0; //failed to find the prestring +} +#endif \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/HWSerial.h b/lib/ITEADLIB_Arduino_SIMCom/HWSerial.h new file mode 100644 index 0000000..8e8fef2 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/HWSerial.h @@ -0,0 +1,72 @@ +//#define MEGA + +#ifndef _HWSERIAL_H_ +#define _HWSERIAL_H_ + +#include "Arduino.h" +#include "Streaming.h" +#include + + +class HWSerial { +#ifdef MEGA +private: + int write_error; + size_t printNumber(unsigned long, uint8_t); + size_t printFloat(double, uint8_t); + +public: + HWSerial(); + + //bool listen(); + void end(); + /* + bool isListening(); + bool overflow(); + */ + int peek(); + virtual void begin(long baud_rate); + + virtual size_t write(uint8_t byte); + size_t write(const char *str) { + return write((const uint8_t *)str, strlen(str)); + } + virtual size_t write(const uint8_t *buffer, size_t size); + + virtual int read(); + virtual int available(); + virtual void flush(); + + size_t print(const __FlashStringHelper *); + size_t print(const String &); + size_t print(const char[]); + size_t print(char); + size_t print(unsigned char, int = DEC); + size_t print(int, int = DEC); + size_t print(unsigned int, int = DEC); + size_t print(long, int = DEC); + size_t print(unsigned long, int = DEC); + size_t print(double, int = 2); + + + size_t println(const __FlashStringHelper *); + size_t println(const String &s); + size_t println(const char[]); + size_t println(char); + size_t println(unsigned char, int = DEC); + size_t println(int, int = DEC); + size_t println(unsigned int, int = DEC); + size_t println(long, int = DEC); + size_t println(unsigned long, int = DEC); + size_t println(double, int = 2); + + size_t println(void); + + int getString( char *pre_string, char *post_string, char *buffer, int length); + boolean find(char *target); + boolean findUntil(char *target, char *terminate); + +#endif + +}; +#endif \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/LICENSE b/lib/ITEADLIB_Arduino_SIMCom/LICENSE new file mode 100644 index 0000000..d7f1051 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/LICENSE @@ -0,0 +1,339 @@ +GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {description} + Copyright (C) {year} {fullname} + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + {signature of Ty Coon}, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/lib/ITEADLIB_Arduino_SIMCom/LOG.cpp b/lib/ITEADLIB_Arduino_SIMCom/LOG.cpp new file mode 100644 index 0000000..7180f0f --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/LOG.cpp @@ -0,0 +1,59 @@ +/* + LOG.cpp - Library for standard logging convention. + Created by Meir Michanie, June 9, 2010. + Released into the public domain. + Version 0.1 +*/ + +#include "LOG.h" + +LOG::LOG(int level) +{ + setLevel(level); +} + +void LOG::DATA(const char* string) +{ + if (_level > 4) { + Serial.print(string); + } +} + +void LOG::DATA(int number) +{ + if (_level > 4) { + Serial.print(number); + } +} + +void LOG::DEBUG(const char* string) +{ + if (_level > 3) { + Serial.print("\n[DEBUG]: "); + Serial.println(string); + } +} + +void LOG::INFO(const char* string) +{ + if (_level > 2) { + Serial.print("\n[INFO]: "); + Serial.println(string); + } +} + +void LOG::WARNING(const char* string) +{ + if (_level > 1) { + Serial.print("\n[WARNING]: "); + Serial.println(string); + } +} + +void LOG::CRITICAL(const char* string) +{ + if (_level > 0) { + Serial.print("\n[CRITICAL]: "); + Serial.println(string); + } +} diff --git a/lib/ITEADLIB_Arduino_SIMCom/LOG.h b/lib/ITEADLIB_Arduino_SIMCom/LOG.h new file mode 100644 index 0000000..ae23942 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/LOG.h @@ -0,0 +1,33 @@ +/* + LOG.h - Library for standard logging convention. + Created by Meir Michanie, June 9, 2010. + Released into the public domain. + Version 0.1 +*/ + +#ifndef LOG_h +#define LOG_h +#include "Arduino.h" + +class LOG { +public: + LOG(int level); + void DEBUG(const char* string); + void INFO(const char* string); + void WARNING(const char* string); + void CRITICAL(const char* string); + void DATA(const char* string); + void DATA(int number); + + inline int getLevel(void) { + return _level; + } + inline void setLevel(int level) { + _level = level; + } + +private: + int _level; +}; + +#endif diff --git a/lib/ITEADLIB_Arduino_SIMCom/README b/lib/ITEADLIB_Arduino_SIMCom/README new file mode 100644 index 0000000..108739f --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/README @@ -0,0 +1,267 @@ +GSM GPRS Shield for Arduino Uno + +For informations and support: +http://www.gsmlib.org +http://code.google.com/p/gsm-shield-arduino/ (no longer supported) +http://www.open-electronics.org/arduino-gsm-shield/ +http://www.futurashop.it/ + +The below functions are always available in the library. + +int attachGPRS(char* domain, char* dom1, char* dom2) + establishes a GPRS connection with domain using authentication (if needed) + parameters and return values: + domain: pointer to a string that contains the domain address of GPRS connection + dom1: pointer to the username string (don't use if not needed) + dom2: pointer to the password string (don't use if not needed) + return: + 0 - unable to establish a GPRS connection + 1 - connection successfully established + +int dettachGPRS() + disconnects the GPRS connection + +int connectTCP(const char* server, int port) + starts a socket connection to the server at specific port + parameters and return values: + server: pointer to the server address string, it can be the IP or normal address + port: port used to establish a connection + e.g. gsm.connectTCP("www.google.it",80) + e.g. gsm.connectTCP("74.125.39.106",80) + return: + 0 - unable to start the TCP connection + 1 - connected to the server as client + Sample: GSM_GPRSLibrary_Client + +int disconnectTCP() + stops the TCP connection to the server + +int connectTCPServer(int port) + puts the SIM900 into server mode, waiting for TCP client connection on the specified port. + parameters and return values: + port: port used for establish a connection + return: + 0 - unable to start server connection + 1 - server started successfully, waiting for client connection + Sample: GSM_GPRSLibrary_Server + +void SimpleRead() + simple way to read from the newsoftserial and print the value on the hardware serial + Sample: GSM_GPRSLibrary_AT + +void SimpleWrite(char *comm) + simple way to write a string on newsoftserial + parameters and return values: + comm: pointer to the string to write + Sample: GSM_GPRSLibrary_AT + +For memory saving, next functions are included in a class, so before use them is needed to include the header and to create the class. + +For calling functions is necessary to include the next two lines +include "call.h"; +CallGSM call_classname; //the name you choose must be the same in the functions below + +void Call(char *number_string) + calls the specific number + e.g. call_classname.Call(“+390123456789″); + +void Call(int sim_position) + calls the number stored at the specified SIM position + e.g. call_classname.Call(1); // call to the number stored at the 1st SIM position + +void HangUp(void) + hangs up call(incoming or active) + e.g. call_classname.HangUp(); + +void PickUp(void) + picks up the incoming call + e.g. call_classname.PickUp(); + +For using SMS functions is necessary to include the next two lines +include "sms.h"; +SMSGSM sms_classname; //the name you choose must be the same in the functions below + +char SendSMS(char *number_str, char *message_str) + sends SMS to the specific phone number + parameters and return values: + number_str: pointer to the phone number string + message_str: pointer to the SMS text string + return: + ERROR ret. val: + ————— + -1 – comm. line to the GSM module is not free + -2 – GSM module didn’t answer in timeout + -3 – GSM module has answered “ERROR” string + OK ret val: + ———– + 0 – SMS was not sent + 1 – SMS was sent 9/15 + example of use: + sms_classname.SendSMS(“00XXXYYYYYYYYY”, “SMS text”); + +char SendSMS(byte sim_phonebook_position, char *message_str) + sends SMS to the specified SIM phonebook position + parameters and return values: + sim_phonebook_position: SIM phonebook position <1..20> + message_str: pointer to the SMS text string + return: + ERROR ret. val: + ————— + -1 – comm. line to the GSM module is not free + -2 – GSM module didn’t answer in timeout + -3 – specified position must be > 0 + OK ret val: + ———– + 0 – SMS was not sent + 1 – SMS was sent + an example of usage: + GSM gsm; + include "sms.h"; + SMSGSM sms_classname; + sms_classname.SendSMS(1, “SMS text”); + +char IsSMSPresent(byte required_status) + finds out if there is present at least one SMS with specified status + if there is new SMS before IsSMSPresent() is executed this SMS has a status UNREAD and then after calling IsSMSPresent() method status of SMS is automatically changed to READ + parameters and return values: + required_status: + SMS_UNREAD – new SMS – not read yet + SMS_READ – already read SMS + SMS_ALL – all stored SMS + return: + ERROR ret. val: + ————— + -1 – comm. line to the GSM module is not free + -2 – GSM module didn’t answer in timeout + OK ret val: + ———– + 0 – there is no SMS with specified status + 1..20 – position where SMS is stored + example of use: + char position; + char phone_number[20]; // array for the phone number string + char *sms_text; + position = sms_classname.IsSMSPresent(SMS_UNREAD); + if (position) { // read new SMS + sms_classname.GetGSM(position, tel_number, &sms_text); + } + +char GetSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len) + reads SMS from specified memory(SIM) position + parameters and return values: + position: SMS position <1..20> + phone_number: a pointer where the phone number string of received SMS will be placed + so the space for the phone number string must be reserved – see example + SMS_text : a pointer where SMS text will be placed + max_SMS_len: maximum length of SMS text excluding also string terminating 0×00 character + return: + ERROR ret. val: + ————— + -1 – comm. line to the GSM module is not free + -2 – GSM module didn’t answer in timeout + -3 – specified position must be > 0 + OK ret val: + ———– + GETSMS_NO_SMS – no SMS was found at the specified position + GETSMS_UNREAD_SMS – new SMS was found at the specified position + GETSMS_READ_SMS – already read SMS was found at the specified position + GETSMS_OTHER_SMS – other type of SMS was found an example of usage: + GSM gsm; + include "sms.h"; + SMSGSM sms_classname; + char position; + char phone_num[20]; // array for the phone number string + char sms_text[100]; // array for the SMS text string + position = sms_classname.IsSMSPresent(SMS_UNREAD); + if (position) { + // there is new SMS => read it + sms_classname.GetGSM(position, phone_num, sms_text, 100); + Serial.println(“DEBUG SMS phone number: “, 0); + Serial.println(phone_num, 0); + Serial.println(“\r\n SMS text: “, 0); + Serial.println(sms_text, 1); + } + +char GetAuthorizedSMS( byte position, char *phone_number, char *SMS_text, byte max_SMS_len, byte first_authorized_pos, byte last_authorized_pos) + reads SMS from specified memory(SIM) position and makes authorization - + it means SMS phone number is compared with specified SIM phonebook position(s) and in case numbers match GETSMS_AUTH_SMS is returned, otherwise GETSMS_NOT_AUTH_SMS is returned + parameters and return values: + position: SMS position to be read <1..20> + phone_number: a pointer where the tel. number string of received SMS will be placed so the space for the phone number string must be reserved – see example + SMS_text : a pointer where SMS text will be placed + max_SMS_len: maximum length of SMS text excluding terminating 0×00 character + first_authorized_pos: initial SIM phonebook position where the authorization process starts + last_authorized_pos: last SIM phonebook position where the authorization proces finishes + Note(important): + ================ + In case first_authorized_pos=0 and also last_authorized_pos=0 + the received SMS phone number is NOT authorized at all, so every + SMS is considered as authorized (GETSMS_AUTH_SMS is returned) + return: + ERROR ret. val: + ————— + -1 – comm. line to the GSM module is not free + -2 – GSM module didn’t answer in timeout + -3 – position must be > 0 + OK ret val: + ———– + GETSMS_NO_SMS – no SMS was found at the specified position + GETSMS_NOT_AUTH_SMS – NOT authorized SMS found at the specified position + GETSMS_AUTH_SMS – authorized SMS found at the specified position + an example of usage: + GSM gsm; + include "sms.h"; + SMSGSM sms_classname; + char phone_num[20]; // array for the phone number string 12/15 + char sms_text[100]; // array for the SMS text string + // authorize SMS with SIM phonebook positions 1..3 + if (GETSMS_AUTH_SMS == sms_classname.GetAuthorizedSMS(1, phone_num, sms_text, 100, 1, 3)) { + // new authorized SMS was detected at the SMS position 1 + Serial.println(“DEBUG SMS phone number: “, 0); + Serial.println(phone_num, 0); + Serial.println(“\r\n SMS text: “, 0); + Serial.println(sms_text, 1); + } + // don’t authorize SMS with SIM phonebook at all + if (GETSMS_AUTH_SMS == sms_classname.GetAuthorizedSMS(1, phone_num, sms_text, 100, 0, 0)) { + // new SMS was detected at the SMS position 1 + // because authorization was not required + // SMS is considered authorized + Serial.println(“DEBUG SMS phone number: “, 0); + Serial.println(phone_num, 0); + Serial.println(“\r\n SMS text: “, 0); + Serial.println(sms_text, 1); + } + +char DeleteSMS(byte position) + deletes SMS from specified SMS position + parameters and return values: + position: SMS position <1..20> + return: + ERROR ret. val: + ————— + -1 – comm. line to the GSM module is not free + -2 – GSM module didn’t answer in timeout + -3 – position must be > 0 + OK ret val: + ———– + 0 – SMS was not deleted + 1 – SMS was deleted + +For HTTP functions is necessary to include the next two lines +include "inetGSM.h"; +inetGSM inet_classname; //the name you choose must be the same in the functions below + +int httpGET(const char* server, int port, const char* path, char* result, int resultlength) + Send a GET request to server, at specified port, for the requested path and save the reply in a string + parameters and return values: + server: the name or IP address of the server + port: number of port used for the connection + path: pointer to the string that contains the requested path e.g. / or /test/test.html + result: pointer to the reply string from the server + resultlength: size of the string with result + return: + 0 - nothing received, maybe there is an error + other - number of byte received + Sample: GSM_GPRSLibrary_Client + diff --git a/lib/ITEADLIB_Arduino_SIMCom/README.md b/lib/ITEADLIB_Arduino_SIMCom/README.md new file mode 100644 index 0000000..3574ba0 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/README.md @@ -0,0 +1,48 @@ +GSM GPRS GPS Bluetooth for SIM800/808/900/908 Library +====== + +# Related Product + +## Mainboard: + + - Gboard (no bluetooth) http://imall.iteadstudio.com/im120411004.html + - Gboard Pro (no bluetooth) http://imall.iteadstudio.com/im130514001.html + - Gboard 800 http://imall.iteadstudio.com/im141125007.html + - Gboard Pro 800 http://imall.iteadstudio.com/im141125008.html + +## Module: + + - SIM900/SIM900A GSM/GPRS Minimum System Module (no bluetooth) http://imall.iteadstudio.com/im140318007.html + - SIM808 GSM/GPRS/GPS Module http://imall.iteadstudio.com/im141125004.html + - SIM908 GSM/GPRS/GPS Module (no bluetooth) http://imall.iteadstudio.com/sim908-gsm-gprs-gps-module.html + + + +### LICENSE: +GNU GPL v3 except where noted otherwise. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +### Contributers: + +Contributions have been made by the following organizations: +- [GSMLIB.org](http://www.gsmlib.org) +- [Open-Electronics](http://www.open-electronics.org/arduino-gsm-shield/) +- [Futura Elettronica](http://www.futurashop.it) +- [Hwkitchen](http://www.hwkitchen.com) + +As well as, but not limited to, the following individuals: + - [@MarcoMartines](https://github.com/MarcoMartines) + - [@madmaze](https://github.com/madmaze) + - commiters from google code: https://code.google.com/p/gsm-shield-arduino/people/list +names listed in no particular order. diff --git a/lib/ITEADLIB_Arduino_SIMCom/SIM900.cpp b/lib/ITEADLIB_Arduino_SIMCom/SIM900.cpp new file mode 100644 index 0000000..7c2ee12 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/SIM900.cpp @@ -0,0 +1,1009 @@ +#include "SIM900.h" +#include "Streaming.h" + +#define _GSM_CONNECTION_TOUT_ 5 +#define _TCP_CONNECTION_TOUT_ 20 +#define _GSM_DATA_TOUT_ 10 + +//#define RESETPIN 7 + +SIMCOM900 gsm; +SIMCOM900::SIMCOM900() {}; +SIMCOM900::~SIMCOM900() {}; + +/********************************************************** +Function: This function premits to wake up the module + (only for SIM908) when it goes in energy saving + mode. + +Author: Marco Martines +Created: unknown +Modified: 18/02/2014 + +Output: none + +Comments: It would be nice to call this function + automatically when gsm.begin is called (of course + only if a SIM908 is used). +**********************************************************/ + +char SIMCOM900::forceON() +{ + char ret_val=0; + char *p_char; + char *p_char1; + + SimpleWriteln(F("AT+CREG?")); + WaitResp(5000, 100, str_ok); + if(IsStringReceived(str_ok)) { + ret_val=1; + } + + p_char = strchr((char *)(gsm.comm_buf),','); + p_char1 = p_char+1; + *(p_char1+2)=0; + p_char = strchr((char *)(p_char1), ','); + if (p_char != NULL) { + *p_char = 0; + } + + if((*p_char1)=='4') { + digitalWrite(GSM_ON, HIGH); + delay(1200); + digitalWrite(GSM_ON, LOW); + delay(10000); + ret_val=2; + } + + return ret_val; +} + +int SIMCOM900::configandwait(char* pin) +{ + int connCode; + //_tf.setTimeout(_GSM_CONNECTION_TOUT_); + + if(pin) setPIN(pin); //syv + + // Try 10 times to register in the network. Note this can take some time! + for(int i=0; i<10; i++) { + //Ask for register status to GPRS network. + SimpleWriteln(F("AT+CGREG?")); + + //Se espera la unsolicited response de registered to network. + while(gsm.WaitResp(5000, 50, "+CGREG: 0,")!=RX_FINISHED_STR_RECV) + //while (_tf.find("+CGREG: 0,")) // CHANGE!!!! + { + //connCode=_tf.getValue(); + connCode=_cell.read(); + if((connCode==1)||(connCode==5)) { + setStatus(READY); + + SimpleWriteln(F("AT+CMGF=1")); //SMS text mode. + delay(200); + // Buah, we should take this to readCall() + SimpleWriteln(F("AT+CLIP=1")); //SMS text mode. + delay(200); + //_cell << "AT+QIDEACT" << _DEC(cr) << endl; //To make sure not pending connection. + //delay(1000); + + return 1; + } + } + } + return 0; +} + +/** + * SIMCOM900::read(char* buffer, int buffersize) + * + * Waits for data to be readable from the gsm module, reads data until + * no more is available or the buffer has been filled + * + * returns number of bytes read + * + */ +int SIMCOM900::read(char* result, int resultlength) +{ + char temp; + int i=0; + +#ifdef DEBUG_ON + Serial.print(F("Starting read..\nWaiting for Data..")); +#endif + // Wait until we start receiving data + while(gsm.available()<1) { + delay(100); +#ifdef DEBUG_ON + Serial.print(F(".")); +#endif + } + + while(gsm.available()>0 && i<(resultlength-1)) { + temp=_cell.read(); + if(temp>0) { +#ifdef DEBUG_ON + Serial.print(temp); +#endif + result[i]=temp; + i++; + } + delay(1); + } + + // Terminate the string + result[resultlength-1]='\0'; + +#ifdef DEBUG_ON + Serial.println(F("\nDone..")); +#endif + return i; +} + +int SIMCOM900::readCellData(int &mcc, int &mnc, long &lac, long &cellid) +{ + if (getStatus()==IDLE) + return 0; + + //_tf.setTimeout(_GSM_DATA_TOUT_); + //_cell.flush(); + SimpleWriteln(F("AT+QENG=1,0")); + SimpleWriteln(F("AT+QENG?")); + if(gsm.WaitResp(5000, 50, "+QENG")!=RX_FINISHED_STR_NOT_RECV) + return 0; + + //mcc=_tf.getValue(); // The first one is 0 + mcc=_cell.read(); + //mcc=_tf.getValue(); + mcc=_cell.read(); + //mnc=_tf.getValue(); + mnc=_cell.read(); + //lac=_tf.getValue(); + lac=_cell.read(); + //cellid=_tf.getValue(); + cellid=_cell.read(); + + gsm.WaitResp(5000, 50, "+OK"); + SimpleWriteln(F("AT+QENG=1,0")); + gsm.WaitResp(5000, 50, "+OK"); + return 1; +} + +boolean SIMCOM900::readSMS(char* msg, int msglength, char* number, int nlength) +{ + Serial.println(F("This method is deprecated! Please use GetSMS in the SMS class.")); + long index; + char *p_char; + char *p_char1; + + /* + if (getStatus()==IDLE) + return false; + */ +#ifdef UNO + _tf.setTimeout(_GSM_DATA_TOUT_); +#endif + //_cell.flush(); + WaitResp(500, 500); + SimpleWriteln(F("AT+CMGL=\"REC UNREAD\",1")); + + WaitResp(5000, 500); + if(gsm.IsStringReceived("+CMGL")) { + + //index + p_char = strchr((char *)(gsm.comm_buf),'+CMGL'); + p_char1 = p_char+3; //we are on the first char of string + p_char = p_char1+1; + *p_char = 0; + index=atoi(p_char1); + + p_char1 = p_char+1; + p_char = strstr((char *)(p_char1), "\",\""); + p_char1 = p_char+3; + p_char = strstr((char *)(p_char1), "\",\""); + if (p_char != NULL) { + *p_char = 0; + } + strcpy(number, (char *)(p_char1)); + ////// + + p_char1 = p_char+3; + p_char = strstr((char *)(p_char1), "\",\""); + p_char1 = p_char+3; + + p_char = strstr((char *)(p_char1), "\n"); + p_char1 = p_char+1; + p_char = strstr((char *)(p_char1), "\n"); + if (p_char != NULL) { + *p_char = 0; + } + strcpy(msg, (char *)(p_char1)); + + // #ifdef UNO + // index=_tf.getValue(); + // #endif + // #ifdef MEGA + //index=_cell.read(); + // #endif + // Serial.println("DEBUG"); + // #ifdef UNO + // _tf.getString("\",\"", "\"", number, nlength); + // #endif + // Serial.println("PRIMA"); + // #ifdef MEGA + // _cell.getString("\",\"", "\"", number, nlength); + // #endif + // Serial.println("DEBUG"); + // #ifdef UNO + // _tf.getString("\n", "\nOK", msg, msglength); + // #endif + // #ifdef MEGA + // _cell.getString("\n", "\nOK", msg, msglength); + // #endif + + SimpleWrite(F("AT+CMGD=")); + SimpleWriteln(index); + // Serial.print("VAL= "); + // Serial.println(index); + gsm.WaitResp(5000, 50, str_ok); + return true; + }; + return false; +}; + +boolean SIMCOM900::readCall(char* number, int nlength) +{ + int index; + + if (getStatus()==IDLE) + return false; + + //_tf.setTimeout(_GSM_DATA_TOUT_); + if(gsm.WaitResp(5000, 50, "+CLIP: \"")!=RX_FINISHED_STR_RECV) + //if(_tf.find("+CLIP: \"")) + { +#ifdef UNO + _tf.getString("", "\"", number, nlength); +#endif +#ifdef MEGA + _cell.getString("", "\"", number, nlength); +#endif + SimpleWriteln(F("ATH")); + delay(1000); + //_cell.flush(); + return true; + }; + return false; +}; + +boolean SIMCOM900::call(char* number, unsigned int milliseconds) +{ + if (getStatus()==IDLE) + return false; + + //_tf.setTimeout(_GSM_DATA_TOUT_); + + SimpleWrite(F("ATD")); + SimpleWrite(number); + SimpleWriteln(F(";")); + delay(milliseconds); + SimpleWriteln(F("ATH")); + + return true; + +} + +int SIMCOM900::setPIN(char *pin) +{ + //Status = READY or ATTACHED. + if((getStatus() != IDLE)) + return 2; + + //_tf.setTimeout(_GSM_DATA_TOUT_); //Timeout for expecting modem responses. + + //_cell.flush(); + + //AT command to set PIN. + SimpleWrite(F("AT+CPIN=")); + SimpleWriteln(pin); + + //Expect str_ok. + + if(gsm.WaitResp(5000, 50, str_ok)!=RX_FINISHED_STR_NOT_RECV) + return 0; + else + return 1; +} + +int SIMCOM900::changeNSIPmode(char mode) +{ + //_tf.setTimeout(_TCP_CONNECTION_TOUT_); + + //if (getStatus()!=ATTACHED) + // return 0; + + //_cell.flush(); + + SimpleWrite(F("AT+QIDNSIP=")); + SimpleWriteln(mode); + if(gsm.WaitResp(5000, 50, str_ok)!=RX_FINISHED_STR_NOT_RECV) return 0; + //if(!_tf.find(str_ok)) return 0; + + return 1; +} + +int SIMCOM900::getCCI(char *cci) +{ + //Status must be READY + if((getStatus() != READY)) + return 2; + + //_tf.setTimeout(_GSM_DATA_TOUT_); //Timeout for expecting modem responses. + + //_cell.flush(); + + //AT command to get CCID. + SimpleWriteln(F("AT+QCCID")); + + //Read response from modem +#ifdef UNO + _tf.getString("AT+QCCID\r\r\r\n","\r\n",cci, 21); +#endif +#ifdef MEGA + _cell.getString("AT+QCCID\r\r\r\n","\r\n",cci, 21); +#endif + + //Expect str_ok. + if(gsm.WaitResp(5000, 50, str_ok)!=RX_FINISHED_STR_NOT_RECV) + return 0; + else + return 1; +} + +int SIMCOM900::getIMEI(char *imei) +{ + + //_tf.setTimeout(_GSM_DATA_TOUT_); //Timeout for expecting modem responses. + + //_cell.flush(); + + //AT command to get IMEI. + SimpleWriteln(F("AT+GSN")); + + //Read response from modem +#ifdef UNO + _tf.getString("\r\n","\r\n",imei, 16); +#endif +#ifdef MEGA + _cell.getString("\r\n","\r\n",imei, 16); +#endif + + //Expect str_ok. + if(gsm.WaitResp(5000, 50, str_ok)!=RX_FINISHED_STR_NOT_RECV) + return 0; + else + return 1; +} + +int SIMCOM900::available() +{ + return _cell.available(); +} + +uint8_t SIMCOM900::read() +{ + return _cell.read(); +} + +void SIMCOM900::SimpleRead() +{ + char datain; + if(_cell.available()>0) { + datain=_cell.read(); + if(datain>0) { + Serial.print(datain); + } + } +} + +void SIMCOM900::SimpleWrite(char *comm) +{ + _cell.print(comm); +} + +void SIMCOM900::SimpleWrite(const char *comm) +{ + _cell.print(comm); +} + +void SIMCOM900::SimpleWrite(int comm) +{ + _cell.print(comm); +} + +void SIMCOM900::SimpleWrite(const __FlashStringHelper *pgmstr) +{ + _cell.print(pgmstr); +} + +void SIMCOM900::SimpleWriteln(char *comm) +{ + _cell.println(comm); +} + +void SIMCOM900::SimpleWriteln(const __FlashStringHelper *pgmstr) +{ + _cell.println(pgmstr); +} + +void SIMCOM900::SimpleWriteln(char const *comm) +{ + _cell.println(comm); +} + +void SIMCOM900::SimpleWriteln(int comm) +{ + _cell.println(comm); +} + +void SIMCOM900::WhileSimpleRead() +{ + char datain; + while(_cell.available()>0) { + datain=_cell.read(); + if(datain>0) { + Serial.print(datain); + } + } +} + +//--------------------------------------------- +/********************************************************** +Turns on/off the speaker + +off_on: 0 - off + 1 - on +**********************************************************/ +void GSM::SetSpeaker(byte off_on) +{ + if (CLS_FREE != GetCommLineStatus()) return; + SetCommLineStatus(CLS_ATCMD); + if (off_on) { + //SendATCmdWaitResp("AT#GPIO=5,1,2", 500, 50, "#GPIO:", 1); + } else { + //SendATCmdWaitResp("AT#GPIO=5,0,2", 500, 50, "#GPIO:", 1); + } + SetCommLineStatus(CLS_FREE); +} + + +byte GSM::IsRegistered(void) +{ + return (module_status & STATUS_REGISTERED); +} + +byte GSM::IsInitialized(void) +{ + return (module_status & STATUS_INITIALIZED); +} + + +/********************************************************** +Method checks if the GSM module is registered in the GSM net +- this method communicates directly with the GSM module + in contrast to the method IsRegistered() which reads the + flag from the module_status (this flag is set inside this method) + +- must be called regularly - from 1sec. to cca. 10 sec. + +return values: + REG_NOT_REGISTERED - not registered + REG_REGISTERED - GSM module is registered + REG_NO_RESPONSE - GSM doesn't response + REG_COMM_LINE_BUSY - comm line between GSM module and Arduino is not free + for communication +**********************************************************/ +byte GSM::CheckRegistration(void) +{ + byte status; + byte ret_val = REG_NOT_REGISTERED; + + if (CLS_FREE != GetCommLineStatus()) return (REG_COMM_LINE_BUSY); + SetCommLineStatus(CLS_ATCMD); + _cell.println(F("AT+CREG?")); + // 5 sec. for initial comm tmout + // 50 msec. for inter character timeout + status = WaitResp(5000, 50); + + if (status == RX_FINISHED) { + // something was received but what was received? + // --------------------------------------------- + if(IsStringReceived("+CREG: 0,1") + || IsStringReceived("+CREG: 0,5")) { + // it means module is registered + // ---------------------------- + module_status |= STATUS_REGISTERED; + + + // in case GSM module is registered first time after reset + // sets flag STATUS_INITIALIZED + // it is used for sending some init commands which + // must be sent only after registration + // -------------------------------------------- + if (!IsInitialized()) { + module_status |= STATUS_INITIALIZED; + SetCommLineStatus(CLS_FREE); + InitParam(PARAM_SET_1); + } + ret_val = REG_REGISTERED; + } else { + // NOT registered + // -------------- + module_status &= ~STATUS_REGISTERED; + ret_val = REG_NOT_REGISTERED; + } + } else { + // nothing was received + // -------------------- + ret_val = REG_NO_RESPONSE; + } + SetCommLineStatus(CLS_FREE); + + + return (ret_val); +} + + +/********************************************************** +Method sets speaker volume + +speaker_volume: volume in range 0..14 + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module did not answer in timeout + -3 - GSM module has answered "ERROR" string + + OK ret val: + ----------- + 0..14 current speaker volume +**********************************************************/ +/* +char GSM::SetSpeakerVolume(byte speaker_volume) +{ + + char ret_val = -1; + + if (CLS_FREE != GetCommLineStatus()) return (ret_val); + SetCommLineStatus(CLS_ATCMD); + // remember set value as last value + if (speaker_volume > 14) speaker_volume = 14; + // select speaker volume (0 to 14) + // AT+CLVL=X X<0..14> + _cell.print("AT+CLVL="); + _cell.print((int)speaker_volume); + _cell.print("\r"); // send + // 10 sec. for initial comm tmout + // 50 msec. for inter character timeout + if (RX_TMOUT_ERR == WaitResp(10000, 50)) { + ret_val = -2; // ERROR + } + else { + if(IsStringReceived(str_ok)) { + last_speaker_volume = speaker_volume; + ret_val = last_speaker_volume; // OK + } + else ret_val = -3; // ERROR + } + + SetCommLineStatus(CLS_FREE); + return (ret_val); +} +*/ +/********************************************************** +Method increases speaker volume + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module did not answer in timeout + -3 - GSM module has answered "ERROR" string + + OK ret val: + ----------- + 0..14 current speaker volume +**********************************************************/ +/* +char GSM::IncSpeakerVolume(void) +{ + char ret_val; + byte current_speaker_value; + + current_speaker_value = last_speaker_volume; + if (current_speaker_value < 14) { + current_speaker_value++; + ret_val = SetSpeakerVolume(current_speaker_value); + } + else ret_val = 14; + + return (ret_val); +} +*/ +/********************************************************** +Method decreases speaker volume + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module did not answer in timeout + -3 - GSM module has answered "ERROR" string + + OK ret val: + ----------- + 0..14 current speaker volume +**********************************************************/ +/* +char GSM::DecSpeakerVolume(void) +{ + char ret_val; + byte current_speaker_value; + + current_speaker_value = last_speaker_volume; + if (current_speaker_value > 0) { + current_speaker_value--; + ret_val = SetSpeakerVolume(current_speaker_value); + } + else ret_val = 0; + + return (ret_val); +} +*/ + +/********************************************************** +Method sends DTMF signal +This function only works when call is in progress + +dtmf_tone: tone to send 0..15 + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - GSM module has answered "ERROR" string + + OK ret val: + ----------- + 0.. tone +**********************************************************/ +/* +char GSM::SendDTMFSignal(byte dtmf_tone) +{ + char ret_val = -1; + + if (CLS_FREE != GetCommLineStatus()) return (ret_val); + SetCommLineStatus(CLS_ATCMD); + // e.g. AT+VTS=5 + _cell.print("AT+VTS="); + _cell.print((int)dtmf_tone); + _cell.print("\r"); + // 1 sec. for initial comm tmout + // 50 msec. for inter character timeout + if (RX_TMOUT_ERR == WaitResp(1000, 50)) { + ret_val = -2; // ERROR + } + else { + if(IsStringReceived(str_ok)) { + ret_val = dtmf_tone; // OK + } + else ret_val = -3; // ERROR + } + + SetCommLineStatus(CLS_FREE); + return (ret_val); +} +*/ + +/********************************************************** +Method returns state of user button + + +return: 0 - not pushed = released + 1 - pushed +**********************************************************/ +byte GSM::IsUserButtonPushed(void) +{ + byte ret_val = 0; + if (CLS_FREE != GetCommLineStatus()) return(0); + SetCommLineStatus(CLS_ATCMD); + //if (AT_RESP_OK == SendATCmdWaitResp("AT#GPIO=9,2", 500, 50, "#GPIO: 0,0", 1)) { + // user button is pushed + // ret_val = 1; + //} + //else ret_val = 0; + //SetCommLineStatus(CLS_FREE); + //return (ret_val); +} + + + +/********************************************************** +Method reads phone number string from specified SIM position + +position: SMS position <1..20> + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - position must be > 0 + phone_number is empty string + + OK ret val: + ----------- + 0 - there is no phone number on the position + 1 - phone number was found + phone_number is filled by the phone number string finished by 0x00 + so it is necessary to define string with at least + 15 bytes(including also 0x00 termination character) + +an example of usage: + GSM gsm; + char phone_num[20]; // array for the phone number string + + if (1 == gsm.GetPhoneNumber(1, phone_num)) { + // valid phone number on SIM pos. #1 + // phone number string is copied to the phone_num array + #ifdef DEBUG_PRINT + gsm.DebugPrint("DEBUG phone number: ", 0); + gsm.DebugPrint(phone_num, 1); + #endif + } + else { + // there is not valid phone number on the SIM pos.#1 + #ifdef DEBUG_PRINT + gsm.DebugPrint("DEBUG there is no phone number", 1); + #endif + } +**********************************************************/ + + +char GSM::GetPhoneNumber(byte position, char *phone_number) +{ + char ret_val = -1; + + char *p_char; + char *p_char1; + + if (position == 0) return (-3); + if (CLS_FREE != GetCommLineStatus()) return (ret_val); + SetCommLineStatus(CLS_ATCMD); + ret_val = 0; // not found yet + phone_number[0] = 0; // phone number not found yet => empty string + + //send "AT+CPBR=XY" - where XY = position + _cell.print(F("AT+CPBR=")); + _cell.print((int)position); + _cell.print("\r"); + + // 5000 msec. for initial comm tmout + // 50 msec. for inter character timeout + switch (WaitResp(5000, 50, "+CPBR")) { + case RX_TMOUT_ERR: + // response was not received in specific time + ret_val = -2; + break; + + case RX_FINISHED_STR_RECV: + // response in case valid phone number stored: + // +CPBR: ,,, + // OK + + // response in case there is not phone number: + // OK + p_char = strstr((char *)(comm_buf),",\""); + if (p_char != NULL) { + p_char++; + p_char++; // we are on the first phone number character + // find out '"' as finish character of phone number string + p_char1 = strchr((char *)(p_char),'"'); + if (p_char1 != NULL) { + *p_char1 = 0; // end of string + } + // extract phone number string + strcpy(phone_number, (char *)(p_char)); + // output value = we have found out phone number string + ret_val = 1; + } + break; + + case RX_FINISHED_STR_NOT_RECV: + // only OK or ERROR => no phone number + ret_val = 0; + break; + } + + SetCommLineStatus(CLS_FREE); + return (ret_val); +} + +/********************************************************** +Method writes phone number string to the specified SIM position + +position: SMS position <1..20> +phone_number: phone number string for the writing + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - position must be > 0 + + OK ret val: + ----------- + 0 - phone number was not written + 1 - phone number was written +**********************************************************/ +char GSM::WritePhoneNumber(byte position, char *phone_number) +{ + char ret_val = -1; + + if (position == 0) return (-3); + if (CLS_FREE != GetCommLineStatus()) return (ret_val); + SetCommLineStatus(CLS_ATCMD); + ret_val = 0; // phone number was not written yet + + //send: AT+CPBW=XY,"00420123456789" + // where XY = position, + // "00420123456789" = phone number string + _cell.print(F("AT+CPBW=")); + _cell.print((int)position); + _cell.print(F(",\"")); + _cell.print(phone_number); + _cell.print(F("\"\r")); + + // 5000 msec. for initial comm tmout + // 50 msec. for inter character timeout + switch (WaitResp(5000, 50, str_ok)) { + case RX_TMOUT_ERR: + // response was not received in specific time + break; + + case RX_FINISHED_STR_RECV: + // response is OK = has been written + ret_val = 1; + break; + + case RX_FINISHED_STR_NOT_RECV: + // other response: e.g. ERROR + break; + } + + SetCommLineStatus(CLS_FREE); + return (ret_val); +} + + +/********************************************************** +Method del phone number from the specified SIM position + +position: SMS position <1..20> + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - position must be > 0 + + OK ret val: + ----------- + 0 - phone number was not deleted + 1 - phone number was deleted +**********************************************************/ +char GSM::DelPhoneNumber(byte position) +{ + char ret_val = -1; + + if (position == 0) return (-3); + if (CLS_FREE != GetCommLineStatus()) return (ret_val); + SetCommLineStatus(CLS_ATCMD); + ret_val = 0; // phone number was not written yet + + //send: AT+CPBW=XY + // where XY = position + _cell.print(F("AT+CPBW=")); + _cell.print((int)position); + _cell.print(F("\r")); + + // 5000 msec. for initial comm tmout + // 50 msec. for inter character timeout + switch (WaitResp(5000, 50, str_ok)) { + case RX_TMOUT_ERR: + // response was not received in specific time + break; + + case RX_FINISHED_STR_RECV: + // response is OK = has been written + ret_val = 1; + break; + + case RX_FINISHED_STR_NOT_RECV: + // other response: e.g. ERROR + break; + } + + SetCommLineStatus(CLS_FREE); + return (ret_val); +} + + + + + +/********************************************************** +Function compares specified phone number string +with phone number stored at the specified SIM position + +position: SMS position <1..20> +phone_number: phone number string which should be compare + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - position must be > 0 + + OK ret val: + ----------- + 0 - phone numbers are different + 1 - phone numbers are the same + + +an example of usage: + if (1 == gsm.ComparePhoneNumber(1, "123456789")) { + // the phone num. "123456789" is stored on the SIM pos. #1 + // phone number string is copied to the phone_num array + #ifdef DEBUG_PRINT + gsm.DebugPrint("DEBUG phone numbers are the same", 1); + #endif + } + else { + #ifdef DEBUG_PRINT + gsm.DebugPrint("DEBUG phone numbers are different", 1); + #endif + } +**********************************************************/ +char GSM::ComparePhoneNumber(byte position, char *phone_number) +{ + char ret_val = -1; + char sim_phone_number[20]; + + + ret_val = 0; // numbers are not the same so far + if (position == 0) return (-3); + if (1 == GetPhoneNumber(position, sim_phone_number)) { + //Serial.print("CHIAMANTE "); + //Serial.println(phone_number); + //Serial.print("SALVATO "); + //Serial.println(sim_phone_number); + + // there is a valid number at the spec. SIM position + // ------------------------------------------------- + if (0 == strcmp(phone_number, sim_phone_number)) { + // phone numbers are the same + // -------------------------- + ret_val = 1; + } + } + return (ret_val); +} + +//----------------------------------------------------- diff --git a/lib/ITEADLIB_Arduino_SIMCom/SIM900.h b/lib/ITEADLIB_Arduino_SIMCom/SIM900.h new file mode 100644 index 0000000..ecb4cea --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/SIM900.h @@ -0,0 +1,42 @@ +#ifndef SIMCOM900_H +#define SIMCOM900_H +#include +#include "HWSerial.h" +#include "GSM.h" +class SIMCOM900 : public virtual GSM { + +private: + int configandwait(char* pin); + int setPIN(char *pin); + int changeNSIPmode(char); + +public: + SIMCOM900(); + ~SIMCOM900(); + int getCCI(char* cci); + int getIMEI(char* imei); + int sendSMS(const char* to, const char* msg); + boolean readSMS(char* msg, int msglength, char* number, int nlength); + boolean readCall(char* number, int nlength); + boolean call(char* number, unsigned int milliseconds); + char forceON(); + virtual int read(char* result, int resultlength); + virtual uint8_t read(); + virtual int available(); + int readCellData(int &mcc, int &mnc, long &lac, long &cellid); + void SimpleRead(); + void WhileSimpleRead(); + void SimpleWrite(char *comm); + void SimpleWrite(char const *comm); + void SimpleWrite(int comm); + void SimpleWrite(const __FlashStringHelper *pgmstr); + void SimpleWriteln(char *comm); + void SimpleWriteln(char const *comm); + void SimpleWriteln(const __FlashStringHelper *pgmstr); + void SimpleWriteln(int comm); +}; + +extern SIMCOM900 gsm; + +#endif + diff --git a/lib/ITEADLIB_Arduino_SIMCom/Streaming.h b/lib/ITEADLIB_Arduino_SIMCom/Streaming.h new file mode 100644 index 0000000..154a5f1 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/Streaming.h @@ -0,0 +1,95 @@ +/* +Streaming.h - Arduino library for supporting the << streaming operator +Copyright (c) 2010 Mikal Hart. All rights reserved. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef ARDUINO_STREAMING +#define ARDUINO_STREAMING + +#include +#include "LOG.h" + +#define __ST_LOG_LEVEL 3 +static LOG _st_logme(__ST_LOG_LEVEL); + +// Generic template +template +inline Print &operator <<(Print &stream, T arg) +{ + stream.print(arg); + _st_logme.DATA(arg); + return stream; +} + +struct _BASED { + long val; + int base; + _BASED(long v, int b): val(v), base(b) + {} +}; + +#define _HEX(a) _BASED(a, HEX) +#define _DEC(a) _BASED(a, DEC) +#define _OCT(a) _BASED(a, OCT) +#define _BIN(a) _BASED(a, BIN) + +// Specialization for class _BASED +// Thanks to Arduino forum user Ben Combee who suggested this +// clever technique to allow for expressions like +// Serial << _HEX(a); + +inline Print &operator <<(Print &obj, const _BASED &arg) +{ + obj.print(arg.val); + return obj; +} + +#if ARDUINO >= 18 +// Specialization for class _FLOAT +// Thanks to Michael Margolis for suggesting a way +// to accommodate Arduino 0018's floating point precision +// feature like this: +// Serial << _FLOAT(gps_latitude, 6); // 6 digits of precision + +struct _FLOAT { + float val; + int digits; + _FLOAT(double v, int d): val(v), digits(d) + {} +}; + +inline Print &operator <<(Print &obj, const _FLOAT &arg) +{ + obj.print(arg.val, arg.digits); + return obj; +} +#endif + +// Specialization for enum _EndLineCode +// Thanks to Arduino forum user Paul V. who suggested this +// clever technique to allow for expressions like +// Serial << "Hello!" << endl; + +enum _EndLineCode { endl }; + +inline Print &operator <<(Print &obj, _EndLineCode arg) +{ + obj.println(); + return obj; +} + +#endif diff --git a/lib/ITEADLIB_Arduino_SIMCom/WideTextFinder.cpp b/lib/ITEADLIB_Arduino_SIMCom/WideTextFinder.cpp new file mode 100644 index 0000000..96fdffc --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/WideTextFinder.cpp @@ -0,0 +1,196 @@ +#include "WideTextFinder.h" + +#define NO_SKIP_CHAR 1 // a magic char not found in a valid numeric field + +// private function to read characters from stream +// the constructors allow one and only one of the streams to be initialized +char WideTextFinder::read() +{ + char r; + startMillis = millis(); + if (nSerialStream != NULL) { + while(millis() < (startMillis + timeout)) { + if (nSerialStream->available() > 0) { + r=nSerialStream->read(); + //if(debug) + //Serial.print(r); + return r; + } + } + } + return 0; // 0 indicates timeout +} + +// constructors +//default timeout is 5 seconds + +WideTextFinder::WideTextFinder(SoftwareSerial &stream, int timeout) : + nSerialStream(&stream) +{ + this->timeout = timeout * 1000L; + debug=true; +} + +void WideTextFinder::setDebug(boolean d) +{ + debug=d; +} + +// public methods +// +// find returns true if the target string is found +boolean WideTextFinder::find(char *target) +{ + return findUntil(target, NULL); +} + +// as above but search ends if the terminate string is found +boolean WideTextFinder::findUntil(char *target, char *terminate) +{ + byte targetLen = strlen(target); + byte index = 0; // maximum target string length is 255 bytes + byte termIndex = 0; + byte termLen = (terminate == NULL ? 0 : strlen(terminate)); + char c; + + if( *target == 0) + return true; // return true if target is a null string + while( (c = read()) != 0) { + if( c == target[index]) { + if(++index >= targetLen) { // return true if all chars in the target match + return true; + } + } else { + index = 0; // reset index if any char does not match + } + if(termLen > 0 && c == terminate[termIndex]) { + if(++termIndex >= termLen) + return false; // return false if terminate string found before target string + } else + termIndex = 0; + } + return false; +} + +// places the string between the prestring and poststring in the given buffer +// buffer must be one more than the longest string to get +// the string will be truncated to fit the buffer length +// end of string determined by a single character match to the first char of poststring +// returns the number of characters placed in the buffer (0 means no valid data found) +int WideTextFinder::getString( char *pre_string, char *post_string, char *buffer, int length) +{ + if( find(pre_string) ) { + int index = 0; + *buffer = 0; + while(index < length-1 ) { + char c = read(); + if( c == 0 ) { + return 0; // timeout returns 0 ! + } else if( c == *post_string ) { + + while (index < length) { + buffer[index] = '\0'; // terminate the string !!!!!!!!!!!IT DOESN'T WORK!!!!!!!!!!!!!!!!! + index++; + } + + //buffer[index]=0; + return index; // data got successfully + } else { + buffer[index++] = c; + } + } + buffer[index] = 0; + return index; // Note: buffer full before the closing post_string encountered + } + return 0; //failed to find the prestring +} + +// getValue method: +// returns the first valid (long) integer value from the current position. +// initial characters that are not digits (or the minus sign) are skipped +// function is terminated by the first character that is not a digit. +long WideTextFinder::getValue() +{ + return getValue(NO_SKIP_CHAR); // terminate on first non-digit character +} + +// as above but a given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +long WideTextFinder::getValue(char skipChar) +{ + boolean isNegative = false; + long value = 0; + char c; + + while( (c = read()) != '-' && (c < '0' || c > '9') && (c!=0) ) + ;// ignore non numeric leading characters + do { + if(c == skipChar ) + ; // ignore this charactor + else if (c==0) // Timeout + return 0; + else if(c == '-') + isNegative = true; + else if(c >= '0' && c <= '9') // is c a digit? + value = value * 10 + c - '0'; + c = read(); + } while( (c >= '0' && c <= '9') || c == skipChar ); + if(isNegative) + value = -value; + return value; +} + +// float version of getValue method: +// as integer version but returns a floating point value +float WideTextFinder::getFloat() +{ + getFloat(NO_SKIP_CHAR); +} + +// as above but the given skipChar is ignored +// this allows format characters (typically commas) in values to be ignored +float WideTextFinder::getFloat(char skipChar) +{ + boolean isNegative = false; + boolean isFraction = false; + long value = 0; + float fValue; + char c; + float fraction = 1.0; + + while( (c = read()) != '-' && (c < '0' || c > '9') ) + ; // ignore non numeric leading characters + do { + if(c == skipChar) + ; // ignore + else if(c == '-') + isNegative = true; + else if (c == '.') + isFraction = true; + else if(c >= '0' && c <= '9') { // is c a digit? + value = value * 10 + c - '0'; + if(isFraction) + fraction *= 0.1; + } + c = read(); + } while( (c >= '0' && c <= '9') || c == '.' || c == skipChar ); + if(isNegative) + value = -value; + if(isFraction) + return value * fraction; + else + return value; +} + + +// returns the number of seconds to wait for the next char before aborting read +unsigned long WideTextFinder::getTimeout() +{ + return timeout; +} + +// set a new value for the wait timeout +void WideTextFinder::setTimeout(unsigned long timeout) +{ + this->timeout = timeout * 1000L; +} diff --git a/lib/ITEADLIB_Arduino_SIMCom/WideTextFinder.h b/lib/ITEADLIB_Arduino_SIMCom/WideTextFinder.h new file mode 100644 index 0000000..83cf5eb --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/WideTextFinder.h @@ -0,0 +1,61 @@ +#ifndef WideTextFinder_h +#define WideTextFinder_h + +//#include +#include +#include + + +class WideTextFinder { +private: + SoftwareSerial* nSerialStream; + + unsigned long timeout; // number of seconds to wait for the next char before aborting read + unsigned long startMillis; // used for timeout measurement + boolean debug; + + char read(); // private function to read from the stream + +public: + // constructor: + // default timeout is 5 seconds + WideTextFinder(SoftwareSerial &stream, int timeout = 5); // Ethernet constructor + + // Manage debug + void setDebug(boolean d); + + // find methods - these seek through the data but do not return anything + // they are useful to skip past unwanted data + // + boolean find(char *target); // reads data from the stream until the target string is found + // returns true if target string is found + + boolean findUntil(char *target, char *terminate); // as above but search ends if the terminate string is found + + + // get methods - these get a numeric value or string from the data stream + // + long getValue(); // returns the first valid (long) integer value from the current position. + // initial characters that are not digits (or the minus sign) are skipped + // integer is terminated by the first character that is not a digit. + + long getValue(char skipChar); // as above but the given skipChar is ignored + // this allows format characters (typically commas) in values to be ignored + + float getFloat(); // float version of getValue + float getFloat(char skipChar); // as above but the given skipChar is ignored + + int getString( char *pre_string, char *post_string, char *buffer, int length); //puts string found between given delimiters in buffer + // string will be truncated to fit the buffer length + // end of string determined by a match of a character to the first char of close delimiter + // returns the number of characters placed in the buffer (0 means no valid data found) + + unsigned long getTimeout(); // returns the number of seconds to wait for the next char before aborting read + + // set methods + // + void setTimeout(unsigned long timeout); // set a new value for the wait timeout + +}; + +#endif diff --git a/lib/ITEADLIB_Arduino_SIMCom/bluetooth.cpp b/lib/ITEADLIB_Arduino_SIMCom/bluetooth.cpp new file mode 100644 index 0000000..1b268be --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/bluetooth.cpp @@ -0,0 +1,264 @@ +#include "bluetooth.h" +bool BlueTooth::powerOn(void) +{ + bool ret_val = false; + gsm.SimpleWriteln("AT+BTPOWER=1"); + gsm.WaitResp(1000, 500, "OK"); + if(gsm.IsStringReceived("OK")) + ret_val = true; + else if(gsm.IsStringReceived("ERROR")) + ret_val = false; + + return ret_val; +} + +bool BlueTooth::powerOff(void) +{ + bool ret_val = false; + gsm.SimpleWriteln("AT+BTPOWER=0"); + gsm.WaitResp(1000, 500, "OK"); + if(gsm.IsStringReceived("OK")) + ret_val = true; + else if(gsm.IsStringReceived("ERROR")) + ret_val = false; + + return ret_val; +} + +int BlueTooth::getHostDeviceName(char* deviceName) +{ + char *s,*p; + int i = 0; + int ret_val = -1; + gsm.SimpleWriteln("AT+BTHOST?"); + gsm.WaitResp(1000, 500, "OK"); + if (gsm.IsStringReceived("OK")) + ret_val = 1; + else + return 0; + if(gsm.IsStringReceived("+BTHOST:")) + { + s = strchr((char *)gsm.comm_buf,':'); + + if(NULL == (s = strchr((char *)gsm.comm_buf,':'))) + { + return -1; + } + p = s + 9;/*+BTHOST: SIM800,33:7d:77:18:62:60*/ + while(*(p) != ',') + { + deviceName[i++] = *p; + p++; + } + deviceName[i] = '\0'; + } + + return i; +} + +int BlueTooth::scanForTargetDevice(char* deviceName) +{ + char *s; + gsm.SimpleWriteln("AT+BTSCAN=1,20"); + /*gsm.RxInit(5000, 1500);*/ + if (RX_FINISHED_STR_RECV == gsm.WaitResp(10000, 10000, "+BTSCAN:")) + { + if(NULL == (s = strstr((char *)gsm.comm_buf,deviceName))) + { + return 0; + } + else + targetDeviceID = atoi(s-3); + } + + return targetDeviceID; +} + +int BlueTooth::sendPairingRequestToDevice(int deviceID) +{ + if(0 == deviceID) + return -1; + + gsm.SimpleWrite("AT+BTPAIR=0,"); + gsm.SimpleWrite(deviceID); + gsm.SimpleWrite("\r\n"); + if (RX_FINISHED_STR_RECV == gsm.WaitResp(2000, 1000, "+BTPAIRING")) { + gsm.SimpleWriteln("AT+BTPAIR=1,1"); + + } + return 0; +} + +int BlueTooth::unPair(void) +{ + int ret_val = -1; + if(0 == targetDeviceID) + return -1; + gsm.SimpleWrite("AT+BTUNPAIR=0"); + /*gsm.SimpleWrite(targetDeviceID);*/ + gsm.SimpleWrite("\r\n"); + gsm.WaitResp(1000, 500, "OK"); + if(gsm.IsStringReceived("OK")) + ret_val = 1; + else + ret_val = 0; + + return ret_val; +} + +int BlueTooth::acceptPairing(void) +{ + char *s = NULL; + if (RX_FINISHED_STR_RECV == gsm.WaitResp(2000, 1000, "+BTPAIRING")) + { + gsm.SimpleWriteln("AT+BTPAIR=1,1"); + Serial.println("+++pair ok+++");/*it indicates device pair ok*/ + if (RX_FINISHED_STR_RECV == gsm.WaitResp(10000, 10000, "+BTPAIR")) + { + if(NULL == (s = strstr((char *)gsm.comm_buf,":"))) + { + return 0; + } + else + targetDeviceID = atoi(s+1); + } + return targetDeviceID; + } + else + { + Serial.println("zlnonono"); /*it indicates that there is no device try to pair with SIM800*/ + return 0; + } +} +int BlueTooth::acceptConnect(void) +{ + int ret_val = -1; + gsm.SimpleWriteln("AT+BTACPT=1"); + gsm.WaitResp(1000, 500, "OK"); + + if(gsm.IsStringReceived("OK")) + ret_val = 1; + else + ret_val = 0; + + return ret_val; +} +int BlueTooth::disconnect(int deviceID) +{ + int ret_val = -1; + if(0 == targetDeviceID) + return -1; + gsm.SimpleWrite("AT+BTDISCONN="); + gsm.SimpleWrite(targetDeviceID); + gsm.SimpleWrite("\r\n"); + gsm.WaitResp(1000, 500, "OK"); + if(gsm.IsStringReceived("OK")) + ret_val = 1; + else + ret_val = 0; + + return ret_val; +} +/* +int BlueTooth::loopHandle(void) +{ + char gprsBuffer[100]; + cleanBuffer(gprsBuffer,100); + while(1) { + if(serialSIM800.available()) + { + break; + } + delay(1000); + } + readBuffer(gprsBuffer,100,DEFAULT_TIMEOUT); + + if(NULL != strstr(gprsBuffer,"+BTPAIRING:")) + { + if(0 != acceptPairing()) + { + return -1; + ERROR("\r\nERROR:bluetoothAcceptPairing\r\n"); + } + } + if((NULL != strstr(gprsBuffer,"+BTCONNECTING:")) && (NULL != strstr(gprsBuffer,"SPP"))) + { + if(0 != acceptConnect()) + { + return -1; + ERROR("\r\nERROR:bluetoothAcceptConnecting\r\n"); + } + } + return 0; +} +*/ + +/*int BlueTooth::getDeviceId(void) +{ + return 1; +}*/ + +int BlueTooth::connectInSPP(int deviceID) /*Serial Port Profile*/ +{ + int ret_val = 1; + if(0 == targetDeviceID) + return -1; + + /*gsm.SimpleWriteln("AT+BTGETPROF);*/ + gsm.SimpleWrite("AT+BTCONNECT="); + gsm.SimpleWrite(targetDeviceID); + gsm.SimpleWrite(",4\r\n"); + Serial.println("***connetc SPP***"); /*it means connect to SPP*/ + if (RX_FINISHED_STR_RECV == gsm.WaitResp(10000, 500, "OK")) + { + return 1; + } + /*gsm.SetCommLineStatus(CLS_FREE); */ + return ret_val; +} + +int BlueTooth::recvInSPP(char* data) +{ + char * p = NULL; + int count = 0; + if (RX_FINISHED_STR_RECV == gsm.WaitResp(1000, 500, "+BTSPPDATA:")) + { + p = strchr((char *)gsm.comm_buf,':'); + if(NULL != p) + { + p += 5; + int i = 0; + while(*(p++) != 0x0D) + { + data[i++] = *p; + } + data[i]='+'; + return 1; + } + else + return 0; + } + else + return 0; +} + +int BlueTooth::sendInSPP(char* data) +{ + int ret_val = -1; + char end[2]; + end[0]=0x1a; + end[1]='\0'; + gsm.SimpleWriteln("AT+BTSPPSEND"); + + if (RX_FINISHED_STR_RECV == gsm.WaitResp(1000, 500, ">")) + { + gsm.SimpleWrite(data); + gsm.SimpleWriteln(end); + if (RX_FINISHED_STR_RECV == gsm.WaitResp(2000, 2000, "SEND OK")) + ret_val = 1; + } + else + ret_val = 0; + + return ret_val; +} diff --git a/lib/ITEADLIB_Arduino_SIMCom/bluetooth.h b/lib/ITEADLIB_Arduino_SIMCom/bluetooth.h new file mode 100644 index 0000000..249bc7d --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/bluetooth.h @@ -0,0 +1,154 @@ +#ifndef __BLUETOOTH_H__ +#define __BLUETOOTH_H__ + +#include "SIM900.h" + +/** + * BlueTooth class. + * + * used to communicate with BlueTooth Module. + */ +class BlueTooth +{ +public: + + /** + * Power on BlueTooth module. + * + * @retval true - success. + * @retval false - failure. + * + */ + bool powerOn(void); + + /** + * Power off BlueTooth module. + * + * @retval true - success. + * @retval false - failure. + * + */ + bool powerOff(void); + + /** + * Get host device name of BlueTooth module. + * + * @param deviceName - buffer array to save device name. + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int getHostDeviceName(char* deviceName); + + /** + * Scan for target device according to device name. + * + * @param deviceName - device which will be scanned for. + * @retval >0 - success. + * @retval <=0 - failure. + * @return targetDeviceID. + * + */ + int scanForTargetDevice(char* deviceName); + + /** + * Send pairing request to device according to deviceID. + * + * @param deviceID - device ID. + * @retval 0 - success. + * @retval -1 - failure. + * + */ + int sendPairingRequestToDevice(int deviceID); + + /** + * Accept other BlueTooth module's pairing request. + * + * @retval >0 - success. + * @retval <=0 - failure. + * @return targetDeviceID. + * + */ + int acceptPairing(void); + + /** + * UnPair with paired BlueTooth device. + * + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int unPair(void); + + /** + * Accept other BlueTooth device's connecting request. + * + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int acceptConnect(void); + + /** + * Wait to handle other BlueTooth device's pairing or connecting request. + * + * @retval 0 - success. + * @retval -1 - failure. + * + */ + int loopHandle(void); + + /** + * Disconnect with connected BlueTooth device. + * + * @param deviceID - device that will be disconnected. + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int disconnect(int deviceID); + + /** + * Connect with other BlueTooth device in SPP profile. + * + * @param deviceID - device that will be connect in SPP profile. + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int connectInSPP(int deviceID); + + /** + * Receive data in SPP profile. + * + * @param data - buffer array to receive data from other BlueTooth device in SPP profile. + * @retval 1 - success. + * @retval 0 - failure. + * + */ + int recvInSPP(char* data); + + /** + * Send data in SPP profile. + * + * @param data - buffer array to send data to other BlueTooth device in SPP profile. + * @reval 1 - success. + * @retal <=0 - failure. + * + */ + int sendInSPP(char* data); + +private: + + /** + * BlueTooth power flag + */ + bool bluetoothPower; + + /** + * target device ID + */ + int targetDeviceID; +}; + +#endif \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/call.cpp b/lib/ITEADLIB_Arduino_SIMCom/call.cpp new file mode 100644 index 0000000..d162d58 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/call.cpp @@ -0,0 +1,334 @@ +#include "call.h" + +/********************************************************** +Method checks status of call + +return: + CALL_NONE - no call activity + CALL_INCOM_VOICE - incoming voice + CALL_ACTIVE_VOICE - active voice + CALL_NO_RESPONSE - no response to the AT command + CALL_COMM_LINE_BUSY - comm line is not free +**********************************************************/ +byte CallGSM::CallStatus(void) +{ + byte ret_val = CALL_NONE; + + if (CLS_FREE != gsm.GetCommLineStatus()) return (CALL_COMM_LINE_BUSY); + gsm.SetCommLineStatus(CLS_ATCMD); + gsm.SimpleWriteln(F("AT+CPAS")); + + // 5 sec. for initial comm tmout + // 50 msec. for inter character timeout + if (RX_TMOUT_ERR == gsm.WaitResp(5000, 50)) { + // nothing was received (RX_TMOUT_ERR) + // ----------------------------------- + ret_val = CALL_NO_RESPONSE; + } else { + // something was received but what was received? + // --------------------------------------------- + // ready (device allows commands from TA/TE) + // +CPAS: 0 OK + // unavailable (device does not allow commands from TA/TE) + // +CPAS: 1 OK + // unknown (device is not guaranteed to respond to instructions) + // +CPAS: 2 OK - NO CALL + // ringing + // +CPAS: 3 OK - NO CALL + // call in progress + // +CPAS: 4 OK - NO CALL + if(gsm.IsStringReceived("+CPAS: 0")) { + // ready - there is no call + // ------------------------ + ret_val = CALL_NONE; + } else if(gsm.IsStringReceived("+CPAS: 3")) { + // incoming call + // -------------- + ret_val = CALL_INCOM_VOICE; + } else if(gsm.IsStringReceived("+CPAS: 4")) { + // active call + // ----------- + ret_val = CALL_ACTIVE_VOICE; + } + } + + gsm.SetCommLineStatus(CLS_FREE); + return (ret_val); + +} + +/********************************************************** +Method checks status of call(incoming or active) +and makes authorization with specified SIM positions range + +phone_number: a pointer where the tel. number string of current call will be placed + so the space for the phone number string must be reserved - see example +first_authorized_pos: initial SIM phonebook position where the authorization process + starts +last_authorized_pos: last SIM phonebook position where the authorization process + finishes + + Note(important): + ================ + In case first_authorized_pos=0 and also last_authorized_pos=0 + the received incoming phone number is NOT authorized at all, so every + incoming is considered as authorized (CALL_INCOM_VOICE_NOT_AUTH is returned) + +return: + CALL_NONE - no call activity + CALL_INCOM_VOICE_AUTH - incoming voice - authorized + CALL_INCOM_VOICE_NOT_AUTH - incoming voice - not authorized + CALL_ACTIVE_VOICE - active voice + CALL_INCOM_DATA_AUTH - incoming data call - authorized + CALL_INCOM_DATA_NOT_AUTH - incoming data call - not authorized + CALL_ACTIVE_DATA - active data call + CALL_NO_RESPONSE - no response to the AT command + CALL_COMM_LINE_BUSY - comm line is not free +**********************************************************/ +byte CallGSM::CallStatusWithAuth(char *phone_number, + byte first_authorized_pos, byte last_authorized_pos) +{ + byte ret_val = CALL_NONE; + byte search_phone_num = 0; + byte i; + byte status; + char *p_char; + char *p_char1; + + phone_number[0] = 0x00; // no phonr number so far + if (CLS_FREE != gsm.GetCommLineStatus()) return (CALL_COMM_LINE_BUSY); + gsm.SetCommLineStatus(CLS_ATCMD); + gsm.SimpleWriteln(F("AT+CLCC")); + + // 5 sec. for initial comm tmout + // and max. 1500 msec. for inter character timeout + gsm.RxInit(5000, 1500); + // wait response is finished + do { + if (gsm.IsStringReceived("OK\r\n")) { + // perfect - we have some response, but what: + + // there is either NO call: + // OK + + // or there is at least 1 call + // +CLCC: 1,1,4,0,0,"+420XXXXXXXXX",145 + // OK + status = RX_FINISHED; + break; // so finish receiving immediately and let's go to + // to check response + } + status = gsm.IsRxFinished(); + } while (status == RX_NOT_FINISHED); + + // generate tmout 30msec. before next AT command + delay(30); + + if (status == RX_FINISHED) { + // something was received but what was received? + // example: //+CLCC: 1,1,4,0,0,"+420XXXXXXXXX",145 + // --------------------------------------------- + if(gsm.IsStringReceived("+CLCC: 1,1,4,0,0")) { + // incoming VOICE call - not authorized so far + // ------------------------------------------- + search_phone_num = 1; + ret_val = CALL_INCOM_VOICE_NOT_AUTH; + } else if(gsm.IsStringReceived("+CLCC: 1,1,4,1,0")) { + // incoming DATA call - not authorized so far + // ------------------------------------------ + search_phone_num = 1; + ret_val = CALL_INCOM_DATA_NOT_AUTH; + } else if(gsm.IsStringReceived("+CLCC: 1,0,0,0,0")) { + // active VOICE call - GSM is caller + // ---------------------------------- + search_phone_num = 1; + ret_val = CALL_ACTIVE_VOICE; + } else if(gsm.IsStringReceived("+CLCC: 1,1,0,0,0")) { + // active VOICE call - GSM is listener + // ----------------------------------- + search_phone_num = 1; + ret_val = CALL_ACTIVE_VOICE; + } else if(gsm.IsStringReceived("+CLCC: 1,1,0,1,0")) { + // active DATA call - GSM is listener + // ---------------------------------- + search_phone_num = 1; + ret_val = CALL_ACTIVE_DATA; + } else if(gsm.IsStringReceived("+CLCC:")) { + // other string is not important for us - e.g. GSM module activate call + // etc. + // IMPORTANT - each +CLCC:xx response has also at the end + // string OK + ret_val = CALL_OTHERS; + } else if(gsm.IsStringReceived("OK")) { + // only "OK" => there is NO call activity + // -------------------------------------- + ret_val = CALL_NONE; + } + + + // now we will search phone num string + if (search_phone_num) { + // extract phone number string + // --------------------------- + p_char = strchr((char *)(gsm.comm_buf),'"'); + p_char1 = p_char+1; // we are on the first phone number character + p_char = strchr((char *)(p_char1),'"'); + if (p_char != NULL) { + *p_char = 0; // end of string + strcpy(phone_number, (char *)(p_char1)); + Serial.print("ATTESO: "); + Serial.println(phone_number); + } else + //Serial.println(gsm.comm_buf); + Serial.println("NULL"); + + if ( (ret_val == CALL_INCOM_VOICE_NOT_AUTH) + || (ret_val == CALL_INCOM_DATA_NOT_AUTH)) { + + if ((first_authorized_pos == 0) && (last_authorized_pos == 0)) { + // authorization is not required => it means authorization is OK + // ------------------------------------------------------------- + if (ret_val == CALL_INCOM_VOICE_NOT_AUTH) ret_val = CALL_INCOM_VOICE_AUTH; + else ret_val = CALL_INCOM_DATA_AUTH; + } else { + // make authorization + // ------------------ + gsm.SetCommLineStatus(CLS_FREE); + for (i = first_authorized_pos; i <= last_authorized_pos; i++) { + if (gsm.ComparePhoneNumber(i, phone_number)) { + // phone numbers are identical + // authorization is OK + // --------------------------- + if (ret_val == CALL_INCOM_VOICE_NOT_AUTH) ret_val = CALL_INCOM_VOICE_AUTH; + else ret_val = CALL_INCOM_DATA_AUTH; + break; // and finish authorization + } + } + } + } + } + + } else { + // nothing was received (RX_TMOUT_ERR) + // ----------------------------------- + ret_val = CALL_NO_RESPONSE; + } + + gsm.SetCommLineStatus(CLS_FREE); + return (ret_val); +} + +/********************************************************** +Method picks up an incoming call + +return: +**********************************************************/ +void CallGSM::PickUp(void) +{ + //if (CLS_FREE != gsm.GetCommLineStatus()) return; + //gsm.SetCommLineStatus(CLS_ATCMD); + gsm.SendATCmdWaitResp("ATA", 10, 10, "OK", 3); + gsm.SimpleWriteln("ATA"); + //gsm.SetCommLineStatus(CLS_FREE); +} + +/********************************************************** +Method hangs up incoming or active call + +return: +**********************************************************/ +void CallGSM::HangUp(void) +{ + //if (CLS_FREE != gsm.GetCommLineStatus()) return; + //gsm.SetCommLineStatus(CLS_ATCMD); + gsm.SendATCmdWaitResp("ATH", 500, 100, "OK", 5); + //gsm.SetCommLineStatus(CLS_FREE); +} + +/********************************************************** +Method calls the specific number + +number_string: pointer to the phone number string + e.g. gsm.Call("+420123456789"); + +**********************************************************/ +void CallGSM::Call(char *number_string) +{ + if (CLS_FREE != gsm.GetCommLineStatus()) return; + gsm.SetCommLineStatus(CLS_ATCMD); + // ATDxxxxxx; + gsm.SimpleWrite(F("ATD")); + gsm.SimpleWrite(number_string); + gsm.SimpleWriteln(F(";")); + // 10 sec. for initial comm tmout + // 50 msec. for inter character timeout + gsm.WaitResp(10000, 50); + gsm.SetCommLineStatus(CLS_FREE); +} + +/********************************************************** +Method calls the number stored at the specified SIM position + +sim_position: position in the SIM <1...> + e.g. gsm.Call(1); +**********************************************************/ +void CallGSM::Call(int sim_position) +{ + if (CLS_FREE != gsm.GetCommLineStatus()) return; + gsm.SetCommLineStatus(CLS_ATCMD); + // ATD>"SM" 1; + gsm.SimpleWrite(F("ATD>\"SM\" ")); + gsm.SimpleWrite(sim_position); + gsm.SimpleWriteln(F(";")); + + // 10 sec. for initial comm tmout + // 50 msec. for inter character timeout + gsm.WaitResp(10000, 50); + + gsm.SetCommLineStatus(CLS_FREE); +} + +void CallGSM::SendDTMF(char *number_string, int time) +{ + if (CLS_FREE != gsm.GetCommLineStatus()) return; + gsm.SetCommLineStatus(CLS_ATCMD); + + gsm.SimpleWrite(F("AT+VTD=")); + gsm.SimpleWriteln(time); + gsm.WaitResp(1000, 100, "OK"); + + gsm.SimpleWrite(F("AT+VTS=\"")); + gsm.SimpleWrite(number_string); + gsm.SimpleWriteln(F("\"")); + + gsm.WaitResp(5000, 100, "OK"); + gsm.SetCommLineStatus(CLS_FREE); +} + +void CallGSM::SetDTMF(int DTMF_status) +{ + if(DTMF_status==1) + gsm.SendATCmdWaitResp("AT+DDET=1", 500, 50, "OK", 5); + else + gsm.SendATCmdWaitResp("AT+DDET=0", 500, 50, "OK", 5); +} + + +char CallGSM::DetDTMF() +{ + char *p_char; + char *p_char1; + char dtmf_char='-'; + gsm.WaitResp(1000, 500); + { + //Serial.print("BUF: "); + //Serial.println((char *)gsm.comm_buf); + //Serial.println("end"); + p_char = strstr((char *)(gsm.comm_buf),"+DTMF:"); + if (p_char != NULL) { + p_char1 = p_char+6; //we are on the first char of BCS + dtmf_char = *p_char1; + } + } + return dtmf_char; +} \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/call.h b/lib/ITEADLIB_Arduino_SIMCom/call.h new file mode 100644 index 0000000..0a5ab1e --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/call.h @@ -0,0 +1,28 @@ +#ifndef _CALL_H_ +#define _CALL_H_ + +#include "SIM900.h" + +class CallGSM { +public: + // finds out the status of call + byte CallStatus(void); + byte CallStatusWithAuth(char *phone_number, + byte first_authorized_pos, byte last_authorized_pos); + // picks up an incoming call + void PickUp(void); + // hangs up an incomming call + void HangUp(void); + // calls the specific number + void Call(char *number_string); + // makes a call to the number stored at the specified SIM position + void Call(int sim_position); + void SendDTMF(char *number_string, int time); + + void SetDTMF(int DTMF_status); + char DetDTMF(); + +}; + +#endif + diff --git a/lib/ITEADLIB_Arduino_SIMCom/doc/Instructions.txt b/lib/ITEADLIB_Arduino_SIMCom/doc/Instructions.txt new file mode 100644 index 0000000..1ab0a54 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/doc/Instructions.txt @@ -0,0 +1,87 @@ +*************************************************** +GSM/GPRS/GPS Shield of Futura/Open-electronics + +http://www.open-electronics.org/ + +http://store.open-electronics.org/index.php?route=common/home + +*************************************************** + + + + + +*************************************************** +For support use the issues' page on google code: + +http://code.google.com/p/gsm-shield-arduino/issues/ + +or Arduino Forum + +*************************************************** + + + + + +*************************************************** +Library created by: + +Marco Martines + +martines[ dot ]marco[ at ]gmail[ dot ]com +*************************************************** + + + + +[1] How to switch between Arduino Mega and Arduino Uno? + + 1) + Open GSM.h and comment-decomment the appropriate lines like below + e.g. for Arduino Mega + //#define UNO + #define MEGA + + 2) + If you use Arduino Uno comment the line in HWSerial.h or decomment if + you are using Arduino Mega + e.g. for Arduino Mega + #define MEGA + + 3) + Save and compile + +[2] How to switch between the old shield (that uses 4 and 5 pins for + SoftwareSerial and the new (that used 2 and 3 pins)? + + 1) + Open GSM.cpp and comment-decomment the appropriate lines like below + e.g. for the new one + + //#define _GSM_TXPIN_ 4 + //#define _GSM_RXPIN_ 5 + #define _GSM_TXPIN_ 2 + #define _GSM_RXPIN_ 3 + + 2) + Save and compile + +[3] My shield doesn't work. Why? + + Check this steps and then ask for support on the issues' page on google + code. + + 1) SIM900 and SIM908 require about 1 A during the hardest tasks. + You should have an external power source that can provide about + 1 A at 8-12 V + + 2) If the SIM90X blinks (1 Hz) for some seconds and then turn off, + probably it's a communication's problem. Check the switch/jumpers + for Serial communication. + + 3) Arduino Uno has 2 KB of RAM. Library takes about 80% (we are working + to reduce it), if you use more than 20% left, Arduino can restart + or print on serial strange strings. + + 4) Check the jumper of communication, power source (battery or externel) and charge. \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/doc/InstructionsBlueTooth.txt b/lib/ITEADLIB_Arduino_SIMCom/doc/InstructionsBlueTooth.txt new file mode 100644 index 0000000..ec82b97 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/doc/InstructionsBlueTooth.txt @@ -0,0 +1,127 @@ +/*BASIC FUNCTIONS in BlueTooth class*/ + + /** + * Power on BlueTooth module. + * + * @retval true - success. + * @retval false - failure. + * + */ + bool powerOn(void); + + /** + * Power off BlueTooth module. + * + * @retval true - success. + * @retval false - failure. + * + */ + bool powerOff(void); + + /** + * Get host device name of BlueTooth module. + * + * @param deviceName - buffer array to save device name. + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int getHostDeviceName(char* deviceName); + + /** + * Scan for target device according to device name. + * + * @param deviceName - device which will be scanned for. + * @retval >0 - success. + * @retval <=0 - failure. + * @return targetDeviceID. + * + */ + int scanForTargetDevice(char* deviceName); + + /** + * Send pairing request to device according to deviceID. + * + * @param deviceID - device ID. + * @retval 0 - success. + * @retval -1 - failure. + * + */ + int sendPairingRequestToDevice(int deviceID); + + /** + * Accept other BlueTooth module's pairing request. + * + * @retval >0 - success. + * @retval <=0 - failure. + * @return targetDeviceID. + * + */ + int acceptPairing(void); + + /** + * UnPair with paired BlueTooth device. + * + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int unPair(void); + + /** + * Accept other BlueTooth device's connecting request. + * + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int acceptConnect(void); + + /** + * Wait to handle other BlueTooth device's pairing or connecting request. + * + * @retval 0 - success. + * @retval -1 - failure. + * + */ + int loopHandle(void); + + /** + * Disconnect with connected BlueTooth device. + * + * @param deviceID - device that will be disconnected. + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int disconnect(int deviceID); + + /** + * Connect with other BlueTooth device in SPP profile. + * + * @param deviceID - device that will be connect in SPP profile. + * @retval 1 - success. + * @retval <=0 - failure. + * + */ + int connectInSPP(int deviceID); + + /** + * Receive data in SPP profile. + * + * @param data - buffer array to receive data from other BlueTooth device in SPP profile. + * @retval 1 - success. + * @retval 0 - failure. + * + */ + int recvInSPP(char* data); + + /** + * Send data in SPP profile. + * + * @param data - buffer array to send data to other BlueTooth device in SPP profile. + * @reval 1 - success. + * @retal <=0 - failure. + * + */ + int sendInSPP(char* data); \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/doc/InstructionsForGBoardPro800.txt b/lib/ITEADLIB_Arduino_SIMCom/doc/InstructionsForGBoardPro800.txt new file mode 100644 index 0000000..72eb1d9 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/doc/InstructionsForGBoardPro800.txt @@ -0,0 +1,35 @@ +/* + *If your board is "Gboard Pro 800" you should edit the following files + */ + +step1: HWSerial.cpp +/* + * all the string "Serial1" should be changed to "Serial2" ,for example: + * HWSerial::HWSerial(){ + * // Serial1.begin(9600); + * Serial2.begin(9600); + * } + */ + +step2: HWSerial.h +/* + * //#define UNO + * #define MEGA + * + */ + +step3: GSM.h +/* + * //#define UNO + * #define MEGA + * + */ + +step4: GSM.cpp +/* + * //#define _GSM_TXPIN_ 2 + * //#define _GSM_RXPIN_ 3 + * #define _GSM_TXPIN_ 16 + * #define _GSM_RXPIN_ 17 + */ + \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/doc/List.txt b/lib/ITEADLIB_Arduino_SIMCom/doc/List.txt new file mode 100644 index 0000000..018f484 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/doc/List.txt @@ -0,0 +1,216 @@ +*************************************************** +BASIC FUNCTIONS in GSM class. +To call a function the code is: gsm.function_name(); +There is no need to create a class object for GSM class. +It'already done inside the library itself. +*************************************************** + +int begin(long baud_rate); + Function to turn on the module and set the baudrate of communication + at specified baud_rate. + +char forceON(); + When you are using the SIM908 and you need to turn the module on the network mode. + It's possible that SIM908 starts itself on charging mode, without network. + +int getIMEI(char* imei); + Get the IMEI code of the phone and save it on the imei string. + +boolean readSMS(char* msg, int msglength, char* number, int nlength); + Read the first msglength byte of the SMS string and save it to the msg string. + Save the first nlenght numbers of the sender number to the number string. + +boolean readCall(char* number, int nlength); + +boolean call(char* number, unsigned int milliseconds); + Call the specified number after the milliseconds specified. + +int readCellData(int &mcc, int &mnc, long &lac, long &cellid); + Read information about the network data. + +void SimpleRead(); + To read, and print on hardware serial, the first byte of the software serial buffer. + +void WhileSimpleRead(); + As SimpleRead() but read until the buffer is empty. + +void SimpleWrite(char *comm); + Write on software serial the specified char. + +void SimpleWrite(char const *comm); + Write on software serial the specified const char. + +void SimpleWrite(int comm); + Write on software serial the specified int. + +void SimpleWriteln(char *comm); + Write on software serial the specified char + and append to the end the return char "\n\r". + +void SimpleWriteln(char const *comm); + Write on software serial the specified const char + and append to the end the return char "\n\r". + +void SimpleWriteln(int comm); + Write on software serial the specified int + and append to the end the return char "\n\r". + +void RxInit(uint16_t start_comm_tmout, uint16_t max_interchar_tmout); + To set the timout during the serial communication, for the entire string + and for the time between two char. + +byte IsRxFinished(void); + To check if the communication is finished, comparing the time + with the timeout selected with the RxInit() function. + +byte IsStringReceived(char const *compare_string); + To check if the received string from software serial is + the same of the specified string. + +byte WaitResp(uint16_t start_comm_tmout, uint16_t max_interchar_tmout, + char const *expected_resp_string); + It merges the RxInit() and IsStringReceived() functions. + +char SendATCmdWaitResp(char const *AT_cmd_string, + uint16_t start_comm_tmout, uint16_t max_interchar_tmout, + char const *response_string, + byte no_of_attempts); + It's a very important function to send a command, wait the response + and check if it is the same of the aspected response. If not retry + for number of attempts specified. + +*************************************************** +SMS FUNCTIONS in SMS class. +It's need to create a class object for SMS class with +SMS sms_obj_name (in the examples it's used SMS sms) +In the examples, to call a function the code is: sms.function_name(); +*************************************************** + +char SendSMS(char *number_str, char *message_str); + Send a SMS to the specified number with the specified string. + +char SendSMS(byte sim_phonebook_position, char *message_str); + Send a SMS to the specified phonebook position with the specified string. + +char IsSMSPresent(byte required_status); + Check if there is a message with the specified attribute like: + SMS_UNREAD + SMS_READ + SMS_ALL + +char GetSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len); + Save the SMS content and sender of the SMS in specified SIM position. + Save the first max_SMS_len byte of the SMS string to the SMS_text string and + the sender to the phone_number string. + +char GetAuthorizedSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len, + byte first_authorized_pos, byte last_authorized_pos); + Method reads SMS from specified SIM position and + makes authorization. It means SMS phone number is compared + with specified SIM phonebook position(s) and in case numbers + match GETSMS_AUTH_SMS is returned, otherwise GETSMS_NOT_AUTH_SMS + is returned. + +char DeleteSMS(byte position); + Method deletes SMS from the specified SMS position + +*************************************************** +CALL FUNCTIONS in CALL class. +It's need to create a class object for SMS class with +CALL call_obj_name (in the examples it's used CALL call) +In the examples, to call a function the code is: call.function_name(); +*************************************************** + +byte CallStatus(void); + Method checks status of call + + return: + CALL_NONE - no call activity + CALL_INCOM_VOICE - incoming voice + CALL_ACTIVE_VOICE - active voice + CALL_NO_RESPONSE - no response to the AT command + CALL_COMM_LINE_BUSY - comm line is not free + +byte CallStatusWithAuth(char *phone_number, + byte first_authorized_pos, byte last_authorized_pos); + Method checks status of call(incoming or active) + and makes authorization with specified SIM positions range + + phone_number: a pointer where the tel. number string of current call will be placed + so the space for the phone number string must be reserved - see example + first_authorized_pos: initial SIM phonebook position where the authorization process + starts + last_authorized_pos: last SIM phonebook position where the authorization process + finishes + + Note(important): + In case first_authorized_pos=0 and also last_authorized_pos=0 + the received incoming phone number is NOT authorized at all, so every + incoming is considered as authorized (CALL_INCOM_VOICE_NOT_AUTH is returned). + + return: + CALL_NONE - no call activity + CALL_INCOM_VOICE_AUTH - incoming voice - authorized + CALL_INCOM_VOICE_NOT_AUTH - incoming voice - not authorized + CALL_ACTIVE_VOICE - active voice + CALL_INCOM_DATA_AUTH - incoming data call - authorized + CALL_INCOM_DATA_NOT_AUTH - incoming data call - not authorized + CALL_ACTIVE_DATA - active data call + CALL_NO_RESPONSE - no response to the AT command + CALL_COMM_LINE_BUSY - comm line is not free + + +void PickUp(void); + To pick up an incoming call. + +void HangUp(void); + To hang up and active call. + +void Call(char *number_string); + To call the specified number; + +void Call(int sim_position); + To call the contact saved on the specified SIM position. + +void SendDTMF(char *number_string, int time); + Send a combination of DTMF stymbols separated by commas. + But a single character does not require quotes. + Time indicates the duration in seconds of each sound. + An example: + call.SendDTMF("1,2,3,4",1); + +*************************************************** +GPRS FUNCTIONS in InetGSM class. +It's need to create a class object for SMS class with +InetGSM inet_obj_name (in the examples it's used InetGSM inet) +In the examples, to call a function the code is: inet.function_name(); +*************************************************** +int attachGPRS(char* domain, char* dom1, char* dom2); + Start a GPRS connection to the specified domain. + It is needs authetication, dom1 is the username, dom2 is the password. + If it is no need, left it blank with. + An example: + inet.attachGPRS("internet.wind","",""); + +int httpGET(const char* server, int port, const char* path, char* result, int resultlength); + Save the first resultlength byte of the server response, after a GET request. + An example: + char response[200]; + inet.httpGET("www.google.com",80,"/news",response,200); + +int dettachGPRS(); + Close the GPRS connection. + +int connectTCP(const char* server, int port); + Start a TCP connection with the server on the specified port. + +int disconnectTCP(); + Close the TCP connection. + +int connectTCPServer(int port); + Put the module on the listening mode, waiting for a TCP connection + on the selected port. + +boolean connectedClient(); + Return true if a client is connected to the module, during the + server mode. \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_AT/GSM_GPRSLibrary_AT.ino b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_AT/GSM_GPRSLibrary_AT.ino new file mode 100644 index 0000000..1ce2d71 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_AT/GSM_GPRSLibrary_AT.ino @@ -0,0 +1,77 @@ +#include "SIM900.h" +#include +//#include "inetGSM.h" +//#include "sms.h" +//#include "call.h" + +//To change pins for Software Serial, use the two lines in GSM.cpp. + +//GSM Shield for Arduino +//www.open-electronics.org +//this code is based on the example of Arduino Labs. + +//Simple sketch to communicate with SIM900 through AT commands. + +//InetGSM inet; +//CallGSM call; +//SMSGSM sms; + +int numdata; +char inSerial[40]; +int i=0; + + +void setup() +{ + //Serial connection. + Serial.begin(9600); + Serial.println("GSM Shield testing."); + //Start configuration of shield with baudrate. + //For http uses is raccomanded to use 4800 or slower. + if (gsm.begin(9600)) + Serial.println("\nstatus=READY"); + else Serial.println("\nstatus=IDLE"); +}; + +void loop() +{ + //Read for new byte on serial hardware, + //and write them on NewSoftSerial. + serialhwread(); + //Read for new byte on NewSoftSerial. + serialswread(); +}; + +void serialhwread() +{ + i=0; + if (Serial.available() > 0) { + while (Serial.available() > 0) { + inSerial[i]=(Serial.read()); + delay(10); + i++; + } + + inSerial[i]='\0'; + if(!strcmp(inSerial,"/END")) { + Serial.println("_"); + inSerial[0]=0x1a; + inSerial[1]='\0'; + gsm.SimpleWriteln(inSerial); + } + //Send a saved AT command using serial port. + if(!strcmp(inSerial,"TEST")) { + Serial.println("SIGNAL QUALITY"); + gsm.SimpleWriteln("AT+CSQ"); + } else { + Serial.println(inSerial); + gsm.SimpleWriteln(inSerial); + } + inSerial[0]='\0'; + } +} + +void serialswread() +{ + gsm.SimpleRead(); +} diff --git a/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_BlueTooth_Connect/GSM_GPRSLibrary_BlueTooth_Connect.ino b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_BlueTooth_Connect/GSM_GPRSLibrary_BlueTooth_Connect.ino new file mode 100644 index 0000000..be9a027 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_BlueTooth_Connect/GSM_GPRSLibrary_BlueTooth_Connect.ino @@ -0,0 +1,45 @@ +#include "bluetooth.h" +#include +/*create a BlueTooth object*/ +BlueTooth blue; +void setup() +{ + /*Serial connection.*/ + Serial.begin(9600); + Serial.println("GSM Shield testing."); + + /*Start configuration of shield with baudrate.*/ + /*For http uses is raccomanded to use 4800 or slower.*/ + if (gsm.begin(9600)) + { + Serial.println("\nstatus=READY"); + } + else + Serial.println("\nstatus=IDLE"); + +}; + +void loop() +{ + if(blue.powerOff() == true) + Serial.println("close ok"); + else + Serial.println("close failed "); + + if(blue.powerOn() == true) + Serial.println("open ok "); + else + Serial.println("open failed"); + + int bluetemp = 0; + delay(2000); + while((bluetemp=blue.acceptPairing()) == 0); + while(1); +}; + + + + + + + diff --git a/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_BlueTooth_SPP/GSM_GPRSLibrary_BlueTooth_SPP.ino b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_BlueTooth_SPP/GSM_GPRSLibrary_BlueTooth_SPP.ino new file mode 100644 index 0000000..ec362d9 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_BlueTooth_SPP/GSM_GPRSLibrary_BlueTooth_SPP.ino @@ -0,0 +1,55 @@ +#include "bluetooth.h" +#include + +/*create a BlueTooth object*/ +BlueTooth blue; +void setup() +{ + /*Serial connection.*/ + Serial.begin(9600); + Serial.println("GSM Shield testing."); + + /*Start configuration of shield with baudrate. */ + /*For http uses is raccomanded to use 4800 or slower.*/ + if (gsm.begin(9600)) + { + Serial.println("\nstatus=READY"); + } + else + Serial.println("\nstatus=IDLE"); + +}; + +void loop() +{ + if(blue.powerOff() == true) + Serial.println("close ok"); + else + Serial.println("close failed "); + + if(blue.powerOn() == true) + Serial.println("open ok "); + else + Serial.println("open failed"); + + int bluetemp = 0; + delay(2000); + while((bluetemp=blue.acceptPairing()) == 0); + while(blue.connectInSPP(bluetemp)) + { + char data[20]={0}; + if(blue.recvInSPP(data) == 1) + Serial.println(data); + if(strlen(data)!=0) + { + blue.sendInSPP(data); + } + } +}; + + + + + + + diff --git a/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Call/GSM_GPRSLibrary_Call.ino b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Call/GSM_GPRSLibrary_Call.ino new file mode 100644 index 0000000..20c6886 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Call/GSM_GPRSLibrary_Call.ino @@ -0,0 +1,60 @@ +#include "SIM900.h" +#include +//We don't need the http functions. So we can disable the next line. +//#include "inetGSM.h" +#include "sms.h" +#include "call.h" + +//To change pins for Software Serial, use the two lines in GSM.cpp. + +//GSM Shield for Arduino +//www.open-electronics.org +//this code is based on the example of Arduino Labs. + +//Simple sketch to check if an incoming call is from an authorized +//number and in this case, send to this number an SMS with the value +//of a digital input. + +//We have to create the classes for SMSs and calls. +CallGSM call; +SMSGSM sms; + +char number[20]; +byte stat=0; +int value=0; +int pin=1; +char value_str[5]; + +void setup() +{ + pinMode(pin,INPUT); + //Serial connection. + Serial.begin(9600); + Serial.println("GSM Shield testing."); + //Start configuration of shield with baudrate. + //For http uses is raccomanded to use 4800 or slower. + if (gsm.begin(2400)) + Serial.println("\nstatus=READY"); + else Serial.println("\nstatus=IDLE"); +}; + +void loop() +{ + //Chekcs status of call + stat=call.CallStatusWithAuth(number,1,3); + //If the incoming call is from an authorized number + //saved on SIM in the positions range from 1 to 3. + if(stat==CALL_INCOM_VOICE_AUTH) { + //Hang up the call. + call.HangUp(); + delay(2000); + //Check the value of the input. + value=digitalRead(1); + //Convert the int to a string. + itoa(value,value_str,10); + //Send an SMS to the previous number with + //the value read previously. + sms.SendSMS(number,value_str); + } + delay(1000); +}; diff --git a/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Client/GSM_GPRSLibrary_Client.ino b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Client/GSM_GPRSLibrary_Client.ino new file mode 100644 index 0000000..181f49b --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Client/GSM_GPRSLibrary_Client.ino @@ -0,0 +1,107 @@ +#include "SIM900.h" +#include +#include "inetGSM.h" +//#include "sms.h" +//#include "call.h" + +//To change pins for Software Serial, use the two lines in GSM.cpp. + +//GSM Shield for Arduino +//www.open-electronics.org +//this code is based on the example of Arduino Labs. + +//Simple sketch to start a connection as client. + +InetGSM inet; +//CallGSM call; +//SMSGSM sms; + +char msg[50]; +int numdata; +char inSerial[50]; +int i=0; +boolean started=false; + +void setup() +{ + //Serial connection. + Serial.begin(9600); + Serial.println("GSM Shield testing."); + //Start configuration of shield with baudrate. + //For http uses is raccomanded to use 4800 or slower. + if (gsm.begin(2400)) { + Serial.println("\nstatus=READY"); + started=true; + } else Serial.println("\nstatus=IDLE"); + + if(started) { + //GPRS attach, put in order APN, username and password. + //If no needed auth let them blank. + if (inet.attachGPRS("internet.wind", "", "")) + Serial.println("status=ATTACHED"); + else Serial.println("status=ERROR"); + delay(1000); + + //Read IP address. + gsm.SimpleWriteln("AT+CIFSR"); + delay(5000); + //Read until serial buffer is empty. + gsm.WhileSimpleRead(); + + //TCP Client GET, send a GET request to the server and + //save the reply. + numdata=inet.httpGET("www.google.com", 80, "/", msg, 50); + //Print the results. + Serial.println("\nNumber of data received:"); + Serial.println(numdata); + Serial.println("\nData received:"); + Serial.println(msg); + } +}; + +void loop() +{ + //Read for new byte on serial hardware, + //and write them on NewSoftSerial. + serialhwread(); + //Read for new byte on NewSoftSerial. + serialswread(); +}; + +void serialhwread() +{ + i=0; + if (Serial.available() > 0) { + while (Serial.available() > 0) { + inSerial[i]=(Serial.read()); + delay(10); + i++; + } + + inSerial[i]='\0'; + if(!strcmp(inSerial,"/END")) { + Serial.println("_"); + inSerial[0]=0x1a; + inSerial[1]='\0'; + gsm.SimpleWriteln(inSerial); + } + //Send a saved AT command using serial port. + if(!strcmp(inSerial,"TEST")) { + Serial.println("SIGNAL QUALITY"); + gsm.SimpleWriteln("AT+CSQ"); + } + //Read last message saved. + if(!strcmp(inSerial,"MSG")) { + Serial.println(msg); + } else { + Serial.println(inSerial); + gsm.SimpleWriteln(inSerial); + } + inSerial[0]='\0'; + } +} + +void serialswread() +{ + gsm.SimpleRead(); +} diff --git a/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_DTMF/GSM_GPRSLibrary_DTMF.ino b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_DTMF/GSM_GPRSLibrary_DTMF.ino new file mode 100644 index 0000000..a1a310f --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_DTMF/GSM_GPRSLibrary_DTMF.ino @@ -0,0 +1,63 @@ +#include "SIM900.h" +#include +//We don't need the http functions. So we can disable the next line. +//#include "inetGSM.h" +#include "sms.h" +#include "call.h" + +//To change pins for Software Serial, use the two lines in GSM.cpp. + +//GSM Shield for Arduino +//www.open-electronics.org +//this code is based on the example of Arduino Labs. + +//Simple sketch to detect DTMF tones during a call + +//We have to create the classes for calls. +CallGSM call; + +char number[20]; +byte stat=0; +int value=0; +int pin=1; +char value_str[5]; +char DTMF_char='_'; +int count=0; + +void setup() +{ + pinMode(pin,INPUT); + //Serial connection. + Serial.begin(9600); + Serial.println("GSM Shield testing."); + //Start configuration of shield with baudrate. + //For http uses is raccomanded to use 4800 or slower. + if (gsm.begin(9600)) + Serial.println("\nstatus=READY"); + else Serial.println("\nstatus=IDLE"); + //Enable DTMF detection for SIM900 + call.SetDTMF(1); +}; + +void loop() +{ + //Chekcs status of call + stat=call.CallStatus(); + //If the incoming call is from an authorized number + //saved on SIM in the positions range from 1 to 3. + if(stat==CALL_INCOM_VOICE) { + Serial.println("Pick Up"); + delay(50); + call.PickUp(); + } + while(stat==CALL_ACTIVE_VOICE) { + for (int k=0; k<100; k++) { + DTMF_char=call.DetDTMF(); + if(DTMF_char!='-') + Serial.println(DTMF_char); + } + stat=call.CallStatus(); + + } + delay(1000); +}; diff --git a/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_GPS/GSM_GPRSLibrary_GPS.ino b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_GPS/GSM_GPRSLibrary_GPS.ino new file mode 100644 index 0000000..90c0607 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_GPS/GSM_GPRSLibrary_GPS.ino @@ -0,0 +1,133 @@ +#include "SIM900.h" +#include +//#include "inetGSM.h" +//#include "sms.h" +//#include "call.h" +#include "gps.h" + +//To change pins for Software Serial, use the two lines in GSM.cpp. + +//GSM Shield for Arduino +//www.open-electronics.org +//this code is based on the example of Arduino Labs. + +//Simple sketch to start a connection as client. + +//InetGSM inet; +//CallGSM call; +//SMSGSM sms; +GPSGSM gps; + +char lon[15]; +char lat[15]; +char alt[15]; +char time[20]; +char vel[15]; +char msg1[5]; +char msg2[5]; + +char stat; +char inSerial[20]; +int i=0; +boolean started=false; + +void setup() +{ + //Serial connection. + Serial.begin(9600); + Serial.println("GSM Shield testing."); + //Start configuration of shield with baudrate. + //For http uses is raccomanded to use 4800 or slower. + if (gsm.begin(2400)) { + Serial.println("\nstatus=READY"); + gsm.forceON(); //To ensure that SIM908 is not only in charge mode + started=true; + } else Serial.println("\nstatus=IDLE"); + + if(started) { + //GPS attach + if (gps.attachGPS()) + Serial.println("status=GPSREADY"); + else Serial.println("status=ERROR"); + + delay(20000); //Time for fixing + stat=gps.getStat(); + if(stat==1) + Serial.println("NOT FIXED"); + else if(stat==0) + Serial.println("GPS OFF"); + else if(stat==2) + Serial.println("2D FIXED"); + else if(stat==3) + Serial.println("3D FIXED"); + delay(5000); + //Get data from GPS + gps.getPar(lon,lat,alt,time,vel); + Serial.println(lon); + Serial.println(lat); + Serial.println(alt); + Serial.println(time); + Serial.println(vel); + } +}; + +void loop() +{ + //Read for new byte on serial hardware, + //and write them on NewSoftSerial. + serialhwread(); + //Read for new byte on NewSoftSerial. + serialswread(); +}; + +void serialhwread() +{ + i=0; + if (Serial.available() > 0) { + while (Serial.available() > 0) { + inSerial[i]=(Serial.read()); + delay(10); + i++; + } + + inSerial[i]='\0'; + if(!strcmp(inSerial,"/END")) { + Serial.println("_"); + inSerial[0]=0x1a; + inSerial[1]='\0'; + gsm.SimpleWriteln(inSerial); + } + //Send a saved AT command using serial port. + if(!strcmp(inSerial,"TEST")) { +// Serial.println("BATTERY TEST 1"); +// gps.getBattInf(msg1,msg2); +// Serial.println(msg1); +// Serial.println(msg2); +// Serial.println("BATTERY TEST 2"); +// gps.getBattTVol(msg1); +// Serial.println(msg1); + stat=gps.getStat(); + if(stat==1) + Serial.println("NOT FIXED"); + else if(stat==0) + Serial.println("GPS OFF"); + else if(stat==2) + Serial.println("2D FIXED"); + else if(stat==3) + Serial.println("3D FIXED"); + } + //Read last message saved. + if(!strcmp(inSerial,"MSG")) { + Serial.println(msg1); + } else { + Serial.println(inSerial); + gsm.SimpleWriteln(inSerial); + } + inSerial[0]='\0'; + } +} + +void serialswread() +{ + gsm.SimpleRead(); +} diff --git a/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_SMS/GSM_GPRSLibrary_SMS.ino b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_SMS/GSM_GPRSLibrary_SMS.ino new file mode 100644 index 0000000..ccd938b --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_SMS/GSM_GPRSLibrary_SMS.ino @@ -0,0 +1,56 @@ +#include "SIM900.h" +#include +//If not used, is better to exclude the HTTP library, +//for RAM saving. +//If your sketch reboots itself proprably you have finished, +//your memory available. +//#include "inetGSM.h" + +//If you want to use the Arduino functions to manage SMS, uncomment the lines below. +#include "sms.h" +SMSGSM sms; + +//To change pins for Software Serial, use the two lines in GSM.cpp. + +//GSM Shield for Arduino +//www.open-electronics.org +//this code is based on the example of Arduino Labs. + +//Simple sketch to send and receive SMS. + +int numdata; +boolean started=false; +char smsbuffer[160]; +char n[20]; + +void setup() +{ + //Serial connection. + Serial.begin(9600); + Serial.println("GSM Shield testing."); + //Start configuration of shield with baudrate. + //For http uses is raccomanded to use 4800 or slower. + if (gsm.begin(2400)) { + Serial.println("\nstatus=READY"); + started=true; + } else Serial.println("\nstatus=IDLE"); + + if(started) { + //Enable this two lines if you want to send an SMS. + //if (sms.SendSMS("3471234567", "Arduino SMS")) + //Serial.println("\nSMS sent OK"); + } + +}; + +void loop() +{ + if(started) { + //Read if there are messages on SIM card and print them. + if(gsm.readSMS(smsbuffer, 160, n, 20)) { + Serial.println(n); + Serial.println(smsbuffer); + } + delay(1000); + } +}; diff --git a/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Server/GSM_GPRSLibrary_Server.ino b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Server/GSM_GPRSLibrary_Server.ino new file mode 100644 index 0000000..db6d08c --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/examples/GSM_GPRSLibrary_Server/GSM_GPRSLibrary_Server.ino @@ -0,0 +1,118 @@ +#include "SIM900.h" +#include +#include "inetGSM.h" +//#include "sms.h" +//#include "call.h" + +//To change pins for Software Serial, use the two lines in GSM.cpp. + +//GSM Shield for Arduino +//www.open-electronics.org +//this code is based on the example of Arduino Labs. + +//Simple sketch to start a connection as server. + +InetGSM inet; +//CallGSM call; +//SMSGSM sms; + +char msg[50]; +int numdata; +char inSerial[50]; +int i=0; +boolean started=false; +long lasttime=millis(); + +void setup() +{ + //Serial connection. + Serial.begin(9600); + Serial.println("GSM Shield testing."); + //Start configuration of shield with baudrate. + //For http uses is raccomanded to use 4800 or slower. + if (gsm.begin(2400)) { + Serial.println("\nstatus=READY"); + started=true; + } else Serial.println("\nstatus=IDLE"); + + if(started) { + //GPRS attach, put in order APN, username and password. + //If no needed auth let them blank. + if (inet.attachGPRS("internet.wind", "", "")) + Serial.println("status=ATTACHED"); + else Serial.println("status=ERROR"); + delay(1000); + + //Read IP address. + gsm.SimpleWriteln("AT+CIFSR"); + delay(5000); + int i=0; + while(i<20) { + gsm.SimpleRead(); + i++; + } + + //TCP Server. Start the socket connection + //as server on the assigned port. + Serial.println(msg); + delay(5000); + if (inet.connectTCPServer(80)) + Serial.println("status=TCPSERVERWAIT"); + else Serial.println("ERROR in Server"); + lasttime=millis(); + } +}; + + +void loop() +{ + if(started) { + //Check if there is an active connection. + if (inet.connectedClient()) { + //Read and print the last message received. + gsm.read(msg, 50); + Serial.println(msg); + } + } else { + serialhwread(); + serialswread(); + } +}; + +void serialhwread() +{ + i=0; + if (Serial.available() > 0) { + while (Serial.available() > 0) { + inSerial[i]=(Serial.read()); + delay(10); + i++; + } + + inSerial[i]='\0'; + if(!strcmp(inSerial,"/END")) { + Serial.println("_"); + inSerial[0]=0x1a; + inSerial[1]='\0'; + gsm.SimpleWriteln(inSerial); + } + //Send a saved AT command using serial port. + if(!strcmp(inSerial,"TEST")) { + Serial.println("SIGNAL QUALITY"); + gsm.SimpleWriteln("AT+CSQ"); + } + //Read last message saved. + if(!strcmp(inSerial,"MSG")) { + Serial.println(msg); + } else { + Serial.println(inSerial); + gsm.SimpleWriteln(inSerial); + } + inSerial[0]='\0'; + } +} + +void serialswread() +{ + gsm.SimpleRead(); +} \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/gps.cpp b/lib/ITEADLIB_Arduino_SIMCom/gps.cpp new file mode 100644 index 0000000..c7445ef --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/gps.cpp @@ -0,0 +1,203 @@ +#include "gps.h" +char GPSGSM::getBattInf(char *str_perc, char *str_vol) +{ + char ret_val=0; + char *p_char; + char *p_char1; + + gsm.SimpleWriteln("AT+CBC"); + gsm.WaitResp(5000, 100, "OK"); + if(gsm.IsStringReceived("+CBC")) + ret_val=1; + + //BCL + p_char = strchr((char *)(gsm.comm_buf),','); + p_char1 = p_char+1; //we are on the first char of BCS + p_char = strchr((char *)(p_char1), ','); + if (p_char != NULL) { + *p_char = 0; + } + strcpy(str_perc, (char *)(p_char1)); + + //Voltage + p_char++; + p_char1 = strchr((char *)(p_char), '\r'); + if (p_char1 != NULL) { + *p_char1 = 0; + } + strcpy(str_vol, (char *)(p_char)); + return ret_val; +} + +char GPSGSM::getBattTVol(char *str_vol) +{ + char *p_char; + char *p_char1; + char ret_val=0; + + gsm.SimpleWriteln("AT+CBTE?"); + gsm.WaitResp(5000, 100, "OK"); + if(gsm.IsStringReceived("+CBTE")) + ret_val=1; + + //BCL + p_char = strchr((char *)(gsm.comm_buf),':'); + p_char1 = p_char+2; //we are on the first char of BCS + p_char = strchr((char *)(p_char1), '\r'); + if (p_char != NULL) { + *p_char = 0; + } + strcpy(str_vol, (char *)(p_char1)); + return ret_val; +} + +char GPSGSM::attachGPS() +{ + if(AT_RESP_ERR_DIF_RESP == gsm.SendATCmdWaitResp("AT+CGPSPWR=1", 500, 100, "OK", 5)) + return 0; + if(AT_RESP_ERR_DIF_RESP == gsm.SendATCmdWaitResp("AT+CGPSRST=1", 500, 100, "OK", 5)) + return 0; + return 1; +} + +char GPSGSM::deattachGPS() +{ + if(AT_RESP_ERR_DIF_RESP == gsm.SendATCmdWaitResp("AT+CGPSPWR=0", 500, 100, "OK", 5)) + return 0; + return 1; +} + +char GPSGSM::getStat() +{ + char ret_val=-1; + gsm.SimpleWriteln("AT+CGPSSTATUS?"); + gsm.WaitResp(5000, 100, "OK"); + if(gsm.IsStringReceived("Unknown")||gsm.IsStringReceived("unknown")) + ret_val=0; + else if(gsm.IsStringReceived("Not")) + ret_val=1; + else if(gsm.IsStringReceived("2D")||gsm.IsStringReceived("2d")) + ret_val=2; + else if(gsm.IsStringReceived("3D")||gsm.IsStringReceived("3d")) + ret_val=3; + return ret_val; +} + +char GPSGSM::getPar(char *str_long, char *str_lat, char *str_alt, char *str_time, char *str_speed) +{ + char ret_val=0; + char *p_char; + char *p_char1; + gsm.SimpleWriteln("AT+CGPSINF=0"); + gsm.WaitResp(5000, 100, "OK"); + if(gsm.IsStringReceived("OK")) + ret_val=1; + + //longitude + p_char = strchr((char *)(gsm.comm_buf),','); + p_char1 = p_char+1; //we are on the first char of longitude + p_char = strchr((char *)(p_char1), ','); + if (p_char != NULL) { + *p_char = 0; + } + strcpy(str_long, (char *)(p_char1)); + + // latitude + p_char++; + p_char1 = strchr((char *)(p_char), ','); + if (p_char1 != NULL) { + *p_char1 = 0; + } + strcpy(str_lat, (char *)(p_char)); + + // altitude + p_char1++; + p_char = strchr((char *)(p_char1), ','); + if (p_char != NULL) { + *p_char = 0; + } + strcpy(str_alt, (char *)(p_char1)); + + // UTC time + p_char++; + p_char1 = strchr((char *)(p_char), ','); + if (p_char1 != NULL) { + *p_char1 = 0; + } + strcpy(str_time, (char *)(p_char)); + + // TTFF + p_char1++; + p_char = strchr((char *)(p_char1), ','); + if (p_char != NULL) { + *p_char = 0; + } + + // num + p_char++; + p_char1 = strchr((char *)(p_char), ','); + if (p_char1 != NULL) { + *p_char1 = 0; + } + + // speed + p_char1++; + p_char = strchr((char *)(p_char1), ','); + if (p_char != NULL) { + *p_char = 0; + } + strcpy(str_speed, (char *)(p_char1)); + + return ret_val; +} + +void parseTime(char *field, int *time) +{ + ////////////////Time//////////// + char tmp[4]; + tmp[2]=0; // Init tmp and null terminate + tmp[0] = field[8]; + tmp[1] = field[9]; + time[0] = atoi(tmp); // Hours + tmp[0] = field[10]; + tmp[1] = field[11]; + time[1] = atoi(tmp); // Minutes + tmp[0] = field[12]; + tmp[1] = field[13]; + time[2] = atoi(tmp); // Seconds + /////////////Date/////////////// + tmp[0] = field[0]; + tmp[1] = field[1]; + tmp[2] = field[2]; + tmp[3] = field[3]; + tmp[4]=0; // Init tmp and null terminate + time[3] = atoi(tmp); // year + tmp[0] = field[4]; + tmp[1] = field[5]; + tmp[2]=0; // Init tmp and null terminate + time[4] = atoi(tmp); // month + tmp[0] = field[6]; + tmp[1] = field[7]; + tmp[2]=0; // Init tmp and null terminate + time[5] = atoi(tmp); // day +} + +// Read the latitude in decimal format from a GGA string +double convertLat(char* latString) +{ + double latitude = atof(latString); // convert to a double (precise) + int deg = (int) latitude / 100; // extract the number of degrees + double min = latitude - (100 * deg); // work out the number of minutes + latitude = deg + (double) min/60.0; // convert to decimal format + return latitude; +} + +// Read the longitude in decimal format from a GGA string +double convertLong(char* longString) +{ + double longitude = atof(longString); // convert to a double + int deg = (int) longitude / 100; // extract the number of degrees + double min = longitude - (100 * deg); // work out the number of minutes + longitude = deg + (double) min/60.00; // convert to decimal format + return longitude; +} \ No newline at end of file diff --git a/lib/ITEADLIB_Arduino_SIMCom/gps.h b/lib/ITEADLIB_Arduino_SIMCom/gps.h new file mode 100644 index 0000000..1da04f4 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/gps.h @@ -0,0 +1,19 @@ +#ifndef _GPS_H_ +#define _GPS_H_ + +#include "SIM900.h" + +class GPSGSM { +public: + char getBattInf(char *str_perc, char *str_vol); + char getBattTVol(char *str_vol); + char attachGPS(); + char deattachGPS(); + char getStat(); + char getPar(char *str_long, char *str_lat, char *str_alt, char *str_time, char *speed); + void parseTime(char *field, int *time); + double convertLat(void); + double convertLong(void); +}; + +#endif diff --git a/lib/ITEADLIB_Arduino_SIMCom/inetGSM.cpp b/lib/ITEADLIB_Arduino_SIMCom/inetGSM.cpp new file mode 100644 index 0000000..faab4c8 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/inetGSM.cpp @@ -0,0 +1,589 @@ +#include "inetGSM.h" +#define _GSM_CONNECTION_TOUT_ 5 +#define _TCP_CONNECTION_TOUT_ 20 +#define _GSM_DATA_TOUT_ 10 + +int InetGSM::httpGET(const char* server, int port, const char* path, char* result, int resultlength) +{ + boolean connected=false; + int n_of_at=0; + int length_write; + char end_c[2]; + end_c[0]=0x1a; + end_c[1]='\0'; + + /* + Status = ATTACHED. + if(gsm.getStatus()!=GSM::ATTACHED) + return 0; + */ + while(n_of_at<3) { + if(!connectTCP(server, port)) { +#ifdef DEBUG_ON + Serial.println("DB:NOT CONN"); +#endif + n_of_at++; + } else { + connected=true; + n_of_at=3; + } + } + + if(!connected) return 0; + + gsm.SimpleWrite("GET "); + gsm.SimpleWrite(path); + gsm.SimpleWrite(" HTTP/1.0\r\nHost: "); + gsm.SimpleWrite(server); + gsm.SimpleWrite("\r\n"); + gsm.SimpleWrite("User-Agent: Arduino"); + gsm.SimpleWrite("\r\n\r\n"); + gsm.SimpleWrite(end_c); + + switch(gsm.WaitResp(10000, 10, "SEND OK")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + + + delay(50); +#ifdef DEBUG_ON + Serial.println("DB:SENT"); +#endif + int res = gsm.read(result, resultlength); + + //gsm.disconnectTCP(); + + //int res=1; + return res; +} + +int InetGSM::httpPOST(const char* server, int port, const char* path, const char* parameters, char* result, int resultlength) +{ + boolean connected=false; + int n_of_at=0; + char itoaBuffer[8]; + int num_char; + char end_c[2]; + end_c[0]=0x1a; + end_c[1]='\0'; + + while(n_of_at<3) { + if(!connectTCP(server, port)) { +#ifdef DEBUG_ON + Serial.println("DB:NOT CONN"); +#endif + n_of_at++; + } else { + connected=true; + n_of_at=3; + } + } + + if(!connected) return 0; + + gsm.SimpleWrite("POST "); + gsm.SimpleWrite(path); + gsm.SimpleWrite(" HTTP/1.1\r\nHost: "); + gsm.SimpleWrite(server); + gsm.SimpleWrite("\r\n"); + gsm.SimpleWrite("User-Agent: Arduino\r\n"); + gsm.SimpleWrite("Authorization: Basic SECRET_CREDENTIAL\r\n"); + gsm.SimpleWrite("X-CSRF-Token: ACCESS_TOKEN\r\n"); + gsm.SimpleWrite("Accept: application/vnd.api+json\r\n"); + gsm.SimpleWrite("Content-Type: application/vnd.api+json\r\n"); + gsm.SimpleWrite("Content-Length: "); + itoa(strlen(parameters),itoaBuffer,10); + gsm.SimpleWrite(itoaBuffer); + gsm.SimpleWrite("\r\n\r\n"); + gsm.SimpleWrite(parameters); + gsm.SimpleWrite("\r\n\r\n"); + gsm.SimpleWrite(end_c); + + switch(gsm.WaitResp(10000, 10, "SEND OK")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + + delay(50); +#ifdef DEBUG_ON + Serial.println("DB:SENT"); +#endif + + int res= gsm.read(result, resultlength); + //gsm.disconnectTCP(); + return res; +} + +int InetGSM::openmail(char* server, char* loginbase64, char* passbase64, char* from, char* to, char* subj) +{ + boolean connected=false; + int n_of_at=0; + char end_c[2]; + end_c[0]=0x1a; + end_c[1]='\0'; + + while(n_of_at<3) { + if(!connectTCP(server, 25)) { +#ifdef DEBUG_ON + Serial.println("DB:NOT CONN"); +#endif + n_of_at++; + } else { + connected=true; + n_of_at=3; + } + } + + if(!connected) return 0; + + delay(100); + gsm.SimpleWrite("HELO "); + gsm.SimpleWrite(server); + gsm.SimpleWrite("\n"); + gsm.SimpleWrite(end_c); + gsm.WaitResp(5000, 100, "OK"); + if(!gsm.IsStringReceived("SEND OK")) + return 0; + delay(500); + gsm.WaitResp(5000, 100); + + delay(100); + gsm.SimpleWriteln("AT+CIPSEND"); + switch(gsm.WaitResp(5000, 200, ">")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + gsm.SimpleWrite("AUTH LOGIN\n"); + gsm.SimpleWrite(end_c); + gsm.WaitResp(5000, 100, "OK"); + if(!gsm.IsStringReceived("OK")) + return 0; + delay(500); + gsm.WaitResp(5000, 100); + + delay(100); + gsm.SimpleWriteln("AT+CIPSEND"); + switch(gsm.WaitResp(5000, 200, ">")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + gsm.SimpleWrite(loginbase64); + gsm.SimpleWrite("\n"); + gsm.SimpleWrite(end_c); + gsm.WaitResp(5000, 100, "OK"); + if(!gsm.IsStringReceived("OK")) + return 0; + delay(500); + gsm.WaitResp(5000, 100); + + delay(100); + gsm.SimpleWriteln("AT+CIPSEND"); + switch(gsm.WaitResp(5000, 200, ">")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + gsm.SimpleWrite(passbase64); + gsm.SimpleWrite("\n"); + gsm.SimpleWrite(end_c); + gsm.WaitResp(5000, 100, "OK"); + if(!gsm.IsStringReceived("OK")) + return 0; + delay(500); + gsm.WaitResp(5000, 100); + + + delay(100); + gsm.SimpleWriteln("AT+CIPSEND"); + switch(gsm.WaitResp(5000, 200, ">")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + gsm.SimpleWrite("MAIL From: <"); + gsm.SimpleWrite(from); + gsm.SimpleWrite(">\n"); + gsm.SimpleWrite(end_c); + gsm.WaitResp(5000, 100, "OK"); + if(!gsm.IsStringReceived("OK")) + return 0; + delay(500); + gsm.WaitResp(5000, 100, ""); + + delay(100); + gsm.SimpleWriteln("AT+CIPSEND"); + switch(gsm.WaitResp(5000, 200, ">")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + gsm.SimpleWrite("RCPT TO: <"); + gsm.SimpleWrite(to); + gsm.SimpleWrite(">\n"); + gsm.SimpleWrite(end_c); + gsm.WaitResp(5000, 100, "OK"); + if(!gsm.IsStringReceived("OK")) + return 0; + delay(500); + gsm.WaitResp(5000, 100, ""); + + delay(100); + gsm.SimpleWriteln("AT+CIPSEND"); + switch(gsm.WaitResp(5000, 200, ">")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + gsm.SimpleWrite("Data\n"); + gsm.SimpleWrite(end_c); + gsm.WaitResp(5000, 100, "OK"); + if(!gsm.IsStringReceived("OK")) + return 0; + delay(500); + gsm.WaitResp(5000, 100, ""); + + delay(100); + gsm.SimpleWriteln("AT+CIPSEND"); + switch(gsm.WaitResp(5000, 200, ">")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + gsm.SimpleWrite("Subject: "); + gsm.SimpleWrite(subj); + gsm.SimpleWrite("\n\n"); + + return 1; +} +int InetGSM::closemail() +{ + char end_c[2]; + end_c[0]=0x1a; + end_c[1]='\0'; + + gsm.SimpleWrite("\n.\n"); + gsm.SimpleWrite(end_c); + disconnectTCP(); + return 1; +} + + +int InetGSM::attachGPRS(char* domain, char* dom1, char* dom2) +{ + int i=0; + delay(5000); + + //gsm._tf.setTimeout(_GSM_DATA_TOUT_); //Timeout for expecting modem responses. + gsm.WaitResp(50, 50); + gsm.SimpleWriteln("AT+CIFSR"); + if(gsm.WaitResp(5000, 50, "ERROR")!=RX_FINISHED_STR_RECV) { +#ifdef DEBUG_ON + Serial.println("DB:ALREADY HAVE AN IP"); +#endif + gsm.SimpleWriteln("AT+CIPCLOSE"); + gsm.WaitResp(5000, 50, "ERROR"); + delay(2000); + gsm.SimpleWriteln("AT+CIPSERVER=0"); + gsm.WaitResp(5000, 50, "ERROR"); + return 1; + } else { + +#ifdef DEBUG_ON + Serial.println("DB:STARTING NEW CONNECTION"); +#endif + + gsm.SimpleWriteln("AT+CIPSHUT"); + + switch(gsm.WaitResp(500, 50, "SHUT OK")) { + + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } +#ifdef DEBUG_ON + Serial.println("DB:SHUTTED OK"); +#endif + delay(1000); + + gsm.SimpleWrite("AT+CSTT=\""); + gsm.SimpleWrite(domain); + gsm.SimpleWrite("\",\""); + gsm.SimpleWrite(dom1); + gsm.SimpleWrite("\",\""); + gsm.SimpleWrite(dom2); + gsm.SimpleWrite("\"\r"); + + + switch(gsm.WaitResp(500, 50, "OK")) { + + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } +#ifdef DEBUG_ON + Serial.println("DB:APN OK"); +#endif + delay(5000); + + gsm.SimpleWriteln("AT+CIICR"); + + switch(gsm.WaitResp(10000, 50, "OK")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } +#ifdef DEBUG_ON + Serial.println("DB:CONNECTION OK"); +#endif + + delay(1000); + + + gsm.SimpleWriteln("AT+CIFSR"); + if(gsm.WaitResp(5000, 50, "ERROR")!=RX_FINISHED_STR_RECV) { +#ifdef DEBUG_ON + Serial.println("DB:ASSIGNED AN IP"); +#endif + gsm.setStatus(gsm.ATTACHED); + return 1; + } +#ifdef DEBUG_ON + Serial.println("DB:NO IP AFTER CONNECTION"); +#endif + return 0; + } +} + +int InetGSM::dettachGPRS() +{ + if (gsm.getStatus()==gsm.IDLE) return 0; + + //gsm._tf.setTimeout(_GSM_CONNECTION_TOUT_); + + //_cell.flush(); + + //GPRS dettachment. + gsm.SimpleWriteln("AT+CGATT=0"); + if(gsm.WaitResp(5000, 50, "OK")!=RX_FINISHED_STR_NOT_RECV) { + gsm.setStatus(gsm.ERROR); + return 0; + } + delay(500); + + // Commented in initial trial code!! + //Stop IP stack. + //_cell << "AT+WIPCFG=0" << _DEC(cr) << endl; + // if(!gsm._tf.find("OK")) return 0; + //Close GPRS bearer. + //_cell << "AT+WIPBR=0,6" << _DEC(cr) << endl; + + gsm.setStatus(gsm.READY); + return 1; +} + +int InetGSM::connectTCP(const char* server, int port) +{ + //gsm._tf.setTimeout(_TCP_CONNECTION_TOUT_); + + //Status = ATTACHED. + //if (getStatus()!=ATTACHED) + //return 0; + + //_cell.flush(); + + //Visit the remote TCP server. + gsm.SimpleWrite("AT+CIPSTART=\"TCP\",\""); + gsm.SimpleWrite(server); + gsm.SimpleWrite("\","); + gsm.SimpleWriteln(port); + + switch(gsm.WaitResp(1000, 200, "OK")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } +#ifdef DEBUG_ON + Serial.println("DB:RECVD CMD"); +#endif + if (!gsm.IsStringReceived("CONNECT OK")) { + switch(gsm.WaitResp(15000, 200, "OK")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + } + +#ifdef DEBUG_ON + Serial.println("DB:OK TCP"); +#endif + + delay(3000); + gsm.SimpleWriteln("AT+CIPSEND"); + switch(gsm.WaitResp(5000, 200, ">")) { + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + +#ifdef DEBUG_ON + Serial.println("DB:>"); +#endif + delay(4000); + return 1; +} + +int InetGSM::disconnectTCP() +{ + //Status = TCPCONNECTEDCLIENT or TCPCONNECTEDSERVER. + /* + if ((getStatus()!=TCPCONNECTEDCLIENT)&&(getStatus()!=TCPCONNECTEDSERVER)) + return 0; + */ + //gsm._tf.setTimeout(_GSM_CONNECTION_TOUT_); + + + //_cell.flush(); + + //Switch to AT mode. + //_cell << "+++" << endl; + + //delay(200); + + //Close TCP client and deact. + gsm.SimpleWriteln("AT+CIPCLOSE"); + + //If remote server close connection AT+QICLOSE generate ERROR + /*if(gsm._tf.find("OK")) + { + if(getStatus()==TCPCONNECTEDCLIENT) + gsm.setStatus(ATTACHED); + else + gsm.setStatus(TCPSERVERWAIT); + return 1; + } + gsm.setStatus(ERROR); + + return 0; */ + if(gsm.getStatus()==gsm.TCPCONNECTEDCLIENT) + gsm.setStatus(gsm.ATTACHED); + else + gsm.setStatus(gsm.TCPSERVERWAIT); + return 1; +} + +int InetGSM::connectTCPServer(int port) +{ + /* + if (getStatus()!=ATTACHED) + return 0; + */ + //gsm._tf.setTimeout(_GSM_CONNECTION_TOUT_); + + //_cell.flush(); + + // Set port + + gsm.SimpleWrite("AT+CIPSERVER=1,"); + gsm.SimpleWriteln(port); + /* + switch(gsm.WaitResp(5000, 50, "OK")){ + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + + switch(gsm.WaitResp(5000, 50, "SERVER")){ //Try SERVER OK + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + } + */ + //delay(200); + + return 1; + +} + +boolean InetGSM::connectedClient() +{ + /* + if (getStatus()!=TCPSERVERWAIT) + return 0; + */ + + gsm.SimpleWriteln("AT+CIPSTATUS"); + // Alternative: AT+QISTAT, although it may be necessary to call an AT + // command every second,which is not wise + /* + switch(gsm.WaitResp(1000, 200, "OK")){ + case RX_TMOUT_ERR: + return 0; + break; + case RX_FINISHED_STR_NOT_RECV: + return 0; + break; + }*/ + //gsm._tf.setTimeout(1); + if(gsm.WaitResp(5000, 50, "CONNECT OK")!=RX_FINISHED_STR_RECV) { + gsm.setStatus(gsm.TCPCONNECTEDSERVER); + return true; + } else + return false; +} + diff --git a/lib/ITEADLIB_Arduino_SIMCom/inetGSM.h b/lib/ITEADLIB_Arduino_SIMCom/inetGSM.h new file mode 100644 index 0000000..41412c8 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/inetGSM.h @@ -0,0 +1,31 @@ +#ifndef _INETGSM_H_ +#define _INETGSM_H_ + +#define BUFFERSIZE 1 + +#include "SIM900.h" + +class InetGSM { +private: + char _buffer[BUFFERSIZE]; + +public: + int httpGET(const char* server, int port, const char* path, char* result, int resultlength); + int httpPOST(const char* server, int port, const char* path, const char* parameters, char* result, int resultlength); + + // Fast and dirty solution. Should make a "mail" object. And by the moment it does not run. + int openmail(char* server, char* loginbase64, char* passbase64, char* from, char* to, char* subj); + int closemail(); + int attachGPRS(char* domain, char* dom1, char* dom2); + int dettachGPRS(); + int connectTCP(const char* server, int port); + int disconnectTCP(); + int connectTCPServer(int port); + boolean connectedClient(); + + // This runs, yes + //int tweet(const char* token, const char* msg); + +}; + +#endif diff --git a/lib/ITEADLIB_Arduino_SIMCom/sms.cpp b/lib/ITEADLIB_Arduino_SIMCom/sms.cpp new file mode 100644 index 0000000..5d935bd --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/sms.cpp @@ -0,0 +1,572 @@ +#include "sms.h" + +/********************************************************** +Method sends SMS + +number_str: pointer to the phone number string +message_str: pointer to the SMS text string + + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - GSM module has answered "ERROR" string + + OK ret val: + ----------- + 0 - SMS was not sent + 1 - SMS was sent + + +an example of usage: + GSM gsm; + gsm.SendSMS("00XXXYYYYYYYYY", "SMS text"); +**********************************************************/ +char SMSGSM::SendSMS(char *number_str, char *message_str) +{ + if(strlen(message_str)>159) + Serial.println(F("Don't send message longer than 160 characters")); + char ret_val = -1; + byte i; + char end[2]; + end[0]=0x1a; + end[1]='\0'; + /* + if (CLS_FREE != gsm.GetCommLineStatus()) return (ret_val); + gsm.SetCommLineStatus(CLS_ATCMD); + ret_val = 0; // still not send + */ + // try to send SMS 3 times in case there is some problem + for (i = 0; i < 1; i++) { + // send AT+CMGS="number_str" + + gsm.SimpleWrite(F("AT+CMGS=\"")); + gsm.SimpleWrite(number_str); + gsm.SimpleWriteln("\""); + +#ifdef DEBUG_ON + Serial.println("DEBUG:SMS TEST"); +#endif + // 1000 msec. for initial comm tmout + // 50 msec. for inter character timeout + if (RX_FINISHED_STR_RECV == gsm.WaitResp(1000, 500, ">")) { +#ifdef DEBUG_ON + Serial.println("DEBUG:>"); +#endif + // send SMS text + gsm.SimpleWrite(message_str); + gsm.SimpleWriteln(end); + //_cell.flush(); // erase rx circular buffer + if (RX_FINISHED_STR_RECV == gsm.WaitResp(7000, 5000, "+CMGS")) { + // SMS was send correctly + ret_val = 1; + + break; + } else continue; + } else { + // try again + continue; + + } + } + + gsm.SetCommLineStatus(CLS_FREE); + return (ret_val); +} + +/********************************************************** +Method sends SMS to the specified SIM phonebook position + +sim_phonebook_position: SIM phonebook position <1..20> +message_str: pointer to the SMS text string + + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - specified position must be > 0 + + OK ret val: + ----------- + 0 - SMS was not sent + 1 - SMS was sent + + +an example of usage: + GSM gsm; + gsm.SendSMS(1, "SMS text"); +**********************************************************/ +char SMSGSM::SendSMS(byte sim_phonebook_position, char *message_str) +{ + char ret_val = -1; + char sim_phone_number[20]; + + ret_val = 0; // SMS is not send yet + if (sim_phonebook_position == 0) return (-3); + if (1 == gsm.GetPhoneNumber(sim_phonebook_position, sim_phone_number)) { + // there is a valid number at the spec. SIM position + // => send SMS + // ------------------------------------------------- + ret_val = SendSMS(sim_phone_number, message_str); + } + return (ret_val); + +} + + +/********************************************************** +Method finds out if there is present at least one SMS with +specified status + +Note: +if there is new SMS before IsSMSPresent() is executed +this SMS has a status UNREAD and then +after calling IsSMSPresent() method status of SMS +is automatically changed to READ + +required_status: SMS_UNREAD - new SMS - not read yet + SMS_READ - already read SMS + SMS_ALL - all stored SMS + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + + OK ret val: + ----------- + 0 - there is no SMS with specified status + 1..20 - position where SMS is stored + (suitable for the function GetSMS()) + + +an example of use: + GSM gsm; + char position; + char phone_number[20]; // array for the phone number string + char sms_text[100]; + + position = gsm.IsSMSPresent(SMS_UNREAD); + if (position) { + // read new SMS + gsm.GetSMS(position, phone_num, sms_text, 100); + // now we have phone number string in phone_num + // and SMS text in sms_text + } +**********************************************************/ +char SMSGSM::IsSMSPresent(byte required_status) +{ + char ret_val = -1; + char *p_char; + byte status; + + if (CLS_FREE != gsm.GetCommLineStatus()) return (ret_val); + gsm.SetCommLineStatus(CLS_ATCMD); + ret_val = 0; // still not present + + switch (required_status) { + case SMS_UNREAD: + gsm.SimpleWriteln(F("AT+CMGL=\"REC UNREAD\"")); + break; + case SMS_READ: + gsm.SimpleWriteln(F("AT+CMGL=\"REC READ\"")); + break; + case SMS_ALL: + gsm.SimpleWriteln(F("AT+CMGL=\"ALL\"")); + break; + } + + // 5 sec. for initial comm tmout + // and max. 1500 msec. for inter character timeout + gsm.RxInit(5000, 1500); + // wait response is finished + do { + if (gsm.IsStringReceived("OK")) { + // perfect - we have some response, but what: + + // there is either NO SMS: + // OK + + // or there is at least 1 SMS + // +CMGL: ,,,,[,,] + // OK + status = RX_FINISHED; + break; // so finish receiving immediately and let's go to + // to check response + } + status = gsm.IsRxFinished(); + } while (status == RX_NOT_FINISHED); + + switch (status) { + case RX_TMOUT_ERR: + // response was not received in specific time + ret_val = -2; + break; + + case RX_FINISHED: + // something was received but what was received? + // --------------------------------------------- + if(gsm.IsStringReceived("+CMGL:")) { + // there is some SMS with status => get its position + // response is: + // +CMGL: ,,,,[,,] + // OK + p_char = (char *)gsm.comm_buf; + Serial.println(p_char); + + if (p_char != NULL) { + String sms_message = String(p_char).substring(0, 16); + int colonPosition = sms_message.indexOf(':', 0); + int commaPosition = sms_message.indexOf(',', 0); + int sms_position = sms_message.substring(colonPosition + 2, commaPosition).toInt(); + + Serial.print("Colon position: "); + Serial.println(colonPosition); + Serial.print("Comma position: "); + Serial.println(commaPosition); + Serial.print("SMS position: "); + Serial.println(sms_position); + + ret_val = sms_position; + } + } else { + // other response like OK or ERROR + ret_val = 0; + } + + // here we have gsm.WaitResp() just for generation tmout 20msec. in case OK was detected + // not due to receiving + gsm.WaitResp(20, 20); + break; + } + + gsm.SetCommLineStatus(CLS_FREE); + return (ret_val); +} + + +/********************************************************** +Method reads SMS from specified memory(SIM) position + +position: SMS position <1..20> +phone_number: a pointer where the phone number string of received SMS will be placed + so the space for the phone number string must be reserved - see example +SMS_text : a pointer where SMS text will be placed +max_SMS_len: maximum length of SMS text excluding also string terminating 0x00 character + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - specified position must be > 0 + + OK ret val: + ----------- + GETSMS_NO_SMS - no SMS was not found at the specified position + GETSMS_UNREAD_SMS - new SMS was found at the specified position + GETSMS_READ_SMS - already read SMS was found at the specified position + GETSMS_OTHER_SMS - other type of SMS was found + + +an example of usage: + GSM gsm; + char position; + char phone_num[20]; // array for the phone number string + char sms_text[100]; // array for the SMS text string + + position = gsm.IsSMSPresent(SMS_UNREAD); + if (position) { + // there is new SMS => read it + gsm.GetSMS(position, phone_num, sms_text, 100); + #ifdef DEBUG_PRINT + gsm.DebugPrint("DEBUG SMS phone number: ", 0); + gsm.DebugPrint(phone_num, 0); + gsm.DebugPrint("\r\n SMS text: ", 0); + gsm.DebugPrint(sms_text, 1); + #endif + } +**********************************************************/ +char SMSGSM::GetSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len) +{ + char ret_val = -1; + char *p_char; + char *p_char1; + byte len; + + if (position == 0) return (-3); + if (CLS_FREE != gsm.GetCommLineStatus()) return (ret_val); + gsm.SetCommLineStatus(CLS_ATCMD); + phone_number[0] = 0; // end of string for now + ret_val = GETSMS_NO_SMS; // still no SMS + + //send "AT+CMGR=X" - where X = position + gsm.SimpleWrite(F("AT+CMGR=")); + gsm.SimpleWriteln((int)position); + + // 5000 msec. for initial comm tmout + // 100 msec. for inter character tmout + switch (gsm.WaitResp(5000, 100, "+CMGR")) { + case RX_TMOUT_ERR: + // response was not received in specific time + ret_val = -2; + break; + + case RX_FINISHED_STR_NOT_RECV: + // OK was received => there is NO SMS stored in this position + if(gsm.IsStringReceived("OK")) { + // there is only response OK + // => there is NO SMS + ret_val = GETSMS_NO_SMS; + } else if(gsm.IsStringReceived("ERROR")) { + // error should not be here but for sure + ret_val = GETSMS_NO_SMS; + } + break; + + case RX_FINISHED_STR_RECV: + // find out what was received exactly + + //response for new SMS: + //+CMGR: "REC UNREAD","+XXXXXXXXXXXX",,"02/03/18,09:54:28+40" + //There is SMS textOK + if(gsm.IsStringReceived("\"REC UNREAD\"")) { + // get phone number of received SMS: parse phone number string + // +XXXXXXXXXXXX + // ------------------------------------------------------- + ret_val = GETSMS_UNREAD_SMS; + } + //response for already read SMS = old SMS: + //+CMGR: "REC READ","+XXXXXXXXXXXX",,"02/03/18,09:54:28+40" + //There is SMS text + else if(gsm.IsStringReceived("\"REC READ\"")) { + // get phone number of received SMS + // -------------------------------- + ret_val = GETSMS_READ_SMS; + } else { + // other type like stored for sending.. + ret_val = GETSMS_OTHER_SMS; + } + + // extract phone number string + // --------------------------- + p_char = strchr((char *)(gsm.comm_buf),','); + p_char1 = p_char+2; // we are on the first phone number character + p_char = strchr((char *)(p_char1),'"'); + if (p_char != NULL) { + *p_char = 0; // end of string + strcpy(phone_number, (char *)(p_char1)); + } + + + // get SMS text and copy this text to the SMS_text buffer + // ------------------------------------------------------ + p_char = strchr(p_char+1, 0x0a); // find + if (p_char != NULL) { + // next character after is the first SMS character + p_char++; // now we are on the first SMS character + + // find as the end of SMS string + p_char1 = strchr((char *)(p_char), 0x0d); + if (p_char1 != NULL) { + // finish the SMS text string + // because string must be finished for right behaviour + // of next strcpy() function + *p_char1 = 0; + } + // in case there is not finish sequence because the SMS is + // too long (more then 130 characters) sms text is finished by the 0x00 + // directly in the gsm.WaitResp() routine + + // find out length of the SMS (excluding 0x00 termination character) + len = strlen(p_char); + + if (len < max_SMS_len) { + // buffer SMS_text has enough place for copying all SMS text + // so copy whole SMS text + // from the beginning of the text(=p_char position) + // to the end of the string(= p_char1 position) + strcpy(SMS_text, (char *)(p_char)); + } else { + // buffer SMS_text doesn't have enough place for copying all SMS text + // so cut SMS text to the (max_SMS_len-1) + // (max_SMS_len-1) because we need 1 position for the 0x00 as finish + // string character + memcpy(SMS_text, (char *)(p_char), (max_SMS_len-1)); + SMS_text[max_SMS_len] = 0; // finish string + } + } + break; + } + + gsm.SetCommLineStatus(CLS_FREE); + return (ret_val); +} + +/********************************************************** +Method reads SMS from specified memory(SIM) position and +makes authorization - it means SMS phone number is compared +with specified SIM phonebook position(s) and in case numbers +match GETSMS_AUTH_SMS is returned, otherwise GETSMS_NOT_AUTH_SMS +is returned + +position: SMS position to be read <1..20> +phone_number: a pointer where the tel. number string of received SMS will be placed + so the space for the phone number string must be reserved - see example +SMS_text : a pointer where SMS text will be placed +max_SMS_len: maximum length of SMS text excluding terminating 0x00 character + +first_authorized_pos: initial SIM phonebook position where the authorization process + starts +last_authorized_pos: last SIM phonebook position where the authorization process + finishes + + Note(important): + ================ + In case first_authorized_pos=0 and also last_authorized_pos=0 + the received SMS phone number is NOT authorized at all, so every + SMS is considered as authorized (GETSMS_AUTH_SMS is returned) + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - position must be > 0 + + OK ret val: + ----------- + GETSMS_NO_SMS - no SMS was found at the specified position + GETSMS_NOT_AUTH_SMS - NOT authorized SMS found at the specified position + GETSMS_AUTH_SMS - authorized SMS found at the specified position + + +an example of usage: + GSM gsm; + char phone_num[20]; // array for the phone number string + char sms_text[100]; // array for the SMS text string + + // authorize SMS with SIM phonebook positions 1..3 + if (GETSMS_AUTH_SMS == gsm.GetAuthorizedSMS(1, phone_num, sms_text, 100, 1, 3)) { + // new authorized SMS was detected at the SMS position 1 + #ifdef DEBUG_PRINT + gsm.DebugPrint("DEBUG SMS phone number: ", 0); + gsm.DebugPrint(phone_num, 0); + gsm.DebugPrint("\r\n SMS text: ", 0); + gsm.DebugPrint(sms_text, 1); + #endif + } + + // don't authorize SMS with SIM phonebook at all + if (GETSMS_AUTH_SMS == gsm.GetAuthorizedSMS(1, phone_num, sms_text, 100, 0, 0)) { + // new SMS was detected at the SMS position 1 + // because authorization was not required + // SMS is considered authorized + #ifdef DEBUG_PRINT + gsm.DebugPrint("DEBUG SMS phone number: ", 0); + gsm.DebugPrint(phone_num, 0); + gsm.DebugPrint("\r\n SMS text: ", 0); + gsm.DebugPrint(sms_text, 1); + #endif + } +**********************************************************/ +char SMSGSM::GetAuthorizedSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len, + byte first_authorized_pos, byte last_authorized_pos) +{ + char ret_val = -1; + byte i; + + ret_val = GetSMS(position, phone_number, SMS_text, max_SMS_len); + if (ret_val < 0) { + // here is ERROR return code => finish + // ----------------------------------- + } else if (ret_val == GETSMS_NO_SMS) { + // no SMS detected => finish + // ------------------------- + } else if (ret_val == GETSMS_READ_SMS) { + // now SMS can has only READ attribute because we have already read + // this SMS at least once by the previous function GetSMS() + // + // new READ SMS was detected on the specified SMS position => + // make authorization now + // --------------------------------------------------------- + if ((first_authorized_pos == 0) && (last_authorized_pos == 0)) { + // authorization is not required => it means authorization is OK + // ------------------------------------------------------------- + ret_val = GETSMS_AUTH_SMS; + } else { + ret_val = GETSMS_NOT_AUTH_SMS; // authorization not valid yet + for (i = first_authorized_pos; i <= last_authorized_pos; i++) { + if (gsm.ComparePhoneNumber(i, phone_number)) { + // phone numbers are identical + // authorization is OK + // --------------------------- + ret_val = GETSMS_AUTH_SMS; + break; // and finish authorization + } + } + } + } + return (ret_val); +} + + +/********************************************************** +Method deletes SMS from the specified SMS position + +position: SMS position <1..20> + +return: + ERROR ret. val: + --------------- + -1 - comm. line to the GSM module is not free + -2 - GSM module didn't answer in timeout + -3 - position must be > 0 + + OK ret val: + ----------- + 0 - SMS was not deleted + 1 - SMS was deleted +**********************************************************/ +char SMSGSM::DeleteSMS(byte position) +{ + char ret_val = -1; + + if (position == 0) return (-3); + if (CLS_FREE != gsm.GetCommLineStatus()) return (ret_val); + gsm.SetCommLineStatus(CLS_ATCMD); + ret_val = 0; // not deleted yet + + //send "AT+CMGD=XY" - where XY = position + gsm.SimpleWrite(F("AT+CMGD=")); + gsm.SimpleWriteln((int)position); + + + // 5000 msec. for initial comm tmout + // 20 msec. for inter character timeout + switch (gsm.WaitResp(5000, 50, "OK")) { + case RX_TMOUT_ERR: + // response was not received in specific time + ret_val = -2; + break; + + case RX_FINISHED_STR_RECV: + // OK was received => SMS deleted + ret_val = 1; + break; + + case RX_FINISHED_STR_NOT_RECV: + // other response: e.g. ERROR => SMS was not deleted + ret_val = 0; + break; + } + + gsm.SetCommLineStatus(CLS_FREE); + return (ret_val); +} + diff --git a/lib/ITEADLIB_Arduino_SIMCom/sms.h b/lib/ITEADLIB_Arduino_SIMCom/sms.h new file mode 100644 index 0000000..867a011 --- /dev/null +++ b/lib/ITEADLIB_Arduino_SIMCom/sms.h @@ -0,0 +1,22 @@ +#ifndef _SMS_H_ +#define _SMS_H_ + +#include "SIM900.h" +#include "string.h" + +class SMSGSM { +public: + // SMS's methods + char SendSMS(char *number_str, char *message_str); + char SendSMS(byte sim_phonebook_position, char *message_str); + char IsSMSPresent(byte required_status); + char GetSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len); + + char GetAuthorizedSMS(byte position, char *phone_number, char *SMS_text, byte max_SMS_len, + byte first_authorized_pos, byte last_authorized_pos); + char DeleteSMS(byte position); + +}; + +#endif + diff --git a/src/main.cpp b/src/main.cpp index 58b344c..9f6b73a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,261 @@ +/** + * Send and Receive SMS with SIM900. + * + * @author ElexParts + * @url https://www.elexparts.com + */ + #include +#include +#include +#include +#include +#include "inetGSM.h" + +// Define constants. +#define DEBUG 1 // Enable or disable debugging +#define DHTPIN A0 // Temperature Sense pin +#define DHTTYPE DHT11 // DHT 11 + +// Configure Temperature sensor. +DHT dht(DHTPIN, DHTTYPE); +float humidity; // Humidity +float temperature; // Temperature +unsigned long previousMillis = 0; // Variable to store current time. +const long interval = 5000; // Set interval to read temperature. + +// Configure GSM module. +InetGSM inet; +char msg[50]; +char inSerial[50]; +int i = 0; + +// Simple sketch to send and receive SMS. +// To change pins for Software Serial, use the two lines in GSM.cpp. +// _GSM_TXPIN_ was set to 2 +// _GSM_RXPIN_ was set to 3 +int gsmStatusLed = 12; + +// Flag to check if GSM has started. +boolean started = false; void setup() { - // put your setup code here, to run once: -} + pinMode(gsmStatusLed, OUTPUT); + + if (DEBUG) { + // Serial connection. + Serial.begin(9600); + while (!Serial) { + ; // wait for serial port to connect. Needed for native USB port only + } + } + + // Initialize Temperature sensor. + dht.begin(); + + Serial.println("Initializing GSM Shield ..."); + + // Start configuration of shield with baudrate (4800 or lower). + if (gsm.begin(2400)) { + Serial.println("\nGSM Status: READY"); + started = true; + } else { + Serial.println("\nGSM Status: IDLE"); + } + + if(started) { + // Turn on LED when GSM is ready. + digitalWrite(gsmStatusLed, HIGH); + + // GPRS attach, put in order APN, username and password. + // If no needed auth let them blank. + // APN is from Sun Cellular Network, change it according + // cellular network provider. + if (inet.attachGPRS("http://globe.com.ph", "", "")) { + Serial.println("GPRS Status: ATTACHED"); + } + else { + Serial.println("GPRS Status: ERROR"); + } + delay(1000); + + // Read IP address. + gsm.SimpleWriteln("AT+CIFSR"); + delay(3000); + + // Read until serial buffer is empty. + gsm.WhileSimpleRead(); + } +}; + +/** + * Serial hardware read. + */ +void serialhwread() { + i = 0; + if (Serial.available() > 0) { + while (Serial.available() > 0) { + inSerial[i]=(Serial.read()); + delay(10); + i++; + } + + inSerial[i]='\0'; + if(!strcmp(inSerial,"/END")) { + Serial.println("_"); + inSerial[0]=0x1a; + inSerial[1]='\0'; + gsm.SimpleWriteln(inSerial); + } + + // Send a saved AT command using serial port. + if(!strcmp(inSerial,"TEST")) { + Serial.println("SIGNAL QUALITY"); + gsm.SimpleWriteln("AT+CSQ"); + } + + // Read last message saved. + if(!strcmp(inSerial,"MSG")) { + Serial.println(msg); + } else { + Serial.println(inSerial); + gsm.SimpleWriteln(inSerial); + } + inSerial[0]='\0'; + } +}; + +/** + * Serial software read. + */ +void serialswread() { + gsm.SimpleRead(); +}; + +/** + * Log temperature data. + */ +void logTemperature(float temperature) { + Serial.println("Logged temperature data."); + + // Account credentials, we are using Basic Authentication for now. + // USERNAME + // PASSWORD + + // Base-encode credentials. + // SECRET_CREDENTIAL + + // Get access token. + // numdata = inet.httpGET("api.elexlabs.com", 80, "/rest/session/token", msg, 1000); + + // Print the results. + // Serial.println("\nGET - Number of data received:"); + // Serial.println(numdata); + // Serial.println("\nGET - Data received:"); + // Serial.println(msg); + + /** + HTTP/1.1 200 OK + Cache-Control: must-revalidate, no-cache, private + Content-Language: en + Expires: Sun, 19 Nov 1978 05:00:00 GMT + Server: nginx + X-Content-Type-Options: nosniff + X-Debug-Token: e29f2c + X-Debug-Token-Link: /admin/reports/profiler/view/e29f2c + X-Frame-Options: SAMEORIGIN + X-Generator: Drupal 8 (https://www.drupal.org) + X-Pantheon-Styx-Hostname: styx-fe3-a-5794d5fd7-qpvrq + X-Styx-Req-Id: styx-24f5a9ba846f9378b2cb5a6c4998e4a1 + X-Ua-Compatible: IE=edge + Accept-Ranges: bytes + Accept-Ranges: bytes + Via: 1.1 varnish + Age: 0 + Accept-Ranges: bytes + Accept-Ranges: bytes + Date: Sun, 27 Jan 2019 05:57:57 GMT + Via: 1.1 varnish + Connection: close + X-Served-By: cache-mdw17345-MDW, cache-hkg17926-HKG + X-Cache: MISS, MISS + X-Cache-Hits: 0, 0 + X-Timer: S1548568881.732217,VS0,VE268 + Vary: + RIC: + Content-Type: text/plain;charset=UTF-8 + Content-Length: 43 + + D6t_CjaEE0buRV677WFUajX28DjBqyfH8iw_99zPMZY + + CLOSED + + */ + + // We're able to get an http response when requesting for access token. + // Now we need to parse it. + // char access_token[60] = "D6t_CjaEE0buRV677WFUajX28DjBqyfH8iw_99zPMZY"; + + // HTTP Headers. + // Authorization Basic SECRET_CREDENTIAL + // X-CSRF-Token ACCESS_TOKEN + // Content-Type application/vnd.api+json + // Accept application/vnd.api+json + + // Parameters in json format. + /** + { + "data": { + "type": "node--contact", + "attributes": { + "title": "Contact", + "field_phone_number": "+639000000000", + "field_message": "SMS message." + } + } + } + */ + + // Do a POST request. + // const char* parameters; + // parameters = "{\"data\":{\"type\":\"node--temperature\",\"attributes\":{\"title\":\"Temperature\",\"field_value_temperature\":21}}}"; + // numdata = inet.httpPOST("dev-elexparts-api.pantheonsite.io", 80, "/json/api/node/temperature", parameters, msg, 50); + + // Print the results. + // Serial.println("\nPOST - Number of data received:"); + // Serial.println(numdata); + // Serial.println("\nPOST - Data received:"); + // Serial.println(msg); +}; void loop() { - // put your main code here, to run repeatedly: -} \ No newline at end of file + unsigned long currentMillis = millis(); + + // Read for new byte on serial hardware, + // and write them on NewSoftSerial. + serialhwread(); + + // Read for new byte on NewSoftSerial. + serialswread(); + + if (currentMillis - previousMillis >= interval) { + // Save the last time we've read the temperature. + previousMillis = currentMillis; + + // Read data and store it to variables hum and temp. + humidity = dht.readHumidity(); + temperature= dht.readTemperature(); + + if (DEBUG) { + // Print temp and humidity values to serial monitor. + Serial.print("Humidity: "); + Serial.print(humidity); + Serial.print(" %, Temp: "); + Serial.print(temperature); + Serial.print(" *C\n"); + } + + // Log temperature data. + logTemperature(temperature); + } +}; \ No newline at end of file