Boron 3G/LTE Europe

Hello,

Tried out a 3G Boron here in Norway and it works great. I also got a Boron LTE unit which I am trying to get going as well with a SIM card from Telenor. CAT M1 is now available here in Norway, on channel 20 from what I can tell.

Big question; How can I make the Boron LTE module use the external sim card holder and register to the Telenor network here in Norway? The APN is ‘telenor.iot’ and I believe we use the 800/1800Mhz bands. Channel 20. My module is probably preconfigured for LTE in the US.

The regular setup process with the Boron LTE using the app seem to bail out after I say that I will not use the device as a mesh device.

I know this is not officially supported by Particle yet, but just interested in seeing what would it take to make this work. Any pointers are most welcome!

To set up a Boron with a 3rd-party SIM card you should follow the instructions here:

https://docs.particle.io/support/particle-devices-faq/electron-3rdparty-sims/

Note that is possible to set up a Boron LTE in other countries using a 3rd-party SIM card, but you’ll probably find it impossible to set up a mesh network because the mobile app setup does not support 3rd-party SIM cards and it’s not possible to set up a mesh network other than by the mobile app at this time.

2 Likes

@rickkas7 Awesome, that worked! Thanks for sharing. Boron LTE module seems to work well on the Telenor CAT M1 network here in Norway. Needed to specify a KeepAlive of 30 seconds though to make it keep the connection.

Hello :wave:t3:
Is it still not possible to setup a Mesh network with a LTE Boron out of the Americas?

Is the internal SIM going to support European countries anytime soon ? Norway, Switzerland and other countries do now have CAT-M1 networks as gularsen said.

Hello,

Would you please let me know how did you set-up the Boron LTE on the Telenor? I try to do it on Telia in Denmark by following the “set up a Boron with a 3rd-party SIM card” instruction but it doesn’t work!

This is the code I used to get the Boron LTE going with a Cat M1 sim from Telenor here in Norway:

/*
 * Project 3rdPartySIM
 * Description:
 * Author:
 * Date:
 */


#include "Particle.h"

#include "dct.h"

SYSTEM_MODE(SEMI_AUTOMATIC);

void setup() {
    Cellular.setActiveSim(EXTERNAL_SIM);
    Cellular.setCredentials("telenor.iot");

    // This clears the setup done flag on brand new devices so it won't stay in listening mode
    const uint8_t val = 0x01;
    dct_write_app_data(&val, DCT_SETUP_DONE_OFFSET, 1);

    // This is just so you know the operation is complete
    pinMode(D7, OUTPUT);
    digitalWrite(D7, HIGH);
}

void loop() {
}

Here is a modified Tinker app to go with it after the initial setup:

#include "Particle.h"

// Set your 3rd-party SIM APN here
// https://docs.particle.io/reference/firmware/electron/#setcredentials-
STARTUP(cellular_credentials_set("telenor.iot", "", "", NULL));
//STARTUP(cellular_credentials_set("telenor", "", "", NULL));

SerialLogHandler logHandler(LOG_LEVEL_ALL);

/* Function prototypes -------------------------------------------------------*/
int tinkerDigitalRead(String pin);
int tinkerDigitalWrite(String command);
int tinkerAnalogRead(String pin);
int tinkerAnalogWrite(String command);

SYSTEM_MODE(AUTOMATIC);

/* This function is called once at start up ----------------------------------*/
void setup()
{
	delay(5000);
	Serial.begin(115200);

	// Set the keep-alive value for 3rd party SIM card here
	// https://docs.particle.io/reference/firmware/electron/#particle-keepalive-
	Particle.keepAlive(30);

	//Setup the Tinker application here

	//Register all the Tinker functions
	Particle.function("digitalread", tinkerDigitalRead);
	Particle.function("digitalwrite", tinkerDigitalWrite);

	Particle.function("analogread", tinkerAnalogRead);
	Particle.function("analogwrite", tinkerAnalogWrite);
}

/* This function loops forever --------------------------------------------*/
void loop()
{
	//This will run in a loop
}

/*******************************************************************************
 * Function Name  : tinkerDigitalRead
 * Description    : Reads the digital value of a given pin
 * Input          : Pin
 * Output         : None.
 * Return         : Value of the pin (0 or 1) in INT type
                    Returns a negative number on failure
 *******************************************************************************/
int tinkerDigitalRead(String pin)
{
	//convert ascii to integer
	int pinNumber = pin.charAt(1) - '0';
	//Sanity check to see if the pin numbers are within limits
	if (pinNumber < 0 || pinNumber > 7) return -1;

	if(pin.startsWith("D"))
	{
		pinMode(pinNumber, INPUT_PULLDOWN);
		return digitalRead(pinNumber);
	}
	else if (pin.startsWith("A"))
	{
		pinMode(pinNumber+10, INPUT_PULLDOWN);
		return digitalRead(pinNumber+10);
	}
#if Wiring_Cellular
	else if (pin.startsWith("B"))
	{
		if (pinNumber > 5) return -3;
		pinMode(pinNumber+24, INPUT_PULLDOWN);
		return digitalRead(pinNumber+24);
	}
	else if (pin.startsWith("C"))
	{
		if (pinNumber > 5) return -4;
		pinMode(pinNumber+30, INPUT_PULLDOWN);
		return digitalRead(pinNumber+30);
	}
#endif
	return -2;
}

/*******************************************************************************
 * Function Name  : tinkerDigitalWrite
 * Description    : Sets the specified pin HIGH or LOW
 * Input          : Pin and value
 * Output         : None.
 * Return         : 1 on success and a negative number on failure
 *******************************************************************************/
int tinkerDigitalWrite(String command)
{
	bool value = 0;
	//convert ascii to integer
	int pinNumber = command.charAt(1) - '0';
	//Sanity check to see if the pin numbers are within limits
	if (pinNumber < 0 || pinNumber > 7) return -1;

	if(command.substring(3,7) == "HIGH") value = 1;
	else if(command.substring(3,6) == "LOW") value = 0;
	else return -2;

	if(command.startsWith("D"))
	{
		pinMode(pinNumber, OUTPUT);
		digitalWrite(pinNumber, value);
		return 1;
	}
	else if(command.startsWith("A"))
	{
		pinMode(pinNumber+10, OUTPUT);
		digitalWrite(pinNumber+10, value);
		return 1;
	}
#if Wiring_Cellular
	else if(command.startsWith("B"))
	{
		if (pinNumber > 5) return -4;
		pinMode(pinNumber+24, OUTPUT);
		digitalWrite(pinNumber+24, value);
		return 1;
	}
	else if(command.startsWith("C"))
	{
		if (pinNumber > 5) return -5;
		pinMode(pinNumber+30, OUTPUT);
		digitalWrite(pinNumber+30, value);
		return 1;
	}
#endif
else return -3;
}

/*******************************************************************************
 * Function Name  : tinkerAnalogRead
 * Description    : Reads the analog value of a pin
 * Input          : Pin
 * Output         : None.
 * Return         : Returns the analog value in INT type (0 to 4095)
                    Returns a negative number on failure
 *******************************************************************************/
int tinkerAnalogRead(String pin)
{
	//convert ascii to integer
	int pinNumber = pin.charAt(1) - '0';
	//Sanity check to see if the pin numbers are within limits
	if (pinNumber < 0 || pinNumber > 7) return -1;

	if(pin.startsWith("D"))
	{
		return -3;
	}
	else if (pin.startsWith("A"))
	{
		return analogRead(pinNumber+10);
	}
#if Wiring_Cellular
	else if (pin.startsWith("B"))
	{
		if (pinNumber < 2 || pinNumber > 5) return -3;
		return analogRead(pinNumber+24);
	}
#endif
	return -2;
}

/*******************************************************************************
 * Function Name  : tinkerAnalogWrite
 * Description    : Writes an analog value (PWM) to the specified pin
 * Input          : Pin and Value (0 to 255)
 * Output         : None.
 * Return         : 1 on success and a negative number on failure
 *******************************************************************************/
int tinkerAnalogWrite(String command)
{
	String value = command.substring(3);

	if(command.substring(0,2) == "TX")
	{
		pinMode(TX, OUTPUT);
		analogWrite(TX, value.toInt());
		return 1;
	}
	else if(command.substring(0,2) == "RX")
	{
		pinMode(RX, OUTPUT);
		analogWrite(RX, value.toInt());
		return 1;
	}

	//convert ascii to integer
	int pinNumber = command.charAt(1) - '0';
	//Sanity check to see if the pin numbers are within limits

	if (pinNumber < 0 || pinNumber > 7) return -1;

	if(command.startsWith("D"))
	{
		pinMode(pinNumber, OUTPUT);
		analogWrite(pinNumber, value.toInt());
		return 1;
	}
	else if(command.startsWith("A"))
	{
		pinMode(pinNumber+10, OUTPUT);
		analogWrite(pinNumber+10, value.toInt());
		return 1;
	}
	else if(command.substring(0,2) == "TX")
	{
		pinMode(TX, OUTPUT);
		analogWrite(TX, value.toInt());
		return 1;
	}
	else if(command.substring(0,2) == "RX")
	{
		pinMode(RX, OUTPUT);
		analogWrite(RX, value.toInt());
		return 1;
	}
#if Wiring_Cellular
	else if (command.startsWith("B"))
	{
		if (pinNumber > 3) return -3;
		pinMode(pinNumber+24, OUTPUT);
		analogWrite(pinNumber+24, value.toInt());
		return 1;
	}
	else if (command.startsWith("C"))
	{
		if (pinNumber < 4 || pinNumber > 5) return -4;
		pinMode(pinNumber+30, OUTPUT);
		analogWrite(pinNumber+30, value.toInt());
		return 1;
	}
#endif
else return -2;
}

Are you sure that your SIM supports LTE Cat M1?
This is not the same as LTE used on your mobile phone.

Thank you.
I did the same but it doesn’t work!
The problem might be related to the SIM. I will test another SIM …

I would expect that the SIM supports Cat-M1, but I am not sure!
Anyway, I will change it with another one …

Trying to get my first Boron LTE running here in Norway, with Telenor LTE-M/CAT-M1 external sim card.
But no luck :frowning:

I have set the external simcard, changed the credidentials to telenor.iot, but stuck on green blinking.
I checked the sim card status, and it is activated according to Telenor.
I am located in a central area with good coverage.

I tried the debug program, but i can’t really read/understand the results. Can anyone spot anything here?

starting tests...
turning cellular on...
0000015002 [system.nm] INFO: State changed: DISABLED -> IFACE_DOWN
0000020243 [hal] INFO: Using external Nano SIM card
deviceID=e00fce68462aa6ce1f02f52d
0000030335 [gsm0710muxer] INFO: Starting GSM07.10 muxer
0000030336 [gsm0710muxer] INFO: Openning mux channel 0
0000030336 [gsm0710muxer] INFO: GSM07.10 muxer thread started
0000030389 [gsm0710muxer] INFO: Resuming channel 0
0000030389 [gsm0710muxer] INFO: Openning mux channel 1
0000030441 [gsm0710muxer] INFO: Resuming channel 1
0000030441 [gsm0710muxer] INFO: Resuming channel 1
manufacturer=u-blox
model=SARA-R410M-02B
firmware version=L0.0.00.00.05.06 [Feb 03 2018 13:00:41]
ordering code=SARA-R410M-02B
IMEI=xxxxxxxxxxxx2267
IMSI=u-blox
ICCID=xxxxxxxxxxxxxx5568
0000030843 [app] INFO: enabling trace logging
0000030845 [ncp.at] TRACE: > AT+CGDCONT?
0000030893 [ncp.at] TRACE: < +CGDCONT: 1,"IP","telenor.iot","0.0.0.0",0,0,0,0
0000030894 [ncp.at] TRACE: < OK
0000030895 [ncp.at] TRACE: > AT+CSQ
0000030943 [ncp.at] TRACE: < +CSQ: 12,99
0000030943 [ncp.at] TRACE: < OK
attempting to connect to the cellular network...
0000030946 [system.nm] INFO: State changed: IFACE_DOWN -> IFACE_REQUEST_UP
0000030946 [system.nm] INFO: State changed: IFACE_DOWN -> IFACE_REQUEST_UP
0000030948 [hal] TRACE: PPP netif -> 8
0000030949 [net.ifapi] INFO: Netif pp3 state UP
0000030949 [net.ifapi] INFO: Netif pp3 state UP
0000030951 [hal] TRACE: PPP thread event LOWER_DOWN
0000030952 [hal] TRACE: PPP thread event ADM_DOWN
0000030954 [hal] TRACE: PPP thread event ADM_UP
0000030956 [hal] TRACE: State NONE -> READY
0000030955 [ncp.at] TRACE: > AT+CGDCONT=1,"IP","telenor.iot"
0000030958 [system.nm] INFO: State changed: IFACE_REQUEST_UP -> IFACE_UP
0000030958 [system.nm] INFO: State changed: IFACE_REQUEST_UP -> IFACE_UP
0000030993 [ncp.at] TRACE: < OK
0000030994 [ncp.at] TRACE: > AT+CEREG=2
0000031043 [ncp.at] TRACE: < OK
0000031043 [hal] TRACE: NCP connection state changed: 1
0000031044 [net.pppncp] TRACE: NCP event 2
0000031045 [net.pppncp] TRACE: State changed event: 1
0000031045 [hal] TRACE: PPP thread event LOWER_DOWN
0000031047 [ncp.at] TRACE: > AT+COPS=0,2
0000031093 [ncp.at] TRACE: < OK
0000031094 [ncp.at] TRACE: > AT+CEREG?
0000031143 [ncp.at] TRACE: < +CEREG: 2,2
0000031144 [ncp.at] TRACE: < OK
0000046244 [ncp.at] TRACE: > AT+CEREG?
0000046293 [ncp.at] TRACE: < +CEREG: 2,2
0000046293 [ncp.at] TRACE: < OK
0000061394 [ncp.at] TRACE: > AT+CEREG?
0000061443 [ncp.at] TRACE: < +CEREG: 2,2
0000061443 [ncp.at] TRACE: < OK
0000061631 [sys.power] TRACE: re-enabling charging
0000061673 [sys.power] TRACE: Battery state UNKNOWN -> CHARGED
0000062761 [sys.power] TRACE: Battery state CHARGED -> DISCONNECTED
0000076544 [ncp.at] TRACE: > AT+CEREG?
0000076593 [ncp.at] TRACE: < +CEREG: 2,2
0000076593 [ncp.at] TRACE: < OK
0000091694 [ncp.at] TRACE: > AT+CEREG?
0000091743 [ncp.at] TRACE: < +CEREG: 2,2
0000091743 [ncp.at] TRACE: < OK
0000106844 [ncp.at] TRACE: > AT+CEREG?
0000106893 [ncp.at] TRACE: < +CEREG: 2,2
0000106893 [ncp.at] TRACE: < OK
0000121994 [ncp.at] TRACE: > AT+CEREG?
0000122043 [ncp.at] TRACE: < +CEREG: 2,2
0000122043 [ncp.at] TRACE: < OK
0000122761 [sys.power] TRACE: re-enabling charging
0000122803 [sys.power] TRACE: Battery state UNKNOWN -> CHARGED
0000123891 [sys.power] TRACE: Battery state CHARGED -> DISCONNECTED
0000137144 [ncp.at] TRACE: > AT+CEREG?
0000137193 [ncp.at] TRACE: < +CEREG: 2,2
0000137193 [ncp.at] TRACE: < OK
0000152294 [ncp.at] TRACE: > AT+CEREG?
0000152343 [ncp.at] TRACE: < +CEREG: 2,2
0000152343 [ncp.at] TRACE: < OK
0000167444 [ncp.at] TRACE: > AT+CEREG?
0000167493 [ncp.at] TRACE: < +CEREG: 2,2
0000167493 [ncp.at] TRACE: < OK
0000182594 [ncp.at] TRACE: > AT+CEREG?
0000182643 [ncp.at] TRACE: < +CEREG: 2,2
0000182643 [ncp.at] TRACE: < OK
0000183891 [sys.power] TRACE: re-enabling charging
0000183933 [sys.power] TRACE: Battery state UNKNOWN -> CHARGED
0000185020 [sys.power] TRACE: Battery state CHARGED -> DISCONNECTED
0000197744 [ncp.at] TRACE: > AT+CEREG?
0000197797 [ncp.at] TRACE: < +CEREG: 2,2
0000197797 [ncp.at] TRACE: < OK

Thomlov: Did you ever get it to connect? I’m having the same issue…

Looking at the possible return codes from the AT+CREG? command :

0000031094 [ncp.at] TRACE: > AT+CEREG?
0000031143 [ncp.at] TRACE: < +CEREG: 2,2
0000031144 [ncp.at] TRACE: < OK

Possible values of registration status are,
0 not registered, MT is not currently searching a new operator to register to
1 registered, home network
2 not registered, but MT is currently searching a new operator to register to
3 registration denied
4 unknown (e.g. out of GERAN/UTRAN/E-UTRAN coverage)
5 registered, roaming
6 registered for “SMS only”, home network (applicable only when indicates E-UTRAN)
7 registered for “SMS only”, roaming (applicable only when indicates E-UTRAN)
8 attached for emergency bearer services only (see NOTE 2) (not applicable)
9 registered for “CSFB not preferred”, home network (applicable only when indicates E-UTRAN)
10 registered for “CSFB not preferred”, roaming (applicable only when indicates E-UTRAN)

Possible values for access technology are,
0 GSM
1 GSM Compact
2 UTRAN
3 GSM w/EGPRS
4 UTRAN w/HSDPA
5 UTRAN w/HSUPA
6 UTRAN w/HSDPA and HSUPA
7 E-UTRAN

It seems that the sim cannot register and that the transport is UTRAN - this means it is a 3G variant and not LTE - so this sim should work in a 3G Boron but will not work in an LTE one…

May want to check the MNO setting on the modem as well, if your SIM is ok. Particle seems to set this to something that works well in the US, but not in Europe. For Europe, it needs to be set to 100, per UBLOX’s AT Command document.