erdemarslan / gsmsim Goto Github PK
View Code? Open in Web Editor NEWGSM Library for SIMCOM Modules on Arduino.
License: MIT License
GSM Library for SIMCOM Modules on Arduino.
License: MIT License
Hi,
Here's an idea I hope you will like, to make this library also usable on other architectures where you don't have SoftwareSerial, you find preexistent instances of HardwareSerial instead.
NOTICE: The calls you are using to SoftwareSerial methods have equivalents of the same exact name in the HardwareSerial class, I didn't have to change any such calls. But I haven't checked that all methods actually behave the same way, I have only tested sending SMS messages so far [EDIT: and dialing a call to a landlilne or mobile phone, both things are working very fine now].
Very short story: I made a program on the STM32F103C8T6 board (very cheap yet much more capable than Uno/ProMini and Leonardo/ProMicro) which - apart other things - sends an SMS from a SIM800L GSM module.
Then, I wanted to give a look at your library and I liked it, you did a great job.
So, I spent a few hours seeing if it could be easily modified to work with a preexistent instance of HardwareSerial, instead of inheriting from SoftwareSerial.
I'm using the Roger Clark core for the STM32F103C8T6. In it, you find one pre-instantiated HardwareSerial object for each hardware serial interface on the board, there's no SoftwareSerial library available as far as I know (slash-dev's answer on this page corroborates that it would be nonsense to use SoftwareSerial on it).
Here's a quick mod of your example which sends an SMS + your GSMSim class. I started from the current official release ver 1.0.19. You don't have to take my work, apart for testing if you want, you can redo what I did rather quickly, starting from the next official GSMSim releaes which would integrate all current ongoing fixes/improvements.
In fact, the process was easy because you very diligently used "this->" every time you called a method inherited from SoftwareSerial.
So, the main modification is to define a member serialManager (or the name you like), which is a reference to an external preexistent instance of a HardwareSerial or SoftwareSerial object, and replace all occurrences of "this->" with "serialManager." occurrences.
Actually, I first modified it for HardwareSerial only and tested it, then I turned it into a template so the same source and maintanance/upgrade work would be usable with both HardwareSerial and SoftwareSerial classes (and possibly other method-to-method compatible classes).
IN CASE SOME PECULIAR PART OF THE SOURCE CODE WOULD HAVE TO BE DIFFERENT, THIS PAGE EXPLAINS HOW TO DO IT WITH "TEMPLATE SPECIALIZATION".
(Of course I had to touch a few other things, certain constructors become unnecessary because now you can initialize an external SerialSoftware object apart, before creating the GSMSim one, when you don't find a pre-instantiated HardwareSerial object of course, such as in the core I'm using with this STM32F103C8T6 boards.)
You'll see that I've also commented out the LED related lines, but you don't have to do the same of course.
I've seen on GitHub that a few minor problems have already been or are already being addressed, e.g. values which can't be represented with uint8_t, or lines with just "false" instead of "return false". The current version of the Arduino IDE was warning on them all.
Finally, I would advise to keep - as I was taught long ago - one single exit point from functions: instead of many return ...
lines, you can have many lines like returnValue = ...
and then one single return returnValue
line at the end.
But your source is so tidy that this is not a real issue.
Here's file GSMSim_TemplateSerial___SMS___v01.001.ino, quick mod of your SMS example:
#include <GSMSim_TemplateSerial.h>
/* Orig lib GSMSim, let's see if we can also use it with a preexistent instance of HardwareSerial instead of inheriting from SoftwareSerial.
Quick mod by Nicola "JazzTp" Bernardelli
STM32F103C8T6 board with Roger Clark's core https://github.com/rogerclarkmelbourne/Arduino_STM32
NOTICE: only tested sending SMS and dialing a number, so far.
*/
#ifdef BOARD_generic_stm32f103c
#define DEFAULT_PIN_RESET PB0
#else
#define DEFAULT_PIN_RESET 2
#endif
#define BAUD 9600
GSMSim_TemplateSerial<HardwareSerial> gsm(Serial2, DEFAULT_PIN_RESET);
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("GSMSim_HWserial Library - SMS Example");
Serial.println("");
delay(1000);
gsm.start(); // baud default 9600
// gsm.start(BAUD);
Serial.println("Changing to text mode.");
gsm.smsTextMode(true); // TEXT or PDU mode. TEXT is readable :)
const char* number = "+905123456789";
char* message = "Hi my friend. How are you?"; // message lenght must be <= 160. Only english characters.
Serial.println("Sending Message --->");
Serial.println(gsm.smsSend(number, message)); // if success it returns true (1) else false (0)
delay(2000);
Serial.println("Listing unread message(s).");
Serial.println(gsm.smsListUnread()); // if not unread messages have it returns "NO_SMS"
Serial.println("Read SMS on index no = 1");
Serial.println(gsm.smsRead(1)); // if no message in that index, it returns INDEX_NO_ERROR
}
void loop() {
// put your main code here, to run repeatedly:
}
And here's file GSMSim_TemplateSerial.h quick mod of your class, you might simply call it GSMSim2 instead of GSMSim_TemplateSerial (it also contains what was in the .cpp file, but please see the note I left where that part begins).
Again: this class does not inherit from SoftwareSerial, this breaks compatibility, you would have to put all ongoing minor fixes into GSMSim, make one final official release, and then leave it and create the new GSMSim2 library, other developers did that with their libraries, leaving both the old and the new one available).
Please just let me know if you want me to e-mail you both files.
[EDIT: sorry I see that here some indent problems appear, I'm seeing it differently in GEdit.]
/* Orig lib GSMSim, let's see if we can also use it with a preexistent instance of HardwareSerial instead of inheriting from SoftwareSerial.
Quick mod by Nicola "JazzTp" Bernardelli
STM32F103C8T6 board with Roger Clark's core https://github.com/rogerclarkmelbourne/Arduino_STM32
NOTICE: only tested sending SMS and dialing a number, so far.
*/
/*
GSMSim_TemplateSerial Library
This library written for SIMCOM Sim800L module. Library may worked on any SIMCOM modules
and GSM Shields.
Created 11.05.2017
By Erdem ARSLAN
Modified 25.08.2017
Erdem ARSLAN
Science and Technology Teacher, an Arduino Lover =)
[email protected]
https://www.erdemarslan.com/
http://www.robothane.net/
http://www.eralabs.net/
*/
#ifndef GSMSim_TemplateSerial_h
#define GSMSim_TemplateSerial_h
// #include <SoftwareSerial.h>
#include "Arduino.h"
// DEFAULT PIN DEFINATIONS IN HERE
// #define DEFAULT_RX_PIN 7
// #define DEFAULT_TX_PIN 8
// #define DEFAULT_RST_PIN 2
// #define DEFAULT_LED_FLAG true
// #define DEFAULT_LED_PIN 13
// #define DEFAULT_LED_PIN 32
#define DEFAULT_BAUD_RATE 9600
#define BUFFER_RESERVE_MEMORY 255
#define TIME_OUT_READ_SERIAL 5000
// PIN (PERSONAL IDENTIFICATION NUMBER) STATUS
#define PIN_READY 0
#define SIM_PIN 1
#define SIM_PUK 2
#define PH_SIM_PIN 3
#define PH_SIM_PUK 4
#define SIM_PIN2 5
#define SIM_PUK2 6
#define PIN_STATUS_UNKNOWN 7
// CALL STATUS
#define READY 0
#define UNKNOWN 2
#define RINGING 3
#define IN_CALL 4
#define NOT_READ 99
// CLASS BEGIN IN HERE
template <class HWorSW_Serial> class GSMSim_TemplateSerial /* : public SoftwareSerial nope, we want to be able to work with pre-instantiated objects */
{
private: /* consider changing to protected! */
HWorSW_Serial& serialManager;
uint32_t _baud;
uint8_t _timeout;
String _buffer;
String _readSerial();
String _readSerial(uint32_t timeout);
uint8_t RESET_PIN;
public:
/*
uint8_t RX_PIN;
uint8_t TX_PIN;
uint8_t RESET_PIN;
uint8_t LED_PIN;
bool LED_FLAG;
uint32_t BAUDRATE;
*/
GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN);
/*
GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN, uint8_t rx, uint8_t tx);
GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN, uint8_t rx, uint8_t tx, uint8_t rst);
GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN, uint8_t rx, uint8_t tx, uint8_t rst, uint8_t led);
GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN, uint8_t rx, uint8_t tx, uint8_t rst, uint8_t led, bool ledflag);
*/
// Başlatıcı Fonksiyon
void start();
void start(uint32_t baud);
// Reset Fonksiyonu
void reset();
// Kontrol Metotları
// Telefon Fonksiyonunu ayarlar
bool setPhoneFunc(uint8_t level);
// Sinyal kalitesi
uint8_t signalQuality();
// Operatöre bağlı mı?
bool isRegistered();
// Sim kart takılımı
bool isSimInserted();
// pin durumu
uint8_t pinStatus();
// operatör adı
String operatorName();
// sim karttaki operatör adı
String operatorNameFromSim();
// telefon durumu
uint8_t phoneStatus();
// echo kapalı
bool echoOff();
// echo açıkı
bool echoOn();
// modül üreticisi
String moduleManufacturer();
// modül modeli
String moduleModel();
// modül revizyon
String moduleRevision();
// modül imei
String moduleIMEI();
// modül imei değiştirme
bool moduleIMEIChange(const char* imeino);
// modül sim no
String moduleIMSI();
// modül sim operatör no
String moduleICCID();
// zil volümü
uint8_t ringerVolume();
// zil seviyesini ayarlar
bool setRingerVolume(uint8_t level);
// speaker düzeyi
uint8_t speakerVolume();
// speaker düzeyini ayarla
bool setSpeakerVolume(uint8_t level);
// debug modu - verbose mode
String moduleDebug();
// Arama Fonksiyonları
// arama yapar
bool call(const char* phone_number);
// arama cevaplar
bool callAnswer();
// aramayı sonlandırır
bool callHangoff();
// arama durumu
uint8_t callStatus();
// COLP u aktif veya pasif yapar
bool callSetCOLP(bool active);
// COLP aktif mi?
bool callIsCOLPActive();
// Arayanı söyleme aktif mi değil mi?
bool callActivateListCurrent(bool active);
// şimdi arayanı söyle
String callReadCurrentCall(String serialRaw);
// SMS Fonksiyonları
// sms i text yada pdu moda döndürür
bool smsTextMode(bool textModeON);
// sms gönderir
bool smsSend(const char* number, const char* message);
// okunmamış mesaj listesi
String smsListUnread();
// indexi verilen mesajı oku
String smsRead(uint8_t index);
// indexi verilen mesajı oku
String smsRead(uint8_t index, bool markRead);
// serialden direk mesajı oku -> serialden gelen veri verilmeli
String smsReadFromSerial(String serialRaw);
// serialden gelen sms bilgisinin indexini ver
uint8_t smsIndexFromSerial(String serialRaw);
// mesaj merkezini öğren
String smsReadMessageCenter();
// mesaj merkezini değiştir
bool smsChangeMessageCenter(const char* messageCenter);
// mesajı sil
bool smsDeleteOne(uint8_t index);
// tüm okunmuşları sil
bool smsDeleteAllRead();
// tüm mesajları sil
bool smsDeleteAll();
// DTMF Fonksiyonları
// DTMF yi ayarlar
bool dtmfSet(bool active, uint8_t interval, bool reportTime, bool soundDetect);
// DTMF yi serialden okur!
String dtmfRead(String serialRaw);
// USSD Kodları
// USSD kodu gönderir
bool ussdSend(const char* code);
// Raw datadan cevabı okur!
String ussdRead(String serialRaw);
// Radyo Kodları
bool fmOpen();
bool fmOpen(bool mainChannel);
bool fmOpen(bool mainChannel, int freq);
bool fmIsOpened();
bool fmClose();
uint8_t fmGetFreq();
bool fmSetFreq(int freq);
uint8_t fmGetVolume();
bool fmSetVolume(int volume);
// GPRS Kodları
// Connect to Bearer
bool gprsConnectBearer();
//String gprsConnectBearerT();
bool gprsConnectBearer(String apn);
bool gprsConnectBearer(String apn, String user, String password);
// Check connection
bool gprsIsConnected();
// get ip address
String gprsGetIP();
// close gprs bearer connection
bool gprsCloseConn();
String gprsHTTPGet(String url);
String gprsHTTPGet(String url, bool read);
// NTP Komutları
bool timeSetServer(int timezone);
bool timeSetServer(int timezone, String server);
String timeSyncFromServer();
String timeGetRaw();
void timeGet(int *day, int *month, int *year, int *hour, int *minute, int *second);
// Email Komutları
bool emailSMTPConf(String server, String port, bool useSSL);
bool emailSMTPAuth(String username, String password);
bool emailSMTPAuth(String username, String password, bool requireAuth);
bool emailSMTPGmail(String username, String password);
String emailSMTPWrite(String from, String to, String title, String message);
String emailSMTPWrite(String from, String to, String title, String message, String fromName, String toName);
String emailSMTPSend();
};
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
//==================================================================================
/* What follows was inside "GSMSim_TemplateSerial.cpp" before changing this class into a template.
If you really want to keep it in a .cpp file, this web page mentions a few possibilities:
https://www.codeproject.com/Articles/48575/How-to-define-a-template-class-in-a-h-file-and-imp
*/
/*
GSMSim_TemplateSerial Library
This library written for SIMCOM Sim800L module. Library may worked on any SIMCOM modules
and GSM Shields.
Created 11.05.2017
By Erdem ARSLAN
Modified 30.08.2017
Erdem ARSLAN
Science and Technology Teacher, an Arduino Lover =)
[email protected]
https://www.erdemarslan.com/
http://www.robothane.net/
http://www.eralabs.net/
*/
#include "Arduino.h"
// #include "GSMSim_TemplateSerial.h" the header includes this file
// #include <SoftwareSerial.h>
template <class HWorSW_Serial>
GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t _RESET_PIN) /* : SoftwareSerial(DEFAULT_RX_PIN, DEFAULT_TX_PIN) */
: serialManager(_serialManager), RESET_PIN(_RESET_PIN)
{
/*
RX_PIN = DEFAULT_RX_PIN;
TX_PIN = DEFAULT_TX_PIN;
RESET_PIN = DEFAULT_RST_PIN;
LED_PIN = DEFAULT_LED_PIN;
LED_FLAG = DEFAULT_LED_FLAG;
*/
}
/* ===================================================================
GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t rx, uint8_t tx) /^ : SoftwareSerial(rx, tx) ^/
: serialManager(_serialManager)
{
/^
RX_PIN = rx;
TX_PIN = tx;
RESET_PIN = DEFAULT_RST_PIN;
LED_PIN = DEFAULT_LED_PIN;
LED_FLAG = DEFAULT_LED_FLAG;
^/
}
GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t rx, uint8_t tx, uint8_t rst) /^ : SoftwareSerial(rx, tx) ^/
: serialManager(_serialManager)
{
/^
RX_PIN = rx;
TX_PIN = tx;
RESET_PIN = rst;
LED_PIN = DEFAULT_LED_PIN;
LED_FLAG = DEFAULT_LED_FLAG;
^/
}
GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t rx, uint8_t tx, uint8_t rst, uint8_t led) /^ : SoftwareSerial(rx, tx) ^/
: serialManager(_serialManager)
{
/^
RX_PIN = rx;
TX_PIN = tx;
RESET_PIN = rst;
LED_PIN = led;
LED_FLAG = DEFAULT_LED_FLAG;
^/
}
GSMSim_TemplateSerial<HWorSW_Serial>::GSMSim_TemplateSerial(HWorSW_Serial& _serialManager, uint8_t rx, uint8_t tx, uint8_t rst, uint8_t led, bool ledflag) /^ : SoftwareSerial(rx, tx) ^/
: serialManager(_serialManager)
{
/^
RX_PIN = rx;
TX_PIN = tx;
RESET_PIN = rst;
LED_PIN = led;
LED_FLAG = ledflag;
^/
}
=================================================================== */
// Start GSMSim_TemplateSerial
template <class HWorSW_Serial>
void GSMSim_TemplateSerial<HWorSW_Serial>::start() {
pinMode(RESET_PIN, OUTPUT);
digitalWrite(RESET_PIN, HIGH);
_baud = DEFAULT_BAUD_RATE;
serialManager.begin(_baud);
/*
if (LED_FLAG) {
pinMode(LED_PIN, OUTPUT);
}
*/
_buffer.reserve(BUFFER_RESERVE_MEMORY);
}
template <class HWorSW_Serial>
void GSMSim_TemplateSerial<HWorSW_Serial>::start(uint32_t baud) {
pinMode(RESET_PIN, OUTPUT);
digitalWrite(RESET_PIN, HIGH);
_baud = baud;
serialManager.begin(_baud);
/*
if (LED_FLAG) {
pinMode(LED_PIN, OUTPUT);
}
*/
_buffer.reserve(BUFFER_RESERVE_MEMORY);
}
// Reset GMS Module
template <class HWorSW_Serial>
void GSMSim_TemplateSerial<HWorSW_Serial>::reset() {
/*
if (LED_FLAG) {
digitalWrite(LED_PIN, HIGH);
}
*/
digitalWrite(RESET_PIN, LOW);
delay(1000);
digitalWrite(RESET_PIN, HIGH);
delay(1000);
// Modul kendine geldi mi onu bekle
serialManager.print(F("AT\r"));
while (_readSerial().indexOf("OK") == -1) {
serialManager.print(F("AT\r"));
}
/*
if (LED_FLAG) {
digitalWrite(LED_PIN, LOW);
}
*/
}
// SET PHONE FUNC
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::setPhoneFunc(uint8_t level = 1) {
if(level != 0 || level != 1 || level != 4) {
return false;
}
else {
serialManager.print(F("AT+CFUN="));
serialManager.print(String(level));
serialManager.print(F("\r"));
_buffer = _readSerial();
if( (_buffer.indexOf("OK") ) != -1) {
return true;
}
else {
return false;
}
}
}
// SIGNAL QUALTY - 0-31 | 0-> poor | 31 - Full | 99 -> Unknown
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::signalQuality() {
serialManager.print(F("AT+CSQ\r"));
_buffer = _readSerial();
if((_buffer.indexOf("+CSQ:")) != -1) {
return _buffer.substring(_buffer.indexOf("+CSQ: ")+6, _buffer.indexOf(",")).toInt();
} else {
return 99;
}
}
// IS Module connected to the operator?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::isRegistered() {
serialManager.print(F("AT+CREG?\r"));
_buffer = _readSerial();
if( (_buffer.indexOf("+CREG: 0,1")) != -1 || (_buffer.indexOf("+CREG: 0,5")) != -1 || (_buffer.indexOf("+CREG: 1,1")) != -1 || (_buffer.indexOf("+CREG: 1,5")) != -1) {
return true;
} else {
return false;
}
}
// IS SIM Inserted?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::isSimInserted() {
serialManager.print(F("AT+CSMINS?\r"));
_buffer = _readSerial();
if(_buffer.indexOf(",") != -1) {
// bölelim
String veri = _buffer.substring(_buffer.indexOf(","), _buffer.indexOf("OK"));
veri.trim();
if(veri == "1") {
return true;
} else {
return false;
}
} else {
return false;
}
}
// Pin statüsü - AT+CPIN?
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::pinStatus() {
serialManager.print(F("AT+CPIN?\r"));
_buffer = _readSerial();
if(_buffer.indexOf("READY") != -1)
{
return 0;
}
else if(_buffer.indexOf("SIM PIN") != -1)
{
return 1;
}
else if(_buffer.indexOf("SIM PUK") != -1)
{
return 2;
}
else if(_buffer.indexOf("PH_SIM PIN") != -1)
{
return 3;
}
else if(_buffer.indexOf("PH_SIM PUK") != -1)
{
return 4;
}
else if(_buffer.indexOf("SIM PIN2") != -1)
{
return 5;
}
else if(_buffer.indexOf("SIM PUK2") != -1)
{
return 6;
}
else {
return 7;
}
}
// OPERATOR NAME
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::operatorName() {
serialManager.print(F("AT+COPS?\r"));
_buffer = _readSerial();
if(_buffer.indexOf(",") == -1) {
return "NOT CONNECTED";
}
else {
return _buffer.substring(_buffer.indexOf(",\"")+2, _buffer.lastIndexOf("\""));
}
}
// OPERATOR NAME FROM SIM
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::operatorNameFromSim() {
serialManager.flush();
serialManager.print(F("AT+CSPN?\r"));
_buffer = _readSerial();
delay(250);
_buffer = _readSerial();
/*
return _buffer;
*/
if(_buffer.indexOf("OK") != -1) {
return _buffer.substring(_buffer.indexOf(" \"") + 2, _buffer.lastIndexOf("\""));
}
else {
return "NOT CONNECTED";
}
}
// PHONE STATUS
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::phoneStatus() {
serialManager.print(F("AT+CPAS\r"));
_buffer = _readSerial();
if((_buffer.indexOf("+CPAS: ")) != -1)
{
return _buffer.substring(_buffer.indexOf("+CPAS: ")+7,_buffer.indexOf("+CPAS: ")+9).toInt();
}
else {
return 99; // not read from module
}
}
// ECHO OFF
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::echoOff() {
serialManager.print(F("ATE0\r"));
_buffer = _readSerial();
if ( (_buffer.indexOf("OK") )!=-1 ) {
return true;
}
else {
return false;
}
}
// ECHO ON
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::echoOn() {
serialManager.print(F("ATE1\r"));
_buffer = _readSerial();
if ( (_buffer.indexOf("OK") )!=-1 ) {
return true;
}
else {
return false;
}
}
// Modül Üreticisi
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleManufacturer() {
serialManager.print(F("AT+CGMI\r"));
_buffer = _readSerial();
String veri = _buffer.substring(8, _buffer.indexOf("OK"));
veri.trim();
veri.replace("_", " ");
return veri;
}
// Modül Modeli
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleModel() {
serialManager.print(F("AT+CGMM\r"));
_buffer = _readSerial();
String veri = _buffer.substring(8, _buffer.indexOf("OK"));
veri.trim();
veri.replace("_", " ");
return veri;
}
// Modül Revizyonu
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleRevision() {
serialManager.print(F("AT+CGMR\r"));
_buffer = _readSerial();
String veri = _buffer.substring(_buffer.indexOf(":")+1 , _buffer.indexOf("OK"));
veri.trim();
return veri;
}
// Modülün IMEI numarası
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleIMEI() {
serialManager.print(F("AT+CGSN\r"));
_buffer = _readSerial();
String veri = _buffer.substring(8, _buffer.indexOf("OK"));
veri.trim();
return veri;
}
// Modülün IMEI Numarasını değiştirir.
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::moduleIMEIChange(const char* imeino) {
return true;
}
// Modülün SIM Numarası
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleIMSI() {
serialManager.print(F("AT+CIMI\r"));
_buffer = _readSerial();
String veri = _buffer.substring(8, _buffer.indexOf("OK"));
veri.trim();
return veri;
}
// Sim Kart Seri Numarası
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleICCID() {
serialManager.print(F("AT+CCID\r"));
_buffer = _readSerial();
String veri = _buffer.substring(8, _buffer.indexOf("OK"));
veri.trim();
return veri;
}
// Çalma Sesi
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::ringerVolume() {
serialManager.print(F("AT+CRSL?\r"));
_buffer = _readSerial();
String veri = _buffer.substring(7, _buffer.indexOf("OK"));
veri.trim();
return veri.toInt();
}
// Çalma sesini ayarla
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::setRingerVolume(uint8_t level) {
if(level > 100) {
level = 100;
}
serialManager.print(F("AT+CRSL="));
serialManager.print(level);
serialManager.print(F("\r"));
_buffer = _readSerial();
if(_buffer.indexOf("OK") != -1) {
return true;
} else {
return false;
}
}
// Hoparlör sesi
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::speakerVolume() {
serialManager.print(F("AT+CLVL?\r"));
_buffer = _readSerial();
String veri = _buffer.substring(7, _buffer.indexOf("OK"));
veri.trim();
return veri.toInt();
}
// Hoparlör sesini ayarla
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::setSpeakerVolume(uint8_t level) {
if(level > 100) {
level = 100;
}
serialManager.print(F("AT+CLVL="));
serialManager.print(level);
serialManager.print(F("\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::moduleDebug() {
serialManager.print(F("AT&V\r"));
return _readSerial();
}
//////////////////////////////////////
// CALL SECTION //
//////////////////////////////////////
// Arama Yapar
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::call(const char* phone_number) {
bool sorgulamaYapma = callIsCOLPActive();
_buffer = _readSerial();
delay(100);
serialManager.print(F("ATD+ ")); /* ATDnumber; => NO DIALTONE, ATD+ works, for instance ATD+ +541198765432; seen here https://lastminuteengineers.com/sim800l-gsm-module-arduino-tutorial/ NOTICE that it is not mentioned in SIM800_Series_AT_Command_Manual_V1.09.pdf */
serialManager.print(phone_number);
serialManager.print(";\r");
if (sorgulamaYapma) {
return true;
}
else {
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1)
{
return true;
}
else {
return false;
}
}
}
// Gelen aramayı cevaplar
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callAnswer() {
serialManager.print(F("ATA\r"));
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
/*
if (_buffer.indexOf("OK") != -1)
{
return true;
}
else {
return false;
}
*/
}
// Aramayı reddeder veya görüşmeyi sonlandırır!
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callHangoff() {
serialManager.print(F("ATH\r"));
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
/*
if (_buffer.indexOf("OK") != -1)
{
return true;
} else {
return false;
}
*/
}
// Arama durumunu belirtir
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::callStatus() {
/*
values of return:
0 Ready (MT allows commands from TA/TE)
2 Unknown (MT is not guaranteed to respond to tructions)
3 Ringing (MT is ready for commands from TA/TE, but the ringer is active)
4 Call in progress
*/
serialManager.print(F("AT+CPAS\r"));
_buffer = _readSerial();
return _buffer.substring(_buffer.indexOf("+CPAS: ") + 7, _buffer.indexOf("+CPAS: ") + 9).toInt();
}
// Connected Line Identification aktif veya kapalı
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callSetCOLP(bool active) {
int durum = active == true ? 1 : 0;
serialManager.print(F("AT+COLP="));
serialManager.print(durum);
serialManager.print("\r");
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
// COLP Aktif mi değil mi?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callIsCOLPActive() {
serialManager.print("AT+COLP?\r");
_buffer = _readSerial();
return (_buffer.indexOf("+COLP: 1") != -1);
}
// Arayanı söyleme aktif mi değil mi?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::callActivateListCurrent(bool active) {
int durum = active == true ? 1 : 0;
serialManager.print(F("AT+CLCC="));
serialManager.print(durum);
serialManager.print("\r");
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
// şimdi arayanı söyle
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::callReadCurrentCall(String serialRaw) {
String sonuc = "";
if (serialRaw.indexOf("+CLCC:") != -1) {
String durum = serialRaw.substring(11,13);
String numara = serialRaw.substring(18, serialRaw.indexOf("\","));
if (durum == "0") {
durum = "STATUS:ACTIVE"; // Görüşme var
}
else if (durum == "1") {
durum = "STATUS:HELD";
}
else if (durum == "2") {
durum = "STATUS:DIALING"; // Çevriliyor
}
else if (durum == "3") {
durum = "STATUS:ALERTING"; // Çalıyor
}
else if (durum == "4") {
durum = "STATUS:INCOMING"; // Gelen arama
}
else if (durum == "5") {
durum = "STATUS:WAITING"; // gelen arama bekliyor
}
else if (durum == "6") {
durum = "STATUS:DISCONNECT"; // görüşme bitti
}
sonuc = durum + "|NUMBER:" + numara;
}
return sonuc;
}
//////////////////////////////////////
// MESAJ BÖLÜMÜ //
//////////////////////////////////////
// SMS i TEXT ya da PDU moduna alır.
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsTextMode(bool textModeON) {
if (textModeON == true) {
serialManager.print(F("AT+CMGF=1\r"));
}
else {
serialManager.print(F("AT+CMGF=0\r"));
}
bool sonuc = false;
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
sonuc = true;
}
return sonuc;
}
// verilen numara ve mesajı gönderir!
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsSend(const char* number, const char* message) {
serialManager.print(F("AT+CMGS=\"")); // command to send sms
serialManager.print(number);
serialManager.print(F("\"\r"));
_buffer = _readSerial();
serialManager.print(message);
serialManager.print("\r");
//change delay 100 to readserial
_buffer += _readSerial();
serialManager.print((char)26);
_buffer += _readSerial();
//expect CMGS:xxx , where xxx is a number,for the sending sms.
/*
return _buffer;
*/
if (((_buffer.indexOf("AT+CMGS")) != -1)) {
return true;
}
else {
return false;
}
}
// Belirtilen klasördeki smslerin indexlerini listeler!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsListUnread() {
serialManager.print(F("AT+CMGL=\"REC UNREAD\",1\r"));
_buffer = _readSerial();
String donus = "";
if (_buffer.indexOf("ERROR") != -1) {
donus = "ERROR";
}
if (_buffer.indexOf("+CMGL:") != -1) {
String veri = _buffer;
bool islem = false;
donus = "";
while (!islem) {
if (veri.indexOf("+CMGL:") == -1) {
islem = true;
continue;
}
veri = veri.substring(veri.indexOf("+CMGL: ") + 7);
String metin = veri.substring(0, veri.indexOf(","));
metin.trim();
if (donus == "") {
donus += "SMSIndexNo:";
donus += metin;
}
else {
donus += ",";
donus += metin;
}
}
}
else {
if (donus != "ERROR") {
donus = "NO_SMS";
}
}
return donus;
}
// Indexi verilen mesajı okur. Anlaşılır hale getirir!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsRead(uint8_t index) {
serialManager.print("AT+CMGR=");
serialManager.print(index);
serialManager.print(",0\r");
_buffer = _readSerial();
String durum = "INDEX_NO_ERROR";
if (_buffer.indexOf("+CMGR:") != -1) {
String klasor, okundumu, telno, zaman, mesaj;
klasor = "UNKNOWN";
okundumu = "UNKNOWN";
if (_buffer.indexOf("REC UNREAD") != -1) {
klasor = "INCOMING";
okundumu = "UNREAD";
}
if (_buffer.indexOf("REC READ") != -1) {
klasor = "INCOMING";
okundumu = "READ";
}
if (_buffer.indexOf("STO UNSENT") != -1) {
klasor = "OUTGOING";
okundumu = "UNSENT";
}
if (_buffer.indexOf("STO SENT") != -1) {
klasor = "OUTGOING";
okundumu = "SENT";
}
String telno_bol1 = _buffer.substring(_buffer.indexOf("\",\"") + 3);
telno = telno_bol1.substring(0, telno_bol1.indexOf("\",\"")); // telefon numarası tamam
String tarih_bol = telno_bol1.substring(telno_bol1.lastIndexOf("\",\"") + 3);
zaman = tarih_bol.substring(0, tarih_bol.indexOf("\"")); // zamanı da aldık. Bir tek mesaj kaldı!
mesaj = tarih_bol.substring(tarih_bol.indexOf("\"") + 1, tarih_bol.lastIndexOf("OK"));
mesaj.trim();
durum = "FOLDER:";
durum += klasor;
durum += "|STATUS:";
durum += okundumu;
durum += "|PHONENO:";
durum += telno;
durum += "|DATETIME:";
durum += zaman;
durum += "|MESSAGE:";
durum += mesaj;
}
return durum;
}
// Indexi verilen mesajı okur. Anlaşılır hale getirir!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsRead(uint8_t index, bool markRead) {
serialManager.print("AT+CMGR=");
serialManager.print(index);
serialManager.print(",");
if (markRead == true) {
serialManager.print("0");
}
else {
serialManager.print("1");
}
serialManager.print("\r");
_buffer = _readSerial();
String durum = "INDEX_NO_ERROR";
if (_buffer.indexOf("+CMGR:") != -1) {
String klasor, okundumu, telno, zaman, mesaj;
klasor = "UNKNOWN";
okundumu = "UNKNOWN";
if (_buffer.indexOf("REC UNREAD") != -1) {
klasor = "INCOMING";
okundumu = "UNREAD";
}
if (_buffer.indexOf("REC READ") != -1) {
klasor = "INCOMING";
okundumu = "READ";
}
if (_buffer.indexOf("STO UNSENT") != -1) {
klasor = "OUTGOING";
okundumu = "UNSENT";
}
if (_buffer.indexOf("STO SENT") != -1) {
klasor = "OUTGOING";
okundumu = "SENT";
}
String telno_bol1 = _buffer.substring(_buffer.indexOf("\",\"") + 3);
telno = telno_bol1.substring(0, telno_bol1.indexOf("\",\"")); // telefon numarası tamam
String tarih_bol = telno_bol1.substring(telno_bol1.lastIndexOf("\",\"") + 3);
zaman = tarih_bol.substring(0, tarih_bol.indexOf("\"")); // zamanı da aldık. Bir tek mesaj kaldı!
mesaj = tarih_bol.substring(tarih_bol.indexOf("\"")+1, tarih_bol.lastIndexOf("OK"));
mesaj.trim();
durum = "FOLDER:";
durum += klasor;
durum += "|STATUS:";
durum += okundumu;
durum += "|PHONENO:";
durum += telno;
durum += "|DATETIME:";
durum += zaman;
durum += "|MESSAGE:";
durum += mesaj;
}
return durum;
}
// Serialden Mesajı okur
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsReadFromSerial(String serialRaw) {
if (serialRaw.indexOf("+CMTI:") != -1) {
String numara = serialRaw.substring(serialRaw.indexOf("\",") + 2);
int no = numara.toInt();
return smsRead(no, true);
}
else {
return "RAW_DATA_NOT_READ";
}
}
// serialden mesajın indexini alır
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::smsIndexFromSerial(String serialRaw) {
if (serialRaw.indexOf("+CMTI:") != -1) {
String numara = serialRaw.substring(serialRaw.indexOf("\",") + 2);
int no = numara.toInt();
return no;
}
else {
return -1;
}
}
// mesaj merkez numasını getirir
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::smsReadMessageCenter() {
serialManager.print("AT+CSCA?\r");
_buffer = _readSerial();
String sonuc = "";
if (_buffer.indexOf("+CSCA:") != -1)
{
sonuc = _buffer.substring(_buffer.indexOf("+CSCA:")+8, _buffer.indexOf("\","));
}
return sonuc;
}
// mesaj merkez numarasını değiştirir
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsChangeMessageCenter(const char* messageCenter) {
serialManager.print("AT+CSCA=\"");
serialManager.print(messageCenter);
serialManager.print("\"\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
// tek bir mesajı siler
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsDeleteOne(uint8_t index) {
serialManager.print(F("AT+CMGD="));
serialManager.print(index);
serialManager.print(F(",0\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
// Tüm okunmuş mesajlaarı siler. Fakat gidene dokunmaz
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsDeleteAllRead() {
serialManager.print(F("AT+CMGD=1,1\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
// okunmuş okunmamış ne varsa siler
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::smsDeleteAll() {
serialManager.print(F("AT+CMGD=1,4\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
//////////////////////////////////////
// DTMF BÖLÜMÜ //
//////////////////////////////////////
// DTMF yi ayarlar
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::dtmfSet(bool active, uint8_t interval, bool reportTime, bool soundDetect) {
int mode = active == true ? 1 : 0;
int rtime = reportTime == true ? 1 : 0;
int ssdet = soundDetect == true ? 1 : 0;
serialManager.print(F("AT+DDET="));
serialManager.print(mode);
serialManager.print(F(","));
serialManager.print(interval);
serialManager.print(F(","));
serialManager.print(rtime);
serialManager.print(F(","));
serialManager.print(ssdet);
serialManager.print(F("\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
// Serialden DTMF Yi okur ve karakter olarak geri döner!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::dtmfRead(String serialRaw) {
if (serialRaw.indexOf("+DTMF:") != -1) {
// var mı yok mu?
String metin;
if (serialRaw.indexOf(",") != -1) {
metin = serialRaw.substring(7, serialRaw.indexOf(","));
}
else {
metin = serialRaw.substring(7);
}
return metin;
}
else {
return "?";
}
}
//////////////////////////////////////
// USSD SECTION //
//////////////////////////////////////
// USSD kodu gönderir
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::ussdSend(const char* code) {
serialManager.print(F("AT+CUSD=1,\""));
serialManager.print(code);
serialManager.print(F("\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
// Raw datadan cevabı okur!
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::ussdRead(String serialRaw) {
if (serialRaw.indexOf("+CUSD:") != -1) {
String metin = serialRaw.substring(serialRaw.indexOf(",\"") + 2, serialRaw.indexOf("\","));
return metin;
}
else {
return "NOT_USSD_RAW";
}
}
//////////////////////////////////////
// FM RADIO SECTION //
//////////////////////////////////////
// SIM800L & SIM800H only
// FM RADIO Open
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmOpen() {
serialManager.print(F("AT+FMOPEN=0\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmOpen(bool mainChannel) {
uint8_t channel = mainChannel == true ? 1 : 0;
serialManager.print(F("AT+FMOPEN="));
serialManager.print(channel);
serialManager.print(F("\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmOpen(bool mainChannel, int freq) {
uint8_t channel = mainChannel == true ? 1 : 0;
int frekans = 875;
if (freq < 875) {
frekans = 875;
}
else if (freq > 1080) {
frekans = 1080;
}
serialManager.print(F("AT+FMOPEN="));
serialManager.print(channel);
serialManager.print(",");
serialManager.print(frekans);
serialManager.print(F("\r"));
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
// IS FM OPENED?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmIsOpened() {
serialManager.print(F("AT+FMOPEN?\r"));
_buffer = _readSerial();
return (_buffer.indexOf("+FMOPEN: 1") != -1);
}
// FM RADIO CLOSE
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmClose() {
serialManager.print(F("AT+FMCLOSE\r"));
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
// GET FM RADIO FREQ
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::fmGetFreq() {
serialManager.print(F("AT+FMFREQ?\r"));
_buffer = _readSerial();
if (_buffer.indexOf("+FMFREQ:") != -1) {
String sonuc = _buffer.substring(_buffer.indexOf("+FMFREQ:")+8);
sonuc.trim();
return sonuc.toInt();
}
else {
return 0;
}
}
// SET FM RADIO FREQ
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmSetFreq(int freq) {
serialManager.print(F("AT+FMFREQ="));
int frekans = 875;
if (freq < 875) {
frekans = 875;
}
if (freq > 1080) {
frekans = 1080;
}
serialManager.print(frekans);
serialManager.print(F("\r"));
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
// GET FM RADIO FREQ
template <class HWorSW_Serial>
uint8_t GSMSim_TemplateSerial<HWorSW_Serial>::fmGetVolume() {
serialManager.print(F("AT+FMVOLUME?\r"));
_buffer = _readSerial();
if (_buffer.indexOf("+FMVOLUME:") != -1) {
String sonuc = _buffer.substring(_buffer.indexOf("+FMVOLUME:")+10);
sonuc.trim();
return sonuc.toInt();
}
else {
return 0;
}
}
// SET FM RADIO FREQ
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::fmSetVolume(int volume) {
serialManager.print(F("AT+FMVOLUME="));
uint8_t vol = 0;
if (volume < 0) {
vol = 0;
}
if (volume > 6) {
vol = 6;
}
serialManager.print(vol);
serialManager.print(F("\r"));
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
//////////////////////////////////////
// GPRS METHODS //
//////////////////////////////////////
// Connect to GPRS Bearer
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsConnectBearer() {
serialManager.print(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print(F("AT+SAPBR=3,1,\"APN\",\"internet\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print(F("AT+SAPBR=3,1,\"USER\",\"\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print(F("AT+SAPBR=3,1,\"PWD\",\"\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print("AT+SAPBR=1,1\r");
_buffer = _readSerial();
delay(50);
_buffer += _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print("AT+SAPBR=2,1\r");
_buffer = _readSerial();
if (_buffer.indexOf("\"0.0.0.0\"") != -1 || _buffer.indexOf("ERR") != -1) {
return false;
}
else {
return true;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsConnectBearer(String apn) {
serialManager.print(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print(F("AT+SAPBR=3,1,\"APN\",\""));
serialManager.print(apn);
serialManager.print(F("\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print(F("AT+SAPBR=3,1,\"USER\",\"\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print(F("AT+SAPBR=3,1,\"PWD\",\"\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print("AT+SAPBR=1,1\r");
_buffer = _readSerial();
delay(50);
_buffer += _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print("AT+SAPBR=2,1\r");
_buffer = _readSerial();
if (_buffer.indexOf("\"0.0.0.0\"") != -1 || _buffer.indexOf("ERR") != -1) {
return false;
}
else {
return true;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsConnectBearer(String apn, String user, String password) {
serialManager.print(F("AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print(F("AT+SAPBR=3,1,\"APN\",\""));
serialManager.print(apn);
serialManager.print(F("\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print(F("AT+SAPBR=3,1,\"USER\",\""));
serialManager.print(user);
serialManager.print(F("\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print(F("AT+SAPBR=3,1,\"PWD\",\""));
serialManager.print(password);
serialManager.print(F("\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
serialManager.print("AT+SAPBR=1,1\r");
_buffer = _readSerial();
delay(50);
_buffer += _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print("AT+SAPBR=2,1\r");
_buffer = _readSerial();
if (_buffer.indexOf("\"0.0.0.0\"") != -1 || _buffer.indexOf("ERR") != -1) {
return false;
}
else {
return true;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
// Check is GPRS connected?
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsIsConnected() {
serialManager.print(F("AT+SAPBR=2,1\r"));
_buffer = _readSerial();
delay(50);
_buffer += _readSerial();
if (_buffer.indexOf("ERR") != -1 || _buffer.indexOf("\"0.0.0.0\"") != -1) {
return false;
}
else {
return true;
}
}
// GET IP Address
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::gprsGetIP() {
serialManager.print(F("AT+SAPBR=2,1\r\n"));
_buffer = _readSerial();
delay(50);
_buffer += _readSerial();
//return _buffer;
if (_buffer.indexOf("ERR") != -1 || _buffer.indexOf("\"0.0.0.0\"") != -1) {
return "ERROR:NO_IP";
}
else {
if (_buffer.indexOf("+SAPBR:") != -1) {
String veri = _buffer.substring(_buffer.indexOf(",\"")+2, _buffer.lastIndexOf("\""));
veri.trim();
return veri;
}
else {
return "ERROR:NO_IP_FETCH";
}
}
}
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::gprsCloseConn() {
serialManager.print(F("AT+SAPBR=0,1\r"));
_buffer = _readSerial();
delay(50);
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::gprsHTTPGet(String url) {
if (gprsIsConnected()) {
// Terminate http connection, if it opened before!
serialManager.print(F("AT+HTTPTERM\r"));
_buffer = _readSerial();
serialManager.print(F("AT+HTTPINIT\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+HTTPPARA=\"CID\",1\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+HTTPPARA=\"URL\",\""));
serialManager.print(url);
serialManager.print("\"\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+HTTPACTION=0\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
_buffer = _readSerial(10000);
if (_buffer.indexOf("+HTTPACTION: 0,") != -1) {
String kod = _buffer.substring(_buffer.indexOf(",")+1, _buffer.lastIndexOf(","));
String uzunluk = _buffer.substring(_buffer.lastIndexOf(",")+1);
String sonuc = "METHOD:GET|HTTPCODE:";
sonuc += kod;
sonuc += "|LENGTH:";
sonuc += uzunluk;
// Bağlantıyı kapat!
serialManager.print(F("AT+HTTPTERM\r"));
_buffer = _readSerial();
sonuc.trim();
return sonuc;
}
else {
return "HTTP_ACTION_READ_ERROR";
}
}
else {
return "HTTP_ACTION_ERROR";
}
}
else {
return "HTTP_PARAMETER_ERROR";
}
}
else {
return "HTTP_PARAMETER_ERROR";
}
}
else {
return "HTTP_INIT_ERROR";
}
}
else {
return "GPRS_NOT_CONNECTED";
}
}
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::gprsHTTPGet(String url, bool read) {
if (gprsIsConnected()) {
// Terminate http connection, if it opened before!
serialManager.print(F("AT+HTTPTERM\r"));
_buffer = _readSerial();
serialManager.print(F("AT+HTTPINIT\r\n"));
_buffer = _readSerial();
//return _buffer;
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+HTTPPARA=\"CID\",1\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+HTTPPARA=\"URL\",\""));
serialManager.print(url);
serialManager.print(F("\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+HTTPACTION=0\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(100);
_buffer = _readSerial(10000);
if (_buffer.indexOf("+HTTPACTION: 0,") != -1) {
String kod = _buffer.substring(_buffer.indexOf(",") + 1, _buffer.lastIndexOf(","));
String uzunluk = _buffer.substring(_buffer.lastIndexOf(",") + 1);
kod.trim();
uzunluk.trim();
serialManager.print(F("AT+HTTPREAD\r"));
_buffer = _readSerial(10000);
String okuma = "";
if (_buffer.indexOf("+HTTPREAD:") != -1) {
String kriter = "+HTTPREAD: " + uzunluk;
String veri = _buffer.substring(_buffer.indexOf(kriter) + kriter.length(), _buffer.lastIndexOf("OK"));
okuma = veri;
}
else {
return "ERROR:HTTP_READ_ERROR";
}
String sonuc = "METHOD:GET|HTTPCODE:";
sonuc += kod;
sonuc += "|LENGTH:";
sonuc += uzunluk;
sonuc += "|DATA:";
okuma.trim();
sonuc += okuma;
serialManager.print(F("AT+HTTPTERM\r"));
_buffer = _readSerial();
sonuc.trim();
return sonuc;
}
else {
return "ERROR:HTTP_ACTION_READ_ERROR";
}
}
else {
return "ERROR:HTTP_ACTION_ERROR";
}
}
else {
return "ERROR:HTTP_PARAMETER_ERROR";
}
}
else {
return "ERROR:HTTP_PARAMETER_ERROR";
}
}
else {
return "ERROR:HTTP_INIT_ERROR";
}
}
else {
return "ERROR:GPRS_NOT_CONNECTED";
}
}
//////////////////////////////////////
// TIME METHODS //
//////////////////////////////////////
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::timeSetServer(int timezone) {
serialManager.print("AT+CNTPCID=1\r");
_buffer = _readSerial();
int zaman = 0;
if (timezone <= -12) {
zaman = -47;
}
if (timezone > 12) {
zaman = 48;
}
if (timezone > -12 || timezone <= 12) {
zaman = timezone * 4;
}
serialManager.print(F("AT+CNTP=\"202.120.2.101\","));
serialManager.print(zaman);
serialManager.print(F("\r"));
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::timeSetServer(int timezone, String server) {
serialManager.print("AT+CNTPCID=1\r");
_buffer = _readSerial();
int zaman = 0;
if (timezone <= -12) {
zaman = -47;
}
if (timezone > 12) {
zaman = 48;
}
if (timezone > -12 || timezone <= 12) {
zaman = timezone * 4;
}
serialManager.print(F("AT+CNTP=\""));
serialManager.print(server);
serialManager.print(F("\","));
serialManager.print(zaman);
serialManager.print(F("\r"));
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::timeSyncFromServer() {
serialManager.print(F("AT+CNTP\r"));
_buffer = _readSerial();
//delay(50);
_buffer = _readSerial(20000);
if (_buffer.indexOf("+CNTP:") != -1) {
String kod = _buffer.substring(8);
kod.trim();
if (kod == "1") {
return "TIME_SYNCHRONIZED_SUCCESS";
}
else if (kod == "61") {
return "NETWORK_ERROR";
}
else if (kod == "62") {
return "DNS_ERROR";
}
else if (kod == "63") {
return "CONNECTION_ERROR";
}
else if (kod == "64") {
return "SERVICE_RESPONSE_ERROR";
}
else if (kod == "65") {
return "SERVICE_RESPONSE_TIMEOUT";
}
else {
return "UNKNOWN_ERROR_" + kod;
}
}
else {
return "AT_COMMAND_ERROR";
//return _buffer;
}
}
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::timeGetRaw() {
serialManager.print("AT+CCLK?\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
String zaman = _buffer.substring(_buffer.indexOf("\"") + 1, _buffer.lastIndexOf("\""));
return zaman;
}
else {
return "ERROR:NOT_GET_DATETIME";
}
}
template <class HWorSW_Serial>
void GSMSim_TemplateSerial<HWorSW_Serial>::timeGet(int *day, int *month, int *year, int *hour, int *minute, int *second) {
serialManager.print("AT+CCLK?\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
_buffer = _buffer.substring(_buffer.indexOf("\"") + 1, _buffer.lastIndexOf("\"") - 1);
*year = (_buffer.substring(0, 2).toInt()) + 2000;
*month = _buffer.substring(3, 5).toInt();
*day = _buffer.substring(6, 8).toInt();
*hour = _buffer.substring(9, 11).toInt();
*minute = _buffer.substring(12, 14).toInt();
*second = _buffer.substring(15, 17).toInt();
}
}
//////////////////////////////////////
// EMAIL METHODS //
//////////////////////////////////////
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPConf(String server, String port, bool useSSL) {
int ssl = useSSL == true ? 1 : 0;
serialManager.print(F("AT+EMAILSSL="));
serialManager.print(ssl);
serialManager.print(F("\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+EMAILCID=1\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+EMAILTO=30\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+SMTPSRV=\""));
serialManager.print(server);
serialManager.print(F("\",\""));
serialManager.print(port);
serialManager.print("\"\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
else {
return false;
}
}
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPAuth(String username, String password) {
serialManager.print(F("AT+SMTPAUTH=1,\""));
serialManager.print(username);
serialManager.print(F("\",\""));
serialManager.print(password);
serialManager.print(F("\"\r"));
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
return true;
}
else {
return false;
}
}
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPAuth(String username, String password, bool requireAuth) {
int auth = requireAuth == true ? 1 : 0;
serialManager.print(F("AT+SMTPAUTH="));
serialManager.print(auth);
serialManager.print(F(",\""));
serialManager.print(username);
serialManager.print(F("\",\""));
serialManager.print(password);
serialManager.print(F("\"\r"));
_buffer = _readSerial();
return (_buffer.indexOf("OK") != -1);
}
template <class HWorSW_Serial>
bool GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPGmail(String username, String password) {
bool conf = emailSMTPConf("smtp.gmail.com", "465", true);
if (conf) {
return emailSMTPAuth(username, password);
}
else {
return false;
}
}
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPWrite(String from, String to, String title, String message) {
serialManager.print(F("AT+SMTPFROM=\""));
serialManager.print(from);
serialManager.print("\"\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print("AT+SMTPRCPT=0\r");
_buffer = _readSerial();
delay(50);
serialManager.print(F("AT+SMTPRCPT=0,1,\""));
serialManager.print(to);
serialManager.print("\"\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+SMTPSUB=\""));
serialManager.print(title);
serialManager.print("\"\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
uint8_t uzunluk = message.length();
serialManager.print(F("AT+SMTPBODY="));
serialManager.print(uzunluk);
serialManager.print("\r");
delay(50);
serialManager.print(message);
serialManager.print(F("\""));
_buffer += _readSerial();
if (_buffer.indexOf("OK") != -1) {
return "OK";
}
else {
return "ERROR:BODY_NOT_SET";
}
}
else {
return "ERROR:TITLE_NOT_SET";
}
}
else {
return "ERROR:TO_NOT_SET";
}
}
else {
return "ERROR:FROM_NOT_SET";
}
}
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPWrite(String from, String to, String title, String message, String fromName, String toName) {
serialManager.print(F("AT+SMTPFROM=\""));
serialManager.print(from);
serialManager.print("\",\"");
serialManager.print(fromName);
serialManager.print("\"\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print("AT+SMTPRCPT=0\r");
_buffer = _readSerial();
delay(50);
serialManager.print(F("AT+SMTPRCPT=0,1,\""));
serialManager.print(to);
serialManager.print("\",\"");
serialManager.print(toName);
serialManager.print("\"\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
serialManager.print(F("AT+SMTPSUB=\""));
serialManager.print(title);
serialManager.print("\"\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
uint8_t uzunluk = message.length();
serialManager.print(F("AT+SMTPBODY="));
serialManager.print(uzunluk);
serialManager.print("\r");
delay(50);
serialManager.print(message);
serialManager.print(F("\""));
_buffer += _readSerial();
if (_buffer.indexOf("OK") != -1) {
return "OK";
}
else {
return "ERROR:BODY_NOT_SET";
}
}
else {
return "ERROR:TITLE_NOT_SET";
}
}
else {
return "ERROR:TO_NOT_SET";
}
}
else {
return "ERROR:FROM_NOT_SET";
}
}
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::emailSMTPSend() {
serialManager.print("AT+SMTPSEND\r");
_buffer = _readSerial();
if (_buffer.indexOf("OK") != -1) {
delay(50);
_buffer = _readSerial(30000);
if (_buffer.indexOf("+SMTPSEND:") != -1) {
String kod = _buffer.substring(12);
kod.trim();
if (kod == "1") {
return "SUCCESS:EMAIL_SEND";
}
else if (kod == "61") {
return "ERROR:NETWORK_ERROR";
}
else if (kod == "62") {
return "ERROR:DNS_RESOLVE_ERROR";
}
else if (kod == "63") {
return "ERROR:TCP_CONNECTION_ERROR";
}
else if (kod == "64") {
return "ERROR:TIMEOUT_SMTP_RESPONSE";
}
else if (kod == "65") {
return "ERROR:SMTP_RESPONSE_ERROR";
}
else if (kod == "66") {
return "ERROR:NOT_AUTH";
}
else if (kod == "67") {
return "ERROR:AUTH_FAILED";
}
else if (kod == "68") {
return "ERROR:BAD_RECIPIENT";
}
else {
return "ERROR:ERROR_NO_" + kod;
}
}
else {
delay(50);
_buffer = _readSerial(30000);
if (_buffer.indexOf("+SMTPSEND:") != -1) {
String kod = _buffer.substring(12);
kod.trim();
if (kod == "1") {
return "SUCCESS:EMAIL_SEND";
}
else if (kod == "61") {
return "ERROR:NETWORK_ERROR";
}
else if (kod == "62") {
return "ERROR:DNS_RESOLVE_ERROR";
}
else if (kod == "63") {
return "ERROR:TCP_CONNECTION_ERROR";
}
else if (kod == "64") {
return "ERROR:TIMEOUT_SMTP_RESPONSE";
}
else if (kod == "65") {
return "ERROR:SMTP_RESPONSE_ERROR";
}
else if (kod == "66") {
return "ERROR:NOT_AUTH";
}
else if (kod == "67") {
return "ERROR:AUTH_FAILED";
}
else if (kod == "68") {
return "ERROR:BAD_RECIPIENT";
}
else {
return "ERROR:ERROR_NO_" + kod;
}
}
else {
return "ERROR:EMAIL_TIMEOUT_ERROR";
}
}
}
else {
return "ERROR:EMAIL_SENDING_ERROR";
}
}
//////////////////////////////////////
// PRIVATE METHODS //
//////////////////////////////////////
// READ FROM SERIAL
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::_readSerial() {
uint64_t timeOld = millis();
while (!serialManager.available() && !(millis() > timeOld + TIME_OUT_READ_SERIAL))
{
delay(13);
}
String str = "";
while (serialManager.available())
{
if (serialManager.available())
{
str += (char) serialManager.read();
/* ^^^^^^ might be unnecessary */
}
}
return str;
}
template <class HWorSW_Serial>
String GSMSim_TemplateSerial<HWorSW_Serial>::_readSerial(uint32_t timeout) {
uint64_t timeOld = millis();
while (!serialManager.available() && !(millis() > timeOld + timeout))
{
delay(13);
}
String str = "";
while (serialManager.available())
{
if (serialManager.available())
{
str += (char) serialManager.read();
/* ^^^^^^ might be unnecessary */
}
}
return str;
}
#endif
All the best,
Nicola
How can you use a string variable as sms message?
For example:
#define SMSNUMBER "+3xxxxxxxxxx"
String MESSAGE = ""; // depending on the reason is this filled with different text by the program/sketch/code
void loop() {
sms.send(SMSNUMBER, MESSAGE);
}
Tthis gives the fault message:
In function 'void SMSSend()': [Sketch]:[Line:Char]: error: no matching function for call to
'GSMSimSMS::send(const char [13], String&)' sms.send(SMSNUMBER, MESSAGE);
When i remove the variable as message does the code compile correctly:
sms.send(SMSNUMBER, "Test Message");
This code also doesn't work:
sms.send(SMSNUMBER, "\""MESSAGE"\"");
fault message:
In function 'void SMSSend()': error: unable to find string literal operator 'operator""MESSAGE' with 'const char [3]', 'unsigned int' arguments
sms.send(SMSNUMBER, "\""MESSAGE"\"");```
I am currently trying to add functionality to parts of you library. Doing that, i constantly run into endles if-else chains big enough for the code to go off the right side of my screen...
These almost always are just checking if something succeeded, and if not exiting the function with an error. This can be written more cleanly like this: if (notFoundOK()) return "ERROR";
. If you are just planning to return an error, this has the same effect. As soon as a return is executed, the function exits and code following it will not be executed.
Here is an example:
GSMSimHTTP.cpp get(String) - original
String GSMSimHTTP::get(String url) {
if (isConnected()) {
// Terminate http connection, if it opened before! Otherwise method not run correctly.
gsm.print(F("AT+HTTPTERM\r"));
_readSerial();
gsm.print(F("AT+HTTPINIT\r"));
_readSerial();
if (_buffer.indexOf(F("OK")) != -1) {
gsm.print(F("AT+HTTPPARA=\"CID\",1\r"));
_readSerial();
if (_buffer.indexOf(F("OK")) != -1) {
gsm.print(F("AT+HTTPPARA=\"URL\",\""));
gsm.print(url);
gsm.print("\"\r");
_readSerial();
if (_buffer.indexOf(F("OK")) != -1) {
gsm.print(F("AT+HTTPACTION=0\r"));
_readSerial();
if (_buffer.indexOf(F("OK")) != -1) {
_readSerial(10000);
if (_buffer.indexOf(F("+HTTPACTION: 0,")) != -1) {
String kod = _buffer.substring(_buffer.indexOf(F(","))+1, _buffer.lastIndexOf(F(",")));
String uzunluk = _buffer.substring(_buffer.lastIndexOf(F(","))+1);
String sonuc = "METHOD:GET|HTTPCODE:";
sonuc += kod;
sonuc += "|LENGTH:";
sonuc += uzunluk;
// Bağlantıyı kapat!
gsm.print(F("AT+HTTPTERM\r"));
_readSerial();
sonuc.trim();
return sonuc;
}
else {
return "HTTP_ACTION_READ_ERROR";
}
}
else {
return "HTTP_ACTION_ERROR";
}
}
else {
return "HTTP_PARAMETER_ERROR";
}
}
else {
return "HTTP_PARAMETER_ERROR";
}
}
else {
return "HTTP_INIT_ERROR";
}
}
else {
return "GPRS_NOT_CONNECTED";
}
}
GSMSimHTTP.cpp get(String) - modified
String GSMSimHTTP::get(String url) {
if (!isConnected()) return "GPRS_NOT_CONNECTED";
// Terminate http connection, if it opened before! Otherwise method not run correctly.
gsm.print(F("AT+HTTPTERM\r"));
_readSerial();
gsm.print(F("AT+HTTPINIT\r"));
_readSerial();
if (_buffer.indexOf(F("OK")) != -1) return "HTTP_INIT_ERROR";
gsm.print(F("AT+HTTPPARA=\"CID\",1\r"));
_readSerial();
if (_buffer.indexOf(F("OK")) == -1) return "HTTP_PARAMETER_ERROR";
gsm.print(F("AT+HTTPPARA=\"URL\",\""));
gsm.print(url);
gsm.print("\"\r");
_readSerial();
if (_buffer.indexOf(F("OK")) == -1) return "HTTP_PARAMETER_ERROR";
gsm.print(F("AT+HTTPACTION=0\r"));
_readSerial();
if (_buffer.indexOf(F("OK")) == -1) return "HTTP_ACTION_ERROR";
_readSerial(30000);
if (_buffer.indexOf(F("+HTTPACTION: 0,")) == -1) return "HTTP_ACTION_READ_ERROR";
String kod = _buffer.substring(_buffer.indexOf(F(","))+1, _buffer.lastIndexOf(F(",")));
String uzunluk = _buffer.substring(_buffer.lastIndexOf(F(","))+1);
kod.trim();
uzunluk.trim();
String sonuc = "METHOD:GET|HTTPCODE:";
sonuc += kod;
sonuc += "|LENGTH:";
sonuc += uzunluk;
// Bağlantıyı kapat!
gsm.print(F("AT+HTTPTERM\r"));
_readSerial();
sonuc.trim();
return sonuc;
}
At least in my opinion, the modified version is much easier to understand. The error message follows right after the condition that could cause it.
You could also replace all checks for OK
in the buffer with one global checkOKinBuffer()
defined in GSMSim.h
All that does not seem too hard to automate. A python script could probably rearrange the code automatically.
Another thing: having multiple functions with nearly-identical code and (even worse) identical strings affects the code size quite significantly. see #52
Hi, Im using the library at the moment, and I like it a lot but some commands didint work for me. Im using a SIM800L and a arduino pro min. I edited the library a bit and now the two funtions are working (isSimInserted() and setPhoneFunc(uint8_t level)).
Here are the two codes working, hope it helps some one else!
bool GSMSim::setPhoneFunc(uint8_t level) {
if(level == 0 || level == 1 || level == 4) {
this->print(F("AT+CFUN="));
this->print(String(level));
this->print(F("\r"));
_buffer = _readSerial();
if( (_buffer.indexOf("OK") ) != -1) {
return true;
}
else {
return false;
}
}
else {
return false;
}
}
and
bool GSMSim::isSimInserted() {
this->print(F("AT+CSMINS?\r"));
_buffer = _readSerial();
if(_buffer.indexOf(",") != -1) {
// bölelim
if(_buffer.substring(_buffer.indexOf(",") + 1, _buffer.indexOf(",") + 2)) {
return true;
} else {
return false;
}
} else {
return false;
}
}
oops it's already implemented. sry. pls delete
Hi, just wondering if this library is still being worked on ?
I would love to use this with the SIM7000G ( currently using the LiliyGo SIM7000G board ) but it crashes the board when I load it.
This might be something to do with the board but I thought I would ask if the SIM7000 was supported.
Thanks for your time and great work.
I want read out the Time with SIM800L. With the command don't go
get(int *day, int *month, int *year, int *hour, int *minute, int *second)
What make i wrong?
Hallo Erdem,
I have tested with success your library "GSMSim" with Arduino UNO in every examples, but I cannot send Email ONLY with the Arduino Nano with the same hardware configuration.
I put a LIPO battery directly to VBAT and GND of my SIM800C (with Arduino UNO and NANO) and my Arduino Nano is powered by the USB cable (to have the debug).
I receive these messages:
GSMSim Library - Send Email Example
Connect to Internet: 1
Set gmail smtp configuration: 1
Write email to someone: ERROR:TITLE_NOT_SET
Send email... : SUCCESS:EMAIL_SEND
Close Internet: 1
But I receive the Email with the "title", but without the "body".
Thanks a lot if you have any suggestion.
Roberto
Graz - Austria
I have some problems with gprsIsConnected at v1.xx.
After the connection request, I have some bad characters at the beginning of the _buffer like:
Send: AT+SAPBR=2,1
Answer: ⸮+ATSAPBR.....
indexOf returns always -1, I think there is an issue at indexOf()..
Now I debugged the _buffer and the first char is 0xE0 = 224 = à
if (_buffer.indexOf("ERR") != -1 || _buffer.indexOf(""0.0.0.0"") != -1 || _buffer.substring(4).indexOf(""0.0.0.0"") != -1) {
Show 99 only. Sim800c connect to operator. I think cmd not work.
Hello, thanks for your library
Using gsm.gprsHTTPGet , I'm able to get results from URLs like www.google.com or www.mysite.com
But not from www.mysite.com/one/or/two/branches
It's just me ?
Thanks in advance
If I use more numbers to call, only first number is active.
Serial.println("Calling the number " + String(phone_no));
Serial.println(gsm.call(phone_no));
delay(10000);
Serial.println("Call hang off");
gsm.callHangoff();
delay(10000);
Serial.println("Calling the number " + String(phone_no));
Serial.println(gsm.call(phone_no));
delay(10000);
Serial.println("Call hang off");
gsm.callHangoff();
No posible to second call
Hello,
Thanks for the library for the SIM900.
But I have a question and I hope you can help me.
I want to join a meeting at Zoom (https://zoom.us/) via the SIM900.
To do this I have to enter (paste) the following (in Android phone) to automatically call:
Phone Number+Pause(2 seconds)+MeetingID+#+Pause(4 seconds)+HostID+#+Pause(4 seconds)+Password+#
(MeetingID and Password as an example)
+31207946519,,83411719839#,,,,#,,,,*999999#
call(PHONE_NUMBER) does not connect.
Only accepts a phone number.
Any idea how I get that to work?
Thank you very much for the effort.
Sincerely,
Arie van den Berg
I want to have a post request to send some data. my question is why is "post" request not in the library. is it not supported on GSM?
hai.... i have project to make a controller relay with sms. and i tested this library on my arduino mega. its work with pin 9 and 10. but the pin comunication is useless if i using digital pin. i try change pin from 9 and 10 to pin 14 and 15 (TX3 and RX3), but not working. why is not working?. does the communication pin must to use serial?
I have tried using the gmail function but i think there is a problem with the "AT+SMTPFROM" part because when i enter the correct email in the .ino example even then it quits out the loop and tells me :
GSMSim Library - Send Email Example
Connect to Internet: 0
Set gmail smtp configuration: 0
Write email to someone: ERROR:FROM_NOT_SET
Send email... : ERROR:EMAIL_SENDING_ERROR
Close Internet: 0
Hi Erdem,
Is there any method like HttpPost. In library i see only httpGet methot wish to have httpPost.
Teşekkürler.
It seems both functions don't work or I'm doing it wrong:
Serial.println(sms.deleteAll()); and I see a 0 in the serial monitor.
If I delete an SMS using sms.deleteOne(idx); I get a 1 if the SMS with index exists.
While testing this lib I had received 2 SMS but their index was 21 and 22.
What about 0 to 20?
Before switching to this lib I was using just serial communication to do some tests with the SIM800L.
I already had received 2 more SMS before switching, but I don't see them with this lib.
Could it be that the lib uses a different memory location on the module compared to using a new module with just serial com?
Best regards,
Robert
Hi, can you disable ou allow the use of AltSoftSerial library instead SoftSerial?
Many functions have largely identical code and even worse, identical strings.
See for example this: https://github.com/H3wastooshort/GSMSim/blob/76da58a0c74fd5ce6e5e3692303a7a767dd6e5c5/src/GSMSimHTTP.cpp#L42
Using enums instead of strings for return codes would be better because
a) it would be easier to code error checks (no comparing strings) and
b) it would save valuable space in flash
You could one std::map (not supported in plain arduino) or errorToString function (just a switch-case with all codes and corresponding strings) to convert error-codes back into strings if needed. I think there is even a way to make enums printable using Arduino's Printable
class.
Hi,
I have module sim7020e, i tried to test it with library called Adafruit FONA Library and it found the card and show me his info with no problem!
My next step was to try to work with you library, but the connection is in initial and your library cant find the modem device.
Please help me, what may be the problem??
Thanks.
If we look into the SIM800L library by cristiansteib, there's a method that retrieves the SMS senders number. Which is a pretty handy feature.
Following is the code segment from cristiansteib's library.
String Sim800l::getNumberSms(uint8_t index){
_buffer=readSms(index);
Serial.println(_buffer.length());
if (_buffer.length() > 10) //avoid empty sms
{
uint8_t _idx1=_buffer.indexOf("+CMGR:");
_idx1=_buffer.indexOf("\",\"",_idx1+1);
return _buffer.substring(_idx1+3,_buffer.indexOf("\",\"",_idx1+4));
}else{
return "";
}
}
The time.get(int *day, int *month, int *year, int *hour, int *minute, int *second) function won't return to the loop even after 1-2min. Is there something wrong with my stuff or can others reproduce the issue?
Thanks in advance...
Detection of DTMF tones - SIM800L module.
I get "OK" when I send 'AT+DDET=1,1000,1,1* ' over uart .
But it doesnt seem to detect anything afterwards.
Perhaps I am doing something wrong.
Would appreciate some feedback.
regards
Atul
ref : *SIM800 Series_AT Command Manual_V1.09
I'm running the SMS example on a sim800l from Amazon. Although it sends the SMS, something seems wrong with receiving the replies from the sent AT-commands.
(I modified the first 3 functions to return the _buffer instead, and it seems like the sim module is just echoing the commands?)
22:10:27.293 -> Set Phone Function... AT+CFUN=1
22:10:29.299 -> is Module Registered to Network?... AT+CREG?
22:10:31.306 -> Signal Quality... AT+CSQ
22:10:33.313 -> Operator Name... NOT CONNECTED
22:10:35.320 -> Init SMS... 0
22:10:37.321 -> List Unread SMS... NO_SMS
22:10:39.368 -> SMS to any number... 1
22:10:42.404 -> Begin to listen incoming messages...
I work with an Arduino Nano. It only has 1 serial connection so I tried different softwareserial, and outputting to a display. Always the same result. The slightly modified code (with softserial):
#include <AltSoftSerial.h>
#include <GSMSimSMS.h>
// You can use any Serial interface. I recommended HardwareSerial. Please use the library with highiest baudrate.
// In examples, i used HardwareSerial. You can change it anymore.
#define RESET_PIN 10 // you can use any pin.
static volatile int num = 0;
AltSoftSerial mySerial;
GSMSimSMS sms(mySerial, RESET_PIN); // GSMSimSMS inherit from GSMSim. You can use GSMSim methods with it.
void initSIM() {
mySerial.begin(9600); // If you dont change module baudrate, it comes with auto baudrate.
delay(1000);
/*
while(!mySerial.available()) {
; // wait for module for connect.
}
*/
Serial.begin(9600); // Serial for debug...
// Init module...
sms.init(); // use for init module. Use it if you dont have any valid reason.
Serial.print("Set Phone Function... ");
Serial.println(sms.setPhoneFunc(1));
delay(1000);
Serial.print("is Module Registered to Network?... ");
Serial.println(sms.isRegistered());
delay(1000);
Serial.print("Signal Quality... ");
Serial.println(sms.signalQuality());
delay(1000);
Serial.print("Operator Name... ");
Serial.println(sms.operatorNameFromSim());
delay(1000);
Serial.print("Init SMS... ");
Serial.println(sms.initSMS()); // Its optional but highly recommended. Some function work with this function.
delay(1000);
Serial.print("List Unread SMS... ");
Serial.println(sms.list(true)); // Its optional but highly recommended. Some function work with this function.
delay(1000);
Serial.print("SMS to any number... ");
Serial.println(sms.send("0032123456789", "Selam kardesim, naber?")); // only use ascii chars please
//delay(1000);
// For other methods please look at readme.txt file.
Serial.println("Begin to listen incoming messages...");
}
void loop() {
char c;
if (Serial.available()) {
c = Serial.read();
mySerial.print(c);
}
if (mySerial.available()) {
c = mySerial.read();
Serial.print(c);
}
}
Hello, great job for this library, it's the only one i play with which answer easily my basic needs: handle incoming call (get phone number), handle incoming sms (getting senderNo and message) and make https post.
But i want to add an mqtt features to my project and can't find a way to achieve it only with this library.
I use it with TinyGSM and Pubsub but since then i'm facing accidental complexity. I no longer systematically enter Serial1.available() in the loop() to process incoming calls or received messages. Sometimes TinyGSM handles it. For example, instead of +CLCC, I get RING or nothing. Other times, nothing happens.
The same goes for SMS. I think it's because i initialise both on the same rx and tx pinout
So does someone achieve to use gsmsim with an mqtt client please ? or perhaps ways to do it ?
Or rewrite if (Serial1.available()) part another way to manage this ?
Im using the lilygo tcall (sim800l and esp32 board)
Hi, Please help me with my problem.
I'm using s800l module with arduino uno. I tried to send and sms using the library but i don't received any text from my module to my phone. I tried to run GSMSim_Module_Info and i got the following details:
GSMSim Library - Module Information
Manufacturer: SIMCOM Ltd
Model: SIMCOM SIM800L
Revision: 1418B04SIM800L24
O
IMEI:
IMSI: 864764036478012
ICCID: 515020210958145
Is Connected?: 0
Signal Quality: 99
Operator: T+CSQ
+CSQ: 27,0
OK
Operator From Sim: GLOBE
Is there something wrong with the output? It says not connected? What does exactly it mean?
I'm from Philippines.
Thank you for making this library.
Hi Erdem,
first let me thank you for developing this lib. I want to use it to realize my sms gateway using the SIM800L on an ESP8266 arduino board.
I get a compile error on line 148:
Lines 127 to 156 in 337a9c8
The defined return type of the send method is boolean
. But you try to return a string. It looks like a unwanted copypaste...
best regards
I am trying to set the APN but I get an error.
Serial.println(http.gprsInit("www.vodafone.net.nz","",""));
But I get the error
GSMSim_HTTP:91:58: error: invalid use of void expression Serial.println(http.gprsInit("www.vodafone.net.nz","",""));
With a chevron pointing to the bracket before the ;.
Seems like the syntax is correct?
When i write
DateTime.get(int *day, int *month, int *year, int *hour, int *minute, int *second);
Become the Error
expected'(' for function-style cast ot type construction
Hi we need to post uint8_t* instead of String without convetion.
can we use Hardware serial ??
AT+CNMI=0,0
This disables SMS on the fly receiving, since, if this is not disabled, the responses not must be parsed correctly
In some project, when we only want to send a sms or make a call, and we no need to answer any incoming call, which make module sim busy in a long period of time. So i think we should have a command that help us to reject an imcoming call positively.
Thank you for all your helps.
I tried to use your library with the following code to read sms
Serial.println("Unread sms");
String list = "NO_SMS";
while (list == "NO_SMS") {
list = gsm.smsListUnread();
Serial.println("No sms");
delay(2000);
}
uint8_t index = list.substring(11).toInt();
Serial.print("Reading sms n. ");
Serial.println(index);
String sms = gsm.smsRead(index, true);
Serial.println(sms);
It receive sms but, when it read, the answer is always INDEX_NO_ERROR
thanks for your help
What about implementing a time.getUNIX() function that returns a uint64_t containting the UNIX timestamp.
Hi! I tried to use your library but there is no way to send an sms
Here my code
`/*
Set Phone Function... 1
is Module Registered to Network?... 1
Signal Quality... 15
Operator Name... Turk Telekom
Init SMS... 1
List Unread SMS... SMSIndexNo:35,36
SMS to any number... 1
Begin to listen incoming messages...
#include <GSMSimSMS.h>
#include <SoftwareSerial.h>
SoftwareSerial Serial1(8, 7); // RX, TX
// You can use any Serial interface. I recommended HardwareSerial. Please use the library with highiest baudrate.
// In examples, i used HardwareSerial. You can change it anymore.
#define RESET_PIN 10 // you can use any pin.
static volatile int num = 0;
GSMSimSMS sms(Serial1, RESET_PIN); // GSMSimSMS inherit from GSMSim. You can use GSMSim methods with it.
void setup() {
Serial1.begin(9600); // If you dont change module baudrate, it comes with auto baudrate.
while(!Serial1) {
; // wait for module for connect.
}
Serial.begin(9600); // Serial for debug...
// Init module...
sms.init(); // use for init module. Use it if you dont have any valid reason.
Serial.print("Set Phone Function... ");
Serial.println(sms.setPhoneFunc(1));
delay(1000);
Serial.print("is Module Registered to Network?... ");
Serial.println(sms.isRegistered());
delay(1000);
Serial.print("Signal Quality... ");
Serial.println(sms.signalQuality());
delay(1000);
Serial.print("Operator Name... ");
Serial.println(sms.operatorNameFromSim());
delay(1000);
Serial.print("Init SMS... ");
Serial.println(sms.initSMS()); // Its optional but highly recommended. Some function work with this function.
delay(1000);
Serial.print("List Unread SMS... ");
Serial.println(sms.list(true)); // Its optional but highly recommended. Some function work with this function.
delay(1000);
Serial.print("SMS to any number... ");
Serial.println(sms.send("+393661789628", "Selam kardesim, naber?")); // only use ascii chars please
delay(1000);
// For other methods please look at readme.txt file.
//Serial.println("Begin to listen incoming messages...");
}
void loop() {
// Use your Serial interface...
// if(Serial1.available()) {
// String buffer = "";
// buffer = Serial1.readString();
// num = num + 1;
// Serial.print(num);
// Serial.print(". ");
// //Serial.println(buffer);
//
// /**/
// // This example for how you catch incoming calls.
// if(buffer.indexOf("+CMTI:") != -1) {
//
// Serial.print("SMS Index No... ");
// int indexno = sms.indexFromSerial(buffer);
// Serial.println(indexno);
//
// Serial.print("Who send the message?...");
// Serial.println(sms.getSenderNo(indexno));
//
// Serial.print("Read the message... ");
// Serial.println(sms.readFromSerial(buffer));
// } else {
// Serial.println(buffer);
// }
//
// }
// put your main code here, to run repeatedly:
}`
Any help is pleased. Thanks
The F() macro is used only sometimes. The RAM load would be decreased if it were to be used more regularly.
Example:
String GSMSimTime::syncFromServer() {
gsm.print("AT+CNTPCID=1\r"); //Bad
_readSerial();
gsm.print(F("AT+CNTP\r")); //Good
_readSerial();
//delay(50);
_readSerial(30000);
Was it just forgotten, or is there something preventing it's use?
As comment mentions there is no such function that handles SIM cards that have active PIN code protection on them.
Comparison is always false due to limited range of data type in bool GSMSim::fmSetVolume(uint8_t volume)
Unused parameter 'imeino' in bool GSMSim::moduleIMEIChange(char* imeino)
Unused parameter 'read' in String GSMSim::gprsHTTPGet(String url, bool read)
No return, in function returning non-void in bool GSM::callHangoff() and similar functions.
Hi,
I have been trying to use the SMSread function.
It always returns back index no error, however manual executing the +CMGR is working fine.
Is there any update
I want you to add a function to display the number of the incoming call.
"IncomingCall(char *number)"
Hello there,
I noticed when using the examples - no matter which one I used, in every example I get the Error " 'Serial1' was not declared in this scope" and I'm quite new to Android, so I do not know, what that means.
However, I see nowhere a "Serial1" is defined in the whole class.
The error always points me to the Serial1 in the loop(). When removing Serial1 in the loop, it points me to the one in setup().
Kind Regards,
Kit
Hi,
I have tested some SIM800L EVB module (with blue PCB), if I use the library not work correctly, because it does not catch the signal by the carrier.
But if I use the AT command for manually catching the signal:
AT+COPS=?
+COPS: (2,"vodafone","voda IT","22210"),(1,"Wind Telecom SpA","I WIND","22288"),,(0-4),(0-2)
for listing all cell operator available and I manually set the operator:
AT+COPS=0,0,"I WIND"
OK
after this operations, I can send correctly SMS, or a call number, etc...
In your library exist some method for send manually AT+COPS
commands?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.