diff --git a/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino b/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino new file mode 100644 index 0000000..6b62f57 --- /dev/null +++ b/examples/Example2_NetworkInfo/Example2_NetworkInfo.ino @@ -0,0 +1,123 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +// Map registration status messages to more readable strings +String registrationString[] = +{ + "Not registered", // 0 + "Registered, home", // 1 + "Searching for operator", // 2 + "Registration denied", // 3 + "Registration unknown", // 4 + "Registered, roaming", // 5 + "Registered, home (SMS only)", // 6 + "Registered, roaming (SMS only)", // 7 + "Registered, emergency service only", // 8 + "Registered, home, CSFB not preferred", // 9 + "Registered, roaming, CSFB not prefered" // 10 +}; + +// If you are based in Europe, you will (probably) need to select MNO_STD_EUROPE +const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL; + +void setup() +{ + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 2 - Network Info")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + if (!myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR)) + { + Serial.println(F("Error setting network. Try cycling the power.")); + while (1) ; + } + + Serial.println(F("Network profile set. Ready to go!")); + + // RSSI: Received signal strength: + Serial.println("RSSI: " + String(myModule.rssi())); + // Registration Status + int regStatus = myModule.registration(); + if ((regStatus >= 0) && (regStatus <= 10)) + { + Serial.println("Network registration: " + registrationString[regStatus]); + } + + // Print the Context IDs, Access Point Names and IP Addresses + Serial.println(F("Available PDP (Packet Data Protocol) APNs (Access Point Names) and IP Addresses:")); + Serial.println(F("Context ID:\tAPN Name:\tIP Address:")); + for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++) + { + String apn = ""; + IPAddress ip(0, 0, 0, 0); + myModule.getAPN(cid, &apn, &ip); + if (apn.length() > 0) + { + Serial.print(cid); + Serial.print(F("\t\t")); + Serial.print(apn); + Serial.print(F("\t")); + Serial.println(ip); + } + } + + Serial.println(); + + if (regStatus > 0) + { + Serial.println(F("All set. Go to the next example!")); + } +} + +void loop() +{ + // Do nothing. Now that we're registered move on to the next example. +} \ No newline at end of file diff --git a/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino new file mode 100644 index 0000000..6532dc8 --- /dev/null +++ b/examples/Example3_RegisterOperator/Example3_RegisterOperator.ino @@ -0,0 +1,326 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +// Map registration status messages to more readable strings +String registrationString[] = +{ + "Not registered", // 0 + "Registered, home", // 1 + "Searching for operator", // 2 + "Registration denied", // 3 + "Registration unknown", // 4 + "Registered, roaming", // 5 + "Registered, home (SMS only)", // 6 + "Registered, roaming (SMS only)", // 7 + "Registered, emergency service only", // 8 + "Registered, home, CSFB not preferred", // 9 + "Registered, roaming, CSFB not prefered" // 10 +}; + +// If you are based in Europe, you will (probably) need to select MNO_STD_EUROPE +const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL; + +const String MOBILE_NETWORK_STRINGS[] = {"default (Undefined/Regulatory)", "SIM ICCID", "AT&T", "Verizon", + "Telstra", "T-Mobile US", "China Telecom", "Sprint", "Vodafone", "NTT DoCoMo", "Telus", "SoftBank", + "Deutsche Telekom", "US Cellular", "SKT", "global (factory default)", "standard Europe", + "standard Europe No-ePCO", "NOT RECOGNIZED"}; + +// Convert the operator number into an index for MOBILE_NETWORK_STRINGS +int convertOperatorNumber( mobile_network_operator_t mno) +{ + switch (mno) + { + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + return ((int)mno); + case 8: + return 7; + case 19: + return 8; + case 20: + return 9; + case 21: + return 10; + case 28: + return 11; + case 31: + return 12; + case 32: + return 13; + case 39: + return 14; + case 90: + return 15; + case 100: + return 16; + case 101: + return 17; + default: // NOT RECOGNIZED + return 18; + } +} + +// This defines the size of the ops struct array. To narrow the operator +// list, set MOBILE_NETWORK_OPERATOR to AT&T, Verizon etc. instead +// of MNO_SW_DEFAULT. +#define MAX_OPERATORS 10 + +// Uncomment this line if you want to be able to communicate directly with the module in the main loop +//#define DEBUG_PASSTHROUGH_ENABLED + +void setup() +{ + int opsAvailable; + struct operator_stats ops[MAX_OPERATORS]; + String currentOperator = ""; + bool newConnection = true; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 3 - Register Operator")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're already connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) { + Serial.print(F("Already connected to: ")); + Serial.println(currentOperator); + // If already connected provide the option to type y to connect to new operator + Serial.println(F("Press y to connect to a new operator, or any other key to continue.\r\n")); + while (!Serial.available()) ; + if (Serial.read() != 'y') + { + newConnection = false; + } + else + { + myModule.deregisterOperator(); // Deregister from the current operator so we can connect to a new one + } + while (Serial.available()) Serial.read(); + } + + if (newConnection) { + // Set MNO to either Verizon, T-Mobile, AT&T, Telstra, etc. + // This will narrow the operator options during our scan later + Serial.println(F("Setting mobile-network operator")); + if (myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR)) + { + Serial.print(F("Set mobile network operator to ")); + Serial.println(MOBILE_NETWORK_STRINGS[convertOperatorNumber(MOBILE_NETWORK_OPERATOR)] + "\r\n"); + } + else + { + Serial.println(F("Error setting MNO. Try cycling the power. Freezing...")); + while (1) ; + } + + // Wait for user to press button before initiating network scan. + Serial.println(F("Press any key scan for networks..")); + serialWait(); + + Serial.println(F("Scanning for networks...this may take up to 3 minutes\r\n")); + // myModule.getOperators takes in a operator_stats struct pointer and max number of + // structs to scan for, then fills up those objects with operator names and numbers + opsAvailable = myModule.getOperators(ops, MAX_OPERATORS); // This will block for up to 3 minutes + + if (opsAvailable > 0) + { + // Pretty-print operators we found: + Serial.println("Found " + String(opsAvailable) + " operators:"); + printOperators(ops, opsAvailable); + Serial.println(String(opsAvailable + 1) + ": use automatic selection"); + Serial.println(); + + // Wait until the user presses a key to initiate an operator connection + Serial.println("Press 1-" + String(opsAvailable + 1) + " to select an operator."); + char c = 0; + bool selected = false; + while (!selected) { + while (!Serial.available()) ; + c = Serial.read(); + int selection = c - '0'; + if ((selection >= 1) && (selection <= (opsAvailable + 1))) { + selected = true; + Serial.println("Connecting to option " + String(selection)); + if (selection == (opsAvailable + 1)) + { + if (myModule.automaticOperatorSelection() == UBX_CELL_SUCCESS) + { + Serial.println("Automatic operator selection: successful\r\n"); + } + else + { + Serial.println(F("Automatic operator selection: error. Reset and try again, or try another network.")); + } + } + else + { + if (myModule.registerOperator(ops[selection - 1]) == UBX_CELL_SUCCESS) + { + Serial.println("Network " + ops[selection - 1].longOp + " registered\r\n"); + } + else + { + Serial.println(F("Error connecting to operator. Reset and try again, or try another network.")); + } + } + } + } + } + else + { + Serial.println(F("Did not find an operator. Double-check SIM and antenna, reset and try again, or try another network.")); + while (1) ; + } + } + + // At the very end print connection information + printInfo(); +} + +void loop() +{ + // Loop provides a debugging interface. + if (mySerial.available()) { + Serial.write((char) mySerial.read()); + } +#ifdef DEBUG_PASSTHROUGH_ENABLED + if (Serial.available()) { + mySerial.write((char) Serial.read()); + } +#endif +} + +void printInfo(void) { + String currentApn = ""; + IPAddress ip(0, 0, 0, 0); + String currentOperator = ""; + + Serial.println(F("Connection info:")); + Serial.println(F("Context ID:\tAPN Name:\tIP Address:")); + for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++) + { + String apn = ""; + IPAddress ip(0, 0, 0, 0); + myModule.getAPN(cid, &apn, &ip); + if (apn.length() > 0) + { + Serial.print(cid); + Serial.print(F("\t\t")); + Serial.print(apn); + Serial.print(F("\t")); + Serial.println(ip); + } + } + + // Operator name or number + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Operator: ")); + Serial.println(currentOperator); + } + + // Received signal strength + Serial.println("RSSI: " + String(myModule.rssi())); + Serial.println(); +} + +void printOperators(struct operator_stats * ops, int operatorsAvailable) +{ + for (int i = 0; i < operatorsAvailable; i++) + { + Serial.print(String(i + 1) + ": "); + Serial.print(ops[i].longOp + " (" + String(ops[i].numOp) + ") - "); + switch (ops[i].stat) + { + case 0: + Serial.print(F("UNKNOWN")); + break; + case 1: + Serial.print(F("AVAILABLE")); + break; + case 2: + Serial.print(F("CURRENT")); + break; + case 3: + Serial.print(F("FORBIDDEN")); + break; + } + switch (ops[i].act) + { + case 0: + Serial.print(F(" - GSM")); + break; + case 2: + Serial.print(F(" - UTRAN")); + break; + case 3: + Serial.print(F(" - GSM/GPRS with EDGE")); + break; + case 7: + Serial.print(F(" - LTE")); // SARA-R5 only supports LTE + break; + } + Serial.println(); + } + Serial.println(); +} + +void serialWait() +{ + while (Serial.available()) Serial.read(); + while (!Serial.available()) ; + delay(100); + while (Serial.available()) Serial.read(); +} \ No newline at end of file diff --git a/examples/Example4_Clock/Example4_Clock.ino b/examples/Example4_Clock/Example4_Clock.ino new file mode 100644 index 0000000..a7a1b25 --- /dev/null +++ b/examples/Example4_Clock/Example4_Clock.ino @@ -0,0 +1,80 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 4 - Clock")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // Make sure automatic time zone updates are enabled + if (myModule.autoTimeZone(true) != UBX_CELL_SUCCESS) + Serial.println(F("Enable autoTimeZone failed!")); + + // Read and print the clock as a String + String theTime = myModule.clock(); + Serial.println(theTime); + + // Read and print the hour, minute, etc. separately + uint8_t year, month, day, hour, minute, second; + int8_t timeZone; + if (myModule.clock( &year, &month, &day, &hour, &minute, &second, &timeZone ) == UBX_CELL_SUCCESS) + // Note: not all Arduino boards implement printf correctly. The formatting may not be correct on some boards. + // Note: the timeZone is defined in 15 minute increments, not hours. -28 indicates the time zone is 7 hours behind UTC/GMT. + Serial.printf("%02d/%02d/%02d %02d:%02d:%02d %+d\r\n", year, month, day, hour, minute, second, timeZone); +} + +void loop() +{ + // Nothing to do here +} \ No newline at end of file diff --git a/examples/Example5_Ping/Example5_Ping.ino b/examples/Example5_Ping/Example5_Ping.ino new file mode 100644 index 0000000..1de835c --- /dev/null +++ b/examples/Example5_Ping/Example5_Ping.ino @@ -0,0 +1,140 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +String pingMe = ""; // The name of the server we are going to ping + +// processPingResult is provided to the u-blox cellular library via a +// callback setter -- setPingCallback. (See the end of setup()) +void processPingResult(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt) +{ + Serial.println(); + Serial.print(F("Ping Result: Retry #:")); + Serial.print(retry); + Serial.print(F(" Ping Size (Bytes):")); + Serial.print(p_size); + Serial.print(F(" Remote Host:\"")); + Serial.print(remote_hostname); + Serial.print(F("\" IP Address:\"")); + Serial.print(String(ip[0])); + Serial.print(F(".")); + Serial.print(String(ip[1])); + Serial.print(F(".")); + Serial.print(String(ip[2])); + Serial.print(F(".")); + Serial.print(String(ip[3])); + Serial.print(F("\" Time To Live (hops):")); + Serial.print(ttl); + Serial.print(F(" Round Trip (ms):")); + Serial.print(rtt); + Serial.println(); +} + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 5 - Ping")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + Serial.println(); + Serial.println(F("*** Set the Serial Monitor line ending to Newline ***")); + + Serial.println(); + Serial.println(F("Enter the name of the server you want to ping (followed by LF / Newline): ")); + Serial.println(F("Example: \"www.google.com\"")); + + // Set a callback to process the Ping result + myModule.setPingCallback(&processPingResult); +} + +void loop() +{ + if (Serial.available()) + { + char c = Serial.read(); + if (c == '\n') + { + // Newline received so let's do that ping! + Serial.println("Pinging " + pingMe + "..."); + myModule.ping(pingMe); // Use the default parameters + + // Use custom parameters + //int retries = 4; // number of retries + //int p_size = 32; // packet size (bytes) + //unsigned long timeout = 5000; // timeout (ms) + //int ttl = 32; // Time To Live + //myModule.ping(pingMe, retries, p_size, timeout, ttl); + + pingMe = ""; // Clear the server name for the next try + } + else + { + // Add serial characters to the server address + pingMe += c; + } + } + + myModule.poll(); // Keep processing data from the module so we can catch the Ping result +} \ No newline at end of file diff --git a/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino b/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino new file mode 100644 index 0000000..ae5a336 --- /dev/null +++ b/examples/Example6_ReceiveSMS/Example6_ReceiveSMS.ino @@ -0,0 +1,256 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 6 - Receive SMS")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); +} + +void loop() +{ + static bool printReadMessages = true; // Print all messages once. Then only print new messages. Unless a message is deleted. + static int previousUsed = -1; // Store the previous number of used memory locations + + // Read the number of used and total messages + int used; + int total; + if (myModule.getPreferredMessageStorage(&used, &total) != UBX_CELL_SUCCESS) + { + Serial.println(F("An error occurred when trying to read ME memory!")); + } + else + { + if ((used != previousUsed) || printReadMessages) // Has a new message arrived? Or was the delete menu opened? + { + Serial.print(F("\r\nNumber of used memory locations: ")); + Serial.println(used); + Serial.print(F("Total number of memory locations: ")); + Serial.println(total); + Serial.println(); + + int memoryLocation = 0; + int foundMessages = 0; + // Keep reading until we find all the messages or we reach the end of the memory + while ((foundMessages < used) && (memoryLocation <= total)) + { + String unread = ""; + String from = ""; + String dateTime = ""; + String message = ""; + // Read the message from this location. Reading from empty message locations returns an ERROR + // unread can be: "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT" + // If the location is empty, readSMSmessage will return a UBX_CELL_ERROR_UNEXPECTED_RESPONSE + if (myModule.readSMSmessage(memoryLocation, &unread, &from, &dateTime, &message) == UBX_CELL_SUCCESS) + { + if (printReadMessages || (unread == "REC UNREAD")) + { + Serial.print(F("Message location: ")); + Serial.println(memoryLocation); + Serial.print(F("Status: ")); + Serial.println(unread); + Serial.print(F("Originator: ")); + Serial.println(from); + Serial.print(F("Date and time: ")); + Serial.println(dateTime); + Serial.println(message); + Serial.println(); + } + foundMessages++; // We found a message + } + memoryLocation++; // Move on to the next memory location + } + + printReadMessages = false; + previousUsed = used; // Update previousUsed + + Serial.println(F("Waiting for a new message...")); + Serial.println(); + Serial.println(F("Hit any key to delete a message...")); + Serial.println(); + } + } + + int delayCount = 0; + while (delayCount < 5000) + { + delay(1); // Delay for five seconds, unless the user presses a key + delayCount++; + + if (Serial.available()) + { + Serial.println(F("To delete a single message: enter its location followed by LF / Newline")); + Serial.println(F("To delete all read messages: enter r followed by LF / Newline")); + Serial.println(F("To delete all read and sent messages: enter s followed by LF / Newline")); + Serial.println(F("To delete all read, sent and unsent messages: enter u followed by LF / Newline")); + Serial.println(F("To delete all messages, including unread messages: enter a followed by LF / Newline")); + Serial.println(F("To exit: enter LF / Newline")); + + Serial.read(); // Read and discard the char that opened the menu + + int location = 0; + bool selected = false; + while (!selected) + { + while (!Serial.available()) ; // Wait for a character to arrive + char c = Serial.read(); // Read it + if (c == '\n') // Is it a LF? + { + if ((location >= 1) && (location <= total)) // Delete a single message at location + { + if (myModule.deleteSMSmessage(location) == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nMessage deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessage not deleted!\r\n")); + } + } + else if (location == 1001) // r + { + if (myModule.deleteReadSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nRead messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else if (location == 1002) // s + { + if (myModule.deleteReadSentSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nRead and sent messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else if (location == 1003) // u + { + if (myModule.deleteReadSentUnsentSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nRead, sent and unsent messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else if (location == 1004) // a + { + if (myModule.deleteAllSMSmessages() == UBX_CELL_SUCCESS) + { + Serial.println(F("\r\nAll messages deleted!\r\n")); + printReadMessages = true; + } + else + { + Serial.println(F("\r\nMessages not deleted!\r\n")); + } + } + else + Serial.println(F("\r\nExit...\r\n")); + selected = true; + } + else if ((c >= '0') && (c <= '9')) + { + location *= 10; // Multiply by 10 + location += c - '0'; // Add the digit + } + else if (c == 'r') + { + location = 1001; + } + else if (c == 's') + { + location = 1002; + } + else if (c == 'u') + { + location = 1003; + } + else if (c == 'a') + { + location = 1004; + } + } + + delayCount = 5000; + } + } +} \ No newline at end of file diff --git a/examples/Example7_SendSMS/Example7_SendSMS.ino b/examples/Example7_SendSMS/Example7_SendSMS.ino new file mode 100644 index 0000000..79bda44 --- /dev/null +++ b/examples/Example7_SendSMS/Example7_SendSMS.ino @@ -0,0 +1,129 @@ +#include "SparkFun_u-blox_Cellular_Arduino_Library.h" + +// Uncomment the line below that you need for Serial on your platform +#define mySerial Serial1 +// SoftwareSerial mySerial(16, 17); + +// Uncomment the module you're using. If your module is not listed below, then +// it's not supported for this example +UBX_CELL myModule; // This example works with all modules, so the base class can be used +// SARA_R5 myModule; // Base SARA-R5 class +// SARA_R500S myModule; +// SARA_R500S_01B myModule; +// SARA_R500S_61B myModule; +// SARA_R510M8S_61B myModule; +// SARA_R510S myModule; +// LARA_R6 myModule; // Base LARA-R6 class +// LARA_R6001 myModule; +// LARA_R6001D myModule; +// LARA_R6401 myModule; +// LARA_R6401D myModule; +// LARA_R6801_00B myModule; +// LARA_R6801D myModule; + +void setup() +{ + String currentOperator = ""; + + Serial.begin(115200); // Start the serial console + + // Wait for user to press key to begin + Serial.println(F("u-blox Cellular Example 7 - Send SMS")); + Serial.println(F("Press any key to begin")); + + while (!Serial.available()) // Wait for the user to press a key (send any serial character) + ; + while (Serial.available()) // Empty the serial RX buffer + Serial.read(); + + Serial.println(F("Beginning...")); + + // myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial + + // For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low + // Uncomment the next line if required + // myModule.invertPowerPin(true); + + // Initialize the module + if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE) ) + { + Serial.println(F("Module connected!")); + } + else + { + Serial.println(F("Unable to communicate with the module.")); + Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again.")); + while (1) ; // Loop forever on fail + } + Serial.println(); + + // First check to see if we're connected to an operator: + if (myModule.getOperator(¤tOperator) == UBX_CELL_SUCCESS) + { + Serial.print(F("Connected to: ")); + Serial.println(currentOperator); + } + else + { + Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. Or wait and retry. Freezing...")); + while (1) + ; // Do nothing more + } + + Serial.println(); + Serial.println(F("*** Set the Serial Monitor line ending to Newline ***")); +} + +void loop() +{ + String destinationNumber = ""; + String message = ""; + boolean keepGoing = true; + + Serial.println(); + Serial.println(F("Enter the destination number (followed by LF / Newline): ")); + + while (keepGoing) + { + if (Serial.available()) + { + char c = Serial.read(); + if (c == '\n') + { + keepGoing = false; // Stop if we receive a newline + } + else + { + destinationNumber += c; // Add serial characters to the destination number + } + } + } + + keepGoing = true; + Serial.println(); + Serial.println(F("Enter the message (followed by LF): ")); + + while (keepGoing) + { + if (Serial.available()) + { + char c = Serial.read(); + if (c == '\n') + { + keepGoing = false; // Stop if we receive a newline + } + else + { + message += c; // Add serial characters to the destination number + } + } + } + + // Once we receive a newline, send the text. + Serial.println("Sending: \"" + message + "\" to " + destinationNumber); + // Call myModule.sendSMS(String number, String message) to send an SMS message. + if (myModule.sendSMS(destinationNumber, message) == UBX_CELL_SUCCESS) + { + Serial.println(F("sendSMS was successful")); + } +} \ No newline at end of file diff --git a/src/sfe_ublox_cellular.cpp b/src/sfe_ublox_cellular.cpp index 6d61078..7d95875 100644 --- a/src/sfe_ublox_cellular.cpp +++ b/src/sfe_ublox_cellular.cpp @@ -722,19 +722,37 @@ bool UBX_CELL::urcHandlerPingCommand(const char* event) if (*searchPtr != '\0') // Make sure we found a quote { + // Extract IP address int remoteIPstore[4]; - scanNum = sscanf(searchPtr, "\",\"%d.%d.%d.%d\",%d,%ld", - &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3], &ttl, &rtt); + scanNum = sscanf(searchPtr, "\",\"%d.%d.%d.%d", + &remoteIPstore[0], &remoteIPstore[1], &remoteIPstore[2], &remoteIPstore[3]); for (int i = 0; i <= 3; i++) { remoteIP[i] = (uint8_t)remoteIPstore[i]; } - if (scanNum == 6) // Make sure we extracted enough data + if (scanNum == 4) // Make sure we extracted enough data { - if (_pingRequestCallback != nullptr) + // Extract TTL, should be immediately after IP address + searchPtr = strchr(searchPtr + 2, ','); // +2 to skip the quote and comma + if(searchPtr != nullptr) { - _pingRequestCallback(retry, p_size, remote_host, remoteIP, ttl, rtt); + // It's possible the TTL is not present (eg. on LARA-R6), so we + // can ignore scanNum since ttl defaults to 0 anyways + scanNum = sscanf(searchPtr, ",%d", &ttl); + + // Extract RTT, should be immediately after TTL + searchPtr = strchr(searchPtr + 1, ','); // +1 to skip the comma + if(searchPtr != nullptr) + { + scanNum = sscanf(searchPtr, ",%ld", &rtt); + + // Callback, if it exists + if (_pingRequestCallback != nullptr) + { + _pingRequestCallback(retry, p_size, remote_host, remoteIP, ttl, rtt); + } + } } } }