|
| 1 | +/* |
| 2 | + Register your SARA-R5/SIM combo on a mobile network operator |
| 3 | + By: Paul Clark |
| 4 | + SparkFun Electronics |
| 5 | + Date: October 20th 2020 |
| 6 | +
|
| 7 | + Please see LICENSE.md for the license information |
| 8 | +
|
| 9 | + This example demonstrates how to initialize your MicroMod Asset Tracker Carrier Board and |
| 10 | + connect it to a mobile network operator (Verizon, AT&T, T-Mobile, etc.). |
| 11 | +
|
| 12 | + Before beginning, you may need to adjust the mobile network operator (MNO) |
| 13 | + setting on line 83. See comments above that line to help select either |
| 14 | + Verizon, T-Mobile, AT&T or others. |
| 15 | + |
| 16 | + This code is intend to run on the MicroMod Asset Tracker Carrier Board |
| 17 | + using (e.g.) the MicroMod Artemis Processor Board |
| 18 | +
|
| 19 | + Select the SparkFun RedBoard Artemis ATP from the SparkFun Apollo3 boards |
| 20 | + |
| 21 | +*/ |
| 22 | + |
| 23 | +//Click here to get the library: http://librarymanager/All#SparkFun_u-blox_SARA-R5_Arduino_Library |
| 24 | +#include <SparkFun_u-blox_SARA-R5_Arduino_Library.h> |
| 25 | + |
| 26 | +// We need to pass a Serial or SoftwareSerial object to the SARA-R5 |
| 27 | +// library. Below creates a SoftwareSerial object on the standard pins: |
| 28 | +// Note: if you're using an Arduino board with a dedicated hardware |
| 29 | +// serial port, comment out the line below. |
| 30 | +//SoftwareSerial saraSerial(8, 9); |
| 31 | + |
| 32 | +// Create a SARA_R5 object to use throughout the sketch |
| 33 | +// We need to tell the library what GPIO pin is connected to the SARA power pin. |
| 34 | +// If you're using the MicroMod Asset Tracker and the MicroMod Artemis Processor Board, |
| 35 | +// the pin number is GPIO2 which is connected to AD34. TO DO: Check this! |
| 36 | +SARA_R5 assetTracker(34); |
| 37 | + |
| 38 | +// To support multiple architectures, serial ports are abstracted here. |
| 39 | +// By default, they'll support AVR's like the Arduino Uno and Redboard |
| 40 | +// For example, on a SAMD21 board SerialMonitor can be changed to SerialUSB |
| 41 | +// and saraSerial can be set to Serial1 (hardware serial port on 0/1) |
| 42 | +#define SerialMonitor Serial |
| 43 | +#define saraSerial Serial1 |
| 44 | + |
| 45 | +// Network operator can be set to either: |
| 46 | +// MNO_SW_DEFAULT -- DEFAULT |
| 47 | +// MNO_ATT -- AT&T |
| 48 | +// MNO_VERIZON -- Verizon |
| 49 | +// MNO_TELSTRA -- Telstra |
| 50 | +// MNO_TMO -- T-Mobile US |
| 51 | +// MNO_CT -- China Telecom |
| 52 | +const mobile_network_operator_t MOBILE_NETWORK_OPERATOR = MNO_SIM_ICCID; |
| 53 | +const String MOBILE_NETWORK_STRINGS[] = {"Default", "SIM_ICCID", "AT&T", "VERIZON", |
| 54 | + "TELSTRA", "T-Mobile US", "CT"}; |
| 55 | + |
| 56 | +// APN -- Access Point Name. Gateway between GPRS MNO |
| 57 | +// and another computer network. E.g. "hologram |
| 58 | +//const String APN = "hologram"; |
| 59 | + |
| 60 | +// The APN can be omitted: this is the so-called "blank APN" setting that may be suggested by |
| 61 | +// network operators (e.g. to roaming devices); in this case the APN string is not included in |
| 62 | +// the message sent to the network. |
| 63 | +const String APN = ""; |
| 64 | + |
| 65 | +// This defines the size of the ops struct array. To narrow the operator |
| 66 | +// list, set MOBILE_NETWORK_OPERATOR to AT&T, Verizeon etc. instead |
| 67 | +// of MNO_SW_DEFAULT. |
| 68 | +#define MAX_OPERATORS 5 |
| 69 | + |
| 70 | +#define DEBUG_PASSTHROUGH_ENABLED |
| 71 | + |
| 72 | +void setup() { |
| 73 | + int opsAvailable; |
| 74 | + struct operator_stats ops[MAX_OPERATORS]; |
| 75 | + String currentOperator = ""; |
| 76 | + bool newConnection = true; |
| 77 | + |
| 78 | + SerialMonitor.begin(9600); |
| 79 | + while (!SerialMonitor) ; // For boards with built-in USB |
| 80 | + |
| 81 | + SerialMonitor.println(F("Initializing the Asset Tracker (SARA-R5)...")); |
| 82 | + SerialMonitor.println(F("...this may take ~25 seconds if the SARA is off.")); |
| 83 | + SerialMonitor.println(F("...it may take ~5 seconds if it just turned on.")); |
| 84 | + |
| 85 | + // Call assetTracker.begin and pass it your Serial/SoftwareSerial object to |
| 86 | + // communicate with the LTE Shield. |
| 87 | + // Note: If you're using an Arduino with a dedicated hardware serial |
| 88 | + // port, you may instead slide "Serial" into this begin call. |
| 89 | + if ( assetTracker.begin(saraSerial, 9600) ) { |
| 90 | + SerialMonitor.println(F("LTE Shield connected!\r\n")); |
| 91 | + } else { |
| 92 | + SerialMonitor.println("Unable to initialize the shield."); |
| 93 | + while(1) ; |
| 94 | + } |
| 95 | + |
| 96 | + // First check to see if we're already connected to an operator: |
| 97 | + if (assetTracker.getOperator(¤tOperator) == SARA_R5_SUCCESS) { |
| 98 | + SerialMonitor.print(F("Already connected to: ")); |
| 99 | + SerialMonitor.println(currentOperator); |
| 100 | + // If already connected provide the option to type y to connect to new operator |
| 101 | + SerialMonitor.println(F("Press y to connect to a new operator, or any other key to continue.\r\n")); |
| 102 | + while (!SerialMonitor.available()) ; |
| 103 | + if (SerialMonitor.read() != 'y') { |
| 104 | + newConnection = false; |
| 105 | + } |
| 106 | + while (SerialMonitor.available()) SerialMonitor.read(); |
| 107 | + } |
| 108 | + |
| 109 | + if (newConnection) { |
| 110 | + // Set MNO to either Verizon, T-Mobile, AT&T, Telstra, etc. |
| 111 | + // This will narrow the operator options during our scan later |
| 112 | + SerialMonitor.println(F("Setting mobile-network operator")); |
| 113 | + if (assetTracker.setNetwork(MOBILE_NETWORK_OPERATOR)) { |
| 114 | + SerialMonitor.print(F("Set mobile network operator to ")); |
| 115 | + SerialMonitor.println(MOBILE_NETWORK_STRINGS[MOBILE_NETWORK_OPERATOR] + "\r\n"); |
| 116 | + } else { |
| 117 | + SerialMonitor.println(F("Error setting MNO. Try cycling power to the shield/Arduino.")); |
| 118 | + while (1) ; |
| 119 | + } |
| 120 | + |
| 121 | + // Set the APN -- Access Point Name -- e.g. "hologram" |
| 122 | + SerialMonitor.println(F("Setting APN...")); |
| 123 | + if (assetTracker.setAPN(APN) == SARA_R5_SUCCESS) { |
| 124 | + SerialMonitor.println(F("APN successfully set.\r\n")); |
| 125 | + } else { |
| 126 | + SerialMonitor.println(F("Error setting APN. Try cycling power to the shield/Arduino.")); |
| 127 | + while (1) ; |
| 128 | + } |
| 129 | + |
| 130 | + // Wait for user to press button before initiating network scan. |
| 131 | + SerialMonitor.println(F("Press any key scan for networks..")); |
| 132 | + serialWait(); |
| 133 | + |
| 134 | + SerialMonitor.println(F("Scanning for operators...this may take up to 3 minutes\r\n")); |
| 135 | + // assetTracker.getOperators takes in a operator_stats struct pointer and max number of |
| 136 | + // structs to scan for, then fills up those objects with operator names and numbers |
| 137 | + opsAvailable = assetTracker.getOperators(ops, MAX_OPERATORS); // This will block for up to 3 minutes |
| 138 | + |
| 139 | + if (opsAvailable > 0) { |
| 140 | + // Pretty-print operators we found: |
| 141 | + SerialMonitor.println("Found " + String(opsAvailable) + " operators:"); |
| 142 | + printOperators(ops, opsAvailable); |
| 143 | + |
| 144 | + // Wait until the user presses a key to initiate an operator connection |
| 145 | + SerialMonitor.println("Press 1-" + String(opsAvailable) + " to select an operator."); |
| 146 | + char c = 0; |
| 147 | + bool selected = false; |
| 148 | + while (!selected) { |
| 149 | + while (!SerialMonitor.available()) ; |
| 150 | + c = SerialMonitor.read(); |
| 151 | + int selection = c - '0'; |
| 152 | + if ((selection >= 1) && (selection <= opsAvailable)) { |
| 153 | + selected = true; |
| 154 | + SerialMonitor.println("Connecting to option " + String(selection)); |
| 155 | + if (assetTracker.registerOperator(ops[selection - 1]) == SARA_R5_SUCCESS) { |
| 156 | + SerialMonitor.println("Network " + ops[selection - 1].longOp + " registered\r\n"); |
| 157 | + } else { |
| 158 | + SerialMonitor.println(F("Error connecting to operator. Reset and try again, or try another network.")); |
| 159 | + } |
| 160 | + } |
| 161 | + } |
| 162 | + } else { |
| 163 | + SerialMonitor.println(F("Did not find an operator. Double-check SIM and antenna, reset and try again, or try another network.")); |
| 164 | + while (1) ; |
| 165 | + } |
| 166 | + } |
| 167 | + |
| 168 | + // At the very end print connection information |
| 169 | + printInfo(); |
| 170 | +} |
| 171 | + |
| 172 | +void loop() { |
| 173 | + // Loop won't do much besides provide a debugging interface. |
| 174 | + // Pass serial data from Arduino to shield and vice-versa |
| 175 | +#ifdef DEBUG_PASSTHROUGH_ENABLED |
| 176 | + if (saraSerial.available()) { |
| 177 | + SerialMonitor.write((char) saraSerial.read()); |
| 178 | + } |
| 179 | + if (SerialMonitor.available()) { |
| 180 | + saraSerial.write((char) SerialMonitor.read()); |
| 181 | + } |
| 182 | +#endif |
| 183 | +} |
| 184 | + |
| 185 | +void printInfo(void) { |
| 186 | + String currentApn = ""; |
| 187 | + IPAddress ip(0, 0, 0, 0); |
| 188 | + String currentOperator = ""; |
| 189 | + |
| 190 | + SerialMonitor.println(F("Connection info:")); |
| 191 | + // APN Connection info: APN name and IP |
| 192 | + if (assetTracker.getAPN(¤tApn, &ip) == SARA_R5_SUCCESS) { |
| 193 | + SerialMonitor.println("APN: " + String(currentApn)); |
| 194 | + SerialMonitor.print("IP: "); |
| 195 | + SerialMonitor.println(ip); |
| 196 | + } |
| 197 | + |
| 198 | + // Operator name or number |
| 199 | + if (assetTracker.getOperator(¤tOperator) == SARA_R5_SUCCESS) { |
| 200 | + SerialMonitor.print(F("Operator: ")); |
| 201 | + SerialMonitor.println(currentOperator); |
| 202 | + } |
| 203 | + |
| 204 | + // Received signal strength |
| 205 | + SerialMonitor.println("RSSI: " + String(assetTracker.rssi())); |
| 206 | + SerialMonitor.println(); |
| 207 | +} |
| 208 | + |
| 209 | +void printOperators(struct operator_stats * ops, int operatorsAvailable) { |
| 210 | + for (int i = 0; i < operatorsAvailable; i++) { |
| 211 | + SerialMonitor.print(String(i + 1) + ": "); |
| 212 | + SerialMonitor.print(ops[i].longOp + " (" + String(ops[i].numOp) + ") - "); |
| 213 | + switch (ops[i].stat) { |
| 214 | + case 0: |
| 215 | + SerialMonitor.println(F("UNKNOWN")); |
| 216 | + break; |
| 217 | + case 1: |
| 218 | + SerialMonitor.println(F("AVAILABLE")); |
| 219 | + break; |
| 220 | + case 2: |
| 221 | + SerialMonitor.println(F("CURRENT")); |
| 222 | + break; |
| 223 | + case 3: |
| 224 | + SerialMonitor.println(F("FORBIDDEN")); |
| 225 | + break; |
| 226 | + } |
| 227 | + } |
| 228 | + SerialMonitor.println(); |
| 229 | +} |
| 230 | + |
| 231 | +void serialWait() { |
| 232 | + while (!SerialMonitor.available()) ; |
| 233 | + while (SerialMonitor.available()) SerialMonitor.read(); |
| 234 | +} |
0 commit comments