In a recent Arduino embedded system I needed to manage an Arduino GSM Shield for some specific use cases. However, I couldn’t use the well-known GSM library due to memory capacity limitations since this library “eats” the Arduino board memory 🙂 I could use an Arduino board with more memory capacity but this was not the case for me. I wrote the library SimpleGSM, which is a simple GSM library for managing the Arduino GSM shield (maybe you can use the library with other GSM cards) and execute some basic operations. I wrote the library to have exactly the operations I wanted. The library uses internally a software serial for the communication.
So, below is the source code of the SimpleGSM library.
SimpleGsm.h
#ifndef _SimpleGsm_H #define _SimpleGsm_H #include "Arduino.h" #include <SoftwareSerial.h> class SimpleGsm : public SoftwareSerial { public: SimpleGsm (const byte rxPin, const byte txPin, const byte powerPin); bool begin (const long baudRate, const byte numberOfRetries); bool disableEcho (); bool setSmsTextMode (); bool sendSms (const String phoneNumber, const String message); bool missedCall (const String phoneNumber, const unsigned long ringingDuration); bool startCall (const String phoneNumber); bool callIsDialing (); bool callIsRinging (); void waitOnCallDialing (); void waitOnCallRinging (const unsigned long duration); bool hangCall (); private: void restart (); bool setEcho (const bool state); bool setSmsMode (const byte mode); void queryForCallStatus (); bool responseIsReceived (char * const pattern, const long timeOut); static char * const OK_RESPONSE_FORMAT; byte _powerPin; }; #endif /* _SimpleGsm_H */
SimpleGsm.cpp
#include "SimpleGsm.h" char * const SimpleGsm::OK_RESPONSE_FORMAT = "\r\nOK\r\n"; SimpleGsm::SimpleGsm (const byte rxPin, const byte txPin, const byte powerPin) : SoftwareSerial (rxPin, txPin) { _powerPin = powerPin; pinMode(_powerPin, OUTPUT); } void SimpleGsm::restart () { digitalWrite(_powerPin, HIGH); delay(12000); digitalWrite(_powerPin, LOW); delay(1000); } bool SimpleGsm::responseIsReceived (char * const pattern, const long timeOut) { this->setTimeout(timeOut); return this->find(pattern); } bool SimpleGsm::disableEcho () { return this->setEcho (false); } bool SimpleGsm::setSmsTextMode () { return this->setSmsMode (1); } bool SimpleGsm::setEcho (const bool state) { this->print(F("ATE")); this->print(state); this->print(F("\r")); return this->responseIsReceived(OK_RESPONSE_FORMAT, 3000); } bool SimpleGsm::setSmsMode (const byte mode) { this->print(F("AT+CMGF=")); this->print(mode); this->print(F("\r")); return this->responseIsReceived(OK_RESPONSE_FORMAT, 3000); } bool SimpleGsm::begin (const long baudRate, const byte numberOfRetries) { SoftwareSerial::begin (baudRate); for (byte i = 0; i < numberOfRetries; i++) { this->restart (); delay(1000); this->print(F("AT\r")); if (this->responseIsReceived(OK_RESPONSE_FORMAT, 3000)) { return true; } } return false; } bool SimpleGsm::sendSms (const String phoneNumber, const String message) { this->print(F("AT+CMGS=\"")); this->print(phoneNumber); this->print(F("\"\r")); if (!this->responseIsReceived("\r\n> ", 3000)) { return false; } this->print(message); this->write(0x1A); return this->responseIsReceived(OK_RESPONSE_FORMAT, 10000); } bool SimpleGsm::startCall (const String phoneNumber) { this->print(F("ATD")); this->print(phoneNumber); this->print(F(";\r")); return this->responseIsReceived(OK_RESPONSE_FORMAT, 3000); } bool SimpleGsm::callIsDialing() { this->queryForCallStatus(); return this->responseIsReceived("+CLCC: 1,0,2,0,0", 500); } bool SimpleGsm::callIsRinging() { this->queryForCallStatus(); return this->responseIsReceived("+CLCC: 1,0,3,0,0", 500); } void SimpleGsm::waitOnCallDialing() { while (this->callIsDialing()) ; } void SimpleGsm::waitOnCallRinging(const unsigned long duration) { const unsigned long previousMillis = millis(); while ((unsigned long) (millis() - previousMillis) < duration) { if (!this->callIsRinging()) { break; } } } bool SimpleGsm::missedCall (const String phoneNumber, const unsigned long ringingDuration) { if (this->startCall(phoneNumber)) { this->waitOnCallDialing(); if (this->callIsRinging()) { this->waitOnCallRinging(ringingDuration); } this->hangCall(); return true; } return false; } void SimpleGsm::queryForCallStatus() { this->print(F("AT+CLCC\r")); } bool SimpleGsm::hangCall () { this->print(F("ATH\r")); return this->responseIsReceived(OK_RESPONSE_FORMAT, 3000); }
Happy Hacking!