From 8027c9746d4e6a63019cc9e60be21de7fc31c670 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 09:14:40 +0200 Subject: [PATCH 01/25] Add support for newlines in SMS messages --- src/ArduinoCellular.cpp | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index ad709fc..2b15184 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -293,13 +293,11 @@ std::vector splitStringByLines(const String& input, char delimiter = '\n if (endIndex == -1) endIndex = input.length(); String line = input.substring(startIndex, endIndex); - if(line.length() > 0 && line != "\r" && line != "\n" && line != "\r\n"){ - // Remove trailing \r if it exists - if (line.endsWith("\r")) { - line.remove(line.length() - 1); - } - lines.push_back(line); + // Remove trailing \r if it exists + if (line.endsWith("\r")) { + line.remove(line.length() - 1); } + lines.push_back(line); startIndex = endIndex + 1; } return lines; @@ -309,19 +307,30 @@ std::vector splitStringByLines(const String& input, char delimiter = '\n std::vector parseSMSData(const String& data) { std::vector smsList = std::vector(); std::vector lines = splitStringByLines(data); - - // Remove last line if it's "OK" - if (lines.size() > 0 && lines[lines.size() - 1] == "OK") { - lines.pop_back(); + + // Remove first line if it's empty + if (lines.size() > 0 && lines[0] == "") { + lines.erase(lines.begin()); } - for(int i = 0; i < lines.size(); i += 2){ + // Remove last 2 lines if second to last line is "OK" + if (lines.size() >= 2 && lines.back() == "OK") { + lines.erase(lines.end() - 2, lines.end()); + } + + for(int i = 0; i < lines.size(); i ++){ if (lines[i].startsWith("+CMGL:")) { + String entry = lines[i]; String message = ""; - if(i + 1 < lines.size()){ - message = lines[i + 1]; + // Loop through the lines until the next +CMGL line and extract the message by concatenating the lines + for (int j = i + 1; j < lines.size(); j++) { + if (lines[j].startsWith("+CMGL:")) { + i = j - 1; + break; + } + message += lines[j] + "\n"; } - SMS sms = parseSMSEntry(lines[i], message); + SMS sms = parseSMSEntry(entry, message); smsList.push_back(sms); } } From d4b6e029fd27b8fd83e872b8de68c9e83dfa73fd Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 09:21:02 +0200 Subject: [PATCH 02/25] Add index property to SMS --- src/ArduinoCellular.cpp | 4 ++++ src/ArduinoCellular.h | 6 ++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index 2b15184..72876b7 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -272,6 +272,10 @@ SMS parseSMSEntry(const String& entry, const String& message) { int fourthQuoteIndex = entry.indexOf('"', thirdQuoteIndex + 1); int commaIndexBeforeTimestamp = entry.lastIndexOf(',', entry.lastIndexOf(',') - 1); + String command = "+CMGL: "; + // Index is between "+CMGL: " and first "," symbol + sms.index = entry.substring(entry.indexOf(command) + command.length(), entry.indexOf(',')).toInt(); + // Extracting number and raw timestamp sms.number = entry.substring(thirdQuoteIndex + 1, fourthQuoteIndex); String rawTimestamp = entry.substring(commaIndexBeforeTimestamp + 2, entry.indexOf('+', commaIndexBeforeTimestamp) + 3); diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index e6ab0a6..01a4c4d 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -37,6 +37,7 @@ enum ModemModel { class SMS { public: String number; /**< The phone number associated with the SMS. */ + int16_t index; /**< The index of the SMS message. */ String message; /**< The content of the SMS message. */ Time timestamp; /**< The timestamp when the SMS was received. */ @@ -46,18 +47,19 @@ class SMS { */ SMS() { this->number = ""; + this->index = -1; this->message = ""; this->timestamp = Time(); } /** * Constructor for SMS. + * @param index The index of the SMS message. * @param number The phone number associated with the SMS. * @param message The content of the SMS message. * @param timestamp The timestamp when the SMS was received. */ - SMS(String number, String message, Time timestamp) { - this->number = number; + SMS(int16_t index, String number, String message, Time timestamp) { this->message = message; this->timestamp = timestamp; } From ac1903098fd4279de866cdc356de40ff1b4b3974 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 09:21:24 +0200 Subject: [PATCH 03/25] Fix date parsing --- src/ArduinoCellular.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index 72876b7..dbe9724 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -249,9 +249,9 @@ Time parseTimestamp(const String ×tampStr) { int firstSlashIndex = date.indexOf('/'); int secondSlashIndex = date.lastIndexOf('/'); - day = date.substring(0, firstSlashIndex).toInt(); + year = date.substring(0, firstSlashIndex).toInt() + 2000; month = date.substring(firstSlashIndex + 1, secondSlashIndex).toInt(); - year = date.substring(secondSlashIndex + 1).toInt() + 2000; + day = date.substring(secondSlashIndex + 1).toInt(); int firstColonIndex = time.indexOf(':'); int secondColonIndex = time.lastIndexOf(':'); From 0172d7b4288a9ff24487cf169d5d0c1ced18a366 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 09:31:32 +0200 Subject: [PATCH 04/25] Use sender instead of number --- src/ArduinoCellular.cpp | 2 +- src/ArduinoCellular.h | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index dbe9724..faac099 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -277,7 +277,7 @@ SMS parseSMSEntry(const String& entry, const String& message) { sms.index = entry.substring(entry.indexOf(command) + command.length(), entry.indexOf(',')).toInt(); // Extracting number and raw timestamp - sms.number = entry.substring(thirdQuoteIndex + 1, fourthQuoteIndex); + sms.sender = entry.substring(thirdQuoteIndex + 1, fourthQuoteIndex); String rawTimestamp = entry.substring(commaIndexBeforeTimestamp + 2, entry.indexOf('+', commaIndexBeforeTimestamp) + 3); // Parse the timestamp diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index 01a4c4d..c88b52e 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -36,8 +36,8 @@ enum ModemModel { */ class SMS { public: - String number; /**< The phone number associated with the SMS. */ int16_t index; /**< The index of the SMS message. */ + String sender; /**< The phone number associated with the SMS. */ String message; /**< The content of the SMS message. */ Time timestamp; /**< The timestamp when the SMS was received. */ @@ -46,8 +46,8 @@ class SMS { * Initializes the number, message, and timestamp to empty values. */ SMS() { - this->number = ""; this->index = -1; + this->sender = ""; this->message = ""; this->timestamp = Time(); } @@ -55,11 +55,12 @@ class SMS { /** * Constructor for SMS. * @param index The index of the SMS message. - * @param number The phone number associated with the SMS. + * @param sender The phone number associated with the sender of the SMS. * @param message The content of the SMS message. * @param timestamp The timestamp when the SMS was received. */ - SMS(int16_t index, String number, String message, Time timestamp) { + SMS(int16_t index, String sender, String message, Time timestamp) { + this->sender = sender; this->message = message; this->timestamp = timestamp; } From 82e648ea98e130ca1e0fa5354d18b44198481db0 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 09:32:03 +0200 Subject: [PATCH 05/25] Avoid extra newline in SMS message --- src/ArduinoCellular.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index faac099..72ce90a 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -334,6 +334,9 @@ std::vector parseSMSData(const String& data) { } message += lines[j] + "\n"; } + // Remove the trailing newline character from the message + message.remove(message.length() - 1); + SMS sms = parseSMSEntry(entry, message); smsList.push_back(sms); } From 0db0da0b0d993fd855f123dad197573cc31da631 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 09:34:06 +0200 Subject: [PATCH 06/25] Remove test data --- examples/ReceiveSMS/arduino_secrets.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/examples/ReceiveSMS/arduino_secrets.h b/examples/ReceiveSMS/arduino_secrets.h index bbcdcc9..c1430af 100644 --- a/examples/ReceiveSMS/arduino_secrets.h +++ b/examples/ReceiveSMS/arduino_secrets.h @@ -2,9 +2,3 @@ #define SECRET_GPRS_APN "apn" // replace with your GPRS APN #define SECRET_GPRS_LOGIN "login" // replace with your GPRS login #define SECRET_GPRS_PASSWORD "password" // replace with your GPRS password - - -#define SECRET_PINNUMBER "1234" // replace with your SIM card PIN -#define SECRET_GPRS_APN "live.vodafone.com" // replace with your GPRS APN -#define SECRET_GPRS_LOGIN "live" // replace with your GPRS login -#define SECRET_GPRS_PASSWORD "" // replace with your GPRS password From 0b32193ffb90acd71d5f53df09f4b05e314f779a Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 09:37:17 +0200 Subject: [PATCH 07/25] Add polling to SMS receive example --- examples/ReceiveSMS/ReceiveSMS.ino | 41 ++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/examples/ReceiveSMS/ReceiveSMS.ino b/examples/ReceiveSMS/ReceiveSMS.ino index 6564db4..e44e091 100644 --- a/examples/ReceiveSMS/ReceiveSMS.ino +++ b/examples/ReceiveSMS/ReceiveSMS.ino @@ -1,24 +1,24 @@ #include "ArduinoCellular.h" #include "arduino_secrets.h" -// #define TINY_GSM_DEBUG Serial -// #define ARDUINO_CELLULAR_DEBUG constexpr int NEW_SMS_INTERRUPT_PIN = A0; ArduinoCellular cellular = ArduinoCellular(); volatile boolean smsReceived = false; +constexpr int POLLING_INTERVAL_MS = 1 * 60 * 1000; // 1 minute void printMessages(std::vector msg){ for(int i = 0; i < msg.size(); i++){ Serial.println("SMS:"); - Serial.print("\t * From: "); Serial.println(msg[i].number); - Serial.print("\t * Message: "); Serial.println(msg[i].message); - Serial.print("\t * Timestamp: "); Serial.println(msg[i].timestamp.getISO8601()); + Serial.print("* Index: "); Serial.println(msg[i].index); + Serial.print("* From: "); Serial.println(msg[i].sender); + Serial.print("* Timestamp: "); Serial.println(msg[i].timestamp.getISO8601()); + Serial.println("* Message: "); Serial.println(msg[i].message); + Serial.println("--------------------\n"); } } void onSMSReceived(){ - Serial.println("New SMS received!"); smsReceived = true; } @@ -26,28 +26,43 @@ void setup(){ Serial.begin(115200); while (!Serial); cellular.setDebugStream(Serial); - cellular.begin(); + Serial.println("Connecting..."); cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD, SECRET_PINNUMBER); - + // Register interrupt based callback for new SMS attachInterrupt(digitalPinToInterrupt(NEW_SMS_INTERRUPT_PIN), onSMSReceived, RISING); - Serial.println("Read SMS:"); std::vector readSMS = cellular.getReadSMS(); - printMessages(readSMS); + if(readSMS.size() > 0){ + Serial.println("Read SMS:"); + printMessages(readSMS); + } - Serial.println("Unread SMS:"); std::vector unreadSMS = cellular.getUnreadSMS(); - printMessages(unreadSMS); + if(unreadSMS.size() > 0){ + Serial.println("Unread SMS:"); + printMessages(unreadSMS); + } } void loop(){ - if(smsReceived){ + static unsigned long lastPoll = 0; + static bool checkForNewSMS = false; + + if(millis() - lastPoll > POLLING_INTERVAL_MS){ + checkForNewSMS = true; + lastPoll = millis(); + } + + if(smsReceived || checkForNewSMS){ smsReceived = false; + checkForNewSMS = false; std::vector unreadSMS = cellular.getUnreadSMS(); + if (unreadSMS.size() > 0){ + Serial.println("New SMS received!"); printMessages(unreadSMS); } } From 9c5325e399fb9903124c9ce812324206a4c5465b Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 14:47:46 +0200 Subject: [PATCH 08/25] Remove need to supply APN settings --- examples/ReceiveSMS/ReceiveSMS.ino | 2 +- examples/ReceiveSMS/arduino_secrets.h | 4 --- src/ArduinoCellular.cpp | 45 +++++++++++++++++---------- src/ArduinoCellular.h | 9 +++--- 4 files changed, 35 insertions(+), 25 deletions(-) delete mode 100644 examples/ReceiveSMS/arduino_secrets.h diff --git a/examples/ReceiveSMS/ReceiveSMS.ino b/examples/ReceiveSMS/ReceiveSMS.ino index e44e091..0217fbf 100644 --- a/examples/ReceiveSMS/ReceiveSMS.ino +++ b/examples/ReceiveSMS/ReceiveSMS.ino @@ -29,7 +29,7 @@ void setup(){ cellular.begin(); Serial.println("Connecting..."); - cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD, SECRET_PINNUMBER); + cellular.connect(); // Register interrupt based callback for new SMS attachInterrupt(digitalPinToInterrupt(NEW_SMS_INTERRUPT_PIN), onSMSReceived, RISING); diff --git a/examples/ReceiveSMS/arduino_secrets.h b/examples/ReceiveSMS/arduino_secrets.h deleted file mode 100644 index c1430af..0000000 --- a/examples/ReceiveSMS/arduino_secrets.h +++ /dev/null @@ -1,4 +0,0 @@ -#define SECRET_PINNUMBER "" // replace with your SIM card PIN -#define SECRET_GPRS_APN "apn" // replace with your GPRS APN -#define SECRET_GPRS_LOGIN "login" // replace with your GPRS login -#define SECRET_GPRS_PASSWORD "password" // replace with your GPRS password diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index 72ce90a..9049f67 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -43,33 +43,46 @@ void ArduinoCellular::begin() { } -bool ArduinoCellular::connect(String apn, String gprsUser, String gprsPass, String pin){ +bool ArduinoCellular::connect(String apn, String username, String password, String pin){ SimStatus simStatus = getSimStatus(); if(simStatus == SimStatus::SIM_LOCKED && pin.length() > 0){ unlockSIM(pin.c_str()); } simStatus = getSimStatus(); - if(simStatus == SimStatus::SIM_READY) { - if(awaitNetworkRegistration()){ - if(connectToGPRS(apn.c_str(), gprsUser.c_str(), gprsPass.c_str())){ - if(this->debugStream != nullptr){ - this->debugStream->println("Setting DNS..."); - } - - auto response = this->sendATCommand("+QIDNSCFG=1,\"8.8.8.8\",\"8.8.4.4\""); - - if(this->debugStream != nullptr){ - this->debugStream->println(response); - } - return true; - } + if(simStatus != SimStatus::SIM_READY) { + if(this->debugStream != nullptr){ + this->debugStream->println("SIM not ready or incorrect PIN provided."); + } + return false; + } + + if(!awaitNetworkRegistration()){ + return false; + } + + if(apn.length() == 0){ + if(this->debugStream != nullptr){ + this->debugStream->println("No APN specified, not connecting to GPRS"); + } + return true; + } + + if(connectToGPRS(apn.c_str(), username.c_str(), password.c_str())){ + auto response = this->sendATCommand("+QIDNSCFG=1,\"8.8.8.8\",\"8.8.4.4\""); + + if(response.indexOf("OK") != -1){ + return true; } else { + if(this->debugStream != nullptr){ + this->debugStream->println("Failed to set DNS."); + } return false; } + } - return false; + return false; } diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index c88b52e..d822fd6 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -95,14 +95,15 @@ class ArduinoCellular { void begin(); /** - * @brief Connects to the network using the specified APN, GPRS username, and GPRS password. + * @brief Registers with the cellular network and connects to the Internet + * if the APN, GPRS username, and GPRS password are provided. * @param apn The Access Point Name. - * @param gprsUser The GPRS username. - * @param gprsPass The GPRS password. + * @param username The APN username. + * @param password The APN password. * @param pin The SIM card PIN. * @return True if the connection is successful, false otherwise. */ - bool connect(String apn, String gprsUser, String gprsPass, String pin = ""); + bool connect(String apn = "", String username = "", String password = "", String pin = ""); /** * @brief Checks if the modem is registered on the network. From b415e2f17cae17673a1091e3509b661169adb7d4 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 14:58:38 +0200 Subject: [PATCH 09/25] Make SIM unlock explicit --- examples/SendSMS/SendSMS.ino | 11 ++++++----- src/ArduinoCellular.cpp | 4 ++-- src/ArduinoCellular.h | 14 +++++++------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/examples/SendSMS/SendSMS.ino b/examples/SendSMS/SendSMS.ino index 563d5b8..ce25b78 100644 --- a/examples/SendSMS/SendSMS.ino +++ b/examples/SendSMS/SendSMS.ino @@ -15,10 +15,6 @@ */ #include "ArduinoCellular.h" -const char apn[] = "internet"; -const char gprsUser[] = ""; -const char gprsPass[] = ""; - ArduinoCellular cellular = ArduinoCellular(); void setup(){ @@ -29,8 +25,13 @@ void setup(){ cellular.begin(); String pinCode = "1234"; // If your SIM card has a PIN code, specify it here + if(pinCode.length() > 0 && !cellular.unlockSIM(pinCode)){ + Serial.println("Failed to unlock SIM card."); + while(true); // Stop here + } + Serial.println("Connecting to network..."); - cellular.connect(apn, gprsUser, gprsPass, pinCode); + cellular.connect(); // APN settings are not required for sending SMS Serial.println("Sending SMS..."); cellular.sendSMS("", "bleep bleep"); diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index 9049f67..74194b7 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -202,11 +202,11 @@ SimStatus ArduinoCellular::getSimStatus(){ } } -bool ArduinoCellular::unlockSIM(const char * pin){ +bool ArduinoCellular::unlockSIM(String pin){ if(this->debugStream != nullptr){ this->debugStream->println("Unlocking SIM..."); } - return modem.simUnlock(pin); + return modem.simUnlock(pin.c_str()); } bool ArduinoCellular::awaitNetworkRegistration(){ diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index d822fd6..38972fc 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -94,6 +94,13 @@ class ArduinoCellular { */ void begin(); + /** + * @brief Unlocks the SIM card using the specified PIN. + * @param pin The SIM card PIN. + * @return True if the SIM card is unlocked, false otherwise. + */ + bool unlockSIM(String pin); + /** * @brief Registers with the cellular network and connects to the Internet * if the APN, GPRS username, and GPRS password are provided. @@ -237,13 +244,6 @@ class ArduinoCellular { */ SimStatus getSimStatus(); - /** - * @brief Unlocks the SIM card using the specified PIN. - * @param pin The SIM card PIN. - * @return True if the SIM card is unlocked, false otherwise. - */ - bool unlockSIM(const char * pin); - /** * @brief Waits for network registration. (Blocking call) * @return True if the network registration is successful, false otherwise. From 91b7b6a9613d75d7bfe81a2fe853283b0b48d89e Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 15:01:49 +0200 Subject: [PATCH 10/25] Remove old include --- examples/ReceiveSMS/ReceiveSMS.ino | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/ReceiveSMS/ReceiveSMS.ino b/examples/ReceiveSMS/ReceiveSMS.ino index 0217fbf..e7165f7 100644 --- a/examples/ReceiveSMS/ReceiveSMS.ino +++ b/examples/ReceiveSMS/ReceiveSMS.ino @@ -1,6 +1,4 @@ #include "ArduinoCellular.h" -#include "arduino_secrets.h" - constexpr int NEW_SMS_INTERRUPT_PIN = A0; From 07bf9d3347cc6847faa97d01c0bb8a31d8202849 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 15:13:45 +0200 Subject: [PATCH 11/25] Turn off debug output by default --- examples/ReceiveSMS/ReceiveSMS.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/ReceiveSMS/ReceiveSMS.ino b/examples/ReceiveSMS/ReceiveSMS.ino index e7165f7..9232efd 100644 --- a/examples/ReceiveSMS/ReceiveSMS.ino +++ b/examples/ReceiveSMS/ReceiveSMS.ino @@ -23,11 +23,12 @@ void onSMSReceived(){ void setup(){ Serial.begin(115200); while (!Serial); - cellular.setDebugStream(Serial); + // cellular.setDebugStream(Serial); // Uncomment this line to enable debug output cellular.begin(); Serial.println("Connecting..."); cellular.connect(); + Serial.println("Connected!"); // Register interrupt based callback for new SMS attachInterrupt(digitalPinToInterrupt(NEW_SMS_INTERRUPT_PIN), onSMSReceived, RISING); From 37c9ce32f022f3150df64b7b12e1d7df1d6298f2 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 15:23:43 +0200 Subject: [PATCH 12/25] Add option for deleting SMS --- examples/DeleteSMS/DeleteSMS.ino | 48 ++++++++++++++++++++++++++++++++ src/ArduinoCellular.cpp | 6 ++++ src/ArduinoCellular.h | 8 ++++++ 3 files changed, 62 insertions(+) create mode 100644 examples/DeleteSMS/DeleteSMS.ino diff --git a/examples/DeleteSMS/DeleteSMS.ino b/examples/DeleteSMS/DeleteSMS.ino new file mode 100644 index 0000000..37cfd3a --- /dev/null +++ b/examples/DeleteSMS/DeleteSMS.ino @@ -0,0 +1,48 @@ +#include "ArduinoCellular.h" + +ArduinoCellular cellular = ArduinoCellular(); + +void printMessages(std::vector msg){ + for(int i = 0; i < msg.size(); i++){ + Serial.println("SMS:"); + Serial.print("* Index: "); Serial.println(msg[i].index); + Serial.print("* From: "); Serial.println(msg[i].sender); + Serial.print("* Timestamp: "); Serial.println(msg[i].timestamp.getISO8601()); + Serial.println("* Message: "); Serial.println(msg[i].message); + Serial.println("--------------------\n"); + } +} + +void setup(){ + Serial.begin(115200); + while (!Serial); + cellular.begin(); + delay(2000); // Give the modem some time to initialize +} + +void loop(){ + std::vector readSMS = cellular.getReadSMS(); + if(readSMS.size() > 0){ + Serial.println("Read SMS:"); + printMessages(readSMS); + } + + std::vector unreadSMS = cellular.getUnreadSMS(); + if(unreadSMS.size() > 0){ + Serial.println("Unread SMS:"); + printMessages(unreadSMS); + } + + // Prompt user which SMS to delete + Serial.println("Enter the index of the SMS you want to delete:"); + + while(Serial.available() == 0); + auto index = Serial.readStringUntil('\n').toInt(); + Serial.println("Deleting SMS..."); + + if(cellular.deleteSMS(index)){ + Serial.println("SMS deleted."); + } else { + Serial.println("Failed to delete SMS."); + } +} diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index 74194b7..cf222ef 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -380,6 +380,12 @@ std::vector ArduinoCellular::getUnreadSMS(){ } } +bool ArduinoCellular::deleteSMS(uint16_t index){ + String command = "+CMGD=" + String(index); + String response = sendATCommand(const_cast(command.c_str())); + return response.indexOf("OK") != -1; +} + void ArduinoCellular::setDebugStream(Stream &stream){ this->debugStream = &stream; } diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index 38972fc..2c302b4 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -176,6 +176,14 @@ class ArduinoCellular { */ std::vector getUnreadSMS(); + /** + * @brief Deletes an SMS message at the specified index. + * + * @param index The index of the SMS message to delete. + * @return True if the SMS message was successfully deleted, false otherwise. + */ + bool deleteSMS(uint16_t index); + /** * @brief Sends an AT command to the modem and waits for a response, then returns the response. * @param command The AT command to send. From e6b7ba2dee6342055e1190fa2670595d07a936bc Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 15:46:03 +0200 Subject: [PATCH 13/25] Remove pin parameter from connect function --- src/ArduinoCellular.cpp | 14 +++++++++----- src/ArduinoCellular.h | 3 +-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index cf222ef..856c3f3 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -43,16 +43,20 @@ void ArduinoCellular::begin() { } -bool ArduinoCellular::connect(String apn, String username, String password, String pin){ +bool ArduinoCellular::connect(String apn, String username, String password){ SimStatus simStatus = getSimStatus(); - if(simStatus == SimStatus::SIM_LOCKED && pin.length() > 0){ - unlockSIM(pin.c_str()); + + if(simStatus == SimStatus::SIM_LOCKED){ + if(this->debugStream != nullptr){ + this->debugStream->println("SIM locked, cannot connect to network."); + } + + return false; } - simStatus = getSimStatus(); if(simStatus != SimStatus::SIM_READY) { if(this->debugStream != nullptr){ - this->debugStream->println("SIM not ready or incorrect PIN provided."); + this->debugStream->println("SIM not ready, cannot connect to network."); } return false; } diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index 2c302b4..bfa3f92 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -107,10 +107,9 @@ class ArduinoCellular { * @param apn The Access Point Name. * @param username The APN username. * @param password The APN password. - * @param pin The SIM card PIN. * @return True if the connection is successful, false otherwise. */ - bool connect(String apn = "", String username = "", String password = "", String pin = ""); + bool connect(String apn = "", String username = "", String password = ""); /** * @brief Checks if the modem is registered on the network. From b2d33d6d24d6b36c2790e397a9aaa37a3c23336b Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Thu, 11 Apr 2024 15:46:12 +0200 Subject: [PATCH 14/25] Clean up examples --- examples/HTTPClient/HTTPClient.ino | 31 +++++++++++++++++------- examples/HTTPSClient/HTTPSClient.ino | 35 ++++++++++++++++++++-------- examples/ReceiveSMS/ReceiveSMS.ino | 8 ++++++- examples/SendSMS/SendSMS.ino | 4 +++- 4 files changed, 57 insertions(+), 21 deletions(-) diff --git a/examples/HTTPClient/HTTPClient.ino b/examples/HTTPClient/HTTPClient.ino index 5525676..74668e5 100644 --- a/examples/HTTPClient/HTTPClient.ino +++ b/examples/HTTPClient/HTTPClient.ino @@ -10,14 +10,7 @@ const int port = 80; ArduinoCellular cellular = ArduinoCellular(); HttpClient client = cellular.getHTTPClient(server, port); -void setup(){ - Serial.begin(115200); - while (!Serial); - cellular.begin(); - cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD, SECRET_PINNUMBER); -} - -void loop(){ +void getResource(){ Serial.println("Making GET request..."); @@ -32,7 +25,27 @@ void loop(){ Serial.println(response); client.stop(); +} - delay(5000); +void setup(){ + Serial.begin(115200); + while (!Serial); + // cellular.setDebugStream(Serial); // Uncomment this line to enable debug output + cellular.begin(); + if(String(SECRET_PINNUMBER).length() > 0 && !cellular.unlockSIM(SECRET_PINNUMBER)){ + Serial.println("Failed to unlock SIM card."); + while(true); // Stop here + } + + Serial.println("Connecting..."); + if(!cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD)){ + Serial.println("Failed to connect to the network."); + while(true); // Stop here + } + Serial.println("Connected!"); + + getResource(); } + +void loop(){} diff --git a/examples/HTTPSClient/HTTPSClient.ino b/examples/HTTPSClient/HTTPSClient.ino index f4b45d7..24aa804 100644 --- a/examples/HTTPSClient/HTTPSClient.ino +++ b/examples/HTTPSClient/HTTPSClient.ino @@ -11,15 +11,7 @@ const int port = 443; ArduinoCellular cellular = ArduinoCellular(); HttpClient client = cellular.getHTTPSClient(server, port); -void setup(){ - Serial.begin(115200); - while (!Serial); - - cellular.begin(); - cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD, SECRET_PINNUMBER); -} - -void loop(){ +void getResource(){ Serial.println("Making GET request..."); client.get(resource); @@ -33,5 +25,28 @@ void loop(){ Serial.println(response); client.stop(); - delay(5000); } + +void setup(){ + Serial.begin(115200); + while (!Serial); + + // cellular.setDebugStream(Serial); // Uncomment this line to enable debug output + cellular.begin(); + + if(String(SECRET_PINNUMBER).length() > 0 && !cellular.unlockSIM(SECRET_PINNUMBER)){ + Serial.println("Failed to unlock SIM card."); + while(true); // Stop here + } + + Serial.println("Connecting..."); + if(!cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD)){ + Serial.println("Failed to connect to the network."); + while(true); // Stop here + } + Serial.println("Connected!"); + + getResource(); +} + +void loop(){} diff --git a/examples/ReceiveSMS/ReceiveSMS.ino b/examples/ReceiveSMS/ReceiveSMS.ino index 9232efd..56c448b 100644 --- a/examples/ReceiveSMS/ReceiveSMS.ino +++ b/examples/ReceiveSMS/ReceiveSMS.ino @@ -25,8 +25,14 @@ void setup(){ while (!Serial); // cellular.setDebugStream(Serial); // Uncomment this line to enable debug output cellular.begin(); + + String pinCode = ""; // If your SIM card has a PIN code, specify it here e.g. "1234" + if(pinCode.length() > 0 && !cellular.unlockSIM(pinCode)){ + Serial.println("Failed to unlock SIM card."); + while(true); // Stop here + } - Serial.println("Connecting..."); + Serial.println("Connecting to network..."); cellular.connect(); Serial.println("Connected!"); diff --git a/examples/SendSMS/SendSMS.ino b/examples/SendSMS/SendSMS.ino index ce25b78..f65bd9c 100644 --- a/examples/SendSMS/SendSMS.ino +++ b/examples/SendSMS/SendSMS.ino @@ -22,9 +22,10 @@ void setup(){ while (!Serial); delay(1000); // Give the serial monitor some time to start + // cellular.setDebugStream(Serial); // Uncomment this line to enable debug output cellular.begin(); - String pinCode = "1234"; // If your SIM card has a PIN code, specify it here + String pinCode = ""; // If your SIM card has a PIN code, specify it here e.g. "1234" if(pinCode.length() > 0 && !cellular.unlockSIM(pinCode)){ Serial.println("Failed to unlock SIM card."); while(true); // Stop here @@ -32,6 +33,7 @@ void setup(){ Serial.println("Connecting to network..."); cellular.connect(); // APN settings are not required for sending SMS + Serial.println("Connected!"); Serial.println("Sending SMS..."); cellular.sendSMS("", "bleep bleep"); From 82a1c6edf5b635eb9ecc89c5cae5a57aab441153 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Fri, 12 Apr 2024 09:51:52 +0200 Subject: [PATCH 15/25] Make ATCommand function accept const char ptr --- src/ArduinoCellular.cpp | 7 +++---- src/ArduinoCellular.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index 856c3f3..bbaaea2 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -247,15 +247,13 @@ bool ArduinoCellular::enableGPS(bool assisted){ //delay(10000); } -String ArduinoCellular::sendATCommand( char * command, unsigned long timeout){ +String ArduinoCellular::sendATCommand(const char * command, unsigned long timeout){ String resp; - modem.sendAT(const_cast(command)); + modem.sendAT(command); modem.waitResponse(timeout, resp); return resp; } - - Time parseTimestamp(const String ×tampStr) { int hour, minute, second, day, month, year, offset; @@ -280,6 +278,7 @@ Time parseTimestamp(const String ×tampStr) { return Time(year, month, day, hour, minute, second, offset); } + // Parses a single SMS entry from the data SMS parseSMSEntry(const String& entry, const String& message) { SMS sms; diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index bfa3f92..8b12589 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -189,7 +189,7 @@ class ArduinoCellular { * @param timeout The timeout (In milliseconds) to wait for the response. * @return The response from the modem. */ - String sendATCommand(char * command, unsigned long timeout = 1000); + String sendATCommand(const char * command, unsigned long timeout = 1000); /** From 0f7a7abf5e58d02be85eb158391cdad0c4617398 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Fri, 12 Apr 2024 10:01:16 +0200 Subject: [PATCH 16/25] Simplify Modem Terminal Sketch --- examples/ModemTerminal/ModemTerminal.ino | 36 ++++++++++++------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/examples/ModemTerminal/ModemTerminal.ino b/examples/ModemTerminal/ModemTerminal.ino index 7436d2e..b9ba519 100644 --- a/examples/ModemTerminal/ModemTerminal.ino +++ b/examples/ModemTerminal/ModemTerminal.ino @@ -1,31 +1,31 @@ #include "ArduinoCellular.h" #include "arduino_secrets.h" - ArduinoCellular cellular = ArduinoCellular(); -float lat = 0.00; -float lon = 0.00; - - void setup(){ Serial.begin(115200); while (!Serial); + cellular.setDebugStream(Serial); // Uncomment this line to enable debug output cellular.begin(); - cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD, SECRET_PINNUMBER); + + if(String(SECRET_PINNUMBER).length() > 0 && !cellular.unlockSIM(SECRET_PINNUMBER)){ + Serial.println("Failed to unlock SIM card."); + while(true); // Stop here + } + + Serial.println("Connecting..."); + cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD); + Serial.println("Connected!"); } void loop() { - if (Serial.available() > 0) { - // Define a buffer to store incoming data. Adjust the size as needed. - char incomingData[255]; // Adjust the size according to your needs - - // Read data from serial until newline is found - int size = Serial.readBytesUntil('\n', incomingData, sizeof(incomingData) - 1); // Leave space for null terminator - - // Null-terminate the string - incomingData[size] = '\0'; - // Call the sendATCommand function with the read data - Serial.println(cellular.sendATCommand(GF(incomingData))); - } + while(Serial.available() == 0); // Wait for user input + + // Read data from serial until newline + String userInput = Serial.readStringUntil('\n'); + + // Call the sendATCommand function with the read data + String response = cellular.sendATCommand(userInput.c_str()); + Serial.println(response); } \ No newline at end of file From 5e5a377bd56554556057cdbf3a30c2a0438d2bcc Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Fri, 12 Apr 2024 14:59:52 +0200 Subject: [PATCH 17/25] Adjust submission parameter for arduino-lint --- .github/workflows/arduino-lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/arduino-lint.yml b/.github/workflows/arduino-lint.yml index e280129..87c995e 100644 --- a/.github/workflows/arduino-lint.yml +++ b/.github/workflows/arduino-lint.yml @@ -22,7 +22,7 @@ jobs: uses: arduino/arduino-lint-action@v1 with: compliance: specification - library-manager: submit + library-manager: update # Always use this setting for official repositories. Remove for 3rd party projects. official: true project-type: library \ No newline at end of file From 206b3f4876438148671c20d1b89ccbadef24232c Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 15 Apr 2024 17:29:11 +0200 Subject: [PATCH 18/25] Remove unused model --- src/ArduinoCellular.cpp | 6 +++--- src/ArduinoCellular.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index bbaaea2..9c22d66 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -21,8 +21,8 @@ void ArduinoCellular::begin() { String modemInfo = this ->sendATCommand("I"); if(modemInfo.indexOf("EC200A") > 0){ this->model = ModemModel::EC200; - } else if (modemInfo.indexOf("EG95") > 0){ - this->model = ModemModel::EG95; + } else if (modemInfo.indexOf("EG25") > 0){ + this->model = ModemModel::EG25; } else { this->model = ModemModel::Unsupported; } @@ -91,7 +91,7 @@ bool ArduinoCellular::connect(String apn, String username, String password){ Location ArduinoCellular::getGPSLocation(unsigned long timeout){ - if (model == ModemModel::EG95){ + if (model == ModemModel::EG25){ float latitude = 0.00000; float longitude = 0.00000; unsigned long startTime = millis(); diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index 8b12589..46095f6 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -27,7 +27,7 @@ */ enum ModemModel { EC200, /**< Quectel EC200 modem. */ - EG95, /**< Quectel EG95 modem. */ + EG25, /**< Quectel EG25 modem. */ Unsupported /**< Unsupported modem model. */ }; From 5cab3ca96b384b93a33a472a820e2f6f11ee35ac Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 15 Apr 2024 17:33:36 +0200 Subject: [PATCH 19/25] Remove dummy function --- src/ArduinoCellular.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index 46095f6..5aa8162 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -137,13 +137,6 @@ class ArduinoCellular { */ Location getGPSLocation(unsigned long timeout = 60000); - /** - * @brief Gets the cellular location. (Blocking call) - * @param timeout The timeout (In milliseconds) to wait for the cellular location. - * @return The cellular location. If the location is not retrieved, the latitude and longitude will be 0.0. - */ - Location getCellularLocation(unsigned long timeout = 10000); - /** * @brief Gets the current time from the network. * @return The current time. From 8b3f60ec4456893c4c1d5b279d33884356717e9a Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 15 Apr 2024 17:34:02 +0200 Subject: [PATCH 20/25] Add documentation --- examples/ModemTerminal/ModemTerminal.ino | 1 + src/ArduinoCellular.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/ModemTerminal/ModemTerminal.ino b/examples/ModemTerminal/ModemTerminal.ino index b9ba519..8718a78 100644 --- a/examples/ModemTerminal/ModemTerminal.ino +++ b/examples/ModemTerminal/ModemTerminal.ino @@ -17,6 +17,7 @@ void setup(){ Serial.println("Connecting..."); cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD); Serial.println("Connected!"); + Serial.println("You can now send AT commands to the modem."); } void loop() { diff --git a/src/ArduinoCellular.h b/src/ArduinoCellular.h index 5aa8162..697fb7b 100644 --- a/src/ArduinoCellular.h +++ b/src/ArduinoCellular.h @@ -179,7 +179,7 @@ class ArduinoCellular { /** * @brief Sends an AT command to the modem and waits for a response, then returns the response. * @param command The AT command to send. - * @param timeout The timeout (In milliseconds) to wait for the response. + * @param timeout The timeout (In milliseconds) to wait for the response. Default is 1000ms. * @return The response from the modem. */ String sendATCommand(const char * command, unsigned long timeout = 1000); From ccec6b9d09069897ff374ad936e1521d954e3213 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 15 Apr 2024 17:35:48 +0200 Subject: [PATCH 21/25] Check return value for assisted GPS --- src/ArduinoCellular.cpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index 9c22d66..d4bb71d 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -231,20 +231,24 @@ bool ArduinoCellular::enableGPS(bool assisted){ this->debugStream->println("Enabling GPS..."); } + String response; + if(assisted){ - sendATCommand("AT+QGPSCFG=\"agpsposmode\",33488767"); + response = sendATCommand("+QGPSCFG=\"agpsposmode\",33488767", 10000); } else { - sendATCommand("AT+QGPSCFG=\"agpsposmode\",8388608"); + // Sets the 23rd bit to 1 to enable standalone GPS + response = sendATCommand("+QGPSCFG=\"agpsposmode\",8388608", 10000); } - //modem.sendAT(GF("+UTIME=1,1")); - //modem.waitResponse(); - //modem.sendAT(GF("+UGPIOC=23,0,1")); - - //modem.waitResponse(); + if(response.indexOf("OK") == -1){ + if(this->debugStream != nullptr){ + this->debugStream->println("Failed to set GPS mode."); + this->debugStream->println("Response: " + response); + } + return false; + } return modem.enableGPS(); - //delay(10000); } String ArduinoCellular::sendATCommand(const char * command, unsigned long timeout){ From ae1a8acad24228370cb7933a5ef2d966e4e2d453 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 15 Apr 2024 17:43:49 +0200 Subject: [PATCH 22/25] Clean up code --- src/ArduinoCellular.cpp | 8 +++----- src/ModemInterface.cpp | 21 +++++++++------------ src/ModemInterface.h | 10 +++++----- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/src/ArduinoCellular.cpp b/src/ArduinoCellular.cpp index d4bb71d..776d6ce 100644 --- a/src/ArduinoCellular.cpp +++ b/src/ArduinoCellular.cpp @@ -14,9 +14,7 @@ ArduinoCellular::ArduinoCellular() { } void ArduinoCellular::begin() { - // set sim slot modem.init(); - String modemInfo = this ->sendATCommand("I"); if(modemInfo.indexOf("EC200A") > 0){ @@ -252,10 +250,10 @@ bool ArduinoCellular::enableGPS(bool assisted){ } String ArduinoCellular::sendATCommand(const char * command, unsigned long timeout){ - String resp; + String response; modem.sendAT(command); - modem.waitResponse(timeout, resp); - return resp; + modem.waitResponse(timeout, response); + return response; } Time parseTimestamp(const String ×tampStr) { diff --git a/src/ModemInterface.cpp b/src/ModemInterface.cpp index c1b8048..4ac5a54 100644 --- a/src/ModemInterface.cpp +++ b/src/ModemInterface.cpp @@ -4,32 +4,29 @@ #include - #if defined(ARDUINO_PORTENTA_C33) + #define ON_PIN 32 // P708 (32) is the ON pin + // P602/P110/P603/P604 -> Serial1 UART Serial1_FC(UART1_TX_PIN, UART1_RX_PIN, 61, 62); #ifdef DUMP_AT_COMMANDS StreamDebugger debugger(Serial1_FC, Serial); - __attribute__ ((init_priority (101))) ModemInterface modem(debugger, 32); + __attribute__ ((init_priority (101))) ModemInterface modem(debugger, ON_PIN); #else - __attribute__ ((init_priority (101))) ModemInterface modem(Serial1_FC, 32); + __attribute__ ((init_priority (101))) ModemInterface modem(Serial1_FC, ON_PIN); #endif -// P708 (32) is the ON pin #elif defined(ARDUINO_PORTENTA_H7_M7) || defined(CORE_CM4) -#include "pinDefinitions.h" - + #include "pinDefinitions.h" + #define ON_PIN PG_3 // PG3 is the ON pin -// P602/P110/P603/P604 -> Serial1 + // P602/P110/P603/P604 -> Serial1 #ifdef DUMP_AT_COMMANDS StreamDebugger debugger(Serial1, Serial); - __attribute__ ((init_priority (101))) ModemInterface modem(debugger, PinNameToIndex(PG_3)); + __attribute__ ((init_priority (101))) ModemInterface modem(debugger, PinNameToIndex(ON_PIN)); #else - __attribute__ ((init_priority (101))) ModemInterface modem(Serial1, PinNameToIndex(PG_3)); + __attribute__ ((init_priority (101))) ModemInterface modem(Serial1, PinNameToIndex(ON_PIN)); #endif - - -// PG3 () is the ON pin #endif diff --git a/src/ModemInterface.h b/src/ModemInterface.h index c04f1f4..9da2ce7 100644 --- a/src/ModemInterface.h +++ b/src/ModemInterface.h @@ -26,9 +26,9 @@ class ModemInterface : public TinyGsmBG96 { /** * @brief Constructor for the ModemInterface class. * @param stream The stream object for communication with the modem. - * @param power_pin The pin number for controlling the power of the modem. + * @param powerPin The pin number for controlling the power of the modem. */ - explicit ModemInterface(Stream& stream, int power_pin) : TinyGsmBG96(stream),stream(&stream),power_pin(power_pin) { + explicit ModemInterface(Stream& stream, int powerPin) : TinyGsmBG96(stream),stream(&stream),powerPin(powerPin) { }; @@ -38,8 +38,8 @@ class ModemInterface : public TinyGsmBG96 { * @return True if initialization is successful, false otherwise. */ bool init(const char* pin = NULL) { - pinMode(power_pin, OUTPUT); - digitalWrite(power_pin, HIGH); + pinMode(powerPin, OUTPUT); + digitalWrite(powerPin, HIGH); delay(1000); #ifdef DUMP_AT_COMMANDS #if defined(ARDUINO_PORTENTA_C33) @@ -54,7 +54,7 @@ class ModemInterface : public TinyGsmBG96 { public: Stream* stream; /**< The stream object for communication with the modem. */ - int power_pin; /**< The pin number for controlling the power of the modem. */ + int powerPin; /**< The pin number for controlling the power of the modem. */ }; /** From 6417815118c1f0f5de7cc56d0966522a6348a862 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 15 Apr 2024 17:48:33 +0200 Subject: [PATCH 23/25] Add example to get location --- examples/GetLocation/GetLocation.ino | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 examples/GetLocation/GetLocation.ino diff --git a/examples/GetLocation/GetLocation.ino b/examples/GetLocation/GetLocation.ino new file mode 100644 index 0000000..c3a3db7 --- /dev/null +++ b/examples/GetLocation/GetLocation.ino @@ -0,0 +1,25 @@ +#include "ArduinoCellular.h" + +ArduinoCellular cellular = ArduinoCellular(); + +void setup(){ + Serial.begin(115200); + while (!Serial); + cellular.setDebugStream(Serial); + cellular.begin(); + + if(!cellular.enableGPS()){ + Serial.println("Failed to enable GPS"); + while(true); // Stop the program + } + delay(2000); // Give the modem some time to initialize +} + +void loop(){ + Location location = cellular.getGPSLocation(); + Serial.println("GPS Location:"); + Serial.print("* Latitude: "); Serial.println(location.latitude, 6); + Serial.print("* Longitude: "); Serial.println(location.longitude, 6); + Serial.println("--------------------\n"); + delay(10000); +} From 2a2e2f69a1808a5943a91e4f5a1112e6eb688fa6 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 15 Apr 2024 17:49:09 +0200 Subject: [PATCH 24/25] Extract time into its own example --- examples/GetTime/GetTime.ino | 28 +++++++++++++++ examples/TimeAndLocation/TimeAndLocation.ino | 36 -------------------- examples/TimeAndLocation/arduino_secrets.h | 4 --- 3 files changed, 28 insertions(+), 40 deletions(-) create mode 100644 examples/GetTime/GetTime.ino delete mode 100644 examples/TimeAndLocation/TimeAndLocation.ino delete mode 100644 examples/TimeAndLocation/arduino_secrets.h diff --git a/examples/GetTime/GetTime.ino b/examples/GetTime/GetTime.ino new file mode 100644 index 0000000..9da77a6 --- /dev/null +++ b/examples/GetTime/GetTime.ino @@ -0,0 +1,28 @@ +#include "ArduinoCellular.h" + +ArduinoCellular cellular = ArduinoCellular(); + +void setup(){ + Serial.begin(115200); + while (!Serial); + cellular.begin(); + + if(!cellular.enableGPS()){ + Serial.println("Failed to enable GPS"); + while(true); // Stop the program + } + delay(2000); // Give the modem some time to initialize +} + +void loop(){ + Location location = cellular.getGPSLocation(10000); + + if(location.latitude == 0.0 && location.longitude == 0.0){ + Serial.println("Failed to get GPS location"); + } else { + Time time = cellular.getGPSTime(); + Serial.print("Current time (ISO8601): "); Serial.println(time.getISO8601()); + } + + delay(10000); +} \ No newline at end of file diff --git a/examples/TimeAndLocation/TimeAndLocation.ino b/examples/TimeAndLocation/TimeAndLocation.ino deleted file mode 100644 index 2e2c286..0000000 --- a/examples/TimeAndLocation/TimeAndLocation.ino +++ /dev/null @@ -1,36 +0,0 @@ -#define DUMP_AT_COMMANDS - -#include "ArduinoCellular.h" -#include "arduino_secrets.h" - -ArduinoCellular cellular = ArduinoCellular(); - -float lat = 0.00000; -float lon = 0.00000; -int year = 0; -int month = 0; -int day = 0; -int hour = 0; -int minute = 0; -int second = 0; - - -void setup(){ - Serial.begin(115200); - while (!Serial); - cellular.begin(); - //cellular.connect(SECRET_GPRS_APN, SECRET_GPRS_LOGIN, SECRET_GPRS_PASSWORD, SECRET_PINNUMBER); - //cellular.enableGPS(false); -} - -void loop(){ - Location loc = cellular.getGPSLocation(10000); - Serial.print("Latitude: "); Serial.println(lat); - Serial.print("Longitude: "); Serial.println(lon); - - Time t = cellular.getGPSTime(); - Serial.print("ISO String: "); Serial.println(t.getISO8601()); - - delay(1000); - -} \ No newline at end of file diff --git a/examples/TimeAndLocation/arduino_secrets.h b/examples/TimeAndLocation/arduino_secrets.h deleted file mode 100644 index de218ed..0000000 --- a/examples/TimeAndLocation/arduino_secrets.h +++ /dev/null @@ -1,4 +0,0 @@ -#define SECRET_PINNUMBER "" // replace with your SIM card PIN -#define SECRET_GPRS_APN "apn" // replace with your GPRS APN -#define SECRET_GPRS_LOGIN "login" // replace with your GPRS login -#define SECRET_GPRS_PASSWORD "password" // replace with your GPRS password \ No newline at end of file From 51b55ecf10fcfce02641e0f9700b4bb101799956 Mon Sep 17 00:00:00 2001 From: Sebastian Romero Date: Mon, 15 Apr 2024 18:28:40 +0200 Subject: [PATCH 25/25] Update documentation --- README.md | 27 ++++++++++++++---------- examples/DeleteSMS/DeleteSMS.ino | 15 +++++++++++++ examples/GetLocation/GetLocation.ino | 12 +++++++++++ examples/GetTime/GetTime.ino | 13 ++++++++++++ examples/HTTPClient/HTTPClient.ino | 15 +++++++++++++ examples/HTTPSClient/HTTPSClient.ino | 14 ++++++++++++ examples/ModemTerminal/ModemTerminal.ino | 14 ++++++++++++ examples/ReceiveSMS/ReceiveSMS.ino | 16 ++++++++++++++ 8 files changed, 115 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 1bf33c6..e9f0f75 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Arduino Cellular +# 📡 Arduino Cellular [![Arduino Lint](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/arduino-lint.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/arduino-lint.yml) [![Compile Examples](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/compile-examples.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/compile-examples.yml) [![Spell Check](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/spell-check.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/spell-check.yml) [![Sync Labels](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/sync-labels.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/sync-labels.yml) [![Render Documentation](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/render-documentation.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_Cellular/actions/workflows/render-documentation.yml) @@ -6,20 +6,23 @@ This library provides a toolkit for interacting with the official Arduino 4G Modules. It allows you to connect to the internet, send and receive SMS messages, and get location from the cellular network or GPS. ## Examples -* [examples/HTTPClient]() - Example of using this library together with [HttpClient]() to connect to a web server -* [examples/HTTPClient]() - Example of using this library together with [HttpClient]() that uses [BearSSL]() under the hood to create a secure connection to a web server -* [examples/ReceiveSMS]() - Example for the SMS sending and receiving functionality -* [examples/TimeAndLocation]() - Use GPS, or Cellular to acquire the location and time of the device. -* [examples/ModemTerminal]() - A handy example for debugging and Testing AT commands - -## Features +* [DeleteSMS](examples/DeleteSMS) - Example that shows how to delete SMS. +* [GetLocation](examples/GetLocation) - Shows how to get the current GPS location. +* [GetTime](examples/GetTime) - Use GPS to acquire the time of the device. +* [HTTPClient](examples/HTTPClient) - Example of using this library together with [ArduinoHttpClient]() to connect to a web server +* [HTTPSClient](examples/HTTPSClient) - Example of using this library together with [ArduinoHttpClient]() that uses [BearSSL]() under the hood to create a secure connection to a web server +* [ModemTerminal](examples/ModemTerminal) - A handy example for debugging and Testing AT commands +* [ReceiveSMS](examples/ReceiveSMS) - Example for the SMS sending and receiving functionality +* [SendSMS](examples/SendSMS) - Shows how to send an SMS + +## ✨ Features * Fast 4G connection to the internet * Secure SSL connections with BearSSL * Get location using GPS or GSM * Synchronise time with the cell provider * Send and Receive SMS Messages -## Instructions +## 👀 Instructions 1. Insert your Arduino 4G module to the Arduino Portenta Mid Carrier 2. Insert a valid SIM card either on the back of the Arduino 4G miniPCI board, or the **PCIE_SIM** connector on the Portenta Mid Carrier 3. Connect the 6 **SERIAL1** header pins to their corresponding pins on the **PCIE_BREAKOUT** header using jumpers @@ -27,8 +30,8 @@ This library provides a toolkit for interacting with the official Arduino 4G Mod 4. Connect the **3V3 PCIE** pin to the **3V3 Buck** ![](https://raw.githubusercontent.com/arduino-libraries/Arduino_Cellular/main/extras/connection_img/buck.jpg?token=GHSAT0AAAAAACNPRJPUBUCALG2FUCDZ7AVCZQVDLJA) 5. Connect external power to the Mid Carrier, via the **VIN** (5-12V) because modem use a lot of power when connecting or getting a GPS location. Make sure your supply can handle around 3A. -6. Get the APN settings from your network operator and add them to the "ArduinoSecrets.h" file for each sketch -```c +6. Get the APN settings from your network operator and add them to the "arduino_secrets.h" file for each sketch +```cpp const char apn[] = "live.vodafone.com"; const char gprsUser[] = "live"; const char gprsPass[] = ""; @@ -36,4 +39,6 @@ const char gprsPass[] = ""; 7. Install the library and it's dependencies 8. Enjoy +## 📖 Documentation +For more information about this library please read the documentation [here](./docs). \ No newline at end of file diff --git a/examples/DeleteSMS/DeleteSMS.ino b/examples/DeleteSMS/DeleteSMS.ino index 37cfd3a..966a763 100644 --- a/examples/DeleteSMS/DeleteSMS.ino +++ b/examples/DeleteSMS/DeleteSMS.ino @@ -1,3 +1,18 @@ +/** + * This example demonstrates how to delete SMS messages using the ArduinoCellular library. + * + * Instructions: + * 1. Insert a SIM card with or without PIN code in the Arduino Pro 4G Module. + * 2. Provide sufficient power to the Arduino Pro 4G Module. Ideally, use a 5V power supply + * with a current rating of at least 2A and connect it to the VIN and GND pins. + * 3. Send an SMS to the SIM card number to test the SMS reception. + * 4. Upload the sketch to the connected Arduino board. + * 5. Check the serial monitor for the received SMS. + * 6. Enter the index of the SMS you want to delete in the serial monitor. + * + * Initial author: Sebastian Romero +*/ + #include "ArduinoCellular.h" ArduinoCellular cellular = ArduinoCellular(); diff --git a/examples/GetLocation/GetLocation.ino b/examples/GetLocation/GetLocation.ino index c3a3db7..7ec02a7 100644 --- a/examples/GetLocation/GetLocation.ino +++ b/examples/GetLocation/GetLocation.ino @@ -1,3 +1,15 @@ +/** + * This example demonstrates how to get the current GPS location using the ArduinoCellular library. + * + * Instructions: + * 1. Move the Arduino Pro 4G Module to an outdoor location with a clear view of the sky. + * 2. Provide sufficient power to the Arduino Pro 4G Module. Ideally, use a 5V power supply + * 3. Upload the sketch to the connected Arduino board. + * 4. Open the serial monitor to view the output. + * + * Initial author: Sebastian Romero +*/ + #include "ArduinoCellular.h" ArduinoCellular cellular = ArduinoCellular(); diff --git a/examples/GetTime/GetTime.ino b/examples/GetTime/GetTime.ino index 9da77a6..af4e2b4 100644 --- a/examples/GetTime/GetTime.ino +++ b/examples/GetTime/GetTime.ino @@ -1,3 +1,16 @@ +/** + * This example demonstrates how to get the current time using the ArduinoCellular library. + * It derives the time from GPS connection. + * + * Instructions: + * 1. Move the Arduino Pro 4G Module to an outdoor location with a clear view of the sky. + * 2. Provide sufficient power to the Arduino Pro 4G Module. Ideally, use a 5V power supply + * 3. Upload the sketch to the connected Arduino board. + * 4. Open the serial monitor to view the output. + * + * Initial author: Cristian Dragomir +*/ + #include "ArduinoCellular.h" ArduinoCellular cellular = ArduinoCellular(); diff --git a/examples/HTTPClient/HTTPClient.ino b/examples/HTTPClient/HTTPClient.ino index 74668e5..fa275ce 100644 --- a/examples/HTTPClient/HTTPClient.ino +++ b/examples/HTTPClient/HTTPClient.ino @@ -1,3 +1,18 @@ +/** + * This example demonstrates how to make a HTTP GET request using + * the ArduinoHttpClient library and the ArduinoCellular library. + * + * Instructions: + * 1. Insert a SIM card with or without PIN code in the Arduino Pro 4G Module. + * 2. Provide sufficient power to the Arduino Pro 4G Module. Ideally, use a 5V power supply + * with a current rating of at least 2A and connect it to the VIN and GND pins. + * 3. Specify the APN, login, and password for your cellular network provider. + * 4. Upload the sketch to the connected Arduino board. + * 5. Open the serial monitor to view the output. + * + * Initial author: Cristian Dragomir +*/ + #define ARDUINO_CELLULAR_DEBUG #include "ArduinoCellular.h" diff --git a/examples/HTTPSClient/HTTPSClient.ino b/examples/HTTPSClient/HTTPSClient.ino index 24aa804..20a328a 100644 --- a/examples/HTTPSClient/HTTPSClient.ino +++ b/examples/HTTPSClient/HTTPSClient.ino @@ -1,3 +1,17 @@ +/** + * Example demonstrating how to make an HTTPS GET request using + * the ArduinoHttpClient library and the ArduinoCellular library. + * + * Instructions: + * 1. Insert a SIM card with or without PIN code in the Arduino Pro 4G Module. + * 2. Provide sufficient power to the Arduino Pro 4G Module. Ideally, use a 5V power supply + * with a current rating of at least 2A and connect it to the VIN and GND pins. + * 3. Specify the APN, login, and password for your cellular network provider. + * 4. Upload the sketch to the connected Arduino board. + * 5. Open the serial monitor to view the output. + * + * Initial author: Cristian Dragomir +*/ #include #include "ArduinoCellular.h" diff --git a/examples/ModemTerminal/ModemTerminal.ino b/examples/ModemTerminal/ModemTerminal.ino index 8718a78..6d064ae 100644 --- a/examples/ModemTerminal/ModemTerminal.ino +++ b/examples/ModemTerminal/ModemTerminal.ino @@ -1,3 +1,17 @@ +/** + * The ModemTerminal example demonstrates how to use the ArduinoCellular library to send raw AT commands to the modem. + * + * Instructions: + * 1. Insert a SIM card with or without PIN code in the Arduino Pro 4G Module. + * 2. Provide sufficient power to the Arduino Pro 4G Module. Ideally, use a 5V power supply + * with a current rating of at least 2A and connect it to the VIN and GND pins. + * 3. Specify the APN, login, and password for your cellular network provider. + * 4. Upload the sketch to the connected Arduino board. + * 5. Open the serial monitor and type AT commands to interact with the modem. + * + * Initial author: Cristian Dragomir +*/ + #include "ArduinoCellular.h" #include "arduino_secrets.h" diff --git a/examples/ReceiveSMS/ReceiveSMS.ino b/examples/ReceiveSMS/ReceiveSMS.ino index 56c448b..c15351f 100644 --- a/examples/ReceiveSMS/ReceiveSMS.ino +++ b/examples/ReceiveSMS/ReceiveSMS.ino @@ -1,3 +1,19 @@ +/** + * This example demonstrates how to receive SMS messages using ArduinoCellular library. + * It supports both polling and interrupt based methods to check for new SMS messages. + * + * Instructions: + * 1. Insert a SIM card with or without PIN code in the Arduino Pro 4G Module. + * 2. Provide sufficient power to the Arduino Pro 4G Module. Ideally, use a 5V power supply + * with a current rating of at least 2A and connect it to the VIN and GND pins. + * 3. Specify the PIN code of your SIM card if it has one. + * 4. Upload the sketch to the connected Arduino board. + * 5. Send an SMS to the SIM card number to test the SMS reception. + * 6. Check the serial monitor for the received SMS. + * + * Initial author: Cristian Dragomir +*/ + #include "ArduinoCellular.h" constexpr int NEW_SMS_INTERRUPT_PIN = A0;