Forum Replies Created
-
AuthorPosts
-
I wish there was some magical way to know why the connection isn’t working or to bribe the thing into working. Obviously from this forum, and from dozens of issues in the TinyGSM library, a lot of people have trouble figuring out the right settings to get their board to connect.
And a new program to try to set it up in bypass to see if we can see what’s failing that way. I’ve also posted this on GitHub here: https://github.com/EnviroDIY/ModularSensors/blob/master/tools/LTExBee_FirstConnectionBypass/LTExBee_FirstConnectionBypass.ino
Arduino123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236#define TINY_GSM_MODEM_SARAR4#define TINY_GSM_RX_BUFFER 64#define TINY_GSM_YIELD_MS 2#define TINY_GSM_DEBUG Serial#include <Arduino.h>#include <StreamDebugger.h>#include <TinyGsmClient.h>StreamDebugger debugger(Serial1, Serial);TinyGsm gsmModem(debugger);const char* apn = "m2m";void setup() {// Set the reset pin HIGH to ensure the Bee does not continually resetpinMode(20, OUTPUT);digitalWrite(20, HIGH);// Set the sleep_rq pin LOW to wake the BeepinMode(23, OUTPUT);digitalWrite(23, LOW);// Set the input pin modepinMode(19, INPUT);// Set console baud rateSerial.begin(115200);delay(10);// Set XBee module baud rateSerial1.begin(9600);// Wait for warm-up, probably overkilldelay(6000);}void loop() {bool success = false;DBG(F("Putting XBee into command mode..."));for (uint8_t i = 0; i < 5; i++) {/** First, wait the required guard time before entering command mode. */delay(1010);/** Now, enter command mode to set all pin I/O functionality. */gsmModem.streamWrite(GF("+++"));success = gsmModem.waitResponse(2000, GF("OK\r")) == 1;if (success) break;}if (success) {DBG(F("Setting I/O Pins..."));/** Enable pin sleep functionality on <code>DIO9</code>.* NOTE: Only the <code>DTR_N/SLEEP_RQ/DIO8</code> pin (9 on the bee socket) can be* used for this pin sleep/wake. */gsmModem.sendAT(GF("D8"), 1);success &= gsmModem.waitResponse(GF("OK\r")) == 1;/** Enable status indication on <code>DIO9</code> - it will be HIGH when the XBee* is awake.* NOTE: Only the <code>ON/SLEEP_N/DIO9</code> pin (13 on the bee socket) can be* used for direct status indication. */gsmModem.sendAT(GF("D9"), 1);success &= gsmModem.waitResponse(GF("OK\r")) == 1;/** Enable CTS on <code>DIO7</code> - it will be <code>LOW</code> when it is clear to send* data to the XBee. This can be used as proxy for status indication if* that pin is not readable.* NOTE: Only the <code>CTS_N/DIO7</code> pin (12 on the bee socket) can be used* for CTS. */gsmModem.sendAT(GF("D7"), 1);success &= gsmModem.waitResponse(GF("OK\r")) == 1;/** Enable association indication on <code>DIO5</code> - this is should be directly* attached to an LED if possible.* - Solid light indicates no connection* - Single blink indicates connection* - double blink indicates connection but failed TCP link on last* attempt** NOTE: Only the <code>Associate/DIO5</code> pin (15 on the bee socket) can be* used for this function. */gsmModem.sendAT(GF("D5"), 1);success &= gsmModem.waitResponse(GF("OK\r")) == 1;/** Enable RSSI PWM output on <code>DIO10</code> - this should be directly attached* to an LED if possible. A higher PWM duty cycle (and thus brighter* LED) indicates better signal quality.* NOTE: Only the <code>DIO10/PWM0</code> pin (6 on the bee socket) can be used for* this function. */gsmModem.sendAT(GF("P0"), 1);success &= gsmModem.waitResponse(GF("OK\r")) == 1;/** Enable pin sleep on the XBee. */DBG(F("Setting Sleep Options..."));gsmModem.sendAT(GF("SM"), 1);success &= gsmModem.waitResponse(GF("OK\r")) == 1;DBG(F("Setting Other Options..."));/** Disable remote manager, USB Direct, and LTE PSM.* NOTE: LTE-M's PSM (Power Save Mode) sounds good, but there's no easy* way on the LTE-M Bee to wake the cell chip itself from PSM, so we'll* use the Digi pin sleep instead. */gsmModem.sendAT(GF("DO"), 0);success &= gsmModem.waitResponse(GF("OK\r")) == 1;/* Make sure USB direct is NOT enabled on the XBee3 units. */gsmModem.sendAT(GF("P1"), 0);success &= gsmModem.waitResponse(GF("OK\r")) == 1;// DBG(F("Setting Cellular Carrier Options..."));// // Carrier Profile - 1 = No profile/SIM ICCID selected// gsmModem.sendAT(GF("CP"),1);// success &= gsmModem.waitResponse(GF("OK\r")) == 1;// // Cellular network technology - LTE-M/NB IoT// gsmModem.sendAT(GF("N#"),0);// success &= gsmModem.waitResponse(GF("OK\r")) == 1;// Make sure airplane mode is off - bypass and airplane mode are// incompatible.DBG(F("Making sure airplane mode is off..."));gsmModem.sendAT(GF("AM"), 0);success &= gsmModem.waitResponse(GF("OK\r")) == 1;DBG(F("Turning on Bypass Mode..."));/** Enable bypass mode. */gsmModem.sendAT(GF("AP5"));success &= gsmModem.waitResponse(GF("OK\r")) == 1;/** Write changes to flash. */gsmModem.sendAT(GF("WR"));success &= gsmModem.waitResponse(GF("OK\r")) == 1;/** Apply changes. */gsmModem.sendAT(GF("AC"));success &= gsmModem.waitResponse(GF("OK\r")) == 1;// Finally, force a reset to actually enter bypass mode - this// effectively exits command mode.DBG(F("Resetting the module to reboot in bypass mode..."));gsmModem.sendAT(GF("FR"));success &= gsmModem.waitResponse(5000L, GF("OK\r")) == 1;// Allow 5s for the unit to reset.delay(500);// Re-initialize the TinyGSM SARA R4 instance.DBG(F("Attempting to reconnect to the u-blox SARA R410M module..."));success &= gsmModem.init();gsmModem.getModemName();} else {// wait a bitdelay(30000L);// try againreturn;}DBG(F("Setting Cellular Carrier Options..."));// Turn off the cellular radio while making network changesgsmModem.sendAT(GF("+CFUN=0"));gsmModem.waitResponse();// Mobile Network Operator Profile// - 0: SW default// - 1: SIM ICCID selected// - 2: ATT// - 3: Verizon// - 4: Telstra// - 5: T-Mobile US// - 6: China Telecom// - 8: Sprint// - 19: Vodafone// - 20: NTT DoCoMo// - 21: Telus// - 28: SoftBank// - 31: Deutsche Telekom// - 32: US Cellular// - 33: VIVO// - 39: SKT// - 44: Claro Brasil// - 45: TIM Brasil// - 46: Orange France// - 90: global// - 100: Standard Europe// - 101: Standard Europe No-ePCO (The factory-programmed configuration of// this profile is the same of the standard Europe profile (<MNO>=100), but// the ePCO is disabled.)// - 102: Standard Japan (global)// - 198: AT&T 2-4-12 (The factory programmed configuration of this profile// is the same of the AT&T profile (<MNO>=2), but the LTE band 5 is// disabled.)// - 201: GCF-PTCRB (This profile is meant only for conformance testing.)gsmModem.sendAT(GF("+UMNOPROF="), 1);gsmModem.waitResponse();// Selected network technology - 7: LTE Cat.M1// - 8: LTE Cat.NB1// Fallback network technology - 7: LTE Cat.M1// - 8: LTE Cat.NB1// NOTE: As of 2020 in the USA, AT&T and Verizon only use LTE-M// T-Mobile uses NB-IOTgsmModem.sendAT(GF("+URAT="), 7, ',', 8);gsmModem.waitResponse();// Set the band mask manually if needed// bit 0 = band 1; bit 127 = band 128gsmModem.sendAT(GF("+UBANDMASK="), 0, ',', 134217732);gsmModem.waitResponse();// Restart the module to apply changes and bring back to full functionalitygsmModem.restart();// Check again for the carrier profile (to ensure it took)// If 1/SIM select was used, this will show what the SIM pickedgsmModem.sendAT(GF("+UMNOPROF?"));gsmModem.waitResponse();// Scan for networks - this is probably really slowDBG(F("Scanning for networks. This may take up to 3 minutes"));gsmModem.sendAT(GF("+COPS=0"));gsmModem.waitResponse();gsmModem.sendAT(GF("+COPS=?"));gsmModem.waitResponse(180000L);// Wait forever for a connectionDBG(F("Waiting for network registration"));while (!gsmModem.isNetworkConnected()) {int csq = gsmModem.getSignalQuality();DBG("Signal quality:", csq);delay(250);}// Print some stuff after connectedString ccid = gsmModem.getSimCCID();DBG("CCID:", ccid);String imei = gsmModem.getIMEI();DBG("IMEI:", imei);String imsi = gsmModem.getIMSI();DBG("IMSI:", imsi);String cop = gsmModem.getOperator();DBG("Operator:", cop);IPAddress local = gsmModem.localIP();DBG("Local IP:", local);// Shut downgsmModem.poweroff();DBG("Powering down.");// And do nothing forever more.while (1) {}}You should set your end of line back to newline instead of carriage return when running this or you might get a lot of extra blank lines in the printout.
Ugh; I thought it would work. 🙁
Two things to try. First, try running the same thing but change your serial monitor settings to show you more of the output. If you’re running the Arduino IDE, when you open the serial port monitor, use the drop-down at the bottom to select “Carriage return.” (See screenshot.) In PlatformIO, add this to the [mayfly] (or [env]) section of your platformio.ini:
INI123monitor_flags =--eolCRThen rerun the same program and you should see much more extensive output. It’s not going to fix anything, but it would be interesting to see the output.
Attachments:
The settings for the profile and the band mask should be saved on the module, so you should only need to set it up one time. But, if you’re using ModularSensors, you’ll see that a bunch of the set-up from the first-run sketch is copied in the set-up for the modem in the example sketches. So when using those examples, you’ll either need to delete those extra set-up lines (and use what’s saved on the module) or change the profile to 1 and add the band mask every time. I’d lean toward re-setting it every time rather than hope the module remembered correctly.
Also, yes, I’ve spent enough time fiddling with the LTE and other modules that I knew exactly what all of those commands were right off the top of my head. The Digi command for setting bands was the only one I needed to check. These things are really troublesome.
To use those commands exactly, you need to switch to bypass mode.
But, the proper equivalent of almost all of those commands area already being used anyway, so you don’t need to change much at all.
They are setting the profile to
1
just like I suggested (that’s theUMNOPROF
). Other than making that change, I think the only thing you need to add is setting the bands (at+ubandmask=0,134217732
in their example). In the first-run sketch, right below setting the network technology (line 123), add the digi equivalent for setting the band mask:gsmModem.sendAT(GF(“BM134217732”));
gsmModem.waitResponse();No, I don’t think those command suggestions from your IoT provider will help much.
The
CPIN
command checks if your SIM is locked by a pin number. If your SIM provider didn’t mention it and give you the pin number, you shouldn’t need it.The proper equivalent to the
CREG
command is already being used in the gsmModem.isNetworkConnected() command on line 155 of the first run sketch.The
COPS=?
command is the same as theAS
command on line 147.You don’t see exactly those commands in the code because you’re not talking to the u-blox chip directly; you’re talking to a Digi programmed processor that’s talking to the u-blox chip. You can issue commands directly to the u-blox chip by switching your XBee3 from Digi recommended “transparent” mode to “bypass” mode. It might be necessary to do that to adjust the band scanning to exactly match your provider, but hopefully just setting the profile will work.
- If the SIM provider says you don’t have to do anything to activate the SIM, I’d trust them.
- Yes, the “AS” command in the first run sketch does that. (line ~147)
- If you’re using an XBee3 LTE-M it *only* supports LTE-M and LTE NB-IoT. Since your provider doesn’t use NB-IoT, LTE-M will be the only possibility. That first-run program you’re using sets the bee to use LTE-M preferentially in line 121, which is what you want.
- This might be your issue. Yes, the module can use all of those bands, but you would commonly set it up to use a specific carrier profile that will optimize searching to only the bands that carrier uses. In the example sketch (line 115), the carrier profile is set to 2/AT&T. Most of AT&T’s traffic is on bands 2, 4, and 12 (https://www.phonearena.com/news/Cheat-sheet-which-4G-LTE-bands-do-AT-T-Verizon-T-Mobile-and-Sprint-use-in-the-USA_id77933). So if you’re setting your module to AT&T, it will not attempt to use band 3 or band 28. I think you would want to select “1” as your carrier profile here, which will set the module for “SIM ICCID/IMSI select.” *Hopefully* your SIM and the module will be friendly enough with each other that the module will then switch its mode to that for your SIM. This doesn’t always work, though. I know with a Hologram SIMs in the USA the module will attempt to switch to 100/Standard Europe based on the SIM ICCID, which won’t work. But with a T-Mobile SIM the “SIM ICCID/IMSI select” setting immediately correctly matched to the 5/T-Mobile profile and the connection worked right away. If just switching the carrier profile to 1 doesn’t work, there are commands to manually try and force the bands. Start with the profile, though.
- Well, I generally think getting the development board is a good idea if you want to ever do much with the XBee (like test multiple boards or update firmware) but it shouldn’t be strictly needed.
Doh! I’m sorry about the missing void statements. That’s what happens when I write code on a discussion forum. Good job fixing it!
The invalid library statements are probably because you put something that wasn’t a library into the library folder, even if it was just an empty folder. The Arduino IDE thinks everything in that C:\Users\wchudyk\Documents\Arduino\libraries folder must be a library and gets confused otherwise.
Ok, so on to the errors on the ESP8266. The board is responding to you, at least to tell you there’s been an error, so that’s a good thing. My first guess would be that your ESP8266 has an older version of the AT firmware, and is expecting a different command. Here’s a new version with some of the older commands, and a check for the modules firmware version. Depending on which version you have, these may still not get you the MAC address, but hopefully they’ll at least get us the version to track down the command that will.
Arduino12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061#include <Arduino.h>void setup(){Serial.begin(115200);Serial1.begin(115200);delay(200);Serial.println("Changing ESP8266 baud, if necessary");Serial.println("This response may not be read-able");Serial1.println("AT+UART_CUR=9600,8,1,0,0");// Wait for and print the response, if it's intelligibledelay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();Serial1.end();Serial1.begin(9600);Serial.println("Asking the ESP for it firmware version");Serial1.println("AT+GMR");Serial.println("Response:");delay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();Serial.println("Making sure the ESP is in station mode");Serial1.println("AT+CWMODE_CUR=1");Serial.println("Response:");delay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();Serial.println("A second attempt to set the ESP mode, using the older command");Serial1.println("AT+CWMODE=1");Serial.println("Response:");delay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();Serial.println("Asking the ESP for its default station mac address");Serial1.println("AT+CIPSTAMAC_DEF?");Serial.println("Response:");delay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();Serial.println("Asking the ESP for its current station mac address");Serial1.println("AT+CIPSTAMAC_CUR?");Serial.println("Response:");delay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();Serial.println("A third attempt to get the mac address, with older command");Serial1.println("AT+CIPSTAMAC?");Serial.println("Response:");delay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();}void loop(){} // do no moreI’m sorry, I should have read that more carefully. That program is meant to be written to an ESP, not to a Mayfly.
Anyway, you should be able to do something like this:
Arduino123456789101112131415161718192021222324252627282930313233#include <Arduino.h>setup(){Serial.begin(115200);Serial1.begin(115200);delay(200);Serial.println("Changing ESP8266 baud, if necessary");Serial.println("This response may not be read-able");Serial1.println("AT+UART_CUR=9600,8,1,0,0");// Wait for and print the response, if it's intelligibledelay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();Serial1.end();Serial1.begin(9600);Serial.println("Asking the ESP for its default station mac address");Serial1.println("AT+CIPSTAMAC_DEF?");Serial.println("Response:");delay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();Serial.println("Asking the ESP for its current station mac address");Serial1.println("AT+CIPSTAMAC_CUR?");Serial.println("Response:");delay(100);while (Serial1.available()){Serial.write(Serial1.read());}Serial.println();}loop(){} // do no moreAlso, if the university requires any sort of two-set log in to the network (like, on a phone where you need to click ok on an “accept the terms” page) you won’t be able to do it.
-
AuthorPosts