Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a0d0ad3

Browse files
authoredJan 4, 2024
Merge pull request #20 from sparkfun/v1.0.0
V1.0.0
2 parents 5fd5fb4 + 4a096df commit a0d0ad3

20 files changed

+10040
-0
lines changed
 
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular_Voice myModule; // This example works with all voice-enabled modules, so this base class can be used
10+
// SparkFun_ublox_LARA_R6001 myModule;
11+
// SparkFun_ublox_LARA_R6401 myModule;
12+
// SparkFun_ublox_LARA_R6801_00B myModule;
13+
14+
void setup()
15+
{
16+
Serial.begin(115200); // Start the serial console
17+
18+
// Wait for user to press key to begin
19+
Serial.println(F("u-blox Cellular Audio Example 1 - Play Tone"));
20+
21+
Serial.println();
22+
Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !"));
23+
Serial.println(F("This example requires an audio codec attached to the I2S interface"));
24+
Serial.println(F("of the cellular modem. Please add one and update this example as"));
25+
Serial.println(F("needed to configure your audio codec!"));
26+
Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !"));
27+
Serial.println();
28+
29+
Serial.println(F("Press any key to begin"));
30+
31+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
32+
;
33+
while (Serial.available()) // Empty the serial RX buffer
34+
Serial.read();
35+
36+
Serial.println(F("Beginning..."));
37+
38+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
39+
40+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
41+
// Uncomment the next line if required
42+
// myModule.invertPowerPin(true);
43+
44+
// Initialize the module
45+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
46+
{
47+
Serial.println(F("Module connected!"));
48+
}
49+
else
50+
{
51+
Serial.println(F("Unable to communicate with the module."));
52+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
53+
while (1)
54+
; // Loop forever on fail
55+
}
56+
Serial.println();
57+
}
58+
59+
void loop()
60+
{
61+
String inputString;
62+
char dtmfChar = 0;
63+
uint16_t frequency = 0;
64+
uint16_t duration = 0;
65+
uint8_t volume = 0;
66+
67+
while (true)
68+
{
69+
while (Serial.available() != 0)
70+
{
71+
Serial.read();
72+
}
73+
Serial.println(F("Enter a frequency in Hz (300-3400) or a DTMF character (0-9, *, #)"));
74+
while (Serial.available() == 0)
75+
{
76+
}
77+
78+
inputString = Serial.readStringUntil('\n');
79+
80+
if (inputString.length() == 1)
81+
{
82+
dtmfChar = inputString.charAt(0);
83+
if ((dtmfChar >= '0' && dtmfChar <= '9') || dtmfChar == '*' || dtmfChar == '#')
84+
{
85+
break;
86+
}
87+
}
88+
else
89+
{
90+
frequency = inputString.toInt();
91+
if (frequency >= 300 && frequency <= 3400)
92+
{
93+
dtmfChar == 0;
94+
break;
95+
}
96+
}
97+
}
98+
99+
while (true)
100+
{
101+
while (Serial.available() != 0)
102+
{
103+
Serial.read();
104+
}
105+
Serial.println(F("Enter a duration in ms (50-1360)"));
106+
while (Serial.available() == 0)
107+
{
108+
}
109+
110+
inputString = Serial.readStringUntil('\n');
111+
duration = inputString.toInt();
112+
if (duration >= 50 && duration <= 1360)
113+
{
114+
break;
115+
}
116+
}
117+
118+
while (true)
119+
{
120+
while (Serial.available() != 0)
121+
{
122+
Serial.read();
123+
}
124+
Serial.println(F("Enter a volume (0-100)"));
125+
while (Serial.available() == 0)
126+
{
127+
}
128+
129+
inputString = Serial.readStringUntil('\n');
130+
volume = inputString.toInt();
131+
if (volume <= 100)
132+
{
133+
break;
134+
}
135+
}
136+
137+
if (dtmfChar == 0)
138+
{
139+
myModule.generateToneFreq(frequency, duration, volume);
140+
}
141+
else
142+
{
143+
myModule.generateToneDTMF(dtmfChar, duration, volume);
144+
}
145+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular_Voice myModule; // This example works with all voice-enabled modules, so this base class can be used
10+
// SparkFun_ublox_LARA_R6001 myModule;
11+
// SparkFun_ublox_LARA_R6401 myModule;
12+
// SparkFun_ublox_LARA_R6801_00B myModule;
13+
14+
void setup()
15+
{
16+
Serial.begin(115200); // Start the serial console
17+
18+
// Wait for user to press key to begin
19+
Serial.println(F("u-blox Cellular Audio Example 2 - Loopback"));
20+
21+
Serial.println();
22+
Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !"));
23+
Serial.println(F("This example requires an audio codec attached to the I2S interface"));
24+
Serial.println(F("of the cellular modem. Please add one and update this example as"));
25+
Serial.println(F("needed to configure your audio codec!"));
26+
Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !"));
27+
Serial.println();
28+
29+
Serial.println(F("Press any key to begin"));
30+
31+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
32+
;
33+
while (Serial.available()) // Empty the serial RX buffer
34+
Serial.read();
35+
36+
Serial.println(F("Beginning..."));
37+
38+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
39+
40+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
41+
// Uncomment the next line if required
42+
// myModule.invertPowerPin(true);
43+
44+
// Initialize the module
45+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
46+
{
47+
Serial.println(F("Module connected!"));
48+
}
49+
else
50+
{
51+
Serial.println(F("Unable to communicate with the module."));
52+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
53+
while (1)
54+
; // Loop forever on fail
55+
}
56+
Serial.println();
57+
}
58+
59+
void loop()
60+
{
61+
while (Serial.available() != 0)
62+
{
63+
Serial.read();
64+
}
65+
Serial.println(F("Enter any key to begin loopback"));
66+
while (Serial.available() == 0)
67+
{
68+
}
69+
70+
myModule.playAudioResource(UBX_CELL_AUDIO_RESOURCE_LOOPBACK);
71+
72+
while (Serial.available() != 0)
73+
{
74+
Serial.read();
75+
}
76+
Serial.println(F("Enter any key to stop loopback"));
77+
while (Serial.available() == 0)
78+
{
79+
}
80+
81+
myModule.stopAudioResource(UBX_CELL_AUDIO_RESOURCE_LOOPBACK);
82+
}
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular_Voice myModule; // This example works with all voice-enabled modules, so this base class can be used
10+
// SparkFun_ublox_LARA_R6001 myModule;
11+
// SparkFun_ublox_LARA_R6401 myModule;
12+
// SparkFun_ublox_LARA_R6801_00B myModule;
13+
14+
bool callInProgress = false;
15+
bool incomingCall = false;
16+
17+
void ringCallback()
18+
{
19+
Serial.println(F("Incoming call! Enter \"A\" to answer, or anything else to reject"));
20+
incomingCall = true;
21+
}
22+
23+
void setup()
24+
{
25+
String currentOperator = "";
26+
27+
Serial.begin(115200); // Start the serial console
28+
29+
// Wait for user to press key to begin
30+
Serial.println(F("u-blox Cellular Audio Example 3 - Call Control"));
31+
32+
Serial.println();
33+
Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !"));
34+
Serial.println(F("This example requires an audio codec attached to the I2S interface"));
35+
Serial.println(F("of the cellular modem. Please add one and update this example as"));
36+
Serial.println(F("needed to configure your audio codec!"));
37+
Serial.println(F("! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! ! ATTENTION ! ! ! ! !"));
38+
Serial.println();
39+
40+
Serial.println(F("Press any key to begin"));
41+
42+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
43+
;
44+
while (Serial.available()) // Empty the serial RX buffer
45+
Serial.read();
46+
47+
Serial.println(F("Beginning..."));
48+
49+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
50+
51+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
52+
// Uncomment the next line if required
53+
// myModule.invertPowerPin(true);
54+
55+
// Initialize the module
56+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
57+
{
58+
Serial.println(F("Module connected!"));
59+
}
60+
else
61+
{
62+
Serial.println(F("Unable to communicate with the module."));
63+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
64+
while (1)
65+
; // Loop forever on fail
66+
}
67+
Serial.println();
68+
69+
// First check to see if we're connected to an operator:
70+
if (myModule.getOperator(&currentOperator) == UBX_CELL_SUCCESS)
71+
{
72+
Serial.print(F("Connected to: "));
73+
Serial.println(currentOperator);
74+
}
75+
else
76+
{
77+
Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. "
78+
"Or wait and retry. Freezing..."));
79+
while (1)
80+
; // Do nothing more
81+
}
82+
83+
// Set callback function for when a new call is received
84+
myModule.setRingCallback(&ringCallback);
85+
86+
Serial.println(F("Enter a number to dial"));
87+
88+
// Clear any input
89+
while (Serial.available())
90+
{
91+
Serial.read();
92+
}
93+
}
94+
95+
void loop()
96+
{
97+
String inputString;
98+
99+
myModule.bufferedPoll();
100+
101+
if (Serial.available())
102+
{
103+
inputString = Serial.readStringUntil('\n');
104+
while (Serial.available())
105+
{
106+
Serial.read();
107+
}
108+
109+
if (incomingCall)
110+
{
111+
if (inputString == "A" || inputString == "a")
112+
{
113+
Serial.println(F("Answering call, enter any key to hang up"));
114+
myModule.answer();
115+
callInProgress = true;
116+
}
117+
else
118+
{
119+
Serial.println(F("Rejecting call"));
120+
myModule.hangUp();
121+
}
122+
incomingCall = false;
123+
}
124+
else if (callInProgress == false)
125+
{
126+
Serial.println("Dialing " + inputString + ", enter any key to hang up");
127+
myModule.dial(inputString);
128+
callInProgress = true;
129+
}
130+
else
131+
{
132+
Serial.println(F("Hanging up, enter a new number to dial"));
133+
myModule.hangUp();
134+
callInProgress = false;
135+
}
136+
}
137+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used
10+
// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class
11+
// SparkFun_ublox_SARA_R500S myModule;
12+
// SparkFun_ublox_SARA_R500S_01B myModule;
13+
// SparkFun_ublox_SARA_R500S_61B myModule;
14+
// SparkFun_ublox_SARA_R510M8S_61B myModule;
15+
// SparkFun_ublox_SARA_R510S myModule;
16+
// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class
17+
// SparkFun_ublox_LARA_R6001 myModule;
18+
// SparkFun_ublox_LARA_R6001D myModule;
19+
// SparkFun_ublox_LARA_R6401 myModule;
20+
// SparkFun_ublox_LARA_R6401D myModule;
21+
// SparkFun_ublox_LARA_R6801_00B myModule;
22+
// SparkFun_ublox_LARA_R6801D myModule;
23+
24+
// Map SIM states to more readable strings
25+
String simStateString[] = {
26+
"Not present", // 0
27+
"PIN needed", // 1
28+
"PIN blocked", // 2
29+
"PUK blocked", // 3
30+
"Not operational", // 4
31+
"Restricted", // 5
32+
"Operational" // 6
33+
};
34+
35+
// processSIMstate is provided to the u-blox cellular library via a
36+
// callback setter -- setSIMstateReadCallback. (See setup())
37+
void processSIMstate(UBX_CELL_sim_states_t state)
38+
{
39+
Serial.println();
40+
Serial.print(F("SIM state: "));
41+
Serial.print(String(state));
42+
Serial.println();
43+
}
44+
45+
void setup()
46+
{
47+
Serial.begin(115200); // Start the serial console
48+
49+
// Wait for user to press key to begin
50+
Serial.println(F("u-blox Cellular Example 1 - Device Identification"));
51+
Serial.println(F("Press any key to begin"));
52+
53+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
54+
;
55+
while (Serial.available()) // Empty the serial RX buffer
56+
Serial.read();
57+
58+
Serial.println(F("Beginning..."));
59+
60+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
61+
62+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
63+
// Uncomment the next line if required
64+
// myModule.invertPowerPin(true);
65+
66+
// Initialize the module
67+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
68+
{
69+
Serial.println(F("Module connected!"));
70+
}
71+
else
72+
{
73+
Serial.println(F("Unable to communicate with the module."));
74+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
75+
while (1)
76+
; // Loop forever on fail
77+
}
78+
Serial.println();
79+
80+
Serial.println("Manufacturer ID: " + String(myModule.getManufacturerID()));
81+
Serial.println("Model ID: " + String(myModule.getModelID()));
82+
Serial.println("Firmware Version: " + String(myModule.getFirmwareVersion()));
83+
Serial.println("Product Serial No.: " + String(myModule.getSerialNo()));
84+
Serial.println("IMEI: " + String(myModule.getIMEI()));
85+
Serial.println("IMSI: " + String(myModule.getIMSI()));
86+
Serial.println("SIM CCID: " + String(myModule.getCCID()));
87+
Serial.println("Subscriber No.: " + String(myModule.getSubscriberNo()));
88+
Serial.println("Capabilities: " + String(myModule.getCapabilities()));
89+
90+
// Set a callback to return the SIM state once requested
91+
myModule.setSIMstateReportCallback(&processSIMstate);
92+
// Now enable SIM state reporting for states 0 to 6 (by setting the reporting mode LSb)
93+
if (myModule.setSIMstateReportingMode(1) == UBX_CELL_SUCCESS)
94+
Serial.println("SIM state reports requested...");
95+
// You can disable the SIM staus reports again by calling assetTracker.setSIMstateReportingMode(0)
96+
}
97+
98+
void loop()
99+
{
100+
myModule.poll(); // Keep processing data from the module so we can extract the SIM status
101+
}
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used
10+
// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class
11+
// SparkFun_ublox_SARA_R500S myModule;
12+
// SparkFun_ublox_SARA_R500S_01B myModule;
13+
// SparkFun_ublox_SARA_R500S_61B myModule;
14+
// SparkFun_ublox_SARA_R510M8S_61B myModule;
15+
// SparkFun_ublox_SARA_R510S myModule;
16+
// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class
17+
// SparkFun_ublox_LARA_R6001 myModule;
18+
// SparkFun_ublox_LARA_R6001D myModule;
19+
// SparkFun_ublox_LARA_R6401 myModule;
20+
// SparkFun_ublox_LARA_R6401D myModule;
21+
// SparkFun_ublox_LARA_R6801_00B myModule;
22+
// SparkFun_ublox_LARA_R6801D myModule;
23+
24+
// Map registration status messages to more readable strings
25+
String registrationString[] = {
26+
"Not registered", // 0
27+
"Registered, home", // 1
28+
"Searching for operator", // 2
29+
"Registration denied", // 3
30+
"Registration unknown", // 4
31+
"Registered, roaming", // 5
32+
"Registered, home (SMS only)", // 6
33+
"Registered, roaming (SMS only)", // 7
34+
"Registered, emergency service only", // 8
35+
"Registered, home, CSFB not preferred", // 9
36+
"Registered, roaming, CSFB not prefered" // 10
37+
};
38+
39+
// If you are based in Europe, you will (probably) need to select MNO_STD_EUROPE
40+
const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL;
41+
42+
void setup()
43+
{
44+
Serial.begin(115200); // Start the serial console
45+
46+
// Wait for user to press key to begin
47+
Serial.println(F("u-blox Cellular Example 2 - Network Info"));
48+
Serial.println(F("Press any key to begin"));
49+
50+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
51+
;
52+
while (Serial.available()) // Empty the serial RX buffer
53+
Serial.read();
54+
55+
Serial.println(F("Beginning..."));
56+
57+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
58+
59+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
60+
// Uncomment the next line if required
61+
// myModule.invertPowerPin(true);
62+
63+
// Initialize the module
64+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
65+
{
66+
Serial.println(F("Module connected!"));
67+
}
68+
else
69+
{
70+
Serial.println(F("Unable to communicate with the module."));
71+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
72+
while (1)
73+
; // Loop forever on fail
74+
}
75+
Serial.println();
76+
77+
if (!myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR))
78+
{
79+
Serial.println(F("Error setting network. Try cycling the power."));
80+
while (1)
81+
;
82+
}
83+
84+
Serial.println(F("Network profile set. Ready to go!"));
85+
86+
// RSSI: Received signal strength:
87+
Serial.println("RSSI: " + String(myModule.rssi()));
88+
// Registration Status
89+
int regStatus = myModule.registration();
90+
if ((regStatus >= 0) && (regStatus <= 10))
91+
{
92+
Serial.println("Network registration: " + registrationString[regStatus]);
93+
}
94+
95+
// Print the Context IDs, Access Point Names and IP Addresses
96+
Serial.println(F("Available PDP (Packet Data Protocol) APNs (Access Point Names) and IP Addresses:"));
97+
Serial.println(F("Context ID:\tAPN Name:\tIP Address:"));
98+
for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++)
99+
{
100+
String apn = "";
101+
IPAddress ip(0, 0, 0, 0);
102+
myModule.getAPN(cid, &apn, &ip);
103+
if (apn.length() > 0)
104+
{
105+
Serial.print(cid);
106+
Serial.print(F("\t\t"));
107+
Serial.print(apn);
108+
Serial.print(F("\t"));
109+
Serial.println(ip);
110+
}
111+
}
112+
113+
Serial.println();
114+
115+
if (regStatus > 0)
116+
{
117+
Serial.println(F("All set. Go to the next example!"));
118+
}
119+
}
120+
121+
void loop()
122+
{
123+
// Do nothing. Now that we're registered move on to the next example.
124+
}
Lines changed: 359 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,359 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used
10+
// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class
11+
// SparkFun_ublox_SARA_R500S myModule;
12+
// SparkFun_ublox_SARA_R500S_01B myModule;
13+
// SparkFun_ublox_SARA_R500S_61B myModule;
14+
// SparkFun_ublox_SARA_R510M8S_61B myModule;
15+
// SparkFun_ublox_SARA_R510S myModule;
16+
// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class
17+
// SparkFun_ublox_LARA_R6001 myModule;
18+
// SparkFun_ublox_LARA_R6001D myModule;
19+
// SparkFun_ublox_LARA_R6401 myModule;
20+
// SparkFun_ublox_LARA_R6401D myModule;
21+
// SparkFun_ublox_LARA_R6801_00B myModule;
22+
// SparkFun_ublox_LARA_R6801D myModule;
23+
24+
// Map registration status messages to more readable strings
25+
String registrationString[] = {
26+
"Not registered", // 0
27+
"Registered, home", // 1
28+
"Searching for operator", // 2
29+
"Registration denied", // 3
30+
"Registration unknown", // 4
31+
"Registered, roaming", // 5
32+
"Registered, home (SMS only)", // 6
33+
"Registered, roaming (SMS only)", // 7
34+
"Registered, emergency service only", // 8
35+
"Registered, home, CSFB not preferred", // 9
36+
"Registered, roaming, CSFB not prefered" // 10
37+
};
38+
39+
// If you are based in Europe, you will (probably) need to select MNO_STD_EUROPE
40+
const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_GLOBAL;
41+
42+
const String MOBILE_NETWORK_STRINGS[] = {"default (Undefined/Regulatory)",
43+
"SIM ICCID",
44+
"AT&T",
45+
"Verizon",
46+
"Telstra",
47+
"T-Mobile US",
48+
"China Telecom",
49+
"Sprint",
50+
"Vodafone",
51+
"NTT DoCoMo",
52+
"Telus",
53+
"SoftBank",
54+
"Deutsche Telekom",
55+
"US Cellular",
56+
"SKT",
57+
"global (factory default)",
58+
"standard Europe",
59+
"standard Europe No-ePCO",
60+
"NOT RECOGNIZED"};
61+
62+
// Convert the operator number into an index for MOBILE_NETWORK_STRINGS
63+
int convertOperatorNumber(mobile_network_operator_t mno)
64+
{
65+
switch (mno)
66+
{
67+
case 0:
68+
case 1:
69+
case 2:
70+
case 3:
71+
case 4:
72+
case 5:
73+
case 6:
74+
return ((int)mno);
75+
case 8:
76+
return 7;
77+
case 19:
78+
return 8;
79+
case 20:
80+
return 9;
81+
case 21:
82+
return 10;
83+
case 28:
84+
return 11;
85+
case 31:
86+
return 12;
87+
case 32:
88+
return 13;
89+
case 39:
90+
return 14;
91+
case 90:
92+
return 15;
93+
case 100:
94+
return 16;
95+
case 101:
96+
return 17;
97+
default: // NOT RECOGNIZED
98+
return 18;
99+
}
100+
}
101+
102+
// This defines the size of the ops struct array. To narrow the operator
103+
// list, set MOBILE_NETWORK_OPERATOR to AT&T, Verizon etc. instead
104+
// of MNO_SW_DEFAULT.
105+
#define MAX_OPERATORS 10
106+
107+
// Uncomment this line if you want to be able to communicate directly with the module in the main loop
108+
// #define DEBUG_PASSTHROUGH_ENABLED
109+
110+
void setup()
111+
{
112+
int opsAvailable;
113+
struct operator_stats ops[MAX_OPERATORS];
114+
String currentOperator = "";
115+
bool newConnection = true;
116+
117+
Serial.begin(115200); // Start the serial console
118+
119+
// Wait for user to press key to begin
120+
Serial.println(F("u-blox Cellular Example 3 - Register Operator"));
121+
Serial.println(F("Press any key to begin"));
122+
123+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
124+
;
125+
while (Serial.available()) // Empty the serial RX buffer
126+
Serial.read();
127+
128+
Serial.println(F("Beginning..."));
129+
130+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
131+
132+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
133+
// Uncomment the next line if required
134+
// myModule.invertPowerPin(true);
135+
136+
// Initialize the module
137+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
138+
{
139+
Serial.println(F("Module connected!"));
140+
}
141+
else
142+
{
143+
Serial.println(F("Unable to communicate with the module."));
144+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
145+
while (1)
146+
; // Loop forever on fail
147+
}
148+
Serial.println();
149+
150+
// First check to see if we're already connected to an operator:
151+
if (myModule.getOperator(&currentOperator) == UBX_CELL_SUCCESS)
152+
{
153+
Serial.print(F("Already connected to: "));
154+
Serial.println(currentOperator);
155+
// If already connected provide the option to type y to connect to new operator
156+
Serial.println(F("Press y to connect to a new operator, or any other key to continue.\r\n"));
157+
while (!Serial.available())
158+
;
159+
if (Serial.read() != 'y')
160+
{
161+
newConnection = false;
162+
}
163+
else
164+
{
165+
myModule.deregisterOperator(); // Deregister from the current operator so we can connect to a new one
166+
}
167+
while (Serial.available())
168+
Serial.read();
169+
}
170+
171+
if (newConnection)
172+
{
173+
// Set MNO to either Verizon, T-Mobile, AT&T, Telstra, etc.
174+
// This will narrow the operator options during our scan later
175+
Serial.println(F("Setting mobile-network operator"));
176+
if (myModule.setNetworkProfile(MOBILE_NETWORK_OPERATOR))
177+
{
178+
Serial.print(F("Set mobile network operator to "));
179+
Serial.println(MOBILE_NETWORK_STRINGS[convertOperatorNumber(MOBILE_NETWORK_OPERATOR)] + "\r\n");
180+
}
181+
else
182+
{
183+
Serial.println(F("Error setting MNO. Try cycling the power. Freezing..."));
184+
while (1)
185+
;
186+
}
187+
188+
// Wait for user to press button before initiating network scan.
189+
Serial.println(F("Press any key scan for networks.."));
190+
serialWait();
191+
192+
Serial.println(F("Scanning for networks...this may take up to 3 minutes\r\n"));
193+
// myModule.getOperators takes in a operator_stats struct pointer and max number of
194+
// structs to scan for, then fills up those objects with operator names and numbers
195+
opsAvailable = myModule.getOperators(ops, MAX_OPERATORS); // This will block for up to 3 minutes
196+
197+
if (opsAvailable > 0)
198+
{
199+
// Pretty-print operators we found:
200+
Serial.println("Found " + String(opsAvailable) + " operators:");
201+
printOperators(ops, opsAvailable);
202+
Serial.println(String(opsAvailable + 1) + ": use automatic selection");
203+
Serial.println();
204+
205+
// Wait until the user presses a key to initiate an operator connection
206+
Serial.println("Press 1-" + String(opsAvailable + 1) + " to select an operator.");
207+
char c = 0;
208+
bool selected = false;
209+
while (!selected)
210+
{
211+
while (!Serial.available())
212+
;
213+
c = Serial.read();
214+
int selection = c - '0';
215+
if ((selection >= 1) && (selection <= (opsAvailable + 1)))
216+
{
217+
selected = true;
218+
Serial.println("Connecting to option " + String(selection));
219+
if (selection == (opsAvailable + 1))
220+
{
221+
if (myModule.automaticOperatorSelection() == UBX_CELL_SUCCESS)
222+
{
223+
Serial.println("Automatic operator selection: successful\r\n");
224+
}
225+
else
226+
{
227+
Serial.println(
228+
F("Automatic operator selection: error. Reset and try again, or try another network."));
229+
}
230+
}
231+
else
232+
{
233+
if (myModule.registerOperator(ops[selection - 1]) == UBX_CELL_SUCCESS)
234+
{
235+
Serial.println("Network " + ops[selection - 1].longOp + " registered\r\n");
236+
}
237+
else
238+
{
239+
Serial.println(
240+
F("Error connecting to operator. Reset and try again, or try another network."));
241+
}
242+
}
243+
}
244+
}
245+
}
246+
else
247+
{
248+
Serial.println(F("Did not find an operator. Double-check SIM and antenna, reset and try again, or try "
249+
"another network."));
250+
while (1)
251+
;
252+
}
253+
}
254+
255+
// At the very end print connection information
256+
printInfo();
257+
}
258+
259+
void loop()
260+
{
261+
// Loop provides a debugging interface.
262+
if (mySerial.available())
263+
{
264+
Serial.write((char)mySerial.read());
265+
}
266+
#ifdef DEBUG_PASSTHROUGH_ENABLED
267+
if (Serial.available())
268+
{
269+
mySerial.write((char)Serial.read());
270+
}
271+
#endif
272+
}
273+
274+
void printInfo(void)
275+
{
276+
String currentApn = "";
277+
IPAddress ip(0, 0, 0, 0);
278+
String currentOperator = "";
279+
280+
Serial.println(F("Connection info:"));
281+
Serial.println(F("Context ID:\tAPN Name:\tIP Address:"));
282+
for (int cid = 0; cid < UBX_CELL_NUM_PDP_CONTEXT_IDENTIFIERS; cid++)
283+
{
284+
String apn = "";
285+
IPAddress ip(0, 0, 0, 0);
286+
myModule.getAPN(cid, &apn, &ip);
287+
if (apn.length() > 0)
288+
{
289+
Serial.print(cid);
290+
Serial.print(F("\t\t"));
291+
Serial.print(apn);
292+
Serial.print(F("\t"));
293+
Serial.println(ip);
294+
}
295+
}
296+
297+
// Operator name or number
298+
if (myModule.getOperator(&currentOperator) == UBX_CELL_SUCCESS)
299+
{
300+
Serial.print(F("Operator: "));
301+
Serial.println(currentOperator);
302+
}
303+
304+
// Received signal strength
305+
Serial.println("RSSI: " + String(myModule.rssi()));
306+
Serial.println();
307+
}
308+
309+
void printOperators(struct operator_stats *ops, int operatorsAvailable)
310+
{
311+
for (int i = 0; i < operatorsAvailable; i++)
312+
{
313+
Serial.print(String(i + 1) + ": ");
314+
Serial.print(ops[i].longOp + " (" + String(ops[i].numOp) + ") - ");
315+
switch (ops[i].stat)
316+
{
317+
case 0:
318+
Serial.print(F("UNKNOWN"));
319+
break;
320+
case 1:
321+
Serial.print(F("AVAILABLE"));
322+
break;
323+
case 2:
324+
Serial.print(F("CURRENT"));
325+
break;
326+
case 3:
327+
Serial.print(F("FORBIDDEN"));
328+
break;
329+
}
330+
switch (ops[i].act)
331+
{
332+
case 0:
333+
Serial.print(F(" - GSM"));
334+
break;
335+
case 2:
336+
Serial.print(F(" - UTRAN"));
337+
break;
338+
case 3:
339+
Serial.print(F(" - GSM/GPRS with EDGE"));
340+
break;
341+
case 7:
342+
Serial.print(F(" - LTE")); // SARA-R5 only supports LTE
343+
break;
344+
}
345+
Serial.println();
346+
}
347+
Serial.println();
348+
}
349+
350+
void serialWait()
351+
{
352+
while (Serial.available())
353+
Serial.read();
354+
while (!Serial.available())
355+
;
356+
delay(100);
357+
while (Serial.available())
358+
Serial.read();
359+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used
10+
// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class
11+
// SparkFun_ublox_SARA_R500S myModule;
12+
// SparkFun_ublox_SARA_R500S_01B myModule;
13+
// SparkFun_ublox_SARA_R500S_61B myModule;
14+
// SparkFun_ublox_SARA_R510M8S_61B myModule;
15+
// SparkFun_ublox_SARA_R510S myModule;
16+
// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class
17+
// SparkFun_ublox_LARA_R6001 myModule;
18+
// SparkFun_ublox_LARA_R6001D myModule;
19+
// SparkFun_ublox_LARA_R6401 myModule;
20+
// SparkFun_ublox_LARA_R6401D myModule;
21+
// SparkFun_ublox_LARA_R6801_00B myModule;
22+
// SparkFun_ublox_LARA_R6801D myModule;
23+
24+
void setup()
25+
{
26+
String currentOperator = "";
27+
28+
Serial.begin(115200); // Start the serial console
29+
30+
// Wait for user to press key to begin
31+
Serial.println(F("u-blox Cellular Example 4 - Clock"));
32+
Serial.println(F("Press any key to begin"));
33+
34+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
35+
;
36+
while (Serial.available()) // Empty the serial RX buffer
37+
Serial.read();
38+
39+
Serial.println(F("Beginning..."));
40+
41+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
42+
43+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
44+
// Uncomment the next line if required
45+
// myModule.invertPowerPin(true);
46+
47+
// Initialize the module
48+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
49+
{
50+
Serial.println(F("Module connected!"));
51+
}
52+
else
53+
{
54+
Serial.println(F("Unable to communicate with the module."));
55+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
56+
while (1)
57+
; // Loop forever on fail
58+
}
59+
Serial.println();
60+
61+
// Make sure automatic time zone updates are enabled
62+
if (myModule.autoTimeZone(true) != UBX_CELL_SUCCESS)
63+
Serial.println(F("Enable autoTimeZone failed!"));
64+
65+
// Read and print the clock as a String
66+
String theTime = myModule.clock();
67+
Serial.println(theTime);
68+
69+
// Read and print the hour, minute, etc. separately
70+
uint8_t year, month, day, hour, minute, second;
71+
int8_t timeZone;
72+
if (myModule.clock(&year, &month, &day, &hour, &minute, &second, &timeZone) == UBX_CELL_SUCCESS)
73+
// Note: not all Arduino boards implement printf correctly. The formatting may not be correct on some boards.
74+
// Note: the timeZone is defined in 15 minute increments, not hours. -28 indicates the time zone is 7 hours
75+
// behind UTC/GMT.
76+
Serial.printf("%02d/%02d/%02d %02d:%02d:%02d %+d\r\n", year, month, day, hour, minute, second, timeZone);
77+
}
78+
79+
void loop()
80+
{
81+
// Nothing to do here
82+
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used
10+
// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class
11+
// SparkFun_ublox_SARA_R500S myModule;
12+
// SparkFun_ublox_SARA_R500S_01B myModule;
13+
// SparkFun_ublox_SARA_R500S_61B myModule;
14+
// SparkFun_ublox_SARA_R510M8S_61B myModule;
15+
// SparkFun_ublox_SARA_R510S myModule;
16+
// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class
17+
// SparkFun_ublox_LARA_R6001 myModule;
18+
// SparkFun_ublox_LARA_R6001D myModule;
19+
// SparkFun_ublox_LARA_R6401 myModule;
20+
// SparkFun_ublox_LARA_R6401D myModule;
21+
// SparkFun_ublox_LARA_R6801_00B myModule;
22+
// SparkFun_ublox_LARA_R6801D myModule;
23+
24+
String pingMe = ""; // The name of the server we are going to ping
25+
26+
// processPingResult is provided to the u-blox cellular library via a
27+
// callback setter -- setPingCallback. (See the end of setup())
28+
void processPingResult(int retry, int p_size, String remote_hostname, IPAddress ip, int ttl, long rtt)
29+
{
30+
Serial.println();
31+
Serial.print(F("Ping Result: Retry #:"));
32+
Serial.print(retry);
33+
Serial.print(F(" Ping Size (Bytes):"));
34+
Serial.print(p_size);
35+
Serial.print(F(" Remote Host:\""));
36+
Serial.print(remote_hostname);
37+
Serial.print(F("\" IP Address:\""));
38+
Serial.print(String(ip[0]));
39+
Serial.print(F("."));
40+
Serial.print(String(ip[1]));
41+
Serial.print(F("."));
42+
Serial.print(String(ip[2]));
43+
Serial.print(F("."));
44+
Serial.print(String(ip[3]));
45+
Serial.print(F("\" Time To Live (hops):"));
46+
Serial.print(ttl);
47+
Serial.print(F(" Round Trip (ms):"));
48+
Serial.print(rtt);
49+
Serial.println();
50+
}
51+
52+
void setup()
53+
{
54+
String currentOperator = "";
55+
56+
Serial.begin(115200); // Start the serial console
57+
58+
// Wait for user to press key to begin
59+
Serial.println(F("u-blox Cellular Example 5 - Ping"));
60+
Serial.println(F("Press any key to begin"));
61+
62+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
63+
;
64+
while (Serial.available()) // Empty the serial RX buffer
65+
Serial.read();
66+
67+
Serial.println(F("Beginning..."));
68+
69+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
70+
71+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
72+
// Uncomment the next line if required
73+
// myModule.invertPowerPin(true);
74+
75+
// Initialize the module
76+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
77+
{
78+
Serial.println(F("Module connected!"));
79+
}
80+
else
81+
{
82+
Serial.println(F("Unable to communicate with the module."));
83+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
84+
while (1)
85+
; // Loop forever on fail
86+
}
87+
Serial.println();
88+
89+
// First check to see if we're connected to an operator:
90+
if (myModule.getOperator(&currentOperator) == UBX_CELL_SUCCESS)
91+
{
92+
Serial.print(F("Connected to: "));
93+
Serial.println(currentOperator);
94+
}
95+
else
96+
{
97+
Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. "
98+
"Or wait and retry. Freezing..."));
99+
while (1)
100+
; // Do nothing more
101+
}
102+
103+
Serial.println();
104+
Serial.println(F("*** Set the Serial Monitor line ending to Newline ***"));
105+
106+
Serial.println();
107+
Serial.println(F("Enter the name of the server you want to ping (followed by LF / Newline): "));
108+
Serial.println(F("Example: \"www.google.com\""));
109+
110+
// Set a callback to process the Ping result
111+
myModule.setPingCallback(&processPingResult);
112+
}
113+
114+
void loop()
115+
{
116+
if (Serial.available())
117+
{
118+
char c = Serial.read();
119+
if (c == '\n')
120+
{
121+
// Newline received so let's do that ping!
122+
Serial.println("Pinging " + pingMe + "...");
123+
myModule.ping(pingMe); // Use the default parameters
124+
125+
// Use custom parameters
126+
// int retries = 4; // number of retries
127+
// int p_size = 32; // packet size (bytes)
128+
// unsigned long timeout = 5000; // timeout (ms)
129+
// int ttl = 32; // Time To Live
130+
// myModule.ping(pingMe, retries, p_size, timeout, ttl);
131+
132+
pingMe = ""; // Clear the server name for the next try
133+
}
134+
else
135+
{
136+
// Add serial characters to the server address
137+
pingMe += c;
138+
}
139+
}
140+
141+
myModule.poll(); // Keep processing data from the module so we can catch the Ping result
142+
}
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used
10+
// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class
11+
// SparkFun_ublox_SARA_R500S myModule;
12+
// SparkFun_ublox_SARA_R500S_01B myModule;
13+
// SparkFun_ublox_SARA_R500S_61B myModule;
14+
// SparkFun_ublox_SARA_R510M8S_61B myModule;
15+
// SparkFun_ublox_SARA_R510S myModule;
16+
// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class
17+
// SparkFun_ublox_LARA_R6001 myModule;
18+
// SparkFun_ublox_LARA_R6001D myModule;
19+
// SparkFun_ublox_LARA_R6401 myModule;
20+
// SparkFun_ublox_LARA_R6401D myModule;
21+
// SparkFun_ublox_LARA_R6801_00B myModule;
22+
// SparkFun_ublox_LARA_R6801D myModule;
23+
24+
void setup()
25+
{
26+
String currentOperator = "";
27+
28+
Serial.begin(115200); // Start the serial console
29+
30+
// Wait for user to press key to begin
31+
Serial.println(F("u-blox Cellular Example 6 - Receive SMS"));
32+
Serial.println(F("Press any key to begin"));
33+
34+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
35+
;
36+
while (Serial.available()) // Empty the serial RX buffer
37+
Serial.read();
38+
39+
Serial.println(F("Beginning..."));
40+
41+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
42+
43+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
44+
// Uncomment the next line if required
45+
// myModule.invertPowerPin(true);
46+
47+
// Initialize the module
48+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
49+
{
50+
Serial.println(F("Module connected!"));
51+
}
52+
else
53+
{
54+
Serial.println(F("Unable to communicate with the module."));
55+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
56+
while (1)
57+
; // Loop forever on fail
58+
}
59+
Serial.println();
60+
61+
// First check to see if we're connected to an operator:
62+
if (myModule.getOperator(&currentOperator) == UBX_CELL_SUCCESS)
63+
{
64+
Serial.print(F("Connected to: "));
65+
Serial.println(currentOperator);
66+
}
67+
else
68+
{
69+
Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. "
70+
"Or wait and retry. Freezing..."));
71+
while (1)
72+
; // Do nothing more
73+
}
74+
75+
while (Serial.available()) // Empty the serial RX buffer
76+
Serial.read();
77+
}
78+
79+
void loop()
80+
{
81+
static bool printReadMessages =
82+
true; // Print all messages once. Then only print new messages. Unless a message is deleted.
83+
static int previousUsed = -1; // Store the previous number of used memory locations
84+
85+
// Read the number of used and total messages
86+
int used;
87+
int total;
88+
if (myModule.getPreferredMessageStorage(&used, &total) != UBX_CELL_SUCCESS)
89+
{
90+
Serial.println(F("An error occurred when trying to read ME memory!"));
91+
}
92+
else
93+
{
94+
if ((used != previousUsed) || printReadMessages) // Has a new message arrived? Or was the delete menu opened?
95+
{
96+
Serial.print(F("\r\nNumber of used memory locations: "));
97+
Serial.println(used);
98+
Serial.print(F("Total number of memory locations: "));
99+
Serial.println(total);
100+
Serial.println();
101+
102+
int memoryLocation = 0;
103+
int foundMessages = 0;
104+
// Keep reading until we find all the messages or we reach the end of the memory
105+
while ((foundMessages < used) && (memoryLocation <= total))
106+
{
107+
String unread = "";
108+
String from = "";
109+
String dateTime = "";
110+
String message = "";
111+
// Read the message from this location. Reading from empty message locations returns an ERROR
112+
// unread can be: "REC UNREAD", "REC READ", "STO UNSENT", "STO SENT"
113+
// If the location is empty, readSMSmessage will return a UBX_CELL_ERROR_UNEXPECTED_RESPONSE
114+
if (myModule.readSMSmessage(memoryLocation, &unread, &from, &dateTime, &message) == UBX_CELL_SUCCESS)
115+
{
116+
if (printReadMessages || (unread == "REC UNREAD"))
117+
{
118+
Serial.print(F("Message location: "));
119+
Serial.println(memoryLocation);
120+
Serial.print(F("Status: "));
121+
Serial.println(unread);
122+
Serial.print(F("Originator: "));
123+
Serial.println(from);
124+
Serial.print(F("Date and time: "));
125+
Serial.println(dateTime);
126+
Serial.println(message);
127+
Serial.println();
128+
}
129+
foundMessages++; // We found a message
130+
}
131+
memoryLocation++; // Move on to the next memory location
132+
}
133+
134+
printReadMessages = false;
135+
previousUsed = used; // Update previousUsed
136+
137+
Serial.println(F("Waiting for a new message..."));
138+
Serial.println();
139+
Serial.println(F("Hit any key to delete a message..."));
140+
Serial.println();
141+
}
142+
}
143+
144+
int delayCount = 0;
145+
while (delayCount < 5000)
146+
{
147+
delay(1); // Delay for five seconds, unless the user presses a key
148+
delayCount++;
149+
150+
if (Serial.available())
151+
{
152+
Serial.println(
153+
F("To delete a single message: enter its location followed by LF / Newline"));
154+
Serial.println(F("To delete all read messages: enter r followed by LF / Newline"));
155+
Serial.println(F("To delete all read and sent messages: enter s followed by LF / Newline"));
156+
Serial.println(F("To delete all read, sent and unsent messages: enter u followed by LF / Newline"));
157+
Serial.println(F("To delete all messages, including unread messages: enter a followed by LF / Newline"));
158+
Serial.println(F("To exit: enter LF / Newline"));
159+
160+
Serial.read(); // Read and discard the char that opened the menu
161+
162+
int location = 0;
163+
bool selected = false;
164+
while (!selected)
165+
{
166+
while (!Serial.available())
167+
; // Wait for a character to arrive
168+
char c = Serial.read(); // Read it
169+
if (c == '\n') // Is it a LF?
170+
{
171+
if ((location >= 1) && (location <= total)) // Delete a single message at location
172+
{
173+
if (myModule.deleteSMSmessage(location) == UBX_CELL_SUCCESS)
174+
{
175+
Serial.println(F("\r\nMessage deleted!\r\n"));
176+
printReadMessages = true;
177+
}
178+
else
179+
{
180+
Serial.println(F("\r\nMessage not deleted!\r\n"));
181+
}
182+
}
183+
else if (location == 1001) // r
184+
{
185+
if (myModule.deleteReadSMSmessages() == UBX_CELL_SUCCESS)
186+
{
187+
Serial.println(F("\r\nRead messages deleted!\r\n"));
188+
printReadMessages = true;
189+
}
190+
else
191+
{
192+
Serial.println(F("\r\nMessages not deleted!\r\n"));
193+
}
194+
}
195+
else if (location == 1002) // s
196+
{
197+
if (myModule.deleteReadSentSMSmessages() == UBX_CELL_SUCCESS)
198+
{
199+
Serial.println(F("\r\nRead and sent messages deleted!\r\n"));
200+
printReadMessages = true;
201+
}
202+
else
203+
{
204+
Serial.println(F("\r\nMessages not deleted!\r\n"));
205+
}
206+
}
207+
else if (location == 1003) // u
208+
{
209+
if (myModule.deleteReadSentUnsentSMSmessages() == UBX_CELL_SUCCESS)
210+
{
211+
Serial.println(F("\r\nRead, sent and unsent messages deleted!\r\n"));
212+
printReadMessages = true;
213+
}
214+
else
215+
{
216+
Serial.println(F("\r\nMessages not deleted!\r\n"));
217+
}
218+
}
219+
else if (location == 1004) // a
220+
{
221+
if (myModule.deleteAllSMSmessages() == UBX_CELL_SUCCESS)
222+
{
223+
Serial.println(F("\r\nAll messages deleted!\r\n"));
224+
printReadMessages = true;
225+
}
226+
else
227+
{
228+
Serial.println(F("\r\nMessages not deleted!\r\n"));
229+
}
230+
}
231+
else
232+
Serial.println(F("\r\nExit...\r\n"));
233+
selected = true;
234+
}
235+
else if ((c >= '0') && (c <= '9'))
236+
{
237+
location *= 10; // Multiply by 10
238+
location += c - '0'; // Add the digit
239+
}
240+
else if (c == 'r')
241+
{
242+
location = 1001;
243+
}
244+
else if (c == 's')
245+
{
246+
location = 1002;
247+
}
248+
else if (c == 'u')
249+
{
250+
location = 1003;
251+
}
252+
else if (c == 'a')
253+
{
254+
location = 1004;
255+
}
256+
}
257+
258+
delayCount = 5000;
259+
}
260+
}
261+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used
10+
// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class
11+
// SparkFun_ublox_SARA_R500S myModule;
12+
// SparkFun_ublox_SARA_R500S_01B myModule;
13+
// SparkFun_ublox_SARA_R500S_61B myModule;
14+
// SparkFun_ublox_SARA_R510M8S_61B myModule;
15+
// SparkFun_ublox_SARA_R510S myModule;
16+
// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class
17+
// SparkFun_ublox_LARA_R6001 myModule;
18+
// SparkFun_ublox_LARA_R6001D myModule;
19+
// SparkFun_ublox_LARA_R6401 myModule;
20+
// SparkFun_ublox_LARA_R6401D myModule;
21+
// SparkFun_ublox_LARA_R6801_00B myModule;
22+
// SparkFun_ublox_LARA_R6801D myModule;
23+
24+
void setup()
25+
{
26+
String currentOperator = "";
27+
28+
Serial.begin(115200); // Start the serial console
29+
30+
// Wait for user to press key to begin
31+
Serial.println(F("u-blox Cellular Example 7 - Send SMS"));
32+
Serial.println(F("Press any key to begin"));
33+
34+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
35+
;
36+
while (Serial.available()) // Empty the serial RX buffer
37+
Serial.read();
38+
39+
Serial.println(F("Beginning..."));
40+
41+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
42+
43+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
44+
// Uncomment the next line if required
45+
// myModule.invertPowerPin(true);
46+
47+
// Initialize the module
48+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
49+
{
50+
Serial.println(F("Module connected!"));
51+
}
52+
else
53+
{
54+
Serial.println(F("Unable to communicate with the module."));
55+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
56+
while (1)
57+
; // Loop forever on fail
58+
}
59+
Serial.println();
60+
61+
// First check to see if we're connected to an operator:
62+
if (myModule.getOperator(&currentOperator) == UBX_CELL_SUCCESS)
63+
{
64+
Serial.print(F("Connected to: "));
65+
Serial.println(currentOperator);
66+
}
67+
else
68+
{
69+
Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. "
70+
"Or wait and retry. Freezing..."));
71+
while (1)
72+
; // Do nothing more
73+
}
74+
75+
Serial.println();
76+
Serial.println(F("*** Set the Serial Monitor line ending to Newline ***"));
77+
}
78+
79+
void loop()
80+
{
81+
String destinationNumber = "";
82+
String message = "";
83+
boolean keepGoing = true;
84+
85+
Serial.println();
86+
Serial.println(F("Enter the destination number (followed by LF / Newline): "));
87+
88+
while (keepGoing)
89+
{
90+
if (Serial.available())
91+
{
92+
char c = Serial.read();
93+
if (c == '\n')
94+
{
95+
keepGoing = false; // Stop if we receive a newline
96+
}
97+
else
98+
{
99+
destinationNumber += c; // Add serial characters to the destination number
100+
}
101+
}
102+
}
103+
104+
keepGoing = true;
105+
Serial.println();
106+
Serial.println(F("Enter the message (followed by LF): "));
107+
108+
while (keepGoing)
109+
{
110+
if (Serial.available())
111+
{
112+
char c = Serial.read();
113+
if (c == '\n')
114+
{
115+
keepGoing = false; // Stop if we receive a newline
116+
}
117+
else
118+
{
119+
message += c; // Add serial characters to the destination number
120+
}
121+
}
122+
}
123+
124+
// Once we receive a newline, send the text.
125+
Serial.println("Sending: \"" + message + "\" to " + destinationNumber);
126+
// Call myModule.sendSMS(String number, String message) to send an SMS message.
127+
if (myModule.sendSMS(destinationNumber, message) == UBX_CELL_SUCCESS)
128+
{
129+
Serial.println(F("sendSMS was successful"));
130+
}
131+
}
Lines changed: 268 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
#include "SparkFun_u-blox_Cellular_Arduino_Library.h"
2+
3+
// Uncomment the line below that you need for Serial on your platform
4+
#define mySerial Serial1
5+
// SoftwareSerial mySerial(16, 17);
6+
7+
// Uncomment the module you're using. If your module is not listed below, then
8+
// it's not supported for this example
9+
SparkFun_ublox_Cellular myModule; // This example works with all modules, so the base class can be used
10+
// SparkFun_ublox_SARA_R5 myModule; // Base SARA-R5 class
11+
// SparkFun_ublox_SARA_R500S myModule;
12+
// SparkFun_ublox_SARA_R500S_01B myModule;
13+
// SparkFun_ublox_SARA_R500S_61B myModule;
14+
// SparkFun_ublox_SARA_R510M8S_61B myModule;
15+
// SparkFun_ublox_SARA_R510S myModule;
16+
// SparkFun_ublox_LARA_R6 myModule; // Base LARA-R6 class
17+
// SparkFun_ublox_LARA_R6001 myModule;
18+
// SparkFun_ublox_LARA_R6001D myModule;
19+
// SparkFun_ublox_LARA_R6401 myModule;
20+
// SparkFun_ublox_LARA_R6401D myModule;
21+
// SparkFun_ublox_LARA_R6801_00B myModule;
22+
// SparkFun_ublox_LARA_R6801D myModule;
23+
24+
// You can change the Quality of Service (QoS) here if you want
25+
int qos = 0;
26+
27+
// Topics that will be used for publishing and subscribing
28+
String publishTopic;
29+
String subscribeTopic;
30+
31+
// Whether we're connected to the MQTT broker
32+
bool mqttConnected = false;
33+
34+
// Callback function for handling MQTT responses from the module
35+
void mqttCallback(int command, int result)
36+
{
37+
if (command == UBX_CELL_MQTT_COMMAND_LOGIN && result == 1)
38+
{
39+
// Connected to broker
40+
mqttConnected = true;
41+
Serial.println(F("Connected to broker!"));
42+
}
43+
else if (command == UBX_CELL_MQTT_COMMAND_LOGOUT && result == 1)
44+
{
45+
// Disconnected from broker
46+
mqttConnected = false;
47+
Serial.println(F("Disconnected from broker!"));
48+
}
49+
else if (command == UBX_CELL_MQTT_COMMAND_SUBSCRIBE && result == 1)
50+
{
51+
// Topic subscription successful
52+
Serial.println(F("Subscribed to topic!"));
53+
Serial.println(F("Enter any text to post to the topic"));
54+
Serial.println();
55+
}
56+
else if (command == UBX_CELL_MQTT_COMMAND_READ)
57+
{
58+
// New message available
59+
Serial.print(F("A new message is available! Total messages to read: "));
60+
Serial.println(result);
61+
Serial.println(F("Enter a blank line to read the oldest message"));
62+
Serial.println();
63+
}
64+
else
65+
{
66+
// Other response
67+
Serial.print(F("Unknown MQTT reponse! Command: "));
68+
Serial.print(command);
69+
Serial.print(F(" Result: "));
70+
Serial.println(result);
71+
}
72+
}
73+
74+
void setup()
75+
{
76+
String currentOperator = "";
77+
78+
Serial.begin(115200); // Start the serial console
79+
80+
// Wait for user to press key to begin
81+
Serial.println(F("u-blox Cellular Example 8 - MQTT"));
82+
Serial.println(F("Press any key to begin"));
83+
84+
while (!Serial.available()) // Wait for the user to press a key (send any serial character)
85+
;
86+
while (Serial.available()) // Empty the serial RX buffer
87+
Serial.read();
88+
89+
Serial.println(F("Beginning..."));
90+
91+
// myModule.enableDebugging(); // Uncomment this line to enable helpful debug messages on Serial
92+
93+
// For the MicroMod Asset Tracker, we need to invert the power pin so it pulls high instead of low
94+
// Uncomment the next line if required
95+
// myModule.invertPowerPin(true);
96+
97+
// Initialize the module
98+
if (myModule.begin(mySerial, UBX_CELL_DEFAULT_BAUD_RATE))
99+
{
100+
Serial.println(F("Module connected!"));
101+
}
102+
else
103+
{
104+
Serial.println(F("Unable to communicate with the module."));
105+
Serial.println(F("Manually power-on (hold the module's On button for 3 seconds) and try again."));
106+
while (1)
107+
; // Loop forever on fail
108+
}
109+
Serial.println();
110+
111+
// First check to see if we're connected to an operator:
112+
if (myModule.getOperator(&currentOperator) == UBX_CELL_SUCCESS)
113+
{
114+
Serial.print(F("Connected to: "));
115+
Serial.println(currentOperator);
116+
}
117+
else
118+
{
119+
Serial.print(F("The module is not yet connected to an operator. Please use the previous examples to connect. "
120+
"Or wait and retry. Freezing..."));
121+
while (1)
122+
; // Do nothing more
123+
}
124+
125+
Serial.println();
126+
127+
// Make sure any previous MQTT connection is closed
128+
myModule.disconnectMQTT();
129+
130+
// Set callback for any MQTT responses from the module
131+
myModule.setMQTTCommandCallback(mqttCallback);
132+
133+
Serial.println(F("Enter the MQTT broker server name"));
134+
135+
// Clear any previous input and wait for new input
136+
while (Serial.available())
137+
Serial.read();
138+
while (!Serial.available())
139+
;
140+
141+
// Get the broker server name
142+
String serverName = Serial.readStringUntil('\n');
143+
Serial.print(F("Server name: "));
144+
Serial.println(serverName);
145+
Serial.println();
146+
147+
Serial.println(F("Enter the MQTT broker server port number"));
148+
Serial.println(F("(or enter nothing for default port of 1883)"));
149+
150+
// Clear any previous input and wait for new input
151+
while (Serial.available())
152+
Serial.read();
153+
while (!Serial.available())
154+
;
155+
156+
// Get the broker server port
157+
String serverPort = Serial.readStringUntil('\n');
158+
159+
// Attempt to parse the port number. If it fails, just set 1883
160+
int port = serverPort.toInt();
161+
if (port == 0)
162+
port = 1883;
163+
164+
Serial.print(F("Server port: "));
165+
Serial.println(port);
166+
Serial.println();
167+
168+
// Now set the MQTT server
169+
myModule.setMQTTserver(serverName, port);
170+
171+
Serial.println(F("Enter the client ID"));
172+
173+
// Clear any previous input and wait for new input
174+
while (Serial.available())
175+
Serial.read();
176+
while (!Serial.available())
177+
;
178+
179+
// Get the client ID
180+
String clientID = Serial.readStringUntil('\n');
181+
Serial.print(F("Client ID: "));
182+
Serial.println(clientID);
183+
Serial.println();
184+
185+
// Set the client ID
186+
myModule.setMQTTclientId(clientID);
187+
188+
Serial.println(F("Connecting to MQTT broker..."));
189+
myModule.connectMQTT();
190+
191+
// Wait for module to connect
192+
while (!mqttConnected)
193+
myModule.poll();
194+
195+
Serial.println();
196+
Serial.println(F("Enter a topic to publish to"));
197+
198+
// Clear any previous input and wait for new input
199+
while (Serial.available())
200+
Serial.read();
201+
while (!Serial.available())
202+
;
203+
204+
// Get the topic name
205+
publishTopic = Serial.readStringUntil('\n');
206+
Serial.print(F("Publish topic: "));
207+
Serial.println(publishTopic);
208+
Serial.println();
209+
210+
Serial.println();
211+
Serial.println(F("Enter a topic to subscribe to"));
212+
213+
// Clear any previous input and wait for new input
214+
while (Serial.available())
215+
Serial.read();
216+
while (!Serial.available())
217+
;
218+
219+
// Get the topic name
220+
subscribeTopic = Serial.readStringUntil('\n');
221+
Serial.print(F("Subscribe topic: "));
222+
Serial.println(subscribeTopic);
223+
Serial.println();
224+
225+
// Subscribe to the topic
226+
myModule.subscribeMQTTtopic(qos, subscribeTopic);
227+
}
228+
229+
void loop()
230+
{
231+
// Need to call poll() frequently to receive updates from the module.
232+
myModule.poll();
233+
234+
// Check for user input
235+
if (Serial.available())
236+
{
237+
// Get user's input
238+
String inputString = Serial.readStringUntil('\n');
239+
240+
// Clear any remaining input
241+
while (Serial.available())
242+
Serial.read();
243+
244+
// Check whether the user entered anything
245+
if (inputString.length() > 0)
246+
{
247+
// Publish the user's input to the topic
248+
Serial.println(F("Publishing message:"));
249+
Serial.println(inputString);
250+
Serial.println();
251+
myModule.mqttPublishTextMsg(publishTopic, inputString.c_str());
252+
}
253+
else
254+
{
255+
// Read next received message
256+
uint8_t buffer[MAX_MQTT_DIRECT_MSG_LEN];
257+
int bytesRead = 0;
258+
myModule.readMQTT(&qos, &subscribeTopic, buffer, MAX_MQTT_DIRECT_MSG_LEN, &bytesRead);
259+
260+
// Print out message
261+
Serial.println(F("Received message:"));
262+
for (int i = 0; i < bytesRead; i++)
263+
Serial.print((char)buffer[i]);
264+
Serial.println();
265+
Serial.println();
266+
}
267+
}
268+
}

‎library.properties

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=SparkFun u-blox Cellular Arduino Library
2+
version=1.0.0
3+
author=SparkFun Electronics <techsupport@sparkfun.com>
4+
maintainer=SparkFun Electronics <sparkfun.com>
5+
sentence=Library for u-blox cellular modules
6+
paragraph=
7+
category=Communication
8+
url=https://github.com/sparkfun/SparkFun_u-blox_Cellular_Arduino_Library
9+
architectures=*
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#include "sfe_lara_r6.h"
2+
#include "sfe_sara_r5.h"
3+
#include "sfe_ublox_cellular.h"
4+
#include "sfe_ublox_cellular_voice.h"

‎src/SparkFun_u-blox_SARA-R5_Arduino_Library.h

Lines changed: 385 additions & 0 deletions
Large diffs are not rendered by default.

‎src/sfe_lara_r6.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#ifndef SFE_LARA_R6_LIBRARY_H
2+
#define SFE_LARA_R6_LIBRARY_H
3+
4+
#include "sfe_ublox_cellular.h"
5+
#include "sfe_ublox_cellular_voice.h"
6+
7+
// Base LARA-R6 class
8+
class SparkFun_ublox_LARA_R6 : public SparkFun_ublox_Cellular
9+
{
10+
};
11+
12+
class SparkFun_ublox_LARA_R6001 : public SparkFun_ublox_LARA_R6, public SparkFun_ublox_Cellular_Voice_Base<SparkFun_ublox_LARA_R6001>
13+
{
14+
};
15+
16+
class SparkFun_ublox_LARA_R6001D : public SparkFun_ublox_LARA_R6
17+
{
18+
};
19+
20+
class SparkFun_ublox_LARA_R6401 : public SparkFun_ublox_LARA_R6, public SparkFun_ublox_Cellular_Voice_Base<SparkFun_ublox_LARA_R6401>
21+
{
22+
};
23+
24+
class SparkFun_ublox_LARA_R6401D : public SparkFun_ublox_LARA_R6
25+
{
26+
};
27+
28+
class SparkFun_ublox_LARA_R6801_00B : public SparkFun_ublox_LARA_R6, public SparkFun_ublox_Cellular_Voice_Base<SparkFun_ublox_LARA_R6801_00B>
29+
{
30+
};
31+
32+
class SparkFun_ublox_LARA_R6801D : public SparkFun_ublox_LARA_R6
33+
{
34+
};
35+
36+
#endif

‎src/sfe_sara_r5.cpp

Lines changed: 330 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,330 @@
1+
#include "sfe_sara_r5.h"
2+
3+
SparkFun_ublox_SARA_R5::SparkFun_ublox_SARA_R5()
4+
{
5+
addURCHandler(UBX_CELL_MESSAGE_PDP_ACTION_URC,
6+
[this](const char *event) { return this->urcHandlerPDPAction(event); });
7+
}
8+
9+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::setUtimeMode(UBX_CELL_utime_mode_t mode, UBX_CELL_utime_sensor_t sensor)
10+
{
11+
UBX_CELL_error_t err;
12+
size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_TIME) + 16;
13+
char command[cmdLen];
14+
15+
if (mode == UBX_CELL_UTIME_MODE_STOP) // stop UTIME does not require a sensor
16+
snprintf(command, cmdLen, "%s=%d", UBX_CELL_GNSS_REQUEST_TIME, mode);
17+
else
18+
snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_GNSS_REQUEST_TIME, mode, sensor);
19+
20+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_10_SEC_TIMEOUT);
21+
return err;
22+
}
23+
24+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor)
25+
{
26+
UBX_CELL_error_t err;
27+
size_t cmdLen = strlen(UBX_CELL_GNSS_REQUEST_TIME) + 2;
28+
char command[cmdLen];
29+
char response[minimumResponseAllocation];
30+
31+
UBX_CELL_utime_mode_t m;
32+
UBX_CELL_utime_sensor_t s;
33+
34+
snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_REQUEST_TIME);
35+
36+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_10_SEC_TIMEOUT);
37+
38+
// Response format: \r\n+UTIME: <mode>[,<sensor>]\r\n\r\nOK\r\n
39+
if (err == UBX_CELL_ERROR_SUCCESS)
40+
{
41+
int mStore, sStore, scanned = 0;
42+
char *searchPtr = strnstr(response, "+UTIME:", minimumResponseAllocation);
43+
if (searchPtr != nullptr)
44+
{
45+
searchPtr += strlen("+UTIME:"); // Move searchPtr to first character - probably a space
46+
while (*searchPtr == ' ')
47+
searchPtr++; // skip spaces
48+
scanned = sscanf(searchPtr, "%d,%d\r\n", &mStore, &sStore);
49+
}
50+
m = (UBX_CELL_utime_mode_t)mStore;
51+
s = (UBX_CELL_utime_sensor_t)sStore;
52+
if (scanned == 2)
53+
{
54+
*mode = m;
55+
*sensor = s;
56+
}
57+
else if (scanned == 1)
58+
{
59+
*mode = m;
60+
*sensor = UBX_CELL_UTIME_SENSOR_NONE;
61+
}
62+
else
63+
err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE;
64+
}
65+
66+
return err;
67+
}
68+
69+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::setUtimeIndication(UBX_CELL_utime_urc_configuration_t config)
70+
{
71+
UBX_CELL_error_t err;
72+
size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_INDICATION) + 16;
73+
char command[cmdLen];
74+
75+
snprintf(command, cmdLen, "%s=%d", UBX_CELL_GNSS_TIME_INDICATION, config);
76+
77+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
78+
return err;
79+
}
80+
81+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config)
82+
{
83+
UBX_CELL_error_t err;
84+
size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_INDICATION) + 2;
85+
char command[cmdLen];
86+
char response[minimumResponseAllocation];
87+
88+
UBX_CELL_utime_urc_configuration_t c;
89+
90+
snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_TIME_INDICATION);
91+
92+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
93+
94+
// Response format: \r\n+UTIMEIND: <mode>\r\n\r\nOK\r\n
95+
if (err == UBX_CELL_ERROR_SUCCESS)
96+
{
97+
int cStore, scanned = 0;
98+
char *searchPtr = strnstr(response, "+UTIMEIND:", minimumResponseAllocation);
99+
if (searchPtr != nullptr)
100+
{
101+
searchPtr += strlen("+UTIMEIND:"); // Move searchPtr to first char
102+
while (*searchPtr == ' ')
103+
searchPtr++; // skip spaces
104+
scanned = sscanf(searchPtr, "%d\r\n", &cStore);
105+
}
106+
c = (UBX_CELL_utime_urc_configuration_t)cStore;
107+
if (scanned == 1)
108+
{
109+
*config = c;
110+
}
111+
else
112+
err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE;
113+
}
114+
115+
return err;
116+
}
117+
118+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::setUtimeConfiguration(int32_t offsetNanoseconds, int32_t offsetSeconds)
119+
{
120+
UBX_CELL_error_t err;
121+
size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 48;
122+
char command[cmdLen];
123+
124+
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
125+
snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds);
126+
#else
127+
snprintf(command, cmdLen, "%s=%ld,%ld", UBX_CELL_GNSS_TIME_CONFIGURATION, offsetNanoseconds, offsetSeconds);
128+
#endif
129+
130+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
131+
return err;
132+
}
133+
134+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds)
135+
{
136+
UBX_CELL_error_t err;
137+
size_t cmdLen = strlen(UBX_CELL_GNSS_TIME_CONFIGURATION) + 2;
138+
char command[cmdLen];
139+
char response[minimumResponseAllocation];
140+
141+
int32_t ons;
142+
int32_t os;
143+
144+
snprintf(command, cmdLen, "%s?", UBX_CELL_GNSS_TIME_CONFIGURATION);
145+
146+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
147+
148+
// Response format: \r\n+UTIMECFG: <offset_nano>,<offset_sec>\r\n\r\nOK\r\n
149+
if (err == UBX_CELL_ERROR_SUCCESS)
150+
{
151+
int scanned = 0;
152+
char *searchPtr = strnstr(response, "+UTIMECFG:", minimumResponseAllocation);
153+
if (searchPtr != nullptr)
154+
{
155+
searchPtr += strlen("+UTIMECFG:"); // Move searchPtr to first char
156+
while (*searchPtr == ' ')
157+
searchPtr++; // skip spaces
158+
#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266)
159+
scanned = sscanf(searchPtr, "%d,%d\r\n", &ons, &os);
160+
#else
161+
scanned = sscanf(searchPtr, "%ld,%ld\r\n", &ons, &os);
162+
#endif
163+
}
164+
if (scanned == 2)
165+
{
166+
*offsetNanoseconds = ons;
167+
*offsetSeconds = os;
168+
}
169+
else
170+
err = UBX_CELL_ERROR_UNEXPECTED_RESPONSE;
171+
}
172+
173+
return err;
174+
}
175+
176+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter, int value)
177+
{
178+
UBX_CELL_error_t err;
179+
size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 24;
180+
char command[cmdLen];
181+
182+
if (profile >= UBX_CELL_NUM_PSD_PROFILES)
183+
return UBX_CELL_ERROR_ERROR;
184+
185+
snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value);
186+
187+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
188+
189+
return err;
190+
}
191+
192+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter,
193+
UBX_CELL_pdp_protocol_type_t value)
194+
{
195+
return (setPDPconfiguration(profile, parameter, (int)value));
196+
}
197+
198+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter,
199+
String value)
200+
{
201+
UBX_CELL_error_t err;
202+
size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64;
203+
char command[cmdLen];
204+
205+
if (profile >= UBX_CELL_NUM_PSD_PROFILES)
206+
return UBX_CELL_ERROR_ERROR;
207+
208+
snprintf(command, cmdLen, "%s=%d,%d,\"%s\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value.c_str());
209+
210+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
211+
212+
return err;
213+
}
214+
215+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter,
216+
IPAddress value)
217+
{
218+
UBX_CELL_error_t err;
219+
size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_CONFIG) + 64;
220+
char command[cmdLen];
221+
222+
if (profile >= UBX_CELL_NUM_PSD_PROFILES)
223+
return UBX_CELL_ERROR_ERROR;
224+
225+
snprintf(command, cmdLen, "%s=%d,%d,\"%d.%d.%d.%d\"", UBX_CELL_MESSAGE_PDP_CONFIG, profile, parameter, value[0],
226+
value[1], value[2], value[3]);
227+
228+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
229+
230+
return err;
231+
}
232+
233+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::performPDPaction(int profile, UBX_CELL_pdp_actions_t action)
234+
{
235+
UBX_CELL_error_t err;
236+
size_t cmdLen = strlen(UBX_CELL_MESSAGE_PDP_ACTION) + 32;
237+
char command[cmdLen];
238+
239+
if (profile >= UBX_CELL_NUM_PSD_PROFILES)
240+
return UBX_CELL_ERROR_ERROR;
241+
242+
snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_MESSAGE_PDP_ACTION, profile, action);
243+
244+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
245+
246+
return err;
247+
}
248+
249+
UBX_CELL_error_t SparkFun_ublox_SARA_R5::getNetworkAssignedIPAddress(int profile, IPAddress *address)
250+
{
251+
size_t cmdLen = strlen(UBX_CELL_NETWORK_ASSIGNED_DATA) + 16;
252+
char command[cmdLen];
253+
char response[minimumResponseAllocation];
254+
UBX_CELL_error_t err;
255+
int scanNum = 0;
256+
int profileStore = 0;
257+
int paramTag = 0; // 0: IP address: dynamic IP address assigned during PDP context activation
258+
int paramVals[4];
259+
260+
snprintf(command, cmdLen, "%s=%d,%d", UBX_CELL_NETWORK_ASSIGNED_DATA, profile, paramTag);
261+
262+
err = sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, response, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
263+
264+
if (err == UBX_CELL_ERROR_SUCCESS)
265+
{
266+
char *searchPtr = strnstr(response, "+UPSND:", minimumResponseAllocation);
267+
if (searchPtr != nullptr)
268+
{
269+
searchPtr += strlen("+UPSND:"); // Move searchPtr to first char
270+
while (*searchPtr == ' ')
271+
searchPtr++; // skip spaces
272+
scanNum = sscanf(searchPtr, "%d,%d,\"%d.%d.%d.%d\"", &profileStore, &paramTag, &paramVals[0], &paramVals[1],
273+
&paramVals[2], &paramVals[3]);
274+
}
275+
if (scanNum != 6)
276+
{
277+
if (_printDebug == true)
278+
{
279+
_debugPort->print(F("getNetworkAssignedIPAddress: error: scanNum is "));
280+
_debugPort->println(scanNum);
281+
}
282+
return UBX_CELL_ERROR_UNEXPECTED_RESPONSE;
283+
}
284+
285+
IPAddress tempAddress = {(uint8_t)paramVals[0], (uint8_t)paramVals[1], (uint8_t)paramVals[2],
286+
(uint8_t)paramVals[3]};
287+
*address = tempAddress;
288+
}
289+
290+
return err;
291+
}
292+
293+
bool SparkFun_ublox_SARA_R5::urcHandlerPDPAction(const char *event)
294+
{
295+
// URC: +UUPSDA (Packet Switched Data Action)
296+
int result;
297+
IPAddress remoteIP = {0, 0, 0, 0};
298+
int scanNum;
299+
int remoteIPstore[4];
300+
301+
char *searchPtr = strnstr(event, UBX_CELL_MESSAGE_PDP_ACTION_URC, _RXBuffSize);
302+
if (searchPtr != nullptr)
303+
{
304+
searchPtr += strlen(UBX_CELL_MESSAGE_PDP_ACTION_URC); // Move searchPtr to first character - probably a space
305+
while (*searchPtr == ' ')
306+
searchPtr++; // skip spaces
307+
scanNum = sscanf(searchPtr, "%d,\"%d.%d.%d.%d\"", &result, &remoteIPstore[0], &remoteIPstore[1],
308+
&remoteIPstore[2], &remoteIPstore[3]);
309+
310+
if (scanNum == 5)
311+
{
312+
if (_printDebug == true)
313+
_debugPort->println(F("processReadEvent: packet switched data action"));
314+
315+
for (int i = 0; i <= 3; i++)
316+
{
317+
remoteIP[i] = (uint8_t)remoteIPstore[i];
318+
}
319+
320+
if (_psdActionRequestCallback != nullptr)
321+
{
322+
_psdActionRequestCallback(result, remoteIP);
323+
}
324+
325+
return true;
326+
}
327+
}
328+
329+
return false;
330+
}

‎src/sfe_sara_r5.h

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#ifndef SFE_SARA_R5_LIBRARY_H
2+
#define SFE_SARA_R5_LIBRARY_H
3+
4+
#include "sfe_ublox_cellular.h"
5+
6+
const char *const UBX_CELL_MESSAGE_PDP_CONFIG = "+UPSD"; // Packet switched Data Profile configuration
7+
const char *const UBX_CELL_MESSAGE_PDP_ACTION = "+UPSDA"; // Perform the action for the specified PSD profile
8+
const char *const UBX_CELL_NETWORK_ASSIGNED_DATA = "+UPSND"; // Packet switched network-assigned data
9+
const char *const UBX_CELL_GNSS_REQUEST_TIME = "+UTIME"; // Ask for time information from cellular modem (CellTime)
10+
const char *const UBX_CELL_GNSS_TIME_INDICATION = "+UTIMEIND"; // Time information request status unsolicited indication
11+
const char *const UBX_CELL_GNSS_TIME_CONFIGURATION = "+UTIMECFG"; // Sets time configuration
12+
13+
const char *const UBX_CELL_MESSAGE_PDP_ACTION_URC = "+UUPSDA:";
14+
15+
// Base SARA-R5 class
16+
class SparkFun_ublox_SARA_R5 : public SparkFun_ublox_Cellular
17+
{
18+
public:
19+
SparkFun_ublox_SARA_R5();
20+
21+
UBX_CELL_error_t setUtimeMode(
22+
UBX_CELL_utime_mode_t mode = UBX_CELL_UTIME_MODE_PPS,
23+
UBX_CELL_utime_sensor_t sensor = UBX_CELL_UTIME_SENSOR_GNSS_LTE); // Time mode, source etc. (+UTIME)
24+
UBX_CELL_error_t getUtimeMode(UBX_CELL_utime_mode_t *mode, UBX_CELL_utime_sensor_t *sensor);
25+
UBX_CELL_error_t setUtimeIndication(
26+
UBX_CELL_utime_urc_configuration_t config = UBX_CELL_UTIME_URC_CONFIGURATION_ENABLED); // +UTIMEIND
27+
UBX_CELL_error_t getUtimeIndication(UBX_CELL_utime_urc_configuration_t *config);
28+
UBX_CELL_error_t setUtimeConfiguration(int32_t offsetNanoseconds = 0, int32_t offsetSeconds = 0); // +UTIMECFG
29+
UBX_CELL_error_t getUtimeConfiguration(int32_t *offsetNanoseconds, int32_t *offsetSeconds);
30+
31+
// Packet Switched Data
32+
// Configure the PDP using +UPSD. See UBX_CELL_pdp_configuration_parameter_t for the list of parameters: protocol,
33+
// APN, username, DNS, etc.
34+
UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter,
35+
int value); // Set parameters in the chosen PSD profile
36+
UBX_CELL_error_t setPDPconfiguration(
37+
int profile, UBX_CELL_pdp_configuration_parameter_t parameter,
38+
UBX_CELL_pdp_protocol_type_t value); // Set parameters in the chosen PSD profile
39+
UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter,
40+
String value); // Set parameters in the chosen PSD profile
41+
UBX_CELL_error_t setPDPconfiguration(int profile, UBX_CELL_pdp_configuration_parameter_t parameter,
42+
IPAddress value); // Set parameters in the chosen PSD profile
43+
UBX_CELL_error_t performPDPaction(
44+
int profile, UBX_CELL_pdp_actions_t action); // Performs the requested action for the specified PSD profile:
45+
// reset, store, load, activate, deactivate
46+
UBX_CELL_error_t getNetworkAssignedIPAddress(
47+
int profile, IPAddress *address); // Get the dynamic IP address assigned during PDP context activation
48+
49+
protected:
50+
bool urcHandlerPDPAction(const char *event);
51+
};
52+
53+
class SparkFun_ublox_SARA_R500S : public SparkFun_ublox_SARA_R5
54+
{
55+
};
56+
57+
class SparkFun_ublox_SARA_R500S_01B : public SparkFun_ublox_SARA_R5
58+
{
59+
};
60+
61+
class SparkFun_ublox_SARA_R500S_61B : public SparkFun_ublox_SARA_R5
62+
{
63+
};
64+
65+
class SparkFun_ublox_SARA_R510M8S_61B : public SparkFun_ublox_SARA_R5
66+
{
67+
};
68+
69+
class SparkFun_ublox_SARA_R510S : public SparkFun_ublox_SARA_R5
70+
{
71+
};
72+
73+
#endif

‎src/sfe_ublox_cellular.cpp

Lines changed: 6011 additions & 0 deletions
Large diffs are not rendered by default.

‎src/sfe_ublox_cellular.h

Lines changed: 1194 additions & 0 deletions
Large diffs are not rendered by default.

‎src/sfe_ublox_cellular_voice.h

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#ifndef SPARKFUN_UBX_CELL_VOICE_ARDUINO_LIBRARY_H
2+
#define SPARKFUN_UBX_CELL_VOICE_ARDUINO_LIBRARY_H
3+
4+
#include "sfe_ublox_cellular.h"
5+
6+
const char *const UBX_CELL_COMMAND_DIAL = "D"; // Dial command
7+
const char *const UBX_CELL_COMMAND_ANSWER = "A"; // Answer call
8+
const char *const UBX_CELL_COMMAND_HANG_UP = "+CHUP"; // Hang up call
9+
const char *const UBX_CELL_COMMAND_PLAY_AUDIO = "+UPAR"; // Play audio resource
10+
const char *const UBX_CELL_COMMAND_STOP_AUDIO = "+USAR"; // Stop audio resource
11+
const char *const UBX_CELL_COMMAND_GENERATE_TONE = "+UTGN"; // Tone generator
12+
13+
const char *const UBX_CELL_RING_URC = "RING";
14+
15+
typedef enum
16+
{
17+
UBX_CELL_AUDIO_RESOURCE_TONE = 0,
18+
UBX_CELL_AUDIO_RESOURCE_MIDI = 1,
19+
UBX_CELL_AUDIO_RESOURCE_LOOPBACK = 2
20+
} UBX_CELL_audio_resource_t;
21+
22+
// Base class for any modules supporting voice calls
23+
template <typename T> class SparkFun_ublox_Cellular_Voice_Base
24+
{
25+
public:
26+
SparkFun_ublox_Cellular_Voice_Base(void)
27+
{
28+
// Set ring URC callback to nullptr
29+
_ringCallback = nullptr;
30+
31+
// Add handler for ring URC
32+
static_cast<T *>(this)->addURCHandler(UBX_CELL_RING_URC,
33+
[this](const char *event) { return this->urcCheckRing(event); });
34+
}
35+
36+
UBX_CELL_error_t dial(String number)
37+
{
38+
char *command;
39+
char *numberCStr;
40+
UBX_CELL_error_t err;
41+
42+
numberCStr = static_cast<T *>(this)->ubx_cell_calloc_char(number.length() + 1);
43+
if (numberCStr == nullptr)
44+
return UBX_CELL_ERROR_OUT_OF_MEMORY;
45+
number.toCharArray(numberCStr, number.length() + 1);
46+
47+
size_t cmdLen = strlen(UBX_CELL_COMMAND_DIAL) + strlen(numberCStr) + 3;
48+
command = static_cast<T *>(this)->ubx_cell_calloc_char(cmdLen);
49+
if (command != nullptr)
50+
{
51+
// Heads up! The dial command is one of the only commands that requires a
52+
// semicolon at the end of it!
53+
snprintf(command, cmdLen, "%s=%s;", UBX_CELL_COMMAND_DIAL, numberCStr);
54+
55+
err = static_cast<T *>(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK, nullptr,
56+
UBX_CELL_10_SEC_TIMEOUT);
57+
58+
free(command);
59+
}
60+
else
61+
{
62+
err = UBX_CELL_ERROR_OUT_OF_MEMORY;
63+
}
64+
65+
free(numberCStr);
66+
67+
return err;
68+
}
69+
70+
UBX_CELL_error_t answer(void)
71+
{
72+
return static_cast<T *>(this)->sendCommandWithResponse(UBX_CELL_COMMAND_ANSWER, UBX_CELL_RESPONSE_OK_OR_ERROR,
73+
nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
74+
}
75+
76+
UBX_CELL_error_t hangUp(void)
77+
{
78+
return static_cast<T *>(this)->sendCommandWithResponse(UBX_CELL_COMMAND_HANG_UP, UBX_CELL_RESPONSE_OK_OR_ERROR,
79+
nullptr, UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
80+
}
81+
82+
UBX_CELL_error_t playAudioResource(uint8_t audio_resource, uint8_t tone_id = 0, uint8_t nof_repeat = 0)
83+
{
84+
UBX_CELL_error_t err;
85+
size_t cmdLen = strlen(UBX_CELL_COMMAND_PLAY_AUDIO) + 13;
86+
char command[cmdLen];
87+
88+
snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_PLAY_AUDIO, audio_resource, tone_id, nof_repeat);
89+
90+
err = static_cast<T *>(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr,
91+
UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
92+
return err;
93+
}
94+
95+
UBX_CELL_error_t stopAudioResource(uint8_t audio_resource)
96+
{
97+
UBX_CELL_error_t err;
98+
size_t cmdLen = strlen(UBX_CELL_COMMAND_STOP_AUDIO) + 5;
99+
char command[cmdLen];
100+
101+
snprintf(command, cmdLen, "%s=%d", UBX_CELL_COMMAND_STOP_AUDIO, audio_resource);
102+
103+
err = static_cast<T *>(this)->sendCommandWithResponse(command, UBX_CELL_RESPONSE_OK_OR_ERROR, nullptr,
104+
UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
105+
return err;
106+
}
107+
108+
UBX_CELL_error_t generateToneFreq(uint16_t frequency, uint16_t duration, uint8_t volume)
109+
{
110+
UBX_CELL_error_t err;
111+
size_t cmdLen = strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 15;
112+
char command[cmdLen];
113+
char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n";
114+
115+
snprintf(command, cmdLen, "%s=%d,%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, frequency, duration, volume);
116+
117+
err = static_cast<T *>(this)->sendCommandWithResponse(command, response, nullptr,
118+
UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
119+
return err;
120+
}
121+
122+
UBX_CELL_error_t generateToneDTMF(char dtmf_character, uint16_t duration, uint8_t volume)
123+
{
124+
UBX_CELL_error_t err;
125+
size_t cmdLen = strlen(UBX_CELL_COMMAND_GENERATE_TONE) + 14;
126+
char command[cmdLen];
127+
char response[] = "\r\nOK\r\n\r\n+UUTGN: 0\r\n";
128+
129+
snprintf(command, cmdLen, "%s=\"%c\",%d,%d", UBX_CELL_COMMAND_GENERATE_TONE, dtmf_character, duration, volume);
130+
131+
err = static_cast<T *>(this)->sendCommandWithResponse(command, response, nullptr,
132+
UBX_CELL_STANDARD_RESPONSE_TIMEOUT);
133+
return err;
134+
}
135+
136+
void setRingCallback(void (*callback)(void))
137+
{
138+
_ringCallback = callback;
139+
}
140+
141+
protected:
142+
// Callback for incoming calls
143+
void (*_ringCallback)(void);
144+
145+
bool urcCheckRing(const char *event)
146+
{
147+
int socket, length;
148+
char *searchPtr = strnstr(event, UBX_CELL_RING_URC, _RXBuffSize);
149+
if (searchPtr != nullptr)
150+
{
151+
if (_ringCallback != nullptr)
152+
{
153+
_ringCallback();
154+
}
155+
return true;
156+
}
157+
158+
return false;
159+
}
160+
};
161+
162+
class SparkFun_ublox_Cellular_Voice : public SparkFun_ublox_Cellular, public SparkFun_ublox_Cellular_Voice_Base<SparkFun_ublox_Cellular_Voice>
163+
{
164+
};
165+
166+
#endif

0 commit comments

Comments
 (0)
Please sign in to comment.