LTExBee_FirstConnectionBypass.ino example

Testing sketch to set up a never-previously-connected LTE XBee running in bypass mode.

Testing sketch to set up a never-previously-connected LTE XBee running in bypass mode.

1/** =========================================================================
2 * @example{lineno} LTExBee_FirstConnectionBypass.ino
3 * @brief Testing sketch to set up a never-previously-connected LTE XBee running
4 * in bypass mode.
5 *
6 * @m_examplenavigation{page_extra_helper_sketches,}
7 * ======================================================================= */
8
9#define TINY_GSM_MODEM_SARAR4
10#define TINY_GSM_RX_BUFFER 64
11#define TINY_GSM_YIELD_MS 2
12#define TINY_GSM_DEBUG Serial
13
14
15#include <Arduino.h>
16#include <StreamDebugger.h>
17#include <TinyGsmClient.h>
18
19StreamDebugger debugger(Serial1, Serial);
20TinyGsm gsmModem(debugger);
21
22const char* apn = "m2m";
23
24void setup() {
25 // Set the reset pin HIGH to ensure the Bee does not continually reset
26 pinMode(20, OUTPUT);
27 digitalWrite(20, HIGH);
28
29 // Set the sleep_rq pin LOW to wake the Bee
30 pinMode(23, OUTPUT);
31 digitalWrite(23, LOW);
32
33 // Set the input pin mode
34 pinMode(19, INPUT);
35
36 // Set console baud rate
37 Serial.begin(115200);
38 delay(10);
39
40 // Set XBee module baud rate
41 Serial1.begin(9600);
42
43 // Wait for warm-up, probably overkill
44 delay(6000);
45}
46
47void loop() {
48 bool success = false;
49 DBG(F("Putting XBee into command mode..."));
50 for (uint8_t i = 0; i < 5; i++) {
51 /** First, wait the required guard time before entering command mode. */
52 delay(1010);
53 /** Now, enter command mode to set all pin I/O functionality. */
54 gsmModem.streamWrite(GF("+++"));
55 success = gsmModem.waitResponse(2000, GF("OK\r")) == 1;
56 if (success) break;
57 }
58 if (success) {
59 DBG(F("Setting I/O Pins..."));
60 /** Enable pin sleep functionality on `DIO9`.
61 * NOTE: Only the `DTR_N/SLEEP_RQ/DIO8` pin (9 on the bee socket) can be
62 * used for this pin sleep/wake. */
63 gsmModem.sendAT(GF("D8"), 1);
64 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
65 /** Enable status indication on `DIO9` - it will be HIGH when the XBee
66 * is awake.
67 * NOTE: Only the `ON/SLEEP_N/DIO9` pin (13 on the bee socket) can be
68 * used for direct status indication. */
69 gsmModem.sendAT(GF("D9"), 1);
70 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
71 /** Enable CTS on `DIO7` - it will be `LOW` when it is clear to send
72 * data to the XBee. This can be used as proxy for status indication if
73 * that pin is not readable.
74 * NOTE: Only the `CTS_N/DIO7` pin (12 on the bee socket) can be used
75 * for CTS. */
76 gsmModem.sendAT(GF("D7"), 1);
77 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
78 /** Enable association indication on `DIO5` - this is should be directly
79 * attached to an LED if possible.
80 * - Solid light indicates no connection
81 * - Single blink indicates connection
82 * - double blink indicates connection but failed TCP link on last
83 * attempt
84 *
85 * NOTE: Only the `Associate/DIO5` pin (15 on the bee socket) can be
86 * used for this function. */
87 gsmModem.sendAT(GF("D5"), 1);
88 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
89 /** Enable RSSI PWM output on `DIO10` - this should be directly attached
90 * to an LED if possible. A higher PWM duty cycle (and thus brighter
91 * LED) indicates better signal quality.
92 * NOTE: Only the `DIO10/PWM0` pin (6 on the bee socket) can be used for
93 * this function. */
94 gsmModem.sendAT(GF("P0"), 1);
95 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
96 /** Enable pin sleep on the XBee. */
97 DBG(F("Setting Sleep Options..."));
98 gsmModem.sendAT(GF("SM"), 1);
99 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
100 DBG(F("Setting Other Options..."));
101 /** Disable remote manager, USB Direct, and LTE PSM.
102 * NOTE: LTE-M's PSM (Power Save Mode) sounds good, but there's no easy
103 * way on the LTE-M Bee to wake the cell chip itself from PSM, so we'll
104 * use the Digi pin sleep instead. */
105 gsmModem.sendAT(GF("DO"), 0);
106 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
107 /* Make sure USB direct is NOT enabled on the XBee3 units. */
108 gsmModem.sendAT(GF("P1"), 0);
109 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
110 // DBG(F("Setting Cellular Carrier Options..."));
111 // // Carrier Profile - 1 = No profile/SIM ICCID selected
112 // gsmModem.sendAT(GF("CP"),1);
113 // success &= gsmModem.waitResponse(GF("OK\r")) == 1;
114 // // Cellular network technology - LTE-M/NB IoT
115 // gsmModem.sendAT(GF("N#"),0);
116 // success &= gsmModem.waitResponse(GF("OK\r")) == 1;
117 // Make sure airplane mode is off - bypass and airplane mode are
118 // incompatible.
119 DBG(F("Making sure airplane mode is off..."));
120 gsmModem.sendAT(GF("AM"), 0);
121 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
122 DBG(F("Turning on Bypass Mode..."));
123 /** Enable bypass mode. */
124 gsmModem.sendAT(GF("AP5"));
125 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
126 /** Write changes to flash. */
127 gsmModem.sendAT(GF("WR"));
128 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
129 /** Apply changes. */
130 gsmModem.sendAT(GF("AC"));
131 success &= gsmModem.waitResponse(GF("OK\r")) == 1;
132 // Finally, force a reset to actually enter bypass mode - this
133 // effectively exits command mode.
134 DBG(F("Resetting the module to reboot in bypass mode..."));
135 gsmModem.sendAT(GF("FR"));
136 success &= gsmModem.waitResponse(5000L, GF("OK\r")) == 1;
137 // Allow 5s for the unit to reset.
138 delay(500);
139 // Re-initialize the TinyGSM SARA R4 instance.
140 DBG(F("Attempting to reconnect to the u-blox SARA R410M module..."));
141 success &= gsmModem.init();
142 gsmModem.getModemName();
143 } else {
144 // wait a bit
145 delay(30000L);
146 // try again
147 return;
148 }
149
150 DBG(F("Setting Cellular Carrier Options..."));
151 // Turn off the cellular radio while making network changes
152 gsmModem.sendAT(GF("+CFUN=0"));
153 gsmModem.waitResponse();
154 // Mobile Network Operator Profile
155 // - 0: SW default
156 // - 1: SIM ICCID selected
157 // - 2: ATT
158 // - 3: Verizon
159 // - 4: Telstra
160 // - 5: T-Mobile US
161 // - 6: China Telecom
162 // - 8: Sprint
163 // - 19: Vodafone
164 // - 20: NTT DoCoMo
165 // - 21: Telus
166 // - 28: SoftBank
167 // - 31: Deutsche Telekom
168 // - 32: US Cellular
169 // - 33: VIVO
170 // - 39: SKT
171 // - 44: Claro Brasil
172 // - 45: TIM Brasil
173 // - 46: Orange France
174 // - 90: global
175 // - 100: Standard Europe
176 // - 101: Standard Europe No-ePCO (The factory-programmed configuration of
177 // this profile is the same of the standard Europe profile (<MNO>=100), but
178 // the ePCO is disabled.)
179 // - 102: Standard Japan (global)
180 // - 198: AT&T 2-4-12 (The factory programmed configuration of this profile
181 // is the same of the AT&T profile (<MNO>=2), but the LTE band 5 is
182 // disabled.)
183 // - 201: GCF-PTCRB (This profile is meant only for conformance testing.)
184 gsmModem.sendAT(GF("+UMNOPROF="), 1);
185 gsmModem.waitResponse();
186 // Selected network technology - 7: LTE Cat.M1
187 // - 8: LTE Cat.NB1
188 // Fallback network technology - 7: LTE Cat.M1
189 // - 8: LTE Cat.NB1
190 // NOTE: As of 2020 in the USA, AT&T and Verizon only use LTE-M
191 // T-Mobile uses NB-IOT
192 gsmModem.sendAT(GF("+URAT="), 7, ',', 8);
193 gsmModem.waitResponse();
194 // Set the band mask manually if needed
195 // bit 0 = band 1; bit 127 = band 128
196 // gsmModem.sendAT(GF("+UBANDMASK="), 0, ',', 134217732);
197 // gsmModem.waitResponse();
198 // Restart the module to apply changes and bring back to full functionality
199 gsmModem.restart();
200
201 // Check again for the carrier profile (to ensure it took)
202 // If 1/SIM select was used, this will show what the SIM picked
203 gsmModem.sendAT(GF("+UMNOPROF?"));
204 gsmModem.waitResponse();
205
206 // Scan for networks - this is probably really slow
207 DBG(F("Scanning for networks. This may take up to 3 minutes"));
208 gsmModem.sendAT(GF("+COPS=0"));
209 gsmModem.waitResponse();
210 gsmModem.sendAT(GF("+COPS=?"));
211 gsmModem.waitResponse(180000L);
212
213 // Wait forever for a connection
214 DBG(F("Waiting for network registration"));
215 while (!gsmModem.isNetworkConnected()) {
216 int csq = gsmModem.getSignalQuality();
217 DBG("Signal quality:", csq);
218 delay(250);
219 }
220
221 // Print some stuff after connected
222 String ccid = gsmModem.getSimCCID();
223 DBG("CCID:", ccid);
224
225 String imei = gsmModem.getIMEI();
226 DBG("IMEI:", imei);
227
228 String imsi = gsmModem.getIMSI();
229 DBG("IMSI:", imsi);
230
231 String cop = gsmModem.getOperator();
232 DBG("Operator:", cop);
233
234 IPAddress local = gsmModem.localIP();
235 DBG("Local IP:", local);
236
237
238 // Shut down
239 gsmModem.poweroff();
240 DBG("Powering down.");
241
242 while (1) {
243 // And do nothing forever more
244 }
245}